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