X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdns.c;h=e3845978c36de35610681faa3ea8bc58a63f68f4;hb=fc55624df0c1956b7b6b4ae35605a6b95704d022;hp=0f0b435de288b9f7ca8bad0421086387f88daafc;hpb=75c121f07a85b4029458f11b113a4655114af126;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/dns.c b/src/src/dns.c index 0f0b435de..e3845978c 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -40,7 +40,7 @@ fakens_search(const uschar *domain, int type, uschar *answerptr, int size) { 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; @@ -48,8 +48,7 @@ struct stat statbuf; /* 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. */ @@ -240,8 +239,7 @@ uschar *pp = buffer; 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--; @@ -250,7 +248,7 @@ if (Ustrchr(string, ':') == NULL) *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 @@ -259,7 +257,6 @@ abbreviation in the textual form. */ #if HAVE_IPV6 else { - int i; 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. */ - 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); - } - 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 @@ -287,12 +281,12 @@ else 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; } - 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_record * rr; 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); @@ -621,7 +614,7 @@ Returns: the return code 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); @@ -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.) -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 */ @@ -732,8 +729,8 @@ if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT) 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), @@ -873,7 +870,6 @@ int 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; @@ -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. */ -for (i = 0; i <= dns_cname_loops; i++) +for (int i = 0; i <= dns_cname_loops; i++) { uschar * data; - dns_record *rr, cname_rr, type_rr; + dns_record cname_rr, type_rr; 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; - 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) { @@ -950,7 +946,8 @@ for (i = 0; i <= dns_cname_loops; i++) 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; @@ -1204,7 +1201,8 @@ if (rr->type == T_A) 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; } @@ -1217,9 +1215,8 @@ else 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; }