summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2014-02-11 23:36:48 +0100
committerArne Schwabe <arne@rfc2549.org>2014-02-11 23:36:48 +0100
commitc373af42b1a75b0f23c2f0edbf196dfbb1ef0a0e (patch)
tree1a6957889611f16974de15418ef0257e9f1ba90d
parent3044e321058be2a7b860a7c10c8efa49afabfcb2 (diff)
Rework and fix config import
-rwxr-xr-xres/values/strings.xml1
-rw-r--r--src/de/blinkt/openvpn/VpnProfile.java34
-rw-r--r--src/de/blinkt/openvpn/activities/ConfigConverter.java749
-rw-r--r--src/de/blinkt/openvpn/activities/FileSelect.java6
-rw-r--r--src/de/blinkt/openvpn/core/ConfigParser.java28
-rw-r--r--src/de/blinkt/openvpn/core/X509Utils.java6
-rw-r--r--src/de/blinkt/openvpn/fragments/Settings_Authentication.java7
-rw-r--r--src/de/blinkt/openvpn/fragments/Utils.java67
-rw-r--r--src/de/blinkt/openvpn/views/FileSelectLayout.java10
9 files changed, 503 insertions, 405 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d96f51a0..f4f7f6eb 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -314,4 +314,5 @@
<string name="blocklocal_summary">Networks directly connected to the local interfaces will not be routed over the VPN. Unchecking this option will redirect all traffic indented for local networks to VPN.</string>
<string name="blocklocal_title">Bypass VPN for local networks</string>
<string name="userpw_file">Username/Password file</string>
+ <string name="imported_from_file">[Imported from: %s]</string>
</resources>
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
index d18fc72a..1ec34b51 100644
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ b/src/de/blinkt/openvpn/VpnProfile.java
@@ -47,6 +47,7 @@ public class VpnProfile implements Serializable {
// 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]]";
+ public static final String DISPLAYNAME_TAG = "[[NAME]]";
public static final String MINIVPN = "miniopenvpn";
private static final long serialVersionUID = 7085688938959334563L;
private static final String OVPNCONFIGFILE = "android.conf";
@@ -462,9 +463,9 @@ public class VpnProfile implements Serializable {
if (filedata == null) {
// TODO: generate good error
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(Locale.ENGLISH, "<%s>\n%s\n</%s>\n", cfgentry, datawoheader, cfgentry);
+ } else if (isEmbedded(filedata)) {
+ String dataWithOutHeader = getEmbeddedContent(filedata);
+ return String.format(Locale.ENGLISH, "<%s>\n%s\n</%s>\n", cfgentry, dataWithOutHeader, cfgentry);
} else {
return String.format(Locale.ENGLISH, "%s %s\n", cfgentry, openVpnEscape(filedata));
}
@@ -583,6 +584,31 @@ public class VpnProfile implements Serializable {
return getKeyStoreCertificates(context, 5);
}
+ public static String getDisplayName(String embeddedFile) {
+ int start = DISPLAYNAME_TAG.length();
+ int end = embeddedFile.indexOf(INLINE_TAG);
+ return embeddedFile.substring(start,end);
+ }
+
+ public static String getEmbeddedContent(String data)
+ {
+ if (!data.contains(INLINE_TAG))
+ return data;
+
+ int start = data.indexOf(INLINE_TAG) + INLINE_TAG.length();
+ return data.substring(start);
+ }
+
+ public static boolean isEmbedded(String data) {
+ if (data==null)
+ return false;
+ if(data.startsWith(INLINE_TAG) || data.startsWith(DISPLAYNAME_TAG))
+ return true;
+ else
+ return false;
+ }
+
+
class NoCertReturnedException extends Exception {
public NoCertReturnedException (String msg) {
super(msg);
@@ -760,7 +786,7 @@ public class VpnProfile implements Serializable {
return false;
String data = "";
- if (mClientKeyFilename.startsWith(INLINE_TAG))
+ if (isEmbedded(mClientKeyFilename))
data = mClientKeyFilename;
else {
char[] buf = new char[2048];
diff --git a/src/de/blinkt/openvpn/activities/ConfigConverter.java b/src/de/blinkt/openvpn/activities/ConfigConverter.java
index 50253915..e999fe9f 100644
--- a/src/de/blinkt/openvpn/activities/ConfigConverter.java
+++ b/src/de/blinkt/openvpn/activities/ConfigConverter.java
@@ -1,24 +1,24 @@
package de.blinkt.openvpn.activities;
-import java.io.*;
-import java.util.*;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
+import android.database.Cursor;
import android.os.Bundle;
import android.os.Environment;
+import android.provider.OpenableColumns;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
+import android.text.TextUtils;
import android.util.Base64;
+import android.util.Log;
import android.view.*;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
-
import android.widget.LinearLayout;
import de.blinkt.openvpn.R;
import de.blinkt.openvpn.VpnProfile;
@@ -29,71 +29,75 @@ import de.blinkt.openvpn.fragments.Utils;
import de.blinkt.openvpn.views.FileSelectLayout;
import junit.framework.Assert;
-import static de.blinkt.openvpn.views.FileSelectLayout.*;
+import java.io.*;
+import java.util.*;
+
+import static de.blinkt.openvpn.views.FileSelectLayout.FileSelectCallback;
public class ConfigConverter extends ListActivity implements FileSelectCallback {
- public static final String IMPORT_PROFILE = "de.blinkt.openvpn.IMPORT_PROFILE";
+ public static final String IMPORT_PROFILE = "de.blinkt.openvpn.IMPORT_PROFILE";
private static final int RESULT_INSTALLPKCS12 = 7;
private static final int CHOOSE_FILE_OFFSET = 1000;
public static final String VPNPROFILE = "vpnProfile";
private VpnProfile mResult;
- private transient ArrayAdapter<String> mArrayAdapter;
+ private transient ArrayAdapter<String> mArrayAdapter;
- private transient List<String> mPathsegments;
+ private transient List<String> mPathsegments;
- private String mAliasName=null;
+ private String mAliasName = null;
private Map<Utils.FileType, FileSelectLayout> fileSelectMap = new HashMap<Utils.FileType, FileSelectLayout>();
+ private String mEmbeddedPwFile;
- @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");
- return true;
- }
+ @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");
+ return true;
+ }
- Intent in = installPKCS12();
+ Intent in = installPKCS12();
- if(in != null)
- startActivityForResult(in, RESULT_INSTALLPKCS12);
- else
- saveProfile();
+ if (in != null)
+ startActivityForResult(in, RESULT_INSTALLPKCS12);
+ else
+ saveProfile();
- return true;
- }
+ return true;
+ }
- return super.onOptionsItemSelected(item);
+ return super.onOptionsItemSelected(item);
- }
+ }
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- if(mResult!=null)
- outState.putSerializable(VPNPROFILE,mResult);
+ if (mResult != null)
+ outState.putSerializable(VPNPROFILE, mResult);
outState.putString("mAliasName", mAliasName);
String[] logentries = new String[mArrayAdapter.getCount()];
- for(int i =0; i < mArrayAdapter.getCount();i++){
+ for (int i = 0; i < mArrayAdapter.getCount(); i++) {
logentries[i] = mArrayAdapter.getItem(i);
}
outState.putStringArray("logentries", logentries);
int[] fileselects = new int[fileSelectMap.size()];
- int k=0;
- for (Utils.FileType key :fileSelectMap.keySet()){
- fileselects[k]=key.getValue();
+ int k = 0;
+ for (Utils.FileType key : fileSelectMap.keySet()) {
+ fileselects[k] = key.getValue();
k++;
}
- outState.putIntArray("fileselects",fileselects);
-
+ outState.putIntArray("fileselects", fileselects);
+ outState.putString("pwfile",mEmbeddedPwFile);
}
@Override
@@ -111,224 +115,222 @@ public class ConfigConverter extends ListActivity implements FileSelectCallback
String data = fs.getData();
- switch (type){
- case USERPW_FILE:
- ConfigParser.useEmbbedUserAuth(mResult, data);
- break;
- case PKCS12:
- mResult.mPKCS12Filename = data;
- break;
- case TLS_AUTH_FILE:
- mResult.mTLSAuthFilename = data;
- break;
- case CA_CERTIFICATE:
- mResult.mCaFilename = data;
- break;
- case CLIENT_CERTIFICATE:
- mResult.mClientCertFilename = data;
- break;
- case KEYFILE:
- mResult.mClientKeyFilename = data;
- break;
- default:
- Assert.fail();
- }
+ switch (type) {
+ case USERPW_FILE:
+ mEmbeddedPwFile = data;
+ break;
+ case PKCS12:
+ mResult.mPKCS12Filename = data;
+ break;
+ case TLS_AUTH_FILE:
+ mResult.mTLSAuthFilename = data;
+ break;
+ case CA_CERTIFICATE:
+ mResult.mCaFilename = data;
+ break;
+ case CLIENT_CERTIFICATE:
+ mResult.mClientCertFilename = data;
+ break;
+ case KEYFILE:
+ mResult.mClientKeyFilename = data;
+ break;
+ default:
+ Assert.fail();
+ }
}
super.onActivityResult(requestCode, resultCode, result);
}
- private void saveProfile() {
- Intent result = new Intent();
- ProfileManager vpl = ProfileManager.getInstance(this);
+ private void saveProfile() {
+ Intent result = new Intent();
+ ProfileManager vpl = ProfileManager.getInstance(this);
+ if (!TextUtils.isEmpty(mEmbeddedPwFile))
+ ConfigParser.useEmbbedUserAuth(mResult, mEmbeddedPwFile);
- vpl.addProfile(mResult);
- vpl.saveProfile(this, mResult);
- vpl.saveProfileList(this);
- result.putExtra(VpnProfile.EXTRA_PROFILEUUID,mResult.getUUID().toString());
- setResult(Activity.RESULT_OK, result);
- finish();
- }
+ vpl.addProfile(mResult);
+ vpl.saveProfile(this, mResult);
+ vpl.saveProfileList(this);
+ result.putExtra(VpnProfile.EXTRA_PROFILEUUID, mResult.getUUID().toString());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
- public void showCertDialog () {
- try {
- KeyChain.choosePrivateKeyAlias(this,
- new KeyChainAliasCallback() {
+ public void showCertDialog() {
+ try {
+ KeyChain.choosePrivateKeyAlias(this,
+ new KeyChainAliasCallback() {
- public void alias(String alias) {
- // Credential alias selected. Remember the alias selection for future use.
- mResult.mAlias=alias;
- saveProfile();
- }
+ public void alias(String alias) {
+ // Credential alias selected. Remember the alias selection for future use.
+ mResult.mAlias = alias;
+ saveProfile();
+ }
- },
- new String[] {"RSA"}, // List of acceptable key types. null for any
- null, // issuer, null for any
- mResult.mServerName, // host name of server requesting the cert, null if unavailable
- -1, // port of server requesting the cert, -1 if unavailable
- mAliasName); // alias to preselect, null if unavailable
- } catch (ActivityNotFoundException anf) {
- Builder ab = new AlertDialog.Builder(this);
- ab.setTitle(R.string.broken_image_cert_title);
- ab.setMessage(R.string.broken_image_cert);
- ab.setPositiveButton(android.R.string.ok, null);
- ab.show();
- }
- }
+ },
+ new String[]{"RSA"}, // List of acceptable key types. null for any
+ null, // issuer, null for any
+ mResult.mServerName, // host name of server requesting the cert, null if unavailable
+ -1, // port of server requesting the cert, -1 if unavailable
+ mAliasName); // alias to preselect, null if unavailable
+ } catch (ActivityNotFoundException anf) {
+ Builder ab = new AlertDialog.Builder(this);
+ ab.setTitle(R.string.broken_image_cert_title);
+ ab.setMessage(R.string.broken_image_cert);
+ ab.setPositiveButton(android.R.string.ok, null);
+ ab.show();
+ }
+ }
- private Intent installPKCS12() {
-
- if(!((CheckBox)findViewById(R.id.importpkcs12)).isChecked()) {
- setAuthTypeToEmbeddedPKCS12();
- return null;
-
- }
- String pkcs12datastr = mResult.mPKCS12Filename;
- if(pkcs12datastr!=null && pkcs12datastr.startsWith(VpnProfile.INLINE_TAG)) {
- Intent inkeyintent = KeyChain.createInstallIntent();
-
- pkcs12datastr= pkcs12datastr.substring(VpnProfile.INLINE_TAG.length());
-
-
- byte[] pkcs12data = Base64.decode(pkcs12datastr, Base64.DEFAULT);
+ private Intent installPKCS12() {
+ if (!((CheckBox) findViewById(R.id.importpkcs12)).isChecked()) {
+ setAuthTypeToEmbeddedPKCS12();
+ return null;
- inkeyintent.putExtra(KeyChain.EXTRA_PKCS12,pkcs12data );
+ }
+ String pkcs12datastr = mResult.mPKCS12Filename;
+ if (VpnProfile.isEmbedded(pkcs12datastr)) {
+ Intent inkeyIntent = KeyChain.createInstallIntent();
- if(mAliasName.equals(""))
- mAliasName=null;
+ pkcs12datastr = VpnProfile.getEmbeddedContent(pkcs12datastr);
- if(mAliasName!=null){
- inkeyintent.putExtra(KeyChain.EXTRA_NAME, mAliasName);
- }
- return inkeyintent;
- }
- return null;
- }
+ byte[] pkcs12data = Base64.decode(pkcs12datastr, Base64.DEFAULT);
+ inkeyIntent.putExtra(KeyChain.EXTRA_PKCS12, pkcs12data);
- private void setAuthTypeToEmbeddedPKCS12() {
- if(mResult.mPKCS12Filename!=null && mResult.mPKCS12Filename.startsWith(VpnProfile.INLINE_TAG)) {
- if(mResult.mAuthenticationType==VpnProfile.TYPE_USERPASS_KEYSTORE)
- mResult.mAuthenticationType=VpnProfile.TYPE_USERPASS_PKCS12;
-
- if(mResult.mAuthenticationType==VpnProfile.TYPE_KEYSTORE)
- mResult.mAuthenticationType=VpnProfile.TYPE_PKCS12;
-
- }
- }
+ if (mAliasName.equals(""))
+ mAliasName = null;
+ if (mAliasName != null) {
+ inkeyIntent.putExtra(KeyChain.EXTRA_NAME, mAliasName);
+ }
+ return inkeyIntent;
+ }
+ return null;
+ }
+
+
+ private void setAuthTypeToEmbeddedPKCS12() {
+ if (VpnProfile.isEmbedded(mResult.mPKCS12Filename)) {
+ if (mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE)
+ mResult.mAuthenticationType = VpnProfile.TYPE_USERPASS_PKCS12;
+ if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE)
+ mResult.mAuthenticationType = VpnProfile.TYPE_PKCS12;
+
+ }
+ }
- private String getUniqueProfileName(String possibleName) {
+ private String getUniqueProfileName(String possibleName) {
- int i=0;
+ int i = 0;
ProfileManager vpl = ProfileManager.getInstance(this);
- String newname = possibleName;
-
- // Default to
- if(mResult.mName!=null && !ConfigParser.CONVERTED_PROFILE.equals(mResult.mName))
- newname=mResult.mName;
-
- while(newname==null || vpl.getProfileByName(newname)!=null) {
- i++;
- if(i==1)
- newname = getString(R.string.converted_profile);
- else
- newname = getString(R.string.converted_profile_i,i);
- }
-
- return newname;
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- MenuInflater inflater = getMenuInflater();
- inflater.inflate(R.menu.import_menu, menu);
- return true;
- }
-
- private String embedFile(String filename, Utils.FileType type)
- {
- if(filename==null)
- return null;
-
- // Already embedded, nothing to do
- if(filename.startsWith(VpnProfile.INLINE_TAG))
- return filename;
-
- File possibleFile = findFile(filename, type);
- if(possibleFile==null)
- return filename;
- else
- return readFileContent(possibleFile,type == Utils.FileType.PKCS12);
-
- }
-
- private File findFile(String filename, Utils.FileType fileType) {
- File foundfile =findFileRaw(filename);
-
- if (foundfile==null && filename!=null && !filename.equals("")) {
- log(R.string.import_could_not_open,filename);
+ String newname = possibleName;
+
+ // Default to
+ if (mResult.mName != null && !ConfigParser.CONVERTED_PROFILE.equals(mResult.mName))
+ newname = mResult.mName;
+
+ while (newname == null || vpl.getProfileByName(newname) != null) {
+ i++;
+ if (i == 1)
+ newname = getString(R.string.converted_profile);
+ else
+ newname = getString(R.string.converted_profile_i, i);
+ }
+
+ return newname;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.import_menu, menu);
+ return true;
+ }
+
+ private String embedFile(String filename, Utils.FileType type) {
+ if (filename == null)
+ return null;
+
+ // Already embedded, nothing to do
+ if (VpnProfile.isEmbedded(filename))
+ return filename;
+
+ File possibleFile = findFile(filename, type);
+ if (possibleFile == null)
+ return filename;
+ else
+ return readFileContent(possibleFile, type == Utils.FileType.PKCS12);
+
+ }
+
+ private File findFile(String filename, Utils.FileType fileType) {
+ File foundfile = findFileRaw(filename);
+
+ if (foundfile == null && filename != null && !filename.equals("")) {
+ log(R.string.import_could_not_open, filename);
addFileSelectDialog(fileType);
}
- return foundfile;
- }
+ return foundfile;
+ }
private void addFileSelectDialog(Utils.FileType type) {
int titleRes = 0;
- String value=null;
+ String value = null;
switch (type) {
case KEYFILE:
titleRes = R.string.client_key_title;
- if (mResult!=null)
+ if (mResult != null)
value = mResult.mClientKeyFilename;
break;
case CLIENT_CERTIFICATE:
titleRes = R.string.client_certificate_title;
- if (mResult!=null)
+ if (mResult != null)
value = mResult.mClientCertFilename;
break;
case CA_CERTIFICATE:
titleRes = R.string.ca_title;
- if (mResult!=null)
+ if (mResult != null)
value = mResult.mCaFilename;
break;
case TLS_AUTH_FILE:
titleRes = R.string.tls_auth_file;
- if (mResult!=null)
+ if (mResult != null)
value = mResult.mTLSAuthFilename;
break;
case PKCS12:
titleRes = R.string.client_pkcs12_title;
- if (mResult!=null)
+ if (mResult != null)
value = mResult.mPKCS12Filename;
break;
case USERPW_FILE:
titleRes = R.string.userpw_file;
- return;
+ value = mEmbeddedPwFile;
+ break;
}
boolean isCert = type == Utils.FileType.CA_CERTIFICATE || type == Utils.FileType.CLIENT_CERTIFICATE;
- FileSelectLayout fl = new FileSelectLayout(this,getString(titleRes), isCert);
+ FileSelectLayout fl = new FileSelectLayout(this, getString(titleRes), isCert);
fileSelectMap.put(type, fl);
fl.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
((LinearLayout) findViewById(R.id.config_convert_root)).addView(fl, 1);
- fl.setData(value,this);
+ fl.setData(value, this);
int i = getFileLayoutOffset(type);
fl.setCaller(this, i, type);
@@ -339,132 +341,127 @@ public class ConfigConverter extends ListActivity implements FileSelectCallback
}
- private File findFileRaw(String filename)
- {
- if(filename == null || filename.equals(""))
- return null;
+ private File findFileRaw(String filename) {
+ if (filename == null || filename.equals(""))
+ return null;
- // Try diffent path relative to /mnt/sdcard
- File sdcard = Environment.getExternalStorageDirectory();
- File root = new File("/");
+ // Try diffent path relative to /mnt/sdcard
+ File sdcard = Environment.getExternalStorageDirectory();
+ File root = new File("/");
- HashSet<File> dirlist = new HashSet<File>();
+ HashSet<File> dirlist = new HashSet<File>();
- for(int i=mPathsegments.size()-1;i >=0 ;i--){
- String path = "";
- for (int j = 0;j<=i;j++) {
- path += "/" + mPathsegments.get(j);
- }
+ for (int i = mPathsegments.size() - 1; i >= 0; i--) {
+ String path = "";
+ for (int j = 0; j <= i; j++) {
+ path += "/" + mPathsegments.get(j);
+ }
// Do a little hackish dance for the Android File Importer
// /document/primary:ovpn/openvpn-imt.conf
- if (path.indexOf(':')!=-1) {
- String possibleDir = path.substring(path.indexOf(':')+1,path.length());
- possibleDir = possibleDir.substring(0,possibleDir.lastIndexOf('/'));
+ if (path.indexOf(':') != -1) {
+ String possibleDir = path.substring(path.indexOf(':') + 1, path.length());
+ possibleDir = possibleDir.substring(0, possibleDir.lastIndexOf('/'));
+
+
+ dirlist.add(new File(sdcard, possibleDir));
+
+ }
+ dirlist.add(new File(path));
+
+
+ }
+ dirlist.add(sdcard);
+ dirlist.add(root);
+
+
+ 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;
- dirlist.add(new File(sdcard,possibleDir));
+ // read the file inline
+ return possibleFile;
}
- dirlist.add(new File(path));
-
-
- }
- dirlist.add(sdcard);
- dirlist.add(root);
-
-
- 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
- return possibleFile;
-
- }
- }
- return null;
- }
-
- String readFileContent(File possibleFile, boolean base64encode) {
- byte [] filedata;
- try {
- filedata = readBytesFromFile(possibleFile);
- } catch (IOException e) {
- log(e.getLocalizedMessage());
- return null;
- }
-
- String data;
- if(base64encode) {
- data = Base64.encodeToString(filedata, Base64.DEFAULT);
- } else {
- data = new String(filedata);
-
- }
- return VpnProfile.INLINE_TAG + data;
-
- }
-
-
- private byte[] readBytesFromFile(File file) throws IOException {
- InputStream input = new FileInputStream(file);
-
- long len= file.length();
+ }
+ return null;
+ }
+
+ String readFileContent(File possibleFile, boolean base64encode) {
+ byte[] filedata;
+ try {
+ filedata = readBytesFromFile(possibleFile);
+ } catch (IOException e) {
+ log(e.getLocalizedMessage());
+ return null;
+ }
+
+ String data;
+ if (base64encode) {
+ data = Base64.encodeToString(filedata, Base64.DEFAULT);
+ } else {
+ data = new String(filedata);
+
+ }
+
+ return VpnProfile.DISPLAYNAME_TAG + possibleFile.getName() + VpnProfile.INLINE_TAG + data;
+
+ }
+
+
+ private byte[] readBytesFromFile(File file) throws IOException {
+ InputStream input = new FileInputStream(file);
+
+ long len = file.length();
if (len > VpnProfile.MAX_EMBED_FILE_SIZE)
throw new IOException("File size of file to import too large.");
- // Create the byte array to hold the data
- byte[] bytes = new byte[(int) len];
-
- // Read in the bytes
- int offset = 0;
- int bytesRead = 0;
- while (offset < bytes.length
- && (bytesRead=input.read(bytes, offset, bytes.length-offset)) >= 0) {
- offset += bytesRead;
- }
-
- input.close();
- return bytes;
- }
-
- void embedFiles() {
- // This where I would like to have a c++ style
- // void embedFile(std::string & option)
-
- if (mResult.mPKCS12Filename!=null) {
- File pkcs12file = findFileRaw(mResult.mPKCS12Filename);
- if(pkcs12file!=null) {
- mAliasName = pkcs12file.getName().replace(".p12", "");
- } else {
- mAliasName = "Imported PKCS12";
- }
- }
-
-
- mResult.mCaFilename = embedFile(mResult.mCaFilename, Utils.FileType.CA_CERTIFICATE);
- mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE);
- mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename, Utils.FileType.KEYFILE);
- mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE);
- mResult.mPKCS12Filename = embedFile(mResult.mPKCS12Filename, Utils.FileType.PKCS12);
-
-
- if(mResult.mUsername == null && mResult.mPassword != null ){
- String data =embedFile(mResult.mPassword, Utils.FileType.USERPW_FILE);
- ConfigParser.useEmbbedUserAuth(mResult, data);
+ // Create the byte array to hold the data
+ byte[] bytes = new byte[(int) len];
+
+ // Read in the bytes
+ int offset = 0;
+ int bytesRead = 0;
+ while (offset < bytes.length
+ && (bytesRead = input.read(bytes, offset, bytes.length - offset)) >= 0) {
+ offset += bytesRead;
+ }
+
+ input.close();
+ return bytes;
+ }
+
+ void embedFiles() {
+ // This where I would like to have a c++ style
+ // void embedFile(std::string & option)
+
+ if (mResult.mPKCS12Filename != null) {
+ File pkcs12file = findFileRaw(mResult.mPKCS12Filename);
+ if (pkcs12file != null) {
+ mAliasName = pkcs12file.getName().replace(".p12", "");
+ } else {
+ mAliasName = "Imported PKCS12";
+ }
}
- }
+
+
+ mResult.mCaFilename = embedFile(mResult.mCaFilename, Utils.FileType.CA_CERTIFICATE);
+ mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE);
+ mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename, Utils.FileType.KEYFILE);
+ mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE);
+ mResult.mPKCS12Filename = embedFile(mResult.mPKCS12Filename, Utils.FileType.PKCS12);
+ mEmbeddedPwFile = embedFile(mResult.mPassword, Utils.FileType.USERPW_FILE);
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -477,11 +474,12 @@ public class ConfigConverter extends ListActivity implements FileSelectCallback
super.onCreate(savedInstanceState);
- if (savedInstanceState !=null && savedInstanceState.containsKey(VPNPROFILE)) {
+ if (savedInstanceState != null && savedInstanceState.containsKey(VPNPROFILE)) {
mResult = (VpnProfile) savedInstanceState.getSerializable(VPNPROFILE);
mAliasName = savedInstanceState.getString("mAliasName");
+ mEmbeddedPwFile = savedInstanceState.getString("pwfile");
mArrayAdapter.addAll(savedInstanceState.getStringArray("logentries"));
- for (int k: savedInstanceState.getIntArray("fileselects")) {
+ for (int k : savedInstanceState.getIntArray("fileselects")) {
addFileSelectDialog(Utils.FileType.getFileTypeByValue(k));
}
@@ -489,34 +487,52 @@ public class ConfigConverter extends ListActivity implements FileSelectCallback
}
+ final android.content.Intent intent = getIntent();
- final android.content.Intent intent = getIntent ();
-
- if (intent != null )
- {
- final android.net.Uri data = intent.getData ();
- if (data != null)
- {
+ if (intent != null) {
+ final android.net.Uri data = intent.getData();
+ if (data != null) {
//log(R.string.import_experimental);
- log(R.string.importing_config,data.toString());
+ log(R.string.importing_config, data.toString());
try {
String possibleName = null;
- if(data.getScheme().equals("file") ||
+ if (data.getScheme().equals("file") ||
data.getLastPathSegment().endsWith(".ovpn") ||
- data.getLastPathSegment().endsWith(".conf"))
- {
+ data.getLastPathSegment().endsWith(".conf")) {
possibleName = data.getLastPathSegment();
- if (possibleName.lastIndexOf('/')!=-1)
- possibleName = possibleName.substring(possibleName.lastIndexOf('/')+1);
+ if (possibleName.lastIndexOf('/') != -1)
+ possibleName = possibleName.substring(possibleName.lastIndexOf('/') + 1);
- if(possibleName!=null){
- possibleName =possibleName.replace(".ovpn", "");
- possibleName =possibleName.replace(".conf", "");
- }
}
InputStream is = getContentResolver().openInputStream(data);
mPathsegments = data.getPathSegments();
+
+ Cursor cursor = getContentResolver().query(data, null, null, null, null);
+ try {
+
+
+ if (cursor.moveToFirst()) {
+ int cidx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
+
+ if (cidx != -1) {
+ String displayName = cursor.getString(cidx);
+ if (displayName != null)
+ possibleName = displayName;
+ }
+ cidx = cursor.getColumnIndex("mime_type");
+ if (cidx != -1) {
+ log("Opening Mime TYPE: " + cursor.getString(cidx));
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ if (possibleName != null) {
+ possibleName = possibleName.replace(".ovpn", "");
+ possibleName = possibleName.replace(".conf", "");
+ }
+
doImport(is, possibleName);
} catch (FileNotFoundException e) {
@@ -532,66 +548,65 @@ public class ConfigConverter extends ListActivity implements FileSelectCallback
}
- @Override
- protected void onStart() {
- super.onStart();
-
+ @Override
+ protected void onStart() {
+ super.onStart();
- }
+ }
- private void log(String logmessage) {
- mArrayAdapter.add(logmessage);
- }
+ private void log(String logmessage) {
+ mArrayAdapter.add(logmessage);
+ }
- private void doImport(InputStream is, String newName) {
- ConfigParser cp = new ConfigParser();
- try {
- InputStreamReader isr = new InputStreamReader(is);
+ private void doImport(InputStream is, String newName) {
+ ConfigParser cp = new ConfigParser();
+ try {
+ InputStreamReader isr = new InputStreamReader(is);
- cp.parseConfig(isr);
- VpnProfile vp = cp.convertProfile();
- mResult = vp;
- embedFiles();
- displayWarnings();
+ cp.parseConfig(isr);
+ VpnProfile vp = cp.convertProfile();
+ mResult = vp;
+ embedFiles();
+ displayWarnings();
mResult.mName = getUniqueProfileName(newName);
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);
- String copt = mResult.mCustomConfigOptions;
- if(copt.startsWith("#")) {
- int until = copt.indexOf('\n');
- copt = copt.substring(until+1);
- }
-
- log(copt);
- }
-
- if(mResult.mAuthenticationType==VpnProfile.TYPE_KEYSTORE ||
- mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
- findViewById(R.id.importpkcs12).setVisibility(View.VISIBLE);
- }
-
- }
-
- private void log(int ressourceId, Object... formatArgs) {
- log(getString(ressourceId,formatArgs));
- }
+ 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);
+ String copt = mResult.mCustomConfigOptions;
+ if (copt.startsWith("#")) {
+ int until = copt.indexOf('\n');
+ copt = copt.substring(until + 1);
+ }
+
+ log(copt);
+ }
+
+ if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE ||
+ mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) {
+ findViewById(R.id.importpkcs12).setVisibility(View.VISIBLE);
+ }
+
+ }
+
+ private void log(int ressourceId, Object... formatArgs) {
+ log(getString(ressourceId, formatArgs));
+ }
}
diff --git a/src/de/blinkt/openvpn/activities/FileSelect.java b/src/de/blinkt/openvpn/activities/FileSelect.java
index 50584063..8967b1bf 100644
--- a/src/de/blinkt/openvpn/activities/FileSelect.java
+++ b/src/de/blinkt/openvpn/activities/FileSelect.java
@@ -185,15 +185,15 @@ public class FileSelect extends Activity {
}
public String getSelectPath() {
- if(!mData.startsWith(VpnProfile.INLINE_TAG))
+ if(VpnProfile.isEmbedded(mData))
return mData;
else
return Environment.getExternalStorageDirectory().getPath();
}
public CharSequence getInlineData() {
- if(mData.startsWith(VpnProfile.INLINE_TAG))
- return mData.substring(VpnProfile.INLINE_TAG.length());
+ if(VpnProfile.isEmbedded(mData))
+ return VpnProfile.getEmbeddedContent(mData);
else
return "";
}
diff --git a/src/de/blinkt/openvpn/core/ConfigParser.java b/src/de/blinkt/openvpn/core/ConfigParser.java
index 06acdf98..22cc5dce 100644
--- a/src/de/blinkt/openvpn/core/ConfigParser.java
+++ b/src/de/blinkt/openvpn/core/ConfigParser.java
@@ -398,10 +398,18 @@ public class ConfigParser {
if(direction!=null)
np.mTLSAuthDirection=direction.get(1);
+ Vector<Vector<String>> defgw = getAllOption("redirect-gateway", 0, 5);
+ if(defgw != null)
+ {
+ np.mUseDefaultRoute=true;
+ checkRedirectParameters(np, defgw);
+ }
- if(getAllOption("redirect-gateway", 0, 5) != null)
- np.mUseDefaultRoute=true;
-
+ Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private",0,5);
+ if (redirectPrivate != null)
+ {
+ checkRedirectParameters(np,redirectPrivate);
+ }
Vector<String> dev =getOption("dev",1,1);
Vector<String> devtype =getOption("dev-type",1,1);
@@ -621,7 +629,17 @@ public class ConfigParser {
return np;
}
- public void useExtraRemotesAsCustom(boolean b) {
+ private void checkRedirectParameters(VpnProfile np, Vector<Vector<String>> defgw) {
+ for (Vector<String> redirect: defgw)
+ for (int i=1;i<redirect.size();i++){
+ if (defgw.get(i).equals("block-local"))
+ np.mAllowLocalLAN=false;
+ else if (defgw.get(i).equals("unblock-local"))
+ np.mAllowLocalLAN=true;
+ }
+ }
+
+ public void useExtraRemotesAsCustom(boolean b) {
this.extraRemotesAsCustom = b;
}
@@ -641,7 +659,7 @@ public class ConfigParser {
static public void useEmbbedUserAuth(VpnProfile np,String inlinedata)
{
- String data = inlinedata.replace(VpnProfile.INLINE_TAG, "");
+ String data = VpnProfile.getEmbeddedContent(inlinedata);
String[] parts = data.split("\n");
if(parts.length >= 2) {
np.mUsername=parts[0];
diff --git a/src/de/blinkt/openvpn/core/X509Utils.java b/src/de/blinkt/openvpn/core/X509Utils.java
index 5781cbf5..da1e4ed5 100644
--- a/src/de/blinkt/openvpn/core/X509Utils.java
+++ b/src/de/blinkt/openvpn/core/X509Utils.java
@@ -25,7 +25,7 @@ public class X509Utils {
InputStream inStream;
- if(certfilename.startsWith(VpnProfile.INLINE_TAG)) {
+ if(VpnProfile.isEmbedded(certfilename)) {
// The java certifcate reader is ... kind of stupid
// It does NOT ignore chars before the --BEGIN ...
int subIndex = certfilename.indexOf("-----BEGIN CERTIFICATE-----");
@@ -45,8 +45,8 @@ public class X509Utils {
Reader inStream;
- if(keyfilename.startsWith(VpnProfile.INLINE_TAG))
- inStream = new StringReader(keyfilename.replace(VpnProfile.INLINE_TAG,""));
+ if(VpnProfile.isEmbedded(keyfilename))
+ inStream = new StringReader(VpnProfile.getEmbeddedContent(keyfilename));
else
inStream = new FileReader(new File(keyfilename));
diff --git a/src/de/blinkt/openvpn/fragments/Settings_Authentication.java b/src/de/blinkt/openvpn/fragments/Settings_Authentication.java
index b153ce4d..236d7947 100644
--- a/src/de/blinkt/openvpn/fragments/Settings_Authentication.java
+++ b/src/de/blinkt/openvpn/fragments/Settings_Authentication.java
@@ -191,7 +191,7 @@ public class Settings_Authentication extends OpenVpnPreferencesFragment implemen
setTlsAuthSummary(result);
} else if (requestCode == SELECT_TLS_FILE_KITKAT && resultCode == Activity.RESULT_OK) {
try {
- mTlsAuthFileData= VpnProfile.INLINE_TAG + Utils.getStringFromFilePickerResult(Utils.FileType.TLS_AUTH_FILE,data,getActivity());
+ mTlsAuthFileData= Utils.getFilePickerResult(Utils.FileType.TLS_AUTH_FILE,data,getActivity());
setTlsAuthSummary(mTlsAuthFileData);
} catch (IOException e) {
VpnStatus.logException(e);
@@ -200,9 +200,12 @@ public class Settings_Authentication extends OpenVpnPreferencesFragment implemen
}
private void setTlsAuthSummary(String result) {
- if(result==null) result = getString(R.string.no_certificate);
+ if(result==null)
+ result = getString(R.string.no_certificate);
if(result.startsWith(VpnProfile.INLINE_TAG))
mTLSAuthFile.setSummary(R.string.inline_file_data);
+ else if (result.startsWith(VpnProfile.DISPLAYNAME_TAG))
+ mExpectTLSCert.setSummary(getString(R.string.imported_from_file, VpnProfile.getDisplayName(result)));
else
mTLSAuthFile.setSummary(result);
}
diff --git a/src/de/blinkt/openvpn/fragments/Utils.java b/src/de/blinkt/openvpn/fragments/Utils.java
index f13b1987..6f06f35a 100644
--- a/src/de/blinkt/openvpn/fragments/Utils.java
+++ b/src/de/blinkt/openvpn/fragments/Utils.java
@@ -3,10 +3,14 @@ package de.blinkt.openvpn.fragments;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
+import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
+import android.provider.OpenableColumns;
import android.util.Base64;
+import android.util.Log;
import android.webkit.MimeTypeMap;
+import de.blinkt.openvpn.VpnProfile;
import junit.framework.Assert;
import java.io.*;
@@ -44,6 +48,21 @@ public class Utils {
i.setType("application/x-pem-file");
supportedMimeTypes.add("application/x-pem-file");
supportedMimeTypes.add("application/pkcs8");
+
+ // Google drive ....
+ supportedMimeTypes.add("application/x-iwork-keynote-sffkey");
+ extensions.add("key");
+ break;
+
+ case TLS_AUTH_FILE:
+ i.setType("text/plain");
+
+ // Backup ....
+ supportedMimeTypes.add("application/pkcs8");
+ // Google Drive is kind of crazy .....
+ supportedMimeTypes.add("application/x-iwork-keynote-sffkey");
+
+ extensions.add("txt");
extensions.add("key");
break;
@@ -52,19 +71,14 @@ public class Utils {
supportedMimeTypes.add("application/x-openvpn-profile");
supportedMimeTypes.add("application/openvpn-profile");
supportedMimeTypes.add("application/ovpn");
+ supportedMimeTypes.add("text/plain");
extensions.add("ovpn");
extensions.add("conf");
break;
- case TLS_AUTH_FILE:
- i.setType("text/plain");
- // Backup ....
- supportedMimeTypes.add("application/pkcs8");
- extensions.add("txt");
- extensions.add("key");
- break;
case USERPW_FILE:
- Assert.fail();
+ i.setType("text/plain");
+ supportedMimeTypes.add("text/plain");
break;
}
@@ -74,10 +88,11 @@ public class Utils {
String mimeType = mtm.getMimeTypeFromExtension(ext);
if (mimeType != null)
supportedMimeTypes.add(mimeType);
- else
- supportedMimeTypes.add("application/octet-stream");
}
+ // Always add this as fallback
+ supportedMimeTypes.add("application/octet-stream");
+
i.putExtra(Intent.EXTRA_MIME_TYPES, supportedMimeTypes.toArray(new String[supportedMimeTypes.size()]));
return i;
}
@@ -94,12 +109,11 @@ public class Utils {
private int value;
FileType(int i) {
- value=i;
+ value = i;
}
- public static FileType getFileTypeByValue(int value)
- {
- switch(value) {
+ public static FileType getFileTypeByValue(int value) {
+ switch (value) {
case 0:
return PKCS12;
case 1:
@@ -140,14 +154,32 @@ public class Utils {
return buffer.toByteArray();
}
- public static String getStringFromFilePickerResult(FileType ft, Intent result, Context c) throws IOException {
+ public static String getFilePickerResult(FileType ft, Intent result, Context c) throws IOException {
Uri uri = result.getData();
- if (uri ==null)
+ if (uri == null)
return null;
byte[] fileData = readBytesFromStream(c.getContentResolver().openInputStream(uri));
String newData = null;
+
+ Cursor cursor = c.getContentResolver().query(uri, null, null, null, null);
+
+ String prefix = "";
+ try {
+ if (cursor.moveToFirst()) {
+ int cidx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
+ if (cidx != -1) {
+ String displayName = cursor.getString(cidx);
+
+ if (!displayName.contains(VpnProfile.INLINE_TAG) && !displayName.contains(VpnProfile.DISPLAYNAME_TAG))
+ prefix = VpnProfile.DISPLAYNAME_TAG + displayName;
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+
switch (ft) {
case PKCS12:
newData = Base64.encodeToString(fileData, Base64.DEFAULT);
@@ -156,6 +188,7 @@ public class Utils {
newData = new String(fileData, "UTF-8");
break;
}
- return newData;
+
+ return prefix + VpnProfile.INLINE_TAG + newData;
}
}
diff --git a/src/de/blinkt/openvpn/views/FileSelectLayout.java b/src/de/blinkt/openvpn/views/FileSelectLayout.java
index 04392b47..362777e4 100644
--- a/src/de/blinkt/openvpn/views/FileSelectLayout.java
+++ b/src/de/blinkt/openvpn/views/FileSelectLayout.java
@@ -29,9 +29,9 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
setData(fileData, c);
} else if (data != null) {
try {
- String newData = Utils.getStringFromFilePickerResult(fileType,data,c);
+ String newData = Utils.getFilePickerResult(fileType, data, c);
if (newData!=null)
- setData(VpnProfile.INLINE_TAG + newData, c);
+ setData(newData, c);
} catch (IOException e) {
VpnStatus.logException(e);
@@ -119,10 +119,12 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
public void setData(String data, Context c) {
mData = data;
if (data == null) {
- mDataView.setText(mFragment.getString(R.string.no_data));
+ mDataView.setText(c.getString(R.string.no_data));
mDataDetails.setText("");
} else {
- if (mData.startsWith(VpnProfile.INLINE_TAG))
+ if (mData.startsWith(VpnProfile.DISPLAYNAME_TAG)) {
+ mDataView.setText(c.getString(R.string.imported_from_file, VpnProfile.getDisplayName(mData)));
+ } else if (mData.startsWith(VpnProfile.INLINE_TAG))
mDataView.setText(R.string.inline_file_data);
else
mDataView.setText(data);