diff options
| -rw-r--r-- | res/values-de/strings.xml | 3 | ||||
| -rw-r--r-- | res/values/strings.xml | 4 | ||||
| -rw-r--r-- | res/xml/general_settings.xml | 5 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnManagementThread.java | 46 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/ProxyDetection.java | 52 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/ShowConfigFragment.java | 2 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 15 | 
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) { | 
