From 48849c7e84aa27cf3caef152ff649f0fed33fc3b Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Mon, 28 Dec 2015 19:06:21 +0900 Subject: [PATCH] Add get/set wifi tethering passphrase functions to avoid permission issue Change-Id: I7effb3a30fd8261a4faa1b578aab1c6f3f8227b2 Signed-off-by: Seonah Moon --- CMakeLists.txt | 2 +- include/mobileap_wifi.h | 7 ++ include/tethering-dbus-interface.xml | 11 +++ packaging/mobileap-agent.spec | 3 +- src/mobileap_main.c | 4 + src/mobileap_wifi.c | 164 +++++++++++++++++++++++++++++++++++ 6 files changed, 189 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d36a211..29f9bc5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") INCLUDE_DIRECTORIES(${INCLUDE_DIR} ${CMAKE_SOURCE_DIR}) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED gio-2.0 gio-unix-2.0 dbus-1 dlog deviced vconf notification capi-network-connection capi-network-bluetooth appcore-common capi-network-wifi capi-network-wifi-direct alarm-service appsvc libcrypto) +pkg_check_modules(pkgs REQUIRED gio-2.0 gio-unix-2.0 dbus-1 dlog deviced vconf notification capi-network-connection capi-network-bluetooth appcore-common capi-network-wifi capi-network-wifi-direct alarm-service appsvc libcrypto key-manager) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") diff --git a/include/mobileap_wifi.h b/include/mobileap_wifi.h index 07534a0..44ced76 100644 --- a/include/mobileap_wifi.h +++ b/include/mobileap_wifi.h @@ -75,4 +75,11 @@ gboolean tethering_enable_wifi_ap(Tethering *obj, GDBusMethodInvocation *context gboolean tethering_disable_wifi_ap(Tethering *obj, GDBusMethodInvocation *context); + +gboolean tethering_get_wifi_tethering_passphrase(Tethering *obj, + GDBusMethodInvocation *context); + +gboolean tethering_set_wifi_tethering_passphrase(Tethering *obj, + GDBusMethodInvocation *context, gchar *passphrase); + #endif /* __MOBILEAP_WIFI_H__ */ diff --git a/include/tethering-dbus-interface.xml b/include/tethering-dbus-interface.xml index 0448c2e..1688399 100644 --- a/include/tethering-dbus-interface.xml +++ b/include/tethering-dbus-interface.xml @@ -102,6 +102,17 @@ + + + + + + + + + + + diff --git a/packaging/mobileap-agent.spec b/packaging/mobileap-agent.spec index 66d8a10..9e3a066 100644 --- a/packaging/mobileap-agent.spec +++ b/packaging/mobileap-agent.spec @@ -1,6 +1,6 @@ Name: mobileap-agent Summary: Mobile AP daemon for setting tethering environments -Version: 1.0.39 +Version: 1.0.40 Release: 1 Group: System/Network License: Apache-2.0 @@ -27,6 +27,7 @@ BuildRequires: pkgconfig(capi-network-wifi) BuildRequires: pkgconfig(alarm-service) BuildRequires: pkgconfig(appsvc) BuildRequires: pkgconfig(libcrypto) +BuildRequires: pkgconfig(key-manager) BuildRequires: cmake %if "%{?profile}" != "tv" Requires(post): bluetooth-agent diff --git a/src/mobileap_main.c b/src/mobileap_main.c index 8d544c0..5fe239d 100644 --- a/src/mobileap_main.c +++ b/src/mobileap_main.c @@ -462,6 +462,10 @@ static void on_bus_acquired_cb (GDBusConnection *connection, const gchar *name, G_CALLBACK(tethering_get_station_info), NULL); g_signal_connect(tethering_obj, "handle-get-data-packet-usage", G_CALLBACK(tethering_get_data_packet_usage), NULL); + g_signal_connect(tethering_obj, "handle-get-wifi-tethering-passphrase", + G_CALLBACK(tethering_get_wifi_tethering_passphrase), NULL); + g_signal_connect(tethering_obj, "handle-set-wifi-tethering-passphrase", + G_CALLBACK(tethering_set_wifi_tethering_passphrase), NULL); _init_network((void *)tethering_obj); _register_vconf_cb((void *)tethering_obj); diff --git a/src/mobileap_wifi.c b/src/mobileap_wifi.c index 9423947..bcc9764 100755 --- a/src/mobileap_wifi.c +++ b/src/mobileap_wifi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "mobileap_softap.h" #include "mobileap_common.h" @@ -30,10 +31,19 @@ #include "mobileap_notification.h" #define WIFI_RECOVERY_GUARD_TIME 1000 /* ms */ +#define MOBILE_AP_WIFI_KEY_MIN_LEN 8 /**< Minimum length of wifi key */ +#define MOBILE_AP_WIFI_KEY_MAX_LEN 64 /**< Maximum length of wifi key */ + +#define MOBILE_AP_WIFI_PASSPHRASE_STORE_KEY "tethering_wifi_passphrase" static mobile_ap_error_code_e __update_softap_settings(softap_settings_t *st, gchar *ssid, gchar *passphrase, int hide_mode, softap_security_type_e security_type); +static mobile_ap_error_code_e __get_passphrase(char *passphrase, + unsigned int passphrase_size, unsigned int *passphrase_len); +static mobile_ap_error_code_e __set_passphrase(const char *passphrase, const unsigned int size); +static char *__get_key_manager_alias(const char* name); static int __turn_off_wifi(Tethering *obj); +static unsigned int __generate_initial_passphrase(char *passphrase, unsigned int size); static GDBusMethodInvocation *g_context = NULL; static guint wifi_recovery_timeout_id = 0; @@ -864,3 +874,157 @@ gboolean _is_trying_wifi_operation(void) { return (g_context || wifi_recovery_timeout_id ? TRUE : FALSE); } + +static char *__get_key_manager_alias(const char* name) +{ + size_t alias_len = strlen(name) + strlen(ckmc_owner_id_system) + strlen(ckmc_owner_id_separator); + char *ckm_alias = (char *)malloc(alias_len + 1); + if (!ckm_alias) { + ERR("Fail to allocate memory\n"); + return NULL; + } + + memset(ckm_alias, 0, alias_len); + strncat(ckm_alias, ckmc_owner_id_system, strlen(ckmc_owner_id_system)); + strncat(ckm_alias, ckmc_owner_id_separator, strlen(ckmc_owner_id_separator)); + strncat(ckm_alias, name, strlen(name)); + + return ckm_alias; +} + +static mobile_ap_error_code_e __set_passphrase(const char *passphrase, const unsigned int size) +{ + if (passphrase == NULL || size == 0) + return MOBILE_AP_ERROR_INVALID_PARAM; + + int ret = -1; + char *alias; + ckmc_raw_buffer_s ckmc_buf; + ckmc_policy_s ckmc_policy; + + ckmc_policy.password = NULL; + ckmc_policy.extractable = true; + + ckmc_buf.data = (unsigned char *) passphrase; + ckmc_buf.size = strlen(passphrase) + 1; + + alias = __get_key_manager_alias(MOBILE_AP_WIFI_PASSPHRASE_STORE_KEY); + + ret = ckmc_remove_data(alias); + if (ret != CKMC_ERROR_NONE && ret != CKMC_ERROR_DB_ALIAS_UNKNOWN) { + ERR("Fail to remove old data : %d", ret); + return MOBILE_AP_ERROR_INTERNAL; + } + + ret = ckmc_save_data(alias, ckmc_buf, ckmc_policy); + if (ret != CKMC_ERROR_NONE) { + ERR("Fail to save the passphrase : %d", ret); + return MOBILE_AP_ERROR_INTERNAL; + } + + if (alias) + free(alias); + + return MOBILE_AP_ERROR_NONE; +} + +static unsigned int __generate_initial_passphrase(char *passphrase, unsigned int size) +{ + if (passphrase == NULL || size == 0 || size < MOBILE_AP_WIFI_KEY_MIN_LEN + 1) + return 0; + + guint32 rand_int = 0; + int index = 0; + + for (index = 0; index < MOBILE_AP_WIFI_KEY_MIN_LEN; index++) { + rand_int = g_random_int_range('a', 'z'); + passphrase[index] = rand_int; + } + + passphrase[index] = '\0'; + return index; +} + +static mobile_ap_error_code_e __get_passphrase(char *passphrase, + unsigned int passphrase_size, unsigned int *passphrase_len) +{ + if (passphrase == NULL || passphrase_size == 0) { + ERR("Invalid parameter\n"); + return MOBILE_AP_ERROR_INVALID_PARAM; + } + + int ret = 0; + char *alias = NULL; + char *passwd = NULL; + char tmp[MOBILE_AP_WIFI_KEY_MAX_LEN + 1] = {0, }; + ckmc_raw_buffer_s *ckmc_buf; + + alias = __get_key_manager_alias(MOBILE_AP_WIFI_PASSPHRASE_STORE_KEY); + ret = ckmc_get_data(alias, passwd, &ckmc_buf); + if (ret < 0) { + DBG("Create new password\n"); + ret = __generate_initial_passphrase(tmp, sizeof(tmp)); + + if (ret == 0) { + ERR("generate_initial_passphrase failed : %d\n", *passphrase_len); + return MOBILE_AP_ERROR_INTERNAL; + } else { + *passphrase_len = ret; + g_strlcpy(passphrase, tmp, (*passphrase_len)+1); + + if (__set_passphrase(passphrase, *passphrase_len) != MOBILE_AP_ERROR_NONE) { + DBG("set_passphrase is failed : %s, %d", passphrase, *passphrase_len); + return MOBILE_AP_ERROR_INTERNAL; + } + } + } else { + *passphrase_len = ckmc_buf->size; + g_strlcpy(passphrase, (char *)ckmc_buf->data, (*passphrase_len) + 1); + } + + if (alias) + free(alias); + + return MOBILE_AP_ERROR_NONE; +} + +gboolean tethering_get_wifi_tethering_passphrase(Tethering *obj, + GDBusMethodInvocation *context) +{ + char passphrase_buf[MOBILE_AP_WIFI_KEY_MAX_LEN + 1] = {0, }; + unsigned int len = 0; + mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE; + + ret = __get_passphrase(passphrase_buf, sizeof(passphrase_buf), &len); + if (ret != MOBILE_AP_ERROR_NONE) { + tethering_complete_get_wifi_tethering_passphrase(obj, context, 0ULL, 0, ret); + return false; + } + + tethering_complete_get_wifi_tethering_passphrase(obj, context, passphrase_buf, len, ret); + + return true; +} + +gboolean tethering_set_wifi_tethering_passphrase(Tethering *obj, + GDBusMethodInvocation *context, gchar *passphrase) +{ + char old_passphrase[MOBILE_AP_WIFI_KEY_MAX_LEN + 1] = {0, }; + unsigned int old_len = 0; + unsigned int passphrase_len = sizeof(passphrase); + mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE; + + ret = __get_passphrase(old_passphrase, sizeof(old_passphrase), &old_len); + if (ret == MOBILE_AP_ERROR_NONE && old_len == passphrase_len && + !g_strcmp0(old_passphrase, passphrase)) { + ret = MOBILE_AP_ERROR_NONE; + tethering_complete_set_wifi_tethering_passphrase(obj, context, ret); + return true; + } + + ret = __set_passphrase(passphrase, passphrase_len); + + tethering_complete_set_wifi_tethering_passphrase(obj, context, ret); + + return true; +} -- 2.7.4