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)

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