diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2012-05-09 02:06:17 +0200 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2012-05-09 02:06:17 +0200 | 
| commit | 95d6e0331e2db3404475efb91b5a7535b843099a (patch) | |
| tree | 8612dfd7101b3fe8b527367090e4818184b6bb2d | |
| parent | 379ae9173874ebe7d3811f0fde9b75221c349386 (diff) | |
Openvpn as external external program is coming nearer ....
| -rw-r--r-- | AndroidManifest.xml | 4 | ||||
| -rw-r--r-- | jni/Android.mk | 3 | ||||
| -rw-r--r-- | openvpn/Android.mk | 8 | ||||
| -rw-r--r-- | openvpn/src/openvpn/error.c | 5 | ||||
| -rw-r--r-- | openvpn/src/openvpn/jniglue.c | 130 | ||||
| -rw-r--r-- | openvpn/src/openvpn/jniglue.h | 3 | ||||
| -rw-r--r-- | openvpn/src/openvpn/manage.c | 10 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPN.java | 9 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPNThread.java | 50 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnManagementThread.java | 30 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnService.java | 6 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 3 | 
12 files changed, 99 insertions, 162 deletions
| diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7c1e07b9..843da00b 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,8 +17,8 @@  <manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="de.blinkt.openvpn" -    android:versionCode="20" -    android:versionName="0.4.10" > +    android:versionCode="21" +    android:versionName="0.5.0" >      <uses-permission android:name="android.permission.INTERNET" /> diff --git a/jni/Android.mk b/jni/Android.mk index 83b84c81..ff17b27b 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -7,6 +7,3 @@ include lzo/Android.mk  include openssl/Android.mk  include openvpn/Android.mk - - - diff --git a/openvpn/Android.mk b/openvpn/Android.mk index 13f23a78..78849702 100644 --- a/openvpn/Android.mk +++ b/openvpn/Android.mk @@ -8,8 +8,9 @@ LOCAL_C_INCLUDES := openssl/include lzo/include openssl/crypto openssl openvpn/s -LOCAL_SHARED_LIBRARIES :=  libssl  libcrypto  liblzo -#LOCAL_STATIC_LIBRARIES :=  libssl  libcrypto  liblzo +#LOCAL_SHARED_LIBRARIES :=  libssl  libcrypto  liblzo +LOCAL_STATIC_LIBRARIES :=  libssl_static libcrypto_static   liblzo-static +  LOCAL_CFLAGS= -DHAVE_CONFIG_H  LOCAL_MODULE = openvpn @@ -87,4 +88,5 @@ LOCAL_SRC_FILES:= src/openvpn/jniglue.c \  	src/openvpn/status.c \  	src/openvpn/tun.c  -include $(BUILD_SHARED_LIBRARY) +#include $(BUILD_SHARED_LIBRARY) +include $(BUILD_EXECUTABLE) diff --git a/openvpn/src/openvpn/error.c b/openvpn/src/openvpn/error.c index 68497941..83a9eb4b 100644 --- a/openvpn/src/openvpn/error.c +++ b/openvpn/src/openvpn/error.c @@ -714,10 +714,7 @@ 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/openvpn/src/openvpn/jniglue.c b/openvpn/src/openvpn/jniglue.c index e11cabd4..c79272d7 100644 --- a/openvpn/src/openvpn/jniglue.c +++ b/openvpn/src/openvpn/jniglue.c @@ -5,144 +5,14 @@  #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); -} - - -// 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); -     -} - -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/openvpn/src/openvpn/jniglue.h b/openvpn/src/openvpn/jniglue.h index 236c0323..a86d52da 100644 --- a/openvpn/src/openvpn/jniglue.h +++ b/openvpn/src/openvpn/jniglue.h @@ -8,8 +8,5 @@  #ifndef xcopenvpn_jniglue_h  #define xcopenvpn_jniglue_h - -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/openvpn/src/openvpn/manage.c b/openvpn/src/openvpn/manage.c index 96ca6eaa..f7ca8e15 100644 --- a/openvpn/src/openvpn/manage.c +++ b/openvpn/src/openvpn/manage.c @@ -58,6 +58,9 @@  #define MANAGEMENT_ECHO_FLAGS 0  #endif +#include <android/log.h> + +  /* tag for blank username/password */  static const char blank_up[] = "[[BLANK]]"; @@ -1808,6 +1811,7 @@ man_io_error (struct management *man, const char *prefix)      return false;  } +  static int  man_read (struct management *man)  { @@ -1820,8 +1824,12 @@ man_read (struct management *man)  #ifdef TARGET_ANDROID      len = read_fd (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL, &fd); -    if(fd >= 0) +    __android_log_print(ANDROID_LOG_DEBUG,"openvpn-dbg","read_fd %d %d", len, fd); +    if(fd >= 0) {          man->connection.lastfdreceived = fd; +        if(len == 0) // No data message but a fd, return without resetting socket... +            return 0; +    }  #else      len = recv (man->connection.sd_cli, buf, sizeof (buf), MSG_NOSIGNAL);  #endif diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index e524da1c..58187df2 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -8,7 +8,7 @@ import android.util.Log;  public class OpenVPN {  	private static OpenVpnService mOpenVpnService;  	private static final int MAXLOGENTRIES = 500; -	public static native int startOpenVPNThreadArgs(String argv[]); +	//public static native int startOpenVPNThreadArgs(String argv[]);  	private static final String TAG = "OpenVpn"; @@ -21,13 +21,14 @@ public class OpenVPN {  	public interface LogListener {  		void newLog(String logmessage);  	} - +	 +	/*  	static {  		System.loadLibrary("crypto");  		System.loadLibrary("ssl");  		System.loadLibrary("lzo");  		System.loadLibrary("openvpn"); -	} +	}*/  	synchronized static void logMessage(int level,String prefix, String message)  	{ @@ -39,7 +40,7 @@ public class OpenVPN {  		// but kills me for logging 100 messages with too many references :(  		// Force GC how and then to kill loose ends  		if(counter++ % 50==0) { -			System.gc(); +			//System.gc();  		}  		for (LogListener ll : logListener) { diff --git a/src/de/blinkt/openvpn/OpenVPNThread.java b/src/de/blinkt/openvpn/OpenVPNThread.java index a5b3e5e4..a8cb8430 100644 --- a/src/de/blinkt/openvpn/OpenVPNThread.java +++ b/src/de/blinkt/openvpn/OpenVPNThread.java @@ -1,6 +1,12 @@  package de.blinkt.openvpn;
 +import java.io.BufferedReader;
 +import java.io.IOException;
 +import java.io.InputStream;
 +import java.io.InputStreamReader;
 +import java.io.Reader;
  import java.util.Arrays;
 +import java.util.LinkedList;
  import android.util.Log;
 @@ -8,12 +14,17 @@ public class OpenVPNThread implements Runnable {  	private static final String TAG = "OpenVPN";
  	private OpenVpnService mService;
  	private String[] mArgv;
 +	private Process mProcess;
  	public OpenVPNThread(OpenVpnService service,String[] argv)
  	{
  		mService = service;
  		mArgv = argv;
  	}
 +	
 +	public void stopProcess() {
 +		mProcess.destroy();
 +	}
  	@Override
  	public void run() {
 @@ -35,12 +46,9 @@ public class OpenVPNThread implements Runnable {  			OpenVPN.logMessage(0, "argv:" , Arrays.toString(mArgv));
 -			OpenVPN.startOpenVPNThreadArgs(mArgv);
 -
 +			startOpenVPNThreadArgs(mArgv);
 -
 -			// Sleep for a while. This also checks if we got interrupted.
 -			Thread.sleep(3000);
 +			
  			//}
  			Log.i(TAG, "Giving up");
  		} catch (Exception e) {
 @@ -60,4 +68,36 @@ public class OpenVPNThread implements Runnable {  			Log.i(TAG, "Exiting");
  		}
  	}
 +
 +	private void startOpenVPNThreadArgs(String[] argv) {
 +		LinkedList<String> argvlist = new LinkedList<String>();
 +		
 +		for(String arg:argv)
 +			argvlist.add(arg);
 +	
 +		ProcessBuilder pb = new ProcessBuilder(argvlist);
 +		pb.redirectErrorStream(true);
 +		try {
 +			mProcess = pb.start();
 +			// Close the output, since we don't need it
 +			mProcess.getOutputStream().close();
 +			InputStream in = mProcess.getInputStream();
 +			BufferedReader br = new BufferedReader(new InputStreamReader(in));
 +			
 +			
 +			while(true) {
 +				String logline = br.readLine();
 +				if(logline==null)
 +					return;
 +				OpenVPN.logMessage(0, "P:", logline);
 +			}
 +		
 +		
 +		} catch (IOException e) {
 +			e.printStackTrace();
 +			stopProcess();
 +		}
 +		
 +		
 +	}
  }
 diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index fd7fe8a8..31ea49e8 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -30,10 +30,12 @@ public class OpenVpnManagementThread implements Runnable {  	public void managmentCommand(String cmd) {
 +		Log.d("openvpn", "mgmt cmd" + mSocket + " "  +cmd + " " );
  		try {
  			mSocket.getOutputStream().write(cmd.getBytes());
  			mSocket.getOutputStream().flush();
  		} catch (IOException e) {
 +			e.printStackTrace();
  		}
  	}
 @@ -94,10 +96,14 @@ public class OpenVpnManagementThread implements Runnable {  			Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
  			int fdint = (Integer) getInt.invoke(fd);
 +			// You can even get more evil by parsing toString() and extract the int from that :)
 +			
  			Log.d("Openvpn", "Got FD from socket: " + fd + " " + fdint);
 -			ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
 +
  			mOpenVPNService.protect(fdint);
 -			pfd.close();
 +			
 +			//ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
 +			//pfd.close();
  			return;
  		} catch (NoSuchMethodException e) {
  			e.printStackTrace();
 @@ -107,8 +113,6 @@ public class OpenVpnManagementThread implements Runnable {  			e.printStackTrace();
  		} catch (InvocationTargetException e) {
  			e.printStackTrace();
 -		} catch (IOException e) {
 -			e.printStackTrace();
  		}
  		Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
  	}
 @@ -142,10 +146,15 @@ public class OpenVpnManagementThread implements Runnable {  				processPWCommand(argument);
  			} else if (cmd.equals("HOLD")) {
  				managmentCommand("hold release\n");
 +				managmentCommand("log on\n");
 +				managmentCommand("bytecount 13\n");
  			} else if (cmd.equals("NEED-OK")) {
  				processNeedCommand(argument);
 +			} else if (cmd.equals("LOG")) {
 +				OpenVPN.logMessage(0, "",  command);
  			} else {
  				OpenVPN.logMessage(0, "MGMT:", "Got unrecognized command" + command);
 +				managmentCommand("log 1\n");
  				Log.i(TAG, "Got unrecognized command" + command);
  			}
  		} else if (command.startsWith("SUCCESS:")) {
 @@ -219,11 +228,17 @@ public class OpenVpnManagementThread implements Runnable {  			FileDescriptor[] fds = {fdtosend};
  			mSocket.setFileDescriptorsForSend(fds);
 -			Log.d("Openvpn", "Sending FD tosocket: " + fdtosend + " " + fdint);
 +			Log.d("Openvpn", "Sending FD tosocket: " + fdtosend + " " + fdint + "  " + pfd);
  			// Trigger a send so we can close the fd on our side of the channel
 +			// The API documentation fails to mention that it will not reset the file descriptor to
 +			// be send and will happily send the file descriptor on every write ...
  			String cmd = String.format("needok '%s' %s\n", needed, "ok");
  			managmentCommand(cmd);
 +			
 +			// Set the FileDescriptor to null to stop this mad behavior 
 +			mSocket.setFileDescriptorsForSend(null);
  			pfd.close();
 +
  			return true;
  		} catch (NoSuchMethodException e) {
  			e.printStackTrace();
 @@ -278,6 +293,11 @@ public class OpenVpnManagementThread implements Runnable {  		for (OpenVpnManagementThread mt: active){
  			mt.managmentCommand("signal SIGINT\n");
  			sendCMD=true;
 +			try {
 +				mt.mSocket.close();
 +			} catch (IOException e) {
 +				e.printStackTrace();
 +			}
  		}
  		return sendCMD;		
  	}
 diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java index 5c9df8b4..a3df9fde 100644 --- a/src/de/blinkt/openvpn/OpenVpnService.java +++ b/src/de/blinkt/openvpn/OpenVpnService.java @@ -151,13 +151,17 @@ public class OpenVpnService extends VpnService implements Handler.Callback {  		if(OpenVpnManagementThread.stopOpenVPN()){  			// an old was asked to exit, wait 2s  			try { -				Thread.sleep(2000); +				Thread.sleep(1000);  			} catch (InterruptedException e) {  			}  		}  		if (mServiceThread!=null) {  			mServiceThread.interrupt(); +			try { +				Thread.sleep(1000); +			} catch (InterruptedException e) { +			}  		} diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 3cbac8d7..ca5d99f6 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -345,7 +345,8 @@ public class VpnProfile implements  Serializable{  		Vector<String> args = new Vector<String>();  		// Add fixed paramenters -		args.add("openvpn"); +		//args.add("/data/data/de.blinkt.openvpn/lib/openvpn"); +		args.add(cacheDir.getAbsolutePath() +"/" +"openvpn");  		args.add("--config");  		args.add(cacheDir.getAbsolutePath() + "/" + OVPNCONFIGFILE); | 
