git://git.exim.org
/
users
/
jgh
/
exim.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
c3680ef
)
Propagate dnssec status from dnslookup router through transport to tpda
author
Jeremy Harris
<jgh146exb@wizmail.org>
Mon, 12 May 2014 14:30:47 +0000
(15:30 +0100)
committer
Jeremy Harris
<jgh146exb@wizmail.org>
Mon, 12 May 2014 14:30:47 +0000
(15:30 +0100)
src/src/deliver.c
patch
|
blob
|
history
src/src/host.c
patch
|
blob
|
history
src/src/route.c
patch
|
blob
|
history
src/src/structs.h
patch
|
blob
|
history
src/src/transports/smtp.c
patch
|
blob
|
history
diff --git
a/src/src/deliver.c
b/src/src/deliver.c
index 3334ba2cb3ea98418ed4388ce7856580300c3d37..777ff8dc75ea7c6bab103d73e2a7ae8715482d9b 100644
(file)
--- a/
src/src/deliver.c
+++ b/
src/src/deliver.c
@@
-730,6
+730,7
@@
pointer to a single host item in their host list, for use by the transport. */
tpda_delivery_local_part = NULL;
tpda_delivery_domain = NULL;
tpda_delivery_confirmation = NULL;
tpda_delivery_local_part = NULL;
tpda_delivery_domain = NULL;
tpda_delivery_confirmation = NULL;
+ lookup_dnssec_authenticated = NULL;
#endif
s = reset_point = store_get(size);
#endif
s = reset_point = store_get(size);
@@
-793,7
+794,7
@@
if (addr->transport->info->local)
else
{
else
{
- if (addr->host_used
!= NULL
)
+ if (addr->host_used)
{
s = d_hostlog(s, &size, &ptr, addr);
if (continue_sequence > 1)
{
s = d_hostlog(s, &size, &ptr, addr);
if (continue_sequence > 1)
@@
-806,6
+807,11
@@
else
tpda_delivery_local_part = addr->local_part;
tpda_delivery_domain = addr->domain;
tpda_delivery_confirmation = addr->message;
tpda_delivery_local_part = addr->local_part;
tpda_delivery_domain = addr->domain;
tpda_delivery_confirmation = addr->message;
+
+ /* DNS lookup status */
+ lookup_dnssec_authenticated = addr->host_used->dnssec==DS_YES ? US"yes"
+ : addr->host_used->dnssec==DS_NO ? US"no"
+ : NULL;
#endif
}
#endif
}
@@
-3019,7
+3025,7
@@
while (!done)
}
while (*ptr++);
break;
}
while (*ptr++);
break;
- #endif
+ #endif
/*SUPPORT_TLS*/
case 'C': /* client authenticator information */
switch (*ptr++)
case 'C': /* client authenticator information */
switch (*ptr++)
@@
-3039,7
+3045,7
@@
while (!done)
#ifdef EXPERIMENTAL_PRDR
case 'P':
#ifdef EXPERIMENTAL_PRDR
case 'P':
-
addr->flags |= af_prdr_used; break;
+ addr->flags |= af_prdr_used; break;
#endif
case 'A':
#endif
case 'A':
@@
-3066,7
+3072,7
@@
while (!done)
addr->user_message = (*ptr)? string_copy(ptr) : NULL;
while(*ptr++);
addr->user_message = (*ptr)? string_copy(ptr) : NULL;
while(*ptr++);
- /* Always two strings for host information, followed by the port number */
+ /* Always two strings for host information, followed by the port number
and DNSSEC mark
*/
if (*ptr != 0)
{
if (*ptr != 0)
{
@@
-3077,6
+3083,10
@@
while (!done)
while(*ptr++);
memcpy(&(h->port), ptr, sizeof(h->port));
ptr += sizeof(h->port);
while(*ptr++);
memcpy(&(h->port), ptr, sizeof(h->port));
ptr += sizeof(h->port);
+ h->dnssec = *ptr == '2' ? DS_YES
+ : *ptr == '1' ? DS_NO
+ : DS_UNK;
+ ptr++;
addr->host_used = h;
}
else ptr++;
addr->host_used = h;
}
else ptr++;
@@
-4104,11
+4114,9
@@
for (delivery_count = 0; addr_remote != NULL; delivery_count++)
retry_item *r;
/* The certificate verification status goes into the flags */
retry_item *r;
/* The certificate verification status goes into the flags */
-
if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
/* Use an X item only if there's something to send */
if (tls_out.certificate_verified) setflag(addr, af_cert_verified);
/* Use an X item only if there's something to send */
-
#ifdef SUPPORT_TLS
if (addr->cipher)
{
#ifdef SUPPORT_TLS
if (addr->cipher)
{
@@
-4179,7
+4187,8
@@
for (delivery_count = 0; addr_remote != NULL; delivery_count++)
}
#ifdef EXPERIMENTAL_PRDR
}
#ifdef EXPERIMENTAL_PRDR
- if (addr->flags & af_prdr_used) rmt_dlv_checked_write(fd, "P", 1);
+ if (addr->flags & af_prdr_used)
+ rmt_dlv_checked_write(fd, "P", 1);
#endif
/* Retry information: for most success cases this will be null. */
#endif
/* Retry information: for most success cases this will be null. */
@@
-4233,6
+4242,11
@@
for (delivery_count = 0; addr_remote != NULL; delivery_count++)
while(*ptr++);
memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
ptr += sizeof(addr->host_used->port);
while(*ptr++);
memcpy(ptr, &(addr->host_used->port), sizeof(addr->host_used->port));
ptr += sizeof(addr->host_used->port);
+
+ /* DNS lookup status */
+ *ptr++ = addr->host_used->dnssec==DS_YES ? '2'
+ : addr->host_used->dnssec==DS_NO ? '1' : '0';
+
}
rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
}
}
rmt_dlv_checked_write(fd, big_buffer, ptr - big_buffer);
}
diff --git
a/src/src/host.c
b/src/src/host.c
index a1db7717e5624fe5315dd716d1de9e4eccc4abb0..a59c4381b9c45160360a32af25b91baa99e9ef3c 100644
(file)
--- a/
src/src/host.c
+++ b/
src/src/host.c
@@
-2065,6
+2065,7
@@
for (i = 1; i <= times;
host->port = PORT_NONE;
host->status = hstatus_unknown;
host->why = hwhy_unknown;
host->port = PORT_NONE;
host->status = hstatus_unknown;
host->why = hwhy_unknown;
+ host->dnssec = DS_UNK;
last = host;
}
last = host;
}
@@
-2080,6
+2081,7
@@
for (i = 1; i <= times;
next->port = PORT_NONE;
next->status = hstatus_unknown;
next->why = hwhy_unknown;
next->port = PORT_NONE;
next->status = hstatus_unknown;
next->why = hwhy_unknown;
+ next->dnssec = DS_UNK;
next->last_try = 0;
next->next = last->next;
last->next = next;
next->last_try = 0;
next->next = last->next;
last->next = next;
@@
-2475,10
+2477,12
@@
int ind_type = 0;
int yield;
dns_answer dnsa;
dns_scan dnss;
int yield;
dns_answer dnsa;
dns_scan dnss;
-BOOL dnssec_request = match_isinlist(host->name, &dnssec_request_domains,
- 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains,
0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
BOOL dnssec_require = match_isinlist(host->name, &dnssec_require_domains,
0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+BOOL dnssec_request = dnssec_require
+ || match_isinlist(host->name, &dnssec_request_domains,
+ 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
+dnssec_status_t dnssec;
/* Set the default fully qualified name to the incoming name, initialize the
resolver if necessary, set up the relevant options, and initialize the flag
/* Set the default fully qualified name to the incoming name, initialize the
resolver if necessary, set up the relevant options, and initialize the flag
@@
-2487,7
+2491,7
@@
that gets set for DNS syntax check errors. */
if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
(whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
(whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
- dnssec_request
|| dnssec_require
+ dnssec_request
);
host_find_failed_syntax = FALSE;
);
host_find_failed_syntax = FALSE;
@@
-2509,9
+2513,17
@@
if ((whichrrs & HOST_FIND_BY_SRV) != 0)
the input name, pass back the new original domain, without the prepended
magic. */
the input name, pass back the new original domain, without the prepended
magic. */
+ dnssec = DS_UNK;
+ lookup_dnssec_authenticated = NULL;
rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name);
rc = dns_lookup(&dnsa, buffer, ind_type, &temp_fully_qualified_name);
- lookup_dnssec_authenticated = !dnssec_request ? NULL
- : dns_is_secure(&dnsa) ? US"yes" : US"no";
+
+ if (dnssec_request)
+ {
+ if (dns_is_secure(&dnsa))
+ { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ else
+ { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ }
if (temp_fully_qualified_name != buffer && fully_qualified_name != NULL)
*fully_qualified_name = temp_fully_qualified_name + prefix_length;
if (temp_fully_qualified_name != buffer && fully_qualified_name != NULL)
*fully_qualified_name = temp_fully_qualified_name + prefix_length;
@@
-2547,9
+2559,17
@@
listed as one for which we continue. */
if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
{
ind_type = T_MX;
if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0)
{
ind_type = T_MX;
+ dnssec = DS_UNK;
+ lookup_dnssec_authenticated = NULL;
rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name);
rc = dns_lookup(&dnsa, host->name, ind_type, fully_qualified_name);
- lookup_dnssec_authenticated = !dnssec_request ? NULL
- : dns_is_secure(&dnsa) ? US"yes" : US"no";
+
+ if (dnssec_request)
+ {
+ if (dns_is_secure(&dnsa))
+ { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ else
+ { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ }
switch (rc)
{
switch (rc)
{
@@
-2593,9
+2613,19
@@
if (rc != DNS_SUCCEED)
last = host; /* End of local chainlet */
host->mx = MX_NONE;
host->port = PORT_NONE;
last = host; /* End of local chainlet */
host->mx = MX_NONE;
host->port = PORT_NONE;
+ dnssec = DS_UNK;
+ lookup_dnssec_authenticated = NULL;
rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE,
fully_qualified_name, dnssec_request, dnssec_require);
rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE,
fully_qualified_name, dnssec_request, dnssec_require);
+ if (dnssec_request)
+ {
+ if (dns_is_secure(&dnsa))
+ { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
+ else
+ { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
+ }
+
/* If one or more address records have been found, check that none of them
are local. Since we know the host items all have their IP addresses
inserted, host_scan_for_local_hosts() can only return HOST_FOUND or
/* If one or more address records have been found, check that none of them
are local. Since we know the host items all have their IP addresses
inserted, host_scan_for_local_hosts() can only return HOST_FOUND or
@@
-2665,9
+2695,7
@@
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
the same precedence to sort randomly. */
if (ind_type == T_MX)
the same precedence to sort randomly. */
if (ind_type == T_MX)
- {
weight = random_number(500);
weight = random_number(500);
- }
/* SRV records are specified with a port and a weight. The weight is used
in a special algorithm. However, to start with, we just use it to order the
/* SRV records are specified with a port and a weight. The weight is used
in a special algorithm. However, to start with, we just use it to order the
@@
-2731,6
+2759,7
@@
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
host->sort_key = precedence * 1000 + weight;
host->status = hstatus_unknown;
host->why = hwhy_unknown;
host->sort_key = precedence * 1000 + weight;
host->status = hstatus_unknown;
host->why = hwhy_unknown;
+ host->dnssec = dnssec;
last = host;
}
last = host;
}
@@
-2747,6
+2776,7
@@
for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
next->sort_key = sort_key;
next->status = hstatus_unknown;
next->why = hwhy_unknown;
next->sort_key = sort_key;
next->status = hstatus_unknown;
next->why = hwhy_unknown;
+ next->dnssec = dnssec;
next->last_try = 0;
/* Handle the case when we have to insert before the first item. */
next->last_try = 0;
/* Handle the case when we have to insert before the first item. */
diff --git
a/src/src/route.c
b/src/src/route.c
index 271175e4bee12f076ad64c9b4ed10539ad37615c..0116e12af484df76ad439f28e85d0fde2c561415 100644
(file)
--- a/
src/src/route.c
+++ b/
src/src/route.c
@@
-1941,6
+1941,7
@@
DEBUG(D_route)
if (h->mx >= 0) debug_printf(" MX=%d", h->mx);
else if (h->mx != MX_NONE) debug_printf(" rgroup=%d", h->mx);
if (h->port != PORT_NONE) debug_printf(" port=%d", h->port);
if (h->mx >= 0) debug_printf(" MX=%d", h->mx);
else if (h->mx != MX_NONE) debug_printf(" rgroup=%d", h->mx);
if (h->port != PORT_NONE) debug_printf(" port=%d", h->port);
+ /* if (h->dnssec != DS_UNK) debug_printf(" dnssec=%s", h->dnssec==DS_YES ? "yes" : "no"); */
debug_printf("\n");
}
}
debug_printf("\n");
}
}
diff --git
a/src/src/structs.h
b/src/src/structs.h
index aba579f892892764a7a2b1a8333c83a0f35590c7..989653e30c60494691aa4618ea9f456b7d4bb9a8 100644
(file)
--- a/
src/src/structs.h
+++ b/
src/src/structs.h
@@
-55,6
+55,8
@@
typedef struct ugid_block {
but also used when checking lists of hosts and when transporting. Looking up
host addresses is done using this structure. */
but also used when checking lists of hosts and when transporting. Looking up
host addresses is done using this structure. */
+typedef enum {DS_UNK=-1, DS_NO, DS_YES} dnssec_status_t;
+
typedef struct host_item {
struct host_item *next;
uschar *name; /* Host name */
typedef struct host_item {
struct host_item *next;
uschar *name; /* Host name */
@@
-65,6
+67,7
@@
typedef struct host_item {
int status; /* Usable, unusable, or unknown */
int why; /* Why host is unusable */
int last_try; /* Time of last try if known */
int status; /* Usable, unusable, or unknown */
int why; /* Why host is unusable */
int last_try; /* Time of last try if known */
+ dnssec_status_t dnssec;
} host_item;
/* Chain of rewrite rules, read from the rewrite config, or parsed from the
} host_item;
/* Chain of rewrite rules, read from the rewrite config, or parsed from the
diff --git
a/src/src/transports/smtp.c
b/src/src/transports/smtp.c
index fd894862072f0dd0512a958e919b67189bdbce93..020f76cac1305f5d5da2bb7b94ab993ec32b04c5 100644
(file)
--- a/
src/src/transports/smtp.c
+++ b/
src/src/transports/smtp.c
@@
-2919,6
+2919,9
@@
for (cutoff_retry = 0; expired &&
deliver_host = host->name;
deliver_host_address = host->address;
deliver_host = host->name;
deliver_host_address = host->address;
+ lookup_dnssec_authenticated = host->dnssec == DS_YES ? US"yes"
+ : host->dnssec == DS_NO ? US"no"
+ : US"";
/* Set up a string for adding to the retry key if the port number is not
the standard SMTP port. A host may have its own port setting that overrides
/* Set up a string for adding to the retry key if the port number is not
the standard SMTP port. A host may have its own port setting that overrides