diff --git a/src/ap.c b/src/ap.c index 5ee07ad2..c1eb9611 100644 --- a/src/ap.c +++ b/src/ap.c @@ -62,7 +62,6 @@ struct ap_state { enum ie_rsn_cipher_suite group_cipher; uint32_t beacon_interval; struct l_uintset *rates; - uint8_t pmk[32]; uint32_t start_stop_cmd_id; uint32_t mlme_watch; uint8_t gtk[CRYPTO_MAX_GTK_LEN]; @@ -114,11 +113,8 @@ void ap_config_free(struct ap_config *config) l_free(config->ssid); - if (config->psk) { - explicit_bzero(config->psk, strlen(config->psk)); - l_free(config->psk); - } - + explicit_bzero(config->passphrase, sizeof(config->passphrase)); + explicit_bzero(config->psk, sizeof(config->psk)); l_free(config->authorized_macs); l_free(config->wsc_name); l_free(config); @@ -177,8 +173,6 @@ static void ap_reset(struct ap_state *ap) { struct netdev *netdev = ap->netdev; - explicit_bzero(ap->pmk, sizeof(ap->pmk)); - if (ap->mlme_watch) l_genl_family_unregister(ap->nl80211, ap->mlme_watch); @@ -652,7 +646,7 @@ static void ap_start_rsna(struct sta_state *sta, const uint8_t *gtk_rsc) handshake_state_set_authenticator(sta->hs, true); handshake_state_set_event_func(sta->hs, ap_handshake_event, sta); handshake_state_set_supplicant_ie(sta->hs, sta->assoc_rsne); - handshake_state_set_pmk(sta->hs, sta->ap->pmk, 32); + handshake_state_set_pmk(sta->hs, sta->ap->config->psk, 32); if (gtk_rsc) handshake_state_set_gtk(sta->hs, sta->ap->gtk, @@ -789,8 +783,14 @@ static void ap_start_eap_wsc(struct sta_state *sta) WSC_CONFIGURATION_METHOD_PUSH_BUTTON); l_settings_set_string(sta->wsc_settings, "WSC", "WPA2-SSID", ap->config->ssid); - l_settings_set_string(sta->wsc_settings, "WSC", "WPA2-Passphrase", - ap->config->psk); + + if (ap->config->passphrase[0]) + l_settings_set_string(sta->wsc_settings, + "WSC", "WPA2-Passphrase", + ap->config->passphrase); + else + l_settings_set_bytes(sta->wsc_settings, + "WSC", "WPA2-PSK", ap->config->psk, 32); sta->hs = netdev_handshake_state_new(ap->netdev); handshake_state_set_authenticator(sta->hs, true); @@ -2032,11 +2032,11 @@ static void ap_mlme_notify(struct l_genl_msg *msg, void *user_data) * @ops.handle_event is required and must react to AP_EVENT_START_FAILED * and AP_EVENT_STOPPING by forgetting the ap_state struct, which is * going to be freed automatically. - * In the @config struct only .ssid and .psk need to be non-NULL, - * other fields are optional. If @ap_start succeeds, the returned - * ap_state takes ownership of @config and the caller shouldn't - * free it or any of the memory pointed to by its members (they - * also can't be static). + * In the @config struct the .ssid field is required and one of + * .passphrase and .psk must be filled in. All other fields are optional. + * If @ap_start succeeds, the returned ap_state takes ownership of + * @config and the caller shouldn't free it or any of the memory pointed + * to by its members (which also can't be static). */ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config, const struct ap_ops *ops, void *user_data) @@ -2046,6 +2046,13 @@ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config, struct l_genl_msg *cmd; uint64_t wdev_id = netdev_get_wdev_id(netdev); + if (L_WARN_ON(!config->ssid)) + return NULL; + + if (L_WARN_ON(!config->passphrase[0] && util_mem_is_zero(config->psk, + sizeof(config->psk)))) + return NULL; + ap = l_new(struct ap_state, 1); ap->nl80211 = l_genl_family_new(iwd_get_genl(), NL80211_GENL_NAME); ap->config = config; @@ -2092,8 +2099,11 @@ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config, wsc_uuid_from_addr(netdev_get_address(netdev), ap->wsc_uuid_r); - if (crypto_psk_from_passphrase(config->psk, (uint8_t *) config->ssid, - strlen(config->ssid), ap->pmk) < 0) + if (config->passphrase[0] && + crypto_psk_from_passphrase(config->passphrase, + (uint8_t *) config->ssid, + strlen(config->ssid), + config->psk) < 0) goto error; if (!frame_watch_add(wdev_id, 0, 0x0000 | @@ -2390,7 +2400,7 @@ static struct l_dbus_message *ap_dbus_start(struct l_dbus *dbus, config = l_new(struct ap_config, 1); config->ssid = l_strdup(ssid); - config->psk = l_strdup(wpa2_psk); + l_strlcpy(config->passphrase, wpa2_psk, sizeof(config->passphrase)); ap_if->ap = ap_start(ap_if->netdev, config, &ap_dbus_ops, ap_if); if (!ap_if->ap) { diff --git a/src/ap.h b/src/ap.h index bbfecd6d..a39797aa 100644 --- a/src/ap.h +++ b/src/ap.h @@ -56,7 +56,8 @@ typedef void (*ap_stopped_func_t)(void *user_data); struct ap_config { char *ssid; - char *psk; + char passphrase[64]; + uint8_t psk[32]; uint8_t channel; uint8_t *authorized_macs; unsigned int authorized_macs_num;