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