David F. Skoll wrote:

Not in filter_sender if we use your patch, unless we parse the
commands file manually.

If you re-work your patch to leave filter_sender as it was, I will
include it in the official release.

Here's the patch again. I was hoping to get some answers about the set_dsn()
stuff before posting...

-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 12:56:27.000000000 -0700
@@ -22,16 +22,18 @@ 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);
 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,
--- mimedefang.pl.in.bak	2005-10-28 08:05:27.000000000 -0600
+++ mimedefang.pl.in	2006-01-17 13:00:34.000000000 -0700
@@ -5168,16 +5168,24 @@ 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 ($_ =~ /^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*)\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);
 	    $MsgID = $QueueID;
@@ -6494,16 +6502,44 @@ 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,
--- utils.c.bak	2005-02-08 09:04:40.000000000 -0700
+++ utils.c	2006-01-17 13:01:56.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
--- 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 13:18:46.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,47 @@ 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) {
+	    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) {
+	    set_dsn(ctx, buf2, 4);
+	    cleanup(ctx);
+	    DEBUG_EXIT("helo", __LINE__, "SMFIS_TEMPFAIL");
+	    return SMFIS_TEMPFAIL;
+	}
+	if (n == 2) {
+	    set_dsn(ctx, buf2, 2);
+	    cleanup(ctx);
+	    return SMFIS_ACCEPT;
+	}
+	if (n == 3) {
+	    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.
@@ -1697,16 +1731,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 +1799,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 +1955,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

Reply via email to