summaryrefslogtreecommitdiff
path: root/src/de/blinkt/openvpn/OpenVpnService.java
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2012-04-30 02:53:12 +0200
committerArne Schwabe <arne@rfc2549.org>2012-04-30 02:53:12 +0200
commit2f73ef1dda56ba7ae588091e0c0e8f71c02bbf32 (patch)
tree2ec9d7e96aea032153e51aa1ec9df4ce23d9ad10 /src/de/blinkt/openvpn/OpenVpnService.java
parentdaf44e6fbde97e23c9e39f26d1ed0bd3a0f02ede (diff)
version 0.4.2
Diffstat (limited to 'src/de/blinkt/openvpn/OpenVpnService.java')
-rw-r--r--src/de/blinkt/openvpn/OpenVpnService.java354
1 files changed, 149 insertions, 205 deletions
diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java
index 39d73adb..031f2a14 100644
--- a/src/de/blinkt/openvpn/OpenVpnService.java
+++ b/src/de/blinkt/openvpn/OpenVpnService.java
@@ -17,13 +17,11 @@
package de.blinkt.openvpn;
import java.io.IOException;
-import java.net.UnknownHostException;
-import java.util.Arrays;
import java.util.Vector;
-import de.blinkt.openvpn.OpenVpnService.CIDRIP;
-
+import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.content.Context;
import android.content.Intent;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
@@ -31,19 +29,15 @@ import android.net.VpnService;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
-import android.util.Log;
import android.widget.Toast;
-public class OpenVpnService extends VpnService implements Handler.Callback, Runnable {
- private static final String TAG = "OpenVpnService";
-
- private String[] mArgv;
+public class OpenVpnService extends VpnService implements Handler.Callback {
+ private static final String TAG = "OpenVpnService";
- private Handler mHandler;
- // Only one VPN, make this thread shared between all instances
- private static Thread mThread;
+ Handler mHandler;
+ private Thread mServiceThread;
- private ParcelFileDescriptor mInterface;
+ private ParcelFileDescriptor mInterface;
private Vector<String> mDnslist=new Vector<String>();
@@ -55,7 +49,14 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
private CIDRIP mLocalIP;
-
+ private OpenVpnManagementThread mSocketManager;
+
+ private Thread mSocketManagerThread;
+
+ private NotificationManager mNotificationManager;
+
+
+
class CIDRIP{
String mIp;
int len;
@@ -63,12 +64,12 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
mIp=ip;
String[] ipt = mask.split("\\.");
long netmask=0;
-
+
netmask += Integer.parseInt(ipt[0]);
netmask += Integer.parseInt(ipt[1])<< 8;
netmask += Integer.parseInt(ipt[2])<< 16;
netmask += Integer.parseInt(ipt[3])<< 24;
-
+
len =0;
while((netmask & 0x1) == 1) {
len++;
@@ -80,209 +81,147 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
return String.format("%s/%d",mIp,len);
}
}
-
- @Override
- public void onRevoke() {
- managmentCommand("signal SIGINT\n");
- mThread=null;
- stopSelf();
- };
-
-
- public void managmentCommand(String cmd) {
- LocalSocket mgmtsocket;
- try {
- byte[] buffer = new byte[400];
- mgmtsocket = new LocalSocket();
-
- mgmtsocket.connect(new LocalSocketAddress(getCacheDir().getAbsolutePath() + "/" + "mgmtsocket",
- LocalSocketAddress.Namespace.FILESYSTEM));
- //mgmtsocket = new Dat("127.0.0.1",OpenVPNClient.MANAGMENTPORT));
-
- //OutputStreamWriter outw = new OutputStreamWriter(mgmtsocket.getOutputStream());
- mgmtsocket.getInputStream().read(buffer);
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- //outw.write(cmd);
- mgmtsocket.getOutputStream().write(cmd.getBytes());
- //outw.flush();
- try {
- Thread.sleep(400);
- } catch (InterruptedException e) {
- }
- mgmtsocket.close();
- } catch (UnknownHostException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
+ @Override
+ public void onRevoke() {
+ mSocketManager.managmentCommand("signal SIGINT\n");
+ mServiceThread=null;
+ stopSelf();
+ };
+
+
+
+
+
+
+ private LocalSocket openManagmentInterface() {
+ // Could take a while to open connection
+ String socketname = (getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
+ LocalSocket sock = new LocalSocket();
+ int tries = 8;
+
+ while(tries > 0 && !sock.isConnected()) {
+ try {
+ sock.connect(new LocalSocketAddress(socketname,
+ LocalSocketAddress.Namespace.FILESYSTEM));
+ } catch (IOException e) {
+ // wait 300 ms before retrying
+ try { Thread.sleep(300);
+ } catch (InterruptedException e1) {}
+
+ }
+ tries--;
}
+ return sock;
+
}
-
-
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- // The handler is only used to show messages.
- if (mHandler == null) {
- mHandler = new Handler(this);
- }
-
- // Stop the previous session by interrupting the thread.
- if (mThread != null) {
- managmentCommand("signal SIGINT\n");
- mThread.interrupt();
- }
-
- // Thread already running, reuse existing,
-
- // Extract information from the intent.
- String prefix = getPackageName();
- mArgv = intent.getStringArrayExtra(prefix + ".ARGV");
-
-
- // Start a new session by creating a new thread.
- mThread = new Thread(this, "OpenVPNThread");
- mThread.start();
-
- String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
- mProfile = ProfileManager.get(profileUUID);
-
- if(intent.hasExtra(prefix +".PKCS12PASS"))
- {
- try {
- String pkcs12password = intent.getStringExtra(prefix +".PKCS12PASS");
- Thread.sleep(3000);
-
- managmentCommand("password 'Private Key' " + pkcs12password + "\n");
- } catch (InterruptedException e) {
- }
-
- }
- if(intent.hasExtra(prefix +".USERNAME"))
- {
- try {
- String user = managmentEscape(intent.getStringExtra(prefix +".USERNAME"));
- String pw = managmentEscape(intent.getStringExtra(prefix +".PASSWORD"));
- Thread.sleep(3000);
-
-
- managmentCommand("username 'Auth' " + user+ "\n" +
- "password 'Auth' " + pw + "\n");
- } catch (InterruptedException e) {
- }
-
- }
-
-
- return START_STICKY;
- }
-
- private String managmentEscape(String unescape) {
- String escapedString = unescape.replace("\\", "\\\\");
- escapedString = escapedString.replace("\"","\\\"");
- escapedString = escapedString.replace("\n","\\n");
- return '"' + escapedString + '"';
+
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // The handler is only used to show messages.
+ if (mHandler == null) {
+ mHandler = new Handler(this);
+ }
+
+ mNotificationManager=(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE);
+
+
+ // Stop the previous session by interrupting the thread.
+ if (mSocketManager != null) {
+ mSocketManager.managmentCommand("signal SIGINT\n");
+ }
+
+ if (mServiceThread!=null) {
+ mServiceThread.interrupt();
+ }
+
+
+ // Extract information from the intent.
+ String prefix = getPackageName();
+ String[] argv = intent.getStringArrayExtra(prefix + ".ARGV");
+
+ String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
+ mProfile = ProfileManager.get(profileUUID);
+
+ // Start a new session by creating a new thread.
+
+ OpenVPNThread serviceThread = new OpenVPNThread(this, argv);
+
+ mServiceThread = new Thread(serviceThread, "OpenVPNServiceThread");
+ mServiceThread.start();
+
+
+ // Open the Management Interface
+ LocalSocket mgmtsocket = openManagmentInterface();
+
+ if(mgmtsocket!=null) {
+ // start a Thread that handles incoming messages of the managment socket
+ mSocketManager = new OpenVpnManagementThread(mProfile,mgmtsocket);
+ mSocketManagerThread = new Thread(mSocketManager,"OpenVPNMgmtThread");
+ mSocketManagerThread.start();
+ }
+
+ return START_STICKY;
}
+
+
+
@Override
- public void onDestroy() {
- if (mThread != null) {
- managmentCommand("signal SIGINT\n");
-
- mThread.interrupt();
- }
- }
-
- @Override
- public boolean handleMessage(Message message) {
- if (message != null) {
- Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
- }
- return true;
- }
-
- @Override
- public synchronized void run() {
- try {
- Log.i(TAG, "Starting o");
-
-
- OpenVPN.setCallback(this);
-
-
- // We try to create the tunnel for several times. The better way
- // is to work with ConnectivityManager, such as trying only when
- // the network is avaiable. Here we just use a counter to keep
- // things simple.
- //for (int attempt = 0; attempt < 10; ++attempt) {
- mHandler.sendEmptyMessage(R.string.connecting);
-
- // Log argv
-
- OpenVPN.logMessage(0, "argv:" , Arrays.toString(mArgv));
-
- OpenVPN.startOpenVPNThreadArgs(mArgv);
-
-
-
- // Sleep for a while. This also checks if we got interrupted.
- Thread.sleep(3000);
- //}
- Log.i(TAG, "Giving up");
- } catch (Exception e) {
- Log.e(TAG, "Got " + e.toString());
- } finally {
- try {
- mInterface.close();
- } catch (Exception e) {
- // ignore
- }
- mInterface = null;
-
-
- mHandler.sendEmptyMessage(R.string.disconnected);
- Log.i(TAG, "Exiting");
- }
- }
+ public void onDestroy() {
+ if (mServiceThread != null) {
+ mSocketManager.managmentCommand("signal SIGINT\n");
+
+ mServiceThread.interrupt();
+ }
+ }
+
+ @Override
+ public boolean handleMessage(Message message) {
+ if (message != null) {
+ Toast.makeText(this, message.what, Toast.LENGTH_SHORT).show();
+ }
+ return true;
+ }
+
+
public ParcelFileDescriptor openTun() {
- Builder builder = new Builder();
-
- builder.addAddress(mLocalIP.mIp, mLocalIP.len);
-
- for (String dns : mDnslist ) {
- builder.addDnsServer(dns);
+ Builder builder = new Builder();
+
+ builder.addAddress(mLocalIP.mIp, mLocalIP.len);
+
+ for (String dns : mDnslist ) {
+ builder.addDnsServer(dns);
}
-
-
- for (CIDRIP route:mRoutes) {
- builder.addRoute(route.mIp, route.len);
- }
-
- if(mDomain!=null)
- builder.addSearchDomain(mDomain);
-
-
- mDnslist.clear();
- mRoutes.clear();
-
-
- builder.setSession(mProfile.mName + " - " + mLocalIP);
-
- // Let the configure Button show the Log
- Intent intent = new Intent(getBaseContext(),LogWindow.class);
- PendingIntent startLW = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
- builder.setConfigureIntent(startLW);
- mInterface = builder.establish();
- return mInterface;
- }
+
+ for (CIDRIP route:mRoutes) {
+ builder.addRoute(route.mIp, route.len);
+ }
+
+ if(mDomain!=null)
+ builder.addSearchDomain(mDomain);
+ mDnslist.clear();
+ mRoutes.clear();
+
+
+ builder.setSession(mProfile.mName + " - " + mLocalIP);
+
+ // Let the configure Button show the Log
+ Intent intent = new Intent(getBaseContext(),LogWindow.class);
+ PendingIntent startLW = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
+ builder.setConfigureIntent(startLW);
+ mInterface = builder.establish();
+ return mInterface;
+
+ }
+
public void addDNS(String dns) {
mDnslist.add(dns);
}
@@ -303,4 +242,9 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
public void setLocalIP(String local, String netmask) {
mLocalIP = new CIDRIP(local, netmask);
}
+
+
+ public Handler getHandler() {
+ return mHandler;
+ }
}