handshake: Convert handshake event callbacks variadic functions

Convert the handshake event callback type to use variable argument
list to allow for more flexibility in event-specific arguments
passed to the callbacks.

Note the uint16_t reason code is promoted to an int when using variable
arguments so va_arg(args, int) has to be used.
This commit is contained in:
Andrew Zaborowski 2019-10-28 15:04:57 +01:00 committed by Denis Kenzior
parent 2c536ba4fa
commit 0cccbea904
8 changed files with 39 additions and 24 deletions

View File

@ -159,7 +159,7 @@ static bool ap_sta_match_addr(const void *a, const void *b)
} }
static void adhoc_handshake_event(struct handshake_state *hs, static void adhoc_handshake_event(struct handshake_state *hs,
enum handshake_event event, void *event_data, void *user_data) enum handshake_event event, void *user_data, ...)
{ {
struct sta_state *sta = user_data; struct sta_state *sta = user_data;
struct adhoc_state *adhoc = sta->adhoc; struct adhoc_state *adhoc = sta->adhoc;

View File

@ -382,16 +382,19 @@ static uint32_t ap_send_mgmt_frame(struct ap_state *ap,
} }
static void ap_handshake_event(struct handshake_state *hs, static void ap_handshake_event(struct handshake_state *hs,
enum handshake_event event, void *event_data, void *user_data) enum handshake_event event, void *user_data, ...)
{ {
struct sta_state *sta = user_data; struct sta_state *sta = user_data;
va_list args;
va_start(args, user_data);
switch (event) { switch (event) {
case HANDSHAKE_EVENT_COMPLETE: case HANDSHAKE_EVENT_COMPLETE:
ap_new_rsna(sta); ap_new_rsna(sta);
break; break;
case HANDSHAKE_EVENT_FAILED: case HANDSHAKE_EVENT_FAILED:
netdev_handshake_failed(hs, l_get_u16(event_data)); netdev_handshake_failed(hs, va_arg(args, int));
/* fall through */ /* fall through */
case HANDSHAKE_EVENT_SETTING_KEYS_FAILED: case HANDSHAKE_EVENT_SETTING_KEYS_FAILED:
sta->sm = NULL; sta->sm = NULL;
@ -399,6 +402,8 @@ static void ap_handshake_event(struct handshake_state *hs,
default: default:
break; break;
} }
va_end(args);
} }
static void ap_start_rsna(struct sta_state *sta, const uint8_t *gtk_rsc) static void ap_start_rsna(struct sta_state *sta, const uint8_t *gtk_rsc)

View File

@ -915,7 +915,7 @@ static void eapol_sm_write(struct eapol_sm *sm, const struct eapol_frame *ef,
static inline void handshake_failed(struct eapol_sm *sm, uint16_t reason_code) static inline void handshake_failed(struct eapol_sm *sm, uint16_t reason_code)
{ {
handshake_event(sm->handshake, HANDSHAKE_EVENT_FAILED, &reason_code); handshake_event(sm->handshake, HANDSHAKE_EVENT_FAILED, reason_code);
eapol_sm_free(sm); eapol_sm_free(sm);
} }
@ -970,7 +970,7 @@ static void __send_eapol_start(struct eapol_sm *sm, bool noencrypt)
uint8_t buf[sizeof(struct eapol_frame)]; uint8_t buf[sizeof(struct eapol_frame)];
struct eapol_frame *frame = (struct eapol_frame *) buf; struct eapol_frame *frame = (struct eapol_frame *) buf;
handshake_event(sm->handshake, HANDSHAKE_EVENT_STARTED, NULL); handshake_event(sm->handshake, HANDSHAKE_EVENT_STARTED);
frame->header.protocol_version = EAPOL_PROTOCOL_VERSION_2001; frame->header.protocol_version = EAPOL_PROTOCOL_VERSION_2001;
frame->header.packet_type = 1; frame->header.packet_type = 1;
@ -1181,7 +1181,7 @@ static void eapol_handle_ptk_1_of_4(struct eapol_sm *sm,
* layers that we need to do a full reauth * layers that we need to do a full reauth
*/ */
handshake_event(sm->handshake, handshake_event(sm->handshake,
HANDSHAKE_EVENT_REKEY_FAILED, NULL); HANDSHAKE_EVENT_REKEY_FAILED);
return; return;
} }

View File

@ -558,7 +558,7 @@ void handshake_state_install_ptk(struct handshake_state *s)
uint32_t cipher = ie_rsn_cipher_suite_to_cipher( uint32_t cipher = ie_rsn_cipher_suite_to_cipher(
s->pairwise_cipher); s->pairwise_cipher);
handshake_event(s, HANDSHAKE_EVENT_SETTING_KEYS, NULL); handshake_event(s, HANDSHAKE_EVENT_SETTING_KEYS);
install_tk(s, handshake_get_tk(s), cipher); install_tk(s, handshake_get_tk(s), cipher);
} }
@ -912,10 +912,3 @@ bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped,
return true; return true;
} }
void handshake_event(struct handshake_state *hs,
enum handshake_event event, void *event_data)
{
if (hs->event_func)
hs->event_func(hs, event, event_data, hs->user_data);
}

View File

@ -54,7 +54,7 @@ enum handshake_event {
typedef void (*handshake_event_func_t)(struct handshake_state *hs, typedef void (*handshake_event_func_t)(struct handshake_state *hs,
enum handshake_event event, enum handshake_event event,
void *event_data, void *user_data); void *user_data, ...);
typedef bool (*handshake_get_nonce_func_t)(uint8_t nonce[]); typedef bool (*handshake_get_nonce_func_t)(uint8_t nonce[]);
typedef void (*handshake_install_tk_func_t)(struct handshake_state *hs, typedef void (*handshake_install_tk_func_t)(struct handshake_state *hs,
@ -130,6 +130,14 @@ struct handshake_state {
handshake_event_func_t event_func; handshake_event_func_t event_func;
}; };
#define handshake_event(hs, event, ...) \
do { \
if (!(hs)->event_func) \
break; \
\
(hs)->event_func((hs), event, (hs)->user_data, ##__VA_ARGS__); \
} while (0)
void handshake_state_free(struct handshake_state *s); void handshake_state_free(struct handshake_state *s);
void handshake_state_set_supplicant_address(struct handshake_state *s, void handshake_state_set_supplicant_address(struct handshake_state *s,
@ -216,6 +224,3 @@ const uint8_t *handshake_util_find_pmkid_kde(const uint8_t *data,
size_t data_len); size_t data_len);
void handshake_util_build_gtk_kde(enum crypto_cipher cipher, const uint8_t *key, void handshake_util_build_gtk_kde(enum crypto_cipher cipher, const uint8_t *key,
unsigned int key_index, uint8_t *to); unsigned int key_index, uint8_t *to);
void handshake_event(struct handshake_state *hs, enum handshake_event event,
void *event_data);

View File

@ -1094,7 +1094,7 @@ static void try_handshake_complete(struct netdev_handshake_state *nhs)
if (nhs->ptk_installed && nhs->gtk_installed && nhs->igtk_installed && if (nhs->ptk_installed && nhs->gtk_installed && nhs->igtk_installed &&
!nhs->complete) { !nhs->complete) {
nhs->complete = true; nhs->complete = true;
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE, NULL); handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE);
netdev_connect_ok(nhs->netdev); netdev_connect_ok(nhs->netdev);
} }
@ -1388,7 +1388,7 @@ static void netdev_group_timeout_cb(struct l_timeout *timeout, void *user_data)
nhs->netdev->index); nhs->netdev->index);
nhs->complete = true; nhs->complete = true;
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE, NULL); handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE);
netdev_connect_ok(nhs->netdev); netdev_connect_ok(nhs->netdev);
} }

View File

@ -650,10 +650,13 @@ static void station_reconnect(struct station *station);
static void station_handshake_event(struct handshake_state *hs, static void station_handshake_event(struct handshake_state *hs,
enum handshake_event event, enum handshake_event event,
void *event_data, void *user_data) void *user_data, ...)
{ {
struct station *station = user_data; struct station *station = user_data;
struct network *network = station->connected_network; struct network *network = station->connected_network;
va_list args;
va_start(args, user_data);
switch (event) { switch (event) {
case HANDSHAKE_EVENT_STARTED: case HANDSHAKE_EVENT_STARTED:
@ -666,7 +669,7 @@ static void station_handshake_event(struct handshake_state *hs,
network_sync_psk(network); network_sync_psk(network);
break; break;
case HANDSHAKE_EVENT_FAILED: case HANDSHAKE_EVENT_FAILED:
netdev_handshake_failed(hs, l_get_u16(event_data)); netdev_handshake_failed(hs, va_arg(args, int));
break; break;
case HANDSHAKE_EVENT_REKEY_FAILED: case HANDSHAKE_EVENT_REKEY_FAILED:
station_reconnect(station); station_reconnect(station);
@ -680,6 +683,8 @@ static void station_handshake_event(struct handshake_state *hs,
*/ */
break; break;
} }
va_end(args);
} }
static bool station_has_erp_identity(struct network *network) static bool station_has_erp_identity(struct network *network)

View File

@ -402,15 +402,22 @@ static void wsc_netdev_event(struct netdev *netdev, enum netdev_event event,
} }
static void wsc_handshake_event(struct handshake_state *hs, static void wsc_handshake_event(struct handshake_state *hs,
enum handshake_event event, void *event_data, void *user_data) enum handshake_event event, void *user_data,
...)
{ {
va_list args;
va_start(args, user_data);
switch (event) { switch (event) {
case HANDSHAKE_EVENT_FAILED: case HANDSHAKE_EVENT_FAILED:
netdev_handshake_failed(hs, l_get_u16(event_data)); netdev_handshake_failed(hs, va_arg(args, int));
break; break;
default: default:
break; break;
} }
va_end(args);
} }
static inline enum wsc_rf_band freq_to_rf_band(uint32_t freq) static inline enum wsc_rf_band freq_to_rf_band(uint32_t freq)