Merge "Add dbus method for getting wifi passphrase" into tizen
[platform/core/connectivity/net-config.git] / src / wifi-config.c
index f889209..99c6903 100755 (executable)
@@ -28,6 +28,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/time.h>
 
 #include <vconf.h>
 
 #define WIFI_SECURITY_WEP              "wep"
 #define WIFI_SECURITY_WPA_PSK  "psk"
 #define WIFI_SECURITY_EAP              "ieee8021x"
+#define WIFI_SECURITY_SAE              "sae"
 
 #define WIFI_CONFIG_PREFIX      "wifi_"
 #define MAC_ADDRESS_LENGTH             12
 #define WIFI_PREFIX_LENGTH             MAC_ADDRESS_LENGTH + 6  /* wifi_485a3f2f506a_ */
 #define PROFILE_PREFIX_LENGTH  WIFI_PREFIX_LENGTH + 21 /* /net/connman/service/wifi_485a3f2f506a_ */
 
-#define WIFI_MAC_PATH_LENGTH           64
-#define WIFI_MAC_ADDR_LENGTH           17
-#define WIFI_MAC_ADDR_PATH             "/sys/class/net/%s/address"
-
 #define        NET_DNS_ADDR_MAX                2
 
 #define MAX_WIFI_PROFILES              200
@@ -236,6 +234,8 @@ static gboolean __get_security_type(const gchar *config_id, gchar **type)
                *type = g_strdup(WIFI_SECURITY_WPA_PSK);
        } else if (g_str_has_suffix(config_id, WIFI_SECURITY_EAP) == TRUE) {
                *type = g_strdup(WIFI_SECURITY_EAP);
+       } else if (g_str_has_suffix(config_id, WIFI_SECURITY_SAE) == TRUE) {
+               *type = g_strdup(WIFI_SECURITY_SAE);
        } else {
                *type = NULL;
                return FALSE;
@@ -289,16 +289,37 @@ static gboolean __remove_file(const gchar *pathname, const gchar *filename)
        return ret;
 }
 
+static gboolean __remove_all_files(const gchar *pathname)
+{
+       DIR *dir_ptr = NULL;
+       struct dirent *file = NULL;
+
+       if ((dir_ptr = opendir(pathname)) == NULL)
+               return TRUE;
+
+       while ((file = readdir(dir_ptr)) != NULL) {
+               if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0)
+                       continue;
+
+               if (__remove_file(pathname, file->d_name) != TRUE) {
+                       ERR("Cannot remove [%s/%s]", pathname, file->d_name);
+                       closedir(dir_ptr);
+
+                       return FALSE;
+               }
+       }
+
+       closedir(dir_ptr);
+
+       return TRUE;
+}
+
 static gboolean __remove_configuration(const gchar *pathname)
 {
        int ret = 0;
 
-       if (__remove_file(pathname, "settings") != TRUE) {
-               ERR("Cannot remove [%s/settings]", pathname);
-               return FALSE;
-       }
-       if (__remove_file(pathname, "data") != TRUE) {
-               ERR("Cannot remove [%s/data]", pathname);
+       if (__remove_all_files(pathname) != TRUE) {
+               ERR("Cannot remove [%s] directory", pathname);
                return FALSE;
        }
 
@@ -335,6 +356,13 @@ static gboolean _load_configuration(const gchar *interface_name,
        config->name = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
        DBG("name [%s]", config->name);
 
+       if (config->name == NULL) {
+               ERR("Fail to get Name of [%s]", group_name);
+               g_key_file_free(keyfile);
+               g_free(group_name);
+               return FALSE;
+       }
+
        __get_security_type(config_id, &config->security_type);
        if (config->security_type == NULL) {
                ERR("Fail to _get_security_type");
@@ -523,9 +551,10 @@ static gboolean _remove_configuration(const gchar *interface_name, const gchar *
                if (__remove_configuration(dir) != TRUE) {
                        ERR("[%s] is existed, but cannot remove", dir);
                        ret = FALSE;
+               } else {
+                       INFO("Success to remove [%s]", dir);
+                       ret = TRUE;
                }
-               INFO("Success to remove [%s]", dir);
-               ret = TRUE;
        } else {
                ERR("[%s] is not existed", dir);
                ret = FALSE;
@@ -625,7 +654,14 @@ static gboolean _get_field(const gchar *interface_name,
        if (g_strcmp0(key, WIFI_CONFIG_NAME) == 0) {
                val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
        } else if (g_strcmp0(key, WIFI_CONFIG_PASSPHRASE) == 0) {
-               val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
+               gchar *enc_pass = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
+               if (enc_pass) {
+                       val = _netconfig_decrypt_passphrase(enc_pass);
+                       g_free(enc_pass);
+
+                       if (!val)
+                               ERR("Failed to decrypt the passphrase");
+               }
        } else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
                val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
        } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
@@ -1050,6 +1086,12 @@ gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context,
        g_return_val_if_fail(wifi != NULL, TRUE);
 
        mac_addr = wifi_state_get_mac_address(ifname);
+       if (!mac_addr) {
+               ERR("Fail to get mac-address");
+               netconfig_error_no_profile(context);
+               return TRUE;
+       }
+
        DBG("%s", mac_addr);
        config_ids = _get_list(mac_addr);
        if (config_ids == NULL) {
@@ -1106,7 +1148,7 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PASSPHRASE, g_variant_new_string(conf->passphrase));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
-       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_int32(conf->frequency));
+       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_uint32(conf->frequency));
 
        if (conf->proxy_address != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
@@ -1188,6 +1230,8 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        gchar *field;
        gchar *group_name = NULL;
        int order = 0;
+       int rv;
+       struct timeval modified_time;
 
        if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
                ERR("Invalid parameter");
@@ -1229,8 +1273,8 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                                conf->is_hidden = NULL;
                        }
                } else if (g_strcmp0(field, WIFI_CONFIG_FREQUENCY) == 0) {
-                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT32)) {
-                               conf->frequency = g_variant_get_int32(value);
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
+                               conf->frequency = g_variant_get_uint32(value);
                                DBG("frequency [%d]", conf->frequency);
                        } else {
                                conf->frequency = 0;
@@ -1339,31 +1383,22 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, conf->favorite);
        g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, conf->autoconnect);
 
-#if GLIB_CHECK_VERSION(2,62,0)
-       gint64 real_time = 0;
-       GDateTime *dt_real_time = NULL;
-
-       real_time = g_get_real_time();
-       dt_real_time = g_date_time_new_from_unix_utc(real_time);
-       if (dt_real_time) {
-               gchar *str = g_date_time_format_iso8601(dt_real_time);
-               g_date_time_unref(dt_real_time);
-               if (str) {
-                       g_key_file_set_string(keyfile, group_name,
-                                             WIFI_CONFIG_MODIFIED, str);
-                       g_free(str);
+       rv = gettimeofday(&modified_time, NULL);
+       if (!rv) {
+               struct tm modified_tm;
+               char time_buf[255];
+               time_t modified_t = modified_time.tv_sec;
+
+               if (localtime_r(&modified_t, &modified_tm)) {
+                       if (strftime(time_buf, sizeof(time_buf), "%FT%TZ", &modified_tm)) {
+                               field = g_strdup(time_buf);
+                               if (field) {
+                                       g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_MODIFIED, field);
+                                       g_free(field);
+                               }
+                       }
                }
        }
-#else /* GLIB_CHECK_VERSION(2,62,0) */
-       GTimeVal modified;
-       g_get_current_time(&modified);
-       gchar *str = g_time_val_to_iso8601(&modified);
-       if (str) {
-               g_key_file_set_string(keyfile, group_name,
-                                     WIFI_CONFIG_MODIFIED, str);
-               g_free(str);
-       }
-#endif /* GLIB_CHECK_VERSION(2,62,0) */
 
        /* Optional field */
        if (conf->proxy_address != NULL) {
@@ -1480,7 +1515,7 @@ gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
        g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
-       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_int32(conf->frequency));
+       g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FREQUENCY, g_variant_new_uint32(conf->frequency));
 
        if (conf->proxy_address != NULL)
                g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
@@ -1597,8 +1632,8 @@ gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *contex
                                conf->is_hidden = NULL;
                        }
                } else if (g_strcmp0(field, WIFI_CONFIG_FREQUENCY) == 0) {
-                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_INT32)) {
-                               conf->frequency = g_variant_get_int32(value);
+                       if (g_variant_is_of_type(value, G_VARIANT_TYPE_UINT32)) {
+                               conf->frequency = g_variant_get_uint32(value);
                                DBG("frequency [%d]", conf->frequency);
                        } else {
                                conf->frequency = 0;
@@ -1811,6 +1846,52 @@ gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context,
        return TRUE;
 }
 
+gboolean handle_reset_wifi_config(Wifi *wifi, GDBusMethodInvocation *context)
+{
+       DIR *dir_ptr = NULL;
+       struct dirent *file = NULL;
+       struct stat buf;
+       char dir_name[512] = { 0, };
+       char file_name[1024] = { 0, };
+
+       g_return_val_if_fail(wifi != NULL, TRUE);
+
+       DBG("Try to remove connman Wi-Fi config files...");
+
+       if ((dir_ptr = opendir(CONNMAN_STORAGE)) != NULL) {
+               while ((file = readdir(dir_ptr)) != NULL) {
+                       if (strncmp(file->d_name, ".", 1) == 0 || strncmp(file->d_name, "..", 2) == 0 ||
+                                       strncmp(file->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
+                               continue;
+                       }
+
+                       snprintf(dir_name, 512, CONNMAN_STORAGE"/%s", file->d_name);
+
+                       if (lstat(dir_name, &buf) == -1)
+                               continue;
+
+                       DBG("Remove wifi config: %s", file->d_name);
+
+                       if (S_ISDIR(buf.st_mode)) {
+                               memset(file_name, 0, 1024);
+                               snprintf(file_name, 1024, "%s/data", dir_name);
+                               unlink(file_name);
+                               memset(file_name, 0, 1024);
+                               snprintf(file_name, 1024, "%s/settings", dir_name);
+                               unlink(file_name);
+                       }
+                       rmdir(dir_name);
+               }
+
+               closedir(dir_ptr);
+               sync();
+       }
+
+       wifi_complete_reset_wifi_config(wifi, context);
+
+       return TRUE;
+}
+
 /* config field key / value */
 /*
  * [wifi_macaddress_config_id]
@@ -1893,7 +1974,7 @@ gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context
        gboolean ret = FALSE;
        gchar *passphrase = NULL;
 
-       if ((wifi == NULL) || (config_id == NULL)) {
+       if ((wifi == NULL) || (ifname == NULL) || (config_id == NULL)) {
                ERR("Invalid parameter");
                netconfig_error_invalid_parameter(context);
                return TRUE;