From b2b46c1867bd7282c91f43e80e0763f86ec791d4 Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Wed, 9 May 2012 02:06:17 +0200 Subject: Openvpn as external external program is coming nearer .... --- src/de/blinkt/openvpn/OpenVPN.java | 9 ++-- src/de/blinkt/openvpn/OpenVPNThread.java | 50 +++++++++++++++++++--- src/de/blinkt/openvpn/OpenVpnManagementThread.java | 30 ++++++++++--- src/de/blinkt/openvpn/OpenVpnService.java | 6 ++- src/de/blinkt/openvpn/VpnProfile.java | 3 +- 5 files changed, 82 insertions(+), 16 deletions(-) (limited to 'src/de/blinkt') diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index e524da1..58187df 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 a5b3e5e..a8cb843 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 argvlist = new LinkedList(); + + 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 fd7fe8a..31ea49e 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 5c9df8b..a3df9fd 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 3cbac8d..ca5d99f 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 args = new Vector(); // 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); -- cgit v1.2.3