Imported Upstream connman version 1.38
[platform/upstream/connman.git] / vpn / plugins / openvpn.c
1 /*
2  *
3  *  ConnMan VPN daemon
4  *
5  *  Copyright (C) 2010-2014  BMW Car IT GmbH.
6  *  Copyright (C) 2016-2019  Jolla Ltd.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 as
10  *  published by the Free Software Foundation.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31 #include <stdio.h>
32 #include <net/if.h>
33 #include <linux/if_tun.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/un.h>
37
38 #include <glib.h>
39
40 #define CONNMAN_API_SUBJECT_TO_CHANGE
41 #include <connman/plugin.h>
42 #include <connman/log.h>
43 #include <connman/task.h>
44 #include <connman/dbus.h>
45 #include <connman/ipconfig.h>
46 #include <connman/agent.h>
47 #include <connman/setting.h>
48 #include <connman/vpn-dbus.h>
49
50 #include "../vpn-provider.h"
51 #include "../vpn-agent.h"
52
53 #include "vpn.h"
54 #include "../vpn.h"
55
56 #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
57
58 static DBusConnection *connection;
59
60 struct {
61         const char *cm_opt;
62         const char *ov_opt;
63         char       has_value;
64 } ov_options[] = {
65         { "Host", "--remote", 1 },
66         { "OpenVPN.CACert", "--ca", 1 },
67         { "OpenVPN.Cert", "--cert", 1 },
68         { "OpenVPN.Key", "--key", 1 },
69         { "OpenVPN.MTU", "--tun-mtu", 1 },
70         { "OpenVPN.NSCertType", "--ns-cert-type", 1 },
71         { "OpenVPN.Proto", "--proto", 1 },
72         { "OpenVPN.Port", "--port", 1 },
73         { "OpenVPN.AuthUserPass", "--auth-user-pass", 1 },
74         { "OpenVPN.AskPass", "--askpass", 1 },
75         { "OpenVPN.AuthNoCache", "--auth-nocache", 0 },
76         { "OpenVPN.TLSRemote", "--tls-remote", 1 },
77         { "OpenVPN.TLSAuth", NULL, 1 },
78         { "OpenVPN.TLSAuthDir", NULL, 1 },
79         { "OpenVPN.TLSCipher", "--tls-cipher", 1},
80         { "OpenVPN.Cipher", "--cipher", 1 },
81         { "OpenVPN.Auth", "--auth", 1 },
82         { "OpenVPN.CompLZO", "--comp-lzo", 0 },
83         { "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
84         { "OpenVPN.ConfigFile", "--config", 1 },
85         { "OpenVPN.DeviceType", NULL, 1 },
86         { "OpenVPN.Verb", "--verb", 1 },
87 };
88
89 struct ov_private_data {
90         struct vpn_provider *provider;
91         struct connman_task *task;
92         char *dbus_sender;
93         char *if_name;
94         vpn_provider_connect_cb_t cb;
95         void *user_data;
96         char *mgmt_path;
97         guint mgmt_timer_id;
98         guint mgmt_event_id;
99         GIOChannel *mgmt_channel;
100         int connect_attempts;
101         int failed_attempts_privatekey;
102 };
103
104 static void ov_connect_done(struct ov_private_data *data, int err)
105 {
106         if (data && data->cb) {
107                 vpn_provider_connect_cb_t cb = data->cb;
108                 void *user_data = data->user_data;
109
110                 /* Make sure we don't invoke this callback twice */
111                 data->cb = NULL;
112                 data->user_data = NULL;
113                 cb(data->provider, user_data, err);
114         }
115
116         if (!err)
117                 data->failed_attempts_privatekey = 0;
118 }
119
120 static void free_private_data(struct ov_private_data *data)
121 {
122         if (vpn_provider_get_plugin_data(data->provider) == data)
123                 vpn_provider_set_plugin_data(data->provider, NULL);
124
125         ov_connect_done(data, EIO);
126         vpn_provider_unref(data->provider);
127         g_free(data->dbus_sender);
128         g_free(data->if_name);
129         g_free(data->mgmt_path);
130         g_free(data);
131 }
132
133 struct nameserver_entry {
134         int id;
135         char *nameserver;
136 };
137
138 static struct nameserver_entry *ov_append_dns_entries(const char *key,
139                                                 const char *value)
140 {
141         struct nameserver_entry *entry = NULL;
142         gchar **options;
143
144         if (!g_str_has_prefix(key, "foreign_option_"))
145                 return NULL;
146
147         options = g_strsplit(value, " ", 3);
148         if (options[0] &&
149                 !strcmp(options[0], "dhcp-option") &&
150                         options[1] &&
151                         !strcmp(options[1], "DNS") &&
152                                 options[2]) {
153
154                 entry = g_try_new(struct nameserver_entry, 1);
155                 if (!entry)
156                         return NULL;
157
158                 entry->nameserver = g_strdup(options[2]);
159                 entry->id = atoi(key + 15); /* foreign_option_XXX */
160         }
161
162         g_strfreev(options);
163
164         return entry;
165 }
166
167 static char *ov_get_domain_name(const char *key, const char *value)
168 {
169         gchar **options;
170         char *domain = NULL;
171
172         if (!g_str_has_prefix(key, "foreign_option_"))
173                 return NULL;
174
175         options = g_strsplit(value, " ", 3);
176         if (options[0] &&
177                 !strcmp(options[0], "dhcp-option") &&
178                         options[1] &&
179                         !strcmp(options[1], "DOMAIN") &&
180                                 options[2]) {
181
182                 domain = g_strdup(options[2]);
183         }
184
185         g_strfreev(options);
186
187         return domain;
188 }
189
190 static gint cmp_ns(gconstpointer a, gconstpointer b)
191 {
192         struct nameserver_entry *entry_a = (struct nameserver_entry *)a;
193         struct nameserver_entry *entry_b = (struct nameserver_entry *)b;
194
195         if (entry_a->id < entry_b->id)
196                 return -1;
197
198         if (entry_a->id > entry_b->id)
199                 return 1;
200
201         return 0;
202 }
203
204 static void free_ns_entry(gpointer data)
205 {
206         struct nameserver_entry *entry = data;
207
208         g_free(entry->nameserver);
209         g_free(entry);
210 }
211
212 static int ov_notify(DBusMessage *msg, struct vpn_provider *provider)
213 {
214         DBusMessageIter iter, dict;
215         const char *reason, *key, *value;
216         char *address = NULL, *gateway = NULL, *peer = NULL, *netmask = NULL;
217         struct connman_ipaddress *ipaddress;
218         GSList *nameserver_list = NULL;
219         struct ov_private_data *data = vpn_provider_get_plugin_data(provider);
220
221         dbus_message_iter_init(msg, &iter);
222
223         dbus_message_iter_get_basic(&iter, &reason);
224         dbus_message_iter_next(&iter);
225
226         if (!provider) {
227                 connman_error("No provider found");
228                 return VPN_STATE_FAILURE;
229         }
230
231         DBG("%p %s", vpn_provider_get_name(provider), reason);
232
233         if (strcmp(reason, "up")) {
234                 ov_connect_done(data, EIO);
235                 return VPN_STATE_DISCONNECT;
236         }
237
238         dbus_message_iter_recurse(&iter, &dict);
239
240         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
241                 struct nameserver_entry *ns_entry = NULL;
242                 DBusMessageIter entry;
243
244                 dbus_message_iter_recurse(&dict, &entry);
245                 dbus_message_iter_get_basic(&entry, &key);
246                 dbus_message_iter_next(&entry);
247                 dbus_message_iter_get_basic(&entry, &value);
248
249                 DBG("%s = %s", key, value);
250
251                 if (!strcmp(key, "trusted_ip"))
252                         gateway = g_strdup(value);
253
254                 if (!strcmp(key, "ifconfig_local"))
255                         address = g_strdup(value);
256
257                 if (!strcmp(key, "ifconfig_netmask"))
258                         netmask = g_strdup(value);
259
260                 if (!strcmp(key, "ifconfig_remote"))
261                         peer = g_strdup(value);
262
263                 if (g_str_has_prefix(key, "route_"))
264                         vpn_provider_append_route(provider, key, value);
265
266                 if ((ns_entry = ov_append_dns_entries(key, value)))
267                         nameserver_list = g_slist_prepend(nameserver_list,
268                                                         ns_entry);
269                 else {
270                         char *domain = ov_get_domain_name(key, value);
271                         if (domain) {
272                                 vpn_provider_set_domain(provider, domain);
273                                 g_free(domain);
274                         }
275                 }
276
277                 dbus_message_iter_next(&dict);
278         }
279
280         ipaddress = connman_ipaddress_alloc(AF_INET);
281         if (!ipaddress) {
282                 g_slist_free_full(nameserver_list, free_ns_entry);
283                 g_free(address);
284                 g_free(gateway);
285                 g_free(peer);
286                 g_free(netmask);
287
288                 return VPN_STATE_FAILURE;
289         }
290
291         connman_ipaddress_set_ipv4(ipaddress, address, netmask, gateway);
292         connman_ipaddress_set_peer(ipaddress, peer);
293         vpn_provider_set_ipaddress(provider, ipaddress);
294
295         if (nameserver_list) {
296                 char *nameservers = NULL;
297                 GSList *tmp;
298
299                 nameserver_list = g_slist_sort(nameserver_list, cmp_ns);
300                 for (tmp = nameserver_list; tmp;
301                                                 tmp = g_slist_next(tmp)) {
302                         struct nameserver_entry *ns = tmp->data;
303
304                         if (!nameservers) {
305                                 nameservers = g_strdup(ns->nameserver);
306                         } else {
307                                 char *str;
308                                 str = g_strjoin(" ", nameservers,
309                                                 ns->nameserver, NULL);
310                                 g_free(nameservers);
311                                 nameservers = str;
312                         }
313                 }
314
315                 g_slist_free_full(nameserver_list, free_ns_entry);
316
317                 vpn_provider_set_nameservers(provider, nameservers);
318
319                 g_free(nameservers);
320         }
321
322         g_free(address);
323         g_free(gateway);
324         g_free(peer);
325         g_free(netmask);
326         connman_ipaddress_free(ipaddress);
327
328         ov_connect_done(data, 0);
329         return VPN_STATE_CONNECT;
330 }
331
332 static int ov_save(struct vpn_provider *provider, GKeyFile *keyfile)
333 {
334         const char *option;
335         int i;
336
337         for (i = 0; i < (int)ARRAY_SIZE(ov_options); i++) {
338                 if (strncmp(ov_options[i].cm_opt, "OpenVPN.", 8) == 0) {
339                         option = vpn_provider_get_string(provider,
340                                                         ov_options[i].cm_opt);
341                         if (!option)
342                                 continue;
343
344                         g_key_file_set_string(keyfile,
345                                         vpn_provider_get_save_group(provider),
346                                         ov_options[i].cm_opt, option);
347                 }
348         }
349         return 0;
350 }
351
352 static int task_append_config_data(struct vpn_provider *provider,
353                                         struct connman_task *task)
354 {
355         const char *option;
356         int i;
357
358         for (i = 0; i < (int)ARRAY_SIZE(ov_options); i++) {
359                 if (!ov_options[i].ov_opt)
360                         continue;
361
362                 option = vpn_provider_get_string(provider,
363                                         ov_options[i].cm_opt);
364                 if (!option)
365                         continue;
366
367                 /*
368                  * If the AuthUserPass option is "-", provide the input
369                  * via management interface
370                  */
371                 if (!strcmp(ov_options[i].cm_opt, "OpenVPN.AuthUserPass") &&
372                                                 !strcmp(option, "-"))
373                         option = NULL;
374
375                 if (connman_task_add_argument(task,
376                                 ov_options[i].ov_opt,
377                                 ov_options[i].has_value ? option : NULL) < 0)
378                         return -EIO;
379
380         }
381
382         return 0;
383 }
384
385 static void close_management_interface(struct ov_private_data *data)
386 {
387         if (data->mgmt_path) {
388                 if (unlink(data->mgmt_path) && errno != ENOENT)
389                         connman_warn("Unable to unlink management socket %s: "
390                                                 "%d", data->mgmt_path, errno);
391
392                 g_free(data->mgmt_path);
393                 data->mgmt_path = NULL;
394         }
395
396         if (data->mgmt_timer_id != 0) {
397                 g_source_remove(data->mgmt_timer_id);
398                 data->mgmt_timer_id = 0;
399         }
400
401         if (data->mgmt_event_id) {
402                 g_source_remove(data->mgmt_event_id);
403                 data->mgmt_event_id = 0;
404         }
405
406         if (data->mgmt_channel) {
407                 g_io_channel_shutdown(data->mgmt_channel, FALSE, NULL);
408                 g_io_channel_unref(data->mgmt_channel);
409                 data->mgmt_channel = NULL;
410         }
411 }
412
413 static void ov_died(struct connman_task *task, int exit_code, void *user_data)
414 {
415         struct ov_private_data *data = user_data;
416
417         /* Cancel any pending agent requests */
418         connman_agent_cancel(data->provider);
419
420         close_management_interface(data);
421
422         vpn_died(task, exit_code, data->provider);
423
424         free_private_data(data);
425 }
426
427 static int run_connect(struct ov_private_data *data,
428                         vpn_provider_connect_cb_t cb, void *user_data)
429 {
430         struct vpn_provider *provider = data->provider;
431         struct connman_task *task = data->task;
432         const char *option;
433         int err = 0;
434
435         option = vpn_provider_get_string(provider, "OpenVPN.ConfigFile");
436         if (!option) {
437                 /*
438                  * Set some default options if user has no config file.
439                  */
440                 option = vpn_provider_get_string(provider, "OpenVPN.TLSAuth");
441                 if (option) {
442                         connman_task_add_argument(task, "--tls-auth", option);
443                         option = vpn_provider_get_string(provider,
444                                                         "OpenVPN.TLSAuthDir");
445                         if (option)
446                                 connman_task_add_argument(task, option, NULL);
447                 }
448
449                 connman_task_add_argument(task, "--nobind", NULL);
450                 connman_task_add_argument(task, "--persist-key", NULL);
451                 connman_task_add_argument(task, "--client", NULL);
452         }
453
454         if (data->mgmt_path) {
455                 connman_task_add_argument(task, "--management", NULL);
456                 connman_task_add_argument(task, data->mgmt_path, NULL);
457                 connman_task_add_argument(task, "unix", NULL);
458                 connman_task_add_argument(task, "--management-query-passwords",
459                                                                 NULL);
460                 connman_task_add_argument(task, "--auth-retry", "interact");
461         }
462
463         connman_task_add_argument(task, "--syslog", NULL);
464
465         connman_task_add_argument(task, "--script-security", "2");
466
467         connman_task_add_argument(task, "--up",
468                                         SCRIPTDIR "/openvpn-script");
469         connman_task_add_argument(task, "--up-restart", NULL);
470
471         connman_task_add_argument(task, "--setenv", NULL);
472         connman_task_add_argument(task, "CONNMAN_BUSNAME",
473                                         dbus_bus_get_unique_name(connection));
474
475         connman_task_add_argument(task, "--setenv", NULL);
476         connman_task_add_argument(task, "CONNMAN_INTERFACE",
477                                         CONNMAN_TASK_INTERFACE);
478
479         connman_task_add_argument(task, "--setenv", NULL);
480         connman_task_add_argument(task, "CONNMAN_PATH",
481                                         connman_task_get_path(task));
482
483         connman_task_add_argument(task, "--dev", data->if_name);
484         option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
485         if (option) {
486                 connman_task_add_argument(task, "--dev-type", option);
487         } else {
488                 /*
489                  * Default to tun for backwards compatibility.
490                  */
491                 connman_task_add_argument(task, "--dev-type", "tun");
492         }
493
494         connman_task_add_argument(task, "--persist-tun", NULL);
495
496 #if !defined TIZEN_EXT
497         connman_task_add_argument(task, "--route-noexec", NULL);
498         connman_task_add_argument(task, "--ifconfig-noexec", NULL);
499 #endif
500
501         /*
502          * Disable client restarts because we can't handle this at the
503          * moment. The problem is that when OpenVPN decides to switch
504          * from CONNECTED state to RECONNECTING and then to RESOLVE,
505          * it is not possible to do a DNS lookup. The DNS server is
506          * not accessible through the tunnel anymore and so we end up
507          * trying to resolve the OpenVPN servers address.
508          */
509         connman_task_add_argument(task, "--ping-restart", "0");
510
511         /*
512          * Disable connetion retrying when OpenVPN is connected over TCP.
513          * With TCP OpenVPN attempts to handle reconnection silently without
514          * reporting the error back when establishing a connection or
515          * reconnecting as succesful one. The latter causes trouble if the
516          * retries are not limited to 1 (no retry) as the interface is up and
517          * connman regards it as the default route and network ceases to work,
518          * including DNS.
519         */
520         option = vpn_provider_get_string(provider, "OpenVPN.Proto");
521         if (option && g_str_has_prefix(option, "tcp"))
522                 connman_task_add_argument(task, "--connect-retry-max", "1");
523
524         err = connman_task_run(task, ov_died, data, NULL, NULL, NULL);
525         if (err < 0) {
526                 data->cb = NULL;
527                 data->user_data = NULL;
528                 connman_error("openvpn failed to start");
529                 return -EIO;
530         } else {
531                 /* This lets the caller know that the actual result of
532                  * the operation will be reported to the callback */
533                 return -EINPROGRESS;
534         }
535 }
536
537 static void ov_quote_credential(GString *line, const char *cred)
538 {
539         if (!line)
540                 return;
541
542         g_string_append_c(line, '"');
543
544         while (*cred != '\0') {
545
546                 switch (*cred) {
547                 case ' ':
548                 case '"':
549                 case '\\':
550                         g_string_append_c(line, '\\');
551                         break;
552                 default:
553                         break;
554                 }
555
556                 g_string_append_c(line, *cred++);
557         }
558
559         g_string_append_c(line, '"');
560 }
561
562 static void ov_return_credentials(struct ov_private_data *data,
563                                 const char *username, const char *password)
564 {
565         GString *reply_string;
566         gchar *reply;
567         gsize len;
568
569         reply_string = g_string_new(NULL);
570
571         g_string_append(reply_string, "username \"Auth\" ");
572         ov_quote_credential(reply_string, username);
573         g_string_append_c(reply_string, '\n');
574
575         g_string_append(reply_string, "password \"Auth\" ");
576         ov_quote_credential(reply_string, password);
577         g_string_append_c(reply_string, '\n');
578
579         len = reply_string->len;
580         reply = g_string_free(reply_string, FALSE);
581
582         g_io_channel_write_chars(data->mgmt_channel, reply, len, NULL, NULL);
583         g_io_channel_flush(data->mgmt_channel, NULL);
584
585         memset(reply, 0, len);
586         g_free(reply);
587 }
588
589 static void ov_return_private_key_password(struct ov_private_data *data,
590                                 const char *privatekeypass)
591 {
592         GString *reply_string;
593         gchar *reply;
594         gsize len;
595
596         reply_string = g_string_new(NULL);
597
598         g_string_append(reply_string, "password \"Private Key\" ");
599         ov_quote_credential(reply_string, privatekeypass);
600         g_string_append_c(reply_string, '\n');
601
602         len = reply_string->len;
603         reply = g_string_free(reply_string, FALSE);
604
605         g_io_channel_write_chars(data->mgmt_channel, reply, len, NULL, NULL);
606         g_io_channel_flush(data->mgmt_channel, NULL);
607
608         memset(reply, 0, len);
609         g_free(reply);
610 }
611
612 static void request_input_append_informational(DBusMessageIter *iter,
613                 void *user_data)
614 {
615         char *str = "string";
616
617         connman_dbus_dict_append_basic(iter, "Type",
618                                 DBUS_TYPE_STRING, &str);
619         str = "informational";
620         connman_dbus_dict_append_basic(iter, "Requirement",
621                                 DBUS_TYPE_STRING, &str);
622 }
623
624 static void request_input_append_mandatory(DBusMessageIter *iter,
625                 void *user_data)
626 {
627         char *str = "string";
628
629         connman_dbus_dict_append_basic(iter, "Type",
630                                 DBUS_TYPE_STRING, &str);
631         str = "mandatory";
632         connman_dbus_dict_append_basic(iter, "Requirement",
633                                 DBUS_TYPE_STRING, &str);
634 }
635
636 static void request_input_append_password(DBusMessageIter *iter,
637                 void *user_data)
638 {
639         char *str = "password";
640
641         connman_dbus_dict_append_basic(iter, "Type",
642                                 DBUS_TYPE_STRING, &str);
643         str = "mandatory";
644         connman_dbus_dict_append_basic(iter, "Requirement",
645                                 DBUS_TYPE_STRING, &str);
646 }
647
648 static void request_input_credentials_reply(DBusMessage *reply,
649                                                         void *user_data)
650 {
651         struct ov_private_data *data = user_data;
652         char *username = NULL;
653         char *password = NULL;
654         char *key;
655         DBusMessageIter iter, dict;
656         DBusError error;
657         int err = 0;
658
659         connman_info("provider %p", data->provider);
660
661         /*
662          * When connmand calls disconnect because of connection timeout no
663          * reply is received.
664          */
665         if (!reply) {
666                 err = ENOENT;
667                 goto err;
668         }
669
670         dbus_error_init(&error);
671
672         err = vpn_agent_check_and_process_reply_error(reply, data->provider,
673                                 data->task, data->cb, data->user_data);
674         if (err) {
675                 /* Ensure cb is called only once */
676                 data->cb = NULL;
677                 data->user_data = NULL;
678                 return;
679         }
680
681         if (!vpn_agent_check_reply_has_dict(reply)) {
682                 err = ENOENT;
683                 goto err;
684         }
685
686         dbus_message_iter_init(reply, &iter);
687         dbus_message_iter_recurse(&iter, &dict);
688         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
689                 DBusMessageIter entry, value;
690
691                 dbus_message_iter_recurse(&dict, &entry);
692                 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
693                         break;
694
695                 dbus_message_iter_get_basic(&entry, &key);
696
697                 if (g_str_equal(key, "OpenVPN.Password")) {
698                         dbus_message_iter_next(&entry);
699                         if (dbus_message_iter_get_arg_type(&entry)
700                                                         != DBUS_TYPE_VARIANT)
701                                 break;
702                         dbus_message_iter_recurse(&entry, &value);
703                         if (dbus_message_iter_get_arg_type(&value)
704                                                         != DBUS_TYPE_STRING)
705                                 break;
706                         dbus_message_iter_get_basic(&value, &password);
707                         vpn_provider_set_string_hide_value(data->provider,
708                                         key, password);
709
710                 } else if (g_str_equal(key, "OpenVPN.Username")) {
711                         dbus_message_iter_next(&entry);
712                         if (dbus_message_iter_get_arg_type(&entry)
713                                                         != DBUS_TYPE_VARIANT)
714                                 break;
715                         dbus_message_iter_recurse(&entry, &value);
716                         if (dbus_message_iter_get_arg_type(&value)
717                                                         != DBUS_TYPE_STRING)
718                                 break;
719                         dbus_message_iter_get_basic(&value, &username);
720                         vpn_provider_set_string_hide_value(data->provider,
721                                         key, username);
722                 }
723
724                 dbus_message_iter_next(&dict);
725         }
726
727         if (!password || !username) {
728                 vpn_provider_indicate_error(data->provider,
729                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
730                 err = EACCES;
731                 goto err;
732         }
733
734         ov_return_credentials(data, username, password);
735
736         return;
737
738 err:
739         ov_connect_done(data, err);
740 }
741
742 static int request_credentials_input(struct ov_private_data *data)
743 {
744         DBusMessage *message;
745         const char *path, *agent_sender, *agent_path;
746         DBusMessageIter iter;
747         DBusMessageIter dict;
748         int err;
749         void *agent;
750
751         agent = connman_agent_get_info(data->dbus_sender, &agent_sender,
752                                                         &agent_path);
753         if (!agent || !agent_path)
754                 return -ESRCH;
755
756         message = dbus_message_new_method_call(agent_sender, agent_path,
757                                         VPN_AGENT_INTERFACE,
758                                         "RequestInput");
759         if (!message)
760                 return -ENOMEM;
761
762         dbus_message_iter_init_append(message, &iter);
763
764         path = vpn_provider_get_path(data->provider);
765         dbus_message_iter_append_basic(&iter,
766                                 DBUS_TYPE_OBJECT_PATH, &path);
767
768         connman_dbus_dict_open(&iter, &dict);
769
770         if (vpn_provider_get_authentication_errors(data->provider))
771                 vpn_agent_append_auth_failure(&dict, data->provider, NULL);
772
773         /* Request temporary properties to pass on to openvpn */
774         connman_dbus_dict_append_dict(&dict, "OpenVPN.Username",
775                         request_input_append_mandatory, NULL);
776
777         connman_dbus_dict_append_dict(&dict, "OpenVPN.Password",
778                         request_input_append_password, NULL);
779
780         vpn_agent_append_host_and_name(&dict, data->provider);
781
782         connman_dbus_dict_close(&iter, &dict);
783
784         err = connman_agent_queue_message(data->provider, message,
785                         connman_timeout_input_request(),
786                         request_input_credentials_reply, data, agent);
787
788         if (err < 0 && err != -EBUSY) {
789                 connman_error("error %d sending agent request", err);
790                 dbus_message_unref(message);
791
792                 return err;
793         }
794
795         dbus_message_unref(message);
796
797         return -EINPROGRESS;
798 }
799
800 static void request_input_private_key_reply(DBusMessage *reply,
801                                                         void *user_data)
802 {
803         struct ov_private_data *data = user_data;
804         const char *privatekeypass = NULL;
805         const char *key;
806         DBusMessageIter iter, dict;
807         DBusError error;
808         int err = 0;
809
810         connman_info("provider %p", data->provider);
811
812         /*
813          * When connmand calls disconnect because of connection timeout no
814          * reply is received.
815          */
816         if (!reply) {
817                 err = ENOENT;
818                 goto err;
819         }
820
821         dbus_error_init(&error);
822
823         err = vpn_agent_check_and_process_reply_error(reply, data->provider,
824                                 data->task, data->cb, data->user_data);
825         if (err) {
826                 /* Ensure cb is called only once */
827                 data->cb = NULL;
828                 data->user_data = NULL;
829                 return;
830         }
831
832         if (!vpn_agent_check_reply_has_dict(reply)) {
833                 err = ENOENT;
834                 goto err;
835         }
836
837         dbus_message_iter_init(reply, &iter);
838         dbus_message_iter_recurse(&iter, &dict);
839         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
840                 DBusMessageIter entry, value;
841
842                 dbus_message_iter_recurse(&dict, &entry);
843                 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
844                         break;
845
846                 dbus_message_iter_get_basic(&entry, &key);
847
848                 if (g_str_equal(key, "OpenVPN.PrivateKeyPassword")) {
849                         dbus_message_iter_next(&entry);
850                         if (dbus_message_iter_get_arg_type(&entry)
851                                                         != DBUS_TYPE_VARIANT)
852                                 break;
853                         dbus_message_iter_recurse(&entry, &value);
854                         if (dbus_message_iter_get_arg_type(&value)
855                                                         != DBUS_TYPE_STRING)
856                                 break;
857                         dbus_message_iter_get_basic(&value, &privatekeypass);
858                         vpn_provider_set_string_hide_value(data->provider,
859                                         key, privatekeypass);
860
861                 }
862
863                 dbus_message_iter_next(&dict);
864         }
865
866         if (!privatekeypass) {
867                 vpn_provider_indicate_error(data->provider,
868                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
869
870                 err = EACCES;
871                 goto err;
872         }
873
874         ov_return_private_key_password(data, privatekeypass);
875
876         return;
877
878 err:
879         ov_connect_done(data, err);
880 }
881
882 static int request_private_key_input(struct ov_private_data *data)
883 {
884         DBusMessage *message;
885         const char *path, *agent_sender, *agent_path;
886         const char *privatekeypass;
887         DBusMessageIter iter;
888         DBusMessageIter dict;
889         int err;
890         void *agent;
891
892         /*
893          * First check if this is the second attempt to get the key within
894          * this connection. In such case there has been invalid Private Key
895          * Password and it must be reset, and queried from user.
896          */
897         if (data->failed_attempts_privatekey) {
898                 vpn_provider_set_string_hide_value(data->provider,
899                                         "OpenVPN.PrivateKeyPassword", NULL);
900         } else {
901                 /* If the encrypted Private key password is kept in memory and
902                  * use it first. If authentication fails this is cleared,
903                  * likewise it is when connman-vpnd is restarted.
904                  */
905                 privatekeypass = vpn_provider_get_string(data->provider,
906                                         "OpenVPN.PrivateKeyPassword");
907                 if (privatekeypass) {
908                         ov_return_private_key_password(data, privatekeypass);
909                         goto out;
910                 }
911         }
912
913         agent = connman_agent_get_info(data->dbus_sender, &agent_sender,
914                                                         &agent_path);
915         if (!agent || !agent_path)
916                 return -ESRCH;
917
918         message = dbus_message_new_method_call(agent_sender, agent_path,
919                                         VPN_AGENT_INTERFACE,
920                                         "RequestInput");
921         if (!message)
922                 return -ENOMEM;
923
924         dbus_message_iter_init_append(message, &iter);
925
926         path = vpn_provider_get_path(data->provider);
927         dbus_message_iter_append_basic(&iter,
928                                 DBUS_TYPE_OBJECT_PATH, &path);
929
930         connman_dbus_dict_open(&iter, &dict);
931
932         connman_dbus_dict_append_dict(&dict, "OpenVPN.PrivateKeyPassword",
933                         request_input_append_password, NULL);
934
935         vpn_agent_append_host_and_name(&dict, data->provider);
936
937         /* Do not allow to store or retrieve the encrypted Private Key pass */
938         vpn_agent_append_allow_credential_storage(&dict, false);
939         vpn_agent_append_allow_credential_retrieval(&dict, false);
940
941         /*
942          * Indicate to keep credentials, the enc Private Key password should
943          * not affect the credential storing.
944          */
945         vpn_agent_append_keep_credentials(&dict, true);
946
947         connman_dbus_dict_append_dict(&dict, "Enter Private Key password",
948                         request_input_append_informational, NULL);
949
950         connman_dbus_dict_close(&iter, &dict);
951
952         err = connman_agent_queue_message(data->provider, message,
953                         connman_timeout_input_request(),
954                         request_input_private_key_reply, data, agent);
955
956         if (err < 0 && err != -EBUSY) {
957                 connman_error("error %d sending agent request", err);
958                 dbus_message_unref(message);
959
960                 return err;
961         }
962
963         dbus_message_unref(message);
964
965 out:
966         return -EINPROGRESS;
967 }
968
969 static gboolean ov_management_handle_input(GIOChannel *source,
970                                 GIOCondition condition, gpointer user_data)
971 {
972         struct ov_private_data *data = user_data;
973         char *str = NULL;
974         int err = 0;
975         bool close = false;
976
977         if (condition & G_IO_IN) {
978                 /*
979                  * Just return if line is not read and str is not allocated.
980                  * Condition check handles closing of the channel later.
981                  */
982                 if (g_io_channel_read_line(source, &str, NULL, NULL, NULL) !=
983                                                         G_IO_STATUS_NORMAL)
984                         return true;
985
986                 str[strlen(str) - 1] = '\0';
987                 connman_warn("openvpn request %s", str);
988
989                 if (g_str_has_prefix(str, ">PASSWORD:Need 'Auth'")) {
990                         /*
991                          * Request credentials from the user
992                          */
993                         err = request_credentials_input(data);
994                         if (err != -EINPROGRESS)
995                                 close = true;
996                 } else if (g_str_has_prefix(str,
997                                 ">PASSWORD:Need 'Private Key'")) {
998                         err = request_private_key_input(data);
999                         if (err != -EINPROGRESS)
1000                                 close = true;
1001                 } else if (g_str_has_prefix(str,
1002                                 ">PASSWORD:Verification Failed: 'Auth'")) {
1003                         /*
1004                          * Add error only, state change indication causes
1005                          * signal to be sent, which is not desired when
1006                          * OpenVPN is in interactive mode.
1007                          */
1008                         vpn_provider_add_error(data->provider,
1009                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
1010                 /*
1011                  * According to the OpenVPN manual about management interface
1012                  * https://openvpn.net/community-resources/management-interface/
1013                  * this should be received but it does not seem to be reported
1014                  * when decrypting private key fails. This requires following
1015                  * patch for OpenVPN (at least <= 2.4.5) in order to work:
1016                  * https://git.sailfishos.org/mer-core/openvpn/blob/
1017                  * 4f4b4af116292a207416c8a990392e35a6fc41af/rpm/privatekey-
1018                  * passphrase-handling.diff
1019                  */
1020                 } else if (g_str_has_prefix(str, ">PASSWORD:Verification "
1021                                 "Failed: 'Private Key'")) {
1022                         data->failed_attempts_privatekey++;
1023                 }
1024
1025                 g_free(str);
1026         } else if (condition & (G_IO_ERR | G_IO_HUP)) {
1027                 connman_warn("Management channel termination");
1028                 close = true;
1029         }
1030
1031         if (close)
1032                 close_management_interface(data);
1033
1034         return true;
1035 }
1036
1037 static int ov_management_connect_timer_cb(gpointer user_data)
1038 {
1039         struct ov_private_data *data = user_data;
1040
1041         if (!data->mgmt_channel) {
1042                 int fd = socket(AF_UNIX, SOCK_STREAM, 0);
1043                 if (fd >= 0) {
1044                         struct sockaddr_un remote;
1045                         int err;
1046
1047                         memset(&remote, 0, sizeof(remote));
1048                         remote.sun_family = AF_UNIX;
1049                         g_strlcpy(remote.sun_path, data->mgmt_path,
1050                                                 sizeof(remote.sun_path));
1051
1052                         err = connect(fd, (struct sockaddr *)&remote,
1053                                                 sizeof(remote));
1054                         if (err == 0) {
1055                                 data->mgmt_channel = g_io_channel_unix_new(fd);
1056                                 data->mgmt_event_id =
1057                                         g_io_add_watch(data->mgmt_channel,
1058                                                 G_IO_IN | G_IO_ERR | G_IO_HUP,
1059                                                 ov_management_handle_input,
1060                                                 data);
1061
1062                                 connman_warn("Connected management socket");
1063                                 data->mgmt_timer_id = 0;
1064                                 return G_SOURCE_REMOVE;
1065                         }
1066                         close(fd);
1067                 }
1068         }
1069
1070         data->connect_attempts++;
1071         if (data->connect_attempts > 30) {
1072                 connman_warn("Unable to connect management socket");
1073                 data->mgmt_timer_id = 0;
1074                 return G_SOURCE_REMOVE;
1075         }
1076
1077         return G_SOURCE_CONTINUE;
1078 }
1079
1080 static int ov_connect(struct vpn_provider *provider,
1081                         struct connman_task *task, const char *if_name,
1082                         vpn_provider_connect_cb_t cb, const char *dbus_sender,
1083                         void *user_data)
1084 {
1085         const char *tmpdir;
1086         struct ov_private_data *data;
1087
1088         data = g_try_new0(struct ov_private_data, 1);
1089         if (!data)
1090                 return -ENOMEM;
1091
1092         vpn_provider_set_plugin_data(provider, data);
1093         data->provider = vpn_provider_ref(provider);
1094         data->task = task;
1095         data->dbus_sender = g_strdup(dbus_sender);
1096         data->if_name = g_strdup(if_name);
1097         data->cb = cb;
1098         data->user_data = user_data;
1099
1100         /*
1101          * We need to use the management interface to provide
1102          * the user credentials and password for decrypting private key.
1103          */
1104
1105         /* Use env TMPDIR for creating management socket, fall back to /tmp */
1106         tmpdir = getenv("TMPDIR");
1107         if (!tmpdir || !*tmpdir)
1108                 tmpdir = "/tmp";
1109
1110         /* Set up the path for the management interface */
1111         data->mgmt_path = g_strconcat(tmpdir, "/connman-vpn-management-",
1112                 vpn_provider_get_ident(provider), NULL);
1113         if (unlink(data->mgmt_path) != 0 && errno != ENOENT) {
1114                 connman_warn("Unable to unlink management socket %s: %d",
1115                                         data->mgmt_path, errno);
1116         }
1117
1118         data->mgmt_timer_id = g_timeout_add(200,
1119                                 ov_management_connect_timer_cb, data);
1120
1121         task_append_config_data(provider, task);
1122
1123         return run_connect(data, cb, user_data);
1124 }
1125
1126 static void ov_disconnect(struct vpn_provider *provider)
1127 {
1128         if (!provider)
1129                 return;
1130
1131         connman_agent_cancel(provider);
1132
1133         vpn_provider_set_state(provider, VPN_PROVIDER_STATE_DISCONNECT);
1134 }
1135
1136 static int ov_device_flags(struct vpn_provider *provider)
1137 {
1138         const char *option;
1139
1140         option = vpn_provider_get_string(provider, "OpenVPN.DeviceType");
1141         if (!option) {
1142                 return IFF_TUN;
1143         }
1144
1145         if (g_str_equal(option, "tap")) {
1146                 return IFF_TAP;
1147         }
1148
1149         if (!g_str_equal(option, "tun")) {
1150                 connman_warn("bad OpenVPN.DeviceType value "
1151                                         "falling back to tun");
1152         }
1153
1154         return IFF_TUN;
1155 }
1156
1157 static int ov_route_env_parse(struct vpn_provider *provider, const char *key,
1158                                         int *family, unsigned long *idx,
1159                                         enum vpn_provider_route_type *type)
1160 {
1161         char *end;
1162         const char *start;
1163
1164         if (g_str_has_prefix(key, "route_network_")) {
1165                 start = key + strlen("route_network_");
1166                 *type = VPN_PROVIDER_ROUTE_TYPE_ADDR;
1167         } else if (g_str_has_prefix(key, "route_netmask_")) {
1168                 start = key + strlen("route_netmask_");
1169                 *type = VPN_PROVIDER_ROUTE_TYPE_MASK;
1170         } else if (g_str_has_prefix(key, "route_gateway_")) {
1171                 start = key + strlen("route_gateway_");
1172                 *type = VPN_PROVIDER_ROUTE_TYPE_GW;
1173         } else
1174                 return -EINVAL;
1175
1176         *family = AF_INET;
1177         *idx = g_ascii_strtoull(start, &end, 10);
1178
1179         return 0;
1180 }
1181
1182 static struct vpn_driver vpn_driver = {
1183         .notify = ov_notify,
1184         .connect        = ov_connect,
1185         .disconnect     = ov_disconnect,
1186         .save           = ov_save,
1187         .device_flags = ov_device_flags,
1188         .route_env_parse = ov_route_env_parse,
1189 };
1190
1191 static int openvpn_init(void)
1192 {
1193         connection = connman_dbus_get_connection();
1194
1195         return vpn_register("openvpn", &vpn_driver, OPENVPN);
1196 }
1197
1198 static void openvpn_exit(void)
1199 {
1200         vpn_unregister("openvpn");
1201
1202         dbus_connection_unref(connection);
1203 }
1204
1205 CONNMAN_PLUGIN_DEFINE(openvpn, "OpenVPN plugin", VERSION,
1206         CONNMAN_PLUGIN_PRIORITY_DEFAULT, openvpn_init, openvpn_exit)