From 5a65e0c5e80d147909acffa14b04d3c99d48de1a Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Sat, 12 May 2012 21:18:37 +0200 Subject: Almost working configuration import --- src/de/blinkt/openvpn/ConfigConverter.java | 195 ++++++++++++++++++ src/de/blinkt/openvpn/ConfigParser.java | 227 ++++++++++++++++++--- src/de/blinkt/openvpn/FileSelect.java | 28 ++- src/de/blinkt/openvpn/FileSelectLayout.java | 4 +- src/de/blinkt/openvpn/FileSelectionFragment.java | 10 +- src/de/blinkt/openvpn/Settings_Authentication.java | 2 +- src/de/blinkt/openvpn/VPNProfileList.java | 41 +++- src/de/blinkt/openvpn/VpnProfile.java | 19 +- 8 files changed, 481 insertions(+), 45 deletions(-) create mode 100644 src/de/blinkt/openvpn/ConfigConverter.java (limited to 'src') diff --git a/src/de/blinkt/openvpn/ConfigConverter.java b/src/de/blinkt/openvpn/ConfigConverter.java new file mode 100644 index 00000000..1973e0ac --- /dev/null +++ b/src/de/blinkt/openvpn/ConfigConverter.java @@ -0,0 +1,195 @@ +package de.blinkt.openvpn; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import android.app.Activity; +import android.app.ListActivity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.ArrayAdapter; +import android.widget.Toast; +import de.blinkt.openvpn.ConfigParser.ConfigParseError; + +public class ConfigConverter extends ListActivity { + + public static final String IMPORT_PROFILE = "de.blinkt.openvpn.IMPORT_PROFILE"; + + private VpnProfile mResult; + private ArrayAdapter mArrayAdapter; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Toast.makeText(this, "Got called!", Toast.LENGTH_LONG).show(); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId()==R.id.cancel){ + setResult(Activity.RESULT_CANCELED); + finish(); + } else if(item.getItemId()==R.id.ok) { + if(mResult==null) { + log("Importing the config had error, cannot save it"); + } + Intent result = new Intent(); + ProfileManager vpl = ProfileManager.getInstance(this); + vpl.addProfile(mResult); + result.putExtra(VpnProfile.EXTRA_PROFILEUUID,mResult.getUUID().toString()); + setResult(Activity.RESULT_OK, result); + finish(); + } + + return super.onOptionsItemSelected(item); + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.import_menu, menu); + return true; + } + + + private String embedFile(String filename) + { + if(filename == null || filename.equals("")) + return null; + // 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("/"); + File[] dirlist = {root, sdcard}; + String[] fileparts = filename.split("/"); + for(File rootdir:dirlist){ + String suffix=""; + for(int i=fileparts.length-1; i >=0;i--) { + if(i==fileparts.length-1) + 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); + int len = fis.read(buf); + while( len > 0){ + filedata += new String(buf,0,len); + len = fis.read(buf); + } + return filedata; + } catch (FileNotFoundException e) { + log(e.getLocalizedMessage()); + } 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(); + + mArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1); + getListView().setAdapter(mArrayAdapter); + final android.content.Intent intent = getIntent (); + + if (intent != null) + { + final android.net.Uri data = intent.getData (); + if (data != null) + { + log(R.string.importing_config,data.toString()); + try { + InputStream is = getContentResolver().openInputStream(data); + doImport(is); + } catch (FileNotFoundException e) { + log(R.string.import_content_resolve_error); + } + } + } + + return; + } + + private void log(String logmessage) { + mArrayAdapter.add(logmessage); + } + + private void doImport(InputStream is) { + ConfigParser cp = new ConfigParser(); + try { + cp.parseConfig(is); + VpnProfile vp = cp.convertProfile(); + mResult = vp; + embedFiles(); + displayWarnings(); + log(R.string.import_done); + return; + + } catch (IOException e) { + log(R.string.error_reading_config_file); + log(e.getLocalizedMessage()); + } catch (ConfigParseError e) { + log(R.string.error_reading_config_file); + log(e.getLocalizedMessage()); + } + mResult=null; + + } + + private void displayWarnings() { + if(mResult.mUseCustomConfig) { + log(R.string.import_warning_custom_options); + log(mResult.mCustomConfigOptions); + } + + if(mResult.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) { + log(R.string.import_pkcs12_to_keystore); + } + + } + + + private void log(int ressourceId, Object... formatArgs) { + log(getString(ressourceId,formatArgs)); + } +} diff --git a/src/de/blinkt/openvpn/ConfigParser.java b/src/de/blinkt/openvpn/ConfigParser.java index 97ca6396..8fde12b8 100644 --- a/src/de/blinkt/openvpn/ConfigParser.java +++ b/src/de/blinkt/openvpn/ConfigParser.java @@ -1,9 +1,11 @@ package de.blinkt.openvpn; import java.io.BufferedReader; -import java.io.FileReader; 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 @@ -16,12 +18,13 @@ public class ConfigParser { private HashMap> options = new HashMap>(); - private void parseConfig(String filename) throws IOException, ConfigParseError { + public void parseConfig(InputStream inputStream) throws IOException, ConfigParseError { - FileReader fr = new FileReader(filename); + InputStreamReader fr = new InputStreamReader(inputStream); BufferedReader br =new BufferedReader(fr); + @SuppressWarnings("unused") int lineno=0; while (true){ @@ -29,8 +32,6 @@ public class ConfigParser { if(line==null) break; lineno++; - System.out.print("LINE:"); - System.out.println(line); Vector args = parseline(line); if(args.size() ==0) continue; @@ -51,7 +52,7 @@ public class ConfigParser { // CHeck for if(arg0.startsWith("<") && arg0.endsWith(">")) { String argname = arg0.substring(1, arg0.length()-1); - String inlinefile = ""; + String inlinefile = VpnProfile.INLINE_TAG; String endtag = String.format("",argname); do { @@ -192,37 +193,217 @@ public class ConfigParser { return parameters; } - void convertProfile() throws ConfigParseError{ - VpnProfile newprofile = new VpnProfile("converted Profile"); + + final String[] unsupportedOptions = { "config", + "connection", + "proto-force", + "remote-random", + "tls-server" + + }; + + // Ignore all scripts + // in most cases these won't work and user who wish to execute scripts will + // figure out themselves + final String[] ignoreOptions = { "tls-client", + "askpass", + "auth-nocache", + "up", + "down", + "route-up", + "ipchange", + "route-up", + "auth-user-pass-verify" + }; + // Missing + // proto tcp-client|udp + + VpnProfile convertProfile() throws ConfigParseError{ + VpnProfile np = new VpnProfile("converted Profile"); // Pull, client, tls-client - + np.clearDefaults(); + if(options.containsKey("client") || options.containsKey("pull")) { - newprofile.mUsePull=true; + np.mUsePull=true; options.remove("pull"); options.remove("client"); } - - if(options.containsKey("secret")){ - newprofile.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; - options.remove("secret"); + + Vector secret = getOption("secret", 1, 2); + if(secret!=null) + { + np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; + np.mUseTLSAuth=true; + np.mTLSAuthFilename=secret.get(1); + if(secret.size()==3) + np.mTLSAuthDirection=secret.get(2); } - + + Vector tlsauth = getOption("tls-auth", 1, 2); + if(tlsauth!=null) + { + np.mUseTLSAuth=true; + np.mTLSAuthFilename=tlsauth.get(1); + if(tlsauth.size()==3) + np.mTLSAuthDirection=tlsauth.get(2); + } + + Vector direction = getOption("key-direction", 1, 1); + if(direction!=null) + np.mTLSAuthDirection=direction.get(1); + if(options.containsKey("redirect-gateway")) { options.remove("redirect-gateway"); - newprofile.mUseDefaultRoute=true; + np.mUseDefaultRoute=true; } else { - newprofile.mUseDefaultRoute=true; + np.mUseDefaultRoute=true; } - - Vector mode = options.get("mode"); + + Vector dev =getOption("dev",1,1); + Vector devtype =getOption("dev-type",1,1); + + if( (devtype !=null && devtype.get(1).equals("tun")) || + (dev!=null && dev.get(1).startsWith("tun")) || + (devtype ==null && dev == null) ) { + //everything okay + } else { + throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail"); + } + + + + Vector mode =getOption("mode",1,1); if (mode != null){ - options.remove("mode"); - if(mode.size() != 2) - throw new ConfigParseError("--mode has more than one parameter"); if(!mode.get(1).equals("p2p")) - throw new ConfigParseError("Invalid mode for --mode specified"); + throw new ConfigParseError("Invalid mode for --mode specified, need p2p"); + } + + // Parse remote config + Vector remote = getOption("remote",1,3); + if(remote != null){ + switch (remote.size()) { + case 4: + String proto = remote.get(3); + if(proto.equals("udp")) + np.mUseUdp=true; + else if (proto.equals("tcp")) + np.mUseUdp=false; + else + throw new ConfigParseError("remote protocol must be tcp or udp"); + case 3: + np.mServerPort = remote.get(2); + case 2: + np.mServerName = remote.get(1); + } } + Vector 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")) + np.mUseUdp=false; + else + throw new ConfigParseError("Unsupported option to --proto " + proto.get(1)); + + } + + Vector dhcpoption = getOption("dhcp-options", 1, 3); + if(dhcpoption!=null) { + String type=dhcpoption.get(1); + + } + + if(getOption("remote-random-hostname", 0, 0)!=null) + np.mUseRandomHostname=true; + + if(getOption("float", 0, 0)!=null) + np.mUseFloat=true; + + if(getOption("comp-lzo", 0, 1)!=null) + np.mUseLzo=true; + + Vector cipher = getOption("cipher", 1, 1); + if(cipher!=null) + np.mCipher= cipher.get(1); + + Vector ca = getOption("ca",1,1); + if(ca!=null){ + np.mCaFilename = ca.get(1); + } + + Vector cert = getOption("cert",1,1); + if(cert!=null){ + np.mClientCertFilename = cert.get(1); + np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES; + } + Vector key= getOption("key",1,1); + if(key!=null) + np.mClientKeyFilename=key.get(1); + + Vector pkcs12 = getOption("pkcs12",1,1); + if(pkcs12!=null) { + np.mPKCS12Filename = pkcs12.get(1); + np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; + } + + Vector tlsremote = getOption("tls-remote",1,1); + if(tlsremote!=null){ + np.mRemoteCN = tlsremote.get(1); + np.mCheckRemoteCN=true; + } + + Vector verb = getOption("verb",1,1); + if(verb!=null){ + np.mVerb=verb.get(1); + } + + // Check the other options + + for(String option:unsupportedOptions) + if(options.containsKey(option)) + throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option)); + + for(String option:ignoreOptions) + // removing an item which is not in the map is no error + options.remove(option); + + if(options.size()> 0) { + String custom = "# These Options were found in the config file but not parsed:\n"; + for(Entry> option:options.entrySet()) { + for (String arg : option.getValue()) { + 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=""; + } + } + + private Vector getOption(String option, int minarg, int maxarg) throws ConfigParseError { + Vector 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); + } + options.remove(option); + return args; } } diff --git a/src/de/blinkt/openvpn/FileSelect.java b/src/de/blinkt/openvpn/FileSelect.java index 3cc060c6..12a3ae01 100644 --- a/src/de/blinkt/openvpn/FileSelect.java +++ b/src/de/blinkt/openvpn/FileSelect.java @@ -13,19 +13,19 @@ import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Fragment; import android.app.FragmentTransaction; -import android.content.Context; import android.content.Intent; 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 INLINE_TAG = "[[INLINE]]"; + public static final String NO_INLINE_SELECTION = "de.blinkt.openvpn.NO_INLINE_SELECTION"; private FileSelectionFragment mFSFragment; private InlineFileTab mInlineFragment; private String mData; private Tab inlineFileTab; private Tab fileExplorerTab; + private boolean mNoInline; public void onCreate(Bundle savedInstanceState) { @@ -33,6 +33,10 @@ public class FileSelect extends Activity { setContentView(R.layout.file_dialog); mData = getIntent().getStringExtra(START_DATA); + if(mData==null) + mData="/sdcard"; + + mNoInline = getIntent().getBooleanExtra(NO_INLINE_SELECTION, false); ActionBar bar = getActionBar(); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); @@ -40,13 +44,15 @@ public class FileSelect extends Activity { inlineFileTab = bar.newTab().setText(R.string.inline_file_tab); mFSFragment = new FileSelectionFragment(); - mInlineFragment = new InlineFileTab(); + mFSFragment.setNoInLine(); fileExplorerTab.setTabListener(new MyTabsListener(this, mFSFragment)); - inlineFileTab.setTabListener(new MyTabsListener(this, mInlineFragment)); - bar.addTab(fileExplorerTab); - bar.addTab(inlineFileTab); + if(!mNoInline) { + mInlineFragment = new InlineFileTab(); + inlineFileTab.setTabListener(new MyTabsListener(this, mInlineFragment)); + bar.addTab(inlineFileTab); + } } @@ -88,7 +94,7 @@ public class FileSelect extends Activity { Exception fe = null; try { FileInputStream fis = new FileInputStream(ifile); - String data =INLINE_TAG; + String data =VpnProfile.INLINE_TAG; byte buf[] =new byte[16384]; int len=fis.read(buf); @@ -116,21 +122,21 @@ public class FileSelect extends Activity { public void setFile(String path) { Intent intent = new Intent(); - intent.putExtra(RESULT_DATA, mData); + intent.putExtra(RESULT_DATA, path); setResult(Activity.RESULT_OK,intent); finish(); } public String getSelectPath() { - if(mData.startsWith(INLINE_TAG)) + if(mData.startsWith(VpnProfile.INLINE_TAG)) return mData; else return "/mnt/sdcard"; } public CharSequence getInlineData() { - if(mData.startsWith(INLINE_TAG)) - return mData.substring(INLINE_TAG.length()); + if(mData.startsWith(VpnProfile.INLINE_TAG)) + return mData.substring(VpnProfile.INLINE_TAG.length()); else return ""; } diff --git a/src/de/blinkt/openvpn/FileSelectLayout.java b/src/de/blinkt/openvpn/FileSelectLayout.java index bbaf7778..0be099af 100644 --- a/src/de/blinkt/openvpn/FileSelectLayout.java +++ b/src/de/blinkt/openvpn/FileSelectLayout.java @@ -57,7 +57,9 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener { public void setData(String data) { mData = data; - if(mData.startsWith(FileSelect.INLINE_TAG)) + if(data==null) + mDataView.setText(mFragment.getString(R.string.no_data)); + else if(mData.startsWith(VpnProfile.INLINE_TAG)) mDataView.setText(R.string.inline_file_data); else mDataView.setText(data); diff --git a/src/de/blinkt/openvpn/FileSelectionFragment.java b/src/de/blinkt/openvpn/FileSelectionFragment.java index 31390280..41c7a1eb 100644 --- a/src/de/blinkt/openvpn/FileSelectionFragment.java +++ b/src/de/blinkt/openvpn/FileSelectionFragment.java @@ -51,6 +51,7 @@ public class FileSelectionFragment extends ListFragment { private HashMap lastPositions = new HashMap(); private String mStartPath; private Button importFile; + private boolean mHideImport=false; @Override @@ -73,6 +74,7 @@ public class FileSelectionFragment extends ListFragment { } }); + importFile = (Button) v.findViewById(R.id.importfile); importFile.setEnabled(false); importFile.setOnClickListener(new OnClickListener() { @@ -83,7 +85,9 @@ public class FileSelectionFragment extends ListFragment { } }); - + if(mHideImport== true) { + importFile.setVisibility(View.GONE); + } return v; @@ -241,4 +245,8 @@ public class FileSelectionFragment extends ListFragment { } } + public void setNoInLine() { + mHideImport=true; + } + } diff --git a/src/de/blinkt/openvpn/Settings_Authentication.java b/src/de/blinkt/openvpn/Settings_Authentication.java index 5849923d..e8740b5d 100644 --- a/src/de/blinkt/openvpn/Settings_Authentication.java +++ b/src/de/blinkt/openvpn/Settings_Authentication.java @@ -131,7 +131,7 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre private void setTlsAuthSummary(String result) { if(result==null) result = getString(R.string.no_certificate); - if(result.startsWith(FileSelect.INLINE_TAG)) + if(result.startsWith(VpnProfile.INLINE_TAG)) mTLSAuthFile.setSummary(R.string.inline_file_data); else mTLSAuthFile.setSummary(result); diff --git a/src/de/blinkt/openvpn/VPNProfileList.java b/src/de/blinkt/openvpn/VPNProfileList.java index a578251c..a14c835e 100644 --- a/src/de/blinkt/openvpn/VPNProfileList.java +++ b/src/de/blinkt/openvpn/VPNProfileList.java @@ -1,11 +1,13 @@ package de.blinkt.openvpn; +import de.blinkt.openvpn.FileSelect.MyTabsListener; import android.app.Activity; import android.app.AlertDialog; import android.app.ListFragment; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.view.ActionMode; import android.view.Menu; @@ -56,11 +58,8 @@ public class VPNProfileList extends ListFragment { } }); - return v; } - - } @@ -68,6 +67,13 @@ public class VPNProfileList extends ListFragment { private static final int MENU_ADD_PROFILE = Menu.FIRST; private static final int START_VPN_CONFIG = 92; + private static final int SELECT_PROFILE = 43; + private static final int IMPORT_PROFILE = 231; + + private static final int MENU_IMPORT_PROFILE = Menu.FIRST +1; + + + private ArrayAdapter mArrayadapter; @@ -104,6 +110,13 @@ public class VPNProfileList extends ListFragment { .setAlphabeticShortcut('a') .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | 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') + .setTitleCondensed(getActivity().getString(R.string.menu_import_short)) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM + | MenuItem.SHOW_AS_ACTION_WITH_TEXT ); } @@ -113,6 +126,11 @@ public class VPNProfileList extends ListFragment { if (itemId == MENU_ADD_PROFILE) { onAddProfileClicked(); return true; + } else if (itemId == MENU_IMPORT_PROFILE) { + Intent intent = new Intent(getActivity(),FileSelect.class); + intent.putExtra(FileSelect.NO_INLINE_SELECTION, true); + startActivityForResult(intent, SELECT_PROFILE); + return true; } else { return super.onOptionsItemSelected(item); } @@ -198,13 +216,26 @@ public class VPNProfileList extends ListFragment { @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == START_VPN_CONFIG && resultCode == Activity.RESULT_OK) { - String configuredVPN = data.getStringExtra(getActivity().getPackageName() + ".profileUUID"); + if(resultCode != Activity.RESULT_OK) + return; + + if (requestCode == START_VPN_CONFIG) { + String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); VpnProfile profile = ProfileManager.get(configuredVPN); getPM().saveProfile(getActivity(), profile); // Name could be modified + } else if(requestCode== SELECT_PROFILE) { + String filedata = data.getStringExtra(FileSelect.RESULT_DATA); + Intent startImport = new Intent(getActivity(),ConfigConverter.class); + startImport.setAction(ConfigConverter.IMPORT_PROFILE); + Uri uri = new Uri.Builder().path(filedata).scheme("file").build(); + startImport.setData(uri); + startActivityForResult(startImport, IMPORT_PROFILE); + } else if(requestCode == IMPORT_PROFILE) { + String profileUUID = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); + mArrayadapter.add(ProfileManager.get(profileUUID)); } } diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 639619ff..b7297e89 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -38,6 +38,8 @@ public class VpnProfile implements Serializable{ 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"; @@ -90,6 +92,17 @@ public class VpnProfile implements Serializable{ public String mCustomConfigOptions=""; public String mVerb="1"; public String mCipher=""; + public static final String INLINE_TAG = "[[INLINE]]"; + + + + public void clearDefaults() { + mServerName="unkown"; + mUsePull=false; + mUseLzo=false; + mUseDefaultRoute=false; + mExpectTLSCert=false; + } public static String openVpnEscape(String unescaped) { @@ -294,11 +307,11 @@ 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(FileSelect.INLINE_TAG)){ - String datawoheader = filedata.substring(FileSelect.INLINE_TAG.length()); + if(filedata.startsWith(VpnProfile.INLINE_TAG)){ + String datawoheader = filedata.substring(VpnProfile.INLINE_TAG.length()); return String.format("<%s>\n%s\n\n",cfgentry,datawoheader,cfgentry); } else { - return String.format("%s %s",cfgentry,openVpnEscape(filedata)); + return String.format("%s %s\n",cfgentry,openVpnEscape(filedata)); } } -- cgit v1.2.3