[Exim] 2 patches for exim 3.30

Top Page
Delete this message
Reply to this message
Author: Marc MERLIN
Date:  
To: exim-users
Subject: [Exim] 2 patches for exim 3.30
Attached at two patches I wrote for exim 3.30:

The first one adds an option to turn off SMTP callbacks on header froms
while leaving it on for envelope froms.
The patch in verify.c is from Philip, the glue to make it an option (and the
option name) are my fault :-)


The second patch adds much better (maybe overkill, but I like to be
thorough) error messages.
My personal favorite is:
----------------------------------------------------------------------------
220 mail.valinux.com ESMTP Exim 3.30-VA-mm1 #6 Wed, 27 Jun 2001 23:33:58 -0700 -
VA int mm6
mail from: pm@???
250 reject all recipients: 3 times bad sender: response from mailhost.directlink
.net [207.239.163.2] after "MAIL FROM: <>" was "501 bogus mail from". This does
not help fight spam effectively, breaks RFCs, and prevents you from getting boun
ces so we can't accept mail from you <pm@???>
----------------------------------------------------------------------------

Among other things, SMTP callback status wasn't reported when the header
from check failed. That's fixed.

See the patches for more details.

I am aware that they may never make it in the main exim 3.x tree since it's
not actively maintained anymore, but that's ok. If they can be useful to
you, this mail wasn't useless :-)

Cheers,
Marc
--
VA Linux Systems Server Sysadmin / Sourceforge mail&list master. 510 687 7061

Home page: http://marc.merlins.org/
Finger marc_f@??? for PGP key
This adds an option to turn off SMTP callbacks on header froms while leaving
it on for envelope froms.
The patch in verify is from Philip, the glue to make it an option (and the
option name) are my fault :-)

Marc MERLIN <marcsoft@???/marc_bts@???> 2001/06/29

diff -urN exim-3.30.orig/src/globals.c exim-3.30/src/globals.c
--- exim-3.30.orig/src/globals.c    Mon Jun 18 04:03:24 2001
+++ exim-3.30/src/globals.c    Fri Jun 29 01:58:24 2001
@@ -668,6 +668,7 @@
 BOOL   sender_verify_batch    = FALSE;
 char  *sender_verify_callback_domains = NULL;
 char  *sender_verify_callback_error = NULL;
+BOOL   sender_verify_callback_hdrfrm = TRUE;
 int    sender_verify_callback_timeout = 30;
 BOOL   sender_verify_fixup    = FALSE;
 char  *sender_verify_hosts    = "*";
diff -urN exim-3.30.orig/src/globals.h exim-3.30/src/globals.h
--- exim-3.30.orig/src/globals.h    Mon Jun 18 04:03:24 2001
+++ exim-3.30/src/globals.h    Fri Jun 29 01:58:24 2001
@@ -491,6 +491,7 @@
 extern BOOL   sender_verify_batch;    /* TRUE if batch SMTP included */
 extern char  *sender_verify_callback_domains; /* For SMTP callbacks */
 extern char  *sender_verify_callback_error;   /* ditto - holds error */
+extern BOOL   sender_verify_callback_hdrfrm;   /* callback on hdrfrm too */
 extern int    sender_verify_callback_timeout; /* ditto */
 extern BOOL   sender_verify_fixup;    /* Fix broken senders from headers */
 extern char  *sender_verify_hosts;    /* Verification hosts */
diff -urN exim-3.30.orig/src/readconf.c exim-3.30/src/readconf.c
--- exim-3.30.orig/src/readconf.c    Mon Jun 18 04:03:26 2001
+++ exim-3.30/src/readconf.c    Mon Jun 25 16:54:04 2001
@@ -221,6 +221,7 @@
   { "sender_verify",            opt_bool,        &sender_verify },
   { "sender_verify_batch",      opt_bool,        &sender_verify_batch },
   { "sender_verify_callback_domains", opt_stringptr, &sender_verify_callback_domains },
+  { "sender_verify_callback_hdrfrm",  opt_bool,  &sender_verify_callback_hdrfrm },
   { "sender_verify_callback_timeout", opt_time,  &sender_verify_callback_timeout },
   { "sender_verify_fixup",      opt_bool,        &sender_verify_fixup },
   { "sender_verify_hosts",      opt_stringptr,   &sender_verify_hosts },
diff -urN exim-3.30.orig/src/verify.c exim-3.30/src/verify.c
--- exim-3.30.orig/src/verify.c    Mon Jun 18 04:03:28 2001
+++ exim-3.30/src/verify.c    Fri Jun 29 01:58:53 2001
@@ -711,7 +730,13 @@
         }
       else
         {
-        new_ok = verify_address(s, NULL, &is_local, newaddr, 0);
+    char *save = sender_verify_hosts_callback;
+        if (! sender_verify_callback_hdrfrm)
+    {
+          sender_verify_hosts_callback = NULL;
+    }
+        new_ok = verify_address(s, NULL, &is_local, newaddr, 0);                
+        sender_verify_hosts_callback = save;
         }


       *ss = terminator;
diff -urN exim-3.30.orig/src/version.c exim-3.30/src/version.c
--- exim-3.30.orig/src/version.c    Mon Jun 18 04:03:28 2001
+++ exim-3.30/src/version.c    Fri Jun 29 02:06:43 2001
@@ -10,7 +10,7 @@
 #include "exim.h"



-#define THIS_VERSION "3.30"
+#define THIS_VERSION "3.30-VA-mm1"


/* The header file cnumber.h contains a single line containing the
Exim had issues with error messages on mail rejection that weren't always
very useful.
This patch adds overkill messages that give a lot more info, as well as gives
an explicit reject when the sending server is refusing empty envelope froms.

I'm to blame for all of it :-)

Marc MERLIN <marcsoft@???/marc_bts@???> 2001/06/29


diff -urN exim-3.30.orig/src/verify.c exim-3.30/src/verify.c
--- exim-3.30.orig/src/verify.c    Mon Jun 18 04:03:28 2001
+++ exim-3.30/src/verify.c    Fri Jun 29 01:58:53 2001
@@ -350,38 +350,57 @@
             smtp_write_command(&outblock, FALSE, "HELO %s\r\n",
               primary_hostname) &&
             smtp_read_response(&inblock, US big_buffer, big_buffer_size, '2',
-              sender_verify_callback_timeout) &&
+              sender_verify_callback_timeout))
+        {
             smtp_write_command(&outblock, FALSE, "MAIL FROM:<>\r\n") &&
             smtp_read_response(&inblock, US big_buffer, big_buffer_size, '2',
-              sender_verify_callback_timeout) &&
-            smtp_write_command(&outblock, FALSE, "RCPT TO:<%.1000s>\r\n",
-              addr->orig))
-          {
-          if (smtp_read_response(&inblock, US big_buffer, big_buffer_size, '2',
-              sender_verify_callback_timeout))
-            {
-            done = TRUE;                /* Address accepted */
-            }
-          else if (errno == 0)
-            {
-            sender_verify_callback_error =
-              string_sprintf("response from %s [%s] was %s", host->name,
-                host->address, big_buffer);
-            if (big_buffer[0] == '5')   /* Address rejected */
+              sender_verify_callback_timeout);
+            if (big_buffer[0] == '5')   /* Bonehead server */
               {
+          HDEBUG(1) debug_printf("MAIL FROM: <> rejected. Losers!\n");
+              sender_verify_callback_error =
+              string_sprintf("response from %s [%s] after \"MAIL FROM: <>\" was \"%s\". This does not help fight spam effectively, breaks RFCs, and prevents you from getting bounces so we can't accept mail from you", 
+        host->name, host->address, big_buffer);
               rc = FAIL;
               addr->message =
                 string_sprintf("callback check with host %s failed: %s",
                   host->name, big_buffer);
               done = TRUE;
               }
+        else
+        {    
+        HDEBUG(1) debug_printf("MAIL FROM: <> accepted, trying RCPT TO\n");
+            if (smtp_write_command(&outblock, FALSE, "RCPT TO:<%.1000s>\r\n",
+              addr->orig))
+          if (smtp_read_response(&inblock, US big_buffer, big_buffer_size, '2',
+          sender_verify_callback_timeout))
+        {
+        done = TRUE;                /* Address accepted */
+        }
+          else if (errno == 0)
+        {
+        sender_verify_callback_error =
+          string_sprintf("response from %s [%s] was %s", host->name,
+            host->address, big_buffer);
+        if (big_buffer[0] == '5')   /* Address rejected */
+          {
+          rc = FAIL;
+          addr->message =
+            string_sprintf("callback check with host %s failed: %s",
+              host->name, big_buffer);
+          done = TRUE;
+          }
+        }
+          }
             }
+        else
+        {
+          HDEBUG(1) debug_printf("SMTP callback didn't complete\n");
+        }
+      smtp_write_command(&outblock, FALSE, "QUIT\r\n");
+      close(inblock.sock);
           }


-        smtp_write_command(&outblock, FALSE, "QUIT\r\n");
-        close(inblock.sock);
-        }
-
       /* Failure to connect to any host, or any response other than 2xx or 5xx
       is a temporary error. */


@@ -768,7 +793,7 @@
 called without first calling the first one. The reason for this approach is
 that some SMTP mailers treat any error returned after the data has been
 transmitted as temporary (contrary to RFC821) and keep retrying, even after
-they have been sent a 5xx error at the previous attempt. To get round this,
+they have been sent a 5xx error at the previous attempt. To get around this,
 exim keeps a database of failed messages and their hosts, and if the same bad
 address is received from the same host soon afterwards, it is rejected at the
 preliminary stage (meaning after MAIL FROM for SMTP) in the hope that the far
@@ -875,14 +900,14 @@
   {
   if (rc == DEFER)
     {
-    *errmess = "warning: temporarily unable to resolve sender address: "
+    *errmess = "warning: temporarily unable to resolve envelope sender address: "
       "accepted unverified";
     }
   else
     {
     *errmess = sender_is_local?
-      "warning: unknown local-part in sender address" :
-      "warning: cannot route to sender address";
+      "warning: unknown local-part in envelope sender address" :
+      "warning: cannot route to envelope sender address";
     }
   *errcode = 250;
   sender_ok = SENDER_OK_WARNING;
@@ -956,9 +981,9 @@
     dbfn_close(dbm_file);
     DEBUG(2) debug_printf("%s verification deferred\n", sender_address);
     *errcode = 451;
-    *errmess = "temporarily unable to verify sender address (try again later)";
+    *errmess = "temporarily unable to verify envelope sender address (try again later)";
     if (sender_verify_callback_error != NULL)
-      *errmess = string_sprintf("%s: %s", *errmess, sender_verify_callback_error);
+      *errmess = string_sprintf("%s. An SMTP callback to your mail server yielded the following error: %s", *errmess, sender_verify_callback_error);
     return FALSE;
     }


@@ -998,7 +1023,7 @@
   {
   *errcode = 550;
   *errmess = sender_is_local?
-    "unknown local-part in sender" : "cannot route to sender";
+    "unknown local-part in sender" : "cannot route to envelope sender";
   if (sender_verify_callback_error != NULL)
     *errmess = string_sprintf("%s: %s", *errmess, sender_verify_callback_error);
   reject->rejected_mail_from = TRUE;
@@ -1100,7 +1125,7 @@
         *errcode = 451;
         *errmess = string_sprintf(
           "can't currently verify any sender in the header lines "
-          "(envelope sender is <%.1024s>) - try later", sender_address);
+          "(envelope sender is <%.1024s>). Are you sure your domain in From: and/or Reply-To: resolves from the internet (host -t MX domain) and can be connected back to for delivery of replies? - Failure is temporary, you can try again later", sender_address);
         return FALSE;
         }


@@ -1112,19 +1137,28 @@
       if (headers_checks_fail)
         {
         *errcode = 550;
-        *errmess = (verify_address_parse_error == NULL)?
-          string_sprintf("there is no valid sender in any header line "
-            "(envelope sender is <%.1024s>)", sender_address) :
-          string_sprintf("%s (envelope sender is <%.1024s>)",
-            verify_address_parse_error,
-            sender_address);
+    if (verify_address_parse_error != NULL)
+      {
+          *errmess = string_sprintf("there is no valid sender in any header line: %s (envelope sender is <%.1024s>)",
+            verify_address_parse_error, sender_address);
+      }
+    else if (sender_verify_callback_error != NULL)
+      {
+          *errmess = string_sprintf("there is no valid sender in any header line"
+            " (envelope sender is <%.1024s>). Your mail server returned: %s.", 
+        sender_address, sender_verify_callback_error);
+      }
+    else
+      {
+          *errmess = string_sprintf("there is no valid sender in any header line"
+            " (envelope sender is <%.1024s>). Are you sure your domain in From: and/or Reply-To: resolves from the internet (host -t MX domain) and can be connected back to for delivery of replies?", 
+        sender_address);
+      }
         return FALSE;
         }


-      log_write(3, LOG_REJECT, "warning: from%s <%.1024s>: %s",
-        host_and_ident(" ", NULL), sender_address,
-        (verify_address_parse_error == NULL)?
-          "no valid sender in headers" : verify_address_parse_error);
+      log_write(3, LOG_REJECT, "warning: rejected from%s <%.1024s>: %s",
+        host_and_ident(" ", NULL), sender_address, errmess);
       break;
       }
     }
@@ -1163,20 +1197,31 @@
   {
   *errcode = 451;
   *errmess = string_sprintf(
-    "temporarily unable to verify sender address <%.1024s> (try later)",
+    "temporarily unable to verify envelope sender address <%.1024s> (There was a temporary failure while looking up the hostname in DNS, it was unreachable, or the mail server(s) for that hostname is/are currently not responding and your address couldn't be verified. You may be using an internal hostname that's not reachable from the internet and if so, bounces can't reach you as a result. You should setup an MX record for it, or masquerade your domain to something that does accept mail from the internet. This failure is temporary",
     sender_address);
+  /* Actually, I don't think this would ever get run, but just in case -- Marc */
+  if (sender_verify_callback_error != NULL)
+    *errmess = string_sprintf("%s: %s", *errmess, sender_verify_callback_error);
   }
 else
   {
   *errcode = 550;
-  *errmess = string_sprintf(sender_is_local?
-    "unknown local part in sender <%.1024s>" :
-    "cannot route to sender <%.1024s>",
-    sender_address);
+  if (sender_verify_callback_error != NULL)
+    {
+    *errmess = string_sprintf(sender_is_local?
+      "unknown local part in envelope sender <%.1024s>" :
+      "cannot route to envelope sender <%.1024s> (The envelope sender does not exist according to your mail server when it was asked): %s",
+      sender_address, sender_verify_callback_error);
+    }
+    else
+    {
+    *errmess = string_sprintf(sender_is_local?
+      "unknown local part in envelope sender <%.1024s>" :
+      "cannot route to envelope sender <%.1024s> (The most probable reason is that your domain doesn't resolve from the internet or the mail server(s) it resolves to isn't/aren't reachable. If you are using an internal domain, you should not expose it in your mail headers as it's not reachable from the internet and bounces can't reach you as a result. You should setup an MX record for it, or masquerade your domain to something that does accept mail from the internet)",
+      sender_address);
+    }
   }


-if (sender_verify_callback_error != NULL)
- *errmess = string_sprintf("%s: %s", *errmess, sender_verify_callback_error);

/* Set up the key name and open the hints database. O_RDWR (rather than
O_WRONLY) is needed by Berkeley native DB even when reading only. If the