Fix path traversal
[platform/core/connectivity/net-config.git] / src / wifi-config.c
index c172345..88cda23 100755 (executable)
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <sys/stat.h>
@@ -28,6 +29,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/time.h>
 
 #include <vconf.h>
 
 #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        NET_DNS_ADDR_MAX                2
 
 #define MAX_WIFI_PROFILES              200
@@ -202,6 +199,11 @@ gboolean wifi_config_get_group_name(const gchar *prefix,
        gchar *g_name = NULL;
        gboolean ret = FALSE;
 
+       if (__netconfig_is_valid_config_id(config_id) == FALSE) {
+               ERR("Invalid config_id [%s]", config_id);
+               return FALSE;
+       }
+
        ret = __get_mac_address(interface_name, &mac_address);
        if ((ret != TRUE) || (strlen(mac_address) == 0)) {
                ERR("Cannot get WIFI MAC address");
@@ -653,7 +655,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) {
@@ -1140,7 +1149,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));
@@ -1211,6 +1220,27 @@ static unsigned char __netconfig_convert_netmask_to_prefixlen(
        return bits;
 }
 
+gboolean __netconfig_is_valid_config_id(const gchar *config_id)
+{
+       int length;
+
+       if (!config_id)
+               return FALSE;
+
+       length = strlen(config_id);
+       if (length < 1 || length > WIFI_CONFIG_ID_LENGTH)
+               return FALSE;
+
+       for (int i = 0; i < length; i++) {
+               if (!(islower(config_id[i])) &&
+                               !(isdigit(config_id[i])) &&
+                               config_id[i] != '_')
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
                const gchar *ifname, const gchar *config_id, GVariant *configuration)
 {
@@ -1222,8 +1252,12 @@ 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)) {
+       if ((wifi == NULL) ||
+                       (__netconfig_is_valid_config_id(config_id) == FALSE) ||
+                       (configuration == NULL)) {
                ERR("Invalid parameter");
                netconfig_error_invalid_parameter(context);
                return TRUE;
@@ -1373,31 +1407,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) {
@@ -1514,7 +1539,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));
@@ -1973,7 +1998,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;