Ok, some progress... I've installed the package, I'm running it currently.
Anyone have any comments on it? Thanks, -Philip
--- examples/init-script.in.bak 2005-10-14 10:16:27.000000000 -0600 +++ examples/init-script.in 2006-01-17 00:58:34.000000000 -0700 @@ -39,16 +39,19 @@ [EMAIL PROTECTED]@ # If you want to keep spool directories around if the filter fails, # set the next one to yes # KEEP_FAILED_DIRECTORIES=no # "yes" turns on the multiplexor relay checking function # MX_RELAY_CHECK=no +# "yes" turns on the multiplexor helo checking function +# MX_HELO_CHECK=no + # "yes" turns on the multiplexor sender checking function # MX_SENDER_CHECK=no # "yes" turns on the multiplexor recipient checking function # MX_RECIPIENT_CHECK=no # Set to yes if you want the multiplexor to log events to syslog MX_LOG=yes @@ -212,16 +215,17 @@ start_it() { printf "%-60s" "Starting $prog: " rm -f $SOCKET > /dev/null 2>&1 $PROGDIR/$prog -P $PID \ -m $MX_SOCKET \ `[ -n "$SPOOLDIR"] && echo "-z $SPOOLDIR"` \ `[ -n "$MX_USER" ] && echo "-U $MX_USER"` \ `[ -n "$SYSLOG_FACILITY" ] && echo "-S $SYSLOG_FACILITY"` \ `[ "$MX_RELAY_CHECK" = "yes" ] && echo "-r"` \ + `[ "$MX_HELO_CHECK" = "yes" ] && echo "-H"` \ `[ "$MX_SENDER_CHECK" = "yes" ] && echo "-s"` \ `[ "$MX_RECIPIENT_CHECK" = "yes" ] && echo "-t"` \ `[ "$KEEP_FAILED_DIRECTORIES" = "yes" ] && echo "-k"` \ `[ "$MD_EXTRA" != "" ] && echo $MD_EXTRA` \ `[ "$ALLOW_NEW_CONNECTIONS_TO_QUEUE" = "yes" ] && echo "-q"` \ -p $SOCKET RETVAL=$? if [ $RETVAL = 0 ] ; then --- mimedefang.h.bak 2005-02-08 09:04:39.000000000 -0700 +++ mimedefang.h 2006-01-17 02:05:15.000000000 -0700 @@ -22,19 +22,21 @@ extern void write_percent_encoded(unsign extern int percent_encode(unsigned char *in, unsigned char *out, int outlen); extern void percent_decode(unsigned char *buf); extern int MXCheckFreeSlaves(char const *sockname); extern int MXScanDir(char const *sockname, char const *dir); extern int MXCommand(char const *sockname, char const *cmd, char *buf, int len); extern int MXRelayOK(char const *sockname, char *msg, char const *ip, char const *name); +extern int MXHeloOK(char const *sockname, char *msg, + char const *helo, char const *ip, char const *name); extern int MXSenderOK(char const *sockname, char *msg, char const **sender_argv, char const *ip, char const *name, - char const *helo, char const *dir, char const *qid); + char const *dir, char const *qid); extern int MXRecipientOK(char const *sockname, char *msg, char const **recip_argv, char const *sender, char const *ip, char const *name, char const *firstRecip, char const *helo, char const *dir, char const *qid, char const *rcpt_mailer, char const *rcpt_host, char const *rcpt_addr); --- mimedefang.pl.in.bak 2005-10-28 08:05:27.000000000 -0600 +++ mimedefang.pl.in 2006-01-17 02:06:59.000000000 -0700 @@ -5168,31 +5168,38 @@ sub do_main_loop () { if ($_ =~ /^relayok (\S*)\s+(\S*)/) { $ip = percent_decode($1); $name = percent_decode($2); relay_ok($ip, $name); chdir($Features{'Path:SPOOLDIR'}); next; } - if ($_ =~ /^senderok (\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)/) { + if ($_ =~ /^helook (\S*)\s+(\S*)\s+(\S*)/) { + $ip = percent_decode($1); + $name = percent_decode($2); + $helo = percent_decode($3); + helo_ok($ip, $name, $helo); + chdir($Features{'Path:SPOOLDIR'}); + next; + } + if ($_ =~ /^senderok (\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)/) { $sender = percent_decode($1); $ip = percent_decode($2); $name = percent_decode($3); - $helo = percent_decode($4); - $CWD = percent_decode($5); - $QueueID = percent_decode($6); + $CWD = percent_decode($4); + $QueueID = percent_decode($5); $MsgID = $QueueID; # Get ESMTP args $_ =~ s/^senderok (\S*\s+){5}\S*\s*//; @ESMTPArgs = map { percent_decode($_) } split(' ', $_); chdir($CWD); - sender_ok($sender, $ip, $name, $helo); + sender_ok($sender, $ip, $name); chdir($Features{'Path:SPOOLDIR'}); next; } if ($_ =~ /^recipok (\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S*)\s+(\S+)\s+(\S+)\s+(\S+)/) { my($rcpt_mailer, $rcpt_host, $rcpt_addr); $recip = percent_decode($1); $sender = percent_decode($2); $ip = percent_decode($3); @@ -6494,42 +6501,68 @@ sub relay_ok ($$) { # Set up globals $RelayAddr = $hostip; $RelayHostname = $hostname; my($ok, $msg, $code, $dsn, $delay) = filter_relay($hostip, $hostname); send_filter_answer($ok, $msg, "filter_relay", "host $hostip ($hostname)", $code, $dsn, $delay); } #*********************************************************************** +# %PROCEDURE: helo_ok +# %ARGUMENTS: +# ip -- IP address of relay host +# name -- name of relay host +# helo -- arg to SMTP HELO command +# %RETURNS: +# Nothing, but prints "ok 1" if we accept connections from this host. +# "ok 0" if not. +#*********************************************************************** +sub helo_ok ($$$) { + my($ip, $name, $helo) = @_; + if (!defined(&filter_helo)) { + send_filter_answer('CONTINUE', "ok", + "filter_helo", "helo $helo"); + return; + } + + # Set up globals + $RelayAddr = $ip; + $RelayHostname = $name; + $Helo = $helo; + + my($ok, $msg, $code, $dsn, $delay) = + filter_helo($ip, $name, $helo); + send_filter_answer($ok, $msg, "filter_helo", "helo $helo", + $code, $dsn, $delay); +} +#*********************************************************************** # %PROCEDURE: sender_ok # %ARGUMENTS: # sender -- e-mail address of sender # ip -- IP address of relay host # name -- name of relay host -# helo -- arg to SMTP HELO command # %RETURNS: # Nothing, but prints "ok 1" if we accept message from this sender, # "ok 0" if not. #*********************************************************************** -sub sender_ok ($$$$) { - my($sender, $ip, $name, $helo) = @_; +sub sender_ok ($$$) { + my($sender, $ip, $name) = @_; if (!defined(&filter_sender)) { send_filter_answer('CONTINUE', "ok", "filter_sender", "sender $sender"); return; } # Set up globals $Sender = $sender; $RelayAddr = $ip; $RelayHostname = $name; - $Helo = $helo; my($ok, $msg, $code, $dsn, $delay) = - filter_sender($sender, $ip, $name, $helo); + filter_sender($sender, $ip, $name); send_filter_answer($ok, $msg, "filter_sender", "sender $sender", $code, $dsn, $delay); } #*********************************************************************** # %PROCEDURE: recipient_ok # %ARGUMENTS: # recipient -- e-mail address of recipient --- utils.c.bak 2005-02-08 09:04:40.000000000 -0700 +++ utils.c 2006-01-17 02:07:52.000000000 -0700 @@ -640,16 +640,56 @@ MXRelayOK(char const *sockname, if (percent_encode_command(1, cmd, sizeof(cmd), "relayok", ip, name, NULL) < 0) { return -1; } if (MXCommand(sockname, cmd, ans, SMALLBUF-1) < 0) return -1; return munch_mx_return(ans, msg); } /********************************************************************** +* %FUNCTION: MXHeloOK +* %ARGUMENTS: +* sockname -- multiplexor socket name +* msg -- buffer for holding error message, at least SMALLBUF chars +* helo -- the helo string +* %RETURNS: +* 1 if it's OK to accept messages from this sender; 0 if not, -1 if error or +* we should tempfail. +* 1 if it's OK to accept connections from this host; 0 if not, -1 if error. +* If connection is rejected, error message *may* be set. +***********************************************************************/ +int +MXHeloOK(char const *sockname, + char *msg, + char const *ip, + char const *name, + char const *helo) +{ + char cmd[SMALLBUF]; + char ans[SMALLBUF]; + + *msg = 0; + + if (!ip || !*ip) { + ip = "UNKNOWN"; + } + if (!name || !*name) { + name = ip; + } + if (!helo) { + helo = "UNKNOWN"; + } + if (percent_encode_command(1, cmd, sizeof(cmd), "helook", ip, name, helo, NULL) < 0) { + return -1; + } + if (MXCommand(sockname, cmd, ans, SMALLBUF-1) < 0) return -1; + return munch_mx_return(ans, msg); +} + +/********************************************************************** * %FUNCTION: MXSenderOK * %ARGUMENTS: * sockname -- socket name * msg -- buffer of at least SMALLBUF size for error message * sender_argv -- args from sendmail. sender_argv[0] is sender; rest are * ESMTP args. * ip -- sending relay's IP address * name -- sending relay's host name @@ -662,17 +702,16 @@ MXRelayOK(char const *sockname, * If message is rejected, error message *may* be set. ***********************************************************************/ int MXSenderOK(char const *sockname, char *msg, char const **sender_argv, char const *ip, char const *name, - char const *helo, char const *dir, char const *qid) { char cmd[SMALLBUF]; char ans[SMALLBUF]; int l, l2, i; char const *sender = sender_argv[0]; @@ -684,22 +723,18 @@ MXSenderOK(char const *sockname, } if (!ip || !*ip) { ip = "UNKNOWN"; } if (!name || !*name) { name = ip; } - if (!helo) { - helo = "UNKNOWN"; - } if (percent_encode_command(0, cmd, sizeof(cmd)-1, "senderok", sender, ip, - name, - helo, dir, qid, NULL) < 0) { + name, dir, qid, NULL) < 0) { return -1; } /* Append ESMTP args */ l = strlen(cmd); for (i=1; sender_argv[i]; i++) { percent_encode((unsigned char *) sender_argv[i], ans, --- redhat/mimedefang-init.in.bak 2004-10-28 14:31:21.000000000 -0600 +++ redhat/mimedefang-init.in 2006-01-17 00:59:57.000000000 -0700 @@ -234,16 +234,17 @@ start() { ulimit -s 2048 daemon $PROGDIR/$prog -P @SPOOLDIR@/$prog.pid \ -m $MX_SOCKET \ $([ -n "$MX_USER" ] && echo "-U $MX_USER") \ $([ -n "$SYSLOG_FACILITY" ] && echo "-S $SYSLOG_FACILITY") \ $([ "$LOG_FILTER_TIME" = "yes" ] && echo "-T") \ $([ "$MX_RELAY_CHECK" = "yes" ] && echo "-r") \ + $([ "$MX_HELO_CHECK" = "yes" ] && echo "-H") \ $([ "$MX_SENDER_CHECK" = "yes" ] && echo "-s") \ $([ "$MX_RECIPIENT_CHECK" = "yes" ] && echo "-t") \ $([ "$KEEP_FAILED_DIRECTORIES" = "yes" ] && echo "-k") \ $([ -n "$MD_EXTRA" ] && echo "$MD_EXTRA") \ -p $SOCKET RETVAL=$? echo --- redhat/mimedefang-sysconfig.in.bak 2005-10-14 10:16:54.000000000 -0600 +++ redhat/mimedefang-sysconfig.in 2006-01-17 00:57:33.000000000 -0700 @@ -125,16 +125,19 @@ MX_USER=defang # If you want to keep spool directories around if the filter fails, # set the next one to yes # KEEP_FAILED_DIRECTORIES=no # If "yes", turn on the multiplexor relay checking function # MX_RELAY_CHECK=no +# If "yes", turn on the multiplexor helo checking function +# MX_HELO_CHECK=no + # If "yes", turn on the multiplexor sender checking function # MX_SENDER_CHECK=no # If "yes", turn on the multiplexor recipient checking function # MX_RECIPIENT_CHECK=no # Set to yes if you want the multiplexor to log events to syslog MX_LOG=yes --- mimedefang.c.bak 2005-10-14 10:33:27.000000000 -0600 +++ mimedefang.c 2006-01-17 02:05:03.000000000 -0700 @@ -177,16 +177,19 @@ static int set_reply(SMFICTX *ctx, char #define CHUNK 4096 /* Number of file descriptors to close when forking */ #define CLOSEFDS 256 /* Mutex to protect mkdir() calls */ static pthread_mutex_t MkdirMutex = PTHREAD_MUTEX_INITIALIZER; +/* Do helo check? */ +static int doHeloCheck = 0; + /* Do relay check? */ static int doRelayCheck = 0; /* Do sender check? */ static int doSenderCheck = 0; /* Do recipient check? */ static int doRecipientCheck = 0; @@ -551,16 +554,51 @@ helo(SMFICTX *ctx, char *helohost) DEBUG_EXIT("helo", __LINE__, "SMFIS_TEMPFAIL"); return SMFIS_TEMPFAIL; } if (data->heloArg) { free(data->heloArg); data->heloArg = NULL; } data->heloArg = strdup_with_log(helohost); + + if (doHeloCheck) { + char buf2[SMALLBUF]; + int n = MXHeloOK(MultiplexorSocketName, buf2, data->hostip, + data->hostname, data->heloArg); + if (n == 0) { + /* Can't call smfi_setreply from helo callback */ + /* set_dsn(ctx, buf2, 5); */ + /* We reject connections from this relay */ + cleanup(ctx); + DEBUG_EXIT("helo", __LINE__, "SMFIS_REJECT"); + return SMFIS_REJECT; + } + if (n < 0) { + /* Can't call smfi_setreply from helo callback */ + /* set_dsn(ctx, buf2, 4); */ + cleanup(ctx); + DEBUG_EXIT("helo", __LINE__, "SMFIS_TEMPFAIL"); + return SMFIS_TEMPFAIL; + } + if (n == 2) { + /* Can't call smfi_setreply from helo callback */ + /* set_dsn(ctx, buf2, 2); */ + cleanup(ctx); + return SMFIS_ACCEPT; + } + if (n == 3) { + /* Can't call smfi_setreply from helo callback */ + /* set_dsn(ctx, buf2, 2); */ + cleanup(ctx); + return SMFIS_DISCARD; + } + } + + DEBUG_EXIT("helo", __LINE__, "SMFIS_CONTINUE"); return SMFIS_CONTINUE; } /********************************************************************** *%FUNCTION: envfrom *%ARGUMENTS: * ctx -- Sendmail filter mail context * from -- list of arguments to "MAIL FROM:" SMTP command. @@ -761,17 +799,17 @@ envfrom(SMFICTX *ctx, char **from) /* Sigh... use our computed address */ data->myip = MyIPAddress; } if (doSenderCheck) { int n = MXSenderOK(MultiplexorSocketName, buf2, (char const **) from, data->hostip, data->hostname, - data->heloArg, data->dir, data->qid); + data->dir, data->qid); if (n == 0) { set_dsn(ctx, buf2, 5); /* We reject connections from this sender */ cleanup(ctx); DEBUG_EXIT("envfrom", __LINE__, "SMFIS_REJECT"); return SMFIS_REJECT; } @@ -1697,16 +1735,17 @@ usage(void) fprintf(stderr, " -C -- Try very hard to conserve file descriptors\n"); fprintf(stderr, " -x string -- Add string as X-Scanned-By header\n"); fprintf(stderr, " -X -- Do not add X-Scanned-By header\n"); fprintf(stderr, " -M -- Protect mkdir with mutex\n"); fprintf(stderr, " -D -- Do not become a daemon (stay in foreground)\n"); fprintf(stderr, " -S facility -- Set syslog(3) facility\n"); fprintf(stderr, " -a macro -- Pass additional Sendmail macro\n"); fprintf(stderr, " -L ip.addr -- Specify 'equivalent-to-loopback' address\n"); + fprintf(stderr, " -H -- Do HELO checks before processing any messages\n"); exit(EXIT_FAILURE); } /********************************************************************** * %FUNCTION: main * %ARGUMENTS: * argc, argv -- the usual suspects * %RETURNS: @@ -1764,17 +1803,17 @@ main(int argc, char **argv) #endif } else { syslog(LOG_WARNING, "Could not determine my own IP address! Ensure that %s has an entry in /etc/hosts or the DNS", buf); fprintf(stderr, "Could not determine my own IP address! Ensure that %s has an entry in /etc/hosts or the DNS\n", buf); } } /* Process command line options */ - while ((c = getopt(argc, argv, "a:Chp:dm:srtkP:U:Tx:MXS:Dvb:L:qz:")) != -1) { + while ((c = getopt(argc, argv, "a:CHhp:dm:srtkP:U:Tx:MXS:Dvb:L:qz:")) != -1) { switch (c) { case 'z': SpoolDir = strdup(optarg); if (!SpoolDir) { fprintf(stderr, "%s: Out of memory\n", argv[0]); exit(EXIT_FAILURE); } break; @@ -1920,16 +1959,19 @@ main(int argc, char **argv) /* Remove socket from file system */ (void) remove(optarg); if (smfi_setconn(optarg) != MI_SUCCESS) { fprintf(stderr, "%s: Could not open connection %s: %s", argv[0], optarg, strerror(errno)); exit(EXIT_FAILURE); } break; + case 'H': + doHeloCheck = 1; + break; default: usage(); break; } } /* Set SpoolDir if it wasn't set on command line */ if (!SpoolDir) {
_______________________________________________ NOTE: If there is a disclaimer or other legal boilerplate in the above message, it is NULL AND VOID. You may ignore it. Visit http://www.mimedefang.org and http://www.roaringpenguin.com MIMEDefang mailing list MIMEDefang@lists.roaringpenguin.com http://lists.roaringpenguin.com/mailman/listinfo/mimedefang