From 10a7ff19aae2c6f568928e256da9117ed9bb35a3 Mon Sep 17 00:00:00 2001 From: Christian Wyglendowski Date: Fri, 21 Dec 2012 17:52:37 -0500 Subject: [PATCH] Properly handle the SSL error queue Errors were not getting cleared from the queue between various OpenSSL function calls. This was causing the error queue to contain misleading information on subsequent calls to SSL_get_error. One degenerate case was incorrect dispatching of errors after a failed SSL_read. Conditions that simply should have lead to another call to SSL_read were being treated as fatal. This was verified while stracing a stud process and seeing read() return with EAGAIN and stud immediately closing the socket fd and logging an SSL_read error. --- stud.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/stud.c b/stud.c index 4b76cba..40d9965 100644 --- a/stud.c +++ b/stud.c @@ -446,6 +446,13 @@ static void shutdown_proxy(proxystate *ps, SHUTDOWN_REQUESTOR req) { close(ps->fd_up); close(ps->fd_down); + // Clear the SSL error queue - it might contain details + // of errors that we haven't consumed for whatever reason. + // If we don't, future calls to SSL_get_error will lead to + // weird/confusing results that can throw off the handling + // of normal conditions like SSL_ERROR_WANT_READ. + ERR_clear_error(); + SSL_set_shutdown(ps->ssl, SSL_SENT_SHUTDOWN); SSL_free(ps->ssl); @@ -672,7 +679,15 @@ static void client_handshake(struct ev_loop *loop, ev_io *w, int revents) { shutdown_proxy(ps, SHUTDOWN_UP); } else { - LOG("{client} Unexpected SSL error (in handshake): %d\n", err); + + // Try and get more detail on the error from the SSL + // error queue. ERR_error_string requires a char buffer + // of 120 bytes. + unsigned long err_detail = ERR_get_error(); + char err_msg[120]; + ERR_error_string(err_detail, err_msg); + + LOG("{client} Unexpected SSL error (in handshake): %d, %s\n", err, err_msg); shutdown_proxy(ps, SHUTDOWN_UP); } }