From 29f037d872198a75880e0816f40b15f4144956dc Mon Sep 17 00:00:00 2001 From: Emeric Brun Date: Fri, 25 Apr 2014 19:05:36 +0200 Subject: [PATCH] MEDIUM: ssl: explicitly log failed handshakes after a heartbeat Add a callback to receive the heartbeat notification. There, we add SSL_SOCK_RECV_HEARTBEAT flag on the ssl session if a heartbeat is seen. If a handshake fails, we log a different message to mention the fact that a heartbeat was seen. The test is only performed on the frontend side. --- src/ssl_sock.c | 67 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 525c7b557a..83c75f1d25 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -79,6 +79,8 @@ #define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001 #define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002 #define SSL_SOCK_SEND_UNLIMITED 0x00000004 +#define SSL_SOCK_RECV_HEARTBEAT 0x00000008 + /* bits 0xFFFF0000 are reserved to store verify errors */ /* Verify errors macros */ @@ -180,6 +182,19 @@ int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store) return 0; } +/* Callback is called for ssl protocol analyse */ +void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) +{ + struct connection *conn = (struct connection *)SSL_get_app_data(ssl); + +#ifdef TLS1_RT_HEARTBEAT + /* test heartbeat received (write_p is set to 0 + for a received record) */ + if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) + conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT; +#endif +} + #ifdef OPENSSL_NPN_NEGOTIATED /* This callback is used so that the server advertises the list of * negociable protocols for NPN. @@ -887,6 +902,8 @@ int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy } SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk); + SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk); + #ifdef OPENSSL_NPN_NEGOTIATED if (bind_conf->npn_str) SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf); @@ -1394,13 +1411,26 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag) if (!errno && conn->flags & CO_FL_WAIT_L4_CONN) conn->flags &= ~CO_FL_WAIT_L4_CONN; if (!conn->err_code) { - if (!((SSL *)conn->xprt_ctx)->packet_length) - if (!errno) - conn->err_code = CO_ER_SSL_EMPTY; + if (!((SSL *)conn->xprt_ctx)->packet_length) { + if (!errno) { + if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) + conn->err_code = CO_ER_SSL_HANDSHAKE_HB; + else + conn->err_code = CO_ER_SSL_EMPTY; + } + else { + if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) + conn->err_code = CO_ER_SSL_HANDSHAKE_HB; + else + conn->err_code = CO_ER_SSL_ABORT; + } + } + else { + if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) + conn->err_code = CO_ER_SSL_HANDSHAKE_HB; else - conn->err_code = CO_ER_SSL_ABORT; - else - conn->err_code = CO_ER_SSL_HANDSHAKE; + conn->err_code = CO_ER_SSL_HANDSHAKE; + } } goto out_error; } @@ -1447,13 +1477,26 @@ int ssl_sock_handshake(struct connection *conn, unsigned int flag) if (!errno && conn->flags & CO_FL_WAIT_L4_CONN) conn->flags &= ~CO_FL_WAIT_L4_CONN; - if (!((SSL *)conn->xprt_ctx)->packet_length) - if (!errno) - conn->err_code = CO_ER_SSL_EMPTY; + if (!((SSL *)conn->xprt_ctx)->packet_length) { + if (!errno) { + if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) + conn->err_code = CO_ER_SSL_HANDSHAKE_HB; + else + conn->err_code = CO_ER_SSL_EMPTY; + } + else { + if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) + conn->err_code = CO_ER_SSL_HANDSHAKE_HB; + else + conn->err_code = CO_ER_SSL_ABORT; + } + } + else { + if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) + conn->err_code = CO_ER_SSL_HANDSHAKE_HB; else - conn->err_code = CO_ER_SSL_ABORT; - else - conn->err_code = CO_ER_SSL_HANDSHAKE; + conn->err_code = CO_ER_SSL_HANDSHAKE; + } goto out_error; } else { -- 2.39.5