When creating a tls session on an incoming connection, a useless roundtrip through the lka is made (see cert.c) to retreive a certificate which is not used anyway: the necessary contexts have already been set up for all pki names (in smtp.c:smtp_setup_events()). This diff makes the codepath more straight-forward and should not change the current behaviour.
Please test and report if you are using server-side tls. Eric. Index: smtp_session.c =================================================================== RCS file: /cvs/src/usr.sbin/smtpd/smtp_session.c,v retrieving revision 1.426 diff -u -p -r1.426 smtp_session.c --- smtp_session.c 24 Apr 2020 11:34:07 -0000 1.426 +++ smtp_session.c 14 Oct 2020 17:12:05 -0000 @@ -134,7 +134,6 @@ struct smtp_session { uint64_t id; struct io *io; struct listener *listener; - void *ssl_ctx; struct sockaddr_storage ss; char rdns[HOST_NAME_MAX+1]; char smtpname[HOST_NAME_MAX+1]; @@ -193,8 +192,7 @@ static void smtp_rfc4954_auth_plain(stru static void smtp_rfc4954_auth_login(struct smtp_session *, char *); static void smtp_free(struct smtp_session *, const char *); static const char *smtp_strstate(int); -static void smtp_cert_init(struct smtp_session *); -static void smtp_cert_init_cb(void *, int, const char *, const void *, size_t); +static void smtp_tls_init(struct smtp_session *); static void smtp_cert_verify(struct smtp_session *); static void smtp_cert_verify_cb(void *, int); static void smtp_auth_failure_pause(struct smtp_session *); @@ -306,7 +304,6 @@ static struct tree wait_parent_auth; static struct tree wait_queue_msg; static struct tree wait_queue_fd; static struct tree wait_queue_commit; -static struct tree wait_ssl_init; static struct tree wait_ssl_verify; static struct tree wait_filters; static struct tree wait_filter_fd; @@ -587,7 +584,6 @@ smtp_session_init(void) tree_init(&wait_queue_msg); tree_init(&wait_queue_fd); tree_init(&wait_queue_commit); - tree_init(&wait_ssl_init); tree_init(&wait_ssl_verify); tree_init(&wait_filters); tree_init(&wait_filter_fd); @@ -1193,7 +1189,7 @@ smtp_io(struct io *io, int evt, void *ar /* Wait for the client to start tls */ if (s->state == STATE_TLS) { - smtp_cert_init(s); + smtp_tls_init(s); break; } @@ -2071,7 +2067,7 @@ static void smtp_proceed_connected(struct smtp_session *s) { if (s->listener->flags & F_SMTPS) - smtp_cert_init(s); + smtp_tls_init(s); else smtp_send_banner(s); } @@ -2261,34 +2257,20 @@ smtp_mailaddr(struct mailaddr *maddr, ch } static void -smtp_cert_init(struct smtp_session *s) +smtp_tls_init(struct smtp_session *s) { - const char *name; - int fallback; + void *ssl_ctx; + void *ssl; - if (s->listener->pki_name[0]) { - name = s->listener->pki_name; - fallback = 0; - } + if (s->listener->pki_name[0]) + ssl_ctx = dict_get(env->sc_ssl_dict, s->listener->pki_name); else { - name = s->smtpname; - fallback = 1; + ssl_ctx = dict_get(env->sc_ssl_dict, s->smtpname); + if (ssl_ctx == NULL) + ssl_ctx = dict_get(env->sc_ssl_dict, "*"); } - if (cert_init(name, fallback, smtp_cert_init_cb, s)) - tree_xset(&wait_ssl_init, s->id, s); -} - -static void -smtp_cert_init_cb(void *arg, int status, const char *name, const void *cert, - size_t cert_len) -{ - struct smtp_session *s = arg; - void *ssl, *ssl_ctx; - - tree_pop(&wait_ssl_init, s->id); - - if (status == CA_FAIL) { + if (ssl_ctx == NULL) { log_info("%016"PRIx64" smtp disconnected " "reason=ca-failure", s->id); @@ -2296,7 +2278,6 @@ smtp_cert_init_cb(void *arg, int status, return; } - ssl_ctx = dict_get(env->sc_ssl_dict, name); ssl = ssl_smtp_init(ssl_ctx, s->listener->flags & F_TLS_VERIFY); io_set_read(s->io); io_start_tls(s->io, ssl);