From ab9933e33e5e7b5066659b4c8911480a70f360f5 Mon Sep 17 00:00:00 2001
From: Arne Schwabe <arne@rfc2549.org>
Date: Sun, 6 May 2012 23:52:22 +0200
Subject: All control of openvpn is now over the unix socket. JNI is only used
 for starting openvpn.

Fix configuration if no DNS information is available. (closes issue #7 hopefully)

Version 0.5.0
---
 openvpn/src/openvpn/manage.c | 50 +++++++++++++++++++++++++++++++++++++++++++-
 openvpn/src/openvpn/manage.h |  1 +
 openvpn/src/openvpn/tun.c    |  8 ++++++-
 3 files changed, 57 insertions(+), 2 deletions(-)

(limited to 'openvpn/src')

diff --git a/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c
index f28278f..96ca6ea 100644
--- a/openvpn/src/openvpn/manage.c
+++ b/openvpn/src/openvpn/manage.c
@@ -67,6 +67,7 @@ struct management *management; /* GLOBAL */
 static void man_output_standalone (struct management *man, volatile int *signal_received);
 static void man_reset_client_socket (struct management *man, const bool exiting);
 static ssize_t write_fd (int fd, void *ptr, size_t nbytes, int flags, int sendfd);
+static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int flags, int *recvfd);
 
 
 static void
@@ -1815,8 +1816,15 @@ man_read (struct management *man)
    */
   unsigned char buf[256];
   int len = 0;
+  int fd = -1;
 
-  len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
+#ifdef TARGET_ANDROID
+    len = read_fd (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL, &fd);
+    if(fd >= 0)
+        man->connection.lastfdreceived = fd;
+#else
+    len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);
+#endif
   if (len == 0)
     {
       man_reset_client_socket (man, false);
@@ -3092,6 +3100,7 @@ management_query_rsa_sig (struct management *man,
 
 #endif
 
+#ifdef TARGET_ANDROID
 static ssize_t write_fd (int fd, void *ptr, size_t nbytes, int flags, int sendfd)
 {
     struct msghdr msg;
@@ -3123,6 +3132,45 @@ static ssize_t write_fd (int fd, void *ptr, size_t nbytes, int flags, int sendfd
     return (sendmsg(fd, &msg, flags));
 }
 
+static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int flags, int *recvfd)
+{
+    struct msghdr msghdr;
+    struct iovec iov[1];
+    ssize_t n;
+    
+    union {
+        struct cmsghdr cm;
+        char     control[CMSG_SPACE(sizeof (int))];
+    } control_un;
+    struct cmsghdr  *cmptr;
+    
+    msghdr.msg_control  = control_un.control;
+    msghdr.msg_controllen = sizeof(control_un.control);
+    
+    msghdr.msg_name = NULL;
+    msghdr.msg_namelen = 0;
+    
+    iov[0].iov_base = ptr;
+    iov[0].iov_len = nbytes;
+    msghdr.msg_iov = iov;
+    msghdr.msg_iovlen = 1;
+    
+    if ( (n = recvmsg(fd, &msghdr, flags)) <= 0)
+        return (n);
+    
+    if ( (cmptr = CMSG_FIRSTHDR(&msghdr)) != NULL &&
+        cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
+        if (cmptr->cmsg_level != SOL_SOCKET)
+            msg (M_ERR, "control level != SOL_SOCKET");
+        if (cmptr->cmsg_type != SCM_RIGHTS)
+            msg (M_ERR, "control type != SCM_RIGHTS");
+        *recvfd = *((int *) CMSG_DATA(cmptr));
+    } else
+        *recvfd = -1;           /* descriptor was not passed */
+    
+    return (n);
+}
+#endif
 
 
 /*
diff --git a/openvpn/src/openvpn/manage.h b/openvpn/src/openvpn/manage.h
index 71e1a84..c7ffb42 100644
--- a/openvpn/src/openvpn/manage.h
+++ b/openvpn/src/openvpn/manage.h
@@ -305,6 +305,7 @@ struct man_connection {
 #endif
 #ifdef TARGET_ANDROID
     int fdtosend;
+    int lastfdreceived;
 #endif
     
 };
diff --git a/openvpn/src/openvpn/tun.c b/openvpn/src/openvpn/tun.c
index 66a09ea..d212376 100644
--- a/openvpn/src/openvpn/tun.c
+++ b/openvpn/src/openvpn/tun.c
@@ -1401,7 +1401,13 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu
         management_query_user_pass(management, &up , "DNSDOMAIN", GET_USER_PASS_NEED_OK,(void*) 0);
     }
     
-    if((tt->fd = android_open_tun())< 0){
+    strcpy(up.username , dev);
+    management_query_user_pass(management, &up , "OPENTUN", GET_USER_PASS_NEED_OK,(void*) 0);
+
+    tt->fd = management->connection.lastfdreceived;
+    management->connection.lastfdreceived=-1;
+    
+    if( (tt->fd < 0) || ! (strcmp("ok",up.password)==0)) {
         msg (M_ERR, "ERROR: Cannot open TUN");
     }
     gc_free (&gc);
-- 
cgit v1.2.3