X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/8e9770348dc4173ab83657ee023c22f479ebb712..HEAD:/src/src/tls-gnu.c diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c index dd70e73e1..7963e2c97 100644 --- a/src/src/tls-gnu.c +++ b/src/src/tls-gnu.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) The Exim Maintainers 2020 - 2022 */ +/* Copyright (c) The Exim Maintainers 2020 - 2024 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* Copyright (c) Phil Pennock 2012 */ /* See the file NOTICE for conditions of use and distribution. */ @@ -1016,7 +1016,7 @@ now = 1; if ( (rc = gnutls_x509_crt_set_version(cert, 3)) || (rc = gnutls_x509_crt_set_serial(cert, &now, sizeof(now))) || (rc = gnutls_x509_crt_set_activation_time(cert, now = time(NULL))) - || (rc = gnutls_x509_crt_set_expiration_time(cert, (long)2 * 60 * 60)) /* 2 hour */ + || (rc = gnutls_x509_crt_set_expiration_time(cert, now + (long)2 * 60 * 60)) /* 2 hour */ || (rc = gnutls_x509_crt_set_key(cert, pkey)) || (rc = gnutls_x509_crt_set_dn_by_oid(cert, @@ -1185,6 +1185,8 @@ tls_server_servercerts_cb(gnutls_session_t session, unsigned int htype, # ifdef notdef_crashes /*XXX crashes */ return gnutls_ext_raw_parse(NULL, tls_server_servercerts_ext, msg, 0); +# else +return GNUTLS_E_SUCCESS; # endif } #endif /*SUPPORT_GNUTLS_EXT_RAW_PARSE*/ @@ -1233,7 +1235,7 @@ switch (htype) return tls_server_ticket_cb(sess, htype, when, incoming, msg); # endif default: - return 0; + return GNUTLS_E_SUCCESS; } } #endif @@ -1628,7 +1630,8 @@ and there seems little downside. */ static void tls_client_creds_init(transport_instance * t, BOOL watch) { -smtp_transport_options_block * ob = t->options_block; +smtp_transport_options_block * ob = t->drinst.options_block; +const uschar * trname = t->drinst.name; exim_gnutls_state_st tpt_dummy_state; host_item * dummy_host = (host_item *)1; uschar * dummy_errstr; @@ -1661,7 +1664,7 @@ if ( opt_set_and_noexpand(ob->tls_certificate) const uschar * pkey = ob->tls_privatekey; DEBUG(D_tls) - debug_printf("TLS: preloading client certs for transport '%s'\n", t->name); + debug_printf("TLS: preloading client certs for transport '%s'\n", trname); /* The state->lib_state.x509_cred is used for the certs load, and is the sole structure element used. So we can set up a dummy. The hoat arg only @@ -1675,7 +1678,7 @@ if ( opt_set_and_noexpand(ob->tls_certificate) } else DEBUG(D_tls) - debug_printf("TLS: not preloading client certs, for transport '%s'\n", t->name); + debug_printf("TLS: not preloading client certs, for transport '%s'\n", trname); /* If tls_verify_certificates is non-empty and has no $, load CAs. If none was configured and we can't handle "system", treat as empty. */ @@ -1689,7 +1692,7 @@ if ( opt_set_and_noexpand(ob->tls_verify_certificates) if (!watch || tls_set_watch(ob->tls_verify_certificates, FALSE)) { DEBUG(D_tls) - debug_printf("TLS: preloading CA bundle for transport '%s'\n", t->name); + debug_printf("TLS: preloading CA bundle for transport '%s'\n", trname); if (creds_load_cabundle(&tpt_dummy_state, ob->tls_verify_certificates, dummy_host, &dummy_errstr) != OK) return; @@ -1699,19 +1702,19 @@ if ( opt_set_and_noexpand(ob->tls_verify_certificates) { if (!watch || tls_set_watch(ob->tls_crl, FALSE)) { - DEBUG(D_tls) debug_printf("TLS: preloading CRL for transport '%s'\n", t->name); + DEBUG(D_tls) debug_printf("TLS: preloading CRL for transport '%s'\n", trname); if (creds_load_crl(&tpt_dummy_state, ob->tls_crl, &dummy_errstr) != OK) return; ob->tls_preload.crl = TRUE; } } else - DEBUG(D_tls) debug_printf("TLS: not preloading CRL, for transport '%s'\n", t->name); + DEBUG(D_tls) debug_printf("TLS: not preloading CRL, for transport '%s'\n", trname); } } else DEBUG(D_tls) - debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", t->name); + debug_printf("TLS: not preloading CA bundle, for transport '%s'\n", trname); /* We do not preload tls_require_ciphers to to the transport as it implicitly depends on DANE or plain usage. */ @@ -1740,7 +1743,7 @@ state_server.lib_state = null_tls_preload; static void tls_client_creds_invalidate(transport_instance * t) { -smtp_transport_options_block * ob = t->options_block; +smtp_transport_options_block * ob = t->drinst.options_block; if (ob->tls_preload.x509_cred) gnutls_certificate_free_credentials(ob->tls_preload.x509_cred); ob->tls_preload = null_tls_preload; @@ -2312,8 +2315,9 @@ old_pool = store_pool; if (*s) s++; /* now on _ between groups */ while ((c = *s)) { - for (*++s && ++s; (c = *s) && c != ')'; s++) - g = string_catn(g, c == '-' ? US"_" : s, 1); + if (*++s) + for (++s; (c = *s) && c != ')'; s++) + g = string_catn(g, c == '-' ? US"_" : s, 1); /* now on ) closing group */ if ((c = *s) && *++s == '-') g = string_catn(g, US"__", 2); /* now on _ between groups */ @@ -2851,7 +2855,7 @@ static int tls_server_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when, unsigned incoming, const gnutls_datum_t * msg) { -DEBUG(D_tls) debug_printf("newticket cb\n"); +DEBUG(D_tls) debug_printf("newticket cb (on server)\n"); tls_in.resumption |= RESUME_CLIENT_REQUESTED; return 0; } @@ -2888,9 +2892,12 @@ tls_server_resume_posthandshake(exim_gnutls_state_st * state) { if (gnutls_session_resumption_requested(state->session)) { - /* This tells us the client sent a full ticket. We use a + /* This tells us the client sent a full (?) ticket. We use a callback on session-ticket request, elsewhere, to tell - if a client asked for a ticket. */ + if a client asked for a ticket. + XXX As of GnuTLS 3.0.1 it seems to be returning true even for + a pure ticket-req (a zero-length Session Ticket extension + in the Client Hello, for 1.2) which mucks up our logic. */ tls_in.resumption |= RESUME_CLIENT_SUGGESTED; DEBUG(D_tls) debug_printf("client requested resumption\n"); @@ -3000,7 +3007,7 @@ exim_gnutls_state_st * state = NULL; if (tls_in.active.sock >= 0) { tls_error(US"STARTTLS received after TLS started", US "", NULL, errstr); - smtp_printf("554 Already in TLS\r\n", FALSE); + smtp_printf("554 Already in TLS\r\n", SP_NO_MORE); return FAIL; } @@ -3079,7 +3086,7 @@ mode, the fflush() happens when smtp_getc() is called. */ if (!state->tlsp->on_connect) { - smtp_printf("220 TLS go ahead\r\n", FALSE); + smtp_printf("220 TLS go ahead\r\n", SP_NO_MORE); fflush(smtp_out); } @@ -3319,7 +3326,8 @@ tls_retrieve_session(tls_support * tlsp, gnutls_session_t session, tlsp->resumption = RESUME_SUPPORTED; if (!conn_args->have_lbserver) - { DEBUG(D_tls) debug_printf("resumption not supported on continued-connection\n"); } + { DEBUG(D_tls) debug_printf( + "resumption not supported: no LB detection done (continued-conn?)\n"); } else if (verify_check_given_host(CUSS &ob->tls_resumption_hosts, conn_args->host) == OK) { dbdata_tls_session * dt; @@ -3347,6 +3355,7 @@ else if (verify_check_given_host(CUSS &ob->tls_resumption_hosts, conn_args->host dbfn_close(dbm_file); } } +else DEBUG(D_tls) debug_printf("no resumption for this host\n"); } @@ -3374,22 +3383,26 @@ if (gnutls_session_get_flags(session) & GNUTLS_SFLAGS_SESSION_TICKET) int dlen = sizeof(dbdata_tls_session) + tkt.size; dbdata_tls_session * dt = store_get(dlen, GET_TAINTED); - DEBUG(D_tls) debug_printf("session data size %u\n", (unsigned)tkt.size); + DEBUG(D_tls) debug_printf(" session data size %u\n", (unsigned)tkt.size); memcpy(dt->session, tkt.data, tkt.size); gnutls_free(tkt.data); - if ((dbm_file = dbfn_open(US"tls", O_RDWR, &dbblock, FALSE, FALSE))) + if ((dbm_file = dbfn_open(US"tls", O_RDWR|O_CREAT, &dbblock, FALSE, FALSE))) { /* key for the db is the IP */ dbfn_write(dbm_file, tlsp->resume_index, dt, dlen); dbfn_close(dbm_file); DEBUG(D_tls) - debug_printf("wrote session db (len %u)\n", (unsigned)dlen); + debug_printf(" wrote session db (len %u)\n", (unsigned)dlen); } } - else DEBUG(D_tls) - debug_printf("extract session data: %s\n", US gnutls_strerror(rc)); + else + { DEBUG(D_tls) + debug_printf(" extract session data: %s\n", US gnutls_strerror(rc)); + } + else DEBUG(D_tls) + debug_printf(" host not resmable; not saving ticket\n"); } } @@ -3406,7 +3419,7 @@ tls_client_ticket_cb(gnutls_session_t sess, u_int htype, unsigned when, exim_gnutls_state_st * state = gnutls_session_get_ptr(sess); tls_support * tlsp = state->tlsp; -DEBUG(D_tls) debug_printf("newticket cb\n"); +DEBUG(D_tls) debug_printf("newticket cb (on client)\n"); if (!tlsp->ticket_received) tls_save_session(tlsp, sess, state->host); @@ -3466,7 +3479,7 @@ tls_client_start(client_conn_ctx * cctx, smtp_connect_args * conn_args, host_item * host = conn_args->host; /* for msgs and option-tests */ transport_instance * tb = conn_args->tblock; /* always smtp or NULL */ smtp_transport_options_block * ob = tb - ? (smtp_transport_options_block *)tb->options_block + ? tb->drinst.options_block : &smtp_transport_option_defaults; int rc; exim_gnutls_state_st * state = NULL; @@ -3891,7 +3904,7 @@ else if (inbytes < 0) return FALSE; } #ifndef DISABLE_DKIM -dkim_exim_verify_feed(state->xfer_buffer, inbytes); +smtp_verify_feed(state->xfer_buffer, inbytes); #endif state->xfer_buffer_hwm = (int) inbytes; state->xfer_buffer_lwm = 0; @@ -3967,7 +3980,7 @@ int n = state->xfer_buffer_hwm - state->xfer_buffer_lwm; if (n > lim) n = lim; if (n > 0) - dkim_exim_verify_feed(state->xfer_buffer+state->xfer_buffer_lwm, n); + smtp_verify_feed(state->xfer_buffer+state->xfer_buffer_lwm, n); #endif }