update support for group key updates with Update WLAN

This commit is contained in:
Andreas Schultz 2016-08-08 09:25:01 +02:00
parent 02e8d534b5
commit 01919fffd9
4 changed files with 134 additions and 2 deletions

View File

@ -7,6 +7,7 @@ Version 1.3.0 - unreleased
---------------------------
* forward PAE (IEEE 802.1X Authentication) frames as raw 802.11 frames to AC
* implement encryption support for group and peer temporal keys (CCMP only)
Version 1.2.1 - 06 May 2016
---------------------------

View File

@ -2178,6 +2178,69 @@ int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params
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)
{
int result = 0;
ASSERT(wlan != NULL);
ASSERT(wlan->device != NULL);
ASSERT(params != NULL);
/* Check device */
if (!(wlan->flags & WIFI_WLAN_RUNNING))
return -1;
/* Save configuration */
#if 0
/* TODO: handle changes in WLAN setting */
wlan->capability = params->capability;
wlan->ht_opmode = ht_opmode_from_ie(wlan->radioid, wlan->wlanid,
params->ie);
log_printf(LOG_DEBUG, "WIFI 802.11: HT OpMode: %04x", wlan->ht_opmode);
wlan->rsne = rsn_from_ie(wlan->radioid, wlan->wlanid,
params->ie);
/* TODO: handle changes in WLAN setting */
build_80211_ie(wlan->radioid, wlan->wlanid,
CAPWAP_IE_BEACONS_ASSOCIATED,
params->ie,
&wlan->beacon_ies, &wlan->beacon_ies_len);
build_80211_ie(wlan->radioid, wlan->wlanid,
CAPWAP_IE_PROBE_RESPONSE_ASSOCIATED,
params->ie,
&wlan->response_ies, &wlan->response_ies_len);
#endif
switch (params->keystatus) {
case 3:
wlan->keyindex = params->keyindex;
wlan->keylength = params->keylength;
if (wlan->key) {
capwap_free(wlan->key);
wlan->key = NULL;
}
if (params->key && params->keylength)
wlan->key = capwap_clone(params->key, params->keylength);
result = wlan_set_key(wlan, wlan->group_cipher_suite, broadcast_ether_addr,
wlan->keyindex, 1, NULL, 0, wlan->key, wlan->keylength);
log_printf(LOG_INFO, "Update GTK on interface: %s, SSID: '%s', result: %d",
wlan->virtname, wlan->ssid, result);
break;
default:
break;
}
return result;
}
/* */
void wifi_wlan_stopap(struct wifi_wlan* wlan)
{

View File

@ -114,6 +114,20 @@ struct wlan_startap_params {
struct capwap_array *ie;
};
struct wlan_updateap_params {
uint8_t radioid;
uint8_t wlanid;
uint16_t capability;
uint8_t qos;
uint8_t keyindex;
uint8_t keystatus;
uint8_t keylength;
uint8_t *key;
struct capwap_array *ie;
};
/* */
struct wlan_send_frame_params {
@ -455,6 +469,7 @@ int wifi_device_updaterates(struct wifi_device* device, uint8_t* rates, int rate
/* WLAN management */
struct wifi_wlan* wifi_wlan_create(struct wifi_device* device, const char* ifname);
int wifi_wlan_startap(struct wifi_wlan* wlan, struct wlan_startap_params* params);
int wifi_wlan_updateap(struct wifi_wlan* wlan, struct wlan_updateap_params* params);
void wifi_wlan_stopap(struct wifi_wlan* wlan);
int wifi_wlan_getbssid(struct wifi_wlan* wlan, uint8_t* bssid);
uint16_t wifi_wlan_check_capability(struct wifi_wlan* wlan, uint16_t capability);

View File

@ -740,8 +740,61 @@ uint32_t wtp_radio_create_wlan(struct capwap_parsed_packet* packet,
}
/* */
uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet) {
/* TODO */
uint32_t wtp_radio_update_wlan(struct capwap_parsed_packet* packet)
{
struct wtp_radio* radio;
struct wtp_radio_wlan* wlan;
struct wlan_updateap_params params;
struct capwap_80211_updatewlan_element* updatewlan;
ASSERT(packet != NULL);
/* Get message elements */
updatewlan = (struct capwap_80211_updatewlan_element*)
capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_UPDATE_WLAN);
if (!updatewlan) {
log_printf(LOG_DEBUG, "Update WLAN: no wlan");
return CAPWAP_RESULTCODE_FAILURE;
}
/* Get physical radio */
radio = wtp_radio_get_phy(updatewlan->radioid);
if (!radio) {
log_printf(LOG_DEBUG, "Update WLAN: no radio");
return CAPWAP_RESULTCODE_FAILURE;
}
/* Check if virtual interface is already exist */
wlan = wtp_radio_get_wlan(radio, updatewlan->wlanid);
if (!wlan || !wlan->wlanhandle) {
log_printf(LOG_DEBUG, "Update WLAN: invalid WLAN ID");
return CAPWAP_RESULTCODE_FAILURE;
}
if (!wlan->in_use) {
log_printf(LOG_DEBUG, "Update WLAN: vif does not exists");
return CAPWAP_RESULTCODE_FAILURE;
}
/* Wlan Update Configuration */
memset(&params, 0, sizeof(struct wlan_updateap_params));
params.radioid = updatewlan->radioid;
params.wlanid = updatewlan->wlanid;
params.capability = reverse(updatewlan->capability);
params.keyindex = updatewlan->keyindex;
params.keystatus = updatewlan->keystatus;
params.keylength = updatewlan->keylength;
params.key = updatewlan->key;
params.ie = (struct capwap_array *)capwap_get_message_element_data(packet, CAPWAP_ELEMENT_80211_IE);
/* Update AP */
if (wifi_wlan_updateap(wlan->wlanhandle, &params)) {
log_printf(LOG_DEBUG, "Update WLAN: update AP failed");
return CAPWAP_RESULTCODE_FAILURE;
}
return CAPWAP_RESULTCODE_SUCCESS;
}