Index: srvrsmtp.c =================================================================== RCS file: /cvs/sendmail/srvrsmtp.c,v retrieving revision 8.829.2.34 retrieving revision 8.829.2.36 diff -u -r8.829.2.34 -r8.829.2.36 --- srvrsmtp.c 14 Jan 2004 19:13:46 -0000 8.829.2.34 +++ srvrsmtp.c 5 Apr 2004 23:25:42 -0000 8.829.2.36 @@ -60,8 +60,8 @@ static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int)); -static time_t checksmtpattack __P((volatile unsigned int *, int, bool, - char *, ENVELOPE *)); +static time_t checksmtpattack __P((volatile unsigned int *, unsigned int, + bool, char *, ENVELOPE *)); static void mail_esmtp_args __P((char *, char *, ENVELOPE *)); static void printvrfyaddr __P((ADDRESS *, bool, bool)); static void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *)); @@ -221,6 +221,18 @@ # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */ #endif /* ! MAXTIMEOUT */ +/* +** Maximum shift value to compute timeout for bad commands. +** This introduces an upper limit of 2^MAXSHIFT for the timeout. +*/ + +#ifndef MAXSHIFT +# define MAXSHIFT 8 +#endif /* ! MAXSHIFT */ +#if MAXSHIFT > 31 + ERROR _MAXSHIFT > 31 is invalid +#endif /* MAXSHIFT */ + #if SM_HEAP_CHECK static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp", "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $"); @@ -3468,7 +3480,7 @@ static time_t checksmtpattack(pcounter, maxcount, waitnow, cname, e) volatile unsigned int *pcounter; - int maxcount; + unsigned int maxcount; bool waitnow; char *cname; ENVELOPE *e; @@ -3478,6 +3490,7 @@ if (++(*pcounter) >= maxcount) { + unsigned int shift; time_t s; if (*pcounter == maxcount && LogLevel > 5) @@ -3486,13 +3499,16 @@ "%s: possible SMTP attack: command=%.40s, count=%u", CurSmtpClient, cname, *pcounter); } - s = 1 << (*pcounter - maxcount); - if (s >= MAXTIMEOUT || s <= 0) + shift = *pcounter - maxcount; + s = 1 << shift; + if (shift > MAXSHIFT || s >= MAXTIMEOUT || s <= 0) s = MAXTIMEOUT; /* sleep at least 1 second before returning */ (void) sleep(*pcounter / maxcount); s -= *pcounter / maxcount; + if (s >= MAXTIMEOUT || s <= 0) + s = MAXTIMEOUT; if (waitnow) { (void) sleep(s);