diff options
| author | schwabe <devnull@localhost> | 2012-04-29 15:22:01 +0200 | 
|---|---|---|
| committer | schwabe <devnull@localhost> | 2012-04-29 15:22:01 +0200 | 
| commit | 1f3ea57ee9f0cabdcfd2b585f16bf754984a669d (patch) | |
| tree | a40f9151d8bd58ec0c39835168f268101d5a4104 /src | |
| parent | 63e466054c2f1d66e4618ac4d73208751f1e5bd1 (diff) | |
Version 0.4
fixes iusse #1
fixes iusse #2
fixes iusse #3
Diffstat (limited to 'src')
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPN.java | 16 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnService.java | 69 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/Settings_Authentication.java | 6 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/Settings_IP.java | 11 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/ShowConfigFragment.java | 12 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VPNPreferences.java | 4 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VPNProfileList.java | 2 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 113 | 
8 files changed, 182 insertions, 51 deletions
diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index bca276c9..c3d92a4c 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -8,7 +8,6 @@ import android.util.Log;  public class OpenVPN {  	private static OpenVpnService mOpenVpnService; -	private static String localip;  	private static final int MAXLOGENTRIES = 500;  	public static native int startOpenVPNThread();  	public static native int startOpenVPNThreadArgs(String argv[]); @@ -32,14 +31,15 @@ public class OpenVPN {  	    }  	 static void addRoute(String dest,String mask, String gw) { -	        Log.i("openvpn" ,"Got Routing information " + dest + " " + mask + "  " + 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.addFirst(prefix + " " + message); +		 logbuffer.addLast(prefix + " " + message);  		 if(logbuffer.size()>MAXLOGENTRIES) -			 logbuffer.removeLast(); +			 logbuffer.removeFirst();  		 // The garbage collector does not collect the String from native  		 // but kills me for logging 100 messages with too many references :( @@ -62,10 +62,10 @@ public class OpenVPN {  	 } -	 static void addInterfaceInfo(int mtu, String local, String remote) +	 static void addInterfaceInfo(int mtu, String local, String netmask)  	 { -		 Log.i("openvpn","Got interface info M"  + mtu + " L: " + local + "R: " + remote); -		 localip=local; +		 Log.i("openvpn","Got interface info M"  + mtu + " L: " + local + "NM: " + netmask); +		 mOpenVpnService.setLocalIP(local,netmask);  	 }  	 static void addDns(String dns) { @@ -96,7 +96,7 @@ public class OpenVPN {  	public static int openTunDevice() {  		Log.d(TAG,"Opening tun device"); -		ParcelFileDescriptor pfd = mOpenVpnService.openTun(localip); +		ParcelFileDescriptor pfd = mOpenVpnService.openTun();  		return pfd.detachFd();  	}  	//! Dummy method being called to force loading of JNI Libraries diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java index 1cc5b2ec..39d73adb 100644 --- a/src/de/blinkt/openvpn/OpenVpnService.java +++ b/src/de/blinkt/openvpn/OpenVpnService.java @@ -21,6 +21,8 @@ import java.net.UnknownHostException;  import java.util.Arrays;  import java.util.Vector; +import de.blinkt.openvpn.OpenVpnService.CIDRIP; +  import android.app.PendingIntent;  import android.content.Intent;  import android.net.LocalSocket; @@ -38,7 +40,8 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn      private String[] mArgv;      private Handler mHandler; -    private Thread mThread; +    // Only one VPN, make this thread shared between all instances +    private static Thread mThread;      private ParcelFileDescriptor mInterface; @@ -48,6 +51,36 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn  	private String mDomain=null; +	private Vector<CIDRIP> mRoutes=new Vector<CIDRIP>(); + +	private CIDRIP mLocalIP; + +	 +	class CIDRIP{ +		String mIp; +		int len; +		public CIDRIP(String ip, String mask){ +			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++; +				netmask = netmask >> 1; +			} +		} +		@Override +		public String toString() { +			return String.format("%s/%d",mIp,len); +		} +	} +	      @Override      public void onRevoke() {      	managmentCommand("signal SIGINT\n"); @@ -216,19 +249,31 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn      } -	public ParcelFileDescriptor openTun(String localip) { -		// FIXME: hardcoded assumptions +	public ParcelFileDescriptor openTun() {          Builder builder = new Builder(); -        builder.addRoute("0.0.0.0", 0); -        builder.addAddress(localip, 24 ); +         +        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); -        builder.setSession(mProfile.mName + " - " + localip); + +        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); @@ -248,4 +293,14 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn  			mDomain=domain;  		}  	} + + +	public void addRoute(String dest, String mask) { +		mRoutes.add(new CIDRIP(dest, mask)); +	} + + +	public void setLocalIP(String local, String netmask) { +		mLocalIP = new CIDRIP(local, netmask); +	}  } diff --git a/src/de/blinkt/openvpn/Settings_Authentication.java b/src/de/blinkt/openvpn/Settings_Authentication.java index f3ebb36d..4c70344d 100644 --- a/src/de/blinkt/openvpn/Settings_Authentication.java +++ b/src/de/blinkt/openvpn/Settings_Authentication.java @@ -58,7 +58,7 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre  		mUseTLSAuth.setChecked(mProfile.mUseTLSAuth);  		mTLSAuthFile.setSummary(mProfile.mTLSAuthFilename); -		//mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection); +		mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection);  	}  	private void saveSettings() { @@ -72,10 +72,10 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre  		else  			mProfile.mTLSAuthFilename = mTLSAuthFile.getSummary().toString(); -		if(mTLSAuthDirection.getEntry()==null) +		if(mTLSAuthDirection.getValue()==null)  			mProfile.mTLSAuthDirection=null;  		else -			mProfile.mTLSAuthDirection = mTLSAuthDirection.getEntry().toString(); +			mProfile.mTLSAuthDirection = mTLSAuthDirection.getValue().toString();  	}  	@Override diff --git a/src/de/blinkt/openvpn/Settings_IP.java b/src/de/blinkt/openvpn/Settings_IP.java index c2b1ed71..de625d22 100644 --- a/src/de/blinkt/openvpn/Settings_IP.java +++ b/src/de/blinkt/openvpn/Settings_IP.java @@ -19,6 +19,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  		private EditTextPreference mCustomRoutes;  		private CheckBoxPreference mUseDefaultRoute;  		private VpnProfile mProfile; +		private CheckBoxPreference mRouteNoPull;  		@Override  		public void onCreate(Bundle savedInstanceState) { @@ -45,6 +46,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mDNS2 = (EditTextPreference) findPreference("dns2");  			mCustomRoutes = (EditTextPreference) findPreference("customRoutes");  			mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute"); +			mRouteNoPull = (CheckBoxPreference) findPreference("routenopull");  			mIPv4.setOnPreferenceChangeListener(this);  			mIPv6.setOnPreferenceChangeListener(this); @@ -72,6 +74,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mSearchdomain.setText(mProfile.mSearchDomain);  			mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute);  			mCustomRoutes.setText(mProfile.mCustomRoutes); +			mRouteNoPull.setChecked(mProfile.mRoutenopull);  			// Sets Summary  			onPreferenceChange(mIPv4, mIPv4.getText()); @@ -105,7 +108,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mProfile.mSearchDomain = mSearchdomain.getText();  			mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked();  			mProfile.mCustomRoutes = mCustomRoutes.getText(); -			 +			mProfile.mRoutenopull = mRouteNoPull.isChecked();  		} @@ -120,10 +123,10 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  				preference.setSummary((String)newValue);  			if(preference== mUsePull || preference == mOverrideDNS) -				if(preference==mOverrideDNS)  +				if(preference==mOverrideDNS) {   					// Set so the function gets the right value  					mOverrideDNS.setChecked((Boolean) newValue); -				 +				}  				setDNSState();  			saveSettings(); @@ -133,6 +136,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  		private void setDNSState() {  			boolean enabled;  			mOverrideDNS.setEnabled(mUsePull.isChecked()); +			mRouteNoPull.setEnabled(mUsePull.isChecked());  			if(!mUsePull.isChecked())  				enabled =true;  			else if (mOverrideDNS.isChecked()) @@ -143,6 +147,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mDNS1.setEnabled(enabled);  			mDNS2.setEnabled(enabled);  			mSearchdomain.setEnabled(enabled); +			  		} diff --git a/src/de/blinkt/openvpn/ShowConfigFragment.java b/src/de/blinkt/openvpn/ShowConfigFragment.java index a69d835a..68898e07 100644 --- a/src/de/blinkt/openvpn/ShowConfigFragment.java +++ b/src/de/blinkt/openvpn/ShowConfigFragment.java @@ -13,10 +13,18 @@ public class ShowConfigFragment extends Fragment {  	{  		String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID");  		VpnProfile vp = ProfileManager.get(profileUUID); -		String cfg=vp.getConfigFile(getActivity().getCacheDir());  		View v=inflater.inflate(R.layout.viewconfig, container,false);  		TextView cv = (TextView) v.findViewById(R.id.configview); -		cv.setText(cfg); +		 +		int check=vp.checkProfile(); +		if(check!=R.string.no_error_found) { +			cv.setText(check); +		} +		else {  +			String cfg=vp.getConfigFile(getActivity().getCacheDir()); + +			cv.setText(cfg); +		}  		return v;  	};  } diff --git a/src/de/blinkt/openvpn/VPNPreferences.java b/src/de/blinkt/openvpn/VPNPreferences.java index 4b1c7377..771cd902 100644 --- a/src/de/blinkt/openvpn/VPNPreferences.java +++ b/src/de/blinkt/openvpn/VPNPreferences.java @@ -44,11 +44,11 @@ public class VPNPreferences extends PreferenceActivity { -		if (hasHeaders()) { +		/* if (hasHeaders()) {  			Button button = new Button(this);  			button.setText("Save");  			setListFooter(button); -		} +		} */  	} diff --git a/src/de/blinkt/openvpn/VPNProfileList.java b/src/de/blinkt/openvpn/VPNProfileList.java index f77c8639..8f4304dc 100644 --- a/src/de/blinkt/openvpn/VPNProfileList.java +++ b/src/de/blinkt/openvpn/VPNProfileList.java @@ -184,7 +184,7 @@ public class VPNProfileList extends PreferenceFragment implements  VpnPreference  			startActivity(startLW); -			OpenVPN.logMessage(0, "", "Building confugration..."); +			OpenVPN.logMessage(0, "", "Building configration...");  			Intent startVPN = mSelectedVPN.prepareIntent(getActivity()); diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index e17fb8ff..2df4ec39 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -12,6 +12,7 @@ import java.security.NoSuchAlgorithmException;  import java.security.PrivateKey;  import java.security.cert.CertificateException;  import java.security.cert.X509Certificate; +import java.util.Collection;  import java.util.Random;  import java.util.UUID;  import java.util.Vector; @@ -35,7 +36,7 @@ public class VpnProfile implements  Serializable{  	static final int TYPE_KEYSTORE=2;  	public static final int TYPE_USERPASS = 3;  	public static final int TYPE_STATICKEYS = 4; -	 +  	private static final String OVPNCONFIGFILE = "android.conf";  	// Keep in order of parceling @@ -71,6 +72,7 @@ public class VpnProfile implements  Serializable{  	public String mRemoteCN="";  	private String mPassword;  	private String mUsername; +	public boolean mRoutenopull=false;  	public int describeContents() { @@ -145,27 +147,27 @@ public class VpnProfile implements  Serializable{  		return mName;  	} -	 +  	public String getConfigFile(File cacheDir)  	{  		String cfg=""; -		 -		 + +  		// TODO  "--remote-cert-eku", "TLS Web Server Authentication" -		 +  		boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS); -	 +  		if(useTLSClient && mUsePull)  			cfg+="client\n";  		else if (mUsePull)  			cfg+="pull\n";  		else if(useTLSClient) -			cfg+="tls-client"; -			 -		 +			cfg+="tls-client\n"; + +  		cfg+="verb 2\n"; @@ -240,19 +242,30 @@ public class VpnProfile implements  Serializable{  		// Basic Settings  		if(!mUsePull ) { -			cfg +="ifconfig " + mIPv4Address + " 255.255.255.255\n"; +			cfg +="ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n";  		} -		 + +		if(mUsePull && mRoutenopull) +			cfg += "route-nopull\n"; + +		if(mUseDefaultRoute) +			cfg += "route 0.0.0.0 0.0.0.0\n"; +		else +			for(String route:getCustomRoutes()) { +				cfg += "route " + route + "\n"; +			} + +  		if(mOverrideDNS || !mUsePull) {  			if(!mDNS1.equals("") && mDNS1!=null)  				cfg+="dhcp-option DNS " + mDNS1 + "\n";  			if(!mDNS2.equals("") && mDNS2!=null)  				cfg+="dhcp-option DNS " + mDNS2 + "\n"; -			 +  		} -		 -		 + +  		// Authentication  		if(mCheckRemoteCN) {  			if(mRemoteCN == null || mRemoteCN.equals("") ) @@ -262,9 +275,52 @@ public class VpnProfile implements  Serializable{  		}  		if(mExpectTLSCert)  			cfg += "remote-cert-tls server\n"; -		 +  		return cfg;  	} + +	private Collection<String> getCustomRoutes() { +		Vector<String> cidrRoutes=new Vector<String>(); +		for(String route:mCustomRoutes.split("[\n \t]")) { +			if(!route.equals("")) { +				String cidrroute = cidrToIPAndNetmask(route); +				if(cidrRoutes == null) +					return null; +				 +				cidrRoutes.add(cidrroute); +			} +		} +		 +		return cidrRoutes; +	} + +	private String cidrToIPAndNetmask(String route) { +		String[] parts = route.split("/"); + +		// No /xx, return verbatim +		if (parts.length ==1) +			return route; + +		if (parts.length!=2) +			return null; +		int len; +		try {  +			len = Integer.parseInt(parts[1]); +		}	catch(NumberFormatException ne) { +			return null; +		} +		if (len <0 || len >32) +			return null; + + +		long nm = 0xffffffffl; +		nm = (nm << len) & 0xffffffffl; + +		String netmask =String.format("%d.%d.%d.%d", (nm & 0xff000000) >> 24,(nm & 0xff0000) >> 16, (nm & 0xff00) >> 8 ,nm & 0xff  );	 +		return parts[0] + "  " + netmask; +	} + +  	private String[] buildOpenvpnArgv(File cacheDir)  	{ @@ -290,8 +346,8 @@ public class VpnProfile implements  Serializable{  	public Intent prepareIntent(Activity activity) {  		String prefix = activity.getPackageName(); -		 -		 Intent intent = new Intent(activity,OpenVpnService.class); + +		Intent intent = new Intent(activity,OpenVpnService.class);  		intent.putExtra(prefix + ".ARGV" , buildOpenvpnArgv(activity.getCacheDir())); @@ -304,14 +360,14 @@ public class VpnProfile implements  Serializable{  			String pkcs12pw = savePKCS12(activity);  			intent.putExtra(prefix + ".PKCS12PASS", pkcs12pw);  		} -		 +  		if(mAuthenticationType == VpnProfile.TYPE_USERPASS) {  			intent.putExtra(prefix + ".USERNAME", mUsername);  			intent.putExtra(prefix + ".PASSWORD", mPassword);  		} -		 +  		intent.putExtra(prefix + ".profileUUID", mUuid.toString()); -		 +  		try {  			FileWriter cfg = new FileWriter(activity.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE);  			cfg.write(getConfigFile(activity.getCacheDir())); @@ -320,10 +376,10 @@ public class VpnProfile implements  Serializable{  		} catch (IOException e) {  			e.printStackTrace();  		} -		 +  		return intent;  	} -	 +  	private String getRandomPW() {  		String pw= "";  		// Put enough digits togher to make a password :) @@ -373,11 +429,18 @@ public class VpnProfile implements  Serializable{  	int checkProfile() {  		if(mAuthenticationType==TYPE_KEYSTORE && mAlias==null)   			return R.string.no_keystore_cert_selected; -		 -		 + +		if(!mUsePull) { +			if(mIPv4Address == null || cidrToIPAndNetmask(mIPv4Address) == null) +				return R.string.ipv4_format_error; +			 +		} +		if(!mUseDefaultRoute && getCustomRoutes()==null) +			return R.string.custom_route_format_error; +  		// Everything okay  		return R.string.no_error_found; -		 +  	}  | 
