mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-13 23:14:46 +00:00
MINOR: ssl: add pattern and ACLs fetches 'ssl_c_notbefore', 'ssl_c_notafter', 'ssl_f_notbefore' and 'ssl_f_notafter'
ssl_c_notbefore: start date of client cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z]) ssl_c_notafter: end date of client cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z]) ssl_f_notbefore: start date of frontend cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z]) ssl_f_notafter: end date of frontend cert (string, eg: "121022182230Z" for YYMMDDhhmmss[Z])
This commit is contained in:
parent
521a011999
commit
ce5ad80c34
@ -8390,6 +8390,16 @@ ssl_c_key_alg <string>
|
||||
layer, and the name of the algorithm used to generate the key of the
|
||||
certificate presented by the client matches the string.
|
||||
|
||||
ssl_c_notafter <string>
|
||||
Returns true when the incoming connection was made over an SSL/TLS transport
|
||||
layer, and the end date of the certificate presented by the client matches
|
||||
the string formatted as YYMMDDhhmmss[Z].
|
||||
|
||||
ssl_c_notbefore <string>
|
||||
Returns true when the incoming connection was made over an SSL/TLS transport
|
||||
layer, and the start date of the certificate presented by the client matches
|
||||
the string formatted as YYMMDDhhmmss[Z].
|
||||
|
||||
ssl_c_s_dn <string>
|
||||
ssl_c_s_dn(entry[,occ]) <string>
|
||||
If no entry specified, returns true when the incoming connection was made
|
||||
@ -8437,6 +8447,16 @@ ssl_c_key_alg <string>
|
||||
layer, and the name of the algorithm used to generate the key of the
|
||||
certificate presented by the frontend matches the string.
|
||||
|
||||
ssl_f_notafter <string>
|
||||
Returns true when the incoming connection was made over an SSL/TLS transport
|
||||
layer, and the end date of the certificate presented by the frontend matches
|
||||
the string formatted as YYMMDDhhmmss[Z].
|
||||
|
||||
ssl_f_notbefore <string>
|
||||
Returns true when the incoming connection was made over an SSL/TLS transport
|
||||
layer, and the start date of the certificate presented by the frontend matches
|
||||
the string formatted as YYMMDDhhmmss[Z].
|
||||
|
||||
ssl_f_s_dn <string>
|
||||
ssl_f_s_dn(entry[,occ]) <string>
|
||||
If no entry specified, returns true when the incoming connection was made
|
||||
@ -9157,6 +9177,16 @@ The list of currently supported pattern fetch functions is the following :
|
||||
the certificate presented by the client when the incoming
|
||||
connection was made over an SSL/TLS transport layer.
|
||||
|
||||
ssl_c_notafter
|
||||
Returns the end date presented by the client as a formatted
|
||||
string YYMMDDhhmmss[Z] when the incoming connection was made
|
||||
over an SSL/TLS transport layer.
|
||||
|
||||
ssl_c_notbefore
|
||||
Returns the start date presented by the client as a formatted
|
||||
string YYMMDDhhmmss[Z] when the incoming connection was made
|
||||
over an SSL/TLS transport layer.
|
||||
|
||||
ssl_c_s_dn[(entry[,occ])]
|
||||
If no entry specified, returns the full distinguished name of
|
||||
the subject of the certificate presented by the client when
|
||||
@ -9204,6 +9234,16 @@ The list of currently supported pattern fetch functions is the following :
|
||||
the certificate presented by the frontend when the incoming
|
||||
connection was made over an SSL/TLS transport layer.
|
||||
|
||||
ssl_f_notafter
|
||||
Returns the end date presented by the frontend as a formatted
|
||||
string YYMMDDhhmmss[Z] when the incoming connection was made
|
||||
over an SSL/TLS transport layer.
|
||||
|
||||
ssl_f_notbefore
|
||||
Returns the start date presented by the frontend as a formatted
|
||||
string YYMMDDhhmmss[Z] when the incoming connection was made
|
||||
over an SSL/TLS transport layer.
|
||||
|
||||
ssl_f_s_dn[(entry[,occ])]
|
||||
If no entry specified, returns the full distinguished name of
|
||||
the subject of the certificate presented by the frontend when
|
||||
|
181
src/ssl_sock.c
181
src/ssl_sock.c
@ -1116,6 +1116,46 @@ ssl_sock_get_serial(X509 *crt, struct chunk *out)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Copy Date in ASN1_UTCTIME format in struct chunk out.
|
||||
* Returns 1 if serial is found and copied, 0 if no valid time found
|
||||
* and -1 if output is not large enough.
|
||||
*/
|
||||
static int
|
||||
ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
|
||||
{
|
||||
if (tm->type == V_ASN1_GENERALIZEDTIME) {
|
||||
ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
|
||||
|
||||
if (gentm->length < 12)
|
||||
return 0;
|
||||
if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
|
||||
return 0;
|
||||
if (out->size < gentm->length-2)
|
||||
return -1;
|
||||
|
||||
memcpy(out->str, gentm->data+2, gentm->length-2);
|
||||
out->len = gentm->length-2;
|
||||
return 1;
|
||||
}
|
||||
else if (tm->type == V_ASN1_UTCTIME) {
|
||||
ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
|
||||
|
||||
if (utctm->length < 10)
|
||||
return 0;
|
||||
if (utctm->data[0] >= 0x35)
|
||||
return 0;
|
||||
if (out->size < utctm->length)
|
||||
return -1;
|
||||
|
||||
memcpy(out->str, utctm->data, utctm->length);
|
||||
out->len = utctm->length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Extract an entry from a X509_NAME and copy its value to an output chunk.
|
||||
* Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
|
||||
*/
|
||||
@ -1265,6 +1305,41 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*str, returns notafter date in ASN1_UTCTIME format */
|
||||
static int
|
||||
smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
|
||||
const struct arg *args, struct sample *smp)
|
||||
{
|
||||
X509 *crt = NULL;
|
||||
int ret = 0;
|
||||
struct chunk *smp_trash;
|
||||
|
||||
if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
|
||||
return 0;
|
||||
|
||||
if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
|
||||
smp->flags |= SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SSL_get_peer_certificate, it increase X509 * ref count */
|
||||
crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
|
||||
if (!crt)
|
||||
goto out;
|
||||
|
||||
smp_trash = sample_get_trash_chunk();
|
||||
if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
|
||||
goto out;
|
||||
|
||||
smp->data.str = *smp_trash;
|
||||
smp->type = SMP_T_STR;
|
||||
ret = 1;
|
||||
out:
|
||||
if (crt)
|
||||
X509_free(crt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
|
||||
static int
|
||||
smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
|
||||
@ -1316,6 +1391,41 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*str, returns notbefore date in ASN1_UTCTIME format */
|
||||
static int
|
||||
smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
|
||||
const struct arg *args, struct sample *smp)
|
||||
{
|
||||
X509 *crt = NULL;
|
||||
int ret = 0;
|
||||
struct chunk *smp_trash;
|
||||
|
||||
if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
|
||||
return 0;
|
||||
|
||||
if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
|
||||
smp->flags |= SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SSL_get_peer_certificate, it increase X509 * ref count */
|
||||
crt = SSL_get_peer_certificate(l4->si[0].conn.xprt_ctx);
|
||||
if (!crt)
|
||||
goto out;
|
||||
|
||||
smp_trash = sample_get_trash_chunk();
|
||||
if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
|
||||
goto out;
|
||||
|
||||
smp->data.str = *smp_trash;
|
||||
smp->type = SMP_T_STR;
|
||||
ret = 1;
|
||||
out:
|
||||
if (crt)
|
||||
X509_free(crt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
|
||||
static int
|
||||
smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
|
||||
@ -1518,6 +1628,69 @@ smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
/*str, returns notafter date in ASN1_UTCTIME format */
|
||||
static int
|
||||
smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
|
||||
const struct arg *args, struct sample *smp)
|
||||
{
|
||||
X509 *crt = NULL;
|
||||
int ret = 0;
|
||||
struct chunk *smp_trash;
|
||||
|
||||
if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
|
||||
return 0;
|
||||
|
||||
if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
|
||||
smp->flags |= SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
|
||||
if (!crt)
|
||||
goto out;
|
||||
|
||||
smp_trash = sample_get_trash_chunk();
|
||||
if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
|
||||
goto out;
|
||||
|
||||
smp->data.str = *smp_trash;
|
||||
smp->type = SMP_T_STR;
|
||||
ret = 1;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*str, returns notbefore date in ASN1_UTCTIME format */
|
||||
static int
|
||||
smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
|
||||
const struct arg *args, struct sample *smp)
|
||||
{
|
||||
X509 *crt = NULL;
|
||||
int ret = 0;
|
||||
struct chunk *smp_trash;
|
||||
|
||||
if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
|
||||
return 0;
|
||||
|
||||
if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
|
||||
smp->flags |= SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
crt = SSL_get_certificate(l4->si[0].conn.xprt_ctx);
|
||||
if (!crt)
|
||||
goto out;
|
||||
|
||||
smp_trash = sample_get_trash_chunk();
|
||||
if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
|
||||
goto out;
|
||||
|
||||
smp->data.str = *smp_trash;
|
||||
smp->type = SMP_T_STR;
|
||||
ret = 1;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* integer, returns the frontend certificate version */
|
||||
static int
|
||||
@ -2421,6 +2594,8 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
{ "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
@ -2428,6 +2603,8 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
{ "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
{ "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_CAP_REQ|SMP_CAP_RES },
|
||||
@ -2456,6 +2633,8 @@ static struct acl_kw_list acl_kws = {{ },{
|
||||
{ "ssl_c_err", acl_parse_int, smp_fetch_ssl_c_err, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_c_i_dn", acl_parse_str, smp_fetch_ssl_c_i_dn, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, ARG2(0,STR,SINT) },
|
||||
{ "ssl_c_key_alg", acl_parse_str, smp_fetch_ssl_c_key_alg, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_c_notafter", acl_parse_str, smp_fetch_ssl_c_notafter, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_c_notbefore", acl_parse_str, smp_fetch_ssl_c_notbefore, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_c_sig_alg", acl_parse_str, smp_fetch_ssl_c_sig_alg, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_c_s_dn", acl_parse_str, smp_fetch_ssl_c_s_dn, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, ARG2(0,STR,SINT) },
|
||||
{ "ssl_c_serial", acl_parse_bin, smp_fetch_ssl_c_serial, acl_match_bin, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
@ -2463,6 +2642,8 @@ static struct acl_kw_list acl_kws = {{ },{
|
||||
{ "ssl_c_version", acl_parse_int, smp_fetch_ssl_c_version, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_f_i_dn", acl_parse_str, smp_fetch_ssl_f_i_dn, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, ARG2(0,STR,SINT) },
|
||||
{ "ssl_f_key_alg", acl_parse_str, smp_fetch_ssl_f_key_alg, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_f_notafter", acl_parse_str, smp_fetch_ssl_f_notafter, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_f_notbefore", acl_parse_str, smp_fetch_ssl_f_notbefore, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_f_sig_alg", acl_parse_str, smp_fetch_ssl_f_sig_alg, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
{ "ssl_f_s_dn", acl_parse_str, smp_fetch_ssl_f_s_dn, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, ARG2(0,STR,SINT) },
|
||||
{ "ssl_f_serial", acl_parse_bin, smp_fetch_ssl_f_serial, acl_match_bin, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
|
||||
|
Loading…
Reference in New Issue
Block a user