Fix svace issue (WGID 208127, 208128)
[platform/upstream/connman.git] / vpn / plugins / ipsec.c
1 /*
2  *
3  *  ConnMan VPN daemon
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License version 2 as
7  *  published by the Free Software Foundation.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <stdio.h>
29 #include <sys/stat.h>
30 #include <net/if.h>
31
32 #include <glib.h>
33 #include <gio/gio.h>
34
35 #include <openssl/bio.h>
36 #include <openssl/pem.h>
37 #include <openssl/err.h>
38 #include <openssl/safestack.h>
39 #include <openssl/pkcs12.h>
40 #include <openssl/x509.h>
41 #include <openssl/conf.h>
42
43 #define CONNMAN_API_SUBJECT_TO_CHANGE
44 #include <connman/plugin.h>
45 #include <connman/log.h>
46 #include <connman/task.h>
47 #include <connman/dbus.h>
48 #include <connman/ipconfig.h>
49
50 #include "../vpn-provider.h"
51
52 #include "vpn.h"
53 #include "ipsec.h"
54 #include "vici-client.h"
55
56 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
57
58 typedef enum {
59         CERT_TYPE_NONE,
60         CERT_TYPE_DER,
61         CERT_TYPE_PEM,
62         CERT_TYPE_PKCS12,
63         CERT_TYPE_MAX,
64 } cert_type_e;
65
66 static DBusConnection *connection;
67 static VICIClient *vici_client;
68 static GFileMonitor* monitor;
69
70 struct openssl_private_data {
71         EVP_PKEY *private_key;
72         X509 *local_cert;
73         STACK_OF(X509) *ca_certs;
74 };
75
76 struct ipsec_private_data {
77         struct vpn_provider *provider;
78         struct openssl_private_data openssl_data;
79         vpn_provider_connect_cb_t cb;
80
81         void *user_data;
82 };
83
84 struct {
85         const char *cm_opt;
86         const char *vici_key;
87         const char *subsection;
88         vici_add_element add_elem;
89 } ipsec_conn_options[] = {
90         {"IPsec.Version", "version", NULL, vici_add_kv},
91         {"IPsec.LeftAddrs", "local_addrs", NULL, vici_add_kvl},
92         {"IPsec.RightAddrs", "remote_addrs", NULL, vici_add_kvl},
93
94         {"IPsec.LocalAuth", "auth", "local", vici_add_kv},
95         {"IPsec.LocalID", "id", "local", vici_add_kv},
96         {"IPsec.LocalXauthID", "xauth_id", "local", vici_add_kv},
97         {"IPsec.LocalXauthAuth", "auth", "local-xauth", vici_add_kv},
98         {"IPsec.LocalXauthXauthID", "xauth_id", "local-xauth", vici_add_kv},
99         {"IPsec.RemoteAuth", "auth", "remote", vici_add_kv},
100         {"IPsec.RemoteID", "id", "remote", vici_add_kv},
101         {"IPsec.RemoteXauthID", "xauth_id", "remote", vici_add_kv},
102         {"IPsec.RemoteXauthAuth", "auth", "remote-xauth", vici_add_kv},
103         {"IPsec.RemoteXauthXauthID", "xauth_id", "remote-xauth", vici_add_kv},
104         {"IPsec.ChildrenLocalTS", "local_ts", "children", vici_add_kvl},
105         {"IPsec.ChildrenRemoteTS", "remote_ts", "children", vici_add_kvl},
106 };
107
108 struct {
109         const char *cm_opt;
110         const char *vici_type;
111 } ipsec_shared_options[] = {
112         {"IPsec.IKEData", "data"},
113         {"IPsec.IKEOwners", "owners"},
114         {"IPsec.XauthData", "data"},
115         {"IPsec.XauthOwners", "owners"},
116 };
117
118 struct {
119         const char *cm_opt;
120         const char *vici_type;
121         const char *vici_flag;
122 } ipsec_cert_options[] = {
123         {"IPsec.CertType", "type", NULL},
124         {"IPsec.CertFlag", "flag", NULL},
125         {"IPsec.CertData", "data", NULL},
126         {"IPsec.CertPass", "data", NULL},
127 };
128
129 struct {
130         const char *cm_opt;
131         const char *vici_type;
132 } ipsec_pkey_options[] = {
133         {"IPsec.PKeyType", "type"},
134         {"IPsec.PKeyData", "data"},
135 };
136
137 static const char *ikev1_esp_proposals [] ={
138                 "aes256-sha256",
139                 "aes128-sha256",
140                 "aes256-sha1",
141                 "aes128-sha1",
142                 "aes256-md5",
143                 "aes128-md5",
144                 "3des-sha1",
145                 "3des-md5",
146                 NULL,
147 };
148
149 static const char *ikev1_proposals [] ={
150                 "aes256-sha256-modp1024",
151                 "aes128-sha256-modp1024",
152                 "aes256-sha1-modp1024",
153                 "aes128-sha1-modp1024",
154                 "aes256-md5-modp1024",
155                 "aes128-md5-modp1024",
156                 "3des-sha1-modp1024",
157                 "3des-md5-modp1024",
158                 NULL,
159 };
160
161 static const char *ikev2_esp_proposals = "aes256-aes128-sha512-sha384-sha256-sha1-modp2048-modp1536-modp1024";
162
163 static const char *ikev2_proposals = "aes256-aes128-sha512-sha384-sha256-sha1-modp2048-modp1536-modp1024";
164
165 static void init_openssl(void)
166 {
167         /* Load the human readable error strings for libcrypto */
168 #if OPENSSL_API_COMPAT < 0x10100000L
169         /* TODO :remove this after debug */
170         DBG("openssl version is under 1.01");
171         ERR_load_crypto_strings();
172 #else
173         /* As of version 1.1.0 OpenSSL will automatically allocate
174          * all resources that it needs so no explicit initialisation
175          * is required. Similarly it will also automatically
176          * deinitialise as required. */
177         /* OPENSSL_init_crypto(); */
178 #endif
179         /* Load all digest and cipher algorithms */
180 #if OPENSSL_API_COMPAT < 0x10100000L
181         OpenSSL_add_all_algorithms();
182 #else
183         /* As of version 1.1.0 OpenSSL will automatically allocate
184          * all resources that it needs so no explicit initialisation
185          * is required. Similarly it will also automatically
186          * deinitialise as required. */
187         /* OPENSSL_init_crypto(); */
188 #endif
189 #if OPENSSL_API_COMPAT < 0x10100000L
190         OPENSSL_config(NULL);
191 #else
192 #endif
193         /* TODO :remove this after debug */
194         DBG("init openssl");
195         return;
196 }
197
198 static void deinit_openssl(void)
199 {
200 #if OPENSSL_API_COMPAT < 0x10100000L
201         EVP_cleanup();
202 #else
203 #endif
204 #if OPENSSL_API_COMPAT < 0x10100000L
205         ERR_free_strings();
206 #else
207 #endif
208         return;
209 }
210
211 static int print_openssl_error_cb(const char *str, size_t len, void *u)
212 {
213         connman_error("%s", str);
214         return 0;
215 }
216
217 static void print_openssl_error()
218 {
219         ERR_print_errors_cb(print_openssl_error_cb, NULL);
220         return;
221 }
222
223 static int get_cert_type(const char *path)
224 {
225         char *down_str = NULL;
226         int cert_type;
227
228         down_str = g_ascii_strdown(path, strlen(path));
229         if (!down_str)
230                 return CERT_TYPE_NONE;
231
232         if(g_str_has_suffix(down_str, ".pem"))
233                 cert_type = CERT_TYPE_PEM;
234         else if (g_str_has_suffix(down_str, ".der") || g_str_has_suffix(down_str, ".crt"))
235                 cert_type = CERT_TYPE_DER;
236         else if (g_str_has_suffix(down_str, ".p12") || g_str_has_suffix(down_str, ".pfx"))
237                 cert_type = CERT_TYPE_PKCS12;
238         else
239                 cert_type = CERT_TYPE_NONE;
240         g_free(down_str);
241
242         return cert_type;
243 }
244
245 static void read_der_file(const char *path, X509 **cert)
246 {
247         FILE *fp = NULL;
248
249         DBG("der path %s\n", path);
250         fp = fopen(path, "r");
251         *cert = d2i_X509_fp(fp, NULL);
252         fclose(fp);
253         return;
254 }
255
256 static void read_pem_file(const char *path, X509 **cert)
257 {
258         FILE *fp = NULL;
259
260         DBG("pem path %s\n", path);
261         fp = fopen(path, "r");
262         *cert = PEM_read_X509(fp, cert, NULL, NULL);
263         fclose(fp);
264         return;
265 }
266
267 static void read_pkcs12_file(const char *path, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
268 {
269         FILE *fp = NULL;
270         PKCS12 *p12;
271
272         DBG("pkcs12 path %s\n", path);
273         fp = fopen(path, "r");
274         if (!fp) {
275                 print_openssl_error();
276                 return;
277         }
278
279         p12 = d2i_PKCS12_fp(fp, NULL);
280         if (!p12) {
281                 print_openssl_error();
282                 fclose(fp);
283                 return;
284         }
285
286         if (!PKCS12_parse(p12, pass, pkey, cert, ca)) {
287                 print_openssl_error();
288                 fclose(fp);
289                 return;
290         }
291
292         PKCS12_free(p12);
293         return;
294 }
295
296 static char *get_private_key_str(struct openssl_private_data *data)
297 {
298         EVP_PKEY *pkey;
299         BIO* bio;
300         BUF_MEM *buf_ptr;
301         char *private_key_str = NULL;
302
303         if (!data)
304                 return NULL;
305
306         if (!(pkey = data->private_key))
307                 return NULL;
308
309         bio = BIO_new(BIO_s_mem());
310         if (!bio) {
311                 print_openssl_error();
312                 return NULL;
313         }
314
315         if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) {
316                 print_openssl_error();
317                 BIO_free(bio);
318                 return NULL;
319         }
320
321         BIO_get_mem_ptr(bio, &buf_ptr);
322         if (!buf_ptr) {
323                 print_openssl_error();
324                 BIO_free(bio);
325                 return NULL;
326         }
327
328         private_key_str = g_try_malloc0(buf_ptr->length + 1);
329         if (!private_key_str) {
330                 print_openssl_error();
331                 BIO_free(bio);
332                 return NULL;
333         }
334
335         g_strlcpy(private_key_str, buf_ptr->data, buf_ptr->length);
336
337         BIO_free(bio);
338
339         return private_key_str;
340 }
341
342 static char *get_cert_str(X509 *cert)
343 {
344         BIO* bio;
345         BUF_MEM *buf_ptr;
346         char *cert_str = NULL;
347
348         if (!cert)
349                 return NULL;
350
351         bio = BIO_new(BIO_s_mem());
352         if (!bio) {
353                 print_openssl_error();
354                 return NULL;
355         }
356
357         if (!PEM_write_bio_X509_AUX(bio, cert)) {
358                 print_openssl_error();
359                 BIO_free(bio);
360                 return NULL;
361         }
362
363         BIO_get_mem_ptr(bio, &buf_ptr);
364         if (!buf_ptr) {
365                 print_openssl_error();
366                 BIO_free(bio);
367                 return NULL;
368         }
369
370         cert_str = g_try_malloc0(buf_ptr->length + 1);
371         if (!cert_str) {
372                 print_openssl_error();
373                 BIO_free(bio);
374                 return NULL;
375         }
376
377         g_strlcpy(cert_str, buf_ptr->data, buf_ptr->length);
378
379         BIO_free(bio);
380         return cert_str;
381 }
382
383 static char * get_local_cert_str(struct openssl_private_data *data)
384 {
385         if (!data)
386                 return NULL;
387
388         if (!(data->local_cert))
389                 return NULL;
390
391         return get_cert_str(data->local_cert);
392 }
393
394 int get_ca_cert_num(struct openssl_private_data *data)
395 {
396         if(!data || !data->ca_certs)
397                 return 0;
398
399         return sk_X509_num(data->ca_certs);
400 }
401
402 static char * get_nth_ca_cert_str(struct openssl_private_data *data, int num)
403 {
404         X509 *cert = NULL;
405
406         if (!data)
407                 return NULL;
408
409         if (!(data->ca_certs))
410                 return NULL;
411
412         cert = sk_X509_value(data->ca_certs, num);
413
414         return get_cert_str(cert);
415 }
416
417 static void extract_cert_info(const char *path, const char *pass, struct openssl_private_data *data)
418 {
419         if(!path || !data) {
420                 /* TODO :remove this after debug */
421                 DBG("there's no cert data");
422                 return;
423         }
424
425         switch (get_cert_type(path)) {
426         case CERT_TYPE_DER:
427                 read_der_file(path, &(data->local_cert));
428                 break;
429         case CERT_TYPE_PEM:
430                 read_pem_file(path, &(data->local_cert));
431                 break;
432         case CERT_TYPE_PKCS12:
433                 read_pkcs12_file(path, pass, &(data->private_key), &(data->local_cert), &(data->ca_certs));
434                 break;
435         default:
436                 break;
437         }
438
439         return;
440 }
441
442 static void free_openssl_private_data(struct openssl_private_data *data)
443 {
444         if (!data)
445                 return;
446
447         EVP_PKEY *private_key = data->private_key;
448         X509 *local_cert = data->local_cert;
449         STACK_OF(X509) *ca_certs = data->ca_certs;
450
451         if (private_key)
452                 EVP_PKEY_free(private_key);
453
454         if (local_cert)
455                 X509_free(local_cert);
456
457         if (ca_certs)
458                 sk_X509_pop_free(ca_certs, X509_free);
459
460         return;
461 }
462
463 static void free_private_data(struct ipsec_private_data *data)
464 {
465         free_openssl_private_data(&(data->openssl_data));
466         deinit_openssl();
467         g_free(data);
468 }
469
470 static int ipsec_notify(DBusMessage *msg, struct vpn_provider *provider)
471 {
472         return 0;
473 }
474
475 static int ipsec_is_same_auth(const char* req, const char* target)
476 {
477         if (req == NULL || target == NULL)
478                 return 0;
479         return (g_strcmp0(req, target) == 0);
480 }
481
482 static int vici_load_cert(const char* type, const char* flag, const char* data)
483 {
484         VICISection *sect;
485         int ret = 0;
486
487         sect = vici_create_section(NULL);
488         if (!sect)
489                 return -ENOMEM;
490
491         vici_add_kv(sect, "type", type, NULL);
492         vici_add_kv(sect, "flag", flag, NULL);
493         vici_add_kv(sect, "data", data, NULL);
494
495         ret = vici_send_request(vici_client, VICI_CMD_LOAD_CERT, sect);
496         if (ret < 0)
497                 connman_error("vici_send_request failed");
498
499         vici_destroy_section(sect);
500
501         return ret;
502 }
503
504 static int vici_load_key(const char* type, const char* data)
505 {
506         VICISection *sect;
507         sect = vici_create_section(NULL);
508         int ret = 0;
509
510         vici_add_kv(sect, "type", type, NULL);
511         vici_add_kv(sect, "data", data, NULL);
512         ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
513         if (ret < 0)
514                 connman_error("vici_send_request failed");
515
516         vici_destroy_section(sect);
517
518         return ret;
519 }
520
521 static void ipsec_add_default_child_sa_data(struct vpn_provider *provider, VICISection *child)
522 {
523         const char *version = vpn_provider_get_string(provider, "IPsec.Version");
524         if (g_strcmp0(version, "1") == 0) {
525                 int i = 0;
526                 GSList *list;
527
528                 for (list = NULL; ikev1_esp_proposals[i] != NULL; i++)
529                         list = g_slist_append(list, g_strdup(ikev1_esp_proposals[i]));
530                 vici_add_list(child, "esp_proposals", list, "net");
531                 g_slist_free_full(list, g_free);
532                 list = NULL;
533         } else {
534                 vici_add_kvl(child, "esp_proposals", ikev2_esp_proposals, "net");
535         }
536         return;
537 }
538
539 static void ipsec_add_default_conn_data(struct vpn_provider *provider, VICISection *conn)
540 {
541         const char *version = vpn_provider_get_string(provider, "IPsec.Version");
542         if (g_strcmp0(version, "1") == 0) {
543                 int i = 0;
544                 GSList *list;
545
546                 for (list = NULL; ikev1_proposals[i] != NULL; i++)
547                         list = g_slist_append(list, g_strdup(ikev1_proposals[i]));
548                 vici_add_list(conn, "proposals", list, NULL);
549                 g_slist_free_full(list, g_free);
550                 list = NULL;
551
552                 if (g_strcmp0(vpn_provider_get_string(provider, "IPsec.LocalAuth"), "psk") == 0)
553                         vici_add_kv(conn, "aggressive", "yes", NULL);
554         } else {
555                 vici_add_kvl(conn, "proposals", ikev2_proposals, NULL);
556         }
557
558         vici_add_kvl(conn, "vips", "0.0.0.0", NULL);
559         return;
560 }
561
562
563 static int ipsec_load_conn(struct vpn_provider *provider, struct ipsec_private_data *data)
564 {
565         const char *key;
566         const char *value;
567         const char *subsection;
568         char *local_cert_str;
569         VICISection *conn;
570         VICISection *children;
571         int i;
572         int ret = 0;
573
574         if (!provider || !data) {
575                 connman_error("invalid provider or data");
576                 return -EINVAL;
577         }
578
579         value = vpn_provider_get_string(provider, "Name");
580         DBG("Name: %s", value);
581         conn = vici_create_section(value);
582         children = vici_create_section("children");
583         add_subsection("children", children, conn);
584
585         for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
586                 value = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
587                 if (!value)
588                         continue;
589
590                 key = ipsec_conn_options[i].vici_key;
591                 subsection = ipsec_conn_options[i].subsection;
592                 ipsec_conn_options[i].add_elem(conn, key, value, subsection);
593         }
594
595         local_cert_str = get_local_cert_str(&(data->openssl_data));
596         if (local_cert_str) {
597                 /* TODO :remove this after debug */
598                 DBG("There's local certification to add local section");
599                 vici_add_kvl(conn, "certs", local_cert_str, "local");
600                 g_free(local_cert_str);
601         }
602
603         ipsec_add_default_conn_data(provider, conn);
604         ipsec_add_default_child_sa_data(provider, children);
605
606         ret = vici_send_request(vici_client, VICI_CMD_LOAD_CONN, conn);
607         if (ret < 0)
608                 connman_error("vici_send_request failed");
609
610         vici_destroy_section(conn);
611
612         return ret;
613 }
614
615 static int ipsec_load_private_data(struct ipsec_private_data *data)
616 {
617         char *private_key_str;
618         char *ca_cert_str;
619         int ca_cert_num;
620         int i;
621         int ret = 0;
622
623         private_key_str = get_private_key_str(&(data->openssl_data));
624         if (private_key_str) {
625                 /* TODO :remove this after debug */
626                 DBG("load private key");
627                 ret = vici_load_key("RSA", private_key_str);
628                 g_free(private_key_str);
629         }
630
631         if (ret < 0)
632                 return ret;
633
634         ca_cert_num = get_ca_cert_num(&(data->openssl_data));
635         if (ca_cert_num < 1)
636                 return 0;
637
638         for (i = 0; i < ca_cert_num; i++) {
639                 /* TODO :remove this after debug */
640                 DBG("load CA cert");
641                 ca_cert_str = get_nth_ca_cert_str(&(data->openssl_data), i);
642                 ret = vici_load_cert("X509", "CA", ca_cert_str);
643                 g_free(ca_cert_str);
644                 if (ret < 0)
645                         return ret;
646         }
647
648         return ret;
649 }
650
651 static int ipsec_load_shared_psk(struct vpn_provider *provider)
652 {
653         const char *data;
654         const char *owner;
655         VICISection *sect;
656         int ret = 0;
657
658         if (!provider) {
659                 connman_error("invalid provider");
660                 ret = -EINVAL;
661         }
662
663         data = vpn_provider_get_string(provider, "IPsec.IKEData");
664         owner = vpn_provider_get_string(provider, "IPsec.IKEOwners");
665         DBG("IKEData: %s, IKEOwners: %s", data, owner);
666
667         if (!data)
668                 return 0;
669
670         sect = vici_create_section(NULL);
671         if (!sect) {
672                 return -ENOMEM;
673         }
674
675         vici_add_kv(sect, "type", VICI_SHARED_TYPE_PSK, NULL);
676         vici_add_kv(sect, "data", data, NULL);
677         vici_add_kvl(sect, "owners", owner, NULL);
678
679         ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
680         if (ret < 0)
681                 connman_error("vici_send_request failed");
682
683         vici_destroy_section(sect);
684
685         return ret;
686 }
687
688 static int ipsec_load_shared_xauth(struct vpn_provider *provider)
689 {
690         const char *data;
691         const char *owner;
692         VICISection *sect;
693         int ret = 0;
694
695         if (!provider) {
696                 connman_error("invalid provider");
697                 return -EINVAL;
698         }
699
700         data = vpn_provider_get_string(provider, "IPsec.XauthData");
701         owner = vpn_provider_get_string(provider, "IPsec.XauthOwners");
702         DBG("XauthData: %s, XauthOwners: %s", data, owner);
703
704         if (!data)
705                 return 0;
706
707         sect = vici_create_section(NULL);
708
709         vici_add_kv(sect, "type", VICI_SHARED_TYPE_XAUTH, NULL);
710         vici_add_kv(sect, "data", data, NULL);
711         vici_add_kvl(sect, "owners", owner, NULL);
712
713         ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
714         if (ret < 0)
715                 connman_error("vici_send_request failed");
716
717         vici_destroy_section(sect);
718
719         return ret;
720 }
721
722 static char *load_file_from_path(const char *path)
723 {
724         struct stat st;
725         FILE *fp = NULL;
726         int fd = 0;
727         size_t  file_size = 0;
728         char *file_buff = NULL;
729
730         if (!path) {
731                 connman_error("File path is NULL\n");
732                 return NULL;
733         }
734
735         fp = fopen(path, "rb");
736         if (!fp) {
737                 connman_error("fopen %s is failed\n", path);
738                 return NULL;
739         }
740
741         fd = fileno(fp);
742         fstat(fd, &st);
743         file_size = st.st_size;
744         file_buff = g_try_malloc0(sizeof(char)*st.st_size);
745         if (file_buff == NULL) {
746                 connman_error("g_try_malloc0 failed\n");
747                 fclose(fp);
748                 return NULL;
749         }
750
751         if (fread(file_buff, 1, file_size, fp) != file_size) {
752                 connman_error("file size not matched\n");
753                 g_free(file_buff);
754                 file_buff = NULL;
755         }
756
757         fclose(fp);
758         return file_buff;
759 }
760
761 static int ipsec_load_key(struct vpn_provider *provider)
762 {
763         const char *type;
764         const char *path;
765         char *data;
766         VICISection *sect;
767         int ret = 0;
768
769         if (!provider) {
770                 connman_error("invalid provider");
771                 return -EINVAL;
772         }
773
774         type = vpn_provider_get_string(provider, "IPsec.PKeyType");
775         path = vpn_provider_get_string(provider, "IPsec.PKeyData");
776         DBG("PKeyType: %s, PKeyData: %s", type, path);
777
778         if (!type || !path)
779                 return 0;
780
781         data = load_file_from_path(path);
782         if (!data)
783                 return 0;
784
785         sect = vici_create_section(NULL);
786         if (!sect)
787                 return -ENOMEM;
788
789         vici_add_kv(sect, "type", type, NULL);
790         vici_add_kv(sect, "data", data, NULL);
791
792         ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
793         if (ret < 0)
794                 connman_error("vici_send_request failed");
795
796         vici_destroy_section(sect);
797         g_free(data);
798
799         return ret;
800 }
801
802 static int ipsec_initiate(struct vpn_provider *provider)
803 {
804         VICISection *sect;
805         int ret = 0;
806
807         sect = vici_create_section(NULL);
808         if (!sect)
809                 return -ENOMEM;
810
811         vici_add_kv(sect, "child", "net", NULL);
812         ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
813         if (ret < 0)
814                 connman_error("vici_send_request failed");
815
816         vici_destroy_section(sect);
817
818         return ret;
819 }
820
821 static int ipsec_load_cert(struct vpn_provider *provider)
822 {
823         const char *type;
824         const char *flag;
825         char *data;
826         const char *local_auth_type;
827         const char *remote_auth_type;
828         int ret = 0;
829
830         if (!provider) {
831                 connman_error("invalid provider");
832                 return -EINVAL;
833         }
834
835         local_auth_type = vpn_provider_get_string(provider, "IPsec.LocalAuth");
836         remote_auth_type = vpn_provider_get_string(provider, "IPsec.RemoteAuth");
837         if (!ipsec_is_same_auth(local_auth_type, "pubkey") &&
838                         !ipsec_is_same_auth(remote_auth_type, "pubkey")) {
839                 DBG("invalid auth type");
840                 return 0;
841         }
842
843         type = vpn_provider_get_string(provider, "IPsec.CertType");
844         flag = vpn_provider_get_string(provider, "IPsec.CertFlag");
845         data = load_file_from_path(vpn_provider_get_string(provider, "IPsec.CertData"));
846         DBG("CertType: %s, CertFalg: %s,CertData: %s", type, flag, data);
847         if (!type || ! flag || !data) {
848                 connman_error("invalid certification information");
849                 g_free(data);
850                 return -EINVAL;
851         }
852
853         ret = vici_load_cert(type, flag, data);
854         if (ret < 0)
855                 connman_error("failed to load cert");
856
857         g_free(data);
858
859         return ret;
860 }
861
862 void connect_reply_cb(int err, void *user_data)
863 {
864         struct ipsec_private_data *data;
865
866         data = (struct ipsec_private_data *)user_data;
867         data->cb(data->provider, data->user_data, err);
868
869         free_private_data(data);
870 }
871
872 static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
873                 vpn_provider_connect_cb_t cb, void* user_data)
874 {
875         struct ipsec_private_data *data;
876         data = g_try_new0(struct ipsec_private_data, 1);
877         if (!data) {
878                 connman_error("out of memory");
879                 return NULL;
880         }
881
882         init_openssl();
883
884         data->provider = provider;
885         data->cb = cb;
886         data->user_data = user_data;
887         return data;
888 }
889
890 static void vici_connect(struct ipsec_private_data *data)
891 {
892         struct vpn_provider *provider = NULL;
893         vpn_provider_connect_cb_t cb = NULL;
894         int err = 0;
895
896         if (!data)
897                 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
898
899         provider = data->provider;
900         cb = data->cb;
901         if (!provider || !cb)
902                 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
903
904         DBG("data %p, provider %p", data, provider);
905
906         /*
907          * Initialize vici client
908          */
909         err = vici_initialize(&vici_client);
910         IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
911
912         /* TODO :remove this after debug */
913         DBG("success to initialize vici socket");
914
915         vici_set_connect_reply_cb(vici_client, (vici_connect_reply_cb)connect_reply_cb, data);
916
917         /*
918          * Send the load-conn command
919          */
920         err = ipsec_load_conn(provider, data);
921         IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
922
923         /* TODO :remove this after debug */
924         DBG("success to ipsec_load_conn");
925
926         err = ipsec_load_private_data(data);
927         IPSEC_ERROR_CHECK_GOTO(err, done, "load private data failed");
928
929         /* TODO :remove this after debug */
930         DBG("success to ipsec_load_private_data");
931
932         /*
933          * Send the load-shared command for PSK
934          */
935         err = ipsec_load_shared_psk(provider);
936         IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
937
938         /* TODO :remove this after debug */
939         DBG("success to ipsec_load_shared_psk");
940
941         /*
942          * Send the load-shared command for XAUTH
943          */
944         err = ipsec_load_shared_xauth(provider);
945         IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
946
947         /* TODO :remove this after debug */
948         DBG("success to ipsec_load_shared_xauth");
949         /*
950          * Send the load-cert command
951          */
952         err = ipsec_load_cert(provider);
953         IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
954
955         /* TODO :remove this after debug */
956         DBG("success to ipsec_load_cert");
957
958         /*
959          * Send the load-key command
960          */
961         err = ipsec_load_key(provider);
962         IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
963
964         /* TODO :remove this after debug */
965         DBG("success to ipsec_load_cert");
966         /*
967          * Send the initiate command
968          */
969         err = ipsec_initiate(provider);
970         IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
971
972         /* TODO :remove this after debug */
973         DBG("success to ipsec_initiate");
974
975 done:
976         /* refer to connect_cb on vpn-provider.c for cb */
977         if(err != 0 && cb)
978                 cb(provider, data->user_data, -err);
979
980         if (data)
981                 g_free(data);
982
983         return;
984 }
985
986 static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
987                 GFileMonitorEvent  event_type, gpointer user_data)
988 {
989         DBG("file %s", g_file_get_path(file));
990         if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
991                 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
992                         DBG("file created: %s", VICI_DEFAULT_URI);
993                         struct ipsec_private_data *data = user_data;
994                         vici_connect(data);
995                         g_object_unref(monitor);
996                 }
997         }
998 }
999
1000 static void monitor_vici_socket(struct ipsec_private_data *data)
1001 {
1002         GError *error = NULL;
1003         GFile* file;
1004
1005         file = g_file_new_for_path(VICI_DEFAULT_URI);
1006         monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &error);
1007         if (error) {
1008                 connman_error("g_file_monitor_directory failed: %s / %d", error->message, error->code);
1009                 g_error_free(error);
1010                 return;
1011         }
1012         /* TODO :remove this after debug */
1013         DBG("starting to monitor vici socket");
1014         g_signal_connect(monitor, "changed", G_CALLBACK(monitor_changed), data);
1015         g_object_unref(file);
1016 }
1017
1018 static void check_vici_socket(struct ipsec_private_data *data)
1019 {
1020         DBG("data %p", data);
1021         if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1022                 DBG("file exists: %s", VICI_DEFAULT_URI);
1023                 vici_connect(data);
1024         } else {
1025                 monitor_vici_socket(data);
1026         }
1027 }
1028
1029 static int ipsec_connect(struct vpn_provider *provider,
1030                         struct connman_task *task, const char *if_name,
1031                         vpn_provider_connect_cb_t cb, const char *dbus_sender,
1032                         void *user_data)
1033 {
1034         struct ipsec_private_data *data;
1035         const char *path;
1036         const char *pass;
1037         int err = 0;
1038
1039         data = create_ipsec_private_data(provider, cb, user_data);
1040         if (!data) {
1041                 connman_error("create ipsec private data failed");
1042                 return -ENOMEM;
1043         }
1044         /*
1045          * Start charon daemon using ipsec script of strongSwan.
1046          */
1047         err = connman_task_run(task, vpn_died, provider, NULL, NULL, NULL);
1048         if (err < 0) {
1049                 connman_error("charon start failed");
1050                 if (cb)
1051                         cb(provider, user_data, err);
1052                 return err;
1053         }
1054
1055         path = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1056         pass = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1057         extract_cert_info(path, pass, &(data->openssl_data));
1058
1059         check_vici_socket(data);
1060 //      g_usleep(G_USEC_PER_SEC);
1061
1062         return err;
1063 }
1064
1065 static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
1066 {
1067         return 0;
1068 }
1069
1070 static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
1071 {
1072         int i;
1073         const char *option;
1074
1075         DBG("");
1076         /*
1077          * Save IKE connection configurations
1078          */
1079         for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
1080                 option = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
1081                 if (option)
1082                         g_key_file_set_string(keyfile,
1083                                         vpn_provider_get_save_group(provider),
1084                                         ipsec_conn_options[i].cm_opt,
1085                                         option);
1086         }
1087
1088         /*
1089          * Save shared IKE PSK, EAP or XAUTH secret
1090          */
1091         for (i = 0; i < (int)ARRAY_SIZE(ipsec_shared_options); i++) {
1092                 option = vpn_provider_get_string(provider, ipsec_shared_options[i].cm_opt);
1093                 if (option)
1094                         g_key_file_set_string(keyfile,
1095                                         vpn_provider_get_save_group(provider),
1096                                         ipsec_shared_options[i].cm_opt,
1097                                         option);
1098         }
1099
1100         /*
1101          * Save certification
1102          */
1103         for (i = 0; i < (int)ARRAY_SIZE(ipsec_cert_options); i++) {
1104                 option = vpn_provider_get_string(provider, ipsec_cert_options[i].cm_opt);
1105                 if (option)
1106                         g_key_file_set_string(keyfile,
1107                                         vpn_provider_get_save_group(provider),
1108                                         ipsec_cert_options[i].cm_opt,
1109                                         option);
1110         }
1111
1112         /*
1113          * Save private key
1114          */
1115         for (i = 0; i < (int)ARRAY_SIZE(ipsec_pkey_options); i++) {
1116                 option = vpn_provider_get_string(provider, ipsec_pkey_options[i].cm_opt);
1117                 if (option)
1118                         g_key_file_set_string(keyfile,
1119                                         vpn_provider_get_save_group(provider),
1120                                         ipsec_pkey_options[i].cm_opt,
1121                                         option);
1122         }
1123
1124         /*
1125          * Save local certification
1126          */
1127         option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1128         if (option)
1129                 g_key_file_set_string(keyfile,
1130                                 vpn_provider_get_save_group(provider),
1131                                 "IPsec.LocalCerts",
1132                                 option);
1133         option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1134         if (option)
1135                 g_key_file_set_string(keyfile,
1136                                 vpn_provider_get_save_group(provider),
1137                                 "IPsec.LocalCertPass",
1138                                 option);
1139         /*
1140          * Save CA certification directory
1141          */
1142         option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
1143         if (option)
1144                 g_key_file_set_string(keyfile,
1145                                 vpn_provider_get_save_group(provider),
1146                                 "IPsec.CACertsDir",
1147                                 option);
1148
1149         return 0;
1150 }
1151
1152 static void ipsec_disconnect(struct vpn_provider *provider)
1153 {
1154         int err = 0;
1155
1156         err = vici_deinitialize(vici_client);
1157         IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
1158 }
1159
1160 static struct vpn_driver vpn_driver = {
1161         .flags = VPN_FLAG_NO_TUN,
1162         .notify = ipsec_notify,
1163         .connect = ipsec_connect,
1164         .error_code = ipsec_error_code,
1165         .save = ipsec_save,
1166         .disconnect = ipsec_disconnect,
1167 };
1168
1169 static int ipsec_init(void)
1170 {
1171         connection = connman_dbus_get_connection();
1172
1173         return vpn_register("ipsec", &vpn_driver, IPSEC);
1174 }
1175
1176 static void ipsec_exit(void)
1177 {
1178         vpn_unregister("ipsec");
1179
1180         dbus_connection_unref(connection);
1181 }
1182
1183 CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
1184         CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)