Wietse Venema: > Wietse Venema: > > Christian Roessner: > > > I double checked that cacert.org's cert is in that path as well > > > and that the c_hash exists, too. I did not find an answer and so > > > I only changed the log level of smtpd_tls_loglevel = 1 to 3. This > > > brought the segfault and this in the logs: > > > > > > Feb 6 19:11:54 mx postfix/master[14500]: warning: process > > > /usr/lib/postfix/smtpd pid 14526 killed by signal 11 > > > Feb 6 19:13:15 mx postfix/master[14736]: warning: process > > > /usr/lib/postfix/smtpd pid 14784 killed by signal 11 > > > > > > > That's easy enough to verify with default configuration and > > > > openssl s_client -starttls smtp -connect 127.0.0.1:25 > > > > For now, just don't set smtpd_tls_loglevel >= 3. > > Or apply the patch below (Postfix 2.8 and later).
That patch stops the segfault in BOTH smtpd and tlsproxy, assuming that one manages to update BOTH executable files. Below is a patch that goes further. Like the earlier patch it fixes the loglevel >= 3 segfault in BOTH smtpd and tlsproxy. In addition, it makes tlsproxy(8) actually log TLS transactions as expected. It works around an undocumented OpenSSL mis-feature, by moving the SSL_set_fd() call from tlsproxy(8) into the Postfix TLS library. Apparently, SSL_set_fd() destroys call-back information that is already set up on an SSL handle. That was causing tlsproxy(8)'s verbose logging to go nowhere. Wietse [file 20110207-tls-log-callback-patch] Patch for Postfix 2.8 and later. 20110207 Bugfix (introduced Postfix 2.8): segfault with smtpd_tls_loglevel >= 3. Files: tls/tls_server.c, tls.h, smtpd.c, tlsproxy.c. diff -cr /var/tmp/postfix-2.9-20110205/src/smtpd/smtpd.c ./src/smtpd/smtpd.c *** /var/tmp/postfix-2.9-20110205/src/smtpd/smtpd.c Sat Feb 5 18:25:25 2011 --- ./src/smtpd/smtpd.c Mon Feb 7 10:27:29 2011 *************** *** 4029,4034 **** --- 4029,4035 ---- TLS_SERVER_START(&props, ctx = smtpd_tls_ctx, stream = state->client, + fd = -1, log_level = var_smtpd_tls_loglevel, timeout = var_smtpd_starttls_tmout, requirecert = requirecert, diff -cr /var/tmp/postfix-2.9-20110205/src/tls/tls.h ./src/tls/tls.h *** /var/tmp/postfix-2.9-20110205/src/tls/tls.h Tue Dec 28 19:24:31 2010 --- ./src/tls/tls.h Mon Feb 7 10:25:04 2011 *************** *** 268,273 **** --- 268,274 ---- typedef struct { TLS_APPL_STATE *ctx; /* TLS application context */ VSTREAM *stream; /* Client stream */ + int fd; /* Event-driven file descriptor */ int log_level; /* TLS log level */ int timeout; /* TLS handshake timeout */ int requirecert; /* Insist on client cert? */ *************** *** 293,302 **** ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \ ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), (props))) ! #define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \ tls_server_start((((props)->a1), ((props)->a2), ((props)->a3), \ ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \ ! ((props)->a8), ((props)->a9), ((props)->a10), (props))) /* * tls_session.c --- 294,303 ---- ((props)->a12), ((props)->a13), ((props)->a14), ((props)->a15), \ ((props)->a16), ((props)->a17), ((props)->a18), ((props)->a19), (props))) ! #define TLS_SERVER_START(props, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) \ tls_server_start((((props)->a1), ((props)->a2), ((props)->a3), \ ((props)->a4), ((props)->a5), ((props)->a6), ((props)->a7), \ ! ((props)->a8), ((props)->a9), ((props)->a10), ((props)->a11), (props))) /* * tls_session.c diff -cr /var/tmp/postfix-2.9-20110205/src/tls/tls_server.c ./src/tls/tls_server.c *** /var/tmp/postfix-2.9-20110205/src/tls/tls_server.c Fri Dec 31 19:01:44 2010 --- ./src/tls/tls_server.c Mon Feb 7 10:38:33 2011 *************** *** 89,95 **** /* SSL_accept(), SSL_read(), SSL_write() and SSL_shutdown(). /* /* To maintain control over TLS I/O, an event-driven server ! /* invokes tls_server_start() with a null VSTREAM argument. /* Then, tls_server_start() performs all the necessary /* preparations before the TLS handshake and returns a partially /* populated TLS context. The event-driven application is then --- 89,96 ---- /* SSL_accept(), SSL_read(), SSL_write() and SSL_shutdown(). /* /* To maintain control over TLS I/O, an event-driven server ! /* invokes tls_server_start() with a null VSTREAM argument and ! /* with an fd argument that specifies the I/O file descriptor. /* Then, tls_server_start() performs all the necessary /* preparations before the TLS handshake and returns a partially /* populated TLS context. The event-driven application is then *************** *** 658,663 **** --- 659,676 ---- SSL_set_accept_state(TLScontext->con); /* + * Connect the SSL connection with the network socket. + */ + if (SSL_set_fd(TLScontext->con, props->stream == 0 ? props->fd : + vstream_fileno(props->stream)) != 1) { + msg_info("SSL_set_fd error to %s", props->namaddr); + tls_print_errors(); + uncache_session(app_ctx->ssl_ctx, TLScontext); + tls_free_context(TLScontext); + return (0); + } + + /* * If the debug level selected is high enough, all of the data is dumped: * 3 will dump the SSL negotiation, 4 will dump everything. * *************** *** 676,692 **** return (TLScontext); /* - * Connect the SSL connection with the network socket. - */ - if (SSL_set_fd(TLScontext->con, vstream_fileno(props->stream)) != 1) { - msg_info("SSL_set_fd error to %s", props->namaddr); - tls_print_errors(); - uncache_session(app_ctx->ssl_ctx, TLScontext); - tls_free_context(TLScontext); - return (0); - } - - /* * Turn on non-blocking I/O so that we can enforce timeouts on network * I/O. */ --- 689,694 ---- diff -cr /var/tmp/postfix-2.9-20110205/src/tlsproxy/tlsproxy.c ./src/tlsproxy/tlsproxy.c *** /var/tmp/postfix-2.9-20110205/src/tlsproxy/tlsproxy.c Mon Jan 17 10:43:31 2011 --- ./src/tlsproxy/tlsproxy.c Mon Feb 7 10:32:28 2011 *************** *** 687,692 **** --- 687,693 ---- TLS_SERVER_START(&props, ctx = tlsp_server_ctx, stream = (VSTREAM *) 0,/* unused */ + fd = state->ciphertext_fd, log_level = var_tlsp_tls_loglevel, timeout = 0, /* unused */ requirecert = (var_tlsp_tls_req_ccert *************** *** 703,720 **** } /* - * This program will do the ciphertext I/O, not libtls. In the future, - * the above event-driven engine may be factored out as a libtls library - * module. - */ - if (SSL_set_fd(state->tls_context->con, state->ciphertext_fd) != 1) { - msg_info("SSL_set_fd error to %s", state->remote_endpt); - tls_print_errors(); - tlsp_state_free(state); - return; - } - - /* * XXX Do we care about TLS session rate limits? Good postscreen(8) * clients will occasionally require the tlsproxy to renew their * whitelist status, but bad clients hammering the server can suck up --- 704,709 ----