mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-30 10:06:43 +00: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, \
|
||||
(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 /* _PROTO_SSL_SOCK_H */
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <common/mini-clist.h>
|
||||
#include <common/openssl-compat.h>
|
||||
|
||||
struct connection;
|
||||
|
||||
struct pkey_info {
|
||||
uint8_t sig; /* TLSEXT_signature_[rsa,ecdsa,...] */
|
||||
uint16_t bits; /* key size in bits */
|
||||
@ -202,6 +204,18 @@ struct issuer_chain {
|
||||
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 /* _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, \
|
||||
(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
|
||||
* 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 */
|
||||
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
|
||||
/* test heartbeat received (write_p is set to 0
|
||||
for a received record) */
|
||||
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;
|
||||
const unsigned char *p = buf;
|
||||
unsigned int payload;
|
||||
@ -1928,6 +1970,13 @@ void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf
|
||||
#endif
|
||||
if (global_ssl.capture_cipherlist > 0)
|
||||
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)
|
||||
@ -13100,6 +13149,11 @@ static void __ssl_sock_init(void)
|
||||
BIO_meth_set_gets(ha_meth, ha_ssl_gets);
|
||||
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user