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.
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.
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
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>
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>
50 #include "../vpn-provider.h"
54 #include "vici-client.h"
56 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
66 static DBusConnection *connection;
67 static VICIClient *vici_client;
68 static GFileMonitor* monitor;
70 struct openssl_private_data {
71 EVP_PKEY *private_key;
73 STACK_OF(X509) *ca_certs;
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;
83 struct ipsec_event_data {
84 vpn_event_callback event_cb;
85 void *event_user_data;
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},
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},
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"},
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},
135 const char *vici_type;
136 } ipsec_pkey_options[] = {
137 {"IPsec.PKeyType", "type"},
138 {"IPsec.PKeyData", "data"},
141 static const char *ikev1_esp_proposals [] ={
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",
165 static const char *ikev2_esp_proposals = "aes256-aes128-sha256-sha1";
167 static const char *ikev2_proposals = "aes256-aes128-sha512-sha384-sha256-sha1-modp2048-modp1536-modp1024";
169 static struct ipsec_event_data event_data;
171 static void init_openssl(void)
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();
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(); */
185 /* Load all digest and cipher algorithms */
186 #if OPENSSL_API_COMPAT < 0x10100000L
187 OpenSSL_add_all_algorithms();
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(); */
195 #if OPENSSL_API_COMPAT < 0x10100000L
196 OPENSSL_config(NULL);
199 /* TODO :remove this after debug */
204 static void deinit_openssl(void)
206 #if OPENSSL_API_COMPAT < 0x10100000L
210 #if OPENSSL_API_COMPAT < 0x10100000L
217 static int print_openssl_error_cb(const char *str, size_t len, void *u)
219 connman_error("%s", str);
223 static void print_openssl_error()
225 ERR_print_errors_cb(print_openssl_error_cb, NULL);
229 static int get_cert_type(const char *path)
231 char *down_str = NULL;
234 down_str = g_ascii_strdown(path, strlen(path));
236 return CERT_TYPE_NONE;
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;
245 cert_type = CERT_TYPE_NONE;
251 static void read_der_file(const char *path, X509 **cert)
255 DBG("der path %s\n", path);
256 fp = fopen(path, "r");
258 connman_error("fopen %s is failed\n", path);
262 *cert = d2i_X509_fp(fp, NULL);
267 static void read_pem_file(const char *path, X509 **cert)
271 DBG("pem path %s\n", path);
272 fp = fopen(path, "r");
274 connman_error("fopen %s is failed\n", path);
278 *cert = PEM_read_X509(fp, cert, NULL, NULL);
283 static void read_pkcs12_file(const char *path, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
288 DBG("pkcs12 path %s\n", path);
289 fp = fopen(path, "r");
291 print_openssl_error();
295 p12 = d2i_PKCS12_fp(fp, NULL);
297 print_openssl_error();
302 if (!PKCS12_parse(p12, pass, pkey, cert, ca)) {
303 print_openssl_error();
312 static char *get_private_key_str(struct openssl_private_data *data)
317 char *private_key_str = NULL;
322 if (!(pkey = data->private_key))
325 bio = BIO_new(BIO_s_mem());
327 print_openssl_error();
331 if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) {
332 print_openssl_error();
337 BIO_get_mem_ptr(bio, &buf_ptr);
339 print_openssl_error();
344 private_key_str = g_try_malloc0(buf_ptr->length + 1);
345 if (!private_key_str) {
346 print_openssl_error();
351 g_strlcpy(private_key_str, buf_ptr->data, buf_ptr->length);
355 return private_key_str;
358 static char *get_cert_str(X509 *cert)
362 char *cert_str = NULL;
367 bio = BIO_new(BIO_s_mem());
369 print_openssl_error();
373 if (!PEM_write_bio_X509_AUX(bio, cert)) {
374 print_openssl_error();
379 BIO_get_mem_ptr(bio, &buf_ptr);
381 print_openssl_error();
386 cert_str = g_try_malloc0(buf_ptr->length + 1);
388 print_openssl_error();
393 g_strlcpy(cert_str, buf_ptr->data, buf_ptr->length);
399 static char * get_local_cert_str(struct openssl_private_data *data)
404 if (!(data->local_cert))
407 return get_cert_str(data->local_cert);
410 int get_ca_cert_num(struct openssl_private_data *data)
412 if(!data || !data->ca_certs)
415 return sk_X509_num(data->ca_certs);
418 static char * get_nth_ca_cert_str(struct openssl_private_data *data, int num)
425 if (!(data->ca_certs))
428 cert = sk_X509_value(data->ca_certs, num);
430 return get_cert_str(cert);
433 static void extract_cert_info(const char *path, const char *pass, struct openssl_private_data *data)
436 /* TODO :remove this after debug */
437 DBG("there's no cert data");
441 switch (get_cert_type(path)) {
443 read_der_file(path, &(data->local_cert));
446 read_pem_file(path, &(data->local_cert));
448 case CERT_TYPE_PKCS12:
449 read_pkcs12_file(path, pass, &(data->private_key), &(data->local_cert), &(data->ca_certs));
458 static void free_openssl_private_data(struct openssl_private_data *data)
463 EVP_PKEY *private_key = data->private_key;
464 X509 *local_cert = data->local_cert;
465 STACK_OF(X509) *ca_certs = data->ca_certs;
468 EVP_PKEY_free(private_key);
471 X509_free(local_cert);
474 sk_X509_pop_free(ca_certs, X509_free);
479 static void free_private_data(struct ipsec_private_data *data)
481 free_openssl_private_data(&(data->openssl_data));
486 static int ipsec_notify(DBusMessage *msg, struct vpn_provider *provider)
491 static void ipsec_set_event_cb(vpn_event_callback event_cb, struct vpn_provider *provider)
493 DBG("set event cb!");
494 event_data.event_cb = event_cb;
495 event_data.event_user_data = provider;
499 static int ipsec_is_same_auth(const char* req, const char* target)
501 if (req == NULL || target == NULL)
503 return (g_strcmp0(req, target) == 0);
506 static int vici_load_cert(const char* type, const char* flag, const char* data)
511 sect = vici_create_section(NULL);
515 vici_add_kv(sect, "type", type, NULL);
516 vici_add_kv(sect, "flag", flag, NULL);
517 vici_add_kv(sect, "data", data, NULL);
519 ret = vici_send_request(vici_client, VICI_CMD_LOAD_CERT, sect);
521 connman_error("vici_send_request failed");
523 vici_destroy_section(sect);
528 static int vici_load_key(const char* type, const char* data)
531 sect = vici_create_section(NULL);
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);
538 connman_error("vici_send_request failed");
540 vici_destroy_section(sect);
545 static void ipsec_add_default_child_sa_data(struct vpn_provider *provider, VICISection *child)
547 const char *version = vpn_provider_get_string(provider, "IPsec.Version");
548 if (g_strcmp0(version, "1") == 0) {
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);
558 vici_add_kvl(child, "esp_proposals", ikev2_esp_proposals, "net");
563 static void ipsec_add_default_conn_data(struct vpn_provider *provider, VICISection *conn)
565 const char *version = vpn_provider_get_string(provider, "IPsec.Version");
566 if (g_strcmp0(version, "1") == 0) {
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);
576 if (g_strcmp0(vpn_provider_get_string(provider, "IPsec.LocalAuth"), "psk") == 0)
577 vici_add_kv(conn, "aggressive", "yes", NULL);
579 vici_add_kvl(conn, "proposals", ikev2_proposals, NULL);
582 vici_add_kvl(conn, "vips", "0.0.0.0", NULL);
587 static int ipsec_load_conn(struct vpn_provider *provider, struct ipsec_private_data *data)
591 const char *subsection;
592 char *local_cert_str;
594 VICISection *children;
598 if (!provider || !data) {
599 connman_error("invalid provider or data");
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);
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);
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);
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);
627 ipsec_add_default_conn_data(provider, conn);
628 ipsec_add_default_child_sa_data(provider, children);
630 ret = vici_send_request(vici_client, VICI_CMD_LOAD_CONN, conn);
632 connman_error("vici_send_request failed");
634 vici_destroy_section(conn);
639 static int ipsec_load_private_data(struct ipsec_private_data *data)
641 char *private_key_str;
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);
658 ca_cert_num = get_ca_cert_num(&(data->openssl_data));
662 for (i = 0; i < ca_cert_num; i++) {
663 /* TODO :remove this after debug */
665 ca_cert_str = get_nth_ca_cert_str(&(data->openssl_data), i);
666 ret = vici_load_cert("X509", "CA", ca_cert_str);
675 static int ipsec_load_shared_psk(struct vpn_provider *provider)
683 connman_error("invalid provider");
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);
694 sect = vici_create_section(NULL);
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);
703 ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
705 connman_error("vici_send_request failed");
707 vici_destroy_section(sect);
712 static int ipsec_load_shared_xauth(struct vpn_provider *provider)
720 connman_error("invalid provider");
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);
731 sect = vici_create_section(NULL);
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);
737 ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
739 connman_error("vici_send_request failed");
741 vici_destroy_section(sect);
746 static char *load_file_from_path(const char *path)
751 size_t file_size = 0;
752 char *file_buff = NULL;
755 connman_error("File path is NULL\n");
759 fp = fopen(path, "rb");
761 connman_error("fopen %s is failed\n", path);
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");
775 if (fread(file_buff, 1, file_size, fp) != file_size) {
776 connman_error("file size not matched\n");
785 static int ipsec_load_key(struct vpn_provider *provider)
794 connman_error("invalid provider");
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);
805 data = load_file_from_path(path);
809 sect = vici_create_section(NULL);
813 vici_add_kv(sect, "type", type, NULL);
814 vici_add_kv(sect, "data", data, NULL);
816 ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
818 connman_error("vici_send_request failed");
820 vici_destroy_section(sect);
826 static int ipsec_initiate(struct vpn_provider *provider)
831 sect = vici_create_section(NULL);
835 vici_add_kv(sect, "child", "net", NULL);
836 ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
838 connman_error("vici_send_request failed");
840 vici_destroy_section(sect);
845 static int ipsec_load_cert(struct vpn_provider *provider)
850 const char *local_auth_type;
851 const char *remote_auth_type;
855 connman_error("invalid provider");
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");
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");
877 ret = vici_load_cert(type, flag, data);
879 connman_error("failed to load cert");
886 static int ipsec_terminate(struct vpn_provider *provider)
891 sect = vici_create_section(NULL);
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);
900 connman_error("vici_send_request failed");
902 vici_destroy_section(sect);
907 static void request_reply_cb(int err, void *user_data)
909 struct ipsec_private_data *data;
911 data = (struct ipsec_private_data *)user_data;
912 DBG("request reply cb");
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? */
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);
925 free_private_data(data);
928 static void ipsec_vici_event_cb(VICIClientEvent event, void *user_data)
930 struct vpn_provider *provider;
932 provider = (struct vpn_provider *)user_data;
934 DBG("Invalid user data");
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);
945 DBG("Unknown event");
951 static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
952 vpn_provider_connect_cb_t cb, void* user_data)
954 struct ipsec_private_data *data;
955 data = g_try_new0(struct ipsec_private_data, 1);
957 connman_error("out of memory");
963 data->provider = provider;
964 data->connect_cb = cb;
965 data->connect_user_data = user_data;
969 static void vici_connect(struct ipsec_private_data *data)
971 struct vpn_provider *provider = NULL;
972 vpn_provider_connect_cb_t cb = NULL;
976 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
978 provider = data->provider;
979 cb = data->connect_cb;
980 if (!provider || !cb)
981 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
983 DBG("data %p, provider %p", data, provider);
986 * Initialize vici client
988 err = vici_initialize(&vici_client);
989 IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
991 /* TODO :remove this after debug */
992 DBG("success to initialize vici socket");
994 vici_set_request_reply_cb(vici_client, (vici_request_reply_cb)request_reply_cb, data);
996 * Sets child-updown event
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");
1001 /* TODO :remove this after debug */
1002 DBG("success to vici_set_event_cb");
1004 * Send the load-conn command
1006 err = ipsec_load_conn(provider, data);
1007 IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
1009 /* TODO :remove this after debug */
1010 DBG("success to ipsec_load_conn");
1012 err = ipsec_load_private_data(data);
1013 IPSEC_ERROR_CHECK_GOTO(err, done, "load private data failed");
1015 /* TODO :remove this after debug */
1016 DBG("success to ipsec_load_private_data");
1019 * Send the load-shared command for PSK
1021 err = ipsec_load_shared_psk(provider);
1022 IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
1024 /* TODO :remove this after debug */
1025 DBG("success to ipsec_load_shared_psk");
1028 * Send the load-shared command for XAUTH
1030 err = ipsec_load_shared_xauth(provider);
1031 IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
1033 /* TODO :remove this after debug */
1034 DBG("success to ipsec_load_shared_xauth");
1036 * Send the load-cert command
1038 err = ipsec_load_cert(provider);
1039 IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
1041 /* TODO :remove this after debug */
1042 DBG("success to ipsec_load_cert");
1045 * Send the load-key command
1047 err = ipsec_load_key(provider);
1048 IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
1050 /* TODO :remove this after debug */
1051 DBG("success to ipsec_load_cert");
1053 * Send the initiate command
1055 err = ipsec_initiate(provider);
1056 IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
1058 /* TODO :remove this after debug */
1059 DBG("success to ipsec_initiate");
1062 /* refer to connect_cb on vpn-provider.c for cb */
1064 cb(provider, data->connect_user_data, -err);
1065 /* TODO: Does close socket needed? when err is not zero */
1070 static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
1071 GFileMonitorEvent event_type, gpointer user_data)
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;
1079 g_object_unref(monitor);
1084 static void monitor_vici_socket(struct ipsec_private_data *data)
1086 GError *error = NULL;
1089 file = g_file_new_for_path(VICI_DEFAULT_URI);
1090 monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &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);
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);
1104 static void check_vici_socket(struct ipsec_private_data *data)
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);
1111 monitor_vici_socket(data);
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,
1120 struct ipsec_private_data *data;
1125 data = create_ipsec_private_data(provider, cb, user_data);
1127 connman_error("create ipsec private data failed");
1131 * Start charon daemon using ipsec script of strongSwan.
1133 err = connman_task_run(task, vpn_died, provider, NULL, NULL, NULL);
1135 connman_error("charon start failed");
1137 cb(provider, user_data, err);
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));
1147 check_vici_socket(data);
1148 // g_usleep(G_USEC_PER_SEC);
1153 static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
1158 static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
1165 * Save IKE connection configurations
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);
1170 g_key_file_set_string(keyfile,
1171 vpn_provider_get_save_group(provider),
1172 ipsec_conn_options[i].cm_opt,
1177 * Save shared IKE PSK, EAP or XAUTH secret
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);
1182 g_key_file_set_string(keyfile,
1183 vpn_provider_get_save_group(provider),
1184 ipsec_shared_options[i].cm_opt,
1189 * Save certification
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);
1194 g_key_file_set_string(keyfile,
1195 vpn_provider_get_save_group(provider),
1196 ipsec_cert_options[i].cm_opt,
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);
1206 g_key_file_set_string(keyfile,
1207 vpn_provider_get_save_group(provider),
1208 ipsec_pkey_options[i].cm_opt,
1213 * Save local certification
1215 option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1217 g_key_file_set_string(keyfile,
1218 vpn_provider_get_save_group(provider),
1221 option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1223 g_key_file_set_string(keyfile,
1224 vpn_provider_get_save_group(provider),
1225 "IPsec.LocalCertPass",
1228 * Save CA certification directory
1230 option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
1232 g_key_file_set_string(keyfile,
1233 vpn_provider_get_save_group(provider),
1240 static void ipsec_disconnect(struct vpn_provider *provider)
1244 * Send the terminate command
1246 err = ipsec_terminate(provider);
1247 IPSEC_ERROR_CHECK_RETURN(err, "terminate failed");
1249 err = vici_deinitialize(vici_client);
1250 IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
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,
1262 .disconnect = ipsec_disconnect,
1265 static int ipsec_init(void)
1267 connection = connman_dbus_get_connection();
1269 event_data.event_cb = NULL;
1270 event_data.event_user_data = NULL;
1272 return vpn_register("ipsec", &vpn_driver, IPSEC);
1275 static void ipsec_exit(void)
1277 vpn_unregister("ipsec");
1279 dbus_connection_unref(connection);
1282 CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
1283 CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)