From ab9933e33e5e7b5066659b4c8911480a70f360f5 Mon Sep 17 00:00:00 2001 From: Arne Schwabe 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') 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