Viktor Dukhovni:
> On Fri, Sep 06, 2019 at 11:03:16AM -0400, Wietse Venema wrote:
>
> > Forget that. The tlsproxy daemon does not use the code that
> > implements tls_fast_shutdown_enable/tls_fast_shutdown.
> >
> > In fact the tlsproxy daemon never invokes SSL_shutdown(), except
> > when there is an I/O error on the plaintext connection between
> > Postfix SMTP client and tlsproxy process, AFTER the TLS handshake
> > has completed.
>
> However, perhaps the code below (which I don't yet properly understand)
> can loop retrying the shutdown, because `SSL_shutdown()` of an SSL
> handle that is not established returns `SSL_ERROR_SSL` when the
> connection is not in an established state, but `tlsp_eval_tls_error()`
> does not clean up when
>
> state->plaintext_buf && NBBIO_WRITE_PEND(state->plaintext_buf)
state->plaintext_buf is NULL until after the SSL handshake completes.
SSL_shutdown(), see below. is called ONLY AFTER state->plaintext_buf
I/O error. But state->plaintext_buf is null until the handshake is
completed.
OpenSSL may enter the init state later, during session
renegotiation. How would we detect that?
Wietse
> is true, perhaps leaving the shutdown to be retried somehow?
>
> src/tlsproxy/tlsproxy.c:tlsp_strategy()
>
> plaintext_buf = state->plaintext_buf;
> if (NBBIO_ERROR_FLAGS(plaintext_buf)) {
> if (NBBIO_ACTIVE_FLAGS(plaintext_buf))
> nbbio_disable_readwrite(state->plaintext_buf);
> ssl_stat = SSL_shutdown(tls_context->con);
> /* XXX Wait for return value 1 if sessions are to be reused? */
> if (ssl_stat < 0) {
> handshake_err = SSL_get_error(tls_context->con, ssl_stat);
> tlsp_eval_tls_error(state, handshake_err);
> /* At this point, state could be a dangling pointer. */
> return;
> }
> tlsp_state_free(state);
> return;
> }
>
> src/tlsproxy/tlsproxy.c:tlsp_eval_tls_error()
>
> /*
> * Some error. Self-destruct. This automagically cleans up all
> * pending read/write and timeout event requests, making state a
> * dangling pointer.
> */
> case SSL_ERROR_SSL:
> tls_print_errors();
> /* FALLTHROUGH */
> default:
>
> /*
> * Allow buffered-up plaintext output to trickle out.
> */
> if (state->plaintext_buf && NBBIO_WRITE_PEND(state->plaintext_buf))
> return (TLSP_STAT_OK);
> tlsp_state_free(state);
> return (TLSP_STAT_ERR);
>
> --
> Viktor.
>