From: Daiki Ueno Date: Tue, 24 Mar 2020 16:51:56 +0000 (+0100) Subject: alert: add callback to intercept alert messages X-Git-Tag: 3.7.0~9^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc50fa0778799caf8dd0a2b87abb23f4feac2b34;p=thirdparty%2Fgnutls.git alert: add callback to intercept alert messages This adds gnutls_alert_set_read_function(), to allow QUIC implementations to be notified when an alert message is sent. Signed-off-by: Daiki Ueno --- diff --git a/devel/libgnutls-latest-x86_64.abi b/devel/libgnutls-latest-x86_64.abi index 8dbbe794b2..94399a34ba 100644 --- a/devel/libgnutls-latest-x86_64.abi +++ b/devel/libgnutls-latest-x86_64.abi @@ -77,6 +77,7 @@ + diff --git a/devel/symbols.last b/devel/symbols.last index 3a9be1bc5e..a3482d25a6 100644 --- a/devel/symbols.last +++ b/devel/symbols.last @@ -25,6 +25,7 @@ gnutls_alert_get_name@GNUTLS_3_4 gnutls_alert_get_strname@GNUTLS_3_4 gnutls_alert_send@GNUTLS_3_4 gnutls_alert_send_appropriate@GNUTLS_3_4 +gnutls_alert_set_read_function@GNUTLS_3_7_0 gnutls_alpn_get_selected_protocol@GNUTLS_3_4 gnutls_alpn_set_protocols@GNUTLS_3_4 gnutls_anon_allocate_client_credentials@GNUTLS_3_4 diff --git a/doc/Makefile.am b/doc/Makefile.am index fd495a83a3..ea2af31976 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -658,6 +658,8 @@ FUNCS += functions/gnutls_alert_send FUNCS += functions/gnutls_alert_send.short FUNCS += functions/gnutls_alert_send_appropriate FUNCS += functions/gnutls_alert_send_appropriate.short +FUNCS += functions/gnutls_alert_set_read_function +FUNCS += functions/gnutls_alert_set_read_function.short FUNCS += functions/gnutls_alpn_get_selected_protocol FUNCS += functions/gnutls_alpn_get_selected_protocol.short FUNCS += functions/gnutls_alpn_set_protocols diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am index 66fb70ab56..0cfec06b7a 100644 --- a/doc/manpages/Makefile.am +++ b/doc/manpages/Makefile.am @@ -130,6 +130,7 @@ APIMANS += gnutls_alert_get_name.3 APIMANS += gnutls_alert_get_strname.3 APIMANS += gnutls_alert_send.3 APIMANS += gnutls_alert_send_appropriate.3 +APIMANS += gnutls_alert_set_read_function.3 APIMANS += gnutls_alpn_get_selected_protocol.3 APIMANS += gnutls_alpn_set_protocols.3 APIMANS += gnutls_anon_allocate_client_credentials.3 diff --git a/lib/alert.c b/lib/alert.c index cfd1205d01..c8ca99286c 100644 --- a/lib/alert.c +++ b/lib/alert.c @@ -165,6 +165,22 @@ gnutls_alert_send(gnutls_session_t session, gnutls_alert_level_t level, _gnutls_record_log("REC: Sending Alert[%d|%d] - %s\n", data[0], data[1], name); + if (session->internals.alert_read_func) { + record_parameters_st *params; + + ret = _gnutls_epoch_get(session, EPOCH_WRITE_CURRENT, ¶ms); + if (ret < 0) + return gnutls_assert_val(ret); + ret = session->internals.alert_read_func(session, + params->write.level, + level, + desc); + if (ret < 0) + return gnutls_assert_val(ret); + + return ret; + } + if ((ret = _gnutls_send_int(session, GNUTLS_ALERT, -1, EPOCH_WRITE_CURRENT, data, 2, diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 182ae6f6c9..b9134dcbdd 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -1234,6 +1234,7 @@ typedef struct { int16_t h_post; /* whether post-generation/receive */ gnutls_handshake_read_func h_read_func; gnutls_handshake_secret_func h_secret_func; + gnutls_alert_read_func alert_read_func; gnutls_keylog_func keylog_func; diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 0fe672fa96..b3f7185e94 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -3265,6 +3265,28 @@ void gnutls_handshake_set_secret_function(gnutls_session_t session, gnutls_handshake_secret_func func); + /** + * gnutls_alert_read_func: + * @session: the current session + * @level: #gnutls_record_encryption_level_t + * @alert_level: the level of the alert + * @alert_desc: the alert description + * + * Function prototype for alert intercepting hooks. It is set using + * gnutls_alert_set_read_function(). + * + * Returns: Non zero on error. + * Since: 3.7.0 + */ +typedef int (*gnutls_alert_read_func) (gnutls_session_t session, + gnutls_record_encryption_level_t level, + gnutls_alert_level_t alert_level, + gnutls_alert_description_t alert_desc); + +void +gnutls_alert_set_read_function(gnutls_session_t session, + gnutls_alert_read_func func); + /* FIPS140-2 related functions */ unsigned gnutls_fips140_mode_enabled(void); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index 58db94fb78..46dab4051a 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -1334,6 +1334,7 @@ GNUTLS_3_6_14 GNUTLS_3_7_0 { global: + gnutls_alert_set_read_function; gnutls_handshake_set_read_function; gnutls_handshake_set_secret_function; gnutls_handshake_write; diff --git a/lib/state.c b/lib/state.c index bdcf4185e3..fcf6183fa4 100644 --- a/lib/state.c +++ b/lib/state.c @@ -1490,6 +1490,23 @@ gnutls_handshake_set_read_function(gnutls_session_t session, session->internals.h_read_func = func; } +/** + * gnutls_alert_set_read_function: + * @session: is #gnutls_session_t type + * @func: is the function to be called + * + * This function will set a callback to be called when an alert + * message is being sent. + * + * Since: 3.7.0 + */ +void +gnutls_alert_set_read_function(gnutls_session_t session, + gnutls_alert_read_func func) +{ + session->internals.alert_read_func = func; +} + /** * gnutls_record_get_state: * @session: is a #gnutls_session_t type