mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: ssl: Add new ssl_fc_hsk_err sample fetch
This new sample fetch along the ssl_fc_hsk_err_str fetch contain the last SSL error of the error stack that occurred during the SSL handshake (from the frontend's perspective). The errors happening during the client's certificate verification will still be given by the ssl_c_err and ssl_c_ca_err fetches. This new fetch will only hold errors retrieved by the OpenSSL ERR_get_error function.
This commit is contained in:
parent
89b65cfd52
commit
7c6898ee49
@ -18925,6 +18925,25 @@ ssl_fc_has_sni : boolean
|
||||
that the SSL library is built with support for TLS extensions enabled (check
|
||||
haproxy -vv).
|
||||
|
||||
ssl_fc_hsk_err : integer
|
||||
When the incoming connection was made over an SSL/TLS transport layer,
|
||||
returns the ID of the latest error that happened during the handshake on the
|
||||
frontend side, or 0 if no error was encountered. Any error happening during
|
||||
the client's certificate verification process will not be raised through this
|
||||
fetch but via the existing "ssl_c_err", "ssl_c_ca_err" and
|
||||
"ssl_c_ca_err_depth" fetches. In order to get a text description of this
|
||||
error code, you can either use the "ssl_fc_hsk_err_str" sample fetch or use
|
||||
the "openssl errstr" command (which takes an error code in hexadecimal
|
||||
representation as parameter). Please refer to your SSL library's
|
||||
documentation to find the exhaustive list of error codes.
|
||||
|
||||
ssl_fc_hsk_err_str : string
|
||||
When the incoming connection was made over an SSL/TLS transport layer,
|
||||
returns a string representation of the latest error that happened during the
|
||||
handshake on the frontend side. Any error happening during the client's
|
||||
certificate verification process will not be raised through this fetch. See
|
||||
also "ssl_fc_hsk_err".
|
||||
|
||||
ssl_fc_is_resumed : boolean
|
||||
Returns true if the SSL/TLS session has been resumed through the use of
|
||||
SSL session cache or TLS tickets on an incoming connection over an SSL/TLS
|
||||
|
@ -235,6 +235,7 @@ struct ssl_sock_ctx {
|
||||
struct wait_event wait_event;
|
||||
struct wait_event *subs;
|
||||
int xprt_st; /* transport layer state, initialized to zero */
|
||||
unsigned long hsk_error_code; /* last handshake error code of the error stack */
|
||||
struct buffer early_buf; /* buffer to store the early data received */
|
||||
int sent_early_data; /* Amount of early data we sent so far */
|
||||
|
||||
|
@ -1188,6 +1188,61 @@ smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
smp_fetch_ssl_fc_hsk_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
struct connection *conn;
|
||||
struct ssl_sock_ctx *ctx;
|
||||
|
||||
conn = objt_conn(smp->sess->origin);
|
||||
if (!conn || conn->xprt != &ssl_sock)
|
||||
return 0;
|
||||
ctx = conn->xprt_ctx;
|
||||
|
||||
if (conn->flags & CO_FL_WAIT_XPRT && !conn->err_code) {
|
||||
smp->flags = SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
return 0;
|
||||
|
||||
smp->flags = SMP_F_VOL_SESS;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = ctx->hsk_error_code;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
smp_fetch_ssl_fc_hsk_err_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
struct connection *conn;
|
||||
struct ssl_sock_ctx *ctx;
|
||||
const char *err_code_str;
|
||||
|
||||
conn = objt_conn(smp->sess->origin);
|
||||
if (!conn || conn->xprt != &ssl_sock)
|
||||
return 0;
|
||||
ctx = conn->xprt_ctx;
|
||||
|
||||
if (conn->flags & CO_FL_WAIT_XPRT && !conn->err_code) {
|
||||
smp->flags = SMP_F_MAY_CHANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ctx || !ctx->hsk_error_code)
|
||||
return 0;
|
||||
|
||||
err_code_str = ERR_error_string(ctx->hsk_error_code, NULL);
|
||||
|
||||
smp->flags = SMP_F_VOL_SESS;
|
||||
smp->data.type = SMP_T_STR;
|
||||
smp->data.u.str.area = (char*)err_code_str;
|
||||
smp->data.u.str.data = strlen(err_code_str);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Dump the SSL keylog, it only works with "tune.ssl.keylog 1" */
|
||||
#ifdef HAVE_SSL_KEYLOG
|
||||
static int smp_fetch_ssl_x_keylog(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
@ -1546,6 +1601,8 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
{ "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_cipherlist_xxh", smp_fetch_ssl_fc_cl_xxh64, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_hsk_err", smp_fetch_ssl_fc_hsk_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_hsk_err_str", smp_fetch_ssl_fc_hsk_err_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
|
||||
/* SSL server certificate fetches */
|
||||
{ "ssl_s_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
|
||||
|
@ -5278,6 +5278,7 @@ static int ssl_sock_init(struct connection *conn, void **xprt_ctx)
|
||||
ctx->subs = NULL;
|
||||
ctx->xprt_st = 0;
|
||||
ctx->xprt_ctx = NULL;
|
||||
ctx->hsk_error_code = 0;
|
||||
|
||||
/* Only work with sockets for now, this should be adapted when we'll
|
||||
* add QUIC support.
|
||||
@ -5556,6 +5557,9 @@ static int ssl_sock_handshake(struct connection *conn, unsigned int flag)
|
||||
/* handshake did not complete, let's find why */
|
||||
ret = SSL_get_error(ctx->ssl, ret);
|
||||
|
||||
if (!ctx->hsk_error_code)
|
||||
ctx->hsk_error_code = ERR_peek_error();
|
||||
|
||||
if (ret == SSL_ERROR_WANT_WRITE) {
|
||||
/* SSL handshake needs to write, L4 connection may not be ready */
|
||||
if (!(ctx->wait_event.events & SUB_RETRY_SEND))
|
||||
|
Loading…
Reference in New Issue
Block a user