Browse Source

[Minor] Try harder to do a "proper" SSL shutdown

tags/1.8.0
Vsevolod Stakhov 5 years ago
parent
commit
faa4da7362
1 changed files with 41 additions and 9 deletions
  1. 41
    9
      src/libutil/ssl_util.c

+ 41
- 9
src/libutil/ssl_util.c View File

@@ -25,15 +25,23 @@
#include <openssl/conf.h>
#include <openssl/x509v3.h>

enum rspamd_ssl_state {
ssl_conn_reset = 0,
ssl_conn_init,
ssl_conn_connected,
ssl_next_read,
ssl_next_write
};

enum rspamd_ssl_shutdown {
ssl_shut_default = 0,
ssl_shut_unclean,
};

struct rspamd_ssl_connection {
gint fd;
enum {
ssl_conn_reset = 0,
ssl_conn_init,
ssl_conn_connected,
ssl_next_read,
ssl_next_write
} state;
enum rspamd_ssl_state state;
enum rspamd_ssl_shutdown shut;
gboolean verify_peer;
SSL *ssl;
gchar *hostname;
@@ -399,6 +407,10 @@ rspamd_ssl_event_handler (gint fd, short what, gpointer ud)
gint ret;
GError *err = NULL;

if (what == EV_TIMEOUT) {
c->shut = ssl_shut_unclean;
}

switch (c->state) {
case ssl_conn_init:
/* Continue connection */
@@ -544,6 +556,8 @@ rspamd_ssl_connect_fd (struct rspamd_ssl_connection *conn, gint fd,
what = EV_WRITE;
}
else {
conn->shut = ssl_shut_unclean;

return FALSE;
}

@@ -573,6 +587,7 @@ rspamd_ssl_read (struct rspamd_ssl_connection *conn, gpointer buf,
errno = EINVAL;
g_set_error (&err, rspamd_ssl_quark (), ECONNRESET,
"ssl state error: cannot read data");
conn->shut = ssl_shut_unclean;
conn->err_handler (conn->handler_data, err);
g_error_free (err);

@@ -593,6 +608,7 @@ rspamd_ssl_read (struct rspamd_ssl_connection *conn, gpointer buf,
return 0;
}
else {
conn->shut = ssl_shut_unclean;
rspamd_tls_set_error (ret, "read", &err);
conn->err_handler (conn->handler_data, err);
g_error_free (err);
@@ -613,6 +629,7 @@ rspamd_ssl_read (struct rspamd_ssl_connection *conn, gpointer buf,
what |= EV_WRITE;
}
else {
conn->shut = ssl_shut_unclean;
rspamd_tls_set_error (ret, "read", &err);
conn->err_handler (conn->handler_data, err);
g_error_free (err);
@@ -667,6 +684,7 @@ rspamd_ssl_write (struct rspamd_ssl_connection *conn, gconstpointer buf,
return -1;
}
else {
conn->shut = ssl_shut_unclean;
rspamd_tls_set_error (ret, "write", &err);
conn->err_handler (conn->handler_data, err);
g_error_free (err);
@@ -686,6 +704,7 @@ rspamd_ssl_write (struct rspamd_ssl_connection *conn, gconstpointer buf,
what = EV_WRITE;
}
else {
conn->shut = ssl_shut_unclean;
rspamd_tls_set_error (ret, "write", &err);
conn->err_handler (conn->handler_data, err);
g_error_free (err);
@@ -757,8 +776,21 @@ rspamd_ssl_connection_free (struct rspamd_ssl_connection *conn)
* if the socket is not ready for writing, in which case this hack will
* lead to an unclean shutdown and lost session on the other end.
*/
SSL_set_shutdown (conn->ssl, SSL_RECEIVED_SHUTDOWN);
SSL_shutdown (conn->ssl);
if (conn->shut == ssl_shut_unclean) {
SSL_set_shutdown (conn->ssl, SSL_RECEIVED_SHUTDOWN|SSL_SENT_SHUTDOWN);
SSL_set_quiet_shutdown (conn->ssl, 1);
}
else {
SSL_set_shutdown (conn->ssl, SSL_RECEIVED_SHUTDOWN);
}

/* Stupid hack to enforce SSL to do shutdown sequence */
for (guint i = 0; i < 4; i++) {
if (SSL_shutdown (conn->ssl)) {
break;
}
}

SSL_free (conn->ssl);

if (conn->hostname) {

Loading…
Cancel
Save