Browse code

Android platform specific changes.

On Android 4.0 (TARGET_ANDROID) the real opening of the tun is handled by
the (Java) application controlling OpenVPN. Instead of calling
ifconfig/route call the management to do the work. When running openvpn as
root openvpn should be compiled as TARGET_LINUX

Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <1367350151-23089-1-git-send-email-arne@rfc2549.org>
URL: http://article.gmane.org/gmane.network.openvpn.devel/7570
Signed-off-by: Gert Doering <gert@greenie.muc.de>

Arne Schwabe authored on 2013/05/01 04:29:11
Showing 9 changed files
... ...
@@ -1849,6 +1849,20 @@ static ssize_t man_recv_with_fd (int fd, void *ptr, size_t nbytes, int flags, in
1849 1849
 
1850 1850
   return (n);
1851 1851
 }
1852
+
1853
+/*
1854
+ * The android control method will instruct the GUI part of openvpn to do
1855
+ * the route/ifconfig/open tun command.   See doc/android.txt for details.
1856
+ */
1857
+bool management_android_control (struct management *man, const char *command, const char *msg)
1858
+{
1859
+  struct user_pass up;
1860
+  CLEAR(up);
1861
+  strncpy (up.username, msg, sizeof(up.username)-1);
1862
+
1863
+  management_query_user_pass(management, &up , command, GET_USER_PASS_NEED_OK,(void*) 0);
1864
+  return strcmp ("ok", up.password)==0;
1865
+}
1852 1866
 #endif
1853 1867
 
1854 1868
 static int
... ...
@@ -376,6 +376,10 @@ bool management_query_user_pass (struct management *man,
376 376
 				 const unsigned int flags,
377 377
 				 const char *static_challenge);
378 378
 
379
+#ifdef TARGET_ANDROID
380
+bool management_android_control (struct management *man, const char *command, const char *msg);
381
+#endif
382
+
379 383
 bool management_should_daemonize (struct management *man);
380 384
 bool management_would_hold (struct management *man);
381 385
 bool management_hold (struct management *man);
... ...
@@ -1125,7 +1125,9 @@ show_tuntap_options (const struct tuntap_options *o)
1125 1125
 }
1126 1126
 
1127 1127
 #endif
1128
+#endif
1128 1129
 
1130
+#if defined(WIN32) || defined(TARGET_ANDROID)
1129 1131
 static void
1130 1132
 dhcp_option_address_parse (const char *name, const char *parm, in_addr_t *array, int *len, int msglevel)
1131 1133
 {
... ...
@@ -5935,6 +5937,8 @@ add_option (struct options *options,
5935 5935
       to->ip_win32_type = index;
5936 5936
       to->ip_win32_defined = true; 
5937 5937
     }
5938
+#endif
5939
+#if defined(WIN32) || defined(TARGET_ANDROID)
5938 5940
   else if (streq (p[0], "dhcp-option") && p[1])
5939 5941
     {
5940 5942
       struct tuntap_options *o = &options->tuntap_options;
... ...
@@ -5986,6 +5990,8 @@ add_option (struct options *options,
5986 5986
 	}
5987 5987
       o->dhcp_options = true;
5988 5988
     }
5989
+#endif
5990
+#ifdef WIN32
5989 5991
   else if (streq (p[0], "show-adapters"))
5990 5992
     {
5991 5993
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -1342,6 +1342,12 @@ add_route (struct route *r,
1342 1342
   argv_msg (D_ROUTE, &argv);
1343 1343
   status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
1344 1344
 
1345
+#elif defined (TARGET_ANDROID)
1346
+  struct buffer out = alloc_buf_gc (64, &gc);
1347
+
1348
+  buf_printf (&out, "%s %s", network, netmask);
1349
+  management_android_control (management, "ROUTE", buf_bptr(&out));
1350
+
1345 1351
 #elif defined (WIN32)
1346 1352
   {
1347 1353
     DWORD ai = TUN_ADAPTER_INDEX_INVALID;
... ...
@@ -1616,6 +1622,13 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla
1616 1616
   argv_msg (D_ROUTE, &argv);
1617 1617
   status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
1618 1618
 
1619
+#elif defined (TARGET_ANDROID)
1620
+    struct buffer out = alloc_buf_gc (64, &gc);
1621
+
1622
+    buf_printf (&out, "%s/%d", network, r6->netbits);
1623
+
1624
+    management_android_control (management, "ROUTE6", buf_bptr(&out));
1625
+
1619 1626
 #elif defined (WIN32)
1620 1627
 
1621 1628
   /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
... ...
@@ -1875,7 +1888,8 @@ delete_route (struct route *r,
1875 1875
 
1876 1876
   argv_msg (D_ROUTE, &argv);
1877 1877
   openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
1878
-
1878
+#elif defined(TARGET_ANDROID)
1879
+  msg (M_NONFATAL, "Sorry, deleting routes on Android is not possible. The VpnService API allows routes to be set on connect only.");
1879 1880
 #else
1880 1881
   msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system.  Try putting your routes in a --route-up script");
1881 1882
 #endif
... ...
@@ -2425,7 +2439,7 @@ show_routes (int msglev)
2425 2425
   gc_free (&gc);
2426 2426
 }
2427 2427
 
2428
-#elif defined(TARGET_LINUX)
2428
+#elif defined(TARGET_LINUX) || defined(TARGET_ANDROID)
2429 2429
 
2430 2430
 void
2431 2431
 get_default_gateway (struct route_gateway_info *rgi)
... ...
@@ -38,6 +38,7 @@
38 38
 #include "ps.h"
39 39
 #include "manage.h"
40 40
 #include "misc.h"
41
+#include "manage.h"
41 42
 
42 43
 #include "memdbg.h"
43 44
 
... ...
@@ -725,6 +726,15 @@ create_socket (struct link_socket *sock)
725 725
     {
726 726
       ASSERT (0);
727 727
     }
728
+#ifdef TARGET_ANDROID
729
+  /* pass socket FD to management interface to pass on to VPNService API
730
+   * as "protected socket" (exempt from being routed into tunnel)
731
+   */
732
+
733
+  management->connection.fdtosend = sock->sd;
734
+  management_android_control (management, "PROTECTFD", __func__);
735
+#endif
736
+
728 737
 }
729 738
 
730 739
 /*
... ...
@@ -1797,6 +1797,8 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
1797 1797
       buf_printf (&out, "IV_PLAT=netbsd\n");
1798 1798
 #elif defined(TARGET_FREEBSD)
1799 1799
       buf_printf (&out, "IV_PLAT=freebsd\n");
1800
+#elif defined(TARGET_ANDROID)
1801
+      buf_printf (&out, "IV_PLAT=android\n");
1800 1802
 #elif defined(WIN32)
1801 1803
       buf_printf (&out, "IV_PLAT=win\n");
1802 1804
 #endif
... ...
@@ -212,7 +212,7 @@
212 212
 #include <net/if_tap.h>
213 213
 #endif
214 214
 
215
-#ifdef TARGET_LINUX
215
+#if defined(TARGET_LINUX) || defined (TARGET_ANDROID)
216 216
 
217 217
 #if defined(HAVE_NETINET_IF_ETHER_H)
218 218
 #include <netinet/if_ether.h>
... ...
@@ -48,6 +48,7 @@
48 48
 #include "win32.h"
49 49
 
50 50
 #include "memdbg.h"
51
+#include <string.h>
51 52
 
52 53
 #ifdef WIN32
53 54
 
... ...
@@ -764,6 +765,34 @@ do_ifconfig (struct tuntap *tt,
764 764
       tt->did_ifconfig = true;
765 765
 
766 766
 #endif /*ENABLE_IPROUTE*/
767
+#elif defined(TARGET_ANDROID)
768
+
769
+      if (do_ipv6) {
770
+          struct buffer out6 = alloc_buf_gc (64, &gc);
771
+          buf_printf (&out6, "%s/%d", ifconfig_ipv6_local,tt->netbits_ipv6);
772
+          management_android_control(management, "IFCONFIG6",buf_bptr(&out6));
773
+      }
774
+
775
+      struct buffer out = alloc_buf_gc (64, &gc);
776
+
777
+      char* top;
778
+      switch(tt->topology) {
779
+      case TOP_NET30:
780
+          top="net30";
781
+          break;
782
+      case TOP_P2P:
783
+          top="p2p";
784
+          break;
785
+      case TOP_SUBNET:
786
+          top="subnet";
787
+          break;
788
+      default:
789
+          top="undef";
790
+      }
791
+
792
+      buf_printf (&out, "%s %s %d %s", ifconfig_local, ifconfig_remote_netmask, tun_mtu, top);
793
+      management_android_control (management, "IFCONFIG", buf_bptr(&out));
794
+
767 795
 #elif defined(TARGET_SOLARIS)
768 796
 
769 797
       /* Solaris 2.6 (and 7?) cannot set all parameters in one go...
... ...
@@ -1368,8 +1397,62 @@ close_tun_generic (struct tuntap *tt)
1368 1368
 
1369 1369
 #endif
1370 1370
 
1371
-#if defined(TARGET_LINUX)
1371
+#if defined (TARGET_ANDROID)
1372
+void
1373
+open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
1374
+{
1375
+#define ANDROID_TUNNAME "vpnservice-tun"
1376
+  int i;
1377
+  struct user_pass up;
1378
+  struct gc_arena gc = gc_new ();
1379
+  bool opentun;
1380
+
1381
+  for (i = 0; i < tt->options.dns_len; ++i) {
1382
+    management_android_control (management, "DNSSERVER",
1383
+                                print_in_addr_t(tt->options.dns[i], 0, &gc));
1384
+  }
1385
+
1386
+  if(tt->options.domain)
1387
+    management_android_control (management, "DNSDOMAIN", tt->options.domain);
1388
+
1389
+  opentun = management_android_control (management, "OPENTUN", dev);
1390
+
1391
+  /* Pick up the fd from management interface after calling the OPENTUN command */
1392
+  tt->fd = management->connection.lastfdreceived;
1393
+  management->connection.lastfdreceived=-1;
1394
+
1395
+  /* Set the actual name to a dummy name */
1396
+  tt->actual_name = string_alloc (ANDROID_TUNNAME, NULL);
1397
+
1398
+  if ((tt->fd < 0) || !opentun)
1399
+    msg (M_ERR, "ERROR: Cannot open TUN");
1400
+
1401
+  gc_free (&gc);
1402
+}
1403
+
1404
+void
1405
+close_tun (struct tuntap *tt)
1406
+{
1407
+    if (tt)
1408
+    {
1409
+        close_tun_generic (tt);
1410
+        free (tt);
1411
+    }
1412
+}
1413
+
1414
+int
1415
+write_tun (struct tuntap* tt, uint8_t *buf, int len)
1416
+{
1417
+    return write (tt->fd, buf, len);
1418
+}
1419
+
1420
+int
1421
+read_tun (struct tuntap* tt, uint8_t *buf, int len)
1422
+{
1423
+    return read (tt->fd, buf, len);
1424
+}
1372 1425
 
1426
+#elif defined(TARGET_LINUX)
1373 1427
 #ifdef HAVE_LINUX_IF_TUN_H	/* New driver support */
1374 1428
 
1375 1429
 #ifndef HAVE_LINUX_SOCKIOS_H
... ...
@@ -38,7 +38,7 @@
38 38
 #include "proto.h"
39 39
 #include "misc.h"
40 40
 
41
-#ifdef WIN32
41
+#if defined(WIN32) || defined(TARGET_ANDROID)
42 42
 
43 43
 #define TUN_ADAPTER_INDEX_INVALID ((DWORD)-1)
44 44
 
... ...
@@ -292,6 +292,8 @@ ifconfig_order(void)
292 292
   return IFCONFIG_AFTER_TUN_OPEN;
293 293
 #elif defined(WIN32)
294 294
   return IFCONFIG_BEFORE_TUN_OPEN;
295
+#elif defined(TARGET_ANDROID)
296
+  return IFCONFIG_BEFORE_TUN_OPEN;
295 297
 #else
296 298
   return IFCONFIG_DEFAULT;
297 299
 #endif
... ...
@@ -304,7 +306,11 @@ ifconfig_order(void)
304 304
 static inline int
305 305
 route_order(void)
306 306
 {
307
+#if defined(TARGET_ANDROID)
308
+    return ROUTE_BEFORE_TUN;
309
+#else
307 310
     return ROUTE_ORDER_DEFAULT;
311
+#endif
308 312
 }
309 313
 
310 314