diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2012-05-13 01:16:27 +0200 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2012-05-13 01:16:27 +0200 | 
| commit | 9e2afc72b16125f7c365b8d600f6f5df36aa8f48 (patch) | |
| tree | f2733212c02f8816a6188c70fd0e358876b90d0e /src | |
| parent | 5a65e0c5e80d147909acffa14b04d3c99d48de1a (diff) | |
Config Import useable (closes issue #14)
Correct save/restore state in Basic Settings (closes issue #17)
Diffstat (limited to 'src')
| -rw-r--r-- | src/de/blinkt/openvpn/CIDRIP.java | 56 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/ConfigConverter.java | 41 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/ConfigParser.java | 152 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/FileSelect.java | 11 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/FileSelectLayout.java | 14 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnService.java | 56 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/Settings_Basic.java | 2 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/Settings_IP.java | 8 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VPNProfileList.java | 22 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/VpnProfile.java | 24 | 
10 files changed, 243 insertions, 143 deletions
| diff --git a/src/de/blinkt/openvpn/CIDRIP.java b/src/de/blinkt/openvpn/CIDRIP.java new file mode 100644 index 00000000..c2f0d821 --- /dev/null +++ b/src/de/blinkt/openvpn/CIDRIP.java @@ -0,0 +1,56 @@ +package de.blinkt.openvpn; + +class CIDRIP{ +	String mIp; +	int len; +	public CIDRIP(String ip, String mask){ +		mIp=ip; +		String[] ipt = mask.split("\\."); +		long netmask=0; + +		netmask += Long.parseLong(ipt[0])<< 24; +		netmask += Integer.parseInt(ipt[1])<< 16; +		netmask += Integer.parseInt(ipt[2])<< 8; +		netmask += Integer.parseInt(ipt[3]); + +		// Add 33. bit to ensure the loop terminates +		netmask += 1l << 32; + +		int lenZeros = 0; +		while((netmask & 0x1) == 0) { +			lenZeros++; +			netmask = netmask >> 1; +		} +		// Check if rest of netmask is only 1s +		if(netmask != (0x1ffffffffl >> lenZeros)) { +			// Asume no CIDR, set /32 +			len=32; +		} else { +			len =32 -lenZeros;  +		} + +	} +	@Override +	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; +		} +	} +}
\ No newline at end of file diff --git a/src/de/blinkt/openvpn/ConfigConverter.java b/src/de/blinkt/openvpn/ConfigConverter.java index 1973e0ac..686a4e42 100644 --- a/src/de/blinkt/openvpn/ConfigConverter.java +++ b/src/de/blinkt/openvpn/ConfigConverter.java @@ -24,7 +24,7 @@ public class ConfigConverter extends ListActivity {  	private VpnProfile mResult;
  	private ArrayAdapter<String> mArrayAdapter;
 -	
 +
  	@Override
  	protected void onCreate(Bundle savedInstanceState) {
 @@ -32,7 +32,7 @@ public class ConfigConverter extends ListActivity {  		Toast.makeText(this, "Got called!", Toast.LENGTH_LONG).show();
  	}
 -	
 +
  	@Override
  	public boolean onOptionsItemSelected(MenuItem item) {
  		if(item.getItemId()==R.id.cancel){
 @@ -41,6 +41,7 @@ public class ConfigConverter extends ListActivity {  		} else if(item.getItemId()==R.id.ok) {
  			if(mResult==null) {
  				log("Importing the config had error, cannot save it");
 +				return true;
  			}
  			Intent result = new Intent();
  			ProfileManager vpl = ProfileManager.getInstance(this);
 @@ -48,6 +49,7 @@ public class ConfigConverter extends ListActivity {  			result.putExtra(VpnProfile.EXTRA_PROFILEUUID,mResult.getUUID().toString());
  			setResult(Activity.RESULT_OK, result);
  			finish();
 +			return true;
  		}
  		return super.onOptionsItemSelected(item);
 @@ -61,7 +63,7 @@ public class ConfigConverter extends ListActivity {  		return true;
  	}
 -	
 +
  	private String embedFile(String filename)
  	{
  		if(filename == null || filename.equals(""))
 @@ -69,7 +71,7 @@ public class ConfigConverter extends ListActivity {  		// Already embedded, nothing to do
  		if(filename.startsWith(VpnProfile.INLINE_TAG))
  			return filename;
 -		
 +
  		// Try diffent path relative to /mnt/sdcard
  		File sdcard = Environment.getExternalStorageDirectory();
  		File root = new File("/");
 @@ -82,15 +84,15 @@ public class ConfigConverter extends ListActivity {  					suffix = fileparts[i];
  				else
  					suffix = fileparts[i] + "/" + suffix;
 -				
 +
  				File possibleFile = new File(rootdir,suffix);
  				if(!possibleFile.canRead())
  					continue;
 -				
 +
  				// read the file inline
  				String filedata = VpnProfile.INLINE_TAG;
  				byte[] buf =new byte[2048];
 -				
 +
  				log(R.string.trying_to_read, possibleFile.getAbsolutePath());
  				try {
  					FileInputStream fis = new FileInputStream(possibleFile);
 @@ -105,25 +107,25 @@ public class ConfigConverter extends ListActivity {  				} catch (IOException e) {
  					log(e.getLocalizedMessage());
  				}	
 -						
 -			
 +
 +
  			}
  		}
  		log(R.string.import_could_not_open,filename);
  		return null;
  	}
 -	
 +
  	void embedFiles() {
  		// This where I would like to have a c++ style
  		// void embedFile(std::string & option)
 -		
 +
  		mResult.mCaFilename = embedFile(mResult.mCaFilename);
  		mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename);
  		mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename);
  		mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename);
  	}
 -	
 -	
 +
 +
  	@Override
  	protected void onStart() {
  		super.onStart();
 @@ -137,6 +139,7 @@ public class ConfigConverter extends ListActivity {  			final android.net.Uri data = intent.getData ();
  			if (data != null)
  			{
 +				log(R.string.import_experimental);
  				log(R.string.importing_config,data.toString());
  				try {
  					InputStream is = getContentResolver().openInputStream(data);
 @@ -146,14 +149,14 @@ public class ConfigConverter extends ListActivity {  				}
  			} 
  		} 
 -				
 +
  		return;
  	}
  	private void log(String logmessage) {
  		mArrayAdapter.add(logmessage);
  	}
 -	
 +
  	private void doImport(InputStream is) {
  		ConfigParser cp = new ConfigParser();
  		try {
 @@ -164,7 +167,7 @@ public class ConfigConverter extends ListActivity {  			displayWarnings();
  			log(R.string.import_done);
  			return;
 -			
 +
  		} catch (IOException e) {
  			log(R.string.error_reading_config_file);
  			log(e.getLocalizedMessage());
 @@ -173,7 +176,7 @@ public class ConfigConverter extends ListActivity {  			log(e.getLocalizedMessage());			
  		}
  		mResult=null;
 -		
 +
  	}
  	private void displayWarnings() {
 @@ -181,11 +184,11 @@ public class ConfigConverter extends ListActivity {  			log(R.string.import_warning_custom_options);
  			log(mResult.mCustomConfigOptions);
  		}
 -		
 +
  		if(mResult.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) {
  			log(R.string.import_pkcs12_to_keystore);
  		}
 -		
 +
  	}
 diff --git a/src/de/blinkt/openvpn/ConfigParser.java b/src/de/blinkt/openvpn/ConfigParser.java index 8fde12b8..a64fb403 100644 --- a/src/de/blinkt/openvpn/ConfigParser.java +++ b/src/de/blinkt/openvpn/ConfigParser.java @@ -5,7 +5,6 @@ import java.io.IOException;  import java.io.InputStream;  import java.io.InputStreamReader;  import java.util.HashMap; -import java.util.Map.Entry;  import java.util.Vector;  //! Openvpn Config FIle Parser, probably not 100% accurate but close enough @@ -17,7 +16,7 @@ import java.util.Vector;  public class ConfigParser { -	private HashMap<String,Vector<String>> options = new HashMap<String, Vector<String>>(); +	private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>();  	public void parseConfig(InputStream inputStream) throws IOException, ConfigParseError { @@ -37,13 +36,16 @@ public class ConfigParser {  				continue; -  			if(args.get(0).startsWith("--"))  				args.set(0, args.get(0).substring(2));  			checkinlinefile(args,br); -			options.put(args.get(0), args); +			String optionname = args.get(0); +			if(!options.containsKey(optionname)) { +				options.put(optionname, new Vector<Vector<String>>()); +			} +			options.get(optionname).add(args);  		}  	} @@ -213,12 +215,18 @@ public class ConfigParser {  			"route-up",  			"ipchange",  			"route-up", -			"auth-user-pass-verify" +			"auth-user-pass-verify", +			"route-gateway", +			"topology", +			"persist-tun", +			"route-metric" +			  	}; -	// Missing -	// proto tcp-client|udp - +	 +	 +	// This method is far too long  	VpnProfile convertProfile() throws ConfigParseError{ +		boolean noauthtypeset=true;  		VpnProfile np = new VpnProfile("converted Profile");  		// Pull, client, tls-client  		np.clearDefaults(); @@ -228,17 +236,34 @@ public class ConfigParser {  			options.remove("pull");  			options.remove("client");  		} - +		  		Vector<String> secret = getOption("secret", 1, 2);  		if(secret!=null)   		{  			np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; +			noauthtypeset=false;  			np.mUseTLSAuth=true;  			np.mTLSAuthFilename=secret.get(1);  			if(secret.size()==3)  				np.mTLSAuthDirection=secret.get(2); +			  		} - +		 +		Vector<Vector<String>> routes = getAllOption("route", 1, 4); +		if(routes!=null) { +			String routeopt = ""; +			for(Vector<String> route:routes){ +				String netmask = "255.255.255.255"; +				if(route.size() >= 3) +					netmask = route.get(2); +				String net = route.get(1);	 +				 +				CIDRIP cidr = new CIDRIP(net, netmask); +				routeopt+=cidr.toString() + " "; +			} +			np.mCustomRoutes=routeopt; +		} +		  		Vector<String> tlsauth = getOption("tls-auth", 1, 2);  		if(tlsauth!=null)   		{ @@ -252,12 +277,9 @@ public class ConfigParser {  		if(direction!=null)  			np.mTLSAuthDirection=direction.get(1); -		if(options.containsKey("redirect-gateway")) { -			options.remove("redirect-gateway"); -			np.mUseDefaultRoute=true; -		} else { + +		if(getAllOption("redirect-gateway", 0, 5) != null)  			np.mUseDefaultRoute=true; -		}  		Vector<String> dev =getOption("dev",1,1);  		Vector<String> devtype =getOption("dev-type",1,1); @@ -296,24 +318,41 @@ public class ConfigParser {  				np.mServerName = remote.get(1);  			}  		} + +		Vector<String> port = getOption("port", 1,1); +		if(port!=null){ +			np.mServerPort = port.get(1); +		} -		Vector<String> proto = getOption("proto, ", 1,1); +		Vector<String> proto = getOption("proto", 1,1);  		if(proto!=null){  			if(proto.get(1).equals("udp"))  				np.mUseUdp=true; -			else if (proto.get(1).equals("tcp-client")) +			else if (proto.get(1).equals("tcp-client") || +					proto.get(1).equals("tcp"))  				np.mUseUdp=false;  			else   				throw new ConfigParseError("Unsupported option to --proto " + proto.get(1)); -					 +  		} -		 -		Vector<String> dhcpoption = getOption("dhcp-options", 1, 3); -		if(dhcpoption!=null) { -			String type=dhcpoption.get(1); +		Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-options", 2, 2); +		if(dhcpoptions!=null) { +			for(Vector<String> dhcpoption:dhcpoptions) { +				String type=dhcpoption.get(1); +				String arg = dhcpoption.get(2); +				if(type.equals("DOMAIN")) { +					np.mSearchDomain=dhcpoption.get(2); +				} else if(type.equals("DNS")) { +					np.mOverrideDNS=true; +					if(np.mDNS1.equals(VpnProfile.DEFAULT_DNS1)) +						np.mDNS1=arg; +					else +						np.mDNS2=arg; +				} +			}  		} -		 +  		if(getOption("remote-random-hostname", 0, 0)!=null)  			np.mUseRandomHostname=true; @@ -336,6 +375,7 @@ public class ConfigParser {  		if(cert!=null){  			np.mClientCertFilename = cert.get(1);  			np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES; +			noauthtypeset=false;  		}  		Vector<String> key= getOption("key",1,1);  		if(key!=null) @@ -345,6 +385,7 @@ public class ConfigParser {  		if(pkcs12!=null) {  			np.mPKCS12Filename = pkcs12.get(1);  			np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; +			noauthtypeset=false;  		}  		Vector<String> tlsremote = getOption("tls-remote",1,1); @@ -352,14 +393,36 @@ public class ConfigParser {  			np.mRemoteCN = tlsremote.get(1);  			np.mCheckRemoteCN=true;  		}  -		 +  		Vector<String> verb = getOption("verb",1,1);  		if(verb!=null){  			np.mVerb=verb.get(1);  		} +		 +		if(getOption("nobind", 0, 0) != null) +			np.mNobind=true; +		 +		if(getOption("auth-user-pass",0,1) != null) { +			if(noauthtypeset) { +				np.mAuthenticationType=VpnProfile.TYPE_USERPASS; +			} else if(np.mAuthenticationType==VpnProfile.TYPE_CERTIFICATES) { +				np.mAuthenticationType=VpnProfile.TYPE_USERPASS_CERTIFICATES; +			} else if(np.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) { +				np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE; +			}  +		} + +		  		// Check the other options +		checkIgnoreAndInvalidOptions(np); +		fixup(np); + +		return np; +	} + +	private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError {  		for(String option:unsupportedOptions)  			if(options.containsKey(option))  				throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option)); @@ -369,24 +432,23 @@ public class ConfigParser {  			options.remove(option);  		if(options.size()> 0) { -			String custom = "# These Options were found in the config file but not parsed:\n"; -			for(Entry<String, Vector<String>> option:options.entrySet()) { -				for (String arg : option.getValue()) { -					custom+= arg + " "; +			String custom = "# These Options were found in the config file do not map to config settings:\n"; + +			for(Vector<Vector<String>> option:options.values()) { +				for(Vector<String> optionsline: option) { +					for (String arg : optionsline) +						custom+= arg + " ";  				}  				custom+="\n"; +  			}  			np.mCustomConfigOptions = custom;  			np.mUseCustomConfig=true;  		} - - -		fixup(np); - -		return np;  	} +  	private void fixup(VpnProfile np) {  		if(np.mRemoteCN.equals(np.mServerName)) {  			np.mRemoteCN=""; @@ -394,14 +456,26 @@ public class ConfigParser {  	}  	private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError { -		Vector<String> args = options.get(option); +		Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg); +		if(alloptions==null) +			return null; +		else +			return alloptions.lastElement(); +	} + + +	private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { +		Vector<Vector<String>> args = options.get(option);  		if(args==null)  			return null; -		if(args.size()< (minarg+1) || args.size() > maxarg+1) { -			String err = String.format("Option %s has %d parameters, expected between %d and %d", -					option,args.size()-1,minarg,maxarg ); -			throw new ConfigParseError(err); -		} + +		for(Vector<String> optionline:args) + +			if(optionline.size()< (minarg+1) || optionline.size() > maxarg+1) { +				String err = String.format("Option %s has %d parameters, expected between %d and %d", +						option,args.size()-1,minarg,maxarg ); +				throw new ConfigParseError(err); +			}  		options.remove(option);  		return args;  	} diff --git a/src/de/blinkt/openvpn/FileSelect.java b/src/de/blinkt/openvpn/FileSelect.java index 12a3ae01..cc8f55f4 100644 --- a/src/de/blinkt/openvpn/FileSelect.java +++ b/src/de/blinkt/openvpn/FileSelect.java @@ -19,6 +19,7 @@ import android.os.Bundle;  public class FileSelect extends Activity {  	public static final String RESULT_DATA = "RESULT_PATH";  	public static final String START_DATA = "START_DATA"; +	public static final String WINDOW_TITLE = "WINDOW_TILE";  	public static final String NO_INLINE_SELECTION = "de.blinkt.openvpn.NO_INLINE_SELECTION";  	private FileSelectionFragment mFSFragment;  	private InlineFileTab mInlineFragment; @@ -26,7 +27,8 @@ public class FileSelect extends Activity {  	private Tab inlineFileTab;  	private Tab fileExplorerTab;  	private boolean mNoInline; - +	 +		  	public void onCreate(Bundle savedInstanceState)  	{  		super.onCreate(savedInstanceState);  @@ -36,6 +38,13 @@ public class FileSelect extends Activity {  		if(mData==null)  			mData="/sdcard"; +		String title = getIntent().getStringExtra(WINDOW_TITLE); +		int titleId = getIntent().getIntExtra(WINDOW_TITLE, 0); +		if(titleId!=0)  +			title =getString(titleId); +		if(title!=null) +			setTitle(title); +		  		mNoInline = getIntent().getBooleanExtra(NO_INLINE_SELECTION, false);  		ActionBar bar = getActionBar(); diff --git a/src/de/blinkt/openvpn/FileSelectLayout.java b/src/de/blinkt/openvpn/FileSelectLayout.java index 0be099af..1a60d135 100644 --- a/src/de/blinkt/openvpn/FileSelectLayout.java +++ b/src/de/blinkt/openvpn/FileSelectLayout.java @@ -19,6 +19,8 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {  	private Fragment mFragment;  	private int mTaskId;  	private Button mSelectButton; +	private boolean mNoInline; +	private String mTitle;  	public FileSelectLayout( Context context,AttributeSet attrset) {  		super(context,attrset); @@ -26,10 +28,10 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {  		TypedArray ta = context.obtainStyledAttributes(attrset,R.styleable.FileSelectLayout); -		String title = ta.getString(R.styleable.FileSelectLayout_title); +		mTitle = ta.getString(R.styleable.FileSelectLayout_title);  		TextView tview = (TextView) findViewById(R.id.file_title); -		tview.setText(title); +		tview.setText(mTitle);  		mDataView = (TextView) findViewById(R.id.file_selected_item);  		mSelectButton = (Button) findViewById(R.id.file_select_button); @@ -46,7 +48,9 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {  	public void getCertificateFileDialog() {  		Intent startFC = new Intent(getContext(),FileSelect.class);  		startFC.putExtra(FileSelect.START_DATA, mData); -		 +		startFC.putExtra(FileSelect.WINDOW_TITLE,mTitle); +		if(mNoInline) +			startFC.putExtra(FileSelect.NO_INLINE_SELECTION, true);  		mFragment.startActivityForResult(startFC,mTaskId);  	} @@ -73,5 +77,9 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {  		}  	} +	public void setNoline() { +		mNoInline=true; +	} +  } diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java index fb60d84c..8a884fcc 100644 --- a/src/de/blinkt/openvpn/OpenVpnService.java +++ b/src/de/blinkt/openvpn/OpenVpnService.java @@ -20,6 +20,7 @@ import java.io.IOException;  import java.util.List;  import java.util.Vector; +  import android.app.ActivityManager;  import android.app.ActivityManager.RunningAppProcessInfo;  import android.app.PendingIntent; @@ -54,61 +55,6 @@ public class OpenVpnService extends VpnService implements Handler.Callback { -	class CIDRIP{ -		String mIp; -		int len; -		public CIDRIP(String ip, String mask){ -			mIp=ip; -			String[] ipt = mask.split("\\."); -			long netmask=0; - -			netmask += Long.parseLong(ipt[0])<< 24; -			netmask += Integer.parseInt(ipt[1])<< 16; -			netmask += Integer.parseInt(ipt[2])<< 8; -			netmask += Integer.parseInt(ipt[3]); - -			// Add 33. bit to ensure the loop terminates -			netmask += 1l << 32; - -			int lenZeros = 0; -			while((netmask & 0x1) == 0) { -				lenZeros++; -				netmask = netmask >> 1; -			} -			// Check if rest of netmask is only 1s -			if(netmask != (0x1ffffffffl >> lenZeros)) { -				// Asume no CIDR, set /32 -				len=32; -			} else { -				len =32 -lenZeros;  -			} - -		} -		@Override -		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() {  		OpenVpnManagementThread.stopOpenVPN(); diff --git a/src/de/blinkt/openvpn/Settings_Basic.java b/src/de/blinkt/openvpn/Settings_Basic.java index 7586b27d..00663173 100644 --- a/src/de/blinkt/openvpn/Settings_Basic.java +++ b/src/de/blinkt/openvpn/Settings_Basic.java @@ -124,6 +124,7 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On  		addFileSelectLayout(mClientCert);  		addFileSelectLayout(mClientKey);  		addFileSelectLayout(mpkcs12); +		mpkcs12.setNoline();  		loadPreferences(); @@ -285,6 +286,7 @@ public class Settings_Basic extends Fragment implements View.OnClickListener, On  	@Override  	public void onSaveInstanceState(Bundle outState) {  		super.onSaveInstanceState(outState); +		savePreferences();  		outState.putString(getActivity().getPackageName() + "profileUUID", mProfile.getUUID().toString());  	} diff --git a/src/de/blinkt/openvpn/Settings_IP.java b/src/de/blinkt/openvpn/Settings_IP.java index de625d22..52dcc5dc 100644 --- a/src/de/blinkt/openvpn/Settings_IP.java +++ b/src/de/blinkt/openvpn/Settings_IP.java @@ -20,6 +20,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  		private CheckBoxPreference mUseDefaultRoute;  		private VpnProfile mProfile;  		private CheckBoxPreference mRouteNoPull; +		private CheckBoxPreference mNobind;  		@Override  		public void onCreate(Bundle savedInstanceState) { @@ -47,6 +48,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mCustomRoutes = (EditTextPreference) findPreference("customRoutes");  			mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute");  			mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); +			mNobind = (CheckBoxPreference) findPreference("nobind");  			mIPv4.setOnPreferenceChangeListener(this);  			mIPv6.setOnPreferenceChangeListener(this); @@ -56,10 +58,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mOverrideDNS.setOnPreferenceChangeListener(this);  			mSearchdomain.setOnPreferenceChangeListener(this);  			mCustomRoutes.setOnPreferenceChangeListener(this); -			 -			 - -			 +						  			loadSettings();  		} @@ -109,6 +108,7 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang  			mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked();  			mProfile.mCustomRoutes = mCustomRoutes.getText();  			mProfile.mRoutenopull = mRouteNoPull.isChecked(); +			mProfile.mNobind = mNobind.isChecked();  		} diff --git a/src/de/blinkt/openvpn/VPNProfileList.java b/src/de/blinkt/openvpn/VPNProfileList.java index a14c835e..beadf53d 100644 --- a/src/de/blinkt/openvpn/VPNProfileList.java +++ b/src/de/blinkt/openvpn/VPNProfileList.java @@ -1,6 +1,5 @@  package de.blinkt.openvpn; -import de.blinkt.openvpn.FileSelect.MyTabsListener;  import android.app.Activity;  import android.app.AlertDialog;  import android.app.ListFragment; @@ -95,6 +94,10 @@ public class VPNProfileList extends ListFragment {  	public void onActivityCreated(Bundle savedInstanceState) {  		super.onActivityCreated(savedInstanceState); +		setListAdapter(); +	} + +	private void setListAdapter() {  		mArrayadapter = new VPNArrayAdapter(getActivity(),R.layout.vpn_list_item,R.id.vpn_item_title);  		mArrayadapter.addAll(getPM().getProfiles()); @@ -112,8 +115,8 @@ public class VPNProfileList extends ListFragment {  				| MenuItem.SHOW_AS_ACTION_WITH_TEXT);  		menu.add(0, MENU_IMPORT_PROFILE, 0, R.string.menu_import) -		.setIcon(android.R.drawable.ic_menu_myplaces) -		.setAlphabeticShortcut('a') +		.setIcon(R.drawable.ic_menu_archive) +		.setAlphabeticShortcut('i')  		.setTitleCondensed(getActivity().getString(R.string.menu_import_short))  		.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM  				| MenuItem.SHOW_AS_ACTION_WITH_TEXT ); @@ -129,6 +132,7 @@ public class VPNProfileList extends ListFragment {  		} else if (itemId == MENU_IMPORT_PROFILE) {  			Intent intent = new Intent(getActivity(),FileSelect.class);  			intent.putExtra(FileSelect.NO_INLINE_SELECTION, true); +			intent.putExtra(FileSelect.WINDOW_TITLE, R.string.import_configuration_file);  			startActivityForResult(intent, SELECT_PROFILE);  			return true;  		} else { @@ -185,12 +189,7 @@ public class VPNProfileList extends ListFragment {  			}); -			dialog.setNegativeButton(android.R.string.cancel, -					new DialogInterface.OnClickListener() { -				@Override -				public void onClick(DialogInterface dialog, int which) { -				} -			}); +			dialog.setNegativeButton(android.R.string.cancel, null);  			dialog.create().show();  		} @@ -224,8 +223,9 @@ public class VPNProfileList extends ListFragment {  			VpnProfile profile = ProfileManager.get(configuredVPN);  			getPM().saveProfile(getActivity(), profile); -			// Name could be modified - +			// Name could be modified, reset List adapter +			setListAdapter(); +			  		} else if(requestCode== SELECT_PROFILE) {  			String filedata = data.getStringExtra(FileSelect.RESULT_DATA);  			Intent startImport = new Intent(getActivity(),ConfigConverter.class); diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index b7297e89..aed9ca03 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -37,14 +37,10 @@ public class VpnProfile implements  Serializable{  	public static final int TYPE_USERPASS_CERTIFICATES = 5;  	public static final int TYPE_USERPASS_PKCS12 = 6;  	public static final int TYPE_USERPASS_KEYSTORE = 7; - +	  	// Don't change this, not all parts of the program use this constant  	public static final String EXTRA_PROFILEUUID = "de.blinkt.openvpn.profileUUID"; - - - - - +	public static final String INLINE_TAG = "[[INLINE]]";  	private static final String OVPNCONFIGFILE = "android.conf";  	protected transient String mTransientPW=null; @@ -52,6 +48,8 @@ public class VpnProfile implements  Serializable{  	private static transient String mTempPKCS12Password; +	public static String DEFAULT_DNS1="131.234.137.23"; +	public static String DEFAULT_DNS2="131.234.137.24";  	// Public attributes, since I got mad with getter/setter  	// set members to default values @@ -71,8 +69,8 @@ public class VpnProfile implements  Serializable{  	public String mPKCS12Password;  	public boolean mUseTLSAuth = false;  	public String mServerName = "openvpn.blinkt.de" ; -	public String mDNS1="131.234.137.23"; -	public String mDNS2="131.234.137.24"; +	public String mDNS1=DEFAULT_DNS1; +	public String mDNS2=DEFAULT_DNS2;  	public String mIPv4Address;  	public String mIPv6Address;  	public boolean mOverrideDNS=false; @@ -92,9 +90,8 @@ public class VpnProfile implements  Serializable{  	public String mCustomConfigOptions="";  	public String mVerb="1";  	public String mCipher=""; -	public static final String INLINE_TAG = "[[INLINE]]"; +	public boolean mNobind=false; -	  	public void clearDefaults() {  		mServerName="unkown"; @@ -266,6 +263,9 @@ public class VpnProfile implements  Serializable{  				cfg+="dhcp-option DNS " + mDNS2 + "\n";  		} +		 +		if(mNobind) +			cfg+="nobind\n"; @@ -307,7 +307,9 @@ public class VpnProfile implements  Serializable{  	//! Put inline data inline and other data as normal escaped filename  	private String insertFileData(String cfgentry, String filedata) { -		if(filedata.startsWith(VpnProfile.INLINE_TAG)){ +		if(filedata==null) { +			return String.format("%s %s\n",cfgentry,"missing"); +		}else if(filedata.startsWith(VpnProfile.INLINE_TAG)){  			String datawoheader = filedata.substring(VpnProfile.INLINE_TAG.length());  			return String.format("<%s>\n%s\n</%s>\n",cfgentry,datawoheader,cfgentry);  		} else { | 
