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,
enum handshake_event event, void *event_data, void *user_data)
enum handshake_event event, void *user_data, ...)
{
struct sta_state *sta = user_data;
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,
enum handshake_event event, void *event_data, void *user_data)
enum handshake_event event, void *user_data, ...)
{
struct sta_state *sta = user_data;
va_list args;
va_start(args, user_data);
switch (event) {
case HANDSHAKE_EVENT_COMPLETE:
ap_new_rsna(sta);
break;
case HANDSHAKE_EVENT_FAILED:
netdev_handshake_failed(hs, l_get_u16(event_data));
netdev_handshake_failed(hs, va_arg(args, int));
/* fall through */
case HANDSHAKE_EVENT_SETTING_KEYS_FAILED:
sta->sm = NULL;
@ -399,6 +402,8 @@ static void ap_handshake_event(struct handshake_state *hs,
default:
break;
}
va_end(args);
}
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)
{
handshake_event(sm->handshake, HANDSHAKE_EVENT_FAILED, &reason_code);
handshake_event(sm->handshake, HANDSHAKE_EVENT_FAILED, reason_code);
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)];
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.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
*/
handshake_event(sm->handshake,
HANDSHAKE_EVENT_REKEY_FAILED, NULL);
HANDSHAKE_EVENT_REKEY_FAILED);
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(
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);
}
@ -912,10 +912,3 @@ bool handshake_decode_fte_key(struct handshake_state *s, const uint8_t *wrapped,
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,
enum handshake_event event,
void *event_data, void *user_data);
void *user_data, ...);
typedef bool (*handshake_get_nonce_func_t)(uint8_t nonce[]);
typedef void (*handshake_install_tk_func_t)(struct handshake_state *hs,
@ -130,6 +130,14 @@ struct handshake_state {
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_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);
void handshake_util_build_gtk_kde(enum crypto_cipher cipher, const uint8_t *key,
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 &&
!nhs->complete) {
nhs->complete = true;
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE, NULL);
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE);
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->complete = true;
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE, NULL);
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE);
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,
enum handshake_event event,
void *event_data, void *user_data)
void *user_data, ...)
{
struct station *station = user_data;
struct network *network = station->connected_network;
va_list args;
va_start(args, user_data);
switch (event) {
case HANDSHAKE_EVENT_STARTED:
@ -666,7 +669,7 @@ static void station_handshake_event(struct handshake_state *hs,
network_sync_psk(network);
break;
case HANDSHAKE_EVENT_FAILED:
netdev_handshake_failed(hs, l_get_u16(event_data));
netdev_handshake_failed(hs, va_arg(args, int));
break;
case HANDSHAKE_EVENT_REKEY_FAILED:
station_reconnect(station);
@ -680,6 +683,8 @@ static void station_handshake_event(struct handshake_state *hs,
*/
break;
}
va_end(args);
}
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,
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) {
case HANDSHAKE_EVENT_FAILED:
netdev_handshake_failed(hs, l_get_u16(event_data));
netdev_handshake_failed(hs, va_arg(args, int));
break;
default:
break;
}
va_end(args);
}
static inline enum wsc_rf_band freq_to_rf_band(uint32_t freq)