eapol: Use handshake_state to store state
Remove the keys and other data from struct eapol_sm, update device.c, netdev.c and wsc.c to use the handshake_state object instead of eapol_sm. This also gets rid of eapol_cancel and the ifindex parameter in some of the eapol functions where sm->handshake->ifindex can be used instead.
This commit is contained in:
parent
061dad2ff5
commit
e32ffc4d98
34
src/device.c
34
src/device.c
|
@ -34,7 +34,7 @@
|
||||||
#include "src/common.h"
|
#include "src/common.h"
|
||||||
#include "src/util.h"
|
#include "src/util.h"
|
||||||
#include "src/ie.h"
|
#include "src/ie.h"
|
||||||
#include "src/eapol.h"
|
#include "src/handshake.h"
|
||||||
#include "src/wiphy.h"
|
#include "src/wiphy.h"
|
||||||
#include "src/scan.h"
|
#include "src/scan.h"
|
||||||
#include "src/netdev.h"
|
#include "src/netdev.h"
|
||||||
|
@ -677,7 +677,7 @@ void device_connect_network(struct device *device, struct network *network,
|
||||||
enum security security = network_get_security(network);
|
enum security security = network_get_security(network);
|
||||||
struct wiphy *wiphy = device->wiphy;
|
struct wiphy *wiphy = device->wiphy;
|
||||||
struct l_dbus *dbus = dbus_get_bus();
|
struct l_dbus *dbus = dbus_get_bus();
|
||||||
struct eapol_sm *sm = NULL;
|
struct handshake_state *hs = NULL;
|
||||||
bool add_mde = false;
|
bool add_mde = false;
|
||||||
uint8_t *mde;
|
uint8_t *mde;
|
||||||
|
|
||||||
|
@ -718,30 +718,26 @@ void device_connect_network(struct device *device, struct network *network,
|
||||||
} else if (info.group_management_cipher != 0)
|
} else if (info.group_management_cipher != 0)
|
||||||
info.mfpc = true;
|
info.mfpc = true;
|
||||||
|
|
||||||
sm = eapol_sm_new();
|
hs = handshake_state_new(netdev_get_ifindex(device->netdev));
|
||||||
|
|
||||||
eapol_sm_set_authenticator_address(sm, bss->addr);
|
|
||||||
eapol_sm_set_supplicant_address(sm,
|
|
||||||
netdev_get_address(device->netdev));
|
|
||||||
|
|
||||||
ssid = network_get_ssid(network);
|
ssid = network_get_ssid(network);
|
||||||
eapol_sm_set_ssid(sm, (void *) ssid, strlen(ssid));
|
handshake_state_set_ssid(hs, (void *) ssid, strlen(ssid));
|
||||||
|
|
||||||
/* RSN takes priority */
|
/* RSN takes priority */
|
||||||
if (bss->rsne) {
|
if (bss->rsne) {
|
||||||
ie_build_rsne(&info, rsne_buf);
|
ie_build_rsne(&info, rsne_buf);
|
||||||
eapol_sm_set_ap_rsn(sm, bss->rsne);
|
handshake_state_set_ap_rsn(hs, bss->rsne);
|
||||||
eapol_sm_set_own_rsn(sm, rsne_buf);
|
handshake_state_set_own_rsn(hs, rsne_buf);
|
||||||
} else {
|
} else {
|
||||||
ie_build_wpa(&info, rsne_buf);
|
ie_build_wpa(&info, rsne_buf);
|
||||||
eapol_sm_set_ap_wpa(sm, bss->wpa);
|
handshake_state_set_ap_wpa(hs, bss->wpa);
|
||||||
eapol_sm_set_own_wpa(sm, rsne_buf);
|
handshake_state_set_own_wpa(hs, rsne_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (security == SECURITY_PSK)
|
if (security == SECURITY_PSK)
|
||||||
eapol_sm_set_pmk(sm, network_get_psk(network));
|
handshake_state_set_pmk(hs, network_get_psk(network));
|
||||||
else
|
else
|
||||||
eapol_sm_set_8021x_config(sm,
|
handshake_state_set_8021x_config(hs,
|
||||||
network_get_settings(network));
|
network_get_settings(network));
|
||||||
|
|
||||||
if (info.akm_suites & (IE_RSN_AKM_SUITE_FT_OVER_8021X |
|
if (info.akm_suites & (IE_RSN_AKM_SUITE_FT_OVER_8021X |
|
||||||
|
@ -762,18 +758,18 @@ void device_connect_network(struct device *device, struct network *network,
|
||||||
mde[1] = 3;
|
mde[1] = 3;
|
||||||
memcpy(mde + 2, bss->mde, 3);
|
memcpy(mde + 2, bss->mde, 3);
|
||||||
|
|
||||||
if (sm)
|
if (hs)
|
||||||
eapol_sm_set_mde(sm, mde);
|
handshake_state_set_mde(hs, mde);
|
||||||
} else
|
} else
|
||||||
mde = NULL;
|
mde = NULL;
|
||||||
|
|
||||||
device->connect_pending = l_dbus_message_ref(message);
|
device->connect_pending = l_dbus_message_ref(message);
|
||||||
|
|
||||||
if (netdev_connect(device->netdev, bss, sm, mde,
|
if (netdev_connect(device->netdev, bss, hs, mde,
|
||||||
device_netdev_event,
|
device_netdev_event,
|
||||||
device_connect_cb, device) < 0) {
|
device_connect_cb, device) < 0) {
|
||||||
if (sm)
|
if (hs)
|
||||||
eapol_sm_free(sm);
|
handshake_state_free(hs);
|
||||||
|
|
||||||
l_free(mde);
|
l_free(mde);
|
||||||
|
|
||||||
|
|
708
src/eapol.c
708
src/eapol.c
File diff suppressed because it is too large
Load Diff
49
src/eapol.h
49
src/eapol.h
|
@ -48,6 +48,7 @@ enum eapol_key_descriptor_version {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eapol_sm;
|
struct eapol_sm;
|
||||||
|
struct handshake_state;
|
||||||
|
|
||||||
struct eapol_header {
|
struct eapol_header {
|
||||||
uint8_t protocol_version;
|
uint8_t protocol_version;
|
||||||
|
@ -108,22 +109,6 @@ typedef int (*eapol_tx_packet_func_t)(uint32_t ifindex, const uint8_t *aa,
|
||||||
const uint8_t *spa,
|
const uint8_t *spa,
|
||||||
const struct eapol_frame *ef,
|
const struct eapol_frame *ef,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
typedef bool (*eapol_get_nonce_func_t)(uint8_t nonce[]);
|
|
||||||
typedef void (*eapol_install_tk_func_t)(uint32_t ifindex, const uint8_t *aa,
|
|
||||||
const uint8_t *tk, uint32_t cipher,
|
|
||||||
void *user_data);
|
|
||||||
typedef void (*eapol_install_gtk_func_t)(uint32_t ifindex, uint8_t key_index,
|
|
||||||
const uint8_t *gtk, uint8_t gtk_len,
|
|
||||||
const uint8_t *rsc, uint8_t rsc_len,
|
|
||||||
uint32_t cipher, void *user_data);
|
|
||||||
typedef void (*eapol_install_igtk_func_t)(uint32_t ifindex, uint8_t key_index,
|
|
||||||
const uint8_t *igtk, uint8_t igtk_len,
|
|
||||||
const uint8_t *ipn, uint8_t ipn_len,
|
|
||||||
uint32_t cipher, void *user_data);
|
|
||||||
typedef void (*eapol_deauthenticate_func_t)(uint32_t ifindex, const uint8_t *aa,
|
|
||||||
const uint8_t *spa,
|
|
||||||
uint16_t reason_code,
|
|
||||||
void *user_data);
|
|
||||||
typedef void (*eapol_rekey_offload_func_t)(uint32_t ifindex,
|
typedef void (*eapol_rekey_offload_func_t)(uint32_t ifindex,
|
||||||
const uint8_t *kek,
|
const uint8_t *kek,
|
||||||
const uint8_t *kck,
|
const uint8_t *kck,
|
||||||
|
@ -132,6 +117,10 @@ typedef void (*eapol_rekey_offload_func_t)(uint32_t ifindex,
|
||||||
typedef void (*eapol_sm_event_func_t)(unsigned int event,
|
typedef void (*eapol_sm_event_func_t)(unsigned int event,
|
||||||
const void *event_data,
|
const void *event_data,
|
||||||
void *user_data);
|
void *user_data);
|
||||||
|
typedef void (*eapol_deauthenticate_func_t)(uint32_t ifindex, const uint8_t *aa,
|
||||||
|
const uint8_t *spa,
|
||||||
|
uint16_t reason_code,
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
bool eapol_calculate_mic(const uint8_t *kck, const struct eapol_key *frame,
|
bool eapol_calculate_mic(const uint8_t *kck, const struct eapol_key *frame,
|
||||||
uint8_t *mic);
|
uint8_t *mic);
|
||||||
|
@ -176,47 +165,23 @@ void __eapol_rx_packet(uint32_t ifindex, const uint8_t *aa,
|
||||||
void __eapol_set_tx_packet_func(eapol_tx_packet_func_t func);
|
void __eapol_set_tx_packet_func(eapol_tx_packet_func_t func);
|
||||||
void __eapol_set_tx_user_data(void *user_data);
|
void __eapol_set_tx_user_data(void *user_data);
|
||||||
|
|
||||||
void __eapol_set_get_nonce_func(eapol_get_nonce_func_t func);
|
|
||||||
void __eapol_set_install_tk_func(eapol_install_tk_func_t func);
|
|
||||||
void __eapol_set_install_gtk_func(eapol_install_gtk_func_t func);
|
|
||||||
void __eapol_set_install_igtk_func(eapol_install_igtk_func_t func);
|
|
||||||
void __eapol_set_deauthenticate_func(eapol_deauthenticate_func_t func);
|
void __eapol_set_deauthenticate_func(eapol_deauthenticate_func_t func);
|
||||||
void __eapol_set_rekey_offload_func(eapol_rekey_offload_func_t func);
|
void __eapol_set_rekey_offload_func(eapol_rekey_offload_func_t func);
|
||||||
void __eapol_update_replay_counter(uint32_t ifindex, const uint8_t *spa,
|
void __eapol_update_replay_counter(uint32_t ifindex, const uint8_t *spa,
|
||||||
const uint8_t *aa, uint64_t replay_counter);
|
const uint8_t *aa, uint64_t replay_counter);
|
||||||
|
|
||||||
struct eapol_sm *eapol_sm_new();
|
struct eapol_sm *eapol_sm_new(struct handshake_state *hs);
|
||||||
void eapol_sm_free(struct eapol_sm *sm);
|
void eapol_sm_free(struct eapol_sm *sm);
|
||||||
|
|
||||||
void eapol_sm_set_protocol_version(struct eapol_sm *sm,
|
void eapol_sm_set_protocol_version(struct eapol_sm *sm,
|
||||||
enum eapol_protocol_version protocol_version);
|
enum eapol_protocol_version protocol_version);
|
||||||
|
|
||||||
void eapol_sm_set_supplicant_address(struct eapol_sm *sm, const uint8_t *spa);
|
|
||||||
void eapol_sm_set_authenticator_address(struct eapol_sm *sm, const uint8_t *aa);
|
|
||||||
void eapol_sm_set_pmk(struct eapol_sm *sm, const uint8_t *pmk);
|
|
||||||
void eapol_sm_set_8021x_config(struct eapol_sm *sm,
|
|
||||||
struct l_settings *settings);
|
|
||||||
void eapol_sm_set_use_eapol_start(struct eapol_sm *sm, bool enabled);
|
void eapol_sm_set_use_eapol_start(struct eapol_sm *sm, bool enabled);
|
||||||
void eapol_sm_set_ap_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie);
|
|
||||||
bool eapol_sm_set_own_rsn(struct eapol_sm *sm, const uint8_t *rsn_ie);
|
|
||||||
void eapol_sm_set_ap_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie);
|
|
||||||
bool eapol_sm_set_own_wpa(struct eapol_sm *sm, const uint8_t *wpa_ie);
|
|
||||||
void eapol_sm_set_user_data(struct eapol_sm *sm, void *user_data);
|
void eapol_sm_set_user_data(struct eapol_sm *sm, void *user_data);
|
||||||
void eapol_sm_set_event_func(struct eapol_sm *sm, eapol_sm_event_func_t func);
|
void eapol_sm_set_event_func(struct eapol_sm *sm, eapol_sm_event_func_t func);
|
||||||
void eapol_sm_set_ssid(struct eapol_sm *sm, const uint8_t *ssid,
|
|
||||||
size_t ssid_len);
|
|
||||||
void eapol_sm_set_mde(struct eapol_sm *sm, const uint8_t *mde);
|
|
||||||
void eapol_sm_set_fte(struct eapol_sm *sm, const uint8_t *fte);
|
|
||||||
void eapol_sm_set_kh_ids(struct eapol_sm *sm, const uint8_t *r0khid,
|
|
||||||
size_t r0khid_len, const uint8_t *r1khid);
|
|
||||||
|
|
||||||
uint32_t eapol_sm_get_pairwise_cipher(struct eapol_sm *sm);
|
void eapol_register(struct eapol_sm *sm);
|
||||||
uint32_t eapol_sm_get_group_cipher(struct eapol_sm *sm);
|
|
||||||
const uint8_t *eapol_sm_get_own_ie(struct eapol_sm *sm, size_t *out_ie_len);
|
|
||||||
|
|
||||||
void eapol_register(uint32_t ifindex, struct eapol_sm *sm);
|
|
||||||
void eapol_start(struct eapol_sm *sm);
|
void eapol_start(struct eapol_sm *sm);
|
||||||
void eapol_cancel(uint32_t ifindex);
|
|
||||||
|
|
||||||
void eapol_pae_open();
|
void eapol_pae_open();
|
||||||
void eapol_pae_close();
|
void eapol_pae_close();
|
||||||
|
|
79
src/netdev.c
79
src/netdev.c
|
@ -43,6 +43,7 @@
|
||||||
#include "src/ie.h"
|
#include "src/ie.h"
|
||||||
#include "src/mpdu.h"
|
#include "src/mpdu.h"
|
||||||
#include "src/eapol.h"
|
#include "src/eapol.h"
|
||||||
|
#include "src/handshake.h"
|
||||||
#include "src/crypto.h"
|
#include "src/crypto.h"
|
||||||
#include "src/device.h"
|
#include "src/device.h"
|
||||||
#include "src/scan.h"
|
#include "src/scan.h"
|
||||||
|
@ -63,6 +64,7 @@ struct netdev {
|
||||||
netdev_disconnect_cb_t disconnect_cb;
|
netdev_disconnect_cb_t disconnect_cb;
|
||||||
void *user_data;
|
void *user_data;
|
||||||
struct eapol_sm *sm;
|
struct eapol_sm *sm;
|
||||||
|
struct handshake_state *handshake;
|
||||||
uint8_t remote_addr[ETH_ALEN];
|
uint8_t remote_addr[ETH_ALEN];
|
||||||
uint32_t pairwise_new_key_cmd_id;
|
uint32_t pairwise_new_key_cmd_id;
|
||||||
uint32_t pairwise_set_key_cmd_id;
|
uint32_t pairwise_set_key_cmd_id;
|
||||||
|
@ -78,7 +80,6 @@ struct netdev {
|
||||||
|
|
||||||
bool connected : 1;
|
bool connected : 1;
|
||||||
bool operational : 1;
|
bool operational : 1;
|
||||||
bool eapol_active : 1;
|
|
||||||
bool rekey_offload_support : 1;
|
bool rekey_offload_support : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,9 +279,9 @@ static void netdev_connect_free(struct netdev *netdev)
|
||||||
netdev->sm = NULL;
|
netdev->sm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->eapol_active) {
|
if (netdev->handshake) {
|
||||||
eapol_cancel(netdev->index);
|
handshake_state_free(netdev->handshake);
|
||||||
netdev->eapol_active = false;
|
netdev->handshake = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev->operational = false;
|
netdev->operational = false;
|
||||||
|
@ -987,7 +988,7 @@ static void netdev_handshake_failed(uint32_t ifindex,
|
||||||
|
|
||||||
l_error("4-Way Handshake failed for ifindex: %d", ifindex);
|
l_error("4-Way Handshake failed for ifindex: %d", ifindex);
|
||||||
|
|
||||||
netdev->eapol_active = false;
|
netdev->sm = NULL;
|
||||||
|
|
||||||
netdev->result = NETDEV_RESULT_HANDSHAKE_FAILED;
|
netdev->result = NETDEV_RESULT_HANDSHAKE_FAILED;
|
||||||
msg = netdev_build_cmd_deauthenticate(netdev, reason_code);
|
msg = netdev_build_cmd_deauthenticate(netdev, reason_code);
|
||||||
|
@ -1138,17 +1139,17 @@ static void netdev_connect_event(struct l_genl_msg *msg,
|
||||||
* in a non-RSN (12.4.2 vs. 12.4.3).
|
* in a non-RSN (12.4.2 vs. 12.4.3).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (netdev->mde && !netdev->sm && fte)
|
if (netdev->mde && !netdev->handshake && fte)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (netdev->mde && netdev->sm) {
|
if (netdev->mde && netdev->handshake) {
|
||||||
struct ie_ft_info ft_info;
|
struct ie_ft_info ft_info;
|
||||||
uint8_t zeros[32];
|
uint8_t zeros[32];
|
||||||
|
|
||||||
if (!fte)
|
if (!fte)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
eapol_sm_set_fte(netdev->sm, fte);
|
handshake_state_set_fte(netdev->handshake, fte);
|
||||||
|
|
||||||
if (ie_parse_fast_bss_transition_from_data(fte,
|
if (ie_parse_fast_bss_transition_from_data(fte,
|
||||||
fte[1] + 2,
|
fte[1] + 2,
|
||||||
|
@ -1168,19 +1169,19 @@ static void netdev_connect_event(struct l_genl_msg *msg,
|
||||||
memcmp(ft_info.snonce, zeros, 32))
|
memcmp(ft_info.snonce, zeros, 32))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
eapol_sm_set_kh_ids(netdev->sm, ft_info.r0khid,
|
handshake_state_set_kh_ids(netdev->handshake,
|
||||||
|
ft_info.r0khid,
|
||||||
ft_info.r0khid_len,
|
ft_info.r0khid_len,
|
||||||
ft_info.r1khid);
|
ft_info.r1khid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netdev->eapol_active) {
|
if (netdev->sm) {
|
||||||
/*
|
/*
|
||||||
* Start processing EAPoL frames now that the state machine
|
* Start processing EAPoL frames now that the state machine
|
||||||
* has all the input data even in FT mode.
|
* has all the input data even in FT mode.
|
||||||
*/
|
*/
|
||||||
eapol_start(netdev->sm);
|
eapol_start(netdev->sm);
|
||||||
netdev->sm = NULL;
|
|
||||||
|
|
||||||
if (netdev->event_filter)
|
if (netdev->event_filter)
|
||||||
netdev->event_filter(netdev,
|
netdev->event_filter(netdev,
|
||||||
|
@ -1229,9 +1230,11 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
* events can be reversed (e.g. connect_event, then PAE data)
|
* events can be reversed (e.g. connect_event, then PAE data)
|
||||||
* due to scheduling
|
* due to scheduling
|
||||||
*/
|
*/
|
||||||
if (netdev->sm) {
|
if (netdev->handshake) {
|
||||||
eapol_register(netdev->index, netdev->sm);
|
if (!netdev->sm)
|
||||||
netdev->eapol_active = true;
|
netdev->sm = eapol_sm_new(netdev->handshake);
|
||||||
|
|
||||||
|
eapol_register(netdev->sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1243,7 +1246,7 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
|
||||||
|
|
||||||
static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||||
struct scan_bss *bss,
|
struct scan_bss *bss,
|
||||||
struct eapol_sm *sm,
|
struct handshake_state *hs,
|
||||||
const uint8_t *mde)
|
const uint8_t *mde)
|
||||||
{
|
{
|
||||||
uint32_t auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
|
uint32_t auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
|
||||||
|
@ -1263,14 +1266,10 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||||
if (bss->capability & IE_BSS_CAP_PRIVACY)
|
if (bss->capability & IE_BSS_CAP_PRIVACY)
|
||||||
l_genl_msg_append_attr(msg, NL80211_ATTR_PRIVACY, 0, NULL);
|
l_genl_msg_append_attr(msg, NL80211_ATTR_PRIVACY, 0, NULL);
|
||||||
|
|
||||||
if (sm) {
|
if (hs) {
|
||||||
uint32_t cipher;
|
|
||||||
uint32_t nl_cipher;
|
uint32_t nl_cipher;
|
||||||
size_t ie_len;
|
|
||||||
const uint8_t *ie;
|
|
||||||
|
|
||||||
cipher = eapol_sm_get_pairwise_cipher(sm);
|
if (hs->pairwise_cipher == IE_RSN_CIPHER_SUITE_CCMP)
|
||||||
if (cipher == IE_RSN_CIPHER_SUITE_CCMP)
|
|
||||||
nl_cipher = CRYPTO_CIPHER_CCMP;
|
nl_cipher = CRYPTO_CIPHER_CCMP;
|
||||||
else
|
else
|
||||||
nl_cipher = CRYPTO_CIPHER_TKIP;
|
nl_cipher = CRYPTO_CIPHER_TKIP;
|
||||||
|
@ -1278,8 +1277,7 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||||
l_genl_msg_append_attr(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
|
l_genl_msg_append_attr(msg, NL80211_ATTR_CIPHER_SUITES_PAIRWISE,
|
||||||
4, &nl_cipher);
|
4, &nl_cipher);
|
||||||
|
|
||||||
cipher = eapol_sm_get_group_cipher(sm);
|
if (hs->group_cipher == IE_RSN_CIPHER_SUITE_CCMP)
|
||||||
if (cipher == IE_RSN_CIPHER_SUITE_CCMP)
|
|
||||||
nl_cipher = CRYPTO_CIPHER_CCMP;
|
nl_cipher = CRYPTO_CIPHER_CCMP;
|
||||||
else
|
else
|
||||||
nl_cipher = CRYPTO_CIPHER_TKIP;
|
nl_cipher = CRYPTO_CIPHER_TKIP;
|
||||||
|
@ -1289,10 +1287,9 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||||
|
|
||||||
l_genl_msg_append_attr(msg, NL80211_ATTR_CONTROL_PORT, 0, NULL);
|
l_genl_msg_append_attr(msg, NL80211_ATTR_CONTROL_PORT, 0, NULL);
|
||||||
|
|
||||||
ie = eapol_sm_get_own_ie(sm, &ie_len);
|
if (hs->own_ie) {
|
||||||
if (ie) {
|
iov[iov_elems].iov_base = (void *) hs->own_ie;
|
||||||
iov[iov_elems].iov_base = (void *) ie;
|
iov[iov_elems].iov_len = hs->own_ie[1] + 2;
|
||||||
iov[iov_elems].iov_len = ie_len;
|
|
||||||
iov_elems += 1;
|
iov_elems += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1312,8 +1309,8 @@ static struct l_genl_msg *netdev_build_cmd_connect(struct netdev *netdev,
|
||||||
static int netdev_connect_common(struct netdev *netdev,
|
static int netdev_connect_common(struct netdev *netdev,
|
||||||
struct l_genl_msg *cmd_connect,
|
struct l_genl_msg *cmd_connect,
|
||||||
struct scan_bss *bss,
|
struct scan_bss *bss,
|
||||||
struct eapol_sm *sm,
|
struct handshake_state *hs,
|
||||||
const uint8_t *mde,
|
struct eapol_sm *sm, const uint8_t *mde,
|
||||||
netdev_event_func_t event_filter,
|
netdev_event_func_t event_filter,
|
||||||
netdev_connect_cb_t cb, void *user_data)
|
netdev_connect_cb_t cb, void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -1331,18 +1328,23 @@ static int netdev_connect_common(struct netdev *netdev,
|
||||||
netdev->user_data = user_data;
|
netdev->user_data = user_data;
|
||||||
memcpy(netdev->remote_addr, bss->addr, ETH_ALEN);
|
memcpy(netdev->remote_addr, bss->addr, ETH_ALEN);
|
||||||
netdev->connected = true;
|
netdev->connected = true;
|
||||||
|
netdev->handshake = hs;
|
||||||
netdev->sm = sm;
|
netdev->sm = sm;
|
||||||
|
|
||||||
if (mde)
|
if (mde)
|
||||||
netdev->mde = l_memdup(mde, mde[1] + 2);
|
netdev->mde = l_memdup(mde, mde[1] + 2);
|
||||||
|
|
||||||
|
if (hs) {
|
||||||
|
handshake_state_set_authenticator_address(hs, bss->addr);
|
||||||
|
handshake_state_set_supplicant_address(hs, netdev->addr);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
||||||
struct eapol_sm *sm,
|
struct handshake_state *hs, const uint8_t *mde,
|
||||||
const uint8_t *mde,
|
|
||||||
netdev_event_func_t event_filter,
|
netdev_event_func_t event_filter,
|
||||||
netdev_connect_cb_t cb, void *user_data)
|
netdev_connect_cb_t cb, void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -1351,16 +1353,16 @@ int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
||||||
if (netdev->connected)
|
if (netdev->connected)
|
||||||
return -EISCONN;
|
return -EISCONN;
|
||||||
|
|
||||||
cmd_connect = netdev_build_cmd_connect(netdev, bss, sm, mde);
|
cmd_connect = netdev_build_cmd_connect(netdev, bss, hs, mde);
|
||||||
if (!cmd_connect)
|
if (!cmd_connect)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return netdev_connect_common(netdev, cmd_connect, bss, sm, mde,
|
return netdev_connect_common(netdev, cmd_connect, bss, hs, NULL, mde,
|
||||||
event_filter, cb, user_data);
|
event_filter, cb, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss,
|
int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss,
|
||||||
struct eapol_sm *sm,
|
struct handshake_state *hs, struct eapol_sm *sm,
|
||||||
netdev_event_func_t event_filter,
|
netdev_event_func_t event_filter,
|
||||||
netdev_connect_cb_t cb, void *user_data)
|
netdev_connect_cb_t cb, void *user_data)
|
||||||
{
|
{
|
||||||
|
@ -1394,7 +1396,7 @@ int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss,
|
||||||
l_genl_msg_append_attr(cmd_connect, NL80211_ATTR_IE, ie_len, ie);
|
l_genl_msg_append_attr(cmd_connect, NL80211_ATTR_IE, ie_len, ie);
|
||||||
l_free(ie);
|
l_free(ie);
|
||||||
|
|
||||||
return netdev_connect_common(netdev, cmd_connect, bss, sm, NULL,
|
return netdev_connect_common(netdev, cmd_connect, bss, hs, sm, NULL,
|
||||||
event_filter, cb, user_data);
|
event_filter, cb, user_data);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -1957,9 +1959,10 @@ bool netdev_init(struct l_genl_family *in,
|
||||||
NULL, NULL))
|
NULL, NULL))
|
||||||
l_error("Registering for MLME notification failed");
|
l_error("Registering for MLME notification failed");
|
||||||
|
|
||||||
__eapol_set_install_tk_func(netdev_set_tk);
|
__handshake_set_install_tk_func(netdev_set_tk);
|
||||||
__eapol_set_install_gtk_func(netdev_set_gtk);
|
__handshake_set_install_gtk_func(netdev_set_gtk);
|
||||||
__eapol_set_install_igtk_func(netdev_set_igtk);
|
__handshake_set_install_igtk_func(netdev_set_igtk);
|
||||||
|
|
||||||
__eapol_set_deauthenticate_func(netdev_handshake_failed);
|
__eapol_set_deauthenticate_func(netdev_handshake_failed);
|
||||||
__eapol_set_rekey_offload_func(netdev_set_rekey_offload);
|
__eapol_set_rekey_offload_func(netdev_set_rekey_offload);
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
struct netdev;
|
struct netdev;
|
||||||
struct scan_bss;
|
struct scan_bss;
|
||||||
struct eapol_sm *sm;
|
struct handshake_state;
|
||||||
|
struct eapol_sm;
|
||||||
|
|
||||||
enum netdev_result {
|
enum netdev_result {
|
||||||
NETDEV_RESULT_OK,
|
NETDEV_RESULT_OK,
|
||||||
|
@ -73,11 +74,11 @@ const char *netdev_get_name(struct netdev *netdev);
|
||||||
bool netdev_get_is_up(struct netdev *netdev);
|
bool netdev_get_is_up(struct netdev *netdev);
|
||||||
|
|
||||||
int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
int netdev_connect(struct netdev *netdev, struct scan_bss *bss,
|
||||||
struct eapol_sm *sm, const uint8_t *mde,
|
struct handshake_state *hs, const uint8_t *mde,
|
||||||
netdev_event_func_t event_filter,
|
netdev_event_func_t event_filter,
|
||||||
netdev_connect_cb_t cb, void *user_data);
|
netdev_connect_cb_t cb, void *user_data);
|
||||||
int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss,
|
int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss,
|
||||||
struct eapol_sm *sm,
|
struct handshake_state *hs, struct eapol_sm *sm,
|
||||||
netdev_event_func_t event_filter,
|
netdev_event_func_t event_filter,
|
||||||
netdev_connect_cb_t cb, void *user_data);
|
netdev_connect_cb_t cb, void *user_data);
|
||||||
int netdev_disconnect(struct netdev *netdev,
|
int netdev_disconnect(struct netdev *netdev,
|
||||||
|
|
24
src/wsc.c
24
src/wsc.c
|
@ -36,6 +36,7 @@
|
||||||
#include "src/wscutil.h"
|
#include "src/wscutil.h"
|
||||||
#include "src/util.h"
|
#include "src/util.h"
|
||||||
#include "src/wsc.h"
|
#include "src/wsc.h"
|
||||||
|
#include "src/handshake.h"
|
||||||
#include "src/eapol.h"
|
#include "src/eapol.h"
|
||||||
#include "src/eap-wsc.h"
|
#include "src/eap-wsc.h"
|
||||||
#include "src/crypto.h"
|
#include "src/crypto.h"
|
||||||
|
@ -66,6 +67,7 @@ struct wsc {
|
||||||
uint8_t addr[6];
|
uint8_t addr[6];
|
||||||
} creds[3];
|
} creds[3];
|
||||||
uint32_t n_creds;
|
uint32_t n_creds;
|
||||||
|
struct l_settings *eap_settings;
|
||||||
|
|
||||||
bool wsc_association : 1;
|
bool wsc_association : 1;
|
||||||
};
|
};
|
||||||
|
@ -203,6 +205,9 @@ static void wsc_connect_cb(struct netdev *netdev, enum netdev_result result,
|
||||||
|
|
||||||
wsc->wsc_association = false;
|
wsc->wsc_association = false;
|
||||||
|
|
||||||
|
l_settings_free(wsc->eap_settings);
|
||||||
|
wsc->eap_settings = NULL;
|
||||||
|
|
||||||
if (result == NETDEV_RESULT_HANDSHAKE_FAILED && wsc->n_creds > 0) {
|
if (result == NETDEV_RESULT_HANDSHAKE_FAILED && wsc->n_creds > 0) {
|
||||||
wsc_store_credentials(wsc);
|
wsc_store_credentials(wsc);
|
||||||
wsc_try_credentials(wsc);
|
wsc_try_credentials(wsc);
|
||||||
|
@ -390,14 +395,17 @@ static inline enum wsc_rf_band freq_to_rf_band(uint32_t freq)
|
||||||
|
|
||||||
static void wsc_connect(struct wsc *wsc)
|
static void wsc_connect(struct wsc *wsc)
|
||||||
{
|
{
|
||||||
struct eapol_sm *sm = eapol_sm_new();
|
struct handshake_state *hs;
|
||||||
|
struct eapol_sm *sm;
|
||||||
struct l_settings *settings = l_settings_new();
|
struct l_settings *settings = l_settings_new();
|
||||||
struct scan_bss *bss = wsc->target;
|
struct scan_bss *bss = wsc->target;
|
||||||
|
uint32_t ifindex = netdev_get_ifindex(device_get_netdev(wsc->device));
|
||||||
|
|
||||||
wsc->target = NULL;
|
wsc->target = NULL;
|
||||||
|
|
||||||
eapol_sm_set_authenticator_address(sm, bss->addr);
|
hs = handshake_state_new(ifindex);
|
||||||
eapol_sm_set_supplicant_address(sm, device_get_address(wsc->device));
|
|
||||||
|
sm = eapol_sm_new(hs);
|
||||||
|
|
||||||
eapol_sm_set_user_data(sm, wsc);
|
eapol_sm_set_user_data(sm, wsc);
|
||||||
eapol_sm_set_event_func(sm, wsc_eapol_event);
|
eapol_sm_set_event_func(sm, wsc_eapol_event);
|
||||||
|
@ -417,11 +425,12 @@ static void wsc_connect(struct wsc *wsc)
|
||||||
l_settings_set_string(settings, "WSC", "EnrolleeMAC",
|
l_settings_set_string(settings, "WSC", "EnrolleeMAC",
|
||||||
util_address_to_string(device_get_address(wsc->device)));
|
util_address_to_string(device_get_address(wsc->device)));
|
||||||
|
|
||||||
eapol_sm_set_8021x_config(sm, settings);
|
handshake_state_set_8021x_config(hs, settings);
|
||||||
l_settings_free(settings);
|
wsc->eap_settings = settings;
|
||||||
|
|
||||||
eapol_sm_set_use_eapol_start(sm, true);
|
eapol_sm_set_use_eapol_start(sm, true);
|
||||||
|
|
||||||
if (netdev_connect_wsc(device_get_netdev(wsc->device), bss, sm,
|
if (netdev_connect_wsc(device_get_netdev(wsc->device), bss, hs, sm,
|
||||||
wsc_netdev_event,
|
wsc_netdev_event,
|
||||||
wsc_connect_cb, wsc) < 0) {
|
wsc_connect_cb, wsc) < 0) {
|
||||||
eapol_sm_free(sm);
|
eapol_sm_free(sm);
|
||||||
|
@ -769,6 +778,9 @@ static void wsc_free(void *userdata)
|
||||||
dbus_pending_reply(&wsc->pending_cancel,
|
dbus_pending_reply(&wsc->pending_cancel,
|
||||||
dbus_error_aborted(wsc->pending_cancel));
|
dbus_error_aborted(wsc->pending_cancel));
|
||||||
|
|
||||||
|
if (wsc->eap_settings)
|
||||||
|
l_settings_free(wsc->eap_settings);
|
||||||
|
|
||||||
l_free(wsc);
|
l_free(wsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue