add vendor VSA to set additional key and IGTK support
IGTK == Management Frame Protection
This commit is contained in:
@ -2123,6 +2123,41 @@ static struct ieee80211_ie *rsn_from_ie(uint8_t radioid, uint8_t wlanid,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define broadcast_ether_addr (const uint8_t *) "\xff\xff\xff\xff\xff\xff"
|
||||
|
||||
static int update_keys(struct wifi_wlan* wlan, struct capwap_array *keys)
|
||||
{
|
||||
int i, result = 0;
|
||||
|
||||
log_printf(LOG_DEBUG, "Wifi Update Keys: %p", keys);
|
||||
if (!keys)
|
||||
return 0;
|
||||
|
||||
log_printf(LOG_DEBUG, "Wifi Update Keys: #%ld", keys->count);
|
||||
for (i = 0; i < keys->count; i++) {
|
||||
struct capwap_vendor_travelping_80211_update_key_element *key =
|
||||
*(struct capwap_vendor_travelping_80211_update_key_element **)
|
||||
capwap_array_get_item_pointer(keys, i);
|
||||
|
||||
log_printf(LOG_DEBUG, "Wifi Update Keys: Update: Status: %d, CipherSuite: %08x, Index: %d, Len: %d",
|
||||
key->keystatus, key->ciphersuite, key->keyindex, key->keylength);
|
||||
switch (key->keystatus) {
|
||||
case 3:
|
||||
result = wlan_set_key(wlan, key->ciphersuite, broadcast_ether_addr,
|
||||
key->keyindex, 1, NULL, 0,
|
||||
key->keylength ? key->key : NULL, key->keylength);
|
||||
|
||||
log_printf(LOG_INFO, "Update KEY on interface: %s, SSID: '%s', result: %d",
|
||||
wlan->virtname, wlan->ssid, result);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* */
|
||||
int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params)
|
||||
{
|
||||
@ -2167,18 +2202,19 @@ int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params
|
||||
|
||||
/* Start AP */
|
||||
result = wlan_startap(wlan);
|
||||
if (!result) {
|
||||
wlan->device->wlanactive++;
|
||||
log_printf(LOG_INFO, "Configured interface: %s, SSID: '%s'", wlan->virtname, wlan->ssid);
|
||||
} else {
|
||||
if (result) {
|
||||
wifi_wlan_stopap(wlan);
|
||||
return result;
|
||||
}
|
||||
|
||||
update_keys(wlan, params->updatekeys);
|
||||
|
||||
wlan->device->wlanactive++;
|
||||
log_printf(LOG_INFO, "Configured interface: %s, SSID: '%s'", wlan->virtname, wlan->ssid);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define broadcast_ether_addr (const uint8_t *) "\xff\xff\xff\xff\xff\xff"
|
||||
|
||||
/* */
|
||||
int wifi_wlan_updateap(struct wifi_wlan* wlan, struct wlan_updateap_params* params)
|
||||
{
|
||||
@ -2237,6 +2273,9 @@ int wifi_wlan_updateap(struct wifi_wlan* wlan, struct wlan_updateap_params* para
|
||||
break;
|
||||
}
|
||||
|
||||
if (!result)
|
||||
update_keys(wlan, params->updatekeys);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -103,6 +103,7 @@ struct wlan_startap_params {
|
||||
uint8_t *key;
|
||||
|
||||
struct capwap_array *ie;
|
||||
struct capwap_array *updatekeys;
|
||||
};
|
||||
|
||||
struct wlan_updateap_params {
|
||||
@ -118,6 +119,7 @@ struct wlan_updateap_params {
|
||||
uint8_t *key;
|
||||
|
||||
struct capwap_array *ie;
|
||||
struct capwap_array *updatekeys;
|
||||
};
|
||||
|
||||
/* */
|
||||
|
@ -1060,7 +1060,12 @@ static int nl80211_set_key(struct wifi_wlan* wlan,
|
||||
msg = nl80211_wlan_msg(wlan, 0, NL80211_CMD_SET_KEY);
|
||||
if (!msg ||
|
||||
nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx) ||
|
||||
nla_put_flag(msg, NL80211_ATTR_KEY_DEFAULT))
|
||||
nla_put_flag(msg, (alg == IEEE80211_CIPHER_SUITE_AES_CMAC ||
|
||||
alg == IEEE80211_CIPHER_SUITE_BIP_GMAC_128 ||
|
||||
alg == IEEE80211_CIPHER_SUITE_BIP_GMAC_256 ||
|
||||
alg == IEEE80211_CIPHER_SUITE_BIP_CMAC_256) ?
|
||||
NL80211_ATTR_KEY_DEFAULT_MGMT :
|
||||
NL80211_ATTR_KEY_DEFAULT))
|
||||
goto fail;
|
||||
|
||||
types = nla_nest_start(msg, NL80211_ATTR_KEY_DEFAULT_TYPES);
|
||||
|
@ -652,6 +652,47 @@ void wtp_radio_receive_data_packet(uint8_t radioid, unsigned short binding, cons
|
||||
}
|
||||
}
|
||||
|
||||
static struct capwap_array *wtp_radio_set_update_keys(struct capwap_parsed_packet *packet,
|
||||
uint8_t radioid, uint8_t wlanid)
|
||||
{
|
||||
int i;
|
||||
struct capwap_array *keys;
|
||||
struct capwap_array *updatekeys = NULL;
|
||||
|
||||
ASSERT(packet != NULL);
|
||||
|
||||
keys = (struct capwap_array *)
|
||||
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_VENDOR_TRAVELPING_80211_UPDATE_KEY);
|
||||
log_printf(LOG_DEBUG, "Set Update Keys: %p", keys);
|
||||
if (!keys)
|
||||
return NULL;
|
||||
|
||||
log_printf(LOG_DEBUG, "Set Update Keys: #%ld", keys->count);
|
||||
for (i = 0; i < keys->count; i++) {
|
||||
struct capwap_vendor_travelping_80211_update_key_element *key =
|
||||
*(struct capwap_vendor_travelping_80211_update_key_element **)
|
||||
capwap_array_get_item_pointer(keys, i);
|
||||
|
||||
log_printf(LOG_DEBUG, "RadioId: %d .. %d, WlanId: %d .. %d",
|
||||
key->radioid, radioid,
|
||||
key->wlanid, wlanid);
|
||||
|
||||
if (key->radioid != radioid || key->wlanid != wlanid)
|
||||
continue;
|
||||
|
||||
if (!updatekeys)
|
||||
updatekeys = capwap_array_create(sizeof(void *), 0, 0);
|
||||
if (!updatekeys) {
|
||||
log_printf(LOG_DEBUG, "Update WLAN: Out of Memory");
|
||||
return NULL;
|
||||
}
|
||||
*(void **)capwap_array_get_item_pointer(updatekeys, updatekeys->count) = key;
|
||||
log_printf(LOG_DEBUG, "Set Update Keys: Update #%ld", updatekeys->count);
|
||||
}
|
||||
|
||||
return updatekeys;
|
||||
}
|
||||
|
||||
/* source http://stackoverflow.com/a/16994674 */
|
||||
static uint16_t reverse(register uint16_t x)
|
||||
{
|
||||
@ -721,6 +762,7 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
|
||||
params.key = addwlan->key;
|
||||
|
||||
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
|
||||
params.updatekeys = wtp_radio_set_update_keys(packet, addwlan->radioid, addwlan->wlanid);
|
||||
|
||||
/* Start AP */
|
||||
if (wifi_wlan_startap(wlan->wlanhandle, ¶ms)) {
|
||||
@ -788,6 +830,7 @@ uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet)
|
||||
params.key = updatewlan->key;
|
||||
|
||||
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
|
||||
params.updatekeys = wtp_radio_set_update_keys(packet, updatewlan->radioid, updatewlan->wlanid);
|
||||
|
||||
/* Update AP */
|
||||
if (wifi_wlan_updateap(wlan->wlanhandle, ¶ms)) {
|
||||
|
Reference in New Issue
Block a user