Wrap tizen specific codes with TIZEN_EXT
[platform/upstream/connman.git] / vpn / plugins / vpn.c
1 /*
2  *
3  *  ConnMan VPN daemon
4  *
5  *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #define _GNU_SOURCE
27 #include <string.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <stdio.h>
32 #include <errno.h>
33 #include <sys/ioctl.h>
34 #include <sys/types.h>
35 #include <linux/if_tun.h>
36 #include <net/if.h>
37
38 #include <dbus/dbus.h>
39
40 #include <glib/gprintf.h>
41
42 #include <connman/log.h>
43 #include <connman/rtnl.h>
44 #include <connman/task.h>
45 #include <connman/inet.h>
46
47 #include "../vpn-rtnl.h"
48 #include "../vpn-provider.h"
49
50 #include "vpn.h"
51
52 struct vpn_data {
53         struct vpn_provider *provider;
54         char *if_name;
55         unsigned flags;
56         unsigned int watch;
57         enum vpn_state state;
58         struct connman_task *task;
59 };
60
61 struct vpn_driver_data {
62         const char *name;
63         const char *program;
64         struct vpn_driver *vpn_driver;
65         struct vpn_provider_driver provider_driver;
66 };
67
68 GHashTable *driver_hash = NULL;
69
70 static int stop_vpn(struct vpn_provider *provider)
71 {
72         struct vpn_data *data = vpn_provider_get_data(provider);
73         struct vpn_driver_data *vpn_driver_data;
74         const char *name;
75         struct ifreq ifr;
76         int fd, err;
77
78         if (!data)
79                 return -EINVAL;
80
81         name = vpn_provider_get_driver_name(provider);
82         if (!name)
83                 return -EINVAL;
84
85         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
86
87         if (vpn_driver_data && vpn_driver_data->vpn_driver &&
88                         vpn_driver_data->vpn_driver->flags == VPN_FLAG_NO_TUN)
89                 return 0;
90
91         memset(&ifr, 0, sizeof(ifr));
92         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
93         sprintf(ifr.ifr_name, "%s", data->if_name);
94
95         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
96         if (fd < 0) {
97                 err = -errno;
98                 connman_error("Failed to open /dev/net/tun to device %s: %s",
99                               data->if_name, strerror(errno));
100                 return err;
101         }
102
103         if (ioctl(fd, TUNSETIFF, (void *)&ifr)) {
104                 err = -errno;
105                 connman_error("Failed to TUNSETIFF for device %s to it: %s",
106                               data->if_name, strerror(errno));
107                 close(fd);
108                 return err;
109         }
110
111         if (ioctl(fd, TUNSETPERSIST, 0)) {
112                 err = -errno;
113                 connman_error("Failed to set tun device %s nonpersistent: %s",
114                               data->if_name, strerror(errno));
115                 close(fd);
116                 return err;
117         }
118         close(fd);
119         DBG("Killed tun device %s", data->if_name);
120         return 0;
121 }
122
123 void vpn_died(struct connman_task *task, int exit_code, void *user_data)
124 {
125         struct vpn_provider *provider = user_data;
126         struct vpn_data *data = vpn_provider_get_data(provider);
127         int state = VPN_STATE_FAILURE;
128         enum vpn_provider_error ret;
129
130         DBG("provider %p data %p", provider, data);
131
132         if (!data)
133                 goto vpn_exit;
134
135         state = data->state;
136
137         stop_vpn(provider);
138         vpn_provider_set_data(provider, NULL);
139
140         if (data->watch != 0) {
141                 vpn_rtnl_remove_watch(data->watch);
142                 data->watch = 0;
143                 vpn_provider_unref(provider);
144         }
145
146 vpn_exit:
147         if (state != VPN_STATE_READY && state != VPN_STATE_DISCONNECT) {
148                 const char *name;
149                 struct vpn_driver_data *vpn_data = NULL;
150
151                 name = vpn_provider_get_driver_name(provider);
152                 if (name)
153                         vpn_data = g_hash_table_lookup(driver_hash, name);
154
155                 if (vpn_data &&
156                                 vpn_data->vpn_driver->error_code)
157                         ret = vpn_data->vpn_driver->error_code(provider,
158                                         exit_code);
159                 else
160                         ret = VPN_PROVIDER_ERROR_UNKNOWN;
161
162                 vpn_provider_indicate_error(provider, ret);
163         } else
164                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_IDLE);
165
166         vpn_provider_set_index(provider, -1);
167
168         if (data) {
169                 vpn_provider_unref(data->provider);
170                 g_free(data->if_name);
171                 g_free(data);
172         }
173
174         connman_task_destroy(task);
175 }
176
177 int vpn_set_ifname(struct vpn_provider *provider, const char *ifname)
178 {
179         struct vpn_data *data = vpn_provider_get_data(provider);
180         int index;
181
182         if (!ifname || !data)
183                 return  -EIO;
184
185         index = connman_inet_ifindex(ifname);
186         if (index < 0)
187                 return  -EIO;
188
189         if (data->if_name)
190                 g_free(data->if_name);
191
192         data->if_name = (char *)g_strdup(ifname);
193         vpn_provider_set_index(provider, index);
194
195         return 0;
196 }
197
198 static void vpn_newlink(unsigned flags, unsigned change, void *user_data)
199 {
200         struct vpn_provider *provider = user_data;
201         struct vpn_data *data = vpn_provider_get_data(provider);
202
203         if ((data->flags & IFF_UP) != (flags & IFF_UP)) {
204                 if (flags & IFF_UP) {
205                         data->state = VPN_STATE_READY;
206                         vpn_provider_set_state(provider,
207                                         VPN_PROVIDER_STATE_READY);
208                 }
209         }
210         data->flags = flags;
211 }
212
213 static DBusMessage *vpn_notify(struct connman_task *task,
214                         DBusMessage *msg, void *user_data)
215 {
216         struct vpn_provider *provider = user_data;
217         struct vpn_data *data;
218         struct vpn_driver_data *vpn_driver_data;
219         const char *name;
220         int state, index, err;
221
222         data = vpn_provider_get_data(provider);
223
224         name = vpn_provider_get_driver_name(provider);
225
226         if (!name) {
227                 DBG("Cannot find VPN driver for provider %p", provider);
228                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
229                 return NULL;
230         }
231
232         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
233         if (!vpn_driver_data) {
234                 DBG("Cannot find VPN driver data for name %s", name);
235                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
236                 return NULL;
237         }
238
239         state = vpn_driver_data->vpn_driver->notify(msg, provider);
240
241         DBG("provider %p driver %s state %d", provider, name, state);
242
243         switch (state) {
244         case VPN_STATE_CONNECT:
245         case VPN_STATE_READY:
246                 if (data->state == VPN_STATE_READY) {
247                         /*
248                          * This is the restart case, in which case we must
249                          * just set the IP address.
250                          *
251                          * We need to remove first the old address, just
252                          * replacing the old address will not work as expected
253                          * because the old address will linger in the interface
254                          * and not disapper so the clearing is needed here.
255                          *
256                          * Also the state must change, otherwise the routes
257                          * will not be set properly.
258                          */
259                         vpn_provider_set_state(provider,
260                                                 VPN_PROVIDER_STATE_CONNECT);
261
262                         vpn_provider_clear_address(provider, AF_INET);
263                         vpn_provider_clear_address(provider, AF_INET6);
264
265                         vpn_provider_change_address(provider);
266                         vpn_provider_set_state(provider,
267                                                 VPN_PROVIDER_STATE_READY);
268                         break;
269                 }
270
271                 index = vpn_provider_get_index(provider);
272                 vpn_provider_ref(provider);
273                 data->watch = vpn_rtnl_add_newlink_watch(index,
274                                                      vpn_newlink, provider);
275                 err = connman_inet_ifup(index);
276                 if (err < 0) {
277                         if (err == -EALREADY)
278                                 /*
279                                  * So the interface is up already, that is just
280                                  * great. Unfortunately in this case the
281                                  * newlink watch might not have been called at
282                                  * all. We must manually call it here so that
283                                  * the provider can go to ready state and the
284                                  * routes are setup properly.
285                                  */
286                                 vpn_newlink(IFF_UP, 0, provider);
287                         else
288                                 DBG("Cannot take interface %d up err %d/%s",
289                                         index, -err, strerror(-err));
290                 }
291                 break;
292
293         case VPN_STATE_UNKNOWN:
294         case VPN_STATE_IDLE:
295         case VPN_STATE_DISCONNECT:
296         case VPN_STATE_FAILURE:
297                 vpn_provider_set_state(provider,
298                                         VPN_PROVIDER_STATE_DISCONNECT);
299                 break;
300
301         case VPN_STATE_AUTH_FAILURE:
302                 vpn_provider_indicate_error(provider,
303                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
304                 break;
305         }
306
307         return NULL;
308 }
309
310 #if defined TIZEN_EXT
311 static void vpn_event(struct vpn_provider *provider, int state)
312 {
313         struct vpn_data *data;
314         struct vpn_driver_data *vpn_driver_data;
315         const char *name;
316         int index, err;
317
318         data = vpn_provider_get_data(provider);
319
320         name = vpn_provider_get_driver_name(provider);
321
322         if (!name) {
323                 DBG("Cannot find VPN driver for provider %p", provider);
324                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
325                 return;
326         }
327
328         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
329         if (!vpn_driver_data) {
330                 DBG("Cannot find VPN driver data for name %s", name);
331                 vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
332                 return;
333         }
334
335         DBG("provider %p driver %s state %d", provider, name, state);
336
337         switch (state) {
338         case VPN_STATE_CONNECT:
339         case VPN_STATE_READY:
340                 if (data->state == VPN_STATE_READY) {
341                         /*
342                          * This is the restart case, in which case we must
343                          * just set the IP address.
344                          *
345                          * We need to remove first the old address, just
346                          * replacing the old address will not work as expected
347                          * because the old address will linger in the interface
348                          * and not disapper so the clearing is needed here.
349                          *
350                          * Also the state must change, otherwise the routes
351                          * will not be set properly.
352                          */
353                         vpn_provider_set_state(provider,
354                                                 VPN_PROVIDER_STATE_CONNECT);
355
356                         vpn_provider_clear_address(provider, AF_INET);
357                         vpn_provider_clear_address(provider, AF_INET6);
358
359                         vpn_provider_change_address(provider);
360                         vpn_provider_set_state(provider,
361                                                 VPN_PROVIDER_STATE_READY);
362                         break;
363                 }
364
365                 index = vpn_provider_get_index(provider);
366                 vpn_provider_ref(provider);
367                 data->watch = vpn_rtnl_add_newlink_watch(index,
368                                                      vpn_newlink, provider);
369                 err = connman_inet_ifup(index);
370                 if (err < 0) {
371                         if (err == -EALREADY)
372                                 /*
373                                  * So the interface is up already, that is just
374                                  * great. Unfortunately in this case the
375                                  * newlink watch might not have been called at
376                                  * all. We must manually call it here so that
377                                  * the provider can go to ready state and the
378                                  * routes are setup properly.
379                                  */
380                                 vpn_newlink(IFF_UP, 0, provider);
381                         else
382                                 DBG("Cannot take interface %d up err %d/%s",
383                                         index, -err, strerror(-err));
384                 }
385                 break;
386
387         case VPN_STATE_UNKNOWN:
388         case VPN_STATE_IDLE:
389         case VPN_STATE_DISCONNECT:
390         case VPN_STATE_FAILURE:
391                 vpn_provider_set_state(provider,
392                                         VPN_PROVIDER_STATE_DISCONNECT);
393                 break;
394
395         case VPN_STATE_AUTH_FAILURE:
396                 vpn_provider_indicate_error(provider,
397                                         VPN_PROVIDER_ERROR_AUTH_FAILED);
398                 break;
399         }
400
401         return;
402 }
403 #endif
404
405 static int vpn_create_tun(struct vpn_provider *provider)
406 {
407         struct vpn_data *data = vpn_provider_get_data(provider);
408         struct ifreq ifr;
409         int i, fd, index;
410         int ret = 0;
411
412         if (!data)
413                 return -EISCONN;
414
415         fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
416         if (fd < 0) {
417                 i = -errno;
418                 connman_error("Failed to open /dev/net/tun: %s",
419                               strerror(errno));
420                 ret = i;
421                 goto exist_err;
422         }
423
424         memset(&ifr, 0, sizeof(ifr));
425         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
426
427         for (i = 0; i < 256; i++) {
428                 sprintf(ifr.ifr_name, "vpn%d", i);
429
430                 if (!ioctl(fd, TUNSETIFF, (void *)&ifr))
431                         break;
432         }
433
434         if (i == 256) {
435                 connman_error("Failed to find available tun device");
436                 close(fd);
437                 ret = -ENODEV;
438                 goto exist_err;
439         }
440
441         data->if_name = (char *)g_strdup(ifr.ifr_name);
442         if (!data->if_name) {
443                 connman_error("Failed to allocate memory");
444                 close(fd);
445                 ret = -ENOMEM;
446                 goto exist_err;
447         }
448
449         if (ioctl(fd, TUNSETPERSIST, 1)) {
450                 i = -errno;
451                 connman_error("Failed to set tun persistent: %s",
452                               strerror(errno));
453                 close(fd);
454                 ret = i;
455                 goto exist_err;
456         }
457
458         close(fd);
459
460         index = connman_inet_ifindex(data->if_name);
461         if (index < 0) {
462                 connman_error("Failed to get tun ifindex");
463                 stop_vpn(provider);
464                 ret = -EIO;
465                 goto exist_err;
466         }
467         vpn_provider_set_index(provider, index);
468
469         return 0;
470
471 exist_err:
472         return ret;
473 }
474
475 static int vpn_connect(struct vpn_provider *provider,
476                         vpn_provider_connect_cb_t cb,
477                         const char *dbus_sender, void *user_data)
478 {
479         struct vpn_data *data = vpn_provider_get_data(provider);
480         struct vpn_driver_data *vpn_driver_data;
481         const char *name;
482         int ret = 0;
483         enum vpn_state state = VPN_STATE_UNKNOWN;
484
485         if (data)
486                 state = data->state;
487
488         DBG("data %p state %d", data, state);
489
490         switch (state) {
491         case VPN_STATE_UNKNOWN:
492                 data = g_try_new0(struct vpn_data, 1);
493                 if (!data)
494                         return -ENOMEM;
495
496                 data->provider = vpn_provider_ref(provider);
497                 data->watch = 0;
498                 data->flags = 0;
499                 data->task = NULL;
500
501                 vpn_provider_set_data(provider, data);
502                 /* fall through */
503
504         case VPN_STATE_DISCONNECT:
505         case VPN_STATE_IDLE:
506         case VPN_STATE_FAILURE:
507         case VPN_STATE_AUTH_FAILURE:
508                 data->state = VPN_STATE_IDLE;
509                 break;
510
511         case VPN_STATE_CONNECT:
512                 return -EINPROGRESS;
513
514         case VPN_STATE_READY:
515                 return -EISCONN;
516         }
517
518         name = vpn_provider_get_driver_name(provider);
519         if (!name)
520                 return -EINVAL;
521
522         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
523
524         if (!vpn_driver_data || !vpn_driver_data->vpn_driver) {
525                 ret = -EINVAL;
526                 goto exist_err;
527         }
528
529         if (vpn_driver_data->vpn_driver->flags != VPN_FLAG_NO_TUN) {
530                 ret = vpn_create_tun(provider);
531                 if (ret < 0)
532                         goto exist_err;
533         }
534
535         data->task = connman_task_create(vpn_driver_data->program);
536
537         if (!data->task) {
538                 ret = -ENOMEM;
539                 stop_vpn(provider);
540                 goto exist_err;
541         }
542
543         if (connman_task_set_notify(data->task, "notify",
544                                         vpn_notify, provider)) {
545                 ret = -ENOMEM;
546                 stop_vpn(provider);
547                 connman_task_destroy(data->task);
548                 data->task = NULL;
549                 goto exist_err;
550         }
551
552
553 #if defined TIZEN_EXT
554         if(vpn_driver_data->vpn_driver->set_event_cb)
555                 vpn_driver_data->vpn_driver->set_event_cb(vpn_event, provider);
556 #endif
557
558         ret = vpn_driver_data->vpn_driver->connect(provider, data->task,
559                                                 data->if_name, cb, dbus_sender,
560                                                 user_data);
561         if (ret < 0 && ret != -EINPROGRESS) {
562                 stop_vpn(provider);
563                 connman_task_destroy(data->task);
564                 data->task = NULL;
565                 goto exist_err;
566         }
567
568         DBG("%s started with dev %s",
569                 vpn_driver_data->provider_driver.name, data->if_name);
570
571         data->state = VPN_STATE_CONNECT;
572
573         return -EINPROGRESS;
574
575 exist_err:
576         vpn_provider_set_index(provider, -1);
577         vpn_provider_set_data(provider, NULL);
578         vpn_provider_unref(data->provider);
579         g_free(data->if_name);
580         g_free(data);
581
582         return ret;
583 }
584
585 static int vpn_probe(struct vpn_provider *provider)
586 {
587         return 0;
588 }
589
590 static int vpn_disconnect(struct vpn_provider *provider)
591 {
592         struct vpn_data *data = vpn_provider_get_data(provider);
593         struct vpn_driver_data *vpn_driver_data;
594         const char *name;
595
596         DBG("disconnect provider %p:", provider);
597
598         if (!data)
599                 return 0;
600
601         name = vpn_provider_get_driver_name(provider);
602         if (!name)
603                 return 0;
604
605         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
606         if (vpn_driver_data->vpn_driver->disconnect)
607                 vpn_driver_data->vpn_driver->disconnect(provider);
608
609         if (data->watch != 0) {
610                 vpn_provider_unref(provider);
611                 vpn_rtnl_remove_watch(data->watch);
612                 data->watch = 0;
613         }
614
615         data->state = VPN_STATE_DISCONNECT;
616         connman_task_stop(data->task);
617
618         return 0;
619 }
620
621 static int vpn_remove(struct vpn_provider *provider)
622 {
623         struct vpn_data *data;
624
625         data = vpn_provider_get_data(provider);
626         if (!data)
627                 return 0;
628
629         if (data->watch != 0) {
630                 vpn_provider_unref(provider);
631                 vpn_rtnl_remove_watch(data->watch);
632                 data->watch = 0;
633         }
634
635         connman_task_stop(data->task);
636
637         g_usleep(G_USEC_PER_SEC);
638         stop_vpn(provider);
639         return 0;
640 }
641
642 static int vpn_save(struct vpn_provider *provider, GKeyFile *keyfile)
643 {
644         struct vpn_driver_data *vpn_driver_data;
645         const char *name;
646
647         name = vpn_provider_get_driver_name(provider);
648         vpn_driver_data = g_hash_table_lookup(driver_hash, name);
649         if (vpn_driver_data &&
650                         vpn_driver_data->vpn_driver->save)
651                 return vpn_driver_data->vpn_driver->save(provider, keyfile);
652
653         return 0;
654 }
655
656 int vpn_register(const char *name, struct vpn_driver *vpn_driver,
657                         const char *program)
658 {
659         struct vpn_driver_data *data;
660
661         data = g_try_new0(struct vpn_driver_data, 1);
662         if (!data)
663                 return -ENOMEM;
664
665         data->name = name;
666         data->program = program;
667
668         data->vpn_driver = vpn_driver;
669
670         data->provider_driver.name = name;
671         data->provider_driver.disconnect = vpn_disconnect;
672         data->provider_driver.connect = vpn_connect;
673         data->provider_driver.probe = vpn_probe;
674         data->provider_driver.remove = vpn_remove;
675         data->provider_driver.save = vpn_save;
676
677         if (!driver_hash)
678                 driver_hash = g_hash_table_new_full(g_str_hash,
679                                                         g_str_equal,
680                                                         NULL, g_free);
681
682         if (!driver_hash) {
683                 connman_error("driver_hash not initialized for %s", name);
684                 g_free(data);
685                 return -ENOMEM;
686         }
687
688         g_hash_table_replace(driver_hash, (char *)name, data);
689
690         vpn_provider_driver_register(&data->provider_driver);
691
692         return 0;
693 }
694
695 void vpn_unregister(const char *name)
696 {
697         struct vpn_driver_data *data;
698
699         data = g_hash_table_lookup(driver_hash, name);
700         if (!data)
701                 return;
702
703         vpn_provider_driver_unregister(&data->provider_driver);
704
705         g_hash_table_remove(driver_hash, name);
706
707         if (g_hash_table_size(driver_hash) == 0)
708                 g_hash_table_destroy(driver_hash);
709 }