summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AndroidManifest.xml4
-rw-r--r--res/layout/basic_settings.xml1
-rw-r--r--res/layout/vpn_list_item.xml2
-rw-r--r--res/menu/logmenu.xml19
-rw-r--r--res/menu/vpn_context.xml3
-rw-r--r--res/values/strings.xml12
-rw-r--r--src/de/blinkt/openvpn/LaunchVPN.java5
-rw-r--r--src/de/blinkt/openvpn/LogWindow.java7
-rw-r--r--src/de/blinkt/openvpn/OpenVPN.java141
-rw-r--r--src/de/blinkt/openvpn/OpenVPNThread.java2
-rw-r--r--src/de/blinkt/openvpn/OpenVpnManagementThread.java14
-rw-r--r--src/de/blinkt/openvpn/OpenVpnService.java73
12 files changed, 194 insertions, 89 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fe250a8..75fe58d 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="15"
- android:versionName="0.4.7" >
+ android:versionCode="16"
+ android:versionName="0.4.8" >
<uses-permission android:name="android.permission.INTERNET" />
diff --git a/res/layout/basic_settings.xml b/res/layout/basic_settings.xml
index e19ec14..6d4b8cc 100644
--- a/res/layout/basic_settings.xml
+++ b/res/layout/basic_settings.xml
@@ -168,7 +168,6 @@
android:layout_marginLeft="8dip"
android:layout_marginRight="8dip"
android:hint="@string/pw_query_hint"
-
android:inputType="textPassword" />
</LinearLayout>
diff --git a/res/layout/vpn_list_item.xml b/res/layout/vpn_list_item.xml
index 75da3cf..16d7d5b 100644
--- a/res/layout/vpn_list_item.xml
+++ b/res/layout/vpn_list_item.xml
@@ -23,7 +23,7 @@
<LinearLayout
android:id="@+id/vpn_list_item_left"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?android:attr/selectableItemBackground"
diff --git a/res/menu/logmenu.xml b/res/menu/logmenu.xml
index 80331c5..b8fd286 100644
--- a/res/menu/logmenu.xml
+++ b/res/menu/logmenu.xml
@@ -5,13 +5,18 @@
android:id="@+id/clearlog"
android:icon="@drawable/ic_menu_trash_holo_light"
android:showAsAction="ifRoom|withText"
- android:title="@string/clear_log"/>
-
- <item android:id="@+id/cancel"
+ android:title="@string/clear_log"
+ android:titleCondensed="@string/clear"/>
+ <item
+ android:id="@+id/cancel"
android:icon="@android:drawable/ic_menu_close_clear_cancel"
android:showAsAction="ifRoom|withText"
android:title="@string/cancel_connection"
- />
-
-
-</menu> \ No newline at end of file
+ android:titleCondensed="@string/cancel"/>
+ <item
+ android:id="@+id/info"
+ android:icon="@android:drawable/ic_menu_info_details"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/show_connection_details"
+ android:titleCondensed="@string/info"/>
+ </menu> \ No newline at end of file
diff --git a/res/menu/vpn_context.xml b/res/menu/vpn_context.xml
index 477c6a8..239f157 100644
--- a/res/menu/vpn_context.xml
+++ b/res/menu/vpn_context.xml
@@ -18,9 +18,8 @@
<!-- <item
android:id="@+id/connect_vpn"
android:alphabeticShortcut="c"
- android:
android:icon="@android:drawable/ic_media_play"
- android:showAsAction="withText|ifRoom"
+ android:showAsAction="ifRoom|withText"
android:title="@string/connect"/>
-->
</menu> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 53483b8..cf8cc5c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -115,7 +115,6 @@
<string name="custom_config_title">Enable Custom Options</string>
<string name="custom_config_summary">Specify custom options. Use with care!</string>
<string name="route_rejected">Route rejected by Android</string>
- <string formatted="false" name="ip_not_cidr">Cannot make sense of %s and %s as IP and CIDR netmask, assuming second address is peer address of remote. Using /32 netmask for local IP.</string>
<string name="cancel_connection">Disconnect</string>
<string name="clear_log">clear log</string>
<string name="title_cancel">Cancel Confirmation</string>
@@ -156,4 +155,15 @@
<string name="tun_error_helpful">" On some custom ICS images the permission on /dev/tun might be wrong, or the tun module might be missing completly"</string>
<string name="tun_open_error">Opening tun interface failed badly.</string>
<string name="error">"Error: "</string>
+ <string name="clear">Clear</string>
+ <string name="info">info</string>
+ <string name="show_connection_details">Show connection details</string>
+ <string name="last_openvpn_tun_config">Last interface configuration from Openvpn:</string>
+ <string name="local_ip_info">Local IP: %1$s/%2$d</string>
+ <string name="dns_server_info">DNS Server: %s</string>
+ <string name="dns_domain_info">DNS Domain: %s</string>
+ <string name="routes_info">Routes: %s</string>
+ <string name="ip_not_cidr">Cannot make sense of %1$s and %2$s as local IP with CIDR netmask, assuming second address is peer address of remote. Using /32 netmask for local IP.</string>
+ <string name="route_not_cidr">Cannot make sense of %1$s and %2$s as IP route with CIDR netmask, using /32 as netmask.</string>
+ <string name="route_not_netip">Corrected route %1$s/%2$s to %3$s/%2$s</string>
</resources>
diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java
index d74834c..2e25f7a 100644
--- a/src/de/blinkt/openvpn/LaunchVPN.java
+++ b/src/de/blinkt/openvpn/LaunchVPN.java
@@ -29,6 +29,8 @@ import android.content.Intent;
import android.net.VpnService;
import android.os.Bundle;
import android.os.Parcelable;
+import android.text.InputType;
+import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
@@ -207,7 +209,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
final EditText entry = new EditText(this);
entry.setSingleLine();
- entry.setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
+ entry.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ entry.setTransformationMethod(new PasswordTransformationMethod());
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Need " + type);
diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java
index 001dbf1..65e8c66 100644
--- a/src/de/blinkt/openvpn/LogWindow.java
+++ b/src/de/blinkt/openvpn/LogWindow.java
@@ -23,6 +23,8 @@ import android.widget.TextView;
import de.blinkt.openvpn.OpenVPN.LogListener;
public class LogWindow extends ListActivity {
+ private String[] mBconfig=null;
+
class LogWindowListAdapter implements ListAdapter,LogListener, Callback {
@@ -36,6 +38,7 @@ public class LogWindow extends ListActivity {
private Vector<DataSetObserver> observers=new Vector<DataSetObserver>();
+
public LogWindowListAdapter() {
initLogBuffer();
@@ -159,7 +162,6 @@ public class LogWindow extends ListActivity {
OpenVPN.logMessage(0,"","Log cleared.");
mHandler.sendEmptyMessage(MESSAGE_CLEARLOG);
}
-
}
@@ -185,6 +187,9 @@ public class LogWindow extends ListActivity {
builder.setNegativeButton(android.R.string.no, null);
builder.show();
return true;
+ } else if(item.getItemId()==R.id.info) {
+ if(mBconfig==null)
+ OpenVPN.triggerLogBuilderConfig();
}
return super.onOptionsItemSelected(item);
diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java
index daa2971..a5f60da 100644
--- a/src/de/blinkt/openvpn/OpenVPN.java
+++ b/src/de/blinkt/openvpn/OpenVPN.java
@@ -10,77 +10,79 @@ public class OpenVPN {
private static final int MAXLOGENTRIES = 500;
public static native int startOpenVPNThread();
public static native int startOpenVPNThreadArgs(String argv[]);
- private static final String TAG = "OpenVpn";
+ private static final String TAG = "OpenVpn";
+
-
public static LinkedList<String> logbuffer = new LinkedList<String>();
private static int counter=0;
private static Vector<LogListener> logListener=new Vector<OpenVPN.LogListener>();
-
+ private static String[] mBconfig=null;
+
public interface LogListener {
void newLog(String logmessage);
}
- static {
- System.loadLibrary("crypto");
- System.loadLibrary("ssl");
- System.loadLibrary("lzo");
- System.loadLibrary("openvpn");
- }
-
- static void addRoute(String dest,String mask, String gw) {
- Log.i("openvpn" ,"Got Routing information " + dest + " " + mask + " " + gw );
- mOpenVpnService.addRoute(dest,mask);
- }
-
- synchronized static void logMessage(int level,String prefix, String message)
- {
- logbuffer.addLast(prefix + " " + message);
- if(logbuffer.size()>MAXLOGENTRIES)
- logbuffer.removeFirst();
-
- // The garbage collector does not collect the String from native
- // 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();
-
- for (LogListener ll : logListener) {
+ static {
+ System.loadLibrary("crypto");
+ System.loadLibrary("ssl");
+ System.loadLibrary("lzo");
+ System.loadLibrary("openvpn");
+ }
+
+ static void addRoute(String dest,String mask, String gw) {
+ Log.i("openvpn" ,"Got Routing information " + dest + " " + mask + " " + gw );
+ mOpenVpnService.addRoute(dest,mask);
+ }
+
+ synchronized static void logMessage(int level,String prefix, String message)
+ {
+ logbuffer.addLast(prefix + " " + message);
+ if(logbuffer.size()>MAXLOGENTRIES)
+ logbuffer.removeFirst();
+
+ // The garbage collector does not collect the String from native
+ // 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();
+ }
+
+ for (LogListener ll : logListener) {
ll.newLog(prefix + " " + message);
}
-
- }
-
- synchronized static void clearLog() {
- logbuffer.clear();
- }
-
- synchronized static void addLogListener(LogListener ll){
- logListener.add(ll);
- }
-
- synchronized static void removeLogListener(LogListener ll) {
- logListener.remove(ll);
- }
-
-
- static void addInterfaceInfo(int mtu, String local, String netmask)
- {
- Log.i("openvpn","Got interface info M" + mtu + " L: " + local + "NM: " + netmask);
- mOpenVpnService.setLocalIP(local,netmask);
- }
-
- static void addDns(String dns) {
- Log.i("openvpn","Got DNS Server: " + dns);
- mOpenVpnService.addDNS(dns);
- }
-
-
- static void addDomain(String domain) {
- Log.i("openvpn","Got DNS Domain: " + domain);
- mOpenVpnService.setDomain(domain);
- }
+
+ }
+
+ synchronized static void clearLog() {
+ logbuffer.clear();
+ }
+
+ synchronized static void addLogListener(LogListener ll){
+ logListener.add(ll);
+ }
+
+ synchronized static void removeLogListener(LogListener ll) {
+ logListener.remove(ll);
+ }
+
+
+ static void addInterfaceInfo(int mtu, String local, String netmask)
+ {
+ Log.i("openvpn","Got interface info M" + mtu + " L: " + local + "NM: " + netmask);
+ mOpenVpnService.setLocalIP(local,netmask);
+ }
+
+ static void addDns(String dns) {
+ Log.i("openvpn","Got DNS Server: " + dns);
+ mOpenVpnService.addDNS(dns);
+ }
+
+
+ static void addDomain(String domain) {
+ Log.i("openvpn","Got DNS Domain: " + domain);
+ mOpenVpnService.setDomain(domain);
+ }
public static void setCallback(OpenVpnService openVpnService) {
@@ -96,19 +98,32 @@ public class OpenVPN {
Log.e("openvpn","Error protecting socket "+ sockfd);
return p;
}
-
+
public static int openTunDevice() {
Log.d(TAG,"Opening tun device");
return mOpenVpnService.openTun();
}
//! Dummy method being called to force loading of JNI Libraries
public static void foo() { }
-
+
synchronized public static String[] getlogbuffer() {
-
+
// The stoned way of java to return an array from a vector
// brought to you by eclipse auto complete
return (String[]) logbuffer.toArray(new String[logbuffer.size()]);
}
+ public static void logBuilderConfig(String[] bconfig) {
+ mBconfig =bconfig;
+ }
+ public static void triggerLogBuilderConfig() {
+ if(mBconfig==null) {
+ logMessage(0, "", "No active interface");
+ } else {
+ for (String item : mBconfig) {
+ logMessage(0, "", item);
+ }
+ }
+
+ }
}
diff --git a/src/de/blinkt/openvpn/OpenVPNThread.java b/src/de/blinkt/openvpn/OpenVPNThread.java
index 124179e..a5b3e5e 100644
--- a/src/de/blinkt/openvpn/OpenVPNThread.java
+++ b/src/de/blinkt/openvpn/OpenVPNThread.java
@@ -55,6 +55,8 @@ public class OpenVPNThread implements Runnable {
mService.getHandler().sendEmptyMessage(R.string.disconnected);
+ // Not a good place to do it, but will do
+ OpenVPN.logBuilderConfig(null);
Log.i(TAG, "Exiting");
}
}
diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
index f05f58d..2421b28 100644
--- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java
+++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
@@ -105,13 +105,14 @@ private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManageme
else if (cmd.equals("PASSWORD")) {
processPWCommand(argument);
} else if (cmd.equals("HOLD")) {
- managmentCommand("hold release\n");
+ managmentCommand("hold release\nlog on\n");
} else if (cmd.equals("PROTECT-FD")) {
protectFD(argument);
}
+ Log.i(TAG, "Got unrecognized command" + command);
+ } else {
+ Log.i(TAG, "Got unrecognized line from managment" + command);
}
- Log.i(TAG, "Got unrecognized command" + command);
-
}
@@ -158,10 +159,13 @@ private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManageme
}
- public static void stopOpenVPN() {
+ public static boolean stopOpenVPN() {
+ boolean sendCMD=false;
for (OpenVpnManagementThread mt: active){
mt.managmentCommand("signal SIGINT\n");
- }
+ sendCMD=true;
+ }
+ return sendCMD;
}
}
diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java
index 076fe7b..b4ae411 100644
--- a/src/de/blinkt/openvpn/OpenVpnService.java
+++ b/src/de/blinkt/openvpn/OpenVpnService.java
@@ -17,8 +17,11 @@
package de.blinkt.openvpn;
import java.io.IOException;
+import java.lang.reflect.Array;
import java.util.Vector;
+import de.blinkt.openvpn.OpenVpnService.CIDRIP;
+
import android.app.PendingIntent;
import android.content.Intent;
import android.net.LocalSocket;
@@ -83,11 +86,30 @@ public class OpenVpnService extends VpnService implements Handler.Callback {
public String toString() {
return String.format("%s/%d",mIp,len);
}
+
+ public boolean normalise(){
+ long ip=0;
+
+ String[] ipt = mIp.split("\\.");
+
+ ip += Long.parseLong(ipt[0])<< 24;
+ ip += Integer.parseInt(ipt[1])<< 16;
+ ip += Integer.parseInt(ipt[2])<< 8;
+ ip += Integer.parseInt(ipt[3]);
+
+ long newip = ip & (0xffffffffl << (32 -len));
+ if (newip != ip){
+ mIp = String.format("%d.%d.%d.%d", (newip & 0xff000000) >> 24,(newip & 0xff0000) >> 16, (newip & 0xff00) >> 8 ,newip & 0xff);
+ return true;
+ } else {
+ return false;
+ }
+ }
}
@Override
public void onRevoke() {
- mSocketManager.managmentCommand("signal SIGINT\n");
+ OpenVpnManagementThread.stopOpenVPN();
mServiceThread=null;
stopSelf();
};
@@ -128,8 +150,12 @@ public class OpenVpnService extends VpnService implements Handler.Callback {
}
// Stop the previous session by interrupting the thread.
- if (mSocketManager != null) {
- mSocketManager.managmentCommand("signal SIGINT\n");
+ if(OpenVpnManagementThread.stopOpenVPN()){
+ // an old was asked to exit, wait 2s
+ try {
+ Thread.sleep(2000);
+ } catch (InterruptedException e) {
+ }
}
if (mServiceThread!=null) {
@@ -210,13 +236,25 @@ public class OpenVpnService extends VpnService implements Handler.Callback {
if(mDomain!=null)
builder.addSearchDomain(mDomain);
-
+ String bconfig[] = new String[5];
+
+ bconfig[0]= getString(R.string.last_openvpn_tun_config);
+ bconfig[1] = String.format(getString(R.string.local_ip_info,mLocalIP.mIp,mLocalIP.len));
+ bconfig[2] = String.format(getString(R.string.dns_server_info, joinString(mDnslist)));
+ bconfig[3] = String.format(getString(R.string.dns_domain_info, mDomain));
+ bconfig[4] = String.format(getString(R.string.routes_info, joinString(mRoutes)));
+
+
+ OpenVPN.logBuilderConfig(bconfig);
+
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);
@@ -233,6 +271,23 @@ public class OpenVpnService extends VpnService implements Handler.Callback {
}
+
+ // Ugly, but java has no such method
+ private <T> String joinString(Vector<T> vec) {
+ String ret = "";
+ if(vec.size() > 0);
+ ret = vec.get(0).toString();
+ for(int i=1;i < vec.size();i++) {
+ ret = ret + ", " + vec.get(i).toString();
+ }
+ return ret;
+ }
+
+
+
+
+
+
public void addDNS(String dns) {
mDnslist.add(dns);
}
@@ -246,7 +301,15 @@ public class OpenVpnService extends VpnService implements Handler.Callback {
public void addRoute(String dest, String mask) {
- mRoutes.add(new CIDRIP(dest, mask));
+ CIDRIP route = new CIDRIP(dest, mask);
+ if(route.len == 32 && !mask.equals("255.255.255.255")) {
+ OpenVPN.logMessage(0, "", String.format(getString(R.string.route_not_cidr,dest,mask)));
+ }
+
+ if(route.normalise())
+ OpenVPN.logMessage(0, "", String.format(getString(R.string.route_not_netip,dest,route.len,route.mIp)));
+
+ mRoutes.add(route);
}