]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: checks: Add support of server side ssl sample fetches
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 30 Apr 2020 08:03:55 +0000 (10:03 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 5 May 2020 09:06:43 +0000 (11:06 +0200)
SSL sample fetches acting on the server connection can now be called from any
sample expression or log-format string in a tcp-check based ruleset. ssl_bc and
ssl_bc_* sample fetches are concerned.

doc/configuration.txt
src/ssl_sock.c

index 86f3f1a4cc71b22d25a145c39f5e104a81a7aae6..4a1c150d5b45f70fc6a28c3690125d83dc5fa7c0 100644 (file)
@@ -16281,11 +16281,13 @@ future information. Those generally include the results of SSL negotiations.
 ssl_bc : boolean
   Returns true when the back connection was made via an SSL/TLS transport
   layer and is locally deciphered. This means the outgoing connection was made
-  other a server with the "ssl" option.
+  other a server with the "ssl" option. It can be used in a tcp-check or an
+  http-check ruleset.
 
 ssl_bc_alg_keysize : integer
   Returns the symmetric cipher key size supported in bits when the outgoing
-  connection was made over an SSL/TLS transport layer.
+  connection was made over an SSL/TLS transport layer. It can be used in a
+  tcp-check or an http-check ruleset.
 
 ssl_bc_alpn : string
   This extracts the Application Layer Protocol Negotiation field from an
@@ -16296,21 +16298,25 @@ ssl_bc_alpn : string
   not advertised unless the "alpn" keyword on the "server" line specifies a
   protocol list. Also, nothing forces the server to pick a protocol from this
   list, any other one may be requested. The TLS ALPN extension is meant to
-  replace the TLS NPN extension. See also "ssl_bc_npn".
+  replace the TLS NPN extension. See also "ssl_bc_npn". It can be used in a
+  tcp-check or an http-check ruleset.
 
 ssl_bc_cipher : string
   Returns the name of the used cipher when the outgoing connection was made
-  over an SSL/TLS transport layer.
+  over an SSL/TLS transport layer. It can be used in a tcp-check or an
+  http-check ruleset.
 
 ssl_bc_client_random : binary
   Returns the client random of the back connection when the incoming connection
   was made over an SSL/TLS transport layer. It is useful to to decrypt traffic
   sent using ephemeral ciphers. This requires OpenSSL >= 1.1.0, or BoringSSL.
+  It can be used in a tcp-check or an http-check ruleset.
 
 ssl_bc_is_resumed : boolean
   Returns true when the back connection was made over an SSL/TLS transport
   layer and the newly created SSL session was resumed using a cached
-  session or a TLS ticket.
+  session or a TLS ticket. It can be used in a tcp-check or an http-check
+  ruleset.
 
 ssl_bc_npn : string
   This extracts the Next Protocol Negotiation field from an outgoing connection
@@ -16320,36 +16326,42 @@ ssl_bc_npn : string
   the TLS NPN extension is not advertised unless the "npn" keyword on the
   "server" line specifies a protocol list. Also, nothing forces the server to
   pick a protocol from this list, any other one may be used. Please note that
-  the TLS NPN extension was replaced with ALPN.
+  the TLS NPN extension was replaced with ALPN. It can be used in a tcp-check
+  or an http-check ruleset.
 
 ssl_bc_protocol : string
   Returns the name of the used protocol when the outgoing connection was made
-  over an SSL/TLS transport layer.
+  over an SSL/TLS transport layer. It can be used in a tcp-check or an
+  http-check ruleset.
 
 ssl_bc_unique_id : binary
   When the outgoing connection was made over an SSL/TLS transport layer,
   returns the TLS unique ID as defined in RFC5929 section 3. The unique id
-  can be encoded to base64 using the converter: "ssl_bc_unique_id,base64".
+  can be encoded to base64 using the converter: "ssl_bc_unique_id,base64". It
+  can be used in a tcp-check or an http-check ruleset.
 
 ssl_bc_server_random : binary
   Returns the server random of the back connection when the incoming connection
   was made over an SSL/TLS transport layer. It is useful to to decrypt traffic
   sent using ephemeral ciphers. This requires OpenSSL >= 1.1.0, or BoringSSL.
+  It can be used in a tcp-check or an http-check ruleset.
 
 ssl_bc_session_id : binary
   Returns the SSL ID of the back connection when the outgoing connection was
   made over an SSL/TLS transport layer. It is useful to log if we want to know
-  if session was reused or not.
+  if session was reused or not. It can be used in a tcp-check or an http-check
+  ruleset.
 
 ssl_bc_session_key : binary
   Returns the SSL session master key of the back connection when the outgoing
   connection was made over an SSL/TLS transport layer. It is useful to decrypt
   traffic sent using ephemeral ciphers. This requires OpenSSL >= 1.1.0, or
-  BoringSSL.
+  BoringSSL. It can be used in a tcp-check or an http-check ruleset.
 
 ssl_bc_use_keysize : integer
   Returns the symmetric cipher key size used in bits when the outgoing
-  connection was made over an SSL/TLS transport layer.
+  connection was made over an SSL/TLS transport layer. It can be used in a
+  tcp-check or an http-check ruleset.
 
 ssl_c_ca_err : integer
   When the incoming connection was made over an SSL/TLS transport layer,
index c4f9a86ad52ab92e7603152b20ed6173e4dc88c2..dfaea05b7bf127ab34ed8a2974c6af97bd0784a6 100644 (file)
@@ -8468,8 +8468,13 @@ smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *
 static int
 smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
+
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 
        smp->data.type = SMP_T_BOOL;
        smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
@@ -8501,10 +8506,16 @@ smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char
 static int
 smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
-       struct ssl_sock_ctx *ctx = conn ? conn->xprt_ctx : NULL;
+       struct connection *conn;
+       struct ssl_sock_ctx *ctx;
+
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 
+       ctx = conn ? conn->xprt_ctx : NULL;
 
        smp->data.type = SMP_T_BOOL;
        smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
@@ -8520,10 +8531,15 @@ smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const ch
 static int
 smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        struct ssl_sock_ctx *ctx;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        smp->flags = 0;
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
@@ -8548,11 +8564,16 @@ smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *
 static int
 smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        struct ssl_sock_ctx *ctx;
        int sint;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        smp->flags = 0;
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
@@ -8574,10 +8595,15 @@ smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const c
 static int
 smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        struct ssl_sock_ctx *ctx;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        smp->flags = 0;
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
@@ -8603,8 +8629,12 @@ smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw,
        smp->flags = SMP_F_CONST;
        smp->data.type = SMP_T_STR;
 
-       conn = (kw[4] != 'b' ) ? objt_conn(smp->sess->origin) :
-           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
        ctx = conn->xprt_ctx;
@@ -8633,8 +8663,11 @@ smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw
        smp->flags = SMP_F_CONST;
        smp->data.type = SMP_T_STR;
 
-       conn = (kw[4] != 'b' ) ? objt_conn(smp->sess->origin) :
-           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
 
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
@@ -8660,10 +8693,15 @@ smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw
 static int
 smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        struct ssl_sock_ctx *ctx;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        smp->flags = 0;
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
@@ -8688,8 +8726,7 @@ smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char
 static int
 smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        SSL_SESSION *ssl_sess;
        struct ssl_sock_ctx *ctx;
        unsigned int len = 0;
@@ -8697,6 +8734,12 @@ smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const ch
        smp->flags = SMP_F_CONST;
        smp->data.type = SMP_T_BIN;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
        ctx = conn->xprt_ctx;
@@ -8719,11 +8762,16 @@ smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const ch
 static int
 smp_fetch_ssl_fc_random(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                                  smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        struct buffer *data;
        struct ssl_sock_ctx *ctx;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
        ctx = conn->xprt_ctx;
@@ -8750,12 +8798,17 @@ smp_fetch_ssl_fc_random(const struct arg *args, struct sample *smp, const char *
 static int
 smp_fetch_ssl_fc_session_key(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        SSL_SESSION *ssl_sess;
        struct buffer *data;
        struct ssl_sock_ctx *ctx;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;
        ctx = conn->xprt_ctx;
@@ -8903,12 +8956,17 @@ smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *
 static int
 smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
-       struct connection *conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
-                                           smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+       struct connection *conn;
        int finished_len;
        struct buffer *finished_trash;
        struct ssl_sock_ctx *ctx;
 
+       if (smp->sess && obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
+               conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
+       else
+               conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
+                       smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
+
        smp->flags = 0;
        if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
                return 0;