[connman]Added support of EAP-FAST,EAP-PWD and EAP-AKA'.
[platform/upstream/connman.git] / gsupplicant / supplicant.c
index 5e9f509..92efbc9 100644 (file)
@@ -221,8 +221,7 @@ struct g_supplicant_bss {
 #if defined TIZEN_EXT
        dbus_bool_t ft_psk;
        dbus_bool_t ft_ieee8021x;
-       char *wifi_vsie;
-       unsigned int wifi_vsie_len;
+       GSList *vsie_list;
        dbus_bool_t hs20;
 #endif
        unsigned int wps_capabilities;
@@ -250,8 +249,7 @@ struct _GSupplicantNetwork {
        char *identity;
        char *phase2;
        unsigned int keymgmt;
-       char *wifi_vsie;
-       unsigned int wifi_vsie_len;
+       GSList *vsie_list;
 #endif
 };
 
@@ -808,7 +806,7 @@ static void remove_network(gpointer data)
        g_free(network->phase2);
 #endif
 #if defined TIZEN_EXT
-       g_free(network->wifi_vsie);
+       g_slist_free_full(network->vsie_list, g_free);
 #endif
 
        g_free(network);
@@ -820,7 +818,7 @@ static void remove_bss(gpointer data)
 
        g_free(bss->path);
 #if defined TIZEN_EXT
-       g_free(bss->wifi_vsie);
+       g_slist_free_full(bss->vsie_list, g_free);
 #endif
        g_free(bss);
 }
@@ -1558,16 +1556,29 @@ bool g_supplicant_network_get_rsn_mode(GSupplicantNetwork *network)
                return false;
 }
 
-const void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network,
-                                               unsigned int *wifi_vsie_len)
+void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network)
 {
-       if (!network) {
-               *wifi_vsie_len = 0;
+       GSList *vsie_list = NULL;
+
+       if (!network)
                return NULL;
+
+       if (g_slist_length(network->vsie_list) > 0) {
+               GSList *list = NULL;
+               unsigned char *vsie = NULL;
+               for (list = network->vsie_list; list; list = list->next) {
+                       unsigned char *ie = (unsigned char *)list->data;
+                       vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
+
+                       if (vsie) {
+                               memcpy(vsie, ie, ie[1]+2);
+                               vsie_list = g_slist_append(vsie_list, vsie);
+                       } else
+                               SUPPLICANT_DBG("Failed to allocate memory");
+               }
        }
 
-       *wifi_vsie_len = network->wifi_vsie_len;
-       return network->wifi_vsie;
+       return vsie_list;
 }
 #endif
 
@@ -1849,14 +1860,18 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
 #if defined TIZEN_EXT
        network->keymgmt = bss->keymgmt;
 
-       if (bss->wifi_vsie_len > 0) {
-               SUPPLICANT_DBG("vsie len: %d", bss->wifi_vsie_len);
-               network->wifi_vsie = (char *)g_try_malloc0(bss->wifi_vsie_len);
-               if(network->wifi_vsie) {
-                       network->wifi_vsie_len = bss->wifi_vsie_len;
-                       memcpy(network->wifi_vsie, bss->wifi_vsie, network->wifi_vsie_len);
-               } else {
-                       SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
+       if (g_slist_length(bss->vsie_list) > 0) {
+               GSList *list = NULL;
+               unsigned char *vsie = NULL;
+               for (list = bss->vsie_list; list; list = list->next) {
+                       unsigned char *ie = (unsigned char *)list->data;
+                       vsie = (unsigned char *)g_try_malloc0(ie[1]+2); // tag number size(1), tag length size(1)
+
+                       if (vsie) {
+                               memcpy(vsie, ie, ie[1]+2);
+                               network->vsie_list = g_slist_append(network->vsie_list, vsie);
+                       } else
+                               SUPPLICANT_DBG("Failed to allocate memory.");
                }
        }
 
@@ -2047,9 +2062,6 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
 {
        struct g_supplicant_bss *bss = user_data;
        const unsigned char WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
-#if defined TIZEN_EXT
-       const unsigned char WIFI_OUI[] = {0x00, 0x16, 0x32};
-#endif
        unsigned char *ie, *ie_end;
        DBusMessageIter array;
        unsigned int value;
@@ -2081,16 +2093,20 @@ static void bss_process_ies(DBusMessageIter *iter, void *user_data)
        for (ie_end = ie + ie_len; ie < ie_end && ie + ie[1] + 1 <= ie_end;
                                                        ie += ie[1] + 2) {
 #if defined TIZEN_EXT
-               if((ie[0] == VENDOR_SPECIFIC_INFO) && (memcmp(ie+2, WIFI_OUI, sizeof(WIFI_OUI)) == 0)) {
-                               SUPPLICANT_DBG("IE: match WIFI_OUI");
-                               bss->wifi_vsie = (char *)g_try_malloc0(ie[1] + 2);   // tag number size(1), tag length size(1)
-                               if (bss->wifi_vsie) {
-                                       bss->wifi_vsie_len = ie[1] + 2;
-                                       memcpy(bss->wifi_vsie, ie, bss->wifi_vsie_len);
-                               } else {
-                                       SUPPLICANT_DBG("Failed to allocate memory for wifi_vsie");
-                               }
-                               continue;
+               unsigned char *vsie;
+               int vsie_len = 0;
+               if(ie[0] == VENDOR_SPECIFIC_INFO && memcmp(ie+2, WPS_OUI, sizeof(WPS_OUI)) != 0) {
+                       SUPPLICANT_DBG("IE: match vendor specific data");
+
+                       vsie_len = ie[1]+2;     // tag number size(1), tag length size(1)
+                       vsie = (unsigned char *)g_try_malloc0(vsie_len);
+
+                       if (vsie) {
+                               memcpy(vsie, ie, vsie_len);
+                               bss->vsie_list = g_slist_append(bss->vsie_list, vsie);
+                       } else
+                               SUPPLICANT_DBG("Failed to allocate memory");
+                       continue;
                }
 #endif
                if (ie[0] != WMM_WPA1_WPS_INFO || ie[1] < WPS_INFO_MIN_LEN ||
@@ -4799,7 +4815,8 @@ static void interface_select_network_params(DBusMessageIter *iter,
        dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
                                        &interface->network_path);
 #if defined TIZEN_EXT
-       dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &ssid->freq);
+       if (!ssid->bssid_for_connect_len)
+               dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &ssid->freq);
 #endif
 }
 
@@ -4826,14 +4843,20 @@ static void interface_add_network_result(const char *error,
 
 #if defined TIZEN_EXT
        SUPPLICANT_DBG(".Interface.SelectNetworkFreq");
-#endif
+       GSupplicantSSID *ssid = data->ssid;
 
-#if defined TIZEN_EXT
-       supplicant_dbus_method_call(data->interface->path,
-                       SUPPLICANT_INTERFACE ".Interface", "SelectNetworkFreq",
-                       interface_select_network_params,
-                       interface_select_network_result, data,
-                       interface);
+       if (!ssid->bssid_for_connect_len)
+               supplicant_dbus_method_call(data->interface->path,
+                               SUPPLICANT_INTERFACE ".Interface", "SelectNetworkFreq",
+                               interface_select_network_params,
+                               interface_select_network_result, data,
+                               interface);
+       else
+               supplicant_dbus_method_call(data->interface->path,
+                               SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
+                               interface_select_network_params,
+                               interface_select_network_result, data,
+                               interface);
 #else
        supplicant_dbus_method_call(data->interface->path,
                        SUPPLICANT_INTERFACE ".Interface", "SelectNetwork",
@@ -5108,6 +5131,33 @@ static void add_network_security_aka_sim(DBusMessageIter *dict,
                        DBUS_TYPE_STRING,
                        &ssid->passphrase);
 }
+
+static void add_network_security_fast(DBusMessageIter *dict,
+               GSupplicantSSID *ssid)
+{
+       /*
+        * For FAST, we at least need:
+        *              id / password
+        *              phase1 (provisiong information)
+        *              pac_file
+        */
+
+       /* Allow provisioing both authenticated and unauthenticated */
+       const char *phase1 = "fast_provisioning=2";
+       supplicant_dbus_dict_append_basic(dict, "phase1",
+                       DBUS_TYPE_STRING,
+                       &phase1);
+
+       SUPPLICANT_DBG("pac_file [%s]", ssid->pac_file);
+       if(ssid->pac_file)
+               supplicant_dbus_dict_append_basic(dict, "pac_file",
+                               DBUS_TYPE_STRING,
+                               &ssid->pac_file);
+
+       supplicant_dbus_dict_append_basic(dict, "password",
+                       DBUS_TYPE_STRING,
+                       &ssid->passphrase);
+}
 #endif
 
 static void add_network_security_eap(DBusMessageIter *dict,
@@ -5134,8 +5184,20 @@ static void add_network_security_eap(DBusMessageIter *dict,
 
 #if defined TIZEN_EXT
        } else if (g_strcmp0(ssid->eap, "sim") == 0 ||
-                       g_strcmp0(ssid->eap, "aka") == 0) {
+                       g_strcmp0(ssid->eap, "aka") == 0 ||
+                       g_strcmp0(ssid->eap, "aka'") == 0) {
                add_network_security_aka_sim(dict, ssid);
+       } else if (g_strcmp0(ssid->eap, "pwd") == 0) {
+               if(!ssid->passphrase)
+                       return;
+               supplicant_dbus_dict_append_basic(dict, "password",
+                               DBUS_TYPE_STRING,
+                               &ssid->passphrase);
+       } else if (g_strcmp0(ssid->eap, "fast") == 0){
+               if (!ssid->identity || !ssid->passphrase)
+                       return;
+
+               add_network_security_fast(dict, ssid);
 #endif
        } else
                return;
@@ -5385,9 +5447,16 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
                        supplicant_dbus_dict_close(iter, &dict);
                        return;
                }
-               snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+
+               if (ssid->bssid_for_connect_len)
+                       snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+                                       ssid->bssid_for_connect[0], ssid->bssid_for_connect[1], ssid->bssid_for_connect[2],
+                                       ssid->bssid_for_connect[3], ssid->bssid_for_connect[4], ssid->bssid_for_connect[5]);
+               else
+                       snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
                                        ssid->bssid[0], ssid->bssid[1], ssid->bssid[2],
                                        ssid->bssid[3], ssid->bssid[4], ssid->bssid[5]);
+
                supplicant_dbus_dict_append_basic(&dict, "bssid",
                                        DBUS_TYPE_STRING, &bssid);
                g_free(bssid);
@@ -5540,11 +5609,13 @@ static void decryption_request_reply(DBusPendingCall *call,
        if (dbus_set_error_from_message(&error, reply)) {
                SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message);
                dbus_error_free(&error);
+               ret = -EINVAL;
                goto done;
        }
 
        if (dbus_message_iter_init(reply, &args) == FALSE) {
                SUPPLICANT_DBG("dbus_message_iter_init() failed");
+               ret = -EINVAL;
                goto done;
        }
 
@@ -5559,6 +5630,7 @@ static void decryption_request_reply(DBusPendingCall *call,
                interface_add_network_result, data,
                data->interface);
 
+done:
        if (ret < 0) {
                SUPPLICANT_DBG("AddNetwork failed %d", ret);
                callback_assoc_failed(decrypt_request_data.data->user_data);
@@ -5567,7 +5639,6 @@ static void decryption_request_reply(DBusPendingCall *call,
                dbus_free(data);
        }
 
-done:
        dbus_message_unref(reply);
        dbus_pending_call_unref(call);
 
@@ -5706,7 +5777,7 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
                        network_remove(intf_data);
                } else
 #if defined TIZEN_EXT
-                       if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) {
+                       if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0 && !ssid->eap) {
                                ret = send_decryption_request(ssid->passphrase, data);
                                if (ret < 0)
                                        SUPPLICANT_DBG("Decryption request failed %d", ret);