#ifdef EXPERIMENTAL_DANE
+/* Lookup TLSA record for host/port.
+Return: OK success with dnssec; DANE mode
+ DEFER Do not use this host now, may retry later
+ FAIL_FORCED No TLSA record; DANE not usable
+ FAIL Do not use this connection
+*/
+
int
-tlsa_lookup(const host_item * host, dns_answer * dnsa,
- BOOL dane_required, BOOL * dane)
+tlsa_lookup(const host_item * host, dns_answer * dnsa, BOOL dane_required)
{
/* move this out to host.c given the similarity to dns_lookup() ? */
uschar buffer[300];
switch (dns_lookup(dnsa, buffer, T_TLSA, &fullname))
{
- case DNS_AGAIN:
- return DEFER; /* just defer this TLS'd conn */
-
- default:
- case DNS_FAIL:
- if (dane_required)
- return FAIL;
- break;
-
case DNS_SUCCEED:
if (!dns_is_secure(dnsa))
{
log_write(0, LOG_MAIN, "DANE error: TLSA lookup not DNSSEC");
return DEFER;
}
- *dane = TRUE;
- break;
+ return OK;
+
+ case DNS_AGAIN:
+ return DEFER; /* just defer this TLS'd conn */
+
+ case DNS_NOMATCH:
+ return dane_required ? FAIL : FAIL_FORCED;
+
+ default:
+ case DNS_FAIL:
+ return dane_required ? FAIL : DEFER;
}
-return OK;
}
#endif
static BOOL
smtp_are_same_identities(uschar * message_id, smtp_compare_t * s_compare)
{
-
uschar * message_local_identity,
* current_local_identity,
* new_sender_address;
if (host->dnssec == DS_YES)
{
- if( ( dane_required
- || verify_check_given_host(&ob->hosts_try_dane, host) == OK
- )
- && (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required, &dane)) != OK
- && dane_required /* do not error on only dane-requested */
+ if( dane_required
+ || verify_check_given_host(&ob->hosts_try_dane, host) == OK
)
- {
- set_errno_nohost(addrlist, ERRNO_DNSDEFER,
- string_sprintf("DANE error: tlsa lookup %s",
- rc == DEFER ? "DEFER" : "FAIL"),
- rc, FALSE);
- return rc;
- }
+ switch (rc = tlsa_lookup(host, &tlsa_dnsa, dane_required))
+ {
+ case OK: dane = TRUE; break;
+ case FAIL_FORCED: break;
+ default: set_errno_nohost(addrlist, ERRNO_DNSDEFER,
+ string_sprintf("DANE error: tlsa lookup %s",
+ rc == DEFER ? "DEFER" : "FAIL"),
+ rc, FALSE);
+ return rc;
+ }
}
else if (dane_required)
{
set_errno_nohost(addrlist, ERRNO_DNSDEFER,
string_sprintf("DANE error: %s lookup not DNSSEC", host->name),
FAIL, FALSE);
- return FAIL;
+ return FAIL;
}
if (dane)
if (!smtp_read_response(&inblock, buffer2, sizeof(buffer2), '2',
ob->command_timeout))
{
- if (errno != 0 || buffer2[0] == 0 ||
- (buffer2[0] == '4' && !ob->tls_tempfail_tryclear))
+ if ( errno != 0
+ || buffer2[0] == 0
+ || (buffer2[0] == '4' && !ob->tls_tempfail_tryclear)
+ )
{
Ustrncpy(buffer, buffer2, sizeof(buffer));
goto RESPONSE_FAILED;
if (rc != OK)
{
# ifdef EXPERIMENTAL_DANE
- if (rc == DEFER && dane && !dane_required)
+ if (rc == DEFER && dane)
{
- log_write(0, LOG_MAIN, "DANE attempt failed;"
- " trying CA-root TLS to %s [%s] (not in hosts_require_dane)",
+ log_write(0, LOG_MAIN,
+ "DANE attempt failed; no TLS connection to %s [%s]",
host->name, host->address);
- dane = FALSE;
- goto TLS_NEGOTIATE;
}
# endif
}
else
{
- const uschar * s;
+ const char * s;
if (hosts_retry == hosts_total)
- s = US"retry time not reached for any host%s";
+ s = "retry time not reached for any host%s";
else if (hosts_fail == hosts_total)
- s = US"all host address lookups%s failed permanently";
+ s = "all host address lookups%s failed permanently";
else if (hosts_defer == hosts_total)
- s = US"all host address lookups%s failed temporarily";
+ s = "all host address lookups%s failed temporarily";
else if (hosts_serial == hosts_total)
- s = US"connection limit reached for all hosts%s";
+ s = "connection limit reached for all hosts%s";
else if (hosts_fail+hosts_defer == hosts_total)
- s = US"all host address lookups%s failed";
+ s = "all host address lookups%s failed";
else
- s = US"some host address lookups failed and retry time "
+ s = "some host address lookups failed and retry time "
"not reached for other hosts or connection limit reached%s";
addr->message = string_sprintf(s,