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 cb;
87 const char *subsection;
88 vici_add_element add_elem;
89 } ipsec_conn_options[] = {
90 {"IPsec.Version", "version", NULL, vici_add_kv},
91 {"IPsec.LeftAddrs", "local_addrs", NULL, vici_add_kvl},
92 {"IPsec.RightAddrs", "remote_addrs", NULL, vici_add_kvl},
94 {"IPsec.LocalAuth", "auth", "local", vici_add_kv},
95 {"IPsec.LocalID", "id", "local", vici_add_kv},
96 {"IPsec.LocalXauthID", "xauth_id", "local", vici_add_kv},
97 {"IPsec.LocalXauthAuth", "auth", "local-xauth", vici_add_kv},
98 {"IPsec.LocalXauthXauthID", "xauth_id", "local-xauth", vici_add_kv},
99 {"IPsec.RemoteAuth", "auth", "remote", vici_add_kv},
100 {"IPsec.RemoteID", "id", "remote", vici_add_kv},
101 {"IPsec.RemoteXauthID", "xauth_id", "remote", vici_add_kv},
102 {"IPsec.RemoteXauthAuth", "auth", "remote-xauth", vici_add_kv},
103 {"IPsec.RemoteXauthXauthID", "xauth_id", "remote-xauth", vici_add_kv},
104 {"IPsec.ChildrenLocalTS", "local_ts", "children", vici_add_kvl},
105 {"IPsec.ChildrenRemoteTS", "remote_ts", "children", vici_add_kvl},
110 const char *vici_type;
111 } ipsec_shared_options[] = {
112 {"IPsec.IKEData", "data"},
113 {"IPsec.IKEOwners", "owners"},
114 {"IPsec.XauthData", "data"},
115 {"IPsec.XauthOwners", "owners"},
120 const char *vici_type;
121 const char *vici_flag;
122 } ipsec_cert_options[] = {
123 {"IPsec.CertType", "type", NULL},
124 {"IPsec.CertFlag", "flag", NULL},
125 {"IPsec.CertData", "data", NULL},
126 {"IPsec.CertPass", "data", NULL},
131 const char *vici_type;
132 } ipsec_pkey_options[] = {
133 {"IPsec.PKeyType", "type"},
134 {"IPsec.PKeyData", "data"},
137 static const char *ikev1_esp_proposals [] ={
149 static const char *ikev1_proposals [] ={
150 "aes256-sha256-modp1024",
151 "aes128-sha256-modp1024",
152 "aes256-sha1-modp1024",
153 "aes128-sha1-modp1024",
154 "aes256-md5-modp1024",
155 "aes128-md5-modp1024",
156 "3des-sha1-modp1024",
161 static const char *ikev2_esp_proposals = "aes256-aes128-sha512-sha384-sha256-sha1-modp2048-modp1536-modp1024";
163 static const char *ikev2_proposals = "aes256-aes128-sha512-sha384-sha256-sha1-modp2048-modp1536-modp1024";
165 static void init_openssl(void)
167 /* Load the human readable error strings for libcrypto */
168 #if OPENSSL_API_COMPAT < 0x10100000L
169 /* TODO :remove this after debug */
170 DBG("openssl version is under 1.01");
171 ERR_load_crypto_strings();
173 /* As of version 1.1.0 OpenSSL will automatically allocate
174 * all resources that it needs so no explicit initialisation
175 * is required. Similarly it will also automatically
176 * deinitialise as required. */
177 /* OPENSSL_init_crypto(); */
179 /* Load all digest and cipher algorithms */
180 #if OPENSSL_API_COMPAT < 0x10100000L
181 OpenSSL_add_all_algorithms();
183 /* As of version 1.1.0 OpenSSL will automatically allocate
184 * all resources that it needs so no explicit initialisation
185 * is required. Similarly it will also automatically
186 * deinitialise as required. */
187 /* OPENSSL_init_crypto(); */
189 #if OPENSSL_API_COMPAT < 0x10100000L
190 OPENSSL_config(NULL);
193 /* TODO :remove this after debug */
198 static void deinit_openssl(void)
200 #if OPENSSL_API_COMPAT < 0x10100000L
204 #if OPENSSL_API_COMPAT < 0x10100000L
211 static int print_openssl_error_cb(const char *str, size_t len, void *u)
213 connman_error("%s", str);
217 static void print_openssl_error()
219 ERR_print_errors_cb(print_openssl_error_cb, NULL);
223 static int get_cert_type(const char *path)
225 char *down_str = NULL;
228 down_str = g_ascii_strdown(path, strlen(path));
230 return CERT_TYPE_NONE;
232 if(g_str_has_suffix(down_str, ".pem"))
233 cert_type = CERT_TYPE_PEM;
234 else if (g_str_has_suffix(down_str, ".der") || g_str_has_suffix(down_str, ".crt"))
235 cert_type = CERT_TYPE_DER;
236 else if (g_str_has_suffix(down_str, ".p12") || g_str_has_suffix(down_str, ".pfx"))
237 cert_type = CERT_TYPE_PKCS12;
239 cert_type = CERT_TYPE_NONE;
245 static void read_der_file(const char *path, X509 **cert)
249 DBG("der path %s\n", path);
250 fp = fopen(path, "r");
251 *cert = d2i_X509_fp(fp, NULL);
256 static void read_pem_file(const char *path, X509 **cert)
260 DBG("pem path %s\n", path);
261 fp = fopen(path, "r");
262 *cert = PEM_read_X509(fp, cert, NULL, NULL);
267 static void read_pkcs12_file(const char *path, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
272 DBG("pkcs12 path %s\n", path);
273 fp = fopen(path, "r");
275 print_openssl_error();
279 p12 = d2i_PKCS12_fp(fp, NULL);
281 print_openssl_error();
286 if (!PKCS12_parse(p12, pass, pkey, cert, ca)) {
287 print_openssl_error();
296 static char *get_private_key_str(struct openssl_private_data *data)
301 char *private_key_str = NULL;
306 if (!(pkey = data->private_key))
309 bio = BIO_new(BIO_s_mem());
311 print_openssl_error();
315 if (!PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, NULL, NULL)) {
316 print_openssl_error();
321 BIO_get_mem_ptr(bio, &buf_ptr);
323 print_openssl_error();
328 private_key_str = g_try_malloc0(buf_ptr->length + 1);
329 if (!private_key_str) {
330 print_openssl_error();
335 g_strlcpy(private_key_str, buf_ptr->data, buf_ptr->length);
339 return private_key_str;
342 static char *get_cert_str(X509 *cert)
346 char *cert_str = NULL;
351 bio = BIO_new(BIO_s_mem());
353 print_openssl_error();
357 if (!PEM_write_bio_X509_AUX(bio, cert)) {
358 print_openssl_error();
363 BIO_get_mem_ptr(bio, &buf_ptr);
365 print_openssl_error();
370 cert_str = g_try_malloc0(buf_ptr->length + 1);
372 print_openssl_error();
377 g_strlcpy(cert_str, buf_ptr->data, buf_ptr->length);
383 static char * get_local_cert_str(struct openssl_private_data *data)
388 if (!(data->local_cert))
391 return get_cert_str(data->local_cert);
394 int get_ca_cert_num(struct openssl_private_data *data)
396 if(!data || !data->ca_certs)
399 return sk_X509_num(data->ca_certs);
402 static char * get_nth_ca_cert_str(struct openssl_private_data *data, int num)
409 if (!(data->ca_certs))
412 cert = sk_X509_value(data->ca_certs, num);
414 return get_cert_str(cert);
417 static void extract_cert_info(const char *path, const char *pass, struct openssl_private_data *data)
420 /* TODO :remove this after debug */
421 DBG("there's no cert data");
425 switch (get_cert_type(path)) {
427 read_der_file(path, &(data->local_cert));
430 read_pem_file(path, &(data->local_cert));
432 case CERT_TYPE_PKCS12:
433 read_pkcs12_file(path, pass, &(data->private_key), &(data->local_cert), &(data->ca_certs));
442 static void free_openssl_private_data(struct openssl_private_data *data)
447 EVP_PKEY *private_key = data->private_key;
448 X509 *local_cert = data->local_cert;
449 STACK_OF(X509) *ca_certs = data->ca_certs;
452 EVP_PKEY_free(private_key);
455 X509_free(local_cert);
458 sk_X509_pop_free(ca_certs, X509_free);
463 static void free_private_data(struct ipsec_private_data *data)
465 free_openssl_private_data(&(data->openssl_data));
470 static int ipsec_notify(DBusMessage *msg, struct vpn_provider *provider)
475 static int ipsec_is_same_auth(const char* req, const char* target)
477 if (req == NULL || target == NULL)
479 return (g_strcmp0(req, target) == 0);
482 static int vici_load_cert(const char* type, const char* flag, const char* data)
487 sect = vici_create_section(NULL);
491 vici_add_kv(sect, "type", type, NULL);
492 vici_add_kv(sect, "flag", flag, NULL);
493 vici_add_kv(sect, "data", data, NULL);
495 ret = vici_send_request(vici_client, VICI_CMD_LOAD_CERT, sect);
497 connman_error("vici_send_request failed");
499 vici_destroy_section(sect);
504 static int vici_load_key(const char* type, const char* data)
507 sect = vici_create_section(NULL);
510 vici_add_kv(sect, "type", type, NULL);
511 vici_add_kv(sect, "data", data, NULL);
512 ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
514 connman_error("vici_send_request failed");
516 vici_destroy_section(sect);
521 static void ipsec_add_default_child_sa_data(struct vpn_provider *provider, VICISection *child)
523 const char *version = vpn_provider_get_string(provider, "IPsec.Version");
524 if (g_strcmp0(version, "1") == 0) {
528 for (list = NULL; ikev1_esp_proposals[i] != NULL; i++)
529 list = g_slist_append(list, g_strdup(ikev1_esp_proposals[i]));
530 vici_add_list(child, "esp_proposals", list, "net");
531 g_slist_free_full(list, g_free);
534 vici_add_kvl(child, "esp_proposals", ikev2_esp_proposals, "net");
539 static void ipsec_add_default_conn_data(struct vpn_provider *provider, VICISection *conn)
541 const char *version = vpn_provider_get_string(provider, "IPsec.Version");
542 if (g_strcmp0(version, "1") == 0) {
546 for (list = NULL; ikev1_proposals[i] != NULL; i++)
547 list = g_slist_append(list, g_strdup(ikev1_proposals[i]));
548 vici_add_list(conn, "proposals", list, NULL);
549 g_slist_free_full(list, g_free);
552 if (g_strcmp0(vpn_provider_get_string(provider, "IPsec.LocalAuth"), "psk") == 0)
553 vici_add_kv(conn, "aggressive", "yes", NULL);
555 vici_add_kvl(conn, "proposals", ikev2_proposals, NULL);
558 vici_add_kvl(conn, "vips", "0.0.0.0", NULL);
563 static int ipsec_load_conn(struct vpn_provider *provider, struct ipsec_private_data *data)
567 const char *subsection;
568 char *local_cert_str;
570 VICISection *children;
574 if (!provider || !data) {
575 connman_error("invalid provider or data");
579 value = vpn_provider_get_string(provider, "Name");
580 DBG("Name: %s", value);
581 conn = vici_create_section(value);
582 children = vici_create_section("children");
583 add_subsection("children", children, conn);
585 for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
586 value = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
590 key = ipsec_conn_options[i].vici_key;
591 subsection = ipsec_conn_options[i].subsection;
592 ipsec_conn_options[i].add_elem(conn, key, value, subsection);
595 local_cert_str = get_local_cert_str(&(data->openssl_data));
596 if (local_cert_str) {
597 /* TODO :remove this after debug */
598 DBG("There's local certification to add local section");
599 vici_add_kvl(conn, "certs", local_cert_str, "local");
600 g_free(local_cert_str);
603 ipsec_add_default_conn_data(provider, conn);
604 ipsec_add_default_child_sa_data(provider, children);
606 ret = vici_send_request(vici_client, VICI_CMD_LOAD_CONN, conn);
608 connman_error("vici_send_request failed");
610 vici_destroy_section(conn);
615 static int ipsec_load_private_data(struct ipsec_private_data *data)
617 char *private_key_str;
623 private_key_str = get_private_key_str(&(data->openssl_data));
624 if (private_key_str) {
625 /* TODO :remove this after debug */
626 DBG("load private key");
627 ret = vici_load_key("RSA", private_key_str);
628 g_free(private_key_str);
634 ca_cert_num = get_ca_cert_num(&(data->openssl_data));
638 for (i = 0; i < ca_cert_num; i++) {
639 /* TODO :remove this after debug */
641 ca_cert_str = get_nth_ca_cert_str(&(data->openssl_data), i);
642 ret = vici_load_cert("X509", "CA", ca_cert_str);
651 static int ipsec_load_shared_psk(struct vpn_provider *provider)
659 connman_error("invalid provider");
663 data = vpn_provider_get_string(provider, "IPsec.IKEData");
664 owner = vpn_provider_get_string(provider, "IPsec.IKEOwners");
665 DBG("IKEData: %s, IKEOwners: %s", data, owner);
670 sect = vici_create_section(NULL);
675 vici_add_kv(sect, "type", VICI_SHARED_TYPE_PSK, NULL);
676 vici_add_kv(sect, "data", data, NULL);
677 vici_add_kvl(sect, "owners", owner, NULL);
679 ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
681 connman_error("vici_send_request failed");
683 vici_destroy_section(sect);
688 static int ipsec_load_shared_xauth(struct vpn_provider *provider)
696 connman_error("invalid provider");
700 data = vpn_provider_get_string(provider, "IPsec.XauthData");
701 owner = vpn_provider_get_string(provider, "IPsec.XauthOwners");
702 DBG("XauthData: %s, XauthOwners: %s", data, owner);
707 sect = vici_create_section(NULL);
709 vici_add_kv(sect, "type", VICI_SHARED_TYPE_XAUTH, NULL);
710 vici_add_kv(sect, "data", data, NULL);
711 vici_add_kvl(sect, "owners", owner, NULL);
713 ret = vici_send_request(vici_client, VICI_CMD_LOAD_SHARED, sect);
715 connman_error("vici_send_request failed");
717 vici_destroy_section(sect);
722 static char *load_file_from_path(const char *path)
727 size_t file_size = 0;
728 char *file_buff = NULL;
731 connman_error("File path is NULL\n");
735 fp = fopen(path, "rb");
737 connman_error("fopen %s is failed\n", path);
743 file_size = st.st_size;
744 file_buff = g_try_malloc0(sizeof(char)*st.st_size);
745 if (file_buff == NULL) {
746 connman_error("g_try_malloc0 failed\n");
751 if (fread(file_buff, 1, file_size, fp) != file_size) {
752 connman_error("file size not matched\n");
761 static int ipsec_load_key(struct vpn_provider *provider)
770 connman_error("invalid provider");
774 type = vpn_provider_get_string(provider, "IPsec.PKeyType");
775 path = vpn_provider_get_string(provider, "IPsec.PKeyData");
776 DBG("PKeyType: %s, PKeyData: %s", type, path);
781 data = load_file_from_path(path);
785 sect = vici_create_section(NULL);
789 vici_add_kv(sect, "type", type, NULL);
790 vici_add_kv(sect, "data", data, NULL);
792 ret = vici_send_request(vici_client, VICI_CMD_LOAD_KEY, sect);
794 connman_error("vici_send_request failed");
796 vici_destroy_section(sect);
802 static int ipsec_initiate(struct vpn_provider *provider)
807 sect = vici_create_section(NULL);
811 vici_add_kv(sect, "child", "net", NULL);
812 ret = vici_send_request(vici_client, VICI_CMD_INITIATE, sect);
814 connman_error("vici_send_request failed");
816 vici_destroy_section(sect);
821 static int ipsec_load_cert(struct vpn_provider *provider)
826 const char *local_auth_type;
827 const char *remote_auth_type;
831 connman_error("invalid provider");
835 local_auth_type = vpn_provider_get_string(provider, "IPsec.LocalAuth");
836 remote_auth_type = vpn_provider_get_string(provider, "IPsec.RemoteAuth");
837 if (!ipsec_is_same_auth(local_auth_type, "pubkey") &&
838 !ipsec_is_same_auth(remote_auth_type, "pubkey")) {
839 DBG("invalid auth type");
843 type = vpn_provider_get_string(provider, "IPsec.CertType");
844 flag = vpn_provider_get_string(provider, "IPsec.CertFlag");
845 data = load_file_from_path(vpn_provider_get_string(provider, "IPsec.CertData"));
846 DBG("CertType: %s, CertFalg: %s,CertData: %s", type, flag, data);
847 if (!type || ! flag || !data) {
848 connman_error("invalid certification information");
853 ret = vici_load_cert(type, flag, data);
855 connman_error("failed to load cert");
862 void connect_reply_cb(int err, void *user_data)
864 struct ipsec_private_data *data;
866 data = (struct ipsec_private_data *)user_data;
867 data->cb(data->provider, data->user_data, err);
869 free_private_data(data);
872 static struct ipsec_private_data* create_ipsec_private_data(struct vpn_provider *provider,
873 vpn_provider_connect_cb_t cb, void* user_data)
875 struct ipsec_private_data *data;
876 data = g_try_new0(struct ipsec_private_data, 1);
878 connman_error("out of memory");
884 data->provider = provider;
886 data->user_data = user_data;
890 static void vici_connect(struct ipsec_private_data *data)
892 struct vpn_provider *provider = NULL;
893 vpn_provider_connect_cb_t cb = NULL;
897 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid data parameter");
899 provider = data->provider;
901 if (!provider || !cb)
902 IPSEC_ERROR_CHECK_GOTO(-1, done, "Invalid provider or callback");
904 DBG("data %p, provider %p", data, provider);
907 * Initialize vici client
909 err = vici_initialize(&vici_client);
910 IPSEC_ERROR_CHECK_GOTO(err, done, "failed to initialize vici_client");
912 /* TODO :remove this after debug */
913 DBG("success to initialize vici socket");
915 vici_set_connect_reply_cb(vici_client, (vici_connect_reply_cb)connect_reply_cb, data);
918 * Send the load-conn command
920 err = ipsec_load_conn(provider, data);
921 IPSEC_ERROR_CHECK_GOTO(err, done, "load-conn failed");
923 /* TODO :remove this after debug */
924 DBG("success to ipsec_load_conn");
926 err = ipsec_load_private_data(data);
927 IPSEC_ERROR_CHECK_GOTO(err, done, "load private data failed");
929 /* TODO :remove this after debug */
930 DBG("success to ipsec_load_private_data");
933 * Send the load-shared command for PSK
935 err = ipsec_load_shared_psk(provider);
936 IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
938 /* TODO :remove this after debug */
939 DBG("success to ipsec_load_shared_psk");
942 * Send the load-shared command for XAUTH
944 err = ipsec_load_shared_xauth(provider);
945 IPSEC_ERROR_CHECK_GOTO(err, done, "load-shared failed");
947 /* TODO :remove this after debug */
948 DBG("success to ipsec_load_shared_xauth");
950 * Send the load-cert command
952 err = ipsec_load_cert(provider);
953 IPSEC_ERROR_CHECK_GOTO(err, done, "load-cert failed");
955 /* TODO :remove this after debug */
956 DBG("success to ipsec_load_cert");
959 * Send the load-key command
961 err = ipsec_load_key(provider);
962 IPSEC_ERROR_CHECK_GOTO(err, done, "load-key failed");
964 /* TODO :remove this after debug */
965 DBG("success to ipsec_load_cert");
967 * Send the initiate command
969 err = ipsec_initiate(provider);
970 IPSEC_ERROR_CHECK_GOTO(err, done, "initiate failed");
972 /* TODO :remove this after debug */
973 DBG("success to ipsec_initiate");
976 /* refer to connect_cb on vpn-provider.c for cb */
978 cb(provider, data->user_data, -err);
986 static void monitor_changed(GFileMonitor *monitor, GFile *file, GFile *other_file,
987 GFileMonitorEvent event_type, gpointer user_data)
989 DBG("file %s", g_file_get_path(file));
990 if (event_type == G_FILE_MONITOR_EVENT_CREATED) {
991 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
992 DBG("file created: %s", VICI_DEFAULT_URI);
993 struct ipsec_private_data *data = user_data;
995 g_object_unref(monitor);
1000 static void monitor_vici_socket(struct ipsec_private_data *data)
1002 GError *error = NULL;
1005 file = g_file_new_for_path(VICI_DEFAULT_URI);
1006 monitor = g_file_monitor_file(file, G_FILE_MONITOR_SEND_MOVED, NULL, &error);
1008 connman_error("g_file_monitor_directory failed: %s / %d", error->message, error->code);
1009 g_error_free(error);
1012 /* TODO :remove this after debug */
1013 DBG("starting to monitor vici socket");
1014 g_signal_connect(monitor, "changed", G_CALLBACK(monitor_changed), data);
1015 g_object_unref(file);
1018 static void check_vici_socket(struct ipsec_private_data *data)
1020 DBG("data %p", data);
1021 if (g_file_test(VICI_DEFAULT_URI, G_FILE_TEST_EXISTS)) {
1022 DBG("file exists: %s", VICI_DEFAULT_URI);
1025 monitor_vici_socket(data);
1029 static int ipsec_connect(struct vpn_provider *provider,
1030 struct connman_task *task, const char *if_name,
1031 vpn_provider_connect_cb_t cb, const char *dbus_sender,
1034 struct ipsec_private_data *data;
1039 data = create_ipsec_private_data(provider, cb, user_data);
1041 connman_error("create ipsec private data failed");
1045 * Start charon daemon using ipsec script of strongSwan.
1047 err = connman_task_run(task, vpn_died, provider, NULL, NULL, NULL);
1049 connman_error("charon start failed");
1051 cb(provider, user_data, err);
1055 path = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1056 pass = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1057 extract_cert_info(path, pass, &(data->openssl_data));
1059 check_vici_socket(data);
1060 // g_usleep(G_USEC_PER_SEC);
1065 static int ipsec_error_code(struct vpn_provider *provider, int exit_code)
1070 static int ipsec_save(struct vpn_provider *provider, GKeyFile *keyfile)
1077 * Save IKE connection configurations
1079 for (i = 0; i < (int)ARRAY_SIZE(ipsec_conn_options); i++) {
1080 option = vpn_provider_get_string(provider, ipsec_conn_options[i].cm_opt);
1082 g_key_file_set_string(keyfile,
1083 vpn_provider_get_save_group(provider),
1084 ipsec_conn_options[i].cm_opt,
1089 * Save shared IKE PSK, EAP or XAUTH secret
1091 for (i = 0; i < (int)ARRAY_SIZE(ipsec_shared_options); i++) {
1092 option = vpn_provider_get_string(provider, ipsec_shared_options[i].cm_opt);
1094 g_key_file_set_string(keyfile,
1095 vpn_provider_get_save_group(provider),
1096 ipsec_shared_options[i].cm_opt,
1101 * Save certification
1103 for (i = 0; i < (int)ARRAY_SIZE(ipsec_cert_options); i++) {
1104 option = vpn_provider_get_string(provider, ipsec_cert_options[i].cm_opt);
1106 g_key_file_set_string(keyfile,
1107 vpn_provider_get_save_group(provider),
1108 ipsec_cert_options[i].cm_opt,
1115 for (i = 0; i < (int)ARRAY_SIZE(ipsec_pkey_options); i++) {
1116 option = vpn_provider_get_string(provider, ipsec_pkey_options[i].cm_opt);
1118 g_key_file_set_string(keyfile,
1119 vpn_provider_get_save_group(provider),
1120 ipsec_pkey_options[i].cm_opt,
1125 * Save local certification
1127 option = vpn_provider_get_string(provider, "IPsec.LocalCerts");
1129 g_key_file_set_string(keyfile,
1130 vpn_provider_get_save_group(provider),
1133 option = vpn_provider_get_string(provider, "IPsec.LocalCertPass");
1135 g_key_file_set_string(keyfile,
1136 vpn_provider_get_save_group(provider),
1137 "IPsec.LocalCertPass",
1140 * Save CA certification directory
1142 option = vpn_provider_get_string(provider, "IPsec.CACertsDir");
1144 g_key_file_set_string(keyfile,
1145 vpn_provider_get_save_group(provider),
1152 static void ipsec_disconnect(struct vpn_provider *provider)
1156 err = vici_deinitialize(vici_client);
1157 IPSEC_ERROR_CHECK_RETURN(err, "failed to deinitialize vici_client");
1160 static struct vpn_driver vpn_driver = {
1161 .flags = VPN_FLAG_NO_TUN,
1162 .notify = ipsec_notify,
1163 .connect = ipsec_connect,
1164 .error_code = ipsec_error_code,
1166 .disconnect = ipsec_disconnect,
1169 static int ipsec_init(void)
1171 connection = connman_dbus_get_connection();
1173 return vpn_register("ipsec", &vpn_driver, IPSEC);
1176 static void ipsec_exit(void)
1178 vpn_unregister("ipsec");
1180 dbus_connection_unref(connection);
1183 CONNMAN_PLUGIN_DEFINE(ipsec, "IPSec plugin", VERSION,
1184 CONNMAN_PLUGIN_PRIORITY_DEFAULT, ipsec_init, ipsec_exit)