X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fdns.c;h=f492613c4785f0e8141718cd94198ef7469316cb;hb=4a142059750e1767f19f6d42da7c1ce4316107eb;hp=3d047abba11cbbbbe62ff8d60962b81b9830cfe1;hpb=b4161d10ee4c4eb7fd61224d827cc89726e2d8f8;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/dns.c b/src/src/dns.c index 3d047abba..f492613c4 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -46,7 +46,7 @@ Returns: length of returned data, or -1 on error (h_errno set) */ static int -fakens_search(uschar *domain, int type, uschar *answerptr, int size) +fakens_search(const uschar *domain, int type, uschar *answerptr, int size) { int len = Ustrlen(domain); int asize = size; /* Locally modified */ @@ -443,7 +443,7 @@ Returns: bool indicating presence of AD bit */ BOOL -dns_is_secure(dns_answer *dnsa) +dns_is_secure(const dns_answer * dnsa) { #ifdef DISABLE_DNSSEC DEBUG(D_dns) @@ -455,6 +455,13 @@ return h->ad ? TRUE : FALSE; #endif } +static void +dns_set_insecure(dns_answer * dnsa) +{ +HEADER * h = (HEADER *)dnsa->answer; +h->ad = 0; +} + @@ -510,7 +517,7 @@ Returns: the return code */ static int -dns_return(uschar *name, int type, int rc) +dns_return(const uschar * name, int type, int rc) { res_state resp = os_get_dns_resolver_res(); tree_node *node = store_get_perm(sizeof(tree_node) + 290); @@ -549,7 +556,7 @@ Returns: DNS_SUCCEED successful lookup */ int -dns_basic_lookup(dns_answer *dnsa, uschar *name, int type) +dns_basic_lookup(dns_answer *dnsa, const uschar *name, int type) { #ifndef STAND_ALONE int rc = -1; @@ -597,7 +604,7 @@ For SRV records, we omit the initial _smtp._tcp. components at the start. */ if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT) { - uschar *checkname = name; + const uschar *checkname = name; int ovector[3*(EXPAND_MAXN+1)]; if (regex_check_dns_names == NULL) @@ -613,7 +620,7 @@ if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT) while (*checkname++ != '.'); } - if (pcre_exec(regex_check_dns_names, NULL, CS checkname, Ustrlen(checkname), + if (pcre_exec(regex_check_dns_names, NULL, CCS checkname, Ustrlen(checkname), 0, PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int)) < 0) { DEBUG(D_dns) @@ -650,7 +657,7 @@ domains, and interfaces to a fake nameserver for certain special zones. */ if (running_in_test_harness) dnsa->answerlen = fakens_search(name, type, dnsa->answer, MAXPACKET); else - dnsa->answerlen = res_search(CS name, C_IN, type, dnsa->answer, MAXPACKET); + dnsa->answerlen = res_search(CCS name, C_IN, type, dnsa->answer, MAXPACKET); if (dnsa->answerlen > MAXPACKET) { @@ -671,9 +678,9 @@ if (dnsa->answerlen < 0) switch (h_errno) name, dns_text_type(type)); /* Cut this out for various test programs */ - #ifndef STAND_ALONE +#ifndef STAND_ALONE save = deliver_domain; - deliver_domain = name; /* set $domain */ + deliver_domain = string_copy(name); /* set $domain */ rc = match_isinlist(name, &dns_again_means_nonexist, 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL); deliver_domain = save; @@ -686,9 +693,9 @@ if (dnsa->answerlen < 0) switch (h_errno) "DNS_NOMATCH\n", name); return dns_return(name, type, DNS_NOMATCH); - #else /* For stand-alone tests */ +#else /* For stand-alone tests */ return dns_return(name, type, DNS_AGAIN); - #endif +#endif case NO_RECOVERY: DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_RECOVERY\n" @@ -749,10 +756,12 @@ Returns: DNS_SUCCEED successful lookup */ int -dns_lookup(dns_answer *dnsa, uschar *name, int type, uschar **fully_qualified_name) +dns_lookup(dns_answer *dnsa, const uschar *name, int type, + uschar **fully_qualified_name) { int i; -uschar *orig_name = name; +const uschar *orig_name = name; +BOOL secure_so_far = TRUE; /* Loop to follow CNAME chains so far, but no further... */ @@ -807,7 +816,12 @@ for (i = 0; i < 10; i++) /* If any data records of the correct type were found, we are done. */ - if (type_rr.data != NULL) return DNS_SUCCEED; + if (type_rr.data != NULL) + { + if (!secure_so_far) /* mark insecure if any element of CNAME chain was */ + dns_set_insecure(dnsa); + return DNS_SUCCEED; + } /* If there are no data records, we need to re-scan the DNS using the domain given in the CNAME record, which should exist (otherwise we should @@ -816,10 +830,13 @@ for (i = 0; i < 10; i++) if (cname_rr.data == NULL) return DNS_FAIL; datalen = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, - cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256); + cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, sizeof(data)); if (datalen < 0) return DNS_FAIL; name = data; + if (!dns_is_secure(dnsa)) + secure_so_far = FALSE; + DEBUG(D_dns) debug_printf("CNAME found: change to %s\n", name); } /* Loop back to do another lookup */ @@ -858,7 +875,7 @@ Returns: DNS_SUCCEED successful lookup */ int -dns_special_lookup(dns_answer *dnsa, uschar *name, int type, +dns_special_lookup(dns_answer *dnsa, const uschar *name, int type, uschar **fully_qualified_name) { if (type >= 0) return dns_lookup(dnsa, name, type, fully_qualified_name); @@ -872,7 +889,7 @@ root servers. */ if (type == T_ZNS) { - uschar *d = name; + const uschar *d = name; while (d != 0) { int rc = dns_lookup(dnsa, d, T_NS, fully_qualified_name); @@ -905,7 +922,7 @@ if (type == T_CSA) rc = dns_lookup(dnsa, srvname, T_SRV, NULL); if (rc == DNS_SUCCEED || rc == DNS_AGAIN) { - if (rc == DNS_SUCCEED) *fully_qualified_name = name; + if (rc == DNS_SUCCEED) *fully_qualified_name = string_copy(name); return rc; } @@ -1013,7 +1030,7 @@ if (type == T_CSA) /* Extract the numerical SRV fields (p is incremented) */ p = rr->data; GETSHORT(priority, p); - GETSHORT(weight, p); + GETSHORT(weight, p); weight = weight; /* compiler quietening */ GETSHORT(port, p); /* Check the CSA version number */