summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2012-07-30 20:43:49 +0200
committerArne Schwabe <arne@rfc2549.org>2012-07-30 20:43:49 +0200
commit704d06d967022737ddd3e6d6549c18402fe75b0f (patch)
treee5ad08d96eae745d631a7cd83f4b7ccecf8ea038
parentaa222a0434ad2c270e94fc2370e71e49d6b5331f (diff)
Use system proxy settings for openvpn
-rw-r--r--res/values-de/strings.xml3
-rw-r--r--res/values/strings.xml4
-rw-r--r--res/xml/general_settings.xml5
-rw-r--r--src/de/blinkt/openvpn/OpenVpnManagementThread.java46
-rw-r--r--src/de/blinkt/openvpn/ProxyDetection.java52
-rw-r--r--src/de/blinkt/openvpn/ShowConfigFragment.java2
-rw-r--r--src/de/blinkt/openvpn/VpnProfile.java15
7 files changed, 110 insertions, 17 deletions
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c7a80eed..8884b9e2 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -194,5 +194,6 @@
<string name="faq_system_dialogs_title">Warnung beim Verbinden und Benachrichtigungston</string>
<string name="tun_error_helpful">Auf manchen ROM Version sind eventuell die Zugriffsrechte von /dev/tun falsch oder das tun Kernel Modul fehlt. Für Cyanogenmod 9 ROMs mit root gibt einen provisorischen Fix in den generellen Einstellungen.</string>
<string name="importpkcs12fromconfig">Importiere die PKCS12 Datei, die in der Konfiguration angegeben ist, in den Android Keystore</string>
-
+ <string name="use_system_proxy">Benutze System Proxies</string>
+ <string name="use_system_proxy_summary">Benutze die System weiten Einstellungen für HTTP/HTTPS Proxies beim Verbinden.</string>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6ad486a5..dcdeb095 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -237,4 +237,8 @@
<string name="setting_loadtun_summary">Try to load the tun.ko kernel module before trying to connect. Needs rooted devices.</string>
<string name="setting_loadtun">Load tun module</string>
<string name="importpkcs12fromconfig">Import PKCS12 from configuration into Android Keystore</string>
+ <string name="getproxy_error">Error getting proxy settings: %s</string>
+ <string name="using_proxy">Using proxy %1$s %2$d</string>
+ <string name="use_system_proxy">Use system proxy</string>
+ <string name="use_system_proxy_summary">Use the system wide configuration for HTTP/HTTPS proxies to connect.</string>
</resources>
diff --git a/res/xml/general_settings.xml b/res/xml/general_settings.xml
index 73b66b00..5a2be01d 100644
--- a/res/xml/general_settings.xml
+++ b/res/xml/general_settings.xml
@@ -16,6 +16,11 @@
android:key="statusafterconnect"
android:summary="@string/keppstatus_summary"
android:title="@string/keepstatus" />
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:key="usesystemproxy"
+ android:summary="@string/use_system_proxy_summary"
+ android:title="@string/use_system_proxy" />
<PreferenceCategory android:title="Device specifics Hacks" >
<CheckBoxPreference
diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
index 99fa55e9..7a0beb1d 100644
--- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java
+++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
@@ -5,6 +5,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
@@ -35,7 +37,7 @@ public class OpenVpnManagementThread implements Runnable {
private String mCurrentstate;
private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
-
+
static private native void jniclose(int fdint);
static private native byte[] rsasign(byte[] input,int pkey) throws InvalidKeyException;
@@ -178,8 +180,10 @@ public class OpenVpnManagementThread implements Runnable {
processNeedCommand(argument);
} else if (cmd.equals("BYTECOUNT")){
processByteCount(argument);
- } else if (cmd.equals("STATE")){
+ } else if (cmd.equals("STATE")) {
processState(argument);
+ } else if (cmd.equals("PROXY")) {
+ processProxyCMD(argument);
} else if (cmd.equals("LOG")) {
String[] args = argument.split(",",3);
// 0 unix time stamp
@@ -200,6 +204,22 @@ public class OpenVpnManagementThread implements Runnable {
}
}
+ private void processProxyCMD(String argument) {
+ SocketAddress proxyaddr = ProxyDetection.detectProxy(mProfile);
+
+
+ if(proxyaddr instanceof InetSocketAddress ){
+ InetSocketAddress isa = (InetSocketAddress) proxyaddr;
+
+ OpenVPN.logInfo(R.string.using_proxy, isa.getHostName(),isa.getPort());
+
+ String proxycmd = String.format("proxy HTTP %s %d\n", isa.getHostName(),isa.getPort());
+ managmentCommand(proxycmd);
+ } else {
+ managmentCommand("proxy NONE\n");
+ }
+
+ }
private void processState(String argument) {
String[] args = argument.split(",",3);
mCurrentstate = args[1];
@@ -337,7 +357,7 @@ public class OpenVpnManagementThread implements Runnable {
}
return false;
}
-
+
private void processPWCommand(String argument) {
//argument has the form Need 'Private Key' password
@@ -400,21 +420,21 @@ public class OpenVpnManagementThread implements Runnable {
}
private void processSignCommand(String b64data) {
-
+
PrivateKey privkey = mProfile.getKeystoreKey();
Exception err =null;
// The Jelly Bean *evil* Hack
-
+
byte[] data = Base64.decode(b64data, Base64.DEFAULT);
if(Build.VERSION.SDK_INT>=16){
processSignJellyBeans(privkey,data);
return;
}
-
-
+
+
try{
-
+
Cipher rsasinger = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
@@ -450,19 +470,19 @@ public class OpenVpnManagementThread implements Runnable {
System.out.println(allm);
Method getKey = privkey.getClass().getSuperclass().getDeclaredMethod("getOpenSSLKey");
getKey.setAccessible(true);
-
+
// Real object type is OpenSSLKey
Object opensslkey = getKey.invoke(privkey);
-
+
getKey.setAccessible(false);
-
+
Method getPkeyContext = opensslkey.getClass().getDeclaredMethod("getPkeyContext");
-
+
// integer pointer to EVP_pkey
getPkeyContext.setAccessible(true);
int pkey = (Integer) getPkeyContext.invoke(opensslkey);
getPkeyContext.setAccessible(false);
-
+
byte[] signed_bytes = rsasign(data, pkey);
String signed_string = Base64.encodeToString(signed_bytes, Base64.NO_WRAP);
managmentCommand("rsa-sig\n");
diff --git a/src/de/blinkt/openvpn/ProxyDetection.java b/src/de/blinkt/openvpn/ProxyDetection.java
new file mode 100644
index 00000000..dfcfbf19
--- /dev/null
+++ b/src/de/blinkt/openvpn/ProxyDetection.java
@@ -0,0 +1,52 @@
+package de.blinkt.openvpn;
+
+import java.net.InetSocketAddress;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+
+public class ProxyDetection {
+ static SocketAddress detectProxy(VpnProfile vp) {
+ // Construct a new url with https as protocol
+ try {
+ URL url = new URL(String.format("https://%s:%s",vp.mServerName,vp.mServerPort));
+ Proxy proxy = getFirstProxy(url);
+
+ if(proxy==null)
+ return null;
+ SocketAddress addr = proxy.address();
+ if (addr instanceof InetSocketAddress) {
+ return addr;
+ }
+
+ } catch (MalformedURLException e) {
+ OpenVPN.logError(R.string.getproxy_error,e.getLocalizedMessage());
+ } catch (URISyntaxException e) {
+ OpenVPN.logError(R.string.getproxy_error,e.getLocalizedMessage());
+ }
+ return null;
+ }
+
+ static Proxy getFirstProxy(URL url) throws URISyntaxException {
+ System.setProperty("java.net.useSystemProxies", "true");
+
+ List<Proxy> proxylist = ProxySelector.getDefault().select(url.toURI());
+
+
+ if (proxylist != null) {
+ for (Proxy proxy: proxylist) {
+ SocketAddress addr = proxy.address();
+
+ if (addr != null) {
+ return proxy;
+ }
+ }
+
+ }
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/ShowConfigFragment.java b/src/de/blinkt/openvpn/ShowConfigFragment.java
index 2f6c23d7..dae83438 100644
--- a/src/de/blinkt/openvpn/ShowConfigFragment.java
+++ b/src/de/blinkt/openvpn/ShowConfigFragment.java
@@ -27,7 +27,7 @@ public class ShowConfigFragment extends Fragment {
configtext = getString(check);
}
else {
- String cfg=vp.getConfigFile(getActivity().getCacheDir());
+ String cfg=vp.getConfigFile(getActivity());
configtext= cfg;
cv.setText(cfg);
}
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
index 4e381fcc..199f6b54 100644
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ b/src/de/blinkt/openvpn/VpnProfile.java
@@ -23,7 +23,9 @@ import org.spongycastle.util.io.pem.PemWriter;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
+import android.preference.PreferenceManager;
import android.security.KeyChain;
import android.security.KeyChainException;
@@ -144,9 +146,10 @@ public class VpnProfile implements Serializable{
}
- public String getConfigFile(File cacheDir)
+ public String getConfigFile(Context context)
{
+ File cacheDir= context.getCacheDir();
String cfg="";
// Enable managment interface
@@ -331,6 +334,14 @@ public class VpnProfile implements Serializable{
if(mUseFloat)
cfg+= "float\n";
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true);
+ if(usesystemproxy) {
+ cfg+= "# Use system proxy setting\n";
+ cfg+= "management-query-proxy\n";
+ }
+
+
if(mUseCustomConfig) {
cfg += "# Custom configuration options\n";
cfg += "# You are on your on own here :)\n";
@@ -464,7 +475,7 @@ public class VpnProfile implements Serializable{
try {
FileWriter cfg = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE);
- cfg.write(getConfigFile(context.getCacheDir()));
+ cfg.write(getConfigFile(context));
cfg.flush();
cfg.close();
} catch (IOException e) {