git://git.exim.org
/
exim.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Compiler quietening
[exim.git]
/
src
/
src
/
dns.c
diff --git
a/src/src/dns.c
b/src/src/dns.c
index 2aeb5af62ae9c92bdaf820dce2ec67a93b987e1e..f492613c4785f0e8141718cd94198ef7469316cb 100644
(file)
--- a/
src/src/dns.c
+++ b/
src/src/dns.c
@@
-2,7
+2,7
@@
* Exim - an Internet mail transport agent *
*************************************************/
* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 201
3
*/
+/* Copyright (c) University of Cambridge 1995 - 201
4
*/
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for interfacing with the DNS. */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions for interfacing with the DNS. */
@@
-46,7
+46,7
@@
Returns: length of returned data, or -1 on error (h_errno set)
*/
static int
*/
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 */
{
int len = Ustrlen(domain);
int asize = size; /* Locally modified */
@@
-159,12
+159,13
@@
the first time we have been here, and set the resolver options.
Arguments:
qualify_single TRUE to set the RES_DEFNAMES option
search_parents TRUE to set the RES_DNSRCH option
Arguments:
qualify_single TRUE to set the RES_DEFNAMES option
search_parents TRUE to set the RES_DNSRCH option
+ use_dnssec TRUE to set the RES_USE_DNSSEC option
Returns: nothing
*/
void
Returns: nothing
*/
void
-dns_init(BOOL qualify_single, BOOL search_parents)
+dns_init(BOOL qualify_single, BOOL search_parents
, BOOL use_dnssec
)
{
res_state resp = os_get_dns_resolver_res();
{
res_state resp = os_get_dns_resolver_res();
@@
-206,6
+207,8
@@
if (dns_use_edns0 >= 0)
# ifndef RES_USE_EDNS0
# error Have RES_USE_DNSSEC but not RES_USE_EDNS0? Something hinky ...
# endif
# ifndef RES_USE_EDNS0
# error Have RES_USE_DNSSEC but not RES_USE_EDNS0? Something hinky ...
# endif
+if (use_dnssec)
+ resp->options |= RES_USE_DNSSEC;
if (dns_dnssec_ok >= 0)
{
if (dns_use_edns0 == 0 && dns_dnssec_ok != 0)
if (dns_dnssec_ok >= 0)
{
if (dns_use_edns0 == 0 && dns_dnssec_ok != 0)
@@
-228,6
+231,9
@@
if (dns_dnssec_ok >= 0)
DEBUG(D_resolver)
debug_printf("Unable to %sset DNSSEC without resolver support.\n",
dns_dnssec_ok ? "" : "un");
DEBUG(D_resolver)
debug_printf("Unable to %sset DNSSEC without resolver support.\n",
dns_dnssec_ok ? "" : "un");
+if (use_dnssec)
+ DEBUG(D_resolver)
+ debug_printf("Unable to set DNSSEC without resolver support.\n");
# endif
#endif /* DISABLE_DNSSEC */
# endif
#endif /* DISABLE_DNSSEC */
@@
-437,7
+443,7
@@
Returns: bool indicating presence of AD bit
*/
BOOL
*/
BOOL
-dns_is_secure(
dns_answer *
dnsa)
+dns_is_secure(
const dns_answer *
dnsa)
{
#ifdef DISABLE_DNSSEC
DEBUG(D_dns)
{
#ifdef DISABLE_DNSSEC
DEBUG(D_dns)
@@
-449,6
+455,13
@@
return h->ad ? TRUE : FALSE;
#endif
}
#endif
}
+static void
+dns_set_insecure(dns_answer * dnsa)
+{
+HEADER * h = (HEADER *)dnsa->answer;
+h->ad = 0;
+}
+
@@
-504,7
+517,7
@@
Returns: the return code
*/
static int
*/
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);
{
res_state resp = os_get_dns_resolver_res();
tree_node *node = store_get_perm(sizeof(tree_node) + 290);
@@
-543,7
+556,7
@@
Returns: DNS_SUCCEED successful lookup
*/
int
*/
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;
{
#ifndef STAND_ALONE
int rc = -1;
@@
-591,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)
{
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)
int ovector[3*(EXPAND_MAXN+1)];
if (regex_check_dns_names == NULL)
@@
-601,13
+614,13
@@
if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT)
/* For an SRV lookup, skip over the first two components (the service and
protocol names, which both start with an underscore). */
/* For an SRV lookup, skip over the first two components (the service and
protocol names, which both start with an underscore). */
- if (type == T_SRV)
+ if (type == T_SRV
|| type == T_TLSA
)
{
while (*checkname++ != '.');
while (*checkname++ != '.');
}
{
while (*checkname++ != '.');
while (*checkname++ != '.');
}
- if (pcre_exec(regex_check_dns_names, NULL, CS checkname, Ustrlen(checkname),
+ if (pcre_exec(regex_check_dns_names, NULL, C
C
S checkname, Ustrlen(checkname),
0, PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int)) < 0)
{
DEBUG(D_dns)
0, PCRE_EOPT, ovector, sizeof(ovector)/sizeof(int)) < 0)
{
DEBUG(D_dns)
@@
-644,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
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(C
C
S name, C_IN, type, dnsa->answer, MAXPACKET);
if (dnsa->answerlen > MAXPACKET)
{
if (dnsa->answerlen > MAXPACKET)
{
@@
-665,9
+678,9
@@
if (dnsa->answerlen < 0) switch (h_errno)
name, dns_text_type(type));
/* Cut this out for various test programs */
name, dns_text_type(type));
/* Cut this out for various test programs */
-
#ifndef STAND_ALONE
+#ifndef STAND_ALONE
save = deliver_domain;
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;
rc = match_isinlist(name, &dns_again_means_nonexist, 0, NULL, NULL,
MCL_DOMAIN, TRUE, NULL);
deliver_domain = save;
@@
-680,9
+693,9
@@
if (dnsa->answerlen < 0) switch (h_errno)
"DNS_NOMATCH\n", name);
return dns_return(name, type, DNS_NOMATCH);
"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);
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"
case NO_RECOVERY:
DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) gave NO_RECOVERY\n"
@@
-743,10
+756,12
@@
Returns: DNS_SUCCEED successful lookup
*/
int
*/
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;
{
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... */
/* Loop to follow CNAME chains so far, but no further... */
@@
-801,7
+816,12
@@
for (i = 0; i < 10; i++)
/* If any data records of the correct type were found, we are done. */
/* 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
/* 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
@@
-810,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,
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 (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 */
DEBUG(D_dns) debug_printf("CNAME found: change to %s\n", name);
} /* Loop back to do another lookup */
@@
-852,7
+875,7
@@
Returns: DNS_SUCCEED successful lookup
*/
int
*/
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);
uschar **fully_qualified_name)
{
if (type >= 0) return dns_lookup(dnsa, name, type, fully_qualified_name);
@@
-866,7
+889,7
@@
root servers. */
if (type == T_ZNS)
{
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);
while (d != 0)
{
int rc = dns_lookup(dnsa, d, T_NS, fully_qualified_name);
@@
-899,7
+922,7
@@
if (type == T_CSA)
rc = dns_lookup(dnsa, srvname, T_SRV, NULL);
if (rc == DNS_SUCCEED || rc == DNS_AGAIN)
{
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;
}
return rc;
}
@@
-1007,7
+1030,7
@@
if (type == T_CSA)
/* Extract the numerical SRV fields (p is incremented) */
p = rr->data;
GETSHORT(priority, p);
/* 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 */
GETSHORT(port, p);
/* Check the CSA version number */
@@
-1249,4
+1272,6
@@
else
return yield;
}
return yield;
}
+/* vi: aw ai sw=2
+*/
/* End of dns.c */
/* End of dns.c */