]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: explicitly log failed handshakes after a heartbeat
authorEmeric Brun <ebrun@haproxy.com>
Fri, 25 Apr 2014 17:05:36 +0000 (19:05 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 25 Apr 2014 17:25:33 +0000 (19:25 +0200)
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

index 525c7b557ac80ccf7bee8483ffd1636c6c98f173..83c75f1d25ca960ff26d4df0809cfa7a4af6cf5c 100644 (file)
@@ -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 {