From: Jaehyun Kim Date: Thu, 28 Dec 2017 11:02:31 +0000 (+0900) Subject: Make WiFi passphrase enc/dec routine async to prevent mutual synchronous call to... X-Git-Tag: accepted/tizen/unified/20171229.070248^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=99feb5906c6a3eefb88477243f2883e18382b900;hp=9458c40dfd9b99b9da24e3cdb249dbc116e8750c;p=platform%2Fupstream%2Fconnman.git Make WiFi passphrase enc/dec routine async to prevent mutual synchronous call to net-config Change-Id: Ic7795b430e92b7ee81d4c65b39ef1aa914fccc1a Signed-off-by: Jaehyun Kim --- diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 9177275..612ab5a 100755 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -399,6 +399,7 @@ struct _GSupplicantCallbacks { const char *property); #if defined TIZEN_EXT void (*system_power_off) (void); + void (*assoc_failed) (void *user_data); #endif void (*add_station) (const char *mac); void (*remove_station) (const char *mac); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index d84c893..9b7e003 100755 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -503,6 +503,17 @@ static void callback_network_merged(GSupplicantNetwork *network) callbacks_pointer->network_merged(network); } + +static void callback_assoc_failed(void *user_data) +{ + if (!callbacks_pointer) + return; + + if (!callbacks_pointer->assoc_failed) + return; + + callbacks_pointer->assoc_failed(user_data); +} #endif static void callback_network_changed(GSupplicantNetwork *network, @@ -5173,6 +5184,135 @@ static void wps_process_credentials(DBusMessageIter *iter, void *user_data) dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials); } +#if defined TIZEN_EXT +#define NETCONFIG_SERVICE "net.netconfig" +#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi" +#define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi" + +struct dec_method_call_data { + struct interface_connect_data *data; + DBusPendingCall *pending_call; +}; + +static struct dec_method_call_data decrypt_request_data; + +static void crypt_method_call_cancel(void) +{ + if (decrypt_request_data.pending_call) { + dbus_pending_call_cancel(decrypt_request_data.pending_call); + dbus_pending_call_unref(decrypt_request_data.pending_call); + decrypt_request_data.pending_call = NULL; + } + + g_free(decrypt_request_data.data->path); + g_free(decrypt_request_data.data->ssid); + dbus_free(decrypt_request_data.data); + decrypt_request_data.data = NULL; +} + +static void decryption_request_reply(DBusPendingCall *call, + void *user_data) +{ + DBusMessage *reply; + DBusError error; + DBusMessageIter args; + char *out_data; + int ret; + static gchar* origin_value = NULL; + struct interface_connect_data *data = user_data; + + g_free(origin_value); + origin_value = NULL; + + SUPPLICANT_DBG(""); + + reply = dbus_pending_call_steal_reply(call); + + dbus_error_init(&error); + if (dbus_set_error_from_message(&error, reply)) { + SUPPLICANT_DBG("decryption_request_reply() %s %s", error.name, error.message); + dbus_error_free(&error); + goto done; + } + + if (dbus_message_iter_init(reply, &args) == FALSE) { + SUPPLICANT_DBG("dbus_message_iter_init() failed"); + goto done; + } + + dbus_message_iter_get_basic(&args, &out_data); + + origin_value = g_strdup((const gchar *)out_data); + data->ssid->passphrase = origin_value; + + ret = supplicant_dbus_method_call(data->interface->path, + SUPPLICANT_INTERFACE ".Interface", "AddNetwork", + interface_add_network_params, + interface_add_network_result, data, + data->interface); + + if (ret < 0) { + SUPPLICANT_DBG("AddNetwork failed %d", ret); + callback_assoc_failed(decrypt_request_data.data->user_data); + g_free(data->path); + g_free(data->ssid); + dbus_free(data); + } + +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); + + decrypt_request_data.pending_call = NULL; + decrypt_request_data.data = NULL; +} + +static int send_decryption_request(const char *passphrase, + struct interface_connect_data *data) +{ + DBusMessage *msg = NULL; + DBusPendingCall *call; + + SUPPLICANT_DBG("Decryption request"); + + if (!passphrase) { + SUPPLICANT_DBG("Invalid parameter"); + return -EINVAL; + } + + if (!connection) + return -EINVAL; + + msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH, + NETCONFIG_WIFI_INTERFACE, "DecryptPassphrase"); + if (!msg) + return -EINVAL; + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase, + DBUS_TYPE_INVALID); + + if (!dbus_connection_send_with_reply(connection, msg, + &call, DBUS_TIMEOUT_USE_DEFAULT)) { + dbus_message_unref(msg); + return -EIO; + } + + if (!call) { + dbus_message_unref(msg); + return -EIO; + } + + decrypt_request_data.pending_call = call; + decrypt_request_data.data = data; + + dbus_pending_call_set_notify(call, decryption_request_reply, data, NULL); + dbus_message_unref(msg); + + SUPPLICANT_DBG("Decryption request succeeded"); + + return 0; +} +#endif int g_supplicant_interface_connect(GSupplicantInterface *interface, GSupplicantSSID *ssid, @@ -5210,6 +5350,13 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface, "ProcessCredentials", DBUS_TYPE_BOOLEAN_AS_STRING, wps_process_credentials, wps_start, data, interface); } else +#if defined TIZEN_EXT + if (ssid->passphrase && g_strcmp0(ssid->passphrase, "") != 0) { + ret = send_decryption_request(ssid->passphrase, data); + if (ret < 0) + SUPPLICANT_DBG("Decryption request failed %d", ret); + } else +#endif ret = supplicant_dbus_method_call(interface->path, SUPPLICANT_INTERFACE ".Interface", "AddNetwork", interface_add_network_params, @@ -5334,7 +5481,17 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface, if (!system_available) return -EFAULT; +#if defined TIZEN_EXT + if (decrypt_request_data.pending_call && + decrypt_request_data.data && + decrypt_request_data.data->user_data == user_data) { + callback_assoc_failed(decrypt_request_data.data->user_data); + crypt_method_call_cancel(); + + return 0; + } +#endif data = dbus_malloc0(sizeof(*data)); if (!data) return -ENOMEM; diff --git a/packaging/connman.spec b/packaging/connman.spec index 3560de5..fee387e 100755 --- a/packaging/connman.spec +++ b/packaging/connman.spec @@ -5,7 +5,7 @@ Name: connman Version: 1.29 -Release: 25 +Release: 26 License: GPL-2.0+ Summary: Connection Manager Url: http://connman.net diff --git a/plugins/wifi.c b/plugins/wifi.c index 9c453b3..995fab4 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -163,65 +163,115 @@ static void start_autoscan(struct connman_device *device); #define NETCONFIG_WIFI_PATH "/net/netconfig/wifi" #define NETCONFIG_WIFI_INTERFACE NETCONFIG_SERVICE ".wifi" -static gchar* send_cryptographic_request(const char *passphrase, const char *method) +struct enc_method_call_data { + DBusConnection *connection; + struct connman_network *network; +}; + +static struct enc_method_call_data encrypt_request_data; + +static void encryption_request_reply(DBusPendingCall *call, + void *user_data) { - DBusConnection *connection = NULL; - DBusMessage *msg = NULL, *reply = NULL; + DBusMessage *reply; DBusError error; - gchar *result; - const char *out_data; + DBusMessageIter args; + char *out_data; + struct connman_service *service; + gchar* encrypted_value = NULL; + struct connman_network *network = encrypt_request_data.network; - if (!passphrase || !method) { - DBG("Invalid parameter"); - return NULL; - } + DBG(""); + + reply = dbus_pending_call_steal_reply(call); dbus_error_init(&error); + if (dbus_set_error_from_message(&error, reply)) { + DBG("send_encryption_request() %s %s", error.name, error.message); + dbus_error_free(&error); + goto done; + } + + if (dbus_message_iter_init(reply, &args) == FALSE) + goto done; + + dbus_message_iter_get_basic(&args, &out_data); + + encrypted_value = g_strdup((const gchar *)out_data); + service = connman_service_lookup_from_network(network); + + if (!service) { + DBG("encryption result: no service"); + goto done; + } + + if (connman_service_get_favorite(service)) { + __connman_service_set_passphrase(service, encrypted_value); + __connman_service_save(service); + } else + connman_network_set_string(network, "WiFi.Passphrase", + encrypted_value); + + DBG("encryption result: succeeded"); + +done: + dbus_message_unref(reply); + dbus_pending_call_unref(call); + dbus_connection_unref(encrypt_request_data.connection); + g_free(encrypted_value); + + encrypt_request_data.connection = NULL; + encrypt_request_data.network = NULL; +} + +static int send_encryption_request(const char *passphrase, + struct connman_network *network) +{ + DBusConnection *connection = NULL; + DBusMessage *msg = NULL; + DBusPendingCall *call; + + if (!passphrase) { + DBG("Invalid parameter"); + return -EINVAL; + } connection = connman_dbus_get_connection(); if (!connection) { DBG("dbus connection does not exist"); - return NULL; + return -EINVAL; } msg = dbus_message_new_method_call(NETCONFIG_SERVICE, NETCONFIG_WIFI_PATH, - NETCONFIG_WIFI_INTERFACE, method); + NETCONFIG_WIFI_INTERFACE, "EncryptPassphrase"); if (!msg) { dbus_connection_unref(connection); - return NULL; + return -EINVAL; } dbus_message_append_args(msg, DBUS_TYPE_STRING, &passphrase, DBUS_TYPE_INVALID); - reply = dbus_connection_send_with_reply_and_block(connection, msg, - DBUS_TIMEOUT_USE_DEFAULT, &error); - if (reply == NULL) { - if (dbus_error_is_set(&error)) { - DBG("%s", error.message); - dbus_error_free(&error); - } else { - DBG("Failed to request cryptographic request"); - } - dbus_connection_unref(connection); + if (!dbus_connection_send_with_reply(connection, msg, + &call, DBUS_TIMEOUT_USE_DEFAULT)) { dbus_message_unref(msg); - return NULL; + dbus_connection_unref(connection); + return -EIO; } - dbus_message_unref(msg); - dbus_connection_unref(connection); - - if (!dbus_message_get_args(reply, NULL, - DBUS_TYPE_STRING, &out_data, - DBUS_TYPE_INVALID)) { - dbus_message_unref(reply); - return NULL; + if (!call) { + dbus_message_unref(msg); + dbus_connection_unref(connection); + return -EIO; } - result = g_strdup((const gchar *)out_data); - dbus_message_unref(reply); + encrypt_request_data.connection = connection; + encrypt_request_data.network = network; + + dbus_pending_call_set_notify(call, encryption_request_reply, NULL, NULL); + dbus_message_unref(msg); - return result; + return 0; } #endif @@ -2349,28 +2399,6 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network) ssid->security = network_security(security); ssid->passphrase = connman_network_get_string(network, "WiFi.Passphrase"); -#if defined TIZEN_EXT - /* Decrypt the passphrase - */ - static gchar* origin_value = NULL; - gchar *passphrase = g_strdup(ssid->passphrase); - g_free(origin_value); - origin_value = NULL; - - if (passphrase && g_strcmp0(passphrase, "") != 0) { - origin_value = send_cryptographic_request(passphrase, - "DecryptPassphrase"); - - if (!origin_value) { - DBG("Decryption failed"); - } else { - DBG("Decryption succeeded"); - ssid->passphrase = origin_value; - } - - } - g_free(passphrase); -#endif ssid->eap = connman_network_get_string(network, "WiFi.EAP"); /* @@ -2707,7 +2735,7 @@ static bool handle_wps_completion(GSupplicantInterface *interface, #if defined TIZEN_EXT /* Check the passphrase and encrypt it */ - gchar *encrypted_value = NULL; + int ret; gchar *passphrase = g_strdup(wps_key); connman_network_set_string(network, "WiFi.PinWPS", NULL); @@ -2718,18 +2746,14 @@ static bool handle_wps_completion(GSupplicantInterface *interface, return true; } - encrypted_value = send_cryptographic_request(passphrase, "EncryptPassphrase"); + ret = send_encryption_request(passphrase, network); g_free(passphrase); - if (!encrypted_value) { - DBG("[WPS] Encryption failed"); - return true; - } - DBG("[WPS] Encryption succeeded"); - connman_network_set_string(network, "WiFi.Passphrase", - encrypted_value); - g_free(encrypted_value); + if (!ret) + DBG("[WPS] Encryption request succeeded"); + else + DBG("[WPS] Encryption request failed %d", ret); #else connman_network_set_string(network, "WiFi.Passphrase", @@ -3687,6 +3711,12 @@ static void network_merged(GSupplicantNetwork *network) wifi->network = connman_network; } + +static void assoc_failed(void *user_data) +{ + struct connman_network *network = user_data; + connman_network_set_associating(network, false); +} #endif static void debug(const char *str) @@ -3743,7 +3773,8 @@ static const GSupplicantCallbacks callbacks = { .peer_request = peer_request, #if defined TIZEN_EXT .system_power_off = system_power_off, - .network_merged = network_merged, + .network_merged = network_merged, + .assoc_failed = assoc_failed, #endif .disconnect_reasoncode = disconnect_reasoncode, .assoc_status_code = assoc_status_code,