From 741ed9fc2503550270eb3e47803373de5c8994fd Mon Sep 17 00:00:00 2001 From: Vinayak Kamath Date: Tue, 30 Apr 2013 13:35:50 +0300 Subject: [PATCH] WPS: Remove duplicate networks after WPS Each attempt to connect to the same network using WPS would result in the duplicate configuration getting added. Avoid such redundant additions by comparing the network configuration with an already existing one and remove the older network if the new credential provisioned through WPS is identical. Signed-hostap: Jouni Malinen --- wpa_supplicant/wps_supplicant.c | 76 +++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 9af608494..b376fb08c 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -219,6 +219,80 @@ static void wpas_wps_security_workaround(struct wpa_supplicant *wpa_s, } +static void wpas_wps_remove_dup_network(struct wpa_supplicant *wpa_s, + struct wpa_ssid *new_ssid) +{ + struct wpa_ssid *ssid, *next; + + for (ssid = wpa_s->conf->ssid, next = ssid ? ssid->next : NULL; ssid; + ssid = next, next = ssid ? ssid->next : NULL) { + /* + * new_ssid has already been added to the list in + * wpas_wps_add_network(), so skip it. + */ + if (ssid == new_ssid) + continue; + + if (ssid->bssid_set || new_ssid->bssid_set) { + if (ssid->bssid_set != new_ssid->bssid_set) + continue; + if (os_memcmp(ssid->bssid, new_ssid->bssid, ETH_ALEN) != + 0) + continue; + } + + /* compare SSID */ + if (ssid->ssid_len == 0 || ssid->ssid_len != new_ssid->ssid_len) + continue; + + if (ssid->ssid && new_ssid->ssid) { + if (os_memcmp(ssid->ssid, new_ssid->ssid, + ssid->ssid_len) != 0) + continue; + } else if (ssid->ssid || new_ssid->ssid) + continue; + + /* 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; + + if (ssid->passphrase && new_ssid->passphrase) { + if (os_strlen(ssid->passphrase) != + os_strlen(new_ssid->passphrase)) + continue; + if (os_strcmp(ssid->passphrase, new_ssid->passphrase) != + 0) + continue; + } else if (ssid->passphrase || new_ssid->passphrase) + continue; + + if ((ssid->psk_set || new_ssid->psk_set) && + os_memcmp(ssid->psk, new_ssid->psk, sizeof(ssid->psk)) != 0) + continue; + + if (ssid->auth_alg == WPA_ALG_WEP) { + if (ssid->wep_tx_keyidx != new_ssid->wep_tx_keyidx) + continue; + if (os_memcmp(ssid->wep_key, new_ssid->wep_key, + sizeof(ssid->wep_key))) + continue; + if (os_memcmp(ssid->wep_key_len, new_ssid->wep_key_len, + sizeof(ssid->wep_key_len))) + continue; + } + + /* Remove the duplicated older network entry. */ + wpa_printf(MSG_DEBUG, "Remove duplicate network %d", ssid->id); + wpas_notify_network_removed(wpa_s, ssid); + wpa_config_remove_network(wpa_s->conf, ssid->id); + } +} + + static int wpa_supplicant_wps_cred(void *ctx, const struct wps_credential *cred) { @@ -438,6 +512,8 @@ static int wpa_supplicant_wps_cred(void *ctx, if (cred->ap_channel) wpa_s->wps_ap_channel = cred->ap_channel; + wpas_wps_remove_dup_network(wpa_s, ssid); + #ifndef CONFIG_NO_CONFIG_WRITE if (wpa_s->conf->update_config && wpa_config_write(wpa_s->confname, wpa_s->conf)) {