Filter rDNS returns for bad chars
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 9 Aug 2022 09:57:56 +0000 (10:57 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 9 Aug 2022 09:57:56 +0000 (10:57 +0100)
doc/doc-txt/ChangeLog
src/src/globals.c
src/src/globals.h
src/src/host.c

index b813033c1ae914ca54f82b4381b45cc45b952112..d17370589aa588813f3839b99407f63a8b2d89c4 100644 (file)
@@ -23,6 +23,9 @@ JH/05 Follow symlinks for placing a watch on TLS creds files.  This means
       it would be the dir with the first symlink.  We still do not monitor
       the entire path.
 
+JH/06 Check for bad chars in rDNS for sender_host_name. The OpenBSD (at least)
+      dn_expand() is happy to pass them through.
+
 
 Exim version 4.96
 -----------------
index c95d24b4743aadf90a3aa01497ce9870497ced5a..574ee60a4819330614fd15f87ba9035aaa0e2a35 100644 (file)
@@ -1016,6 +1016,10 @@ uschar *keep_environment       = NULL;
 int     keep_malformed         = 4*24*60*60;    /* 4 days */
 
 uschar *eldap_dn               = NULL;
+const uschar *letter_digit_hyphen_dot =
+    US"abcdefghijklmnopqrstuvwxyz"
+      ".-0123456789"
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 #ifdef EXPERIMENTAL_ESMTP_LIMITS
 uschar *limits_advertise_hosts = US"*";
 #endif
index c9ef5e484ff045b5ebbaece100fa0c697d3a53de..3f3c798b71b5a40d5fd1258e62667b6876abb13e 100644 (file)
@@ -680,6 +680,7 @@ extern uschar *keep_environment;       /* Whitelist for environment variables */
 extern int     keep_malformed;         /* Time to keep malformed messages */
 
 extern uschar *eldap_dn;               /* Where LDAP DNs are left */
+extern const uschar *letter_digit_hyphen_dot; /* Legitimate DNS host name chars */
 #ifdef EXPERIMENTAL_ESMTP_LIMITS
 extern uschar *limits_advertise_hosts; /* for banner/EHLO pipelining */
 #endif
index fed9f4b5f241d24626996fa95b0fd5d9f798358e..b6c2ea0827053c3e8a2daedbd249200e042d94d0 100644 (file)
@@ -84,13 +84,13 @@ random_number(int limit)
 if (limit < 1)
   return 0;
 if (random_seed == 0)
-  {
-  if (f.running_in_test_harness) random_seed = 42; else
+  if (f.running_in_test_harness)
+    random_seed = 42;
+  else
     {
     int p = (int)getpid();
     random_seed = (int)time(NULL) ^ ((p << 16) | p);
     }
-  }
 random_seed = 1103515245 * random_seed + 12345;
 return (unsigned int)(random_seed >> 16) % limit;
 }
@@ -1646,6 +1646,7 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0)))
            rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_PTR)
         {
         uschar * s = store_get(ssize, GET_TAINTED);    /* names are tainted */
+       unsigned slen;
 
         /* If an overlong response was received, the data will have been
         truncated and dn_expand may fail. */
@@ -1658,13 +1659,19 @@ while ((ordername = string_nextinlist(&list, &sep, NULL, 0)))
           break;
           }
 
-        store_release_above(s + Ustrlen(s) + 1);
-        if (!s[0])
+        store_release_above(s + (slen = Ustrlen(s)) + 1);
+        if (!*s)
           {
           HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an "
             "empty name: treated as non-existent host name\n");
           continue;
           }
+       if (Ustrspn(s, letter_digit_hyphen_dot) != slen)
+          {
+          HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an "
+            "illegal name (bad char): treated as non-existent host name\n");
+          continue;
+          }
         if (!sender_host_name) sender_host_name = s;
        else *aptr++ = s;
         while (*s) { *s = tolower(*s); s++; }