]> git.netwichtig.de Git - user/henk/code/exim.git/blobdiff - src/src/dns.c
Routers: make retry_use_local_part default true when any non-domain condition is...
[user/henk/code/exim.git] / src / src / dns.c
index 0f0b435de288b9f7ca8bad0421086387f88daafc..e3845978c36de35610681faa3ea8bc58a63f68f4 100644 (file)
@@ -40,7 +40,7 @@ fakens_search(const uschar *domain, int type, uschar *answerptr, int size)
 {
 int len = Ustrlen(domain);
 int asize = size;                  /* Locally modified */
 {
 int len = Ustrlen(domain);
 int asize = size;                  /* Locally modified */
-uschar name[256];
+uschar * name;
 uschar utilname[256];
 uschar *aptr = answerptr;          /* Locally modified */
 struct stat statbuf;
 uschar utilname[256];
 uschar *aptr = answerptr;          /* Locally modified */
 struct stat statbuf;
@@ -48,8 +48,7 @@ struct stat statbuf;
 /* Remove terminating dot. */
 
 if (domain[len - 1] == '.') len--;
 /* Remove terminating dot. */
 
 if (domain[len - 1] == '.') len--;
-Ustrncpy(name, domain, len);
-name[len] = 0;
+name = string_copyn(domain, len);
 
 /* Look for the fakens utility, and if it exists, call it. */
 
 
 /* Look for the fakens utility, and if it exists, call it. */
 
@@ -240,8 +239,7 @@ uschar *pp = buffer;
 if (Ustrchr(string, ':') == NULL)
 #endif
   {
 if (Ustrchr(string, ':') == NULL)
 #endif
   {
-  int i;
-  for (i = 0; i < 4; i++)
+  for (int i = 0; i < 4; i++)
     {
     const uschar *ppp = p;
     while (ppp > string && ppp[-1] != '.') ppp--;
     {
     const uschar *ppp = p;
     while (ppp > string && ppp[-1] != '.') ppp--;
@@ -250,7 +248,7 @@ if (Ustrchr(string, ':') == NULL)
     *pp++ = '.';
     p = ppp - 1;
     }
     *pp++ = '.';
     p = ppp - 1;
     }
-  Ustrcpy(pp, "in-addr.arpa");
+  Ustrcpy(pp, US"in-addr.arpa");
   }
 
 /* Handle IPv6 address; convert to binary so as to fill out any
   }
 
 /* Handle IPv6 address; convert to binary so as to fill out any
@@ -259,7 +257,6 @@ abbreviation in the textual form. */
 #if HAVE_IPV6
 else
   {
 #if HAVE_IPV6
 else
   {
-  int i;
   int v6[4];
   (void)host_aton(string, v6);
 
   int v6[4];
   (void)host_aton(string, v6);
 
@@ -267,13 +264,10 @@ else
   nibble, and look in the ip6.int domain. The domain was subsequently
   changed to ip6.arpa. */
 
   nibble, and look in the ip6.int domain. The domain was subsequently
   changed to ip6.arpa. */
 
-  for (i = 3; i >= 0; i--)
-    {
-    int j;
-    for (j = 0; j < 32; j += 4)
+  for (int i = 3; i >= 0; i--)
+    for (int j = 0; j < 32; j += 4)
       pp += sprintf(CS pp, "%x.", (v6[i] >> j) & 15);
       pp += sprintf(CS pp, "%x.", (v6[i] >> j) & 15);
-    }
-  Ustrcpy(pp, "ip6.arpa.");
+  Ustrcpy(pp, US"ip6.arpa.");
 
   /* Another way of doing IPv6 reverse lookups was proposed in conjunction
   with A6 records. However, it fell out of favour when they did. The
 
   /* Another way of doing IPv6 reverse lookups was proposed in conjunction
   with A6 records. However, it fell out of favour when they did. The
@@ -287,12 +281,12 @@ else
   Ustrcpy(pp, "\\[x");
   pp += 3;
 
   Ustrcpy(pp, "\\[x");
   pp += 3;
 
-  for (i = 0; i < 4; i++)
+  for (int i = 0; i < 4; i++)
     {
     sprintf(pp, "%08X", v6[i]);
     pp += 8;
     }
     {
     sprintf(pp, "%08X", v6[i]);
     pp += 8;
     }
-  Ustrcpy(pp, "].ip6.arpa.");
+  Ustrcpy(pp, US"].ip6.arpa.");
   **************************************************/
 
   }
   **************************************************/
 
   }
@@ -467,11 +461,10 @@ static const uschar *
 dns_extract_auth_name(const dns_answer * dnsa) /* FIXME: const dns_answer */
 {
 dns_scan dnss;
 dns_extract_auth_name(const dns_answer * dnsa) /* FIXME: const dns_answer */
 {
 dns_scan dnss;
-dns_record * rr;
 const HEADER * h = (const HEADER *) dnsa->answer;
 
 if (h->nscount && h->aa)
 const HEADER * h = (const HEADER *) dnsa->answer;
 
 if (h->nscount && h->aa)
-  for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
+  for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY);
        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
     if (rr->type == (h->ancount ? T_NS : T_SOA))
       return string_copy(rr->name);
        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
     if (rr->type == (h->ancount ? T_NS : T_SOA))
       return string_copy(rr->name);
@@ -621,7 +614,7 @@ Returns:     the return code
 static int
 dns_return(const uschar * name, int type, int rc)
 {
 static int
 dns_return(const uschar * name, int type, int rc)
 {
-tree_node *node = store_get_perm(sizeof(tree_node) + 290);
+tree_node *node = store_get_perm(sizeof(tree_node) + 290, TRUE);
 dns_fail_tag(node->name, name, type);
 node->data.val = rc;
 (void)tree_insertnode(&tree_dns_fails, node);
 dns_fail_tag(node->name, name, type);
 node->data.val = rc;
 (void)tree_insertnode(&tree_dns_fails, node);
@@ -716,7 +709,11 @@ lookup, which constructs the names itself, so they should be OK. Besides,
 bitstring labels don't conform to normal name syntax. (But the aren't used any
 more.)
 
 bitstring labels don't conform to normal name syntax. (But the aren't used any
 more.)
 
-For SRV records, we omit the initial _smtp._tcp. components at the start. */
+For SRV records, we omit the initial _smtp._tcp. components at the start.
+The check has been seen to bite on the destination of a SRV lookup that
+initiall hit a CNAME, for which the next name had only two components.
+RFC2782 makes no mention of the possibiility of CNAMES, but the Wikipedia
+article on SRV says they are not a valid configuration. */
 
 #ifndef STAND_ALONE   /* Omit this for stand-alone tests */
 
 
 #ifndef STAND_ALONE   /* Omit this for stand-alone tests */
 
@@ -732,8 +729,8 @@ if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT)
 
   if (type == T_SRV || type == T_TLSA)
     {
 
   if (type == T_SRV || type == T_TLSA)
     {
-    while (*checkname++ != '.');
-    while (*checkname++ != '.');
+    while (*checkname && *checkname++ != '.') ;
+    while (*checkname && *checkname++ != '.') ;
     }
 
   if (pcre_exec(regex_check_dns_names, NULL, CCS checkname, Ustrlen(checkname),
     }
 
   if (pcre_exec(regex_check_dns_names, NULL, CCS checkname, Ustrlen(checkname),
@@ -873,7 +870,6 @@ int
 dns_lookup(dns_answer *dnsa, const uschar *name, int type,
   const uschar **fully_qualified_name)
 {
 dns_lookup(dns_answer *dnsa, const uschar *name, int type,
   const uschar **fully_qualified_name)
 {
-int i;
 const uschar *orig_name = name;
 BOOL secure_so_far = TRUE;
 
 const uschar *orig_name = name;
 BOOL secure_so_far = TRUE;
 
@@ -884,10 +880,10 @@ resolvers hiding behind a config variable. Loop to follow CNAME chains so far,
 but no further...  The testsuite tests the latter case, mostly assuming that the
 former will work. */
 
 but no further...  The testsuite tests the latter case, mostly assuming that the
 former will work. */
 
-for (i = 0; i <= dns_cname_loops; i++)
+for (int i = 0; i <= dns_cname_loops; i++)
   {
   uschar * data;
   {
   uschar * data;
-  dns_record *rr, cname_rr, type_rr;
+  dns_record cname_rr, type_rr;
   dns_scan dnss;
   int rc;
 
   dns_scan dnss;
   int rc;
 
@@ -903,7 +899,7 @@ for (i = 0; i <= dns_cname_loops; i++)
   area in the dnsa block. */
 
   cname_rr.data = type_rr.data = NULL;
   area in the dnsa block. */
 
   cname_rr.data = type_rr.data = NULL;
-  for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
+  for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS);
        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
     if (rr->type == type)
       {
        rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT))
     if (rr->type == type)
       {
@@ -950,7 +946,8 @@ for (i = 0; i <= dns_cname_loops; i++)
   if (!cname_rr.data)
     return DNS_FAIL;
 
   if (!cname_rr.data)
     return DNS_FAIL;
 
-  data = store_get(256);
+  /* DNS data comes from the outside, hence tainted */
+  data = store_get(256, TRUE);
   if (dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
       cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256) < 0)
     return DNS_FAIL;
   if (dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen,
       cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256) < 0)
     return DNS_FAIL;
@@ -1204,7 +1201,8 @@ if (rr->type == T_A)
   uschar *p = US rr->data;
   if (p + 4 <= dnsa_lim)
     {
   uschar *p = US rr->data;
   if (p + 4 <= dnsa_lim)
     {
-    yield = store_get(sizeof(dns_address) + 20);
+    /* the IP is not regarded as tainted */
+    yield = store_get(sizeof(dns_address) + 20, FALSE);
     (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
     yield->next = NULL;
     }
     (void)sprintf(CS yield->address, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
     yield->next = NULL;
     }
@@ -1217,9 +1215,8 @@ else
   if (rr->data + 16 <= dnsa_lim)
     {
     struct in6_addr in6;
   if (rr->data + 16 <= dnsa_lim)
     {
     struct in6_addr in6;
-    int i;
-    for (i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
-    yield = store_get(sizeof(dns_address) + 50);
+    for (int i = 0; i < 16; i++) in6.s6_addr[i] = rr->data[i];
+    yield = store_get(sizeof(dns_address) + 50, FALSE);
     inet_ntop(AF_INET6, &in6, CS yield->address, 50);
     yield->next = NULL;
     }
     inet_ntop(AF_INET6, &in6, CS yield->address, 50);
     yield->next = NULL;
     }