diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2012-04-16 19:21:14 +0200 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2012-04-16 19:21:14 +0200 | 
| commit | 3e4d8f433239c40311037616b1b8833a06651ae0 (patch) | |
| tree | 98ab7fce0d011d34677b0beb762d389cb5c39199 /openvpn/0001-initial-android-hacks.patch | |
Initial import
Diffstat (limited to 'openvpn/0001-initial-android-hacks.patch')
| -rw-r--r-- | openvpn/0001-initial-android-hacks.patch | 523 | 
1 files changed, 523 insertions, 0 deletions
| diff --git a/openvpn/0001-initial-android-hacks.patch b/openvpn/0001-initial-android-hacks.patch new file mode 100644 index 00000000..e78cc7de --- /dev/null +++ b/openvpn/0001-initial-android-hacks.patch @@ -0,0 +1,523 @@ +From d573932062cb4afd7f001899978e37ce446934e7 Mon Sep 17 00:00:00 2001 +From: Arne Schwabe <arne@rfc2549.org> +Date: Tue, 10 Apr 2012 00:34:51 +0200 +Subject: [PATCH] initial android hacks + +--- + src/compat/compat-rsa_generate_key.c |   47 ++++++++++ + src/openvpn/error.c                  |   19 ++++- + src/openvpn/jniglue.c                |  162 ++++++++++++++++++++++++++++++++++ + src/openvpn/jniglue.h                |   19 ++++ + src/openvpn/options.c                |    1 + + src/openvpn/route.c                  |    7 ++- + src/openvpn/socket.c                 |   25 +++++ + src/openvpn/ssl.c                    |    2 + + src/openvpn/syshead.h                |    2 +- + src/openvpn/tun.c                    |   22 ++++- + src/openvpn/tun.h                    |    2 + + 11 files changed, 303 insertions(+), 5 deletions(-) + create mode 100644 src/compat/compat-rsa_generate_key.c + create mode 100644 src/openvpn/jniglue.c + create mode 100644 src/openvpn/jniglue.h + +diff --git a/src/compat/compat-rsa_generate_key.c b/src/compat/compat-rsa_generate_key.c +new file mode 100644 +index 0000000..99725da +--- /dev/null ++++ b/src/compat/compat-rsa_generate_key.c +@@ -0,0 +1,47 @@ ++#include <stdio.h> ++#include <time.h> ++#include "cryptlib.h" ++#include <openssl/bn.h> ++#include <openssl/rsa.h> ++ ++RSA *RSA_generate_key(int bits, unsigned long e_value, ++		      void (*callback)(int,int,void *), void *cb_arg) ++{ ++  BN_GENCB cb; ++  int i; ++  RSA *rsa = RSA_new(); ++  BIGNUM *e = BN_new(); ++ ++  if(!rsa || !e) goto err; ++ ++  /* The problem is when building with 8, 16, or 32 BN_ULONG, ++   * unsigned long can be larger */ ++  for (i=0; i<(int)sizeof(unsigned long)*8; i++) ++    { ++      if (e_value & (1UL<<i)) ++	if (BN_set_bit(e,i) == 0) ++	  goto err; ++    } ++ ++  BN_GENCB_set_old(&cb, callback, cb_arg); ++ ++  if(RSA_generate_key_ex(rsa, bits, e, &cb)) { ++    BN_free(e); ++    return rsa; ++  } ++ err: ++  if(e) BN_free(e); ++  if(rsa) RSA_free(rsa); ++  return 0; ++} ++ ++ ++ ++void mlockall(){} ++char * ++getpass (prompt) ++     const char *prompt; ++{ ++  return ""; ++} ++ +diff --git a/src/openvpn/error.c b/src/openvpn/error.c +index d6ad639..d4a3cff 100644 +--- a/src/openvpn/error.c ++++ b/src/openvpn/error.c +@@ -199,6 +199,16 @@ msg_fp(const unsigned int flags) +  + int x_msg_line_num; /* GLOBAL */ +  ++#include "android/log.h" ++void x_msg2(const unsigned int flags, const char *format, ...) { ++    va_list arglist; ++    va_start(arglist,format); ++    //	vsnprintf(m1, 100, "foo bbaz",arglist); ++    __android_log_vprint(ANDROID_LOG_DEBUG, "openvpn",format, arglist); ++    va_end(arglist); ++} ++ ++ + void x_msg (const unsigned int flags, const char *format, ...) + { +   struct gc_arena gc; +@@ -350,6 +360,10 @@ void x_msg (const unsigned int flags, const char *format, ...) + 	} +     } +  ++#ifdef TARGET_ANDROID ++   android_openvpn_log(prefix,prefix_sep,m1);; ++#endif ++     +   if (flags & M_FATAL) +     msg (M_INFO, "Exiting due to fatal error"); +  +@@ -701,7 +715,10 @@ openvpn_exit (const int status) +       if (status == OPENVPN_EXIT_STATUS_GOOD) + 	perf_output_results (); +     } +- ++#ifdef TARGET_ANDROID ++    android_openvpn_exit(status); ++#endif ++     +   exit (status); + } +  +diff --git a/src/openvpn/jniglue.c b/src/openvpn/jniglue.c +new file mode 100644 +index 0000000..2d52936 +--- /dev/null ++++ b/src/openvpn/jniglue.c +@@ -0,0 +1,162 @@ ++#include <jni.h> ++#include <android/log.h> ++#include <stdlib.h> ++#include <setjmp.h> ++ ++#include "jniglue.h" ++ ++JNIEXPORT jint Java_de_blinkt_OpenVPN_startOpenVPNThread(JNIEnv* env, jclass jc); ++ ++ ++extern int main (int argc, char *argv[]); ++ ++static jmp_buf jump_buffer; ++ ++int callmain (int argc, char *argv[]) { ++    if(!setjmp(jump_buffer)) ++        main(argc,argv); ++} ++ ++ ++void android_openvpn_exit(int status) { ++    longjmp(jump_buffer,status+1); ++} ++ ++ ++void testmsg(char* m1, ...) { ++	va_list arglist; ++	va_start(arglist,m1); ++	//	vsnprintf(m1, 100, "foo bbaz",arglist); ++	__android_log_vprint(ANDROID_LOG_DEBUG, "openvpn",m1, arglist); ++		va_end(arglist); ++} ++ ++// Store env and class, we allow only one instance ++// so make these variables global for now ++jclass openvpnclass; ++JNIEnv* openvpnjenv; ++ ++//Lde/blinkt/openvpn/OpenVPN startOpenVPNThread startOpenVPNThread ++ jint Java_de_blinkt_openvpn_OpenVPN_startOpenVPNThread(JNIEnv* env, jclass jc){ ++    char* argv[] = {"openvpn", "--client", ++                    "--dev","tun", ++                    "--comp-lzo", ++//                    "--redirect-gateway","def1", ++//                    "--pkcs12","/mnt/sdcard/Network_Certificate.p12", ++                    "--remote-cert-eku", "TLS Web Server Authentication", ++                    "--remote","openvpn.uni-paderborn.de", ++                    "--ca","/mnt/sdcard/ca.pem", ++                    "--key","/mnt/sdcard/schwabe.key", ++                    "--cert","/mnt/sdcard/schwabe.pem", ++                    "--verb","4" ++                }; ++      ++     openvpnclass = jc; ++     openvpnjenv= env; ++     int argc=17; ++ ++    return callmain(argc,argv); ++ } ++ ++void Java_de_blinkt_openvpn_OpenVPN_startOpenVPNThreadArgs(JNIEnv *env,jclass jc, jobjectArray stringArray) { ++    openvpnclass = jc; ++    openvpnjenv= env; ++     ++    int stringCount = (*env)->GetArrayLength(env, stringArray); ++     ++     ++    const char** argv = calloc(stringCount,sizeof(const char*)); ++     ++    int i; ++    for (i=0; i<stringCount; i++) { ++        jstring string = (jstring) (*env)->GetObjectArrayElement(env, stringArray, i); ++        jboolean isCopy; ++        const char* rawString = (*env)->GetStringUTFChars(env, string, &isCopy); ++         ++        // Copy the string to able to release it ++        argv[i] = rawString; ++ ++    } ++     ++    // Call main ++    callmain(stringCount,argv); ++     ++    // Release the Strings ++    for(i=0; i<stringCount;i++){ ++        jstring string = (jstring) (*env)->GetObjectArrayElement(env, stringArray, i); ++        (*env)->ReleaseStringUTFChars(env,string,argv[i]); ++    } ++    free(argv); ++} ++     ++ ++ ++ ++jint JNI_OnLoad(JavaVM *vm, void *reserved) { ++    __android_log_write(ANDROID_LOG_DEBUG,"openvpn", "Loading openvpn native library $id$ compiled on "   __DATE__ " " __TIME__ ); ++    return JNI_VERSION_1_2; ++} ++ ++void addInterfaceInformation(int mtu,const char* ifconfig_local, const char* ifconfig_remote) ++{ ++    jstring jlocal = (*openvpnjenv)->NewStringUTF(openvpnjenv, ifconfig_local); ++    jstring jremote = (*openvpnjenv)->NewStringUTF(openvpnjenv, ifconfig_remote); ++ ++    jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "addInterfaceInfo",  ++                                                            "(ILjava/lang/String;Ljava/lang/String;)V"); ++    (*openvpnjenv)->CallStaticVoidMethod(openvpnjenv,openvpnclass,aMethodID,mtu,jlocal,jremote); ++     ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jlocal); ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jremote); ++ ++     ++} ++ ++void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,const char* m1) ++{ ++    __android_log_print(ANDROID_LOG_DEBUG,"openvpn","%s%s%s",prefix,prefix_sep,m1); ++ ++    jstring jprefix = (*openvpnjenv)->NewStringUTF(openvpnjenv, prefix); ++    jstring jmessage = (*openvpnjenv)->NewStringUTF(openvpnjenv, m1); ++     ++    jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "logMessage",  ++                                                            "(ILjava/lang/String;Ljava/lang/String;)V"); ++     ++    (*openvpnjenv)->CallStaticVoidMethod(openvpnjenv,openvpnclass,aMethodID,level,jprefix,jmessage); ++     ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jprefix); ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jmessage); ++     ++} ++ ++ ++unsigned char android_protect_socket(int sockfd) { ++    jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "protectSocket",  ++                                                            "(I)Z"); ++    return (*openvpnjenv)->CallStaticBooleanMethod(openvpnjenv,openvpnclass,aMethodID,sockfd); ++ ++} ++int android_open_tun () { ++    jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "openTunDevice",  ++                                                            "()I"); ++    return (*openvpnjenv)->CallStaticIntMethod(openvpnjenv,openvpnclass,aMethodID); ++ ++} ++ ++void addRouteInformation(const char* dest, const char* mask, const char* gw) { ++     ++    jstring jmask =  (*openvpnjenv)->NewStringUTF(openvpnjenv, mask); ++    jstring jdest =  (*openvpnjenv)->NewStringUTF(openvpnjenv, dest); ++    jstring jgw =    (*openvpnjenv)->NewStringUTF(openvpnjenv, gw); ++    jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "addRoute",  ++                                            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); ++    (*openvpnjenv)->CallStaticVoidMethod(openvpnjenv,openvpnclass,aMethodID,jdest,jmask,jgw); ++ ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jmask); ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jdest); ++    (*openvpnjenv)->DeleteLocalRef(openvpnjenv,jgw); ++ ++ ++} ++ ++ +diff --git a/src/openvpn/jniglue.h b/src/openvpn/jniglue.h +new file mode 100644 +index 0000000..cb3ae41 +--- /dev/null ++++ b/src/openvpn/jniglue.h +@@ -0,0 +1,19 @@ ++// ++//  jniglue.h ++//  xcopenvpn ++// ++//  Created by Arne Schwabe on 29.03.12. ++//  Copyright (c) 2012 Universität Paderborn. All rights reserved. ++// ++ ++#ifndef xcopenvpn_jniglue_h ++#define xcopenvpn_jniglue_h ++ ++void testmsg(char* m1, ...); ++void addRouteInformation(const char* dest, const char* mask, const char* gw); ++void addInterfaceInformation(int mtu,const char* ifconfig_local, const char* ifconfig_remote); ++void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,const char* m1); ++void android_openvpn_exit(int status); ++ ++ ++#endif +diff --git a/src/openvpn/options.c b/src/openvpn/options.c +index bd83843..fcf436c 100644 +--- a/src/openvpn/options.c ++++ b/src/openvpn/options.c +@@ -560,6 +560,7 @@ static const char usage_message[] = + #if OPENSSL_VERSION_NUMBER >= 0x00907000L +   " and CRLs).\n" + #else /* OPENSSL_VERSION_NUMBER >= 0x00907000L */ ++#error WTF! +   ").\n" +   "                  WARNING: no support of CRL available with this version.\n" + #endif /* OPENSSL_VERSION_NUMBER >= 0x00907000L */ +diff --git a/src/openvpn/route.c b/src/openvpn/route.c +index 7c25c77..6c3ad90 100644 +--- a/src/openvpn/route.c ++++ b/src/openvpn/route.c +@@ -1344,6 +1344,11 @@ add_route (struct route *r, +   argv_msg (D_ROUTE, &argv); +   status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed"); +  ++#elif defined (TARGET_ANDROID) ++#include "jniglue.h" ++ ++    addRouteInformation(network, netmask, gateway); ++ + #elif defined (WIN32) +   { +     DWORD ai = TUN_ADAPTER_INDEX_INVALID; +@@ -2371,7 +2376,7 @@ show_routes (int msglev) +   gc_free (&gc); + } +  +-#elif defined(TARGET_LINUX) ++#elif defined(TARGET_LINUX) || defined(TARGET_ANDROID) +  + void + get_default_gateway (struct route_gateway_info *rgi) +diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c +index 6b1f8d2..364b97e 100644 +--- a/src/openvpn/socket.c ++++ b/src/openvpn/socket.c +@@ -41,6 +41,11 @@ +  + #include "memdbg.h" +  ++#ifdef TARGET_ANDROID ++#include "jniglue.h" ++#endif  ++ ++ + const int proto_overhead[] = { /* indexed by PROTO_x */ +   0, +   IPv4_UDP_HEADER_SIZE, /* IPv4 */ +@@ -858,6 +863,11 @@ create_socket_tcp (void) +   } + #endif +  ++#ifdef TARGET_ANDROID ++    /* Protects the socket from being routed via VPN */ ++    android_protect_socket(sd); ++#endif ++ +   return sd; + } +  +@@ -885,6 +895,12 @@ create_socket_udp (const unsigned int flags) + #endif +     } + #endif ++ ++#ifdef TARGET_ANDROID ++    /* Protects the socket from being routed via VPN */ ++    android_protect_socket(sd); ++#endif ++ +   return sd; + } +  +@@ -904,6 +920,11 @@ create_socket_udp6 (const unsigned int flags) + 	msg(M_SOCKERR, "UDP: failed setsockopt for IPV6_RECVPKTINFO"); +     } + #endif ++#ifdef TARGET_ANDROID ++    /* Protects the socket from being routed via VPN */ ++    android_protect_socket(sd); ++#endif ++ +   return sd; + } +  +@@ -922,6 +943,10 @@ create_socket_tcp6 (void) + 		    (void *) &on, sizeof (on)) < 0) +       msg (M_SOCKERR, "TCP: Cannot setsockopt SO_REUSEADDR on TCP6 socket"); +   } ++#ifdef TARGET_ANDROID ++    /* Protects the socket from being routed via VPN */ ++    android_protect_socket(sd); ++#endif +  +   return sd; + } +diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c +index 251f8ed..537fc12 100644 +--- a/src/openvpn/ssl.c ++++ b/src/openvpn/ssl.c +@@ -1645,6 +1645,8 @@ push_peer_info(struct buffer *buf, struct tls_session *session) +       buf_printf (&out, "IV_PLAT=netbsd\n"); + #elif defined(TARGET_FREEBSD) +       buf_printf (&out, "IV_PLAT=freebsd\n"); ++#elif defined(TARGET_ANDROID) ++      buf_printf(&out, "IV_PLAT=android\n"); + #elif defined(WIN32) +       buf_printf (&out, "IV_PLAT=win\n"); + #endif +diff --git a/src/openvpn/syshead.h b/src/openvpn/syshead.h +index 0595b67..56a5429 100644 +--- a/src/openvpn/syshead.h ++++ b/src/openvpn/syshead.h +@@ -211,7 +211,7 @@ + #include <net/if_tap.h> + #endif +  +-#ifdef TARGET_LINUX ++#if defined(TARGET_LINUX) || defined (TARGET_ANDROID) +  + #if defined(HAVE_NETINET_IF_ETHER_H) + #include <netinet/if_ether.h> +diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c +index b99071c..db8104d 100644 +--- a/src/openvpn/tun.c ++++ b/src/openvpn/tun.c +@@ -49,6 +49,11 @@ +  + #include "memdbg.h" +  ++#ifdef TARGET_ANDROID ++#include "jniglue.h" ++#endif ++ ++ + #ifdef WIN32 +  + /* #define SIMULATE_DHCP_FAILED */       /* simulate bad DHCP negotiation */ +@@ -768,6 +773,8 @@ do_ifconfig (struct tuntap *tt, +       tt->did_ifconfig = true; +  + #endif /*ENABLE_IPROUTE*/ ++#elif defined(TARGET_ANDROID) ++       addInterfaceInformation(tun_mtu,ifconfig_local, ifconfig_remote_netmask); + #elif defined(TARGET_SOLARIS) +  +       /* Solaris 2.6 (and 7?) cannot set all parameters in one go... +@@ -1365,7 +1372,16 @@ close_tun_generic (struct tuntap *tt) +  + #endif +  +-#if defined(TARGET_LINUX) ++#if defined(TARGET_LINUX) || defined(TARGET_ANDROID) ++ ++#if defined (TARGET_ANDROID) ++void ++open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) ++{ ++    tt->fd = android_open_tun(); ++} ++ ++#else +  + #ifdef HAVE_LINUX_IF_TUN_H	/* New driver support */ +  +@@ -1373,6 +1389,7 @@ close_tun_generic (struct tuntap *tt) + #error header file linux/sockios.h required + #endif +  ++ + #if defined(HAVE_TUN_PI) && defined(HAVE_IPHDR) && defined(HAVE_IOVEC) && defined(ETH_P_IPV6) && defined(ETH_P_IP) && defined(HAVE_READV) && defined(HAVE_WRITEV) + #define LINUX_IPV6 1 + /* #warning IPv6 ON */ +@@ -1426,7 +1443,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu +       if (!tt->ipv6) + 	ifr.ifr_flags = IFF_NO_PI; +  +-#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN) ++#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN) && !defined(TARGET_ANDROID) +       ifr.ifr_flags |= IFF_ONE_QUEUE; + #endif +  +@@ -1516,6 +1533,7 @@ open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tu + } +  + #endif /* HAVE_LINUX_IF_TUN_H */ ++#endif /* TARGET_ANDROID */ +  + #ifdef TUNSETPERSIST +  +diff --git a/src/openvpn/tun.h b/src/openvpn/tun.h +index 9bd990f..63ab872 100644 +--- a/src/openvpn/tun.h ++++ b/src/openvpn/tun.h +@@ -292,6 +292,8 @@ ifconfig_order(void) +   return IFCONFIG_AFTER_TUN_OPEN; + #elif defined(WIN32) +   return IFCONFIG_BEFORE_TUN_OPEN; ++#elif defined(TARGET_ANDROID) ++  return IFCONFIG_BEFORE_TUN_OPEN; + #else +   return IFCONFIG_DEFAULT; + #endif +--  +1.7.5.4 + | 
