Merge 4.80.1 security fix in.
[exim.git] / src / src / host.c
index 039f58fb219576862ae7f7602d06c8bb4bdc70c5..785eea412bd33faae15a86278fdf72b29ce0b46d 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/host.c,v 1.26 2006/10/09 14:36:25 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2006 */
+/* Copyright (c) University of Cambridge 1995 - 2012 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
@@ -70,6 +68,9 @@ sprintf(addr, "%d.%d.%d.%d",
 very good for the uses to which it is put. When running the regression tests,
 start with a fixed seed.
 
+If you need better, see vaguely_random_number() which is potentially stronger,
+if a crypto library is available, but might end up just calling this instead.
+
 Arguments:
   limit:    one more than the largest number required
 
@@ -79,6 +80,8 @@ Returns:    a pseudo-random number in the range 0 to limit-1
 int
 random_number(int limit)
 {
+if (limit < 1)
+  return 0;
 if (random_seed == 0)
   {
   if (running_in_test_harness) random_seed = 42; else
@@ -1174,10 +1177,10 @@ host_is_tls_on_connect_port(int port)
 {
 int sep = 0;
 uschar buffer[32];
-uschar *list = tls_on_connect_ports;
+uschar *list = tls_in.on_connect_ports;
 uschar *s;
 
-if (tls_on_connect) return TRUE;
+if (tls_in.on_connect) return TRUE;
 
 while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
   {
@@ -1502,7 +1505,7 @@ if (hosts == NULL)
 treat this as non-existent. In some operating systems, this is returned as an
 empty string; in others as a single dot. */
 
-if (hosts->h_name[0] == 0 || hosts->h_name[0] == '.')
+if (hosts->h_name == NULL || hosts->h_name[0] == 0 || hosts->h_name[0] == '.')
   {
   HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an empty name: "
     "treated as non-existent host name\n");
@@ -1594,7 +1597,7 @@ dns_record *rr;
 dns_answer dnsa;
 dns_scan dnss;
 
-host_lookup_deferred = host_lookup_failed = FALSE;
+sender_host_dnssec = host_lookup_deferred = host_lookup_failed = FALSE;
 
 HDEBUG(D_host_lookup)
   debug_printf("looking up host name for %s\n", sender_host_address);
@@ -1636,6 +1639,13 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))
       int count = 0;
       int old_pool = store_pool;
 
+      /* Ideally we'd check DNSSEC both forward and reverse, but we use the
+      gethost* routines for forward, so can't do that unless/until we rewrite. */
+      sender_host_dnssec = dns_is_secure(&dnsa);
+      DEBUG(D_dns)
+        debug_printf("Reverse DNS security status: %s\n",
+            sender_host_dnssec ? "DNSSEC verified (AD)" : "unverified");
+
       store_pool = POOL_PERM;        /* Save names in permanent storage */
 
       for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
@@ -1792,6 +1802,7 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++)
     {
     HDEBUG(D_host_lookup) debug_printf("temporary error for host name lookup\n");
     host_lookup_deferred = TRUE;
+    sender_host_name = NULL;
     return DEFER;
     }
   else