]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl: add 'ssl_npn' sample/acl to extract TLS/NPN information
authorWilly Tarreau <w@1wt.eu>
Mon, 15 Oct 2012 11:19:06 +0000 (13:19 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 15 Oct 2012 11:19:06 +0000 (13:19 +0200)
This may be used to distinguish between SPDY versions for example.

doc/configuration.txt
src/ssl_sock.c

index 208c43221e9e24400491b032b0b4846231379997..119f4401c3c1b9201966e93bb978fe3f0e376e72 100644 (file)
@@ -8339,6 +8339,12 @@ ssl_has_sni
   that the SSL library is build with support for TLS extensions enabled (check
   haproxy -vv).
 
+ssl_npn <string>
+  Returns true when the incoming connection was made over an SSL/TLS transport
+  layer which deciphered it and found a Next Protocol Negociation TLS extension
+  sent by the client, matching the specified string. This requires that the SSL
+  library is build with support for TLS extensions enabled (check haproxy -vv).
+
 ssl_sni <string>
   Returns true when the incoming connection was made over an SSL/TLS transport
   layer which deciphered it and found a Server Name Indication TLS extension
@@ -8996,6 +9002,13 @@ The list of currently supported pattern fetch functions is the following :
                otherwise zero. This requires that the SSL library is build with
                support for TLS extensions enabled (check haproxy -vv).
 
+  ssl_npn      This extracts the Next Protocol Negociation field from an
+               incoming connection made via an SSL/TLS transport layer and
+               locally deciphered by haproxy. The result is a string containing
+               the protocol name advertised by the client. The SSL library must
+               have been built with support for TLS extensions enabled (check
+               haproxy -vv).
+
   ssl_sni      This extracts the Server Name Indication field from an incoming
                connection made via an SSL/TLS transport layer and locally
                deciphered by haproxy. The result typically is a string matching
index 9aed915711b485e3636643e5582cfd22ef93427c..6121b12847a5c88262628b2adafa871bcf5026dd 100644 (file)
@@ -1118,6 +1118,30 @@ smp_fetch_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int o
 #endif
 }
 
+static int
+smp_fetch_ssl_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+                  const struct arg *args, struct sample *smp)
+{
+#ifdef OPENSSL_NPN_NEGOTIATED
+       smp->flags = 0;
+       smp->type = SMP_T_CSTR;
+
+       if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
+               return 0;
+
+       smp->data.str.str = NULL;
+       SSL_get0_next_proto_negotiated(l4->si[0].conn.xprt_ctx,
+                                       (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
+
+       if (!smp->data.str.str)
+               return 0;
+
+       return 1;
+#else
+       return 0;
+#endif
+}
+
 static int
 smp_fetch_ssl_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
                   const struct arg *args, struct sample *smp)
@@ -1662,6 +1686,9 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
        { "client_crt",             smp_fetch_client_crt,         0,    NULL,    SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
        { "is_ssl",                 smp_fetch_is_ssl,             0,    NULL,    SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
        { "ssl_has_sni",            smp_fetch_has_sni,            0,    NULL,    SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
+#ifdef OPENSSL_NPN_NEGOTIATED
+       { "ssl_npn",                smp_fetch_ssl_npn,            0,    NULL,    SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
+#endif
        { "ssl_sni",                smp_fetch_ssl_sni,            0,    NULL,    SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
        { "ssl_verify_caerr",       smp_fetch_verify_caerr,       0,    NULL,    SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
        { "ssl_verify_caerr_depth", smp_fetch_verify_caerr_depth, 0,    NULL,    SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
@@ -1677,6 +1704,9 @@ static struct acl_kw_list acl_kws = {{ },{
        { "client_crt",             acl_parse_int, smp_fetch_client_crt,         acl_match_nothing, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
        { "is_ssl",                 acl_parse_int, smp_fetch_is_ssl,             acl_match_nothing, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
        { "ssl_has_sni",            acl_parse_int, smp_fetch_has_sni,            acl_match_nothing, ACL_USE_L6REQ_PERMANENT, 0 },
+#ifdef OPENSSL_NPN_NEGOTIATED
+       { "ssl_npn",                acl_parse_str, smp_fetch_ssl_npn,            acl_match_str,     ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
+#endif
        { "ssl_sni",                acl_parse_str, smp_fetch_ssl_sni,            acl_match_str,     ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
        { "ssl_sni_end",            acl_parse_str, smp_fetch_ssl_sni,            acl_match_end,     ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
        { "ssl_sni_reg",            acl_parse_str, smp_fetch_ssl_sni,            acl_match_reg,     ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },