summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehyun Kim <jeik01.kim@samsung.com>2017-12-28 20:02:31 +0900
committerJaehyun Kim <jeik01.kim@samsung.com>2017-12-28 20:11:46 +0900
commit99feb5906c6a3eefb88477243f2883e18382b900 (patch)
treea39f9fdcc1a2e2a869258111259a7365cde9a61a
parent9458c40dfd9b99b9da24e3cdb249dbc116e8750c (diff)
downloadconnman-99feb5906c6a3eefb88477243f2883e18382b900.tar.gz
connman-99feb5906c6a3eefb88477243f2883e18382b900.tar.bz2
connman-99feb5906c6a3eefb88477243f2883e18382b900.zip
Make WiFi passphrase enc/dec routine async to prevent mutual synchronous call to net-configsubmit/tizen/20171229.034008accepted/tizen/unified/20171229.070248
Change-Id: Ic7795b430e92b7ee81d4c65b39ef1aa914fccc1a Signed-off-by: Jaehyun Kim <jeik01.kim@samsung.com>
-rwxr-xr-xgsupplicant/gsupplicant.h1
-rwxr-xr-xgsupplicant/supplicant.c157
-rwxr-xr-xpackaging/connman.spec2
-rwxr-xr-xplugins/wifi.c165
4 files changed, 257 insertions, 68 deletions
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index 9177275e..612ab5ae 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 d84c8930..9b7e003f 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 3560de57..fee387e9 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 9c453b34..995fab47 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,