]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: Set connection error code in case of SSL read or write fatal failure
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Wed, 29 Sep 2021 16:56:51 +0000 (18:56 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 30 Sep 2021 09:04:35 +0000 (11:04 +0200)
In case of a connection error happening after the SSL handshake is
completed, the error code stored in the connection structure would not
always be set, hence having some connection failures being described as
successful in the fc_conn_err or bc_conn_err sample fetches.
The most common case in which it could happen is when the SSL server
rejects the client's certificate. The SSL_do_handshake call on the
client side would be sucessful because the client effectively sent its
client hello and certificate information to the server, but the next
call to SSL_read on the client side would raise an SSL_ERROR_SSL code
(through the SSL_get_error function) which is decribed in OpenSSL
documentation as a non-recoverable and fatal SSL error.
This patch ensures that in such a case, the connection's error code is
set to a special CO_ERR_SSL_FATAL value.

doc/configuration.txt
include/haproxy/connection-t.h
include/haproxy/connection.h
src/ssl_sock.c

index a7e8cdd80f1327b2dcb18f987fc53f6e90afa34d..5b0aad2f0cdb4dbcf662727d80dffd9aaa9e4653 100644 (file)
@@ -18030,6 +18030,7 @@ fc_conn_err_str : string
   | 40 | "SOCKS4 Proxy read error during handshake"                                |
   | 41 | "SOCKS4 Proxy deny the request"                                           |
   | 42 | "SOCKS4 Proxy handshake aborted by server"                                |
+  | 43 | "SSL fatal error"                                                         |
   +----+---------------------------------------------------------------------------+
 
 fc_http_major : integer
index ed41cff824318faef696901327379da018120ae2..4e4b65ee87784e801cf2fdb6def83e9e10d7683d 100644 (file)
@@ -250,6 +250,8 @@ enum {
        CO_ER_SOCKS4_RECV,       /* SOCKS4 Proxy read error during handshake */
        CO_ER_SOCKS4_DENY,       /* SOCKS4 Proxy deny the request */
        CO_ER_SOCKS4_ABORT,      /* SOCKS4 Proxy handshake aborted by server */
+
+       CO_ERR_SSL_FATAL,        /* SSL fatal error during a SSL_read or SSL_write */
 };
 
 /* error return codes for accept_conn() */
index 77afb2bb00615630ff47911de95a5bc09aa828ea..7e5ee7e8ca59850a1e58ed6760fd68d7a1bf5271 100644 (file)
@@ -834,6 +834,8 @@ static inline const char *conn_err_code_str(struct connection *c)
        case CO_ER_SOCKS4_RECV:    return "SOCKS4 Proxy read error during handshake";
        case CO_ER_SOCKS4_DENY:    return "SOCKS4 Proxy deny the request";
        case CO_ER_SOCKS4_ABORT:   return "SOCKS4 Proxy handshake aborted by server";
+
+       case CO_ERR_SSL_FATAL:     return "SSL fatal error";
        }
        return NULL;
 }
index b5da625fd24db98b690c101b41f52b768fb88804..285a7c6ee300bc0adcd6f8b63093a803d60c794d 100644 (file)
@@ -6185,6 +6185,9 @@ static size_t ssl_sock_to_buf(struct connection *conn, void *xprt_ctx, struct bu
                                break;
                        } else if (ret == SSL_ERROR_ZERO_RETURN)
                                goto read0;
+                       else if (ret == SSL_ERROR_SSL) {
+                               conn->err_code = CO_ERR_SSL_FATAL;
+                       }
                        /* For SSL_ERROR_SYSCALL, make sure to clear the error
                         * stack before shutting down the connection for
                         * reading. */
@@ -6346,6 +6349,9 @@ static size_t ssl_sock_from_buf(struct connection *conn, void *xprt_ctx, const s
 #endif
                                break;
                        }
+                       else if (ret == SSL_ERROR_SSL || ret == SSL_ERROR_SYSCALL) {
+                               conn->err_code = CO_ERR_SSL_FATAL;
+                       }
                        goto out_error;
                }
        }