handshake: remove handshake related netdev events

Handshake related netdev events were removed in favor of
handshake events. Now events will be emitted on the handshake
object related to the 4-way handshake and key settings. Events
are:

HANDSHAKE_EVENT_STARTED
HANDSHAKE_EVENT_SETTING_KEYS
HANDSHAKE_EVENT_COMPLETE
HANDSHAKE_EVENT_FAILED

Right now, since netdev only operates in station mode, nothing
listens for COMPLETE/FAILED, as device/wsc gets notified by the
connect_cb when the connection was successful. The COMPLETE/
FAILED were added in preperation for AP moving into eapol/netdev.
This commit is contained in:
James Prestwood 2018-06-22 11:13:27 -07:00 committed by Denis Kenzior
parent c5893f7da8
commit aac00bf33a
7 changed files with 75 additions and 34 deletions

View File

@ -640,6 +640,34 @@ static enum ie_rsn_akm_suite device_select_akm_suite(struct network *network,
return 0;
}
static void device_handshake_event(struct handshake_state *hs,
enum handshake_event event,
void *event_data, void *user_data)
{
struct device *device = user_data;
struct network *network = device->connected_network;
switch (event) {
case HANDSHAKE_EVENT_STARTED:
l_debug("Handshaking");
break;
case HANDSHAKE_EVENT_SETTING_KEYS:
l_debug("Setting keys");
/* If we got here, then our PSK works. Save if required */
network_sync_psk(network);
break;
case HANDSHAKE_EVENT_COMPLETE:
case HANDSHAKE_EVENT_FAILED:
/*
* currently we dont care about any other events. The
* netdev_connect_cb will notify us when the connection is
* complete.
*/
break;
}
}
static struct handshake_state *device_handshake_setup(struct device *device,
struct network *network,
struct scan_bss *bss)
@ -651,6 +679,8 @@ static struct handshake_state *device_handshake_setup(struct device *device,
hs = netdev_handshake_state_new(device->netdev);
handshake_state_set_event_func(hs, device_handshake_event, device);
if (security == SECURITY_PSK || security == SECURITY_8021X) {
const struct l_settings *settings = iwd_get_config();
struct ie_rsn_info bss_info;
@ -1579,12 +1609,10 @@ static void device_signal_agent_release(struct signal_agent *agent,
l_dbus_send(dbus_get_bus(), msg);
}
static void device_netdev_event(struct netdev *netdev, enum netdev_event event,
void *user_data)
{
struct device *device = user_data;
struct network *network = device->connected_network;
switch (event) {
case NETDEV_EVENT_AUTHENTICATING:
@ -1592,16 +1620,6 @@ static void device_netdev_event(struct netdev *netdev, enum netdev_event event,
break;
case NETDEV_EVENT_ASSOCIATING:
l_debug("Associating");
break;
case NETDEV_EVENT_4WAY_HANDSHAKE:
l_debug("Handshaking");
break;
case NETDEV_EVENT_SETTING_KEYS:
l_debug("Setting keys");
/* If we got here, then our PSK works. Save if required */
network_sync_psk(network);
break;
case NETDEV_EVENT_LOST_BEACON:
device_lost_beacon(device);

View File

@ -740,6 +740,8 @@ 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);
if (deauthenticate)
deauthenticate(sm->handshake->ifindex,
sm->handshake->aa, sm->handshake->spa,
@ -799,6 +801,8 @@ static void send_eapol_start(struct l_timeout *timeout, void *user_data)
uint8_t buf[sizeof(struct eapol_frame)];
struct eapol_frame *frame = (struct eapol_frame *) buf;
handshake_event(sm->handshake, HANDSHAKE_EVENT_STARTED, NULL);
l_timeout_remove(sm->eapol_start_timeout);
sm->eapol_start_timeout = NULL;

View File

@ -187,11 +187,6 @@ bool handshake_state_set_own_wpa(struct handshake_state *s,
return handshake_state_setup_own_ciphers(s, &info);
}
void handshake_state_set_user_data(struct handshake_state *s, void *user_data)
{
s->user_data = user_data;
}
void handshake_state_set_ssid(struct handshake_state *s, const uint8_t *ssid,
size_t ssid_len)
{
@ -225,6 +220,14 @@ void handshake_state_set_kh_ids(struct handshake_state *s,
memcpy(s->r1khid, r1khid, 6);
}
void handshake_state_set_event_func(struct handshake_state *s,
handshake_event_func_t func,
void *user_data)
{
s->event_func = func;
s->user_data = user_data;
}
void handshake_state_new_snonce(struct handshake_state *s)
{
get_nonce(s->snonce);
@ -336,6 +339,8 @@ 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);
install_tk(s, ptk->tk, cipher);
}
}
@ -622,3 +627,10 @@ 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

@ -42,6 +42,17 @@ enum handshake_kde {
HANDSHAKE_KDE_MULTIBAND_KEY_ID = 0x000fac0c,
};
enum handshake_event {
HANDSHAKE_EVENT_STARTED,
HANDSHAKE_EVENT_SETTING_KEYS,
HANDSHAKE_EVENT_COMPLETE,
HANDSHAKE_EVENT_FAILED
};
typedef void (*handshake_event_func_t)(struct handshake_state *hs,
enum handshake_event event,
void *event_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,
const uint8_t *tk, uint32_t cipher);
@ -96,6 +107,8 @@ struct handshake_state {
void *user_data;
void (*free)(struct handshake_state *s);
handshake_event_func_t event_func;
};
void handshake_state_free(struct handshake_state *s);
@ -104,7 +117,6 @@ void handshake_state_set_supplicant_address(struct handshake_state *s,
const uint8_t *spa);
void handshake_state_set_authenticator_address(struct handshake_state *s,
const uint8_t *aa);
void handshake_state_set_user_data(struct handshake_state *s, void *user_data);
void handshake_state_set_pmk(struct handshake_state *s, const uint8_t *pmk,
size_t pmk_len);
void handshake_state_set_8021x_config(struct handshake_state *s,
@ -128,6 +140,10 @@ void handshake_state_set_kh_ids(struct handshake_state *s,
const uint8_t *r0khid, size_t r0khid_len,
const uint8_t *r1khid);
void handshake_state_set_event_func(struct handshake_state *s,
handshake_event_func_t func,
void *user_data);
void handshake_state_new_snonce(struct handshake_state *s);
void handshake_state_new_anonce(struct handshake_state *s);
void handshake_state_set_anonce(struct handshake_state *s,
@ -164,3 +180,6 @@ const uint8_t *handshake_util_find_igtk_kde(const uint8_t *data,
size_t data_len, size_t *out_igtk_len);
const uint8_t *handshake_util_find_pmkid_kde(const uint8_t *data,
size_t data_len);
void handshake_event(struct handshake_state *hs, enum handshake_event event,
void *event_data);

View File

@ -943,6 +943,7 @@ static void netdev_setting_keys_failed(struct netdev_handshake_state *nhs,
nhs->set_station_cmd_id = 0;
netdev->result = NETDEV_RESULT_KEY_SETTING_FAILED;
msg = netdev_build_cmd_disconnect(netdev,
MMPDU_REASON_CODE_UNSPECIFIED);
netdev->disconnect_cmd_id = l_genl_family_send(nl80211, msg,
@ -972,6 +973,8 @@ static void netdev_set_station_cb(struct l_genl_msg *msg, void *user_data)
return;
}
handshake_event(&nhs->super, HANDSHAKE_EVENT_COMPLETE, NULL);
done:
netdev_connect_ok(netdev);
}
@ -1248,10 +1251,6 @@ static void netdev_set_tk(struct handshake_state *hs,
l_debug("%d", netdev->index);
if (netdev->event_filter)
netdev->event_filter(netdev, NETDEV_EVENT_SETTING_KEYS,
netdev->user_data);
rc = MMPDU_REASON_CODE_INVALID_PAIRWISE_CIPHER;
if (!netdev_copy_tk(tk_buf, tk, cipher, false))
goto invalid_key;
@ -1599,14 +1598,8 @@ static void netdev_connect_event(struct l_genl_msg *msg,
if (!eapol_start(netdev->sm))
goto error;
if (!netdev->in_ft) {
if (netdev->event_filter)
netdev->event_filter(netdev,
NETDEV_EVENT_4WAY_HANDSHAKE,
netdev->user_data);
if (!netdev->in_ft)
return;
}
}
if (netdev->in_ft) {

View File

@ -40,8 +40,6 @@ enum netdev_result {
enum netdev_event {
NETDEV_EVENT_AUTHENTICATING,
NETDEV_EVENT_ASSOCIATING,
NETDEV_EVENT_4WAY_HANDSHAKE,
NETDEV_EVENT_SETTING_KEYS,
NETDEV_EVENT_LOST_BEACON,
NETDEV_EVENT_DISCONNECT_BY_AP,
NETDEV_EVENT_DISCONNECT_BY_SME,

View File

@ -367,9 +367,6 @@ static void wsc_netdev_event(struct netdev *netdev, enum netdev_event event,
case NETDEV_EVENT_AUTHENTICATING:
case NETDEV_EVENT_ASSOCIATING:
break;
case NETDEV_EVENT_4WAY_HANDSHAKE:
l_info("Running EAP-WSC");
break;
case NETDEV_EVENT_LOST_BEACON:
l_debug("Lost beacon");
break;