X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Ftls-openssl.c;h=4de3cad513428b1951e160b1b0a56d057d7fd257;hb=723fe533c452eb258a5a7e0b808d714bbbc7cb01;hp=b77ed32e1c99cbb513a992e99692a977e7880e56;hpb=4f59c424dabfc69b7313d84685df68dd406d6ff9;p=exim.git diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index b77ed32e1..4de3cad51 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -120,7 +120,7 @@ typedef struct tls_ext_ctx_cb { #ifdef EXPERIMENTAL_CERTNAMES uschar * verify_cert_hostnames; #endif -#ifdef EXPERIMENTAL_TPDA +#ifdef EXPERIMENTAL_EVENT uschar * event_action; #endif } tls_ext_ctx_cb; @@ -167,27 +167,28 @@ Returns: OK/DEFER/FAIL static int tls_error(uschar *prefix, host_item *host, uschar *msg) { -if (msg == NULL) +if (!msg) { ERR_error_string(ERR_get_error(), ssl_errstring); msg = (uschar *)ssl_errstring; } -if (host == NULL) +if (host) + { + log_write(0, LOG_MAIN, "H=%s [%s] TLS error on connection (%s): %s", + host->name, host->address, prefix, msg); + return FAIL; + } +else { uschar *conn_info = smtp_get_connection_info(); if (Ustrncmp(conn_info, US"SMTP ", 5) == 0) conn_info += 5; + /* I'd like to get separated H= here, but too hard for now */ log_write(0, LOG_MAIN, "TLS error on %s (%s): %s", conn_info, prefix, msg); return DEFER; } -else - { - log_write(0, LOG_MAIN, "TLS error on connection to %s [%s] (%s): %s", - host->name, host->address, prefix, msg); - return FAIL; - } } @@ -286,6 +287,7 @@ verify_callback(int state, X509_STORE_CTX *x509ctx, { X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx); int depth = X509_STORE_CTX_get_error_depth(x509ctx); +uschar * ev; static uschar txt[256]; X509_NAME_oneline(X509_get_subject_name(cert), CS txt, sizeof(txt)); @@ -321,12 +323,12 @@ else if (depth != 0) ERR_clear_error(); } #endif -#ifdef EXPERIMENTAL_TPDA - if (tlsp == &tls_out && client_static_cbinfo->event_action) +#ifdef EXPERIMENTAL_EVENT + ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action; + if (ev) { tlsp->peercert = X509_dup(cert); - if (tpda_raise_event(client_static_cbinfo->event_action, - US"tls:cert", string_sprintf("%d", depth)) == DEFER) + if (event_raise(ev, US"tls:cert", string_sprintf("%d", depth)) == DEFER) { log_write(0, LOG_MAIN, "SSL verify denied by event-action: " "depth=%d cert=%s", depth, txt); @@ -390,11 +392,10 @@ else # endif #endif /*EXPERIMENTAL_CERTNAMES*/ -#ifdef EXPERIMENTAL_TPDA - if (tlsp == &tls_out) - { - if (tpda_raise_event(client_static_cbinfo->event_action, - US"tls:cert", US"0") == DEFER) +#ifdef EXPERIMENTAL_EVENT + ev = tlsp == &tls_out ? client_static_cbinfo->event_action : event_action; + if (ev) + if (event_raise(ev, US"tls:cert", US"0") == DEFER) { log_write(0, LOG_MAIN, "SSL verify denied by event-action: " "depth=0 cert=%s", txt); @@ -402,7 +403,6 @@ else *calledp = TRUE; return 0; /* reject */ } - } #endif DEBUG(D_tls) debug_printf("SSL%s verify ok: depth=0 SN=%s\n", @@ -437,7 +437,7 @@ verify_callback_client_dane(int state, X509_STORE_CTX * x509ctx) { X509 * cert = X509_STORE_CTX_get_current_cert(x509ctx); static uschar txt[256]; -#ifdef EXPERIMENTAL_TPDA +#ifdef EXPERIMENTAL_EVENT int depth = X509_STORE_CTX_get_error_depth(x509ctx); #endif @@ -447,10 +447,10 @@ DEBUG(D_tls) debug_printf("verify_callback_client_dane: %s\n", txt); tls_out.peerdn = txt; tls_out.peercert = X509_dup(cert); -#ifdef EXPERIMENTAL_TPDA +#ifdef EXPERIMENTAL_EVENT if (client_static_cbinfo->event_action) { - if (tpda_raise_event(client_static_cbinfo->event_action, + if (event_raise(client_static_cbinfo->event_action, US"tls:cert", string_sprintf("%d", depth)) == DEFER) { log_write(0, LOG_MAIN, "DANE verify denied by event-action: " @@ -1139,7 +1139,7 @@ else cbinfo->dhparam = dhparam; cbinfo->server_cipher_list = NULL; cbinfo->host = host; -#ifdef EXPERIMENTAL_TPDA +#ifdef EXPERIMENTAL_EVENT cbinfo->event_action = NULL; #endif @@ -1377,7 +1377,16 @@ if (expcerts != NULL && *expcerts != '\0') return tls_error(US"SSL_CTX_load_verify_locations", host, NULL); /* Load the list of CAs for which we will accept certs, for sending - to the client. XXX only for file source, not dir? */ + to the client. This is only for the one-file tls_verify_certificates + variant. + If a list isn't loaded into the server, but + some verify locations are set, the server end appears to make + a wildcard reqest for client certs. + Meanwhile, the client library as deafult behaviour *ignores* the list + we send over the wire - see man SSL_CTX_set_client_cert_cb. + Because of this, and that the dir variant is likely only used for + the public-CA bundle (not for a private CA), not worth fixing. + */ if (file != NULL) { STACK_OF(X509_NAME) * names = SSL_load_client_CA_file(CS file); @@ -1702,22 +1711,23 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); uint8_t usage, selector, mtype; const char * mdname; - found++; usage = *p++; + + /* Only DANE-TA(2) and DANE-EE(3) are supported */ + if (usage != 2 && usage != 3) continue; + selector = *p++; mtype = *p++; switch (mtype) { - default: - log_write(0, LOG_MAIN, - "DANE error: TLSA record w/bad mtype 0x%x", mtype); - return FAIL; - case 0: mdname = NULL; break; - case 1: mdname = "sha256"; break; - case 2: mdname = "sha512"; break; + default: continue; /* Only match-types 0, 1, 2 are supported */ + case 0: mdname = NULL; break; + case 1: mdname = "sha256"; break; + case 2: mdname = "sha512"; break; } + found++; switch (DANESSL_add_tlsa(ssl, usage, selector, mdname, p, rr->size - 3)) { default: @@ -1732,7 +1742,7 @@ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); if (found) return OK; -log_write(0, LOG_MAIN, "DANE error: No TLSA records"); +log_write(0, LOG_MAIN, "DANE error: No usable TLSA records"); return FAIL; } #endif /*EXPERIMENTAL_DANE*/ @@ -1924,8 +1934,8 @@ if (request_ocsp) } #endif -#ifdef EXPERIMENTAL_TPDA -client_static_cbinfo->event_action = tb->tpda_event_action; +#ifdef EXPERIMENTAL_EVENT +client_static_cbinfo->event_action = tb->event_action; #endif /* There doesn't seem to be a built-in timeout on connection. */