summaryrefslogtreecommitdiff
path: root/openvpn/0001-initial-android-hacks.patch
diff options
context:
space:
mode:
Diffstat (limited to 'openvpn/0001-initial-android-hacks.patch')
-rw-r--r--openvpn/0001-initial-android-hacks.patch523
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
+