aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/wps_supplicant.c
diff options
context:
space:
mode:
authorHu Wang <huw@qti.qualcomm.com>2014-08-29 17:11:13 (GMT)
committerJouni Malinen <j@w1.fi>2014-08-29 17:25:18 (GMT)
commite5a4b85b2fa416efb516825f884a0eda5b3f1c40 (patch)
tree40fc346d556cc3a08da91d336f6ac1acbb6e3bfc /wpa_supplicant/wps_supplicant.c
parentdb9418bb1b8054b54d9b299e0334850d5e2b77ad (diff)
downloadhostap-e5a4b85b2fa416efb516825f884a0eda5b3f1c40.zip
hostap-e5a4b85b2fa416efb516825f884a0eda5b3f1c40.tar.gz
hostap-e5a4b85b2fa416efb516825f884a0eda5b3f1c40.tar.bz2
WPS: Merge mixed-WPA/WPA2 credentials if received in same session
Some deployed APs send two credentials when in mixed-WPA/WPA2 configuration; one for the WPA-Personal/TKIP and the other for WPA2-Personal/CCMP. Previously, this would result in two network blocks getting added for the single AP. This can be somewhat confusing and unnecessary, so merge such credentials into a single one that allows both WPA and WPA2 to be used. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant/wps_supplicant.c')
-rw-r--r--wpa_supplicant/wps_supplicant.c51
1 files changed, 49 insertions, 2 deletions
diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c
index fd0d14a..40a5c69 100644
--- a/wpa_supplicant/wps_supplicant.c
+++ b/wpa_supplicant/wps_supplicant.c
@@ -286,11 +286,54 @@ static void wpas_wps_remove_dup_network(struct wpa_supplicant *wpa_s,
/* compare security parameters */
if (ssid->auth_alg != new_ssid->auth_alg ||
ssid->key_mgmt != new_ssid->key_mgmt ||
- ssid->proto != new_ssid->proto ||
- ssid->pairwise_cipher != new_ssid->pairwise_cipher ||
ssid->group_cipher != new_ssid->group_cipher)
continue;
+ /*
+ * Some existing WPS APs will send two creds in case they are
+ * configured for mixed mode operation (WPA+WPA2 and TKIP+CCMP).
+ * Try to merge these two creds if they are received in the same
+ * M8 message.
+ */
+ if (ssid->wps_run && ssid->wps_run == new_ssid->wps_run &&
+ wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
+ if (new_ssid->passphrase && ssid->passphrase &&
+ os_strcmp(new_ssid->passphrase, ssid->passphrase) !=
+ 0) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: M8 Creds with different passphrase - do not merge");
+ continue;
+ }
+
+ if (new_ssid->psk_set &&
+ (!ssid->psk_set ||
+ os_memcmp(new_ssid->psk, ssid->psk, 32) != 0)) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: M8 Creds with different PSK - do not merge");
+ continue;
+ }
+
+ if ((new_ssid->passphrase && !ssid->passphrase) ||
+ (!new_ssid->passphrase && ssid->passphrase)) {
+ wpa_printf(MSG_DEBUG,
+ "WPS: M8 Creds with different passphrase/PSK type - do not merge");
+ continue;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "WPS: Workaround - merge likely WPA/WPA2-mixed mode creds in same M8 message");
+ new_ssid->proto |= ssid->proto;
+ new_ssid->pairwise_cipher |= ssid->pairwise_cipher;
+ } else {
+ /*
+ * proto and pairwise_cipher difference matter for
+ * non-mixed-mode creds.
+ */
+ if (ssid->proto != new_ssid->proto ||
+ ssid->pairwise_cipher != new_ssid->pairwise_cipher)
+ continue;
+ }
+
/* Remove the duplicated older network entry. */
wpa_printf(MSG_DEBUG, "Remove duplicate network %d", ssid->id);
wpas_notify_network_removed(wpa_s, ssid);
@@ -411,6 +454,7 @@ static int wpa_supplicant_wps_cred(void *ctx,
}
wpa_config_set_network_defaults(ssid);
+ ssid->wps_run = wpa_s->wps_run;
os_free(ssid->ssid);
ssid->ssid = os_malloc(cred->ssid_len);
@@ -1004,6 +1048,9 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s,
{
struct wpa_bss *bss;
+ wpa_s->wps_run++;
+ if (wpa_s->wps_run == 0)
+ wpa_s->wps_run++;
wpa_s->after_wps = 0;
wpa_s->known_wps_freq = 0;
if (freq) {