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.
> 

Reply via email to