diff options
author | Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com> | 2012-04-28 12:00:08 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2012-04-28 20:05:27 +0200 |
commit | 8796333af04b7d96dff3c4dbc5b57f5152a8b454 (patch) | |
tree | 815435bccce232d3f08f002b4334bfd7e637b837 /gsupplicant/supplicant.c | |
parent | 66126366c458c197ae5c44778b024bed93217d40 (diff) | |
download | connman-8796333af04b7d96dff3c4dbc5b57f5152a8b454.tar.gz connman-8796333af04b7d96dff3c4dbc5b57f5152a8b454.tar.bz2 connman-8796333af04b7d96dff3c4dbc5b57f5152a8b454.zip |
gssuplicant: Fix when a bss should be added or replaced in a network
Note: on wpa_supplivant 0.7.x this fixes bug 21332 _only_ when switching
from wep to psk, not the other way round due to wpa_supplicant not telling
about RSN/WPA fields being empty. This could be fixed in parsing IE every
time it is updated, if wpa_s signals it. It work properly on
wpa_supplicant 0.8.x and 1.x since signaling RSN/WPA changes has been
fixed.
Fixes BMC#21332
Diffstat (limited to 'gsupplicant/supplicant.c')
-rw-r--r-- | gsupplicant/supplicant.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 87a5b1cf..0ceffc75 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -1374,12 +1374,8 @@ static void bss_property(const char *key, DBusMessageIter *iter, SUPPLICANT_DBG("key %s", key); - if (key == NULL) { - bss_compute_security(bss); - - add_or_replace_bss_to_network(bss); + if (key == NULL) return; - } if (g_strcmp0(key, "BSSID") == 0) { DBusMessageIter array; @@ -1526,7 +1522,9 @@ static void interface_bss_added_with_keys(DBusMessageIter *iter, return; supplicant_dbus_property_foreach(iter, bss_property, bss); - bss_property(NULL, NULL, bss); + + bss_compute_security(bss); + add_or_replace_bss_to_network(bss); } static void interface_bss_added_without_keys(DBusMessageIter *iter, @@ -1543,6 +1541,9 @@ static void interface_bss_added_without_keys(DBusMessageIter *iter, supplicant_dbus_property_get_all(bss->path, SUPPLICANT_INTERFACE ".BSS", bss_property, bss); + + bss_compute_security(bss); + add_or_replace_bss_to_network(bss); } static void update_signal(gpointer key, gpointer value, @@ -2026,6 +2027,7 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter) { GSupplicantInterface *interface; GSupplicantNetwork *network; + GSupplicantSecurity old_security; struct g_supplicant_bss *bss; SUPPLICANT_DBG(""); @@ -2044,6 +2046,39 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter) supplicant_dbus_property_foreach(iter, bss_property, bss); + old_security = network->security; + bss_compute_security(bss); + + if (old_security != bss->security) { + struct g_supplicant_bss *new_bss; + + SUPPLICANT_DBG("New network security for %s", bss->ssid); + + /* Security change policy: + * - we first copy the current bss into a new one with + * its own pointer (path) + * - we remove the current bss related nework which will + * tell the plugin about such removal. This is done due + * to the fact that a security change means a group change + * so a complete network change. + * (current bss becomes invalid as well) + * - we add the new bss: it adds new network and tell the + * plugin about it. */ + + new_bss = g_try_new0(struct g_supplicant_bss, 1); + if (new_bss == NULL) + return; + + memcpy(new_bss, bss, sizeof(struct g_supplicant_bss)); + new_bss->path = g_strdup(bss->path); + + g_hash_table_remove(interface->network_table, network->group); + + add_or_replace_bss_to_network(new_bss); + + return; + } + if (bss->signal == network->signal) return; |