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 int read_der_file(const char *path, X509 **cert)
257 /* TODO :remove this after debug */
258 DBG("there's no cert data");
262 DBG("der path %s\n", path);
263 fp = fopen(path, "r");
265 connman_error("Failed to open file");
269 *cert = d2i_X509_fp(fp, NULL);
271 connman_error("Failed to read der file");
279 static int read_pem_file(const char *path, X509 **cert)
285 /* TODO :remove this after debug */
286 DBG("there's no cert data");
290 DBG("pem path %s\n", path);
291 fp = fopen(path, "r");
293 connman_error("Failed to open file");
297 *cert = PEM_read_X509(fp, cert, NULL, NULL);
299 connman_error("Failed to read pem file");
307 static int read_pkcs12_file(const char *path, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
313 if(!path || !pass || !pkey || !cert || !ca) {
314 /* TODO :remove this after debug */
315 DBG("there's no cert data");
319 DBG("pkcs12 path %s\n", path);
320 fp = fopen(path, "r");
322 connman_error("Failed to open file");
326 p12 = d2i_PKCS12_fp(fp, NULL);
328 connman_error("Failed to open pkcs12");
333 if (!PKCS12_parse(p12, pass, pkey, cert, ca)) {
334 connman_error("Failed to parse pkcs12");
344 static char *get_private_key_str(struct openssl_private_data *data)
349 char *private_key_str = NULL;
354 if (!(pkey = data->private_key))
357 bio = BIO_new(BIO_s_mem());
359 print_openssl_error();
363 if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) {
364 print_openssl_error();
369 BIO_get_mem_ptr(bio, &buf_ptr);
371 print_openssl_error();
376 private_key_str = g_try_malloc0(buf_ptr->length + 1);
377 if (!private_key_str) {
378 print_openssl_error();
383 g_strlcpy(private_key_str, buf_ptr->data, buf_ptr->length);
387 return private_key_str;
390 static char *get_cert_str(X509 *cert)
394 char *cert_str = NULL;
399 bio = BIO_new(BIO_s_mem());
401 print_openssl_error();
405 if (!PEM_write_bio_X509_AUX(bio, cert)) {
406 print_openssl_error();
411 BIO_get_mem_ptr(bio, &buf_ptr);
413 print_openssl_error();
418 cert_str = g_try_malloc0(buf_ptr->length + 1);
420 print_openssl_error();
425 g_strlcpy(cert_str, buf_ptr->data, buf_ptr->length);
431 static char * get_local_cert_str(struct openssl_private_data *data)
436 if (!(data->local_cert))
439 return get_cert_str(data->local_cert);
442 int get_ca_cert_num(struct openssl_private_data *data)
444 if(!data || !data->ca_certs)
447 return sk_X509_num(data->ca_certs);
450 static char * get_nth_ca_cert_str(struct openssl_private_data *data, int num)
457 if (!(data->ca_certs))
460 cert = sk_X509_value(data->ca_certs, num);
462 return get_cert_str(cert);
465 static int extract_cert_info(const char *path, const char *pass, struct openssl_private_data *data)
469 /* TODO :remove this after debug */
470 DBG("there's no cert data");
474 switch (get_cert_type(path)) {
476 err = read_der_file(path, &(data->local_cert));
479 err = read_pem_file(path, &(data->local_cert));
481 case CERT_TYPE_PKCS12:
482 err = read_pkcs12_file(path, pass, &(data->private_key), &(data->local_cert), &(data->ca_certs));
491 static void free_openssl_private_data(struct openssl_private_data *data)
496 EVP_PKEY *private_key = data->private_key;
497 X509 *local_cert = data->local_cert;
498 STACK_OF(X509) *ca_certs = data->ca_certs;
501 EVP_PKEY_free(private_key);
504 X509_free(local_cert);
507 sk_X509_pop_free(ca_certs, X509_free);
512 static void free_private_data(struct ipsec_private_data *data)
514 free_openssl_private_data(&(data->openssl_data));
519 static int ipsec_notify(DBusMessage *msg, struct vpn_provider *provider)
524 static void ipsec_set_event_cb(vpn_event_callback event_cb, struct vpn_provider *provider)
526 DBG("set event cb!");
527 event_data.event_cb = event_cb;
528 event_data.event_user_data = provider;
532 static int ipsec_is_same_auth(const char* req, const char* target)
534 if (req == NULL || target == NULL)
536 return (g_strcmp0(req, target) == 0);
539 static int vici_load_cert(const char* type, const char* flag, const char* data)
544 sect = vici_create_section(NULL);
548 vici_add_kv(sect, "type", type, NULL);
549 vici_add_kv(sect, "flag", flag, NULL);
550 vici_add_kv(sect, "data", data, NULL);
552 ret = vici_send_request(vici_client, VICI_CMD_LOAD_CERT, sect);
554 connman_error("vici_send_request failed");
556 vici_destroy_section(sect);
561 static int vici_load_key(const char* type, const char* data)
564 sect = vici_create_section(NULL);
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);
571 connman_error("vici_send_request failed");
573 vici_destroy_section(sect);
578 static void ipsec_add_default_child_sa_data(struct vpn_provider *provider, VICISection *child)
580 const char *version = vpn_provider_get_string(provider, "IPsec.Version");
581 if (g_strcmp0(version, "1") == 0) {
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);
591 vici_add_kvl(child, "esp_proposals", ikev2_esp_proposals, "net");
596 static void ipsec_add_default_conn_data(struct vpn_provider *provider, VICISection *conn)
598 const char *version = vpn_provider_get_string(provider, "IPsec.Version");
599 if (g_strcmp0(version, "1") == 0) {
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);
609 if (g_strcmp0(vpn_provider_get_string(provider, "IPsec.LocalAuth"), "psk") == 0)
610 vici_add_kv(conn, "aggressive", "yes", NULL);
612 vici_add_kvl(conn, "proposals", ikev2_proposals, NULL);
615 vici_add_kvl(conn, "vips", "0.0.0.0", NULL);
620 static int ipsec_load_conn(struct vpn_provider *provider, struct ipsec_private_data *data)
624 const char *subsection;
625 char *local_cert_str;
627 VICISection *children;
631 if (!provider || !data) {
632 connman_error("invalid provider or data");
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);
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);
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);
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);
660 ipsec_add_default_conn_data(provider, conn);
661 ipsec_add_default_child_sa_data(provider, children);
663 ret = vici_send_request(vici_client, VICI_CMD_LOAD_CONN, conn);
665 connman_error("vici_send_request failed");
667 vici_destroy_section(conn);
672 static int ipsec_load_private_data(struct ipsec_private_data *data)
674 char *private_key_str;
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);
691 ca_cert_num = get_ca_cert_num(&(data->openssl_data));
695 for (i = 0; i < ca_cert_num; i++) {
696 /* TODO :remove this after debug */
698 ca_cert_str = get_nth_ca_cert_str(&(data->openssl_data), i);
699 ret = vici_load_cert("X509", "CA", ca_cert_str);
708 static int ipsec_load_shared_psk(struct vpn_provider *provider)
716 connman_error("invalid provider");
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);
727 sect = vici_create_section(NULL);
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);
736 ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
738 connman_error("vici_send_request failed");
740 vici_destroy_section(sect);
745 static int ipsec_load_shared_xauth(struct vpn_provider *provider)
753 connman_error("invalid provider");
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);
764 sect = vici_create_section(NULL);
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);
770 ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
772 connman_error("vici_send_request failed");
774 vici_destroy_section(sect);
779 static char *load_file_from_path(const char *path)
784 size_t file_size = 0;
785 char *file_buff = NULL;
788 connman_error("File path is NULL\n");
792 fp = fopen(path, "rb");
794 connman_error("fopen %s is failed\n", path);
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");
808 if (fread(file_buff, 1, file_size, fp) != file_size) {
809 connman_error("file size not matched\n");
818 static int ipsec_load_key(struct vpn_provider *provider)
827 connman_error("invalid provider");
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);
838 data = load_file_from_path(path);
842 sect = vici_create_section(NULL);
848 vici_add_kv(sect, "type", type, NULL);
849 vici_add_kv(sect, "data", data, NULL);
851 ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
853 connman_error("vici_send_request failed");
855 vici_destroy_section(sect);
861 static int ipsec_initiate(struct vpn_provider *provider)
866 sect = vici_create_section(NULL);
870 vici_add_kv(sect, "child", "net", NULL);
871 ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
873 connman_error("vici_send_request failed");
875 vici_destroy_section(sect);
880 static int ipsec_load_cert(struct vpn_provider *provider)
885 const char *local_auth_type;
886 const char *remote_auth_type;
890 connman_error("invalid provider");
894 local_auth_type = vpn_provider_get_string(provider, "IPsec.LocalAuth");
895 remote_auth_type = vpn_provider_get_string(provider, "IPsec.RemoteAuth");
896 if (!ipsec_is_same_auth(local_auth_type, "pubkey") &&
897 !ipsec_is_same_auth(remote_auth_type, "pubkey")) {
898 DBG("invalid auth type");
902 type = vpn_provider_get_string(provider, "IPsec.CertType");
903 flag = vpn_provider_get_string(provider, "IPsec.CertFlag");
904 data = load_file_from_path(vpn_provider_get_string(provider, "IPsec.CertData"));
905 DBG("CertType: %s, CertFalg: %s,CertData: %s", type, flag, data);
906 if (!type || ! flag || !data) {
907 connman_error("invalid certification information");
912 ret = vici_load_cert(type, flag, data);
914 connman_error("failed to load cert");
921 static int ipsec_terminate(struct vpn_provider *provider)
926 sect = vici_create_section(NULL);
930 vici_add_kv(sect, "child", "net", NULL);
931 vici_add_kv(sect, "ike", vpn_provider_get_string(provider, "Name"), NULL);
932 vici_add_kv(sect, "timeout", "-1", NULL);
933 ret = vici_send_request(vici_client, VICI_CMD_TERMINATE, sect);
935 connman_error("vici_send_request failed");
937 vici_destroy_section(sect);
942 static void request_reply_cb(int err, void *user_data)
944 struct ipsec_private_data *data;
946 data = (struct ipsec_private_data *)user_data;
947 DBG("request reply cb");
950 if (event_data.event_cb)
951 event_data.event_cb(event_data.event_user_data, VPN_STATE_FAILURE);
952 /* TODO: Does close socket needed? */
954 DBG("Series of requests are succeeded");
955 /* TODO: Not sure about below */
956 if (event_data.event_cb)
957 event_data.event_cb(event_data.event_user_data, VPN_STATE_CONNECT);
960 free_private_data(data);
963 static void ipsec_vici_event_cb(VICIClientEvent event, void *user_data)
965 struct vpn_provider *provider;
967 provider = (struct vpn_provider *)user_data;
969 DBG("Invalid user data");
973 if(event == VICI_EVENT_CHILD_UP) {
974 if (event_data.event_cb)
975 event_data.event_cb(event_data.event_user_data, VPN_STATE_READY);
976 } else if (event == VICI_EVENT_CHILD_DOWN) {
977 if (event_data.event_cb)
978 event_data.event_cb(event_data.event_user_data, VPN_STATE_DISCONNECT);
980 DBG("Unknown event");
986 static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
987 vpn_provider_connect_cb_t cb, void* user_data)
989 struct ipsec_private_data *data;
990 data = g_try_new0(struct ipsec_private_data, 1);
992 connman_error("out of memory");
998 data->provider = provider;
999 data->connect_cb = cb;
1000 data->connect_user_data = user_data;
1004 static void vici_connect(struct ipsec_private_data *data)
1006 struct vpn_provider *provider = NULL;
1007 vpn_provider_connect_cb_t cb = NULL;
1011 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
1013 provider = data->provider;
1014 cb = data->connect_cb;
1015 if (!provider || !cb)
1016 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
1018 DBG("data %p, provider %p", data, provider);
1021 * Initialize vici client
1023 err = vici_initialize(&vici_client);
1024 IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
1026 /* TODO :remove this after debug */
1027 DBG("success to initialize vici socket");
1029 vici_set_request_reply_cb(vici_client, (vici_request_reply_cb)request_reply_cb, data);
1031 * Sets child-updown event
1033 err = vici_set_event_cb(vici_client, (vici_event_cb)ipsec_vici_event_cb, provider);
1034 IPSEC_ERROR_CHECK_GOTO(err, done, "register event failed");
1036 /* TODO :remove this after debug */
1037 DBG("success to vici_set_event_cb");
1039 * Send the load-conn command
1041 err = ipsec_load_conn(provider, data);
1042 IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
1044 /* TODO :remove this after debug */
1045 DBG("success to ipsec_load_conn");
1047 err = ipsec_load_private_data(data);
1048 IPSEC_ERROR_CHECK_GOTO(err, done, "load private data failed");
1050 /* TODO :remove this after debug */
1051 DBG("success to ipsec_load_private_data");
1054 * Send the load-shared command for PSK
1056 err = ipsec_load_shared_psk(provider);
1057 IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
1059 /* TODO :remove this after debug */
1060 DBG("success to ipsec_load_shared_psk");
1063 * Send the load-shared command for XAUTH
1065 err = ipsec_load_shared_xauth(provider);
1066 IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
1068 /* TODO :remove this after debug */
1069 DBG("success to ipsec_load_shared_xauth");
1071 * Send the load-cert command
1073 err = ipsec_load_cert(provider);
1074 IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
1076 /* TODO :remove this after debug */
1077 DBG("success to ipsec_load_cert");
1080 * Send the load-key command
1082 err = ipsec_load_key(provider);
1083 IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
1085 /* TODO :remove this after debug */
1086 DBG("success to ipsec_load_cert");
1088 * Send the initiate command
1090 err = ipsec_initiate(provider);
1091 IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
1093 /* TODO :remove this after debug */
1094 DBG("success to ipsec_initiate");
1097 /* refer to connect_cb on vpn-provider.c for cb */
1099 cb(provider, data->connect_user_data, -err);
1100 /* TODO: Does close socket needed? when err is not zero */
1105 static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
1106 GFileMonitorEvent event_type, gpointer user_data)
1108 DBG("file %s", g_file_get_path(file));
1109 if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
1110 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1111 DBG("file created: %s", VICI_DEFAULT_URI);
1112 struct ipsec_private_data *data = user_data;
1114 g_object_unref(monitor);
1119 static void monitor_vici_socket(struct ipsec_private_data *data)
1121 GError *error = NULL;
1124 file = g_file_new_for_path(VICI_DEFAULT_URI);
1125 monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &error);
1127 connman_error("g_file_monitor_directory failed: %s / %d", error->message, error->code);
1128 g_error_free(error);
1129 if(event_data.event_cb)
1130 event_data.event_cb(event_data.event_user_data, VPN_STATE_FAILURE);
1133 /* TODO :remove this after debug */
1134 DBG("starting to monitor vici socket");
1135 g_signal_connect(monitor, "changed", G_CALLBACK(monitor_changed), data);
1136 g_object_unref(file);
1139 static void check_vici_socket(struct ipsec_private_data *data)
1141 DBG("data %p", data);
1142 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1143 DBG("file exists: %s", VICI_DEFAULT_URI);
1146 monitor_vici_socket(data);
1150 static void ipsec_died(struct connman_task *task, int exit_code, void *user_data)
1152 DBG("task %p exit_code %d", task, exit_code);
1153 unlink(VICI_DEFAULT_URI);
1154 vpn_died(task, exit_code, user_data);
1157 static int ipsec_connect(struct vpn_provider *provider,
1158 struct connman_task *task, const char *if_name,
1159 vpn_provider_connect_cb_t cb, const char *dbus_sender,
1162 struct ipsec_private_data *data;
1167 data = create_ipsec_private_data(provider, cb, user_data);
1169 connman_error("create ipsec private data failed");
1173 * Start charon daemon using ipsec script of strongSwan.
1175 err = connman_task_run(task, ipsec_died, provider, NULL, NULL, NULL);
1177 connman_error("charon start failed");
1179 cb(provider, user_data, err);
1185 path = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1186 pass = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1187 err = extract_cert_info(path, pass, &(data->openssl_data));
1189 connman_error("extract cert info failed");
1191 cb(provider, user_data, err);
1197 check_vici_socket(data);
1198 // g_usleep(G_USEC_PER_SEC);
1203 static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
1208 static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
1215 * Save IKE connection configurations
1217 for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
1218 option = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
1220 g_key_file_set_string(keyfile,
1221 vpn_provider_get_save_group(provider),
1222 ipsec_conn_options[i].cm_opt,
1227 * Save shared IKE PSK, EAP or XAUTH secret
1229 for (i = 0; i < (int)ARRAY_SIZE(ipsec_shared_options); i++) {
1230 option = vpn_provider_get_string(provider, ipsec_shared_options[i].cm_opt);
1232 g_key_file_set_string(keyfile,
1233 vpn_provider_get_save_group(provider),
1234 ipsec_shared_options[i].cm_opt,
1239 * Save certification
1241 for (i = 0; i < (int)ARRAY_SIZE(ipsec_cert_options); i++) {
1242 option = vpn_provider_get_string(provider, ipsec_cert_options[i].cm_opt);
1244 g_key_file_set_string(keyfile,
1245 vpn_provider_get_save_group(provider),
1246 ipsec_cert_options[i].cm_opt,
1253 for (i = 0; i < (int)ARRAY_SIZE(ipsec_pkey_options); i++) {
1254 option = vpn_provider_get_string(provider, ipsec_pkey_options[i].cm_opt);
1256 g_key_file_set_string(keyfile,
1257 vpn_provider_get_save_group(provider),
1258 ipsec_pkey_options[i].cm_opt,
1263 * Save local certification
1265 option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1267 g_key_file_set_string(keyfile,
1268 vpn_provider_get_save_group(provider),
1271 option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1273 g_key_file_set_string(keyfile,
1274 vpn_provider_get_save_group(provider),
1275 "IPsec.LocalCertPass",
1278 * Save CA certification directory
1280 option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
1282 g_key_file_set_string(keyfile,
1283 vpn_provider_get_save_group(provider),
1290 static void ipsec_disconnect(struct vpn_provider *provider)
1294 * Send the terminate command
1296 err = ipsec_terminate(provider);
1297 IPSEC_ERROR_CHECK_RETURN(err, "terminate failed");
1299 err = vici_deinitialize(vici_client);
1300 IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
1305 static struct vpn_driver vpn_driver = {
1306 .flags = VPN_FLAG_NO_TUN,
1307 .notify = ipsec_notify,
1308 .set_event_cb = ipsec_set_event_cb,
1309 .connect = ipsec_connect,
1310 .error_code = ipsec_error_code,
1312 .disconnect = ipsec_disconnect,
1315 static int ipsec_init(void)
1317 connection = connman_dbus_get_connection();
1319 event_data.event_cb = NULL;
1320 event_data.event_user_data = NULL;
1322 return vpn_register("ipsec", &vpn_driver, IPSEC);
1325 static void ipsec_exit(void)
1327 vpn_unregister("ipsec");
1329 dbus_connection_unref(connection);
1332 CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
1333 CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)