Merge "Added support to set private-key password." into tizen
[platform/core/connectivity/net-config.git] / src / wifi-config.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <dirent.h>
25 #include <sys/stat.h>
26 #include <glib.h>
27 #include <unistd.h>
28
29 #include <vconf.h>
30
31 #include "log.h"
32 #include "util.h"
33 #include "neterror.h"
34 #include "wifi-config.h"
35 #include "netsupplicant.h"
36 #include "wifi-key-encryption.h"
37
38 #define CONNMAN_STORAGE         "/var/lib/connman"
39
40 #define WIFI_SECURITY_NONE              "none"
41 #define WIFI_SECURITY_WEP               "wep"
42 #define WIFI_SECURITY_WPA_PSK   "psk"
43 #define WIFI_SECURITY_EAP               "ieee8021x"
44
45 #define WIFI_CONFIG_PREFIX      "wifi_"
46 #define MAC_ADDRESS_LENGTH              12
47 #define WIFI_PREFIX_LENGTH              MAC_ADDRESS_LENGTH + 6  /* wifi_485a3f2f506a_ */
48 #define PROFILE_PREFIX_LENGTH   WIFI_PREFIX_LENGTH + 21 /* /net/connman/service/wifi_485a3f2f506a_ */
49
50 #define WIFI_MAC_ADD_LENGTH             17
51 #define WIFI_MAC_ADD_PATH               "/sys/class/net/wlan0/address"
52
53 struct wifi_eap_config {
54         gchar *anonymous_identity;
55         gchar *ca_cert;
56         gchar *client_cert;
57         gchar *private_key;
58         gchar *private_key_password;
59         gchar *identity;
60         gchar *eap_type;
61         gchar *eap_auth_type;
62         gchar *subject_match;
63 };
64
65 struct wifi_config {
66         gchar *name;
67         gchar *ssid;
68         gchar *passphrase;
69         gchar *security_type;
70         gboolean favorite;
71         gboolean autoconnect;
72         gchar *is_hidden;
73         gchar *proxy_address;
74         struct wifi_eap_config *eap_config;
75         gchar *last_error;
76 };
77
78 static void __free_wifi_configuration(struct wifi_config *conf)
79 {
80         if (conf == NULL)
81                 return;
82
83         g_free(conf->name);
84         g_free(conf->ssid);
85         g_free(conf->passphrase);
86         g_free(conf->security_type);
87         g_free(conf->is_hidden);
88         g_free(conf->proxy_address);
89         g_free(conf->last_error);
90         if (conf->eap_config) {
91                 g_free(conf->eap_config->anonymous_identity);
92                 g_free(conf->eap_config->ca_cert);
93                 g_free(conf->eap_config->client_cert);
94                 g_free(conf->eap_config->private_key);
95                 g_free(conf->eap_config->private_key_password);
96                 g_free(conf->eap_config->identity);
97                 g_free(conf->eap_config->eap_type);
98                 g_free(conf->eap_config->eap_auth_type);
99                 g_free(conf->eap_config->subject_match);
100                 g_free(conf->eap_config);
101         }
102         g_free(conf);
103 }
104
105 static gboolean __get_mac_address(gchar **mac_address)
106 {
107         gchar *tmp_mac = NULL;
108         gchar *tmp = NULL;
109         gchar mac[13] = { 0, };
110         gint i = 0, j = 0;
111
112         if (TIZEN_TV) {
113                 FILE *fp = NULL;
114                 char buf[WIFI_MAC_ADD_LENGTH + 1];
115                 if (0 == access(WIFI_MAC_ADD_PATH, F_OK))
116                         fp = fopen(WIFI_MAC_ADD_PATH, "r");
117
118                 if (fp == NULL) {
119                         ERR("Failed to open file %s\n", WIFI_MAC_ADD_PATH);
120                         *mac_address = NULL;
121                         return FALSE;
122                 }
123
124                 if (fgets(buf, sizeof(buf), fp) == NULL) {
125                         ERR("Failed to get MAC info from %s\n", WIFI_MAC_ADD_PATH);
126                         *mac_address = NULL;
127                         fclose(fp);
128                         return FALSE;
129                 }
130                 tmp_mac = (gchar *)malloc(WIFI_MAC_ADD_LENGTH + 1);
131                 if (tmp_mac == NULL) {
132                         ERR("malloc() failed");
133                         *mac_address = NULL;
134                         fclose(fp);
135                         return FALSE;
136                 }
137                 memset(tmp_mac, 0, WIFI_MAC_ADD_LENGTH + 1);
138                 g_strlcpy(tmp_mac, buf, WIFI_MAC_ADD_LENGTH + 1);
139                 fclose(fp);
140         } else {
141                 tmp_mac = vconf_get_str(VCONFKEY_WIFI_BSSID_ADDRESS);
142                 if (tmp_mac == NULL) {
143                         ERR("vconf_get_str(WIFI_BSSID_ADDRESS) Failed");
144                         *mac_address = NULL;
145                         return FALSE;
146                 }
147         }
148         tmp = g_ascii_strdown(tmp_mac, (gssize)strlen(tmp_mac));
149         free(tmp_mac);
150         while (tmp && tmp[i]) {
151                 if (tmp[i] != ':')
152                         mac[j++] = tmp[i];
153                 i++;
154         }
155         mac[12] = '\0';
156         *mac_address = g_strdup(mac);
157
158         return TRUE;
159 }
160
161 static gboolean __get_group_name(const gchar *prefix, const gchar *config_id, gchar **group_name)
162 {
163         gchar *mac_address = NULL;
164         gchar *g_name = NULL;
165         gboolean ret = FALSE;
166
167         ret = __get_mac_address(&mac_address);
168         if ((ret != TRUE) || (strlen(mac_address) == 0)) {
169                 ERR("Cannot get WIFI MAC address");
170                 g_free(mac_address);
171                 return FALSE;
172         }
173
174         g_name = g_strdup_printf("%s%s_%s", prefix, mac_address, config_id);
175         if (g_name == NULL) {
176                 g_free(mac_address);
177                 return FALSE;
178         }
179
180         *group_name = g_strdup(g_name);
181
182         g_free(mac_address);
183         g_free(g_name);
184
185         return TRUE;
186 }
187
188 static gboolean __get_security_type(const gchar *config_id, gchar **type)
189 {
190         if (g_str_has_suffix(config_id, WIFI_SECURITY_NONE) == TRUE) {
191                 *type = g_strdup(WIFI_SECURITY_NONE);
192         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_WEP) == TRUE) {
193                 *type = g_strdup(WIFI_SECURITY_WEP);
194         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_WPA_PSK) == TRUE) {
195                 *type = g_strdup(WIFI_SECURITY_WPA_PSK);
196         } else if (g_str_has_suffix(config_id, WIFI_SECURITY_EAP) == TRUE) {
197                 *type = g_strdup(WIFI_SECURITY_EAP);
198         } else {
199                 *type = NULL;
200                 return FALSE;
201         }
202
203         return TRUE;
204 }
205
206 static gboolean __get_config_id(const gchar *profile, gchar **config_id)
207 {
208         *config_id = g_strdup(profile + PROFILE_PREFIX_LENGTH);
209         if (*config_id == NULL) {
210                 ERR("OOM");
211                 return FALSE;
212         }
213
214         return TRUE;
215 }
216
217
218 static GKeyFile *__get_configuration_keyfile(const gchar *group_name)
219 {
220         GKeyFile *keyfile = NULL;
221         gchar *path;
222
223         path = g_strdup_printf(CONNMAN_STORAGE "/%s/settings", group_name);
224
225         keyfile = netconfig_keyfile_load(path);
226         if (keyfile == NULL)
227                 ERR("keyfile[%s] is NULL", path);
228
229         g_free(path);
230
231         return keyfile;
232 }
233
234 static gboolean __remove_file(const gchar *pathname, const gchar *filename)
235 {
236         gboolean ret = FALSE;
237         gchar *path;
238
239         path = g_strdup_printf("%s/%s", pathname, filename);
240         if (g_file_test(path, G_FILE_TEST_EXISTS) == FALSE) {
241                 ret = TRUE;
242         } else if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == TRUE) {
243                 unlink(path);
244                 ret = TRUE;
245         }
246
247         g_free(path);
248         return ret;
249 }
250
251 static gboolean __remove_configuration(const gchar *pathname)
252 {
253         int ret = 0;
254
255         if (__remove_file(pathname, "settings") != TRUE) {
256                 ERR("Cannot remove [%s/settings]", pathname);
257                 return FALSE;
258         }
259         if (__remove_file(pathname, "data") != TRUE) {
260                 ERR("Cannot remove [%s/data]", pathname);
261                 return FALSE;
262         }
263
264         ret = rmdir(pathname);
265         if (ret == -1) {
266                 ERR("Cannot remove [%s]", pathname);
267                 return FALSE;
268         }
269
270         return TRUE;
271 }
272
273 static gboolean _load_configuration(const gchar *config_id, struct wifi_config *config)
274 {
275         GKeyFile *keyfile;
276         gchar *group_name;
277         gboolean hidden = FALSE;
278         gboolean ret = FALSE;
279
280         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
281         if (ret != TRUE) {
282                 ERR("Fail to get_wifi_config_group_name");
283                 return FALSE;
284         }
285
286         keyfile = __get_configuration_keyfile(group_name);
287         if (keyfile == NULL) {
288                 ERR("Fail to __get_configuration_keyfile[%s]", group_name);
289                 g_free(group_name);
290                 return FALSE;
291         }
292
293         config->name = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
294         DBG("name [%s]", config->name);
295
296         __get_security_type(config_id, &config->security_type);
297         if (config->security_type == NULL) {
298                 ERR("Fail to _get_security_type");
299                 g_key_file_free(keyfile);
300                 g_free(group_name);
301                 return FALSE;
302         }
303         DBG("security_type [%s]", config->security_type);
304
305         config->proxy_address = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
306         if (config->proxy_address)
307                 DBG("proxy_address [%s]", config->proxy_address);
308
309         hidden = g_key_file_get_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, NULL);
310         if (hidden)
311                 config->is_hidden = g_strdup("TRUE");
312         else
313                 config->is_hidden = g_strdup("FALSE");
314         DBG("is_hidden [%s]", config->is_hidden);
315
316         if (g_strcmp0(config->security_type, WIFI_SECURITY_EAP) == 0) {
317                 config->eap_config->anonymous_identity = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, NULL);
318                 config->eap_config->ca_cert = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CACERT, NULL);
319                 config->eap_config->client_cert = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CLIENTCERT, NULL);
320                 config->eap_config->private_key = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_PRIVATEKEY, NULL);
321                 config->eap_config->private_key_password = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, NULL);
322                 config->eap_config->identity = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_IDENTITY, NULL);
323                 config->eap_config->eap_type = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_TYPE, NULL);
324                 config->eap_config->eap_auth_type = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_AUTH_TYPE, NULL);
325                 config->eap_config->subject_match = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_SUBJECT_MATCH, NULL);
326
327                 if (config->eap_config->anonymous_identity)
328                         DBG("anonymous_identity [%s]", config->eap_config->anonymous_identity);
329                 if (config->eap_config->ca_cert)
330                         DBG("ca_cert [%s]", config->eap_config->ca_cert);
331                 if (config->eap_config->client_cert)
332                         DBG("client_cert [%s]", config->eap_config->client_cert);
333                 if (config->eap_config->private_key)
334                         DBG("private_key [%s]", config->eap_config->private_key);
335                 if (config->eap_config->private_key_password)
336                         DBG("private_key_password [%s]", config->eap_config->private_key_password);
337                 if (config->eap_config->identity)
338                         DBG("identity [%s]", config->eap_config->identity);
339                 if (config->eap_config->eap_type)
340                         DBG("eap_type [%s]", config->eap_config->eap_type);
341                 if (config->eap_config->eap_auth_type)
342                         DBG("eap_auth_type [%s]", config->eap_config->eap_auth_type);
343                 if (config->eap_config->subject_match)
344                         DBG("subject_match [%s]", config->eap_config->subject_match);
345         }
346
347         config->last_error = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_FAILURE, NULL);
348         if (config->last_error)
349                 DBG("last_error [%s]", config->last_error);
350
351         g_key_file_free(keyfile);
352         g_free(group_name);
353
354         return TRUE;
355 }
356
357 static gboolean _save_configuration(const gchar *config_id, GKeyFile *keyfile)
358 {
359         gchar *dir;
360         gchar *path;
361         gchar *group_name;
362         gboolean ret = FALSE;
363
364         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
365         if (ret != TRUE) {
366                 ERR("Fail to get_wifi_config_group_name");
367                 return FALSE;
368         }
369
370         dir = g_strdup_printf(CONNMAN_STORAGE "/%s", group_name);
371         if (g_file_test(dir, G_FILE_TEST_IS_DIR) == TRUE) {
372                 if (__remove_configuration(dir) != TRUE) {
373                         ERR("[%s] is existed, but cannot remove", dir);
374                         g_free(group_name);
375                         g_free(dir);
376                         return FALSE;
377                 }
378         }
379
380         if (mkdir(dir, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) < 0) {
381                 ERR("Cannot mkdir %s", dir);
382                 g_free(group_name);
383                 g_free(dir);
384                 return FALSE;
385         }
386
387         path = g_strdup_printf(CONNMAN_STORAGE "/%s/settings", group_name);
388         netconfig_keyfile_save(keyfile, path);
389         g_free(group_name);
390         g_free(dir);
391         g_free(path);
392
393         return TRUE;
394 }
395
396 static gboolean _remove_configuration(const gchar *config_id)
397 {
398         gboolean ret = FALSE;
399         gchar *dir;
400         gchar *group_name;
401
402         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
403         if (ret != TRUE) {
404                 ERR("Fail to get_wifi_config_group_name");
405                 return FALSE;
406         }
407
408         dir = g_strdup_printf(CONNMAN_STORAGE "/%s", group_name);
409         if (g_file_test(dir, G_FILE_TEST_IS_DIR) == TRUE) {
410                 if (__remove_configuration(dir) != TRUE) {
411                         ERR("[%s] is existed, but cannot remove", dir);
412                         ret = FALSE;
413                 }
414                 INFO("Success to remove [%s]", dir);
415                 ret = TRUE;
416         } else {
417                 ERR("[%s] is not existed", dir);
418                 ret = FALSE;
419         }
420
421         g_free(group_name);
422         g_free(dir);
423
424         return ret;
425 }
426
427
428 static gboolean _set_field(const gchar *config_id, const gchar *key, const gchar *value)
429 {
430         gboolean ret = TRUE;
431         GKeyFile *keyfile;
432         gchar *group_name;
433
434         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
435         if (ret != TRUE) {
436                 ERR("Fail to get_wifi_config_group_name");
437                 return FALSE;
438         }
439         DBG("group_name %s", group_name);
440
441         keyfile = __get_configuration_keyfile(group_name);
442         if (keyfile == NULL) {
443                 ERR("Fail to __get_configuration_keyfile");
444                 g_free(group_name);
445                 return FALSE;
446         }
447
448         if (g_strcmp0(key, WIFI_CONFIG_PROXY_METHOD) == 0) {
449                 g_key_file_set_string(keyfile, group_name, key, value);
450         } else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
451                 g_key_file_set_string(keyfile, group_name, key, value);
452         } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
453                 gboolean hidden = FALSE;
454                 if (g_strcmp0(value, "TRUE") == 0)
455                         hidden = TRUE;
456                 g_key_file_set_boolean(keyfile, group_name, key, hidden);
457         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
458                 g_key_file_set_string(keyfile, group_name, key, value);
459         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CACERT) == 0) {
460                 g_key_file_set_string(keyfile, group_name, key, value);
461         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
462                 g_key_file_set_string(keyfile, group_name, key, value);
463         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
464                 g_key_file_set_string(keyfile, group_name, key, value);
465         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_IDENTITY) == 0) {
466                 g_key_file_set_string(keyfile, group_name, key, value);
467         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_TYPE) == 0) {
468                 g_key_file_set_string(keyfile, group_name, key, value);
469         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
470                 g_key_file_set_string(keyfile, group_name, key, value);
471         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
472                 g_key_file_set_string(keyfile, group_name, key, value);
473         } else {
474                 ERR("key[%s] is not supported", key);
475                 ret = FALSE;
476         }
477
478         _save_configuration(config_id, keyfile);
479
480         g_key_file_free(keyfile);
481         g_free(group_name);
482
483         return ret;
484 }
485
486 static gboolean _get_field(const gchar *config_id, const gchar *key, gchar **value)
487 {
488         GKeyFile *keyfile;
489         gchar *group_name;
490         gchar *val = NULL;
491         gboolean hidden = FALSE;
492         gboolean ret = FALSE;
493
494         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
495         if (ret != TRUE) {
496                 ERR("Fail to get_wifi_config_group_name");
497                 return FALSE;
498         }
499         DBG("group_name %s", group_name);
500
501         keyfile = __get_configuration_keyfile(group_name);
502         if (keyfile == NULL) {
503                 ERR("Fail to __get_configuration_keyfile");
504                 g_free(group_name);
505                 return FALSE;
506         }
507
508         if (g_strcmp0(key, WIFI_CONFIG_NAME) == 0) {
509                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_NAME, NULL);
510         } else if (g_strcmp0(key, WIFI_CONFIG_PASSPHRASE) == 0) {
511                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, NULL);
512         } else if (g_strcmp0(key, WIFI_CONFIG_PROXY_SERVER) == 0) {
513                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, NULL);
514         } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
515                 hidden = g_key_file_get_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, NULL);
516                 if (hidden)
517                         val = g_strdup("TRUE");
518                 else
519                         val = g_strdup("FALSE");
520         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
521                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, NULL);
522         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CACERT) == 0) {
523                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CACERT, NULL);
524         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
525                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CLIENTCERT, NULL);
526         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
527                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_PRIVATEKEY, NULL);
528         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_IDENTITY) == 0) {
529                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_IDENTITY, NULL);
530         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_TYPE) == 0) {
531                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_TYPE, NULL);
532         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
533                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_AUTH_TYPE, NULL);
534         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
535                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_SUBJECT_MATCH, NULL);
536         } else if (g_strcmp0(key, WIFI_CONFIG_FAILURE) == 0) {
537                 val = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_FAILURE, NULL);
538         } else {
539                 ERR("Invalid key[%s]", key);
540                 val = g_strdup("NOTSUPPORTED");
541         }
542
543         *value = g_strdup(val);
544         g_free(val);
545
546         g_key_file_free(keyfile);
547         g_free(group_name);
548
549         return TRUE;
550 }
551
552 static GSList *_get_list(void)
553 {
554         GSList *list = NULL;
555         struct dirent *dp = NULL;
556         DIR *dir;
557
558         dir = opendir(CONNMAN_STORAGE);
559         if (dir == NULL) {
560                 ERR("Cannot open dir %s", CONNMAN_STORAGE);
561                 return NULL;
562         }
563
564         while ((dp = readdir(dir)) != NULL) {
565                 if (g_strcmp0(dp->d_name, ".") == 0 || g_strcmp0(dp->d_name, "..") == 0 ||
566                                 strncmp(dp->d_name, WIFI_CONFIG_PREFIX, strlen(WIFI_CONFIG_PREFIX)) != 0) {
567                         continue;
568                 }
569                 gchar *config_id = g_strdup(dp->d_name + WIFI_PREFIX_LENGTH);
570                 list = g_slist_append(list, g_strdup(config_id));
571                 g_free(config_id);
572         }
573         closedir(dir);
574
575         return list;
576 }
577
578 gboolean wifi_config_get_config_id(const gchar *service_profile, gchar **config_id)
579 {
580         gboolean ret = FALSE;
581         gchar *val = NULL;
582
583         if ((service_profile == NULL) || (config_id == NULL)) {
584                 ERR("Invalid parameter");
585                 return FALSE;
586         }
587
588         ret = __get_config_id(service_profile, &val);
589         *config_id = g_strdup(val);
590         g_free(val);
591
592         return ret;
593 }
594
595 gboolean wifi_config_remove_configuration(const gchar *config_id)
596 {
597         gboolean ret = FALSE;
598
599         ret = _remove_configuration(config_id);
600
601         return ret;
602 }
603
604 int __netconfig_hex_char_to_num(char c)
605 {
606         if (c >= '0' && c <= '9')
607                 return c - '0';
608
609         if (c >= 'a' && c <= 'f')
610                 return c - 'a' + 10;
611
612         if (c >= 'A' && c <= 'F')
613                 return c - 'A' + 10;
614
615         return -1;
616 }
617
618 int __netconfig_hex_to_byte(const char *hex)
619 {
620         int a, b;
621
622         a = __netconfig_hex_char_to_num(*hex++);
623         if (a < 0)
624                 return -1;
625
626         b = __netconfig_hex_char_to_num(*hex++);
627         if (b < 0)
628                 return -1;
629
630         return (a << 4) | b;
631 }
632
633 int __netconfig_hex_str_to_bin(const char *hex, unsigned char *buf, size_t len)
634 {
635         size_t i;
636         int a;
637         const char *ipos = hex;
638         unsigned char *opos = buf;
639
640         for (i = 0; i < len; i++) {
641                 a = __netconfig_hex_to_byte(ipos);
642                 if (a < 0)
643                         return -1;
644
645                 *opos++ = a;
646                 ipos += 2;
647         }
648
649         return 0;
650 }
651
652 static int __netconfig_byte_to_txt(const unsigned char *src, char **dst, int src_len)
653 {
654         int dst_length = 0;
655         int i = 0;
656         char *buf = NULL;
657
658         if (src_len <= 0) {
659                 ERR("Invalid parameter.");
660                 return -1;
661         }
662
663         *dst = (char *) g_try_malloc0((2*src_len)+1);
664         if (!(*dst)) {
665                 ERR("failed to allocate memory to buffer.");
666                 return -1;
667         }
668
669         buf = (*dst);
670
671         for (i = 0; i < src_len; i++) {
672                 snprintf(buf, 3, "%02x", src[i]);
673                 buf += 2;
674                 dst_length += 2;
675         }
676
677         return dst_length;
678 }
679
680 static int __netconfig_unpack_ay_malloc(unsigned char **dst, GVariantIter *iter)
681 {
682         GVariantIter *iter_copy = NULL;
683         int length = 0;
684         char tmp = 0;
685         unsigned char *tmp_dst = NULL;
686
687         if (!dst || *dst || !iter) {
688                 ERR("Invalid parameter");
689                 return 0;
690         }
691
692         iter_copy = g_variant_iter_copy(iter);
693
694         while (g_variant_iter_loop(iter, "y", &tmp))
695                 length++;
696         g_variant_iter_free(iter);
697
698         tmp_dst = (unsigned char *)g_try_malloc0(length + 1);
699         if (!tmp_dst) {
700                 ERR("failed to allocate memory");
701                 g_variant_iter_free(iter_copy);
702                 return 0;
703         }
704
705         length = 0;
706         while (g_variant_iter_loop(iter_copy, "y", &tmp_dst[length]))
707                 length++;
708         g_variant_iter_free(iter_copy);
709
710         if (length == 0) {
711                 g_free(tmp_dst);
712                 tmp_dst = NULL;
713         } else {
714                 tmp_dst[length] = '\0';
715         }
716
717         *dst = tmp_dst;
718         DBG("Length [%d]", length);
719         return length;
720 }
721
722 gboolean _add_vsie(int frame_id, const char* vsie)
723 {
724         GVariant *params = NULL;
725         GVariant *message = NULL;
726         GVariantBuilder *bytearray_builder = NULL;
727         char *if_path;
728         int i = 0;
729         size_t vsie_len = 0;
730
731         unsigned char *bytearray = NULL;
732         size_t bytearray_len = 0;
733
734         if (frame_id >= NETCONFIG_VSIE_FRAME_MAX) {
735                 DBG("Invalid parameter, frame-id: %d", frame_id);
736                 return FALSE;
737         }
738
739         vsie_len = strlen(vsie);
740         if (vsie_len == 0) {
741                 DBG("vsie length is zero");
742                 return FALSE;
743         }
744
745         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
746
747         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
748         if (bytearray == NULL) {
749                 DBG("Failed to allocate memory to bytearray");
750                 return FALSE;
751         }
752
753         if (__netconfig_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
754                 DBG("invalid vsie string");
755                 g_free(bytearray);
756                 return FALSE;
757         }
758
759         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
760         for (i = 0; i < bytearray_len; i++)
761                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
762
763         params = g_variant_new("(iay)", frame_id, bytearray_builder);
764         g_variant_builder_unref(bytearray_builder);
765
766         if_path = netconfig_wifi_get_supplicant_interface();
767
768         if (if_path == NULL) {
769                 ERR("Fail to get wpa_supplicant DBus path");
770                 g_free(bytearray);
771                 return FALSE;
772         }
773
774         message = netconfig_supplicant_invoke_dbus_method(SUPPLICANT_SERVICE,
775                         if_path, SUPPLICANT_INTERFACE ".Interface", "VendorElemAdd", params);
776
777         g_free(if_path);
778         if (message == NULL) {
779                 ERR("Failed to send command to wpa_supplicant");
780                 g_free(bytearray);
781                 return FALSE;
782         }
783
784         DBG("Succeeded to add vsie: Frame ID[%d], VSIE[%s]", frame_id, vsie);
785
786         g_free(bytearray);
787         return TRUE;
788 }
789
790 gboolean _get_vsie(int frame_id, char **vsie)
791 {
792         GVariant *params = NULL;
793         GVariant *message = NULL;
794         char *if_path;
795
796         if (frame_id >= NETCONFIG_VSIE_FRAME_MAX) {
797                 DBG("Invalid parameter, frame-id: %d", frame_id);
798                 return FALSE;
799         }
800
801         if_path = netconfig_wifi_get_supplicant_interface();
802         if (if_path == NULL) {
803                 ERR("Fail to get wpa_supplicant DBus path");
804                 return FALSE;
805         }
806
807         params = g_variant_new("(i)", frame_id);
808
809         message = netconfig_supplicant_invoke_dbus_method(SUPPLICANT_SERVICE,
810                         if_path, SUPPLICANT_INTERFACE ".Interface", "VendorElemGet", params);
811
812         g_free(if_path);
813         if (message == NULL) {
814                 ERR("Failed to send command to wpa_supplicant");
815                 return FALSE;
816         } else {
817                 GVariantIter *iter = NULL;
818                 unsigned char *vsie_bytes = NULL;
819                 int vsie_len = 0;
820                 int ret = 0;
821
822                 g_variant_get(message, "(ay)", &iter);
823                 if (iter == NULL) {
824                         ERR("vsie is not present");
825                         return FALSE;
826                 }
827
828                 vsie_len = __netconfig_unpack_ay_malloc(&vsie_bytes, iter);
829                 if (vsie_bytes == NULL) {
830                         ERR("vsie_bytes not allocated");
831                         return FALSE;
832                 }
833
834                 ret = __netconfig_byte_to_txt(vsie_bytes, vsie, vsie_len);
835                 if (ret < 0) {
836                         g_free(vsie_bytes);
837                         ERR("vsie not allocated.");
838                         return FALSE;
839                 }
840
841                 g_free(vsie_bytes);
842         }
843
844         ERR("Succeeded to get vsie: Frame ID[%d], VSIE[%s]", frame_id, *vsie);
845
846         return TRUE;
847
848 }
849
850 gboolean _remove_vsie(int frame_id, const char *vsie)
851 {
852         GVariant *params = NULL;
853         GVariant *message = NULL;
854         GVariantBuilder *bytearray_builder = NULL;
855         char *if_path;
856         int i = 0;
857         size_t vsie_len = 0;
858
859         unsigned char *bytearray = NULL;
860         size_t bytearray_len = 0;
861
862         if (frame_id >= NETCONFIG_VSIE_FRAME_MAX) {
863                 DBG("Invalid parameter, frame-id: %d", frame_id);
864                 return FALSE;
865         }
866
867         vsie_len = strlen(vsie);
868         if (vsie_len == 0) {
869                 DBG("vsie length is zero");
870                 return FALSE;
871         }
872
873         bytearray_len = (vsie_len % 2) ? ((vsie_len / 2) + 1) : (vsie_len / 2);
874
875         bytearray = (unsigned char *) g_try_malloc0(bytearray_len);
876         if (bytearray == NULL) {
877                 DBG("Failed to allocate memory to bytearray");
878                 return FALSE;
879         }
880
881         if (__netconfig_hex_str_to_bin(vsie, bytearray, bytearray_len) < 0) {
882                 DBG("invalid vsie string");
883                 g_free(bytearray);
884                 return FALSE;
885         }
886
887         bytearray_builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
888         for (i = 0; i < bytearray_len; i++)
889                 g_variant_builder_add(bytearray_builder, "y", bytearray[i]);
890
891         params = g_variant_new("(iay)", frame_id, bytearray_builder);
892         g_variant_builder_unref(bytearray_builder);
893
894         if_path = netconfig_wifi_get_supplicant_interface();
895         if (if_path == NULL) {
896                 ERR("Fail to get wpa_supplicant DBus path");
897                 g_free(bytearray);
898                 return FALSE;
899         }
900
901         message = netconfig_supplicant_invoke_dbus_method(SUPPLICANT_SERVICE,
902                         if_path, SUPPLICANT_INTERFACE ".Interface", "VendorElemRem", params);
903
904         g_free(if_path);
905         if (message == NULL) {
906                 ERR("Failed to send command to wpa_supplicant");
907                 g_free(bytearray);
908                 return FALSE;
909         }
910
911         DBG("Succeeded to remove vsie: Frame ID[%d], VSIE[%s]", frame_id, vsie);
912
913         g_free(bytearray);
914         return TRUE;
915 }
916
917 /* dbus method */
918 gboolean handle_get_config_ids(Wifi *wifi, GDBusMethodInvocation *context)
919 {
920         guint i = 0;
921         GSList *config_ids = NULL;
922         guint length;
923         gchar **result = NULL;
924
925         g_return_val_if_fail(wifi != NULL, TRUE);
926
927         config_ids = _get_list();
928         if (config_ids == NULL) {
929                 ERR("Fail to get config list");
930                 netconfig_error_no_profile(context);
931                 return TRUE;
932         }
933
934         length = g_slist_length(config_ids);
935         result = g_new0(gchar *, length + 1);
936         for (i = 0; i < length; i++) {
937                 gchar *config_id = g_slist_nth_data(config_ids, i);
938                 result[i] = g_strdup(config_id);
939         }
940
941         config_ids = g_slist_nth(config_ids, 0);
942         g_slist_free_full(config_ids, g_free);
943
944         wifi_complete_get_config_ids(wifi, context, (const gchar * const *)result);
945
946         for (i = 0; i < length; i++)
947                 if (result[i])
948                         g_free(result[i]);
949
950         if (result)
951                 g_free(result);
952
953         return TRUE;
954 }
955
956 gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context,
957                 const gchar *config_id)
958 {
959         gboolean ret = FALSE;
960         GVariantBuilder *b = NULL;
961         struct wifi_config *conf = NULL;
962
963         g_return_val_if_fail(wifi != NULL, TRUE);
964
965         conf = g_new0(struct wifi_config, 1);
966
967         ret = _load_configuration(config_id, conf);
968         if (ret != TRUE) {
969                 g_free(conf);
970                 ERR("Fail to _load_configuration");
971                 netconfig_error_no_profile(context);
972                 return TRUE;
973         }
974
975         b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
976         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
977         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
978         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
979
980         if (conf->proxy_address != NULL)
981                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
982         else
983                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string("NONE"));
984
985         if (conf->last_error != NULL)
986                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string(conf->last_error));
987         else
988                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string("ERROR_NONE"));
989
990         g_free(conf->proxy_address);
991         g_free(conf->last_error);
992         g_free(conf->name);
993         g_free(conf->security_type);
994         g_free(conf->is_hidden);
995         g_free(conf);
996
997         wifi_complete_load_configuration(wifi, context, g_variant_builder_end(b));
998         g_variant_builder_unref(b);
999         return TRUE;
1000 }
1001
1002 gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1003                 const gchar *config_id, GVariant *configuration)
1004 {
1005         gboolean ret = FALSE;
1006         struct wifi_config *conf = NULL;
1007         GKeyFile *keyfile = NULL;
1008         GVariantIter *iter;
1009         GVariant *value;
1010         gchar *field;
1011         gchar *group_name = NULL;
1012
1013         if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
1014                 ERR("Invalid parameter");
1015                 netconfig_error_invalid_parameter(context);
1016                 return TRUE;
1017         }
1018
1019         conf = g_new0(struct wifi_config, 1);
1020
1021         g_variant_get(configuration, "a{sv}", &iter);
1022         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1023                 if (g_strcmp0(field, WIFI_CONFIG_NAME) == 0) {
1024                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1025                                 conf->name = g_strdup(g_variant_get_string(value, NULL));
1026                                 DBG("name [%s]", conf->name);
1027                         } else {
1028                                 conf->name = NULL;
1029                         }
1030                 } else if (g_strcmp0(field, WIFI_CONFIG_SSID) == 0) {
1031                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1032                                 conf->ssid = g_strdup(g_variant_get_string(value, NULL));
1033                                 DBG("ssid [%s]", conf->ssid);
1034                         } else {
1035                                 conf->ssid = NULL;
1036                         }
1037                 } else if (g_strcmp0(field, WIFI_CONFIG_PASSPHRASE) == 0) {
1038                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1039                                 conf->passphrase = g_strdup(g_variant_get_string(value, NULL));
1040                                 DBG("passphrase []");
1041                         } else {
1042                                 conf->passphrase = NULL;
1043                         }
1044                 } else if (g_strcmp0(field, WIFI_CONFIG_HIDDEN) == 0) {
1045                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1046                                 conf->is_hidden = g_strdup(g_variant_get_string(value, NULL));
1047                                 DBG("is_hidden [%s]", conf->is_hidden);
1048                         } else {
1049                                 conf->is_hidden = NULL;
1050                         }
1051                 } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) {
1052                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1053                                 conf->proxy_address = g_strdup(g_variant_get_string(value, NULL));
1054                                 DBG("proxy_address [%s]", conf->proxy_address);
1055                         } else {
1056                                 conf->proxy_address = NULL;
1057                         }
1058                 }
1059         }
1060         conf->favorite = TRUE;
1061         conf->autoconnect = TRUE;
1062
1063         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
1064         if (ret != TRUE) {
1065                 g_free(conf->name);
1066                 g_free(conf->ssid);
1067                 g_free(conf->passphrase);
1068                 g_free(conf->is_hidden);
1069                 g_free(conf->proxy_address);
1070                 g_free(conf);
1071                 ERR("Fail to get_wifi_config_group_name");
1072                 netconfig_error_fail_save_congifuration(context);
1073                 return TRUE;
1074         }
1075
1076         keyfile = g_key_file_new();
1077         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_NAME, conf->name);
1078         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_SSID, conf->ssid);
1079
1080         if (conf->passphrase != NULL) {
1081                 gchar *enc_data = NULL;
1082                 enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
1083
1084                 if (!enc_data) {
1085                         ERR("Failed to encrypt the passphrase");
1086                 } else {
1087                         g_free(conf->passphrase);
1088                         conf->passphrase = enc_data;
1089                 }
1090
1091                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, conf->passphrase);
1092         }
1093
1094         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, conf->favorite);
1095         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, conf->autoconnect);
1096
1097         /* Optional field */
1098         if (conf->proxy_address != NULL) {
1099                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_METHOD, "manual");
1100                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, conf->proxy_address);
1101         }
1102
1103         if (conf->is_hidden != NULL) {
1104                 gboolean hidden = FALSE;
1105                 if (g_strcmp0(conf->is_hidden, "TRUE") == 0)
1106                         hidden = TRUE;
1107                 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
1108         }
1109
1110         ret = _save_configuration(config_id, keyfile);
1111         if (ret == TRUE) {
1112                 INFO("Success to save configuration [%s]", config_id);
1113                 wifi_complete_save_configuration(wifi, context);
1114         } else {
1115                 INFO("Fail to save configuration [%s]", config_id);
1116                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSaveConfiguration");
1117         }
1118
1119         g_key_file_free(keyfile);
1120         g_free(group_name);
1121         g_free(conf->name);
1122         g_free(conf->ssid);
1123         g_free(conf->passphrase);
1124         g_free(conf->is_hidden);
1125         g_free(conf->proxy_address);
1126         g_free(conf);
1127
1128         g_variant_iter_free(iter);
1129
1130         return TRUE;
1131 }
1132
1133 gboolean handle_load_eap_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1134                 const gchar *config_id)
1135 {
1136         gboolean ret = FALSE;
1137         GVariantBuilder *b = NULL;
1138         struct wifi_config *conf = NULL;
1139
1140         g_return_val_if_fail(wifi != NULL, TRUE);
1141
1142         conf = g_new0(struct wifi_config, 1);
1143         conf->eap_config = g_new0(struct wifi_eap_config, 1);
1144
1145         ret = _load_configuration(config_id, conf);
1146         if (ret != TRUE) {
1147                 g_free(conf->eap_config);
1148                 g_free(conf);
1149                 ERR("Fail to _load_configuration");
1150                 netconfig_error_no_profile(context);
1151                 return TRUE;
1152         }
1153
1154         b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
1155         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_NAME, g_variant_new_string(conf->name));
1156         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_SECURITY_TYPE, g_variant_new_string(conf->security_type));
1157         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_HIDDEN, g_variant_new_string(conf->is_hidden));
1158         if (conf->proxy_address != NULL)
1159                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string(conf->proxy_address));
1160         else
1161                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string("NONE"));
1162
1163         if (conf->last_error != NULL)
1164                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string(conf->last_error));
1165         else
1166                 g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string("ERROR_NONE"));
1167
1168         if (conf->eap_config != NULL) {
1169                 if (conf->eap_config->anonymous_identity != NULL)
1170                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, g_variant_new_string(conf->eap_config->anonymous_identity));
1171                 else
1172                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, g_variant_new_string("NONE"));
1173
1174                 if (conf->eap_config->ca_cert != NULL)
1175                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CACERT, g_variant_new_string(conf->eap_config->ca_cert));
1176                 else
1177                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CACERT, g_variant_new_string("NONE"));
1178
1179                 if (conf->eap_config->client_cert != NULL)
1180                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CLIENTCERT, g_variant_new_string(conf->eap_config->client_cert));
1181                 else
1182                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_CLIENTCERT, g_variant_new_string("NONE"));
1183
1184                 if (conf->eap_config->private_key != NULL)
1185                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY, g_variant_new_string(conf->eap_config->private_key));
1186                 else
1187                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY, g_variant_new_string("NONE"));
1188
1189                 if (conf->eap_config->private_key_password != NULL)
1190                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, g_variant_new_string(conf->eap_config->private_key_password));
1191                 else
1192                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, g_variant_new_string("NONE"));
1193
1194                 if (conf->eap_config->identity != NULL)
1195                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_IDENTITY, g_variant_new_string(conf->eap_config->identity));
1196                 else
1197                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_IDENTITY, g_variant_new_string("NONE"));
1198
1199                 if (conf->eap_config->eap_type != NULL)
1200                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_TYPE, g_variant_new_string(conf->eap_config->eap_type));
1201                 else
1202                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_TYPE, g_variant_new_string("NONE"));
1203
1204                 if (conf->eap_config->eap_auth_type != NULL)
1205                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_AUTH_TYPE, g_variant_new_string(conf->eap_config->eap_auth_type));
1206                 else
1207                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_AUTH_TYPE, g_variant_new_string("NONE"));
1208
1209                 if (conf->eap_config->subject_match != NULL)
1210                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_SUBJECT_MATCH, g_variant_new_string(conf->eap_config->subject_match));
1211                 else
1212                         g_variant_builder_add(b, "{sv}", WIFI_CONFIG_EAP_SUBJECT_MATCH, g_variant_new_string("NONE"));
1213         }
1214
1215         __free_wifi_configuration(conf);
1216
1217         wifi_complete_load_eap_configuration(wifi, context, g_variant_builder_end(b));
1218         g_variant_builder_unref(b);
1219         return TRUE;
1220 }
1221
1222 gboolean handle_save_eap_configuration(Wifi *wifi, GDBusMethodInvocation *context,
1223                 const gchar *config_id, GVariant *configuration)
1224 {
1225         gboolean ret = FALSE;
1226         struct wifi_config *conf = NULL;
1227         GKeyFile *keyfile = NULL;
1228         GVariantIter *iter;
1229         GVariant *value;
1230         gchar *field;
1231         gchar *group_name = NULL;
1232
1233         if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) {
1234                 ERR("Invalid parameter");
1235                 netconfig_error_invalid_parameter(context);
1236                 return TRUE;
1237         }
1238
1239         conf = g_new0(struct wifi_config, 1);
1240         conf->eap_config = g_new0(struct wifi_eap_config, 1);
1241
1242         g_variant_get(configuration, "a{sv}", &iter);
1243         while (g_variant_iter_loop(iter, "{sv}", &field, &value)) {
1244                 if (g_strcmp0(field, WIFI_CONFIG_NAME) == 0) {
1245                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1246                                 conf->name = g_strdup(g_variant_get_string(value, NULL));
1247                                 DBG("name [%s]", conf->name);
1248                         } else {
1249                                 conf->name = NULL;
1250                         }
1251                 } else if (g_strcmp0(field, WIFI_CONFIG_SSID) == 0) {
1252                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1253                                 conf->ssid = g_strdup(g_variant_get_string(value, NULL));
1254                                 DBG("ssid [%s]", conf->ssid);
1255                         } else {
1256                                 conf->ssid = NULL;
1257                         }
1258                 } else if (g_strcmp0(field, WIFI_CONFIG_PASSPHRASE) == 0) {
1259                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1260                                 conf->passphrase = g_strdup(g_variant_get_string(value, NULL));
1261                                 DBG("passphrase [%s]", conf->passphrase);
1262                         } else {
1263                                 conf->passphrase = NULL;
1264                         }
1265                 } else if (g_strcmp0(field, WIFI_CONFIG_HIDDEN) == 0) {
1266                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1267                                 conf->is_hidden = g_strdup(g_variant_get_string(value, NULL));
1268                                 DBG("is_hidden [%s]", conf->is_hidden);
1269                         } else {
1270                                 conf->is_hidden = NULL;
1271                         }
1272                 } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) {
1273                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1274                                 conf->proxy_address = g_strdup(g_variant_get_string(value, NULL));
1275                                 DBG("proxy_address [%s]", conf->proxy_address);
1276                         } else {
1277                                 conf->proxy_address = NULL;
1278                         }
1279                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
1280                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1281                                 conf->eap_config->anonymous_identity = g_strdup(g_variant_get_string(value, NULL));
1282                                 DBG("anonymous_identity [%s]", conf->eap_config->anonymous_identity);
1283                         } else {
1284                                 conf->eap_config->anonymous_identity = NULL;
1285                         }
1286                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_CACERT) == 0) {
1287                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1288                                 conf->eap_config->ca_cert = g_strdup(g_variant_get_string(value, NULL));
1289                                 DBG("ca_cert [%s]", conf->eap_config->ca_cert);
1290                         } else {
1291                                 conf->eap_config->ca_cert = NULL;
1292                         }
1293                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
1294                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1295                                 conf->eap_config->client_cert = g_strdup(g_variant_get_string(value, NULL));
1296                                 DBG("client_cert [%s]", conf->eap_config->client_cert);
1297                         } else {
1298                                 conf->eap_config->client_cert = NULL;
1299                         }
1300                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
1301                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1302                                 conf->eap_config->private_key = g_strdup(g_variant_get_string(value, NULL));
1303                                 DBG("private_key [%s]", conf->eap_config->private_key);
1304                         } else {
1305                                 conf->eap_config->private_key = NULL;
1306                         }
1307                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD) == 0) {
1308                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1309                                 conf->eap_config->private_key_password = g_strdup(g_variant_get_string(value, NULL));
1310                                 DBG("private_key_password[%s]", conf->eap_config->private_key_password);
1311                         } else {
1312                                 conf->eap_config->private_key_password = NULL;
1313                         }
1314                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_IDENTITY) == 0) {
1315                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1316                                 conf->eap_config->identity = g_strdup(g_variant_get_string(value, NULL));
1317                                 DBG("identity [%s]", conf->eap_config->identity);
1318                         } else {
1319                                 conf->eap_config->identity = NULL;
1320                         }
1321                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_TYPE) == 0) {
1322                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1323                                 conf->eap_config->eap_type = g_strdup(g_variant_get_string(value, NULL));
1324                                 DBG("eap_type [%s]", conf->eap_config->eap_type);
1325                         } else {
1326                                 conf->eap_config->eap_type = NULL;
1327                         }
1328                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
1329                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1330                                 conf->eap_config->eap_auth_type = g_strdup(g_variant_get_string(value, NULL));
1331                                 DBG("eap_auth_type [%s]", conf->eap_config->eap_auth_type);
1332                         } else {
1333                                 conf->eap_config->eap_auth_type = NULL;
1334                         }
1335                 } else if (g_strcmp0(field, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
1336                         if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) {
1337                                 conf->eap_config->subject_match = g_strdup(g_variant_get_string(value, NULL));
1338                                 DBG("subject_match [%s]", conf->eap_config->subject_match);
1339                         } else {
1340                                 conf->eap_config->subject_match = NULL;
1341                         }
1342                 }
1343         }
1344         conf->favorite = TRUE;
1345         conf->autoconnect = TRUE;
1346
1347         ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name);
1348         if (ret != TRUE) {
1349                 __free_wifi_configuration(conf);
1350                 ERR("Fail to get_wifi_config_group_name");
1351                 return TRUE;
1352         }
1353
1354         keyfile = g_key_file_new();
1355         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_NAME, conf->name);
1356         g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_SSID, conf->ssid);
1357
1358         if (conf->passphrase != NULL) {
1359                 gchar *enc_data = NULL;
1360                 enc_data = _netconfig_encrypt_passphrase(conf->passphrase);
1361
1362                 if (!enc_data) {
1363                         ERR("Failed to encrypt the passphrase");
1364                 } else {
1365                         g_free(conf->passphrase);
1366                         conf->passphrase = enc_data;
1367                 }
1368                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PASSPHRASE, conf->passphrase);
1369         }
1370
1371         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_FAVORITE, conf->favorite);
1372         g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_AUTOCONNECT, conf->autoconnect);
1373
1374         /* Optional field */
1375         if (conf->proxy_address != NULL) {
1376                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_METHOD, "manual");
1377                 g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_PROXY_SERVER, conf->proxy_address);
1378         }
1379
1380         if (conf->is_hidden != NULL) {
1381                 gboolean hidden = FALSE;
1382                 if (g_strcmp0(conf->is_hidden, "TRUE") == 0)
1383                         hidden = TRUE;
1384                 g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden);
1385         }
1386
1387         if (conf->eap_config->anonymous_identity != NULL)
1388                 g_key_file_set_string(keyfile, group_name,
1389                         WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, conf->eap_config->anonymous_identity);
1390
1391         if (conf->eap_config->ca_cert != NULL)
1392                 g_key_file_set_string(keyfile, group_name,
1393                         WIFI_CONFIG_EAP_CACERT, conf->eap_config->ca_cert);
1394
1395         if (conf->eap_config->client_cert != NULL)
1396                 g_key_file_set_string(keyfile, group_name,
1397                         WIFI_CONFIG_EAP_CLIENTCERT, conf->eap_config->client_cert);
1398
1399         if (conf->eap_config->private_key != NULL)
1400                 g_key_file_set_string(keyfile, group_name,
1401                         WIFI_CONFIG_EAP_PRIVATEKEY, conf->eap_config->private_key);
1402
1403         if (conf->eap_config->private_key_password != NULL)
1404                 g_key_file_set_string(keyfile, group_name,
1405                         WIFI_CONFIG_EAP_PRIVATEKEY_PASSWORD, conf->eap_config->private_key_password);
1406
1407         if (conf->eap_config->identity != NULL)
1408                 g_key_file_set_string(keyfile, group_name,
1409                         WIFI_CONFIG_EAP_IDENTITY, conf->eap_config->identity);
1410
1411         if (conf->eap_config->eap_type != NULL)
1412                 g_key_file_set_string(keyfile, group_name,
1413                         WIFI_CONFIG_EAP_TYPE, conf->eap_config->eap_type);
1414
1415         if (conf->eap_config->eap_auth_type != NULL)
1416                 g_key_file_set_string(keyfile, group_name,
1417                         WIFI_CONFIG_EAP_AUTH_TYPE, conf->eap_config->eap_auth_type);
1418
1419         if (conf->eap_config->subject_match != NULL)
1420                 g_key_file_set_string(keyfile, group_name,
1421                         WIFI_CONFIG_EAP_SUBJECT_MATCH, conf->eap_config->subject_match);
1422
1423         ret = _save_configuration(config_id, keyfile);
1424         if (ret == TRUE) {
1425                 INFO("Success to save eap configuration [%s]", config_id);
1426                 wifi_complete_save_eap_configuration(wifi, context);
1427         } else {
1428                 INFO("Fail to save eap configuration [%s]", config_id);
1429                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailSaveEapConfiguration");
1430         }
1431
1432         g_key_file_free(keyfile);
1433         g_free(group_name);
1434         __free_wifi_configuration(conf);
1435
1436         g_variant_iter_free(iter);
1437
1438         return TRUE;
1439 }
1440
1441 gboolean handle_remove_configuration(Wifi *wifi, GDBusMethodInvocation *context, const gchar *config_id)
1442 {
1443         gboolean ret = FALSE;
1444
1445         if ((wifi == NULL) || (config_id == NULL)) {
1446                 ERR("Invalid parameter");
1447                 netconfig_error_invalid_parameter(context);
1448                 return TRUE;
1449         }
1450
1451         ret = _remove_configuration(config_id);
1452         if (ret != TRUE) {
1453                 /* no configuration or error */
1454                 ERR("No [%s] configuration", config_id);
1455                 netconfig_error_no_profile(context);
1456                 return TRUE;
1457         }
1458
1459         wifi_complete_remove_configuration(wifi, context);
1460         return TRUE;
1461 }
1462
1463 /* config field key / value */
1464 /*
1465  * [wifi_macaddress_config_id]
1466  * Name=name (mandatory)
1467  * SSID=SSID (mandatory)
1468  * Frequency=2462 (X)
1469  * Favorite=true (X)
1470  * AutoConnect=true (Default true)
1471  * Modified=2015-03-20 (X)
1472  * IPv4.method=manual (O)
1473  * IPv4.DHCP.LastAddress=192.0.0.1 (X)
1474  * IPv6.method=auto (X)
1475  * IPv6.privacy=disabled (X)
1476  * IPv4.netmask_prefixlen=24 (X)
1477  * IPv4.local_address=192.0.0.1 (O)
1478  * IPv4.gateway=192.0.0.1 (O ? X ?)
1479  * Nameservers=192.168.43.22; (O)
1480  * Proxy.Method=manual (O)
1481  * Proxy.Servers=trst.com:8888; (O)
1482  */
1483 gboolean handle_set_config_field(Wifi *wifi, GDBusMethodInvocation *context,
1484                 const gchar *config_id, const gchar *key, const gchar *value)
1485 {
1486         gboolean ret = FALSE;
1487         gchar *keyfile_key = NULL;
1488
1489         g_return_val_if_fail(wifi != NULL, TRUE);
1490         g_return_val_if_fail(config_id != NULL, TRUE);
1491         g_return_val_if_fail(key != NULL, TRUE);
1492
1493         DBG("Key[%s] Value[%d]", key, value);
1494
1495         if (g_strcmp0(key, WIFI_CONFIG_PROXYADDRESS) == 0) {
1496                 ret = _set_field(config_id, WIFI_CONFIG_PROXY_METHOD, "manual");
1497                 if (!ret) {
1498                         ERR("Fail to [%s]set_wifi_config_field(%s/manual)", config_id, WIFI_CONFIG_PROXY_METHOD);
1499                         netconfig_error_invalid_parameter(context);
1500                         return TRUE;
1501                 }
1502                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_PROXY_SERVER);
1503         } else if (g_strcmp0(key, WIFI_CONFIG_HIDDEN) == 0) {
1504                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_HIDDEN);
1505         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY) == 0) {
1506                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY);
1507         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CACERT) == 0) {
1508                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_CACERT);
1509         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_CLIENTCERT) == 0) {
1510                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_CLIENTCERT);
1511         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_PRIVATEKEY) == 0) {
1512                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_PRIVATEKEY);
1513         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_IDENTITY) == 0) {
1514                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_IDENTITY);
1515         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_TYPE) == 0) {
1516                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_TYPE);
1517         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_AUTH_TYPE) == 0) {
1518                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_AUTH_TYPE);
1519         } else if (g_strcmp0(key, WIFI_CONFIG_EAP_SUBJECT_MATCH) == 0) {
1520                 keyfile_key = g_strdup_printf("%s", WIFI_CONFIG_EAP_SUBJECT_MATCH);
1521         } else {
1522                 ERR("Not supported key[%s]", key);
1523                 netconfig_error_invalid_parameter(context);
1524                 return TRUE;
1525         }
1526
1527         ret = _set_field(config_id, keyfile_key, (const gchar *)value);
1528         if (!ret) {
1529                 ERR("Fail to [%s]set_wifi_config_field(%s/%s)", config_id, key, value);
1530         }
1531
1532         if (keyfile_key != NULL)
1533                 g_free(keyfile_key);
1534
1535         wifi_complete_set_config_field(wifi, context);
1536         return TRUE;
1537 }
1538
1539 gboolean handle_get_config_passphrase(Wifi *wifi, GDBusMethodInvocation *context, const gchar *config_id)
1540 {
1541         gboolean ret = FALSE;
1542         gchar *passphrase = NULL;
1543
1544         if ((wifi == NULL) || (config_id == NULL)) {
1545                 ERR("Invalid parameter");
1546                 netconfig_error_invalid_parameter(context);
1547                 return TRUE;
1548         }
1549
1550         ret = _get_field(config_id, WIFI_CONFIG_PASSPHRASE, &passphrase);
1551         if (!ret) {
1552                 ERR("Fail to [%s] _get_field(%s)", config_id, WIFI_CONFIG_PASSPHRASE);
1553                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
1554                 return TRUE;
1555         }
1556
1557         wifi_complete_get_config_passphrase(wifi, context, passphrase);
1558         g_free(passphrase);
1559
1560         return TRUE;
1561 }
1562
1563 gboolean handle_add_vsie(Wifi *wifi, GDBusMethodInvocation *context,
1564                 int frame_id, const gchar *vsie)
1565 {
1566         DBG("Frame ID: [%d] VSIE: [%s]", frame_id, vsie);
1567
1568         g_return_val_if_fail(wifi != NULL, TRUE);
1569         g_return_val_if_fail(vsie != NULL, TRUE);
1570
1571         gboolean ret = FALSE;
1572
1573         ret = _add_vsie(frame_id, vsie);
1574         if (!ret) {
1575                 DBG("Failed to add vsie: %s", vsie);
1576                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
1577                 return TRUE;
1578         }
1579
1580         wifi_complete_add_vsie(wifi, context);
1581         return TRUE;
1582 }
1583
1584 gboolean handle_get_vsie(Wifi *wifi, GDBusMethodInvocation *context,
1585                 int frame_id)
1586 {
1587         DBG("Frame ID: [%d]", frame_id);
1588
1589         g_return_val_if_fail(wifi != NULL, TRUE);
1590
1591         gboolean ret = FALSE;
1592         gchar *vsie = NULL;
1593
1594         ret = _get_vsie(frame_id, &vsie);
1595         if (!ret) {
1596                 DBG("Failed to get vsie for frame:[%d]", frame_id);
1597                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
1598                 return TRUE;
1599         }
1600
1601         DBG("Received vsie: %s", vsie);
1602         wifi_complete_get_vsie(wifi, context, vsie);
1603
1604         return TRUE;
1605 }
1606
1607 gboolean handle_remove_vsie(Wifi *wifi, GDBusMethodInvocation *context,
1608                 int frame_id, const gchar *vsie)
1609 {
1610         DBG("Frame ID: [%d] VSIE: [%s]", frame_id, vsie);
1611
1612         g_return_val_if_fail(wifi != NULL, TRUE);
1613         g_return_val_if_fail(vsie != NULL, TRUE);
1614
1615         gboolean ret = FALSE;
1616
1617         ret = _remove_vsie(frame_id, vsie);
1618         if (!ret) {
1619                 DBG("Failed to remove vsie: %s", vsie);
1620                 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "OperationFailed");
1621                 return TRUE;
1622         }
1623
1624         wifi_complete_remove_vsie(wifi, context);
1625         return TRUE;
1626 }