Fix comparison of [IPv6:....] to sender host address for
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 22 Aug 2005 15:28:20 +0000 (15:28 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 22 Aug 2005 15:28:20 +0000 (15:28 +0000)
$sender_rcvhost.

doc/doc-txt/ChangeLog
src/src/host.c

index 81029b4..8eddabf 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.207 2005/08/22 14:01:37 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.208 2005/08/22 15:28:20 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -107,6 +107,11 @@ PH/25 Make $smtp_command_argument available after all SMTP commands. This means
       that in an ACL for RCPT (for example), you can examine exactly what was
       received.
 
+PH/26 Exim was recognizing IPv6 addresses of the form [IPv6:....] in EHLO
+      commands, but it was not correctly comparing the address with the actual
+      client host address. Thus, it would show the EHLO address in Received:
+      header lines when this was not necessary.
+
 
 Exim version 4.52
 -----------------
index 9f3a068..58e18a7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/host.c,v 1.12 2005/08/09 13:31:52 ph10 Exp $ */
+/* $Cambridge: exim/src/src/host.c,v 1.13 2005/08/22 15:28:20 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -435,11 +435,41 @@ if (sender_host_name == NULL)
 else
   {
   int len;
+  BOOL no_helo = FALSE;
+
+  /* Comparing a HELO name to a host name is easy */
+
   if (sender_helo_name == NULL ||
-      strcmpic(sender_host_name, sender_helo_name) == 0 ||
-        (sender_helo_name[0] == '[' &&
-         sender_helo_name[(len=Ustrlen(sender_helo_name))-1] == ']' &&
-         strncmpic(sender_helo_name+1, sender_host_address, len - 2) == 0))
+      strcmpic(sender_host_name, sender_helo_name) == 0)
+    no_helo = TRUE;
+
+  /* If HELO/EHLO was followed by an IP literal, it's much more messy because
+  of two features of IPv6. Firstly, there's the "IPv6:" prefix (Exim is liberal
+  and doesn't require this, for historical reasons). Secondly, an IPv6 address
+  may not be given in canonical form, so we have to canonicize it before
+  comparing. As it happens, the code works for both IPv4 and IPv6. */
+
+  else if (sender_helo_name[0] == '[' &&
+           sender_helo_name[(len=Ustrlen(sender_helo_name))-1] == ']')
+    {
+    uschar *helo_ip;
+    int offset = 1;
+
+    if (strncmpic(sender_helo_name+1, US"IPv6:",5) == 0) offset += 5;
+    helo_ip = string_copyn(sender_helo_name + offset, len - offset - 1);
+
+    if (string_is_ip_address(helo_ip, NULL) != 0)
+      {
+      int x[4];
+      int size;
+      size = host_aton(helo_ip, x);
+      helo_ip = store_get(48);  /* large enough for full IPv6 */
+      (void)host_nmtoa(size, x, -1, helo_ip, ':');
+      if (strcmpic(helo_ip, sender_host_address) == 0) no_helo = TRUE;
+      }
+    }
+
+  if (no_helo)
     {
     sender_fullhost = string_sprintf("%s %s", sender_host_name, address);
     sender_rcvhost = (sender_ident == NULL)?