From 8645704bb007f7431e9837e9c90b7d966b10099b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Oct 2008 18:53:56 +0200 Subject: [PATCH] Fix handling of WiFi SSID values --- plugins/supplicant.c | 58 ++++++++++++++++++++++---- plugins/supplicant.h | 7 +++- plugins/wifi.c | 116 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 127 insertions(+), 54 deletions(-) diff --git a/plugins/supplicant.c b/plugins/supplicant.c index 8944d43..d72b838 100644 --- a/plugins/supplicant.c +++ b/plugins/supplicant.c @@ -505,8 +505,35 @@ static void append_entry(DBusMessageIter *dict, dbus_message_iter_close_container(dict, &entry); } -static int set_network(struct supplicant_task *task, const char *network, - const char *passphrase) +static void append_array(DBusMessageIter *dict, + const char *key, int type, void *val, int len) +{ + DBusMessageIter entry, value, array; + + if (type != DBUS_TYPE_BYTE) + return; + + dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, + NULL, &entry); + + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key); + + dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, &value); + + dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, &array); + dbus_message_iter_append_fixed_array(&array, type, val, len); + dbus_message_iter_close_container(&value, &array); + + dbus_message_iter_close_container(&entry, &value); + + dbus_message_iter_close_container(dict, &entry); +} + +static int set_network(struct supplicant_task *task, + const unsigned char *network, int len, + const char *passphrase) { DBusMessage *message, *reply; DBusMessageIter array, dict; @@ -529,7 +556,7 @@ static int set_network(struct supplicant_task *task, const char *network, DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - append_entry(&dict, "ssid", DBUS_TYPE_STRING, &network); + append_array(&dict, "ssid", DBUS_TYPE_BYTE, &network, len); if (passphrase && strlen(passphrase) > 0) { const char *key_mgmt = "WPA-PSK"; @@ -597,7 +624,21 @@ static void extract_ssid(struct supplicant_network *network, dbus_message_iter_recurse(value, &array); dbus_message_iter_get_fixed_array(&array, &ssid, &ssid_len); - network->identifier = g_strdup((char *) ssid); + if (ssid_len < 1) + return; + + network->ssid = g_try_malloc(ssid_len); + if (network->ssid == NULL) + return; + + memcpy(network->ssid, ssid, ssid_len); + network->ssid_len = ssid_len; + + network->identifier = g_try_malloc0(ssid_len + 1); + if (network->identifier == NULL) + return; + + memcpy(network->identifier, ssid, ssid_len); } static void extract_wpaie(struct supplicant_network *network, @@ -689,6 +730,8 @@ static void properties_reply(DBusPendingCall *call, void *user_data) if (task->callback && task->callback->scan_result) task->callback->scan_result(task->element, network); + g_free(network->identifier); + g_free(network->ssid); g_free(network); done: @@ -1017,10 +1060,11 @@ int __supplicant_scan(struct connman_element *element) return 0; } -int __supplicant_connect(struct connman_element *element, const char *ssid) +int __supplicant_connect(struct connman_element *element, + const unsigned char *ssid, int ssid_len, + const char *passphrase) { struct supplicant_task *task; - const char *passphrase = NULL; DBG("element %p name %s", element, element->name); @@ -1033,7 +1077,7 @@ int __supplicant_connect(struct connman_element *element, const char *ssid) select_network(task); disable_network(task); - set_network(task, ssid, passphrase); + set_network(task, ssid, ssid_len, passphrase); enable_network(task); diff --git a/plugins/supplicant.h b/plugins/supplicant.h index 20552e6..538c84f 100644 --- a/plugins/supplicant.h +++ b/plugins/supplicant.h @@ -38,7 +38,8 @@ enum supplicant_state { struct supplicant_network { gchar *identifier; - GByteArray *ssid; + guint8 *ssid; + guint ssid_len; guint capabilities; gboolean has_wep; gboolean has_wpa; @@ -61,5 +62,7 @@ int __supplicant_stop(struct connman_element *element); int __supplicant_scan(struct connman_element *element); -int __supplicant_connect(struct connman_element *element, const char *ssid); +int __supplicant_connect(struct connman_element *element, + const unsigned char *ssid, int ssid_len, + const char *passphrase); int __supplicant_disconnect(struct connman_element *element); diff --git a/plugins/wifi.c b/plugins/wifi.c index 1dcd135..f7280b1 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -32,6 +32,12 @@ #include "supplicant.h" +struct wifi_data { + GStaticMutex mutex; + GSList *list; + gchar *identifier; +}; + static int network_probe(struct connman_element *element) { DBG("element %p name %s", element, element->name); @@ -46,18 +52,32 @@ static void network_remove(struct connman_element *element) static int network_enable(struct connman_element *element) { + char *identifier, *passphrase = NULL; + unsigned char *ssid; + int ssid_len; + DBG("element %p name %s", element, element->name); - element->enabled = FALSE; - connman_element_update(element); + if (connman_element_get_static_property(element, + "Identifier", &identifier) == FALSE) + return -EIO; + + if (connman_element_get_static_array_property(element, + "SSID", &ssid, &ssid_len) == FALSE) + return -EIO; + + if (element->parent != NULL) { + struct wifi_data *data = connman_element_get_data(element->parent); - if (element->parent) { - g_free(element->parent->network.identifier); - element->parent->network.identifier = - g_strdup(element->network.identifier); + if (data != NULL) { + g_free(data->identifier); + data->identifier = g_strdup(identifier); + } } - if (__supplicant_connect(element, element->network.identifier) < 0) + DBG("identifier %s passhprase %s", identifier, passphrase); + + if (__supplicant_connect(element, ssid, ssid_len, passphrase) < 0) connman_error("Failed to initiate connect"); return 0; @@ -71,9 +91,6 @@ static int network_disable(struct connman_element *element) __supplicant_disconnect(element); - element->enabled = FALSE; - connman_element_update(element); - return 0; } @@ -87,11 +104,6 @@ static struct connman_driver network_driver = { .disable = network_disable, }; -struct wifi_data { - GStaticMutex mutex; - GSList *list; -}; - static struct connman_element *find_element(struct wifi_data *data, const char *identifier) { @@ -100,11 +112,8 @@ static struct connman_element *find_element(struct wifi_data *data, for (list = data->list; list; list = list->next) { struct connman_element *element = list->data; - if (element->network.identifier == NULL) - continue; - - if (g_str_equal(element->network.identifier, - identifier) == TRUE) + if (connman_element_match_static_property(element, + "Identifier", &identifier) == TRUE) return element; } @@ -119,10 +128,10 @@ static void state_change(struct connman_element *parent, DBG("state %d", state); - if (parent->network.identifier == NULL) + if (data->identifier == NULL) return; - element = find_element(data, parent->network.identifier); + element = find_element(data, data->identifier); if (element == NULL) return; @@ -134,9 +143,6 @@ static void state_change(struct connman_element *parent, dhcp->type = CONNMAN_ELEMENT_TYPE_DHCP; dhcp->index = element->index; - element->enabled = TRUE; - connman_element_update(element); - connman_element_register(dhcp, element); } } @@ -181,13 +187,14 @@ static void scan_result(struct connman_element *parent, element->type = CONNMAN_ELEMENT_TYPE_NETWORK; element->index = parent->index; - element->network.identifier = g_strdup(network->identifier); - data->list = g_slist_append(data->list, element); - connman_element_add_static_property(element, "SSID", + connman_element_add_static_property(element, "Identifier", DBUS_TYPE_STRING, &network->identifier); + connman_element_add_static_array_property(element, "SSID", + DBUS_TYPE_BYTE, &network->ssid, network->ssid_len); + connman_element_register(element, parent); } @@ -204,7 +211,6 @@ static struct supplicant_callback wifi_callback = { static int wifi_probe(struct connman_element *element) { struct wifi_data *data; - int err; DBG("element %p name %s", element, element->name); @@ -216,6 +222,36 @@ static int wifi_probe(struct connman_element *element) connman_element_set_data(element, data); + return 0; +} + +static void wifi_remove(struct connman_element *element) +{ + struct wifi_data *data = connman_element_get_data(element); + + DBG("element %p name %s", element, element->name); + + connman_element_set_data(element, NULL); + + g_free(data->identifier); + g_free(data); +} + +static int wifi_update(struct connman_element *element) +{ + DBG("element %p name %s", element, element->name); + + __supplicant_scan(element); + + return 0; +} + +static int wifi_enable(struct connman_element *element) +{ + int err; + + DBG("element %p name %s", element, element->name); + err = __supplicant_start(element, &wifi_callback); if (err < 0) return err; @@ -225,41 +261,29 @@ static int wifi_probe(struct connman_element *element) return 0; } -static void wifi_remove(struct connman_element *element) +static int wifi_disable(struct connman_element *element) { struct wifi_data *data = connman_element_get_data(element); GSList *list; DBG("element %p name %s", element, element->name); - __supplicant_stop(element); - - connman_element_set_data(element, NULL); - - if (data == NULL) - return; + __supplicant_disconnect(element); g_static_mutex_lock(&data->mutex); for (list = data->list; list; list = list->next) { struct connman_element *network = list->data; - connman_element_unregister(network); connman_element_unref(network); } g_slist_free(data->list); + data->list = NULL; g_static_mutex_unlock(&data->mutex); - g_free(data); -} - -static int wifi_update(struct connman_element *element) -{ - DBG("element %p name %s", element, element->name); - - __supplicant_scan(element); + connman_element_unregister_children(element); return 0; } @@ -271,6 +295,8 @@ static struct connman_driver wifi_driver = { .probe = wifi_probe, .remove = wifi_remove, .update = wifi_update, + .enable = wifi_enable, + .disable = wifi_disable, }; static int wifi_init(void) -- 2.7.4