mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MEDIUM: ssl: allow to register callbacks for SSL/TLS protocol messages
This patch adds the ability to register callbacks for SSL/TLS protocol messages by using the function ssl_sock_register_msg_callback(). All registered callback functions will be called when observing received or sent SSL/TLS protocol messages.
This commit is contained in:
parent
5ce3c14aa9
commit
1e7ed04665
@ -103,6 +103,12 @@ void ssl_async_fd_free(int fd);
|
|||||||
|
|
||||||
#define sh_ssl_sess_tree_lookup(k) (struct sh_ssl_sess_hdr *)ebmb_lookup(sh_ssl_sess_tree, \
|
#define sh_ssl_sess_tree_lookup(k) (struct sh_ssl_sess_hdr *)ebmb_lookup(sh_ssl_sess_tree, \
|
||||||
(k), SSL_MAX_SSL_SESSION_ID_LENGTH);
|
(k), SSL_MAX_SSL_SESSION_ID_LENGTH);
|
||||||
|
|
||||||
|
/* Registers the function <func> in order to be called on SSL/TLS protocol
|
||||||
|
* message processing.
|
||||||
|
*/
|
||||||
|
int ssl_sock_register_msg_callback(ssl_sock_msg_callback_func func);
|
||||||
|
|
||||||
#endif /* USE_OPENSSL */
|
#endif /* USE_OPENSSL */
|
||||||
#endif /* _PROTO_SSL_SOCK_H */
|
#endif /* _PROTO_SSL_SOCK_H */
|
||||||
|
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include <common/mini-clist.h>
|
#include <common/mini-clist.h>
|
||||||
#include <common/openssl-compat.h>
|
#include <common/openssl-compat.h>
|
||||||
|
|
||||||
|
struct connection;
|
||||||
|
|
||||||
struct pkey_info {
|
struct pkey_info {
|
||||||
uint8_t sig; /* TLSEXT_signature_[rsa,ecdsa,...] */
|
uint8_t sig; /* TLSEXT_signature_[rsa,ecdsa,...] */
|
||||||
uint16_t bits; /* key size in bits */
|
uint16_t bits; /* key size in bits */
|
||||||
@ -202,6 +204,18 @@ struct issuer_chain {
|
|||||||
char *path;
|
char *path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*ssl_sock_msg_callback_func)(struct connection *conn,
|
||||||
|
int write_p, int version, int content_type,
|
||||||
|
const void *buf, size_t len, SSL *ssl);
|
||||||
|
|
||||||
|
/* This structure contains a function pointer <func> that is called
|
||||||
|
* when observing received or sent SSL/TLS protocol messages, such as
|
||||||
|
* handshake messages or other events that can occur during processing.
|
||||||
|
*/
|
||||||
|
struct ssl_sock_msg_callback {
|
||||||
|
ssl_sock_msg_callback_func func;
|
||||||
|
struct list list; /* list of registered callbacks */
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* USE_OPENSSL */
|
#endif /* USE_OPENSSL */
|
||||||
#endif /* _TYPES_SSL_SOCK_H */
|
#endif /* _TYPES_SSL_SOCK_H */
|
||||||
|
@ -629,6 +629,46 @@ static struct eb_root *sh_ssl_sess_tree; /* ssl shared session tree */
|
|||||||
#define sh_ssl_sess_tree_lookup(k) (struct sh_ssl_sess_hdr *)ebmb_lookup(sh_ssl_sess_tree, \
|
#define sh_ssl_sess_tree_lookup(k) (struct sh_ssl_sess_hdr *)ebmb_lookup(sh_ssl_sess_tree, \
|
||||||
(k), SSL_MAX_SSL_SESSION_ID_LENGTH);
|
(k), SSL_MAX_SSL_SESSION_ID_LENGTH);
|
||||||
|
|
||||||
|
/* List head of all registered SSL/TLS protocol message callbacks. */
|
||||||
|
struct list ssl_sock_msg_callbacks = LIST_HEAD_INIT(ssl_sock_msg_callbacks);
|
||||||
|
|
||||||
|
/* Registers the function <func> in order to be called on SSL/TLS protocol
|
||||||
|
* message processing. It will return 0 if the function <func> is not set
|
||||||
|
* or if it fails to allocate memory.
|
||||||
|
*/
|
||||||
|
int ssl_sock_register_msg_callback(ssl_sock_msg_callback_func func)
|
||||||
|
{
|
||||||
|
struct ssl_sock_msg_callback *cbk;
|
||||||
|
|
||||||
|
if (!func)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cbk = calloc(1, sizeof(*cbk));
|
||||||
|
if (!cbk) {
|
||||||
|
ha_alert("out of memory in ssl_sock_register_msg_callback().\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbk->func = func;
|
||||||
|
|
||||||
|
LIST_ADDQ(&ssl_sock_msg_callbacks, &cbk->list);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Used to free all SSL/TLS protocol message callbacks that were
|
||||||
|
* registered by using ssl_sock_register_msg_callback().
|
||||||
|
*/
|
||||||
|
static void ssl_sock_unregister_msg_callbacks(void)
|
||||||
|
{
|
||||||
|
struct ssl_sock_msg_callback *cbk, *cbkback;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(cbk, cbkback, &ssl_sock_msg_callbacks, list) {
|
||||||
|
LIST_DEL(&cbk->list);
|
||||||
|
free(cbk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function gives the detail of the SSL error. It is used only
|
* This function gives the detail of the SSL error. It is used only
|
||||||
* if the debug mode and the verbose mode are activated. It dump all
|
* if the debug mode and the verbose mode are activated. It dump all
|
||||||
@ -1887,11 +1927,13 @@ void ssl_sock_parse_clienthello(int write_p, int version, int content_type,
|
|||||||
/* Callback is called for ssl protocol analyse */
|
/* Callback is called for ssl protocol analyse */
|
||||||
void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
|
void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
|
||||||
{
|
{
|
||||||
|
struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
|
||||||
|
struct ssl_sock_msg_callback *cbk;
|
||||||
|
|
||||||
#ifdef TLS1_RT_HEARTBEAT
|
#ifdef TLS1_RT_HEARTBEAT
|
||||||
/* test heartbeat received (write_p is set to 0
|
/* test heartbeat received (write_p is set to 0
|
||||||
for a received record) */
|
for a received record) */
|
||||||
if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
|
if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
|
||||||
struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
|
|
||||||
struct ssl_sock_ctx *ctx = conn->xprt_ctx;
|
struct ssl_sock_ctx *ctx = conn->xprt_ctx;
|
||||||
const unsigned char *p = buf;
|
const unsigned char *p = buf;
|
||||||
unsigned int payload;
|
unsigned int payload;
|
||||||
@ -1928,6 +1970,13 @@ void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf
|
|||||||
#endif
|
#endif
|
||||||
if (global_ssl.capture_cipherlist > 0)
|
if (global_ssl.capture_cipherlist > 0)
|
||||||
ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
|
ssl_sock_parse_clienthello(write_p, version, content_type, buf, len, ssl);
|
||||||
|
|
||||||
|
/* Try to call all callback functions that were registered by using
|
||||||
|
* ssl_sock_register_msg_callback().
|
||||||
|
*/
|
||||||
|
list_for_each_entry(cbk, &ssl_sock_msg_callbacks, list) {
|
||||||
|
cbk->func(conn, write_p, version, content_type, buf, len, ssl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
|
#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
|
||||||
@ -13100,6 +13149,11 @@ static void __ssl_sock_init(void)
|
|||||||
BIO_meth_set_gets(ha_meth, ha_ssl_gets);
|
BIO_meth_set_gets(ha_meth, ha_ssl_gets);
|
||||||
|
|
||||||
HA_SPIN_INIT(&ckch_lock);
|
HA_SPIN_INIT(&ckch_lock);
|
||||||
|
|
||||||
|
/* Try to free all callbacks that were registered by using
|
||||||
|
* ssl_sock_register_msg_callback().
|
||||||
|
*/
|
||||||
|
hap_register_post_deinit(ssl_sock_unregister_msg_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute and register the version string */
|
/* Compute and register the version string */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user