Merge "Handle the failure case due to the invalid cert file" 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 (!fp) {
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 (!fp) {
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                 ret = -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                 return -ENOMEM;
845
846         vici_add_kv(sect, "type", type, NULL);
847         vici_add_kv(sect, "data", data, NULL);
848
849         ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
850         if (ret < 0)
851                 connman_error("vici_send_request failed");
852
853         vici_destroy_section(sect);
854         g_free(data);
855
856         return ret;
857 }
858
859 static int ipsec_initiate(struct vpn_provider *provider)
860 {
861         VICISection *sect;
862         int ret = 0;
863
864         sect = vici_create_section(NULL);
865         if (!sect)
866                 return -ENOMEM;
867
868         vici_add_kv(sect, "child", "net", NULL);
869         ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
870         if (ret < 0)
871                 connman_error("vici_send_request failed");
872
873         vici_destroy_section(sect);
874
875         return ret;
876 }
877
878 static int ipsec_load_cert(struct vpn_provider *provider)
879 {
880         const char *type;
881         const char *flag;
882         char *data;
883         const char *local_auth_type;
884         const char *remote_auth_type;
885         int ret = 0;
886
887         if (!provider) {
888                 connman_error("invalid provider");
889                 return -EINVAL;
890         }
891
892         local_auth_type = vpn_provider_get_string(provider, "IPsec.LocalAuth");
893         remote_auth_type = vpn_provider_get_string(provider, "IPsec.RemoteAuth");
894         if (!ipsec_is_same_auth(local_auth_type, "pubkey") &&
895                         !ipsec_is_same_auth(remote_auth_type, "pubkey")) {
896                 DBG("invalid auth type");
897                 return 0;
898         }
899
900         type = vpn_provider_get_string(provider, "IPsec.CertType");
901         flag = vpn_provider_get_string(provider, "IPsec.CertFlag");
902         data = load_file_from_path(vpn_provider_get_string(provider, "IPsec.CertData"));
903         DBG("CertType: %s, CertFalg: %s,CertData: %s", type, flag, data);
904         if (!type || ! flag || !data) {
905                 connman_error("invalid certification information");
906                 g_free(data);
907                 return -EINVAL;
908         }
909
910         ret = vici_load_cert(type, flag, data);
911         if (ret < 0)
912                 connman_error("failed to load cert");
913
914         g_free(data);
915
916         return ret;
917 }
918
919 static int ipsec_terminate(struct vpn_provider *provider)
920 {
921         VICISection *sect;
922         int ret = 0;
923
924         sect = vici_create_section(NULL);
925         if (!sect)
926                 return -ENOMEM;
927
928         vici_add_kv(sect, "child", "net", NULL);
929         vici_add_kv(sect, "ike", vpn_provider_get_string(provider, "Name"), NULL);
930         vici_add_kv(sect, "timeout", "-1", NULL);
931         ret = vici_send_request(vici_client, VICI_CMD_TERMINATE, sect);
932         if (ret < 0)
933                 connman_error("vici_send_request failed");
934
935         vici_destroy_section(sect);
936
937         return ret;
938 }
939
940 static void request_reply_cb(int err, void *user_data)
941 {
942         struct ipsec_private_data *data;
943
944         data = (struct ipsec_private_data *)user_data;
945         DBG("request reply cb");
946
947         if(err != 0) {
948                 if (event_data.event_cb)
949                         event_data.event_cb(event_data.event_user_data, VPN_STATE_FAILURE);
950                 /* TODO: Does close socket needed? */
951         } else {
952                 DBG("Series of requests are succeeded");
953                 /* TODO: Not sure about below */
954                 if (event_data.event_cb)
955                         event_data.event_cb(event_data.event_user_data, VPN_STATE_CONNECT);
956         }
957
958         free_private_data(data);
959 }
960
961 static void ipsec_vici_event_cb(VICIClientEvent event, void *user_data)
962 {
963         struct vpn_provider *provider;
964
965         provider = (struct vpn_provider *)user_data;
966         if (!provider) {
967                 DBG("Invalid user data");
968                 return;
969         }
970
971         if(event == VICI_EVENT_CHILD_UP) {
972                 if (event_data.event_cb)
973                         event_data.event_cb(event_data.event_user_data, VPN_STATE_READY);
974         } else if (event == VICI_EVENT_CHILD_DOWN) {
975                 if (event_data.event_cb)
976                         event_data.event_cb(event_data.event_user_data, VPN_STATE_DISCONNECT);
977         } else {
978                 DBG("Unknown event");
979         }
980
981         return;
982 }
983
984 static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
985                 vpn_provider_connect_cb_t cb, void* user_data)
986 {
987         struct ipsec_private_data *data;
988         data = g_try_new0(struct ipsec_private_data, 1);
989         if (!data) {
990                 connman_error("out of memory");
991                 return NULL;
992         }
993
994         init_openssl();
995
996         data->provider = provider;
997         data->connect_cb = cb;
998         data->connect_user_data = user_data;
999         return data;
1000 }
1001
1002 static void vici_connect(struct ipsec_private_data *data)
1003 {
1004         struct vpn_provider *provider = NULL;
1005         vpn_provider_connect_cb_t cb = NULL;
1006         int err = 0;
1007
1008         if (!data)
1009                 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
1010
1011         provider = data->provider;
1012         cb = data->connect_cb;
1013         if (!provider || !cb)
1014                 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
1015
1016         DBG("data %p, provider %p", data, provider);
1017
1018         /*
1019          * Initialize vici client
1020          */
1021         err = vici_initialize(&vici_client);
1022         IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
1023
1024         /* TODO :remove this after debug */
1025         DBG("success to initialize vici socket");
1026
1027         vici_set_request_reply_cb(vici_client, (vici_request_reply_cb)request_reply_cb, data);
1028         /*
1029          * Sets child-updown event
1030          */
1031         err = vici_set_event_cb(vici_client, (vici_event_cb)ipsec_vici_event_cb, provider);
1032         IPSEC_ERROR_CHECK_GOTO(err, done, "register event failed");
1033
1034         /* TODO :remove this after debug */
1035         DBG("success to vici_set_event_cb");
1036         /*
1037          * Send the load-conn command
1038          */
1039         err = ipsec_load_conn(provider, data);
1040         IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
1041
1042         /* TODO :remove this after debug */
1043         DBG("success to ipsec_load_conn");
1044
1045         err = ipsec_load_private_data(data);
1046         IPSEC_ERROR_CHECK_GOTO(err, done, "load private data failed");
1047
1048         /* TODO :remove this after debug */
1049         DBG("success to ipsec_load_private_data");
1050
1051         /*
1052          * Send the load-shared command for PSK
1053          */
1054         err = ipsec_load_shared_psk(provider);
1055         IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
1056
1057         /* TODO :remove this after debug */
1058         DBG("success to ipsec_load_shared_psk");
1059
1060         /*
1061          * Send the load-shared command for XAUTH
1062          */
1063         err = ipsec_load_shared_xauth(provider);
1064         IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
1065
1066         /* TODO :remove this after debug */
1067         DBG("success to ipsec_load_shared_xauth");
1068         /*
1069          * Send the load-cert command
1070          */
1071         err = ipsec_load_cert(provider);
1072         IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
1073
1074         /* TODO :remove this after debug */
1075         DBG("success to ipsec_load_cert");
1076
1077         /*
1078          * Send the load-key command
1079          */
1080         err = ipsec_load_key(provider);
1081         IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
1082
1083         /* TODO :remove this after debug */
1084         DBG("success to ipsec_load_cert");
1085         /*
1086          * Send the initiate command
1087          */
1088         err = ipsec_initiate(provider);
1089         IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
1090
1091         /* TODO :remove this after debug */
1092         DBG("success to ipsec_initiate");
1093
1094 done:
1095         /* refer to connect_cb on vpn-provider.c for cb */
1096         if(cb)
1097                 cb(provider, data->connect_user_data, -err);
1098         /* TODO: Does close socket needed? when err is not zero */
1099
1100         return;
1101 }
1102
1103 static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
1104                 GFileMonitorEvent  event_type, gpointer user_data)
1105 {
1106         DBG("file %s", g_file_get_path(file));
1107         if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
1108                 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1109                         DBG("file created: %s", VICI_DEFAULT_URI);
1110                         struct ipsec_private_data *data = user_data;
1111                         vici_connect(data);
1112                         g_object_unref(monitor);
1113                 }
1114         }
1115 }
1116
1117 static void monitor_vici_socket(struct ipsec_private_data *data)
1118 {
1119         GError *error = NULL;
1120         GFile* file;
1121
1122         file = g_file_new_for_path(VICI_DEFAULT_URI);
1123         monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &error);
1124         if (error) {
1125                 connman_error("g_file_monitor_directory failed: %s / %d", error->message, error->code);
1126                 g_error_free(error);
1127                 if(event_data.event_cb)
1128                         event_data.event_cb(event_data.event_user_data, VPN_STATE_FAILURE);
1129                 return;
1130         }
1131         /* TODO :remove this after debug */
1132         DBG("starting to monitor vici socket");
1133         g_signal_connect(monitor, "changed", G_CALLBACK(monitor_changed), data);
1134         g_object_unref(file);
1135 }
1136
1137 static void check_vici_socket(struct ipsec_private_data *data)
1138 {
1139         DBG("data %p", data);
1140         if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1141                 DBG("file exists: %s", VICI_DEFAULT_URI);
1142                 vici_connect(data);
1143         } else {
1144                 monitor_vici_socket(data);
1145         }
1146 }
1147
1148 static void ipsec_died(struct connman_task *task, int exit_code, void *user_data)
1149 {
1150        DBG("task %p exit_code %d", task, exit_code);
1151        unlink(VICI_DEFAULT_URI);
1152        vpn_died(task, exit_code, user_data);
1153 }
1154
1155 static int ipsec_connect(struct vpn_provider *provider,
1156                         struct connman_task *task, const char *if_name,
1157                         vpn_provider_connect_cb_t cb, const char *dbus_sender,
1158                         void *user_data)
1159 {
1160         struct ipsec_private_data *data;
1161         const char *path;
1162         const char *pass;
1163         int err = 0;
1164
1165         data = create_ipsec_private_data(provider, cb, user_data);
1166         if (!data) {
1167                 connman_error("create ipsec private data failed");
1168                 return -ENOMEM;
1169         }
1170         /*
1171          * Start charon daemon using ipsec script of strongSwan.
1172          */
1173         err = connman_task_run(task, ipsec_died, provider, NULL, NULL, NULL);
1174         if (err < 0) {
1175                 connman_error("charon start failed");
1176                 if (cb)
1177                         cb(provider, user_data, err);
1178
1179                 g_free(data);
1180                 return err;
1181         }
1182
1183         path = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1184         pass = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1185         err = extract_cert_info(path, pass, &(data->openssl_data));
1186         if (err < 0) {
1187                 connman_error("extract cert info failed");
1188                 if (cb)
1189                         cb(provider, user_data, err);
1190
1191                 g_free(data);
1192                 return err;
1193         }
1194
1195         check_vici_socket(data);
1196 //      g_usleep(G_USEC_PER_SEC);
1197
1198         return err;
1199 }
1200
1201 static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
1202 {
1203         return 0;
1204 }
1205
1206 static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
1207 {
1208         int i;
1209         const char *option;
1210
1211         DBG("");
1212         /*
1213          * Save IKE connection configurations
1214          */
1215         for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
1216                 option = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
1217                 if (option)
1218                         g_key_file_set_string(keyfile,
1219                                         vpn_provider_get_save_group(provider),
1220                                         ipsec_conn_options[i].cm_opt,
1221                                         option);
1222         }
1223
1224         /*
1225          * Save shared IKE PSK, EAP or XAUTH secret
1226          */
1227         for (i = 0; i < (int)ARRAY_SIZE(ipsec_shared_options); i++) {
1228                 option = vpn_provider_get_string(provider, ipsec_shared_options[i].cm_opt);
1229                 if (option)
1230                         g_key_file_set_string(keyfile,
1231                                         vpn_provider_get_save_group(provider),
1232                                         ipsec_shared_options[i].cm_opt,
1233                                         option);
1234         }
1235
1236         /*
1237          * Save certification
1238          */
1239         for (i = 0; i < (int)ARRAY_SIZE(ipsec_cert_options); i++) {
1240                 option = vpn_provider_get_string(provider, ipsec_cert_options[i].cm_opt);
1241                 if (option)
1242                         g_key_file_set_string(keyfile,
1243                                         vpn_provider_get_save_group(provider),
1244                                         ipsec_cert_options[i].cm_opt,
1245                                         option);
1246         }
1247
1248         /*
1249          * Save private key
1250          */
1251         for (i = 0; i < (int)ARRAY_SIZE(ipsec_pkey_options); i++) {
1252                 option = vpn_provider_get_string(provider, ipsec_pkey_options[i].cm_opt);
1253                 if (option)
1254                         g_key_file_set_string(keyfile,
1255                                         vpn_provider_get_save_group(provider),
1256                                         ipsec_pkey_options[i].cm_opt,
1257                                         option);
1258         }
1259
1260         /*
1261          * Save local certification
1262          */
1263         option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1264         if (option)
1265                 g_key_file_set_string(keyfile,
1266                                 vpn_provider_get_save_group(provider),
1267                                 "IPsec.LocalCerts",
1268                                 option);
1269         option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1270         if (option)
1271                 g_key_file_set_string(keyfile,
1272                                 vpn_provider_get_save_group(provider),
1273                                 "IPsec.LocalCertPass",
1274                                 option);
1275         /*
1276          * Save CA certification directory
1277          */
1278         option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
1279         if (option)
1280                 g_key_file_set_string(keyfile,
1281                                 vpn_provider_get_save_group(provider),
1282                                 "IPsec.CACertsDir",
1283                                 option);
1284
1285         return 0;
1286 }
1287
1288 static void ipsec_disconnect(struct vpn_provider *provider)
1289 {
1290         int err = 0;
1291         /*
1292          * Send the terminate command
1293          */
1294         err = ipsec_terminate(provider);
1295         IPSEC_ERROR_CHECK_RETURN(err, "terminate failed");
1296
1297         err = vici_deinitialize(vici_client);
1298         IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
1299
1300         return;
1301 }
1302
1303 static struct vpn_driver vpn_driver = {
1304         .flags = VPN_FLAG_NO_TUN,
1305         .notify = ipsec_notify,
1306         .set_event_cb = ipsec_set_event_cb,
1307         .connect = ipsec_connect,
1308         .error_code = ipsec_error_code,
1309         .save = ipsec_save,
1310         .disconnect = ipsec_disconnect,
1311 };
1312
1313 static int ipsec_init(void)
1314 {
1315         connection = connman_dbus_get_connection();
1316
1317         event_data.event_cb = NULL;
1318         event_data.event_user_data = NULL;
1319
1320         return vpn_register("ipsec", &vpn_driver, IPSEC);
1321 }
1322
1323 static void ipsec_exit(void)
1324 {
1325         vpn_unregister("ipsec");
1326
1327         dbus_connection_unref(connection);
1328 }
1329
1330 CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
1331         CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)