Apply DNS configuration method
[platform/upstream/connman.git] / src / config.c
old mode 100644 (file)
new mode 100755 (executable)
index 330ae81..25dd174
@@ -52,6 +52,7 @@ struct connman_config_service {
        char *private_key_passphrase_type;
        char *phase2;
        char *passphrase;
+       enum connman_service_security security;
        GSList *service_identifiers;
        char *config_ident; /* file prefix */
        char *config_entry; /* entry name */
@@ -99,6 +100,7 @@ static bool cleanup = false;
 #define SERVICE_KEY_IDENTITY           "Identity"
 #define SERVICE_KEY_PHASE2             "Phase2"
 #define SERVICE_KEY_PASSPHRASE         "Passphrase"
+#define SERVICE_KEY_SECURITY           "Security"
 #define SERVICE_KEY_HIDDEN             "Hidden"
 
 #define SERVICE_KEY_IPv4               "IPv4"
@@ -129,6 +131,7 @@ static const char *service_possible_keys[] = {
        SERVICE_KEY_IDENTITY,
        SERVICE_KEY_PHASE2,
        SERVICE_KEY_PASSPHRASE,
+       SERVICE_KEY_SECURITY,
        SERVICE_KEY_HIDDEN,
        SERVICE_KEY_IPv4,
        SERVICE_KEY_IPv6,
@@ -399,7 +402,7 @@ static bool load_service_generic(GKeyFile *keyfile,
                        char *ptr;
                        long int value = strtol(mask, &ptr, 10);
 
-                       if (ptr != mask && *ptr == '\0' && value <= 32)
+                       if (ptr != mask && *ptr == '\0' && value && value <= 32)
                                prefix_len = value;
 
                        addr = 0xffffffff << (32 - prefix_len);
@@ -513,6 +516,7 @@ static bool load_service(GKeyFile *keyfile, const char *group,
        struct connman_config_service *service;
        const char *ident;
        char *str, *hex_ssid;
+       enum connman_service_security security;
        bool service_created = false;
 
        /* Strip off "service_" prefix */
@@ -664,6 +668,41 @@ static bool load_service(GKeyFile *keyfile, const char *group,
                service->passphrase = str;
        }
 
+       str = __connman_config_get_string(keyfile, group, SERVICE_KEY_SECURITY,
+                       NULL);
+       security = __connman_service_string2security(str);
+
+       if (service->eap) {
+
+               if (str && security != CONNMAN_SERVICE_SECURITY_8021X)
+                       connman_info("Mismatch between EAP configuration and "
+                                       "setting %s = %s",
+                                       SERVICE_KEY_SECURITY, str);
+
+               service->security = CONNMAN_SERVICE_SECURITY_8021X;
+
+       } else if (service->passphrase) {
+
+               if (str) {
+                       if (security == CONNMAN_SERVICE_SECURITY_PSK ||
+#if defined TIZEN_EXT
+                           security == CONNMAN_SERVICE_SECURITY_RSN ||
+#endif
+                                       security == CONNMAN_SERVICE_SECURITY_WEP) {
+                               service->security = security;
+                       } else {
+                               connman_info("Mismatch with passphrase and "
+                                               "setting %s = %s",
+                                               SERVICE_KEY_SECURITY, str);
+
+                               service->security =
+                                       CONNMAN_SERVICE_SECURITY_PSK;
+                       }
+
+               } else
+                       service->security = CONNMAN_SERVICE_SECURITY_PSK;
+       }
+
        service->config_ident = g_strdup(config->ident);
        service->config_entry = g_strdup_printf("service_%s", service->ident);
 
@@ -855,7 +894,7 @@ static void config_notify_handler(struct inotify_event *event,
                return;
        }
 
-       if (event->mask & IN_CREATE)
+       if (event->mask & IN_CREATE || event->mask & IN_MOVED_TO)
                create_config(ident);
 
        if (event->mask & IN_MODIFY) {
@@ -1027,6 +1066,10 @@ static void provision_service_wifi(struct connman_config_service *config,
 
        if (config->phase2)
                __connman_service_set_string(service, "Phase2", config->phase2);
+#if defined TIZEN_EXT
+       else
+               __connman_service_set_string(service, "Phase2", NULL);
+#endif
 
        if (config->passphrase)
                __connman_service_set_string(service, "Passphrase",
@@ -1054,6 +1097,20 @@ static gboolean remove_virtual_config(gpointer user_data)
        return FALSE;
 }
 
+#if defined TIZEN_EXT
+static bool __check_address_type(int address_family, const char *address)
+{
+       unsigned char buf[sizeof(struct in6_addr)] = {0, };
+       int err = 0;
+
+       err = inet_pton(address_family, address, buf);
+       if(err > 0)
+               return TRUE;
+
+       return FALSE;
+}
+#endif
+
 static int try_provision_service(struct connman_config_service *config,
                                struct connman_service *service)
 {
@@ -1063,22 +1120,6 @@ static int try_provision_service(struct connman_config_service *config,
        const void *ssid;
        unsigned int ssid_len;
 
-       type = connman_service_get_type(service);
-       if (type == CONNMAN_SERVICE_TYPE_WIFI &&
-                               g_strcmp0(config->type, "wifi") != 0)
-               return -ENOENT;
-
-       if (type == CONNMAN_SERVICE_TYPE_ETHERNET &&
-                               g_strcmp0(config->type, "ethernet") != 0)
-               return -ENOENT;
-
-       if (type == CONNMAN_SERVICE_TYPE_GADGET &&
-                               g_strcmp0(config->type, "gadget") != 0)
-               return -ENOENT;
-
-       DBG("service %p ident %s", service,
-                                       __connman_service_get_ident(service));
-
        network = __connman_service_get_network(service);
        if (!network) {
                connman_error("Service has no network set");
@@ -1088,6 +1129,50 @@ static int try_provision_service(struct connman_config_service *config,
        DBG("network %p ident %s", network,
                                connman_network_get_identifier(network));
 
+       type = connman_service_get_type(service);
+
+       switch(type) {
+       case CONNMAN_SERVICE_TYPE_WIFI:
+               if (__connman_service_string2type(config->type) != type)
+                       return -ENOENT;
+
+               ssid = connman_network_get_blob(network, "WiFi.SSID",
+                                               &ssid_len);
+               if (!ssid) {
+                       connman_error("Network SSID not set");
+                       return -EINVAL;
+               }
+
+               if (!config->ssid || ssid_len != config->ssid_len)
+                       return -ENOENT;
+
+               if (memcmp(config->ssid, ssid, ssid_len))
+                       return -ENOENT;
+
+               break;
+
+       case CONNMAN_SERVICE_TYPE_ETHERNET:
+       case CONNMAN_SERVICE_TYPE_GADGET:
+
+               if (__connman_service_string2type(config->type) != type)
+                       return -ENOENT;
+
+               break;
+
+       case CONNMAN_SERVICE_TYPE_UNKNOWN:
+       case CONNMAN_SERVICE_TYPE_SYSTEM:
+       case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+       case CONNMAN_SERVICE_TYPE_CELLULAR:
+       case CONNMAN_SERVICE_TYPE_GPS:
+       case CONNMAN_SERVICE_TYPE_VPN:
+       case CONNMAN_SERVICE_TYPE_P2P:
+
+               return -ENOENT;
+       }
+
+       DBG("service %p ident %s", service,
+                                       __connman_service_get_ident(service));
+
        if (config->mac) {
                struct connman_device *device;
                const char *device_addr;
@@ -1106,22 +1191,6 @@ static int try_provision_service(struct connman_config_service *config,
                        return -ENOENT;
        }
 
-       if (g_strcmp0(config->type, "wifi") == 0 &&
-                               type == CONNMAN_SERVICE_TYPE_WIFI) {
-               ssid = connman_network_get_blob(network, "WiFi.SSID",
-                                               &ssid_len);
-               if (!ssid) {
-                       connman_error("Network SSID not set");
-                       return -EINVAL;
-               }
-
-               if (!config->ssid || ssid_len != config->ssid_len)
-                       return -ENOENT;
-
-               if (memcmp(config->ssid, ssid, ssid_len) != 0)
-                       return -ENOENT;
-       }
-
        if (!config->ipv6_address) {
                connman_network_set_ipv6_method(network,
                                                CONNMAN_IPCONFIG_METHOD_AUTO);
@@ -1210,9 +1279,6 @@ static int try_provision_service(struct connman_config_service *config,
                g_slist_prepend(config->service_identifiers,
                                g_strdup(service_id));
 
-       if (!config->virtual)
-               __connman_service_set_immutable(service, true);
-
        __connman_service_set_favorite_delayed(service, true, true);
 
        __connman_service_set_config(service, config->config_ident,
@@ -1227,8 +1293,19 @@ static int try_provision_service(struct connman_config_service *config,
                __connman_service_nameserver_clear(service);
 
                for (i = 0; config->nameservers[i]; i++) {
+#if defined TIZEN_EXT
+                       if (__check_address_type(AF_INET, config->nameservers[i]))
+                               __connman_service_nameserver_append(service,
+                                               config->nameservers[i], false,
+                                               CONNMAN_IPCONFIG_TYPE_IPV4);
+                       else if (__check_address_type(AF_INET6, config->nameservers[i]))
+                               __connman_service_nameserver_append(service,
+                                               config->nameservers[i], false,
+                                               CONNMAN_IPCONFIG_TYPE_IPV6);
+#else
                        __connman_service_nameserver_append(service,
                                                config->nameservers[i], false);
+#endif
                }
        }
 
@@ -1240,13 +1317,10 @@ static int try_provision_service(struct connman_config_service *config,
                __connman_service_set_timeservers(service,
                                                config->timeservers);
 
-       if (g_strcmp0(config->type, "wifi") == 0 &&
-                               type == CONNMAN_SERVICE_TYPE_WIFI) {
+       if (type == CONNMAN_SERVICE_TYPE_WIFI) {
                provision_service_wifi(config, service, network,
                                                        ssid, ssid_len);
-       } else
-               __connman_service_connect(service,
-                                       CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+       }
 
        __connman_service_mark_dirty();
 
@@ -1260,8 +1334,21 @@ static int try_provision_service(struct connman_config_service *config,
                virtual->vfile = config->virtual_file;
 
                g_timeout_add(0, remove_virtual_config, virtual);
-       } else
-               __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+
+               return 0;
+       }
+
+       __connman_service_set_immutable(service, true);
+
+       if (type == CONNMAN_SERVICE_TYPE_ETHERNET ||
+                       type == CONNMAN_SERVICE_TYPE_GADGET) {
+               __connman_service_connect(service,
+                               CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+
+               return 0;
+       }
+
+       __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
 
        return 0;
 }
@@ -1301,6 +1388,13 @@ int __connman_config_provision_service(struct connman_service *service)
                        type != CONNMAN_SERVICE_TYPE_GADGET)
                return -ENOSYS;
 
+#if defined TIZEN_EXT
+       if(type == CONNMAN_SERVICE_TYPE_WIFI &&
+                       __connman_service_get_security(service) ==
+                       CONNMAN_SERVICE_SECURITY_NONE)
+               return -ENOSYS;
+#endif
+
        return find_and_provision_service(service);
 }
 
@@ -1375,12 +1469,14 @@ static void generate_random_string(char *str, int length)
 {
        uint8_t val;
        int i;
+       uint64_t rand;
 
        memset(str, '\0', length);
 
        for (i = 0; i < length-1; i++) {
                do {
-                       val = (uint8_t)(random() % 122);
+                       __connman_util_get_random(&rand);
+                       val = (uint8_t)(rand % 122);
                        if (val < 48)
                                val += 48;
                } while((val > 57 && val < 65) || (val > 90 && val < 97));