diff -ur sendmail-8.13.1-orig/cf/m4/proto.m4 sendmail-8.13.1-RS/cf/m4/proto.m4 --- sendmail-8.13.1-orig/cf/m4/proto.m4 2004-07-27 13:32:48.000000000 -0400 +++ sendmail-8.13.1-RS/cf/m4/proto.m4 2004-10-25 22:05:32.000000000 -0400 @@ -578,6 +578,19 @@ # once the threshold number of recipients have been rejected _OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0') +ifdef(`_FFR_BADRCPT_SHUTDOWN', `dnl +# number of bad recipients before connection is evaluated for +# shutdown with 421 code. Zero disables. Numbers less than 5 not +# recommended. +_OPTION(BadRcptShutdown, `confBAD_RCPT_SHUTDOWN', `0') +# Percentage of bad recipients of total before shutdown is +# allowed. 81 is a good number, only dropping connection if +# 2 out of 10 rcpts or less are good. +# If 100, the connection will never be shut down onon good recipients. +# If 0 the connection will be shut down as soon as BadRcptShutdown +# bad rcpts are reached. +_OPTION(BadRcptShutdownGood, `confBAD_RCPT_SHUTDOWN_GOOD', `100')') + # shall we get local names from our installed interfaces? _OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False') diff -ur sendmail-8.13.1-orig/sendmail/readcf.c sendmail-8.13.1-RS/sendmail/readcf.c --- sendmail-8.13.1-orig/sendmail/readcf.c 2004-07-23 16:45:02.000000000 -0400 +++ sendmail-8.13.1-RS/sendmail/readcf.c 2004-10-24 21:05:13.000000000 -0400 @@ -2190,6 +2190,12 @@ # define O_HELONAME 0xd8 { "HeloName", O_HELONAME, OI_NONE }, #endif /* _FFR_HELONAME */ +#if _FFR_BADRCPT_SHUTDOWN +# define O_RCPTSHUTD 0xd9 + { "BadRcptShutdown", O_RCPTSHUTD, OI_SAFE }, +# define O_RCPTSHUTDG 0xda + { "BadRcptShutdownGood", O_RCPTSHUTDG, OI_SAFE }, +#endif /* _FFR_BADRCPT_SHUTDOWN */ { NULL, '\0', OI_NONE } }; @@ -3249,6 +3255,16 @@ case O_RCPTTHROT: BadRcptThrottle = atoi(val); break; +#if _FFR_BADRCPT_SHUTDOWN + + case O_RCPTSHUTD: + BadRcptShutdown = atoi(val); + break; + + case O_RCPTSHUTDG: + BadRcptShutdownGood = atoi(val); + break; +#endif /* _FFR_BADRCPT_SHUTDOWN */ case O_DEADLETTER: CANONIFY(val); diff -ur sendmail-8.13.1-orig/sendmail/sendmail.h sendmail-8.13.1-RS/sendmail/sendmail.h --- sendmail-8.13.1-orig/sendmail/sendmail.h 2004-07-14 17:54:22.000000000 -0400 +++ sendmail-8.13.1-RS/sendmail/sendmail.h 2004-10-24 21:19:33.000000000 -0400 @@ -2185,6 +2185,10 @@ EXTERN char OpMode; /* operation mode, see below */ EXTERN char SpaceSub; /* substitution for */ EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */ +#if _FFR_BADRCPT_SHUTDOWN +EXTERN int BadRcptShutdown; /* Shutdown connection for rejected RCPTs */ +EXTERN int BadRcptShutdownGood; /* above even when there are good RCPTs */ +#endif /* _FFR_BADRCPT_SHUTDOWN */ EXTERN int CheckpointInterval; /* queue file checkpoint interval */ EXTERN int ConfigLevel; /* config file level */ EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */ diff -ur sendmail-8.13.1-orig/sendmail/srvrsmtp.c sendmail-8.13.1-RS/sendmail/srvrsmtp.c --- sendmail-8.13.1-orig/sendmail/srvrsmtp.c 2004-07-08 19:29:33.000000000 -0400 +++ sendmail-8.13.1-RS/sendmail/srvrsmtp.c 2004-10-25 16:01:22.000000000 -0400 @@ -2424,6 +2424,41 @@ case CMDRCPT: /* rcpt -- designate recipient */ DELAY_CONN("RCPT"); +#if _FFR_BADRCPT_SHUTDOWN + if (BadRcptShutdown > 0 && + n_badrcpts >= BadRcptShutdown) + { + bool result_flag = false; + + if (!BadRcptShutdownGood || !smtp.sm_nrcpts) + result_flag = true; + + if (!result_flag) + { + float f = n_badrcpts; + float g = smtp.sm_nrcpts + n_badrcpts; + float h = f/g; + + h *= 100.00; + if (h >= BadRcptShutdownGood) + result_flag = true; + } + + if (result_flag) + { + if (LogLevel > 5) + sm_syslog(LOG_INFO, e->e_id, + "%s: Possible SMTP RCPT flood, shutting down connection.", + CurSmtpClient); + message("421 4.7.0 %s Too many bad recipients; closing connection", + MyHostName); + + /* arrange to ignore any current send list */ + e->e_sendqueue = NULL; + goto doquit; + } + } +#endif /* _FFR_BADRCPT_SHUTDOWN */ if (BadRcptThrottle > 0 && n_badrcpts >= BadRcptThrottle) {