Fix svace issues (WGID-207858, 208122, 208137, 208138)
[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
275         p12 = d2i_PKCS12_fp(fp, NULL);
276         if (!p12) {
277                 print_openssl_error();
278                 fclose(fp);
279                 return;
280         }
281
282         if (!PKCS12_parse(p12, pass, pkey, cert, ca)) {
283                 print_openssl_error();
284                 fclose(fp);
285                 return;
286         }
287
288         PKCS12_free(p12);
289         return;
290 }
291
292 static char *get_private_key_str(struct openssl_private_data *data)
293 {
294         EVP_PKEY *pkey;
295         BIO* bio;
296         BUF_MEM *buf_ptr;
297         char *private_key_str = NULL;
298
299         if (!data)
300                 return NULL;
301
302         if (!(pkey = data->private_key))
303                 return NULL;
304
305         bio = BIO_new(BIO_s_mem());
306         if (!bio) {
307                 print_openssl_error();
308                 return NULL;
309         }
310
311         if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) {
312                 print_openssl_error();
313                 BIO_free(bio);
314                 return NULL;
315         }
316
317         BIO_get_mem_ptr(bio, &buf_ptr);
318         if (!buf_ptr) {
319                 print_openssl_error();
320                 BIO_free(bio);
321                 return NULL;
322         }
323
324         private_key_str = g_try_malloc0(buf_ptr->length + 1);
325         if (!private_key_str) {
326                 print_openssl_error();
327                 BIO_free(bio);
328                 return NULL;
329         }
330
331         g_strlcpy(private_key_str, buf_ptr->data, buf_ptr->length);
332
333         BIO_free(bio);
334
335         return private_key_str;
336 }
337
338 static char *get_cert_str(X509 *cert)
339 {
340         BIO* bio;
341         BUF_MEM *buf_ptr;
342         char *cert_str = NULL;
343
344         if (!cert)
345                 return NULL;
346
347         bio = BIO_new(BIO_s_mem());
348         if (!bio) {
349                 print_openssl_error();
350                 return NULL;
351         }
352
353         if (!PEM_write_bio_X509_AUX(bio, cert)) {
354                 print_openssl_error();
355                 BIO_free(bio);
356                 return NULL;
357         }
358
359         BIO_get_mem_ptr(bio, &buf_ptr);
360         if (!buf_ptr) {
361                 print_openssl_error();
362                 BIO_free(bio);
363                 return NULL;
364         }
365
366         cert_str = g_try_malloc0(buf_ptr->length + 1);
367         if (!cert_str) {
368                 print_openssl_error();
369                 BIO_free(bio);
370                 return NULL;
371         }
372
373         g_strlcpy(cert_str, buf_ptr->data, buf_ptr->length);
374
375         BIO_free(bio);
376         return cert_str;
377 }
378
379 static char * get_local_cert_str(struct openssl_private_data *data)
380 {
381         if (!data)
382                 return NULL;
383
384         if (!(data->local_cert))
385                 return NULL;
386
387         return get_cert_str(data->local_cert);
388 }
389
390 int get_ca_cert_num(struct openssl_private_data *data)
391 {
392         if(!data || !data->ca_certs)
393                 return 0;
394
395         return sk_X509_num(data->ca_certs);
396 }
397
398 static char * get_nth_ca_cert_str(struct openssl_private_data *data, int num)
399 {
400         X509 *cert = NULL;
401
402         if (!data)
403                 return NULL;
404
405         if (!(data->ca_certs))
406                 return NULL;
407
408         cert = sk_X509_value(data->ca_certs, num);
409
410         return get_cert_str(cert);
411 }
412
413 static void extract_cert_info(const char *path, const char *pass, struct openssl_private_data *data)
414 {
415         if(!path || !data) {
416                 /* TODO :remove this after debug */
417                 DBG("there's no cert data");
418                 return;
419         }
420
421         switch (get_cert_type(path)) {
422         case CERT_TYPE_DER:
423                 read_der_file(path, &(data->local_cert));
424                 break;
425         case CERT_TYPE_PEM:
426                 read_pem_file(path, &(data->local_cert));
427                 break;
428         case CERT_TYPE_PKCS12:
429                 read_pkcs12_file(path, pass, &(data->private_key), &(data->local_cert), &(data->ca_certs));
430                 break;
431         default:
432                 break;
433         }
434
435         return;
436 }
437
438 static void free_openssl_private_data(struct openssl_private_data *data)
439 {
440         if (!data)
441                 return;
442
443         EVP_PKEY *private_key = data->private_key;
444         X509 *local_cert = data->local_cert;
445         STACK_OF(X509) *ca_certs = data->ca_certs;
446
447         if (private_key)
448                 EVP_PKEY_free(private_key);
449
450         if (local_cert)
451                 X509_free(local_cert);
452
453         if (ca_certs)
454                 sk_X509_pop_free(ca_certs, X509_free);
455
456         return;
457 }
458
459 static void free_private_data(struct ipsec_private_data *data)
460 {
461         free_openssl_private_data(&(data->openssl_data));
462         deinit_openssl();
463         g_free(data);
464 }
465
466 static int ipsec_notify(DBusMessage *msg, struct vpn_provider *provider)
467 {
468         return 0;
469 }
470
471 static int ipsec_is_same_auth(const char* req, const char* target)
472 {
473         if (req == NULL || target == NULL)
474                 return 0;
475         return (g_strcmp0(req, target) == 0);
476 }
477
478 static int vici_load_cert(const char* type, const char* flag, const char* data)
479 {
480         VICISection *sect;
481         int ret = 0;
482
483         sect = vici_create_section(NULL);
484         if (!sect)
485                 return -ENOMEM;
486
487         vici_add_kv(sect, "type", type, NULL);
488         vici_add_kv(sect, "flag", flag, NULL);
489         vici_add_kv(sect, "data", data, NULL);
490
491         ret = vici_send_request(vici_client, VICI_CMD_LOAD_CERT, sect);
492         if (ret < 0)
493                 connman_error("vici_send_request failed");
494
495         vici_destroy_section(sect);
496
497         return ret;
498 }
499
500 static int vici_load_key(const char* type, const char* data)
501 {
502         VICISection *sect;
503         sect = vici_create_section(NULL);
504         int ret = 0;
505
506         vici_add_kv(sect, "type", type, NULL);
507         vici_add_kv(sect, "data", data, NULL);
508         ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
509         if (ret < 0)
510                 connman_error("vici_send_request failed");
511
512         vici_destroy_section(sect);
513
514         return ret;
515 }
516
517 static void ipsec_add_default_child_sa_data(struct vpn_provider *provider, VICISection *child)
518 {
519         const char *version = vpn_provider_get_string(provider, "IPsec.Version");
520         if (g_strcmp0(version, "1") == 0) {
521                 int i = 0;
522                 GSList *list;
523
524                 for (list = NULL; ikev1_esp_proposals[i] != NULL; i++)
525                         list = g_slist_append(list, g_strdup(ikev1_esp_proposals[i]));
526                 vici_add_list(child, "esp_proposals", list, "net");
527                 list = NULL;
528         } else {
529                 vici_add_kvl(child, "esp_proposals", ikev2_esp_proposals, "net");
530         }
531         return;
532 }
533
534 static void ipsec_add_default_conn_data(struct vpn_provider *provider, VICISection *conn)
535 {
536         const char *version = vpn_provider_get_string(provider, "IPsec.Version");
537         if (g_strcmp0(version, "1") == 0) {
538                 int i = 0;
539                 GSList *list;
540
541                 for (list = NULL; ikev1_proposals[i] != NULL; i++)
542                         list = g_slist_append(list, g_strdup(ikev1_proposals[i]));
543                 vici_add_list(conn, "proposals", list, NULL);
544                 list = NULL;
545
546                 if (g_strcmp0(vpn_provider_get_string(provider, "IPsec.LocalAuth"), "psk") == 0)
547                         vici_add_kv(conn, "aggressive", "yes", NULL);
548
549         } else {
550                 vici_add_kvl(conn, "proposals", ikev2_proposals, NULL);
551         }
552
553         vici_add_kvl(conn, "vips", "0.0.0.0", NULL);
554         return;
555 }
556
557
558 static int ipsec_load_conn(struct vpn_provider *provider, struct ipsec_private_data *data)
559 {
560         const char *key;
561         const char *value;
562         const char *subsection;
563         char *local_cert_str;
564         VICISection *conn;
565         VICISection *children;
566         int i;
567         int ret = 0;
568
569         if (!provider || !data) {
570                 connman_error("invalid provider or data");
571                 return -EINVAL;
572         }
573
574         value = vpn_provider_get_string(provider, "Name");
575         DBG("Name: %s", value);
576         conn = vici_create_section(value);
577         children = vici_create_section("children");
578         add_subsection("children", children, conn);
579
580         for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
581                 value = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
582                 if (!value)
583                         continue;
584
585                 key = ipsec_conn_options[i].vici_key;
586                 subsection = ipsec_conn_options[i].subsection;
587                 ipsec_conn_options[i].add_elem(conn, key, value, subsection);
588         }
589
590         local_cert_str = get_local_cert_str(&(data->openssl_data));
591         if (local_cert_str) {
592                 /* TODO :remove this after debug */
593                 DBG("There's local certification to add local section");
594                 vici_add_kvl(conn, "certs", local_cert_str, "local");
595                 g_free(local_cert_str);
596         }
597
598         ipsec_add_default_conn_data(provider, conn);
599         ipsec_add_default_child_sa_data(provider, children);
600
601         ret = vici_send_request(vici_client, VICI_CMD_LOAD_CONN, conn);
602         if (ret < 0)
603                 connman_error("vici_send_request failed");
604
605         vici_destroy_section(conn);
606
607         return ret;
608 }
609
610 static int ipsec_load_private_data(struct ipsec_private_data *data)
611 {
612         char *private_key_str;
613         char *ca_cert_str;
614         int ca_cert_num;
615         int i;
616         int ret = 0;
617
618         private_key_str = get_private_key_str(&(data->openssl_data));
619         if (private_key_str) {
620                 /* TODO :remove this after debug */
621                 DBG("load private key");
622                 ret = vici_load_key("RSA", private_key_str);
623                 g_free(private_key_str);
624         }
625
626         if (ret < 0)
627                 return ret;
628
629         ca_cert_num = get_ca_cert_num(&(data->openssl_data));
630         if (ca_cert_num < 1)
631                 return 0;
632
633         for (i = 0; i < ca_cert_num; i++) {
634                 /* TODO :remove this after debug */
635                 DBG("load CA cert");
636                 ca_cert_str = get_nth_ca_cert_str(&(data->openssl_data), i);
637                 ret = vici_load_cert("X509", "CA", ca_cert_str);
638                 g_free(ca_cert_str);
639                 if (ret < 0)
640                         return ret;
641         }
642
643         return ret;
644 }
645
646 static int ipsec_load_shared_psk(struct vpn_provider *provider)
647 {
648         const char *data;
649         const char *owner;
650         VICISection *sect;
651         int ret = 0;
652
653         if (!provider) {
654                 connman_error("invalid provider");
655                 ret = -EINVAL;
656         }
657
658         data = vpn_provider_get_string(provider, "IPsec.IKEData");
659         owner = vpn_provider_get_string(provider, "IPsec.IKEOwners");
660         DBG("IKEData: %s, IKEOwners: %s", data, owner);
661
662         if (!data)
663                 return 0;
664
665         sect = vici_create_section(NULL);
666         if (!sect) {
667                 return -ENOMEM;
668         }
669
670         vici_add_kv(sect, "type", VICI_SHARED_TYPE_PSK, NULL);
671         vici_add_kv(sect, "data", data, NULL);
672         vici_add_kvl(sect, "owners", owner, NULL);
673
674         ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
675         if (ret < 0)
676                 connman_error("vici_send_request failed");
677
678         vici_destroy_section(sect);
679
680         return ret;
681 }
682
683 static int ipsec_load_shared_xauth(struct vpn_provider *provider)
684 {
685         const char *data;
686         const char *owner;
687         VICISection *sect;
688         int ret = 0;
689
690         if (!provider) {
691                 connman_error("invalid provider");
692                 return -EINVAL;
693         }
694
695         data = vpn_provider_get_string(provider, "IPsec.XauthData");
696         owner = vpn_provider_get_string(provider, "IPsec.XauthOwners");
697         DBG("XauthData: %s, XauthOwners: %s", data, owner);
698
699         if (!data)
700                 return 0;
701
702         sect = vici_create_section(NULL);
703
704         vici_add_kv(sect, "type", VICI_SHARED_TYPE_XAUTH, NULL);
705         vici_add_kv(sect, "data", data, NULL);
706         vici_add_kvl(sect, "owners", owner, NULL);
707
708         ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
709         if (ret < 0)
710                 connman_error("vici_send_request failed");
711
712         vici_destroy_section(sect);
713
714         return ret;
715 }
716
717 static char *load_file_from_path(const char *path)
718 {
719         struct stat st;
720         FILE *fp = NULL;
721         int fd = 0;
722         size_t  file_size = 0;
723         char *file_buff = NULL;
724
725         if (!path) {
726                 connman_error("File path is NULL\n");
727                 return NULL;
728         }
729
730         fp = fopen(path, "rb");
731         if (!fp) {
732                 connman_error("fopen %s is failed\n", path);
733                 return NULL;
734         }
735
736         fd = fileno(fp);
737         fstat(fd, &st);
738         file_size = st.st_size;
739         file_buff = g_try_malloc0(sizeof(char)*st.st_size);
740         if (file_buff == NULL) {
741                 connman_error("g_try_malloc0 failed\n");
742                 fclose(fp);
743                 return NULL;
744         }
745
746         if (fread(file_buff, 1, file_size, fp) != file_size) {
747                 connman_error("file size not matched\n");
748                 g_free(file_buff);
749                 file_buff = NULL;
750         }
751
752         fclose(fp);
753         return file_buff;
754 }
755
756 static int ipsec_load_key(struct vpn_provider *provider)
757 {
758         const char *type;
759         const char *path;
760         char *data;
761         VICISection *sect;
762         int ret = 0;
763
764         if (!provider) {
765                 connman_error("invalid provider");
766                 return -EINVAL;
767         }
768
769         type = vpn_provider_get_string(provider, "IPsec.PKeyType");
770         path = vpn_provider_get_string(provider, "IPsec.PKeyData");
771         DBG("PKeyType: %s, PKeyData: %s", type, path);
772
773         if (!type || !path)
774                 return 0;
775
776         data = load_file_from_path(path);
777         if (!data)
778                 return 0;
779
780         sect = vici_create_section(NULL);
781         if (!sect)
782                 return -ENOMEM;
783
784         vici_add_kv(sect, "type", type, NULL);
785         vici_add_kv(sect, "data", data, NULL);
786
787         ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
788         if (ret < 0)
789                 connman_error("vici_send_request failed");
790
791         vici_destroy_section(sect);
792         g_free(data);
793
794         return ret;
795 }
796
797 static int ipsec_initiate(struct vpn_provider *provider)
798 {
799         VICISection *sect;
800         int ret = 0;
801
802         sect = vici_create_section(NULL);
803         if (!sect)
804                 return -ENOMEM;
805
806         vici_add_kv(sect, "child", "net", NULL);
807         ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
808         if (ret < 0)
809                 connman_error("vici_send_request failed");
810
811         vici_destroy_section(sect);
812
813         return ret;
814 }
815
816 static int ipsec_load_cert(struct vpn_provider *provider)
817 {
818         const char *type;
819         const char *flag;
820         char *data;
821         const char *local_auth_type;
822         const char *remote_auth_type;
823         int ret = 0;
824
825         if (!provider) {
826                 connman_error("invalid provider");
827                 return -EINVAL;
828         }
829
830         local_auth_type = vpn_provider_get_string(provider, "IPsec.LocalAuth");
831         remote_auth_type = vpn_provider_get_string(provider, "IPsec.RemoteAuth");
832         if (!ipsec_is_same_auth(local_auth_type, "pubkey") &&
833                         !ipsec_is_same_auth(remote_auth_type, "pubkey")) {
834                 DBG("invalid auth type");
835                 return 0;
836         }
837
838         type = vpn_provider_get_string(provider, "IPsec.CertType");
839         flag = vpn_provider_get_string(provider, "IPsec.CertFlag");
840         data = load_file_from_path(vpn_provider_get_string(provider, "IPsec.CertData"));
841         DBG("CertType: %s, CertFalg: %s,CertData: %s", type, flag, data);
842         if (!type || ! flag || !data) {
843                 connman_error("invalid certification information");
844                 g_free(data);
845                 return -EINVAL;
846         }
847
848         ret = vici_load_cert(type, flag, data);
849         if (ret < 0)
850                 connman_error("failed to load cert");
851
852         g_free(data);
853
854         return ret;
855 }
856
857 void connect_reply_cb(int err, void *user_data)
858 {
859         struct ipsec_private_data *data;
860
861         data = (struct ipsec_private_data *)user_data;
862         data->cb(data->provider, data->user_data, err);
863
864         free_private_data(data);
865 }
866
867 static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
868                 vpn_provider_connect_cb_t cb, void* user_data)
869 {
870         struct ipsec_private_data *data;
871         data = g_try_new0(struct ipsec_private_data, 1);
872         if (!data) {
873                 connman_error("out of memory");
874                 return NULL;
875         }
876
877         init_openssl();
878
879         data->provider = provider;
880         data->cb = cb;
881         data->user_data = user_data;
882         return data;
883 }
884
885 static void vici_connect(struct ipsec_private_data *data)
886 {
887         struct vpn_provider *provider = NULL;
888         vpn_provider_connect_cb_t cb = NULL;
889         int err = 0;
890
891         if (!data)
892                 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
893
894         provider = data->provider;
895         cb = data->cb;
896         if (!provider || !cb)
897                 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
898
899         DBG("data %p, provider %p", data, provider);
900
901         /*
902          * Initialize vici client
903          */
904         err = vici_initialize(&vici_client);
905         IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
906
907         /* TODO :remove this after debug */
908         DBG("success to initialize vici socket");
909
910         vici_set_connect_reply_cb(vici_client, (vici_connect_reply_cb)connect_reply_cb, data);
911
912         /*
913          * Send the load-conn command
914          */
915         err = ipsec_load_conn(provider, data);
916         IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
917
918         /* TODO :remove this after debug */
919         DBG("success to ipsec_load_conn");
920
921         err = ipsec_load_private_data(data);
922         IPSEC_ERROR_CHECK_GOTO(err, done, "load private data failed");
923
924         /* TODO :remove this after debug */
925         DBG("success to ipsec_load_private_data");
926
927         /*
928          * Send the load-shared command for PSK
929          */
930         err = ipsec_load_shared_psk(provider);
931         IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
932
933         /* TODO :remove this after debug */
934         DBG("success to ipsec_load_shared_psk");
935
936         /*
937          * Send the load-shared command for XAUTH
938          */
939         err = ipsec_load_shared_xauth(provider);
940         IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
941
942         /* TODO :remove this after debug */
943         DBG("success to ipsec_load_shared_xauth");
944         /*
945          * Send the load-cert command
946          */
947         err = ipsec_load_cert(provider);
948         IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
949
950         /* TODO :remove this after debug */
951         DBG("success to ipsec_load_cert");
952
953         /*
954          * Send the load-key command
955          */
956         err = ipsec_load_key(provider);
957         IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
958
959         /* TODO :remove this after debug */
960         DBG("success to ipsec_load_cert");
961         /*
962          * Send the initiate command
963          */
964         err = ipsec_initiate(provider);
965         IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
966
967         /* TODO :remove this after debug */
968         DBG("success to ipsec_initiate");
969
970 done:
971         /* refer to connect_cb on vpn-provider.c for cb */
972         if(err != 0 && cb)
973                 cb(provider, data->user_data, -err);
974
975         if (data)
976                 g_free(data);
977
978         return;
979 }
980
981 static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
982                 GFileMonitorEvent  event_type, gpointer user_data)
983 {
984         DBG("file %s", g_file_get_path(file));
985         if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
986                 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
987                         DBG("file created: %s", VICI_DEFAULT_URI);
988                         struct ipsec_private_data *data = user_data;
989                         vici_connect(data);
990                         g_object_unref(monitor);
991                 }
992         }
993 }
994
995 static void monitor_vici_socket(struct ipsec_private_data *data)
996 {
997         GError *error = NULL;
998         GFile* file;
999
1000         file = g_file_new_for_path(VICI_DEFAULT_URI);
1001         monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &error);
1002         if (error) {
1003                 connman_error("g_file_monitor_directory failed: %s / %d", error->message, error->code);
1004                 g_error_free(error);
1005                 return;
1006         }
1007         /* TODO :remove this after debug */
1008         DBG("starting to monitor vici socket");
1009         g_signal_connect(monitor, "changed", G_CALLBACK(monitor_changed), data);
1010         g_object_unref(file);
1011 }
1012
1013 static void check_vici_socket(struct ipsec_private_data *data)
1014 {
1015         DBG("data %p", data);
1016         if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1017                 DBG("file exists: %s", VICI_DEFAULT_URI);
1018                 vici_connect(data);
1019         } else {
1020                 monitor_vici_socket(data);
1021         }
1022 }
1023
1024 static int ipsec_connect(struct vpn_provider *provider,
1025                         struct connman_task *task, const char *if_name,
1026                         vpn_provider_connect_cb_t cb, const char *dbus_sender,
1027                         void *user_data)
1028 {
1029         struct ipsec_private_data *data;
1030         const char *path;
1031         const char *pass;
1032         int err = 0;
1033
1034         data = create_ipsec_private_data(provider, cb, user_data);
1035         if (!data) {
1036                 connman_error("create ipsec private data failed");
1037                 return -ENOMEM;
1038         }
1039         /*
1040          * Start charon daemon using ipsec script of strongSwan.
1041          */
1042         err = connman_task_run(task, vpn_died, provider, NULL, NULL, NULL);
1043         if (err < 0) {
1044                 connman_error("charon start failed");
1045                 if (cb)
1046                         cb(provider, user_data, err);
1047                 return err;
1048         }
1049
1050         path = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1051         pass = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1052         extract_cert_info(path, pass, &(data->openssl_data));
1053
1054         check_vici_socket(data);
1055 //      g_usleep(G_USEC_PER_SEC);
1056
1057         return err;
1058 }
1059
1060 static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
1061 {
1062         return 0;
1063 }
1064
1065 static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
1066 {
1067         int i;
1068         const char *option;
1069
1070         DBG("");
1071         /*
1072          * Save IKE connection configurations
1073          */
1074         for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
1075                 option = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
1076                 if (option)
1077                         g_key_file_set_string(keyfile,
1078                                         vpn_provider_get_save_group(provider),
1079                                         ipsec_conn_options[i].cm_opt,
1080                                         option);
1081         }
1082
1083         /*
1084          * Save shared IKE PSK, EAP or XAUTH secret
1085          */
1086         for (i = 0; i < (int)ARRAY_SIZE(ipsec_shared_options); i++) {
1087                 option = vpn_provider_get_string(provider, ipsec_shared_options[i].cm_opt);
1088                 if (option)
1089                         g_key_file_set_string(keyfile,
1090                                         vpn_provider_get_save_group(provider),
1091                                         ipsec_shared_options[i].cm_opt,
1092                                         option);
1093         }
1094
1095         /*
1096          * Save certification
1097          */
1098         for (i = 0; i < (int)ARRAY_SIZE(ipsec_cert_options); i++) {
1099                 option = vpn_provider_get_string(provider, ipsec_cert_options[i].cm_opt);
1100                 if (option)
1101                         g_key_file_set_string(keyfile,
1102                                         vpn_provider_get_save_group(provider),
1103                                         ipsec_cert_options[i].cm_opt,
1104                                         option);
1105         }
1106
1107         /*
1108          * Save private key
1109          */
1110         for (i = 0; i < (int)ARRAY_SIZE(ipsec_pkey_options); i++) {
1111                 option = vpn_provider_get_string(provider, ipsec_pkey_options[i].cm_opt);
1112                 if (option)
1113                         g_key_file_set_string(keyfile,
1114                                         vpn_provider_get_save_group(provider),
1115                                         ipsec_pkey_options[i].cm_opt,
1116                                         option);
1117         }
1118
1119         /*
1120          * Save local certification
1121          */
1122         option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1123         if (option)
1124                 g_key_file_set_string(keyfile,
1125                                 vpn_provider_get_save_group(provider),
1126                                 "IPsec.LocalCerts",
1127                                 option);
1128         option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1129         if (option)
1130                 g_key_file_set_string(keyfile,
1131                                 vpn_provider_get_save_group(provider),
1132                                 "IPsec.LocalCertPass",
1133                                 option);
1134         /*
1135          * Save CA certification directory
1136          */
1137         option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
1138         if (option)
1139                 g_key_file_set_string(keyfile,
1140                                 vpn_provider_get_save_group(provider),
1141                                 "IPsec.CACertsDir",
1142                                 option);
1143
1144         return 0;
1145 }
1146
1147 static void ipsec_disconnect(struct vpn_provider *provider)
1148 {
1149         int err = 0;
1150
1151         err = vici_deinitialize(vici_client);
1152         IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
1153 }
1154
1155 static struct vpn_driver vpn_driver = {
1156         .flags = VPN_FLAG_NO_TUN,
1157         .notify = ipsec_notify,
1158         .connect = ipsec_connect,
1159         .error_code = ipsec_error_code,
1160         .save = ipsec_save,
1161         .disconnect = ipsec_disconnect,
1162 };
1163
1164 static int ipsec_init(void)
1165 {
1166         connection = connman_dbus_get_connection();
1167
1168         return vpn_register("ipsec", &vpn_driver, IPSEC);
1169 }
1170
1171 static void ipsec_exit(void)
1172 {
1173         vpn_unregister("ipsec");
1174
1175         dbus_connection_unref(connection);
1176 }
1177
1178 CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
1179         CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)