summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2012-08-22 23:52:25 +0200
committerArne Schwabe <arne@rfc2549.org>2012-08-22 23:52:25 +0200
commitb3c34c5ecaf55c944ae1a7cbf3ab0010b70d91e7 (patch)
tree0e6676515840f136abe2c1de7e2f4ab534fc2de7
parent765818d19bbc5debfc2fd034943c071008b4090c (diff)
Enable the config converter to convert openvpn 2.2 tls-remote format to 2.3 format
-rw-r--r--res/layout/config_converter.xml36
-rw-r--r--res/values-de/strings.xml6
-rw-r--r--res/values/strings.xml1
-rw-r--r--src/de/blinkt/openvpn/ConfigConverter.java813
-rw-r--r--src/de/blinkt/openvpn/VpnProfile.java2
5 files changed, 442 insertions, 416 deletions
diff --git a/res/layout/config_converter.xml b/res/layout/config_converter.xml
index 13733fb3..ea60c076 100644
--- a/res/layout/config_converter.xml
+++ b/res/layout/config_converter.xml
@@ -3,20 +3,26 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
-<CheckBox
- android:id="@+id/importpkcs12"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:checked="true"
- android:text="@string/importpkcs12fromconfig"
- android:visibility="gone"
- />
- <ListView
- android:id="@android:id/list"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
-
-
- </LinearLayout>
+ <CheckBox
+ android:id="@+id/importpkcs12"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:checked="true"
+ android:text="@string/importpkcs12fromconfig"
+ android:visibility="gone" />
+ <CheckBox
+ android:id="@+id/correcttls"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:checked="true"
+ android:text="@string/correcttls"
+ android:visibility="gone" />
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 01e53c65..cb7b8965 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -207,10 +207,12 @@
<string name="restart_vpn_after_change">Konfigurationsänderungen werden erst nach einem VPN Neustart aktiv. Jetzt neu verbinden?</string>
<string name="configuration_changed">Konfiguration geändert</string>
<string name="log_no_last_vpn">Konnte das zuletzt verbundene Profile beim Versuch des Editieren nicht ermitteln.</string>
-<string name="faq_duplicate_notification_title">Doppelte Benachrichtigungen</string>
+ <string name="faq_duplicate_notification_title">Doppelte Benachrichtigungen</string>
<string name="faq_duplicate_notification">Android beendet automatisch Anwendungen und Dienste, die im Hintergrund laufen, wenn der Arbeitsspeicher knapp wird. Wird dabei Openvpn beendet, bricht die VPN Verbindung ab. Um dies zu vermeiden, läuft der VPN Prozess mit einer höheren Priorität. Um eine höhere Prioität nutzen zu können, muss die Anwesenheit des Prozesses dem Benutzer im Form einer Benachrichtigung mitgeteilt werden. Daher zeigt Openvpn für Android immer seine eigene Benachrichtigung an. Die Schlüssel Benachrichtung, die auch im letzen Eintrag erklärt wird, zählt leider nicht als Benachrichtigung, die der Anwendung erlaubt mit höherer Priorität zu arbeiten.</string>
<string name="no_vpn_profiles_defined">Keine VPN Profile definiert.</string>
<string name="add_new_vpn_hint">Benutzen Sie &lt;img src=\"ic_menu_add\"/> um ein neues VPN anzulegen</string>
<string name="vpn_import_hint">Benutzen Sie &lt;img src=\"ic_menu_archive\"/> um ein vorhandenes (.ovpn oder .conf) Profil von Ihrer SD Karte zu importieren</string>
<string name="faq_hint">Lesen Sie auch die FAQ. Dort befindet sich eine Schnellstart Anleitung</string>
-</resources>
+ <string name="correcttls">Konventiere den remote-tls Parameter vom OpenVPN 2.2 zum OpenVPN 2.3 Format</string>
+
+</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1d9c8f67..643d0919 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -255,4 +255,5 @@
<string name="add_new_vpn_hint">Use the &lt;img src=\"ic_menu_add\"/> icon to add a new VPN</string>
<string name="vpn_import_hint">Use the &lt;img src=\"ic_menu_archive\"/> icon to import an existing (.ovpn or .conf) profile from your sdcard.</string>
<string name="faq_hint">Be sure to also check out the FAQ. There is a quick start guide.</string>
+ <string name="correcttls">Convert remote-tls format from OpenVPN 2.2 to 2.3 format</string>
</resources>
diff --git a/src/de/blinkt/openvpn/ConfigConverter.java b/src/de/blinkt/openvpn/ConfigConverter.java
index ee5a4415..af2113ea 100644
--- a/src/de/blinkt/openvpn/ConfigConverter.java
+++ b/src/de/blinkt/openvpn/ConfigConverter.java
@@ -1,398 +1,415 @@
-
-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 java.util.List;
-import java.util.Vector;
-
-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.os.Bundle;
-import android.os.Environment;
-import android.security.KeyChain;
-import android.security.KeyChainAliasCallback;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.CheckBox;
-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<String> mArrayAdapter;
-
- private List<String> mPathsegments;
-
- private String mAliasName=null;
-
- private int RESULT_INSTALLPKCS12 = 7;
-
- private String mPossibleName=null;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.config_converter);
- }
-
-
-
- @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();
-
- if(in != null)
- startActivityForResult(in, RESULT_INSTALLPKCS12);
- else
- saveProfile();
-
- return true;
- }
-
- return super.onOptionsItemSelected(item);
-
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if(requestCode==RESULT_INSTALLPKCS12) {
- if(resultCode==Activity.RESULT_OK) {
- showCertDialog();
- }
- }
-
- super.onActivityResult(requestCode, resultCode, data);
- }
-
- private void saveProfile() {
- Intent result = new Intent();
- ProfileManager vpl = ProfileManager.getInstance(this);
-
- setUniqueProfileName(vpl);
- 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 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();
- }
- }
-
-
- private Intent installPKCS12() {
- if(!((CheckBox)findViewById(R.id.importpkcs12)).isChecked())
- return null;
- File possiblepkcs12 = findFile(mResult.mPKCS12Filename);
-
- if(possiblepkcs12!=null) {
- Intent inkeyintent = KeyChain.createInstallIntent();
- byte[] pkcs12data;
- try {
- pkcs12data = readBytesFromFile(possiblepkcs12);
- } catch (IOException e) {
- return null;
- }
-
- inkeyintent.putExtra(KeyChain.EXTRA_PKCS12,pkcs12data );
-
- mAliasName = possiblepkcs12.getName().replace(".p12", "");
- if(mAliasName.equals(""))
- mAliasName=null;
-
- if(mAliasName!=null){
- inkeyintent.putExtra(KeyChain.EXTRA_NAME, mAliasName);
- }
- return inkeyintent;
-
- }
- return null;
- }
-
-
- private void setUniqueProfileName(ProfileManager vpl) {
- int i=0;
-
- String newname = mPossibleName;
-
- while(vpl.getProfileByName(newname)!=null) {
- i++;
- if(i==1)
- newname = getString(R.string.converted_profile);
- else
- newname = getString(R.string.converted_profile_i,i);
- }
-
- mResult.mName=newname;
- }
-
- @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)
- return null;
-
- // Already embedded, nothing to do
- if(filename.startsWith(VpnProfile.INLINE_TAG))
- return filename;
-
- File possibleFile = findFile(filename);
- if(possibleFile==null)
- return null;
- else
- return readFileContent(possibleFile);
-
- }
-
- private File findFile(String filename)
- {
- if(filename == null || filename.equals(""))
- return null;
-
- // Try diffent path relative to /mnt/sdcard
- File sdcard = Environment.getExternalStorageDirectory();
- File root = new File("/");
-
- Vector<File> dirlist = new Vector<File>();
-
- for(int i=mPathsegments.size()-1;i >=0 ;i--){
- String path = "";
- for (int j = 0;j<=i;j++) {
- path += "/" + mPathsegments.get(j);
- }
- 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;
-
- }
- }
- log(R.string.import_could_not_open,filename);
- return null;
- }
-
- String readFileContent(File possibleFile) {
- String filedata = "";
- 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);
- }
- fis.close();
- return VpnProfile.INLINE_TAG + filedata;
- } catch (FileNotFoundException e) {
- log(e.getLocalizedMessage());
- } catch (IOException e) {
- log(e.getLocalizedMessage());
- }
-
- return null;
- }
-
-
- private byte[] readBytesFromFile(File file) throws IOException {
- InputStream input = new FileInputStream(file);
-
- long len= file.length();
-
-
- // 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)
-
- mResult.mCaFilename = embedFile(mResult.mCaFilename);
- mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename);
- mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename);
- mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename);
-
- if(mResult.mUsername != null && !mResult.mUsername.equals("")){
- String data =embedFile(mResult.mUsername);
- mResult.mName=null;
- if(data!=null) {
- data = data.replace(VpnProfile.INLINE_TAG, "");
- String[] parts = data.split("\n");
- if(parts.length >= 2) {
- mResult.mName=parts[0];
- mResult.mPassword=parts[1];
- }
- }
- }
- }
-
-
- @Override
- protected void onStart() {
- super.onStart();
-
- mArrayAdapter = new ArrayAdapter<String>(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.import_experimental);
- log(R.string.importing_config,data.toString());
- try {
- if(data.getScheme().equals("file")) {
- mPossibleName = data.getLastPathSegment();
- if(mPossibleName!=null){
- mPossibleName =mPossibleName.replace(".ovpn", "");
- mPossibleName =mPossibleName.replace(".conf", "");
- }
- }
- InputStream is = getContentResolver().openInputStream(data);
- mPathsegments = data.getPathSegments();
-
- 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);
- 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));
- }
-}
+
+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 java.util.List;
+import java.util.Vector;
+
+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.os.Bundle;
+import android.os.Environment;
+import android.security.KeyChain;
+import android.security.KeyChainAliasCallback;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.CheckBox;
+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<String> mArrayAdapter;
+
+ private List<String> mPathsegments;
+
+ private String mAliasName=null;
+
+ private int RESULT_INSTALLPKCS12 = 7;
+
+ private String mPossibleName=null;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.config_converter);
+ }
+
+
+
+ @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();
+
+ if(in != null)
+ startActivityForResult(in, RESULT_INSTALLPKCS12);
+ else
+ saveProfile();
+
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if(requestCode==RESULT_INSTALLPKCS12) {
+ if(resultCode==Activity.RESULT_OK) {
+ showCertDialog();
+ }
+ }
+
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
+ private void saveProfile() {
+ Intent result = new Intent();
+ ProfileManager vpl = ProfileManager.getInstance(this);
+
+ if(((CheckBox)findViewById(R.id.correcttls)).isChecked() && isOldCNFormat()) {
+ convertTLSRemote();
+ }
+
+ setUniqueProfileName(vpl);
+ vpl.addProfile(mResult);
+ vpl.saveProfile(this, mResult);
+ vpl.saveProfileList(this);
+ result.putExtra(VpnProfile.EXTRA_PROFILEUUID,mResult.getUUID().toString());
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ }
+
+
+
+ private void convertTLSRemote() {
+ if(mResult.mRemoteCN.startsWith("/"))
+ mResult.mRemoteCN = mResult.mRemoteCN.substring(1);
+ mResult.mRemoteCN = mResult.mRemoteCN.replace("/", ", ");
+ }
+
+ 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();
+ }
+
+
+ },
+ 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())
+ return null;
+ File possiblepkcs12 = findFile(mResult.mPKCS12Filename);
+
+ if(possiblepkcs12!=null) {
+ Intent inkeyintent = KeyChain.createInstallIntent();
+ byte[] pkcs12data;
+ try {
+ pkcs12data = readBytesFromFile(possiblepkcs12);
+ } catch (IOException e) {
+ return null;
+ }
+
+ inkeyintent.putExtra(KeyChain.EXTRA_PKCS12,pkcs12data );
+
+ mAliasName = possiblepkcs12.getName().replace(".p12", "");
+ if(mAliasName.equals(""))
+ mAliasName=null;
+
+ if(mAliasName!=null){
+ inkeyintent.putExtra(KeyChain.EXTRA_NAME, mAliasName);
+ }
+ return inkeyintent;
+
+ }
+ return null;
+ }
+
+
+ private void setUniqueProfileName(ProfileManager vpl) {
+ int i=0;
+
+ String newname = mPossibleName;
+
+ while(vpl.getProfileByName(newname)!=null) {
+ i++;
+ if(i==1)
+ newname = getString(R.string.converted_profile);
+ else
+ newname = getString(R.string.converted_profile_i,i);
+ }
+
+ mResult.mName=newname;
+ }
+
+ @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)
+ return null;
+
+ // Already embedded, nothing to do
+ if(filename.startsWith(VpnProfile.INLINE_TAG))
+ return filename;
+
+ File possibleFile = findFile(filename);
+ if(possibleFile==null)
+ return null;
+ else
+ return readFileContent(possibleFile);
+
+ }
+
+ private File findFile(String filename)
+ {
+ if(filename == null || filename.equals(""))
+ return null;
+
+ // Try diffent path relative to /mnt/sdcard
+ File sdcard = Environment.getExternalStorageDirectory();
+ File root = new File("/");
+
+ Vector<File> dirlist = new Vector<File>();
+
+ for(int i=mPathsegments.size()-1;i >=0 ;i--){
+ String path = "";
+ for (int j = 0;j<=i;j++) {
+ path += "/" + mPathsegments.get(j);
+ }
+ 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;
+
+ }
+ }
+ log(R.string.import_could_not_open,filename);
+ return null;
+ }
+
+ String readFileContent(File possibleFile) {
+ String filedata = "";
+ 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);
+ }
+ fis.close();
+ return VpnProfile.INLINE_TAG + filedata;
+ } catch (FileNotFoundException e) {
+ log(e.getLocalizedMessage());
+ } catch (IOException e) {
+ log(e.getLocalizedMessage());
+ }
+
+ return null;
+ }
+
+
+ private byte[] readBytesFromFile(File file) throws IOException {
+ InputStream input = new FileInputStream(file);
+
+ long len= file.length();
+
+
+ // 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)
+
+ mResult.mCaFilename = embedFile(mResult.mCaFilename);
+ mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename);
+ mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename);
+ mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename);
+
+ if(mResult.mUsername != null && !mResult.mUsername.equals("")){
+ String data =embedFile(mResult.mUsername);
+ mResult.mName=null;
+ if(data!=null) {
+ data = data.replace(VpnProfile.INLINE_TAG, "");
+ String[] parts = data.split("\n");
+ if(parts.length >= 2) {
+ mResult.mName=parts[0];
+ mResult.mPassword=parts[1];
+ }
+ }
+ }
+ }
+
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ mArrayAdapter = new ArrayAdapter<String>(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.import_experimental);
+ log(R.string.importing_config,data.toString());
+ try {
+ if(data.getScheme().equals("file")) {
+ mPossibleName = data.getLastPathSegment();
+ if(mPossibleName!=null){
+ mPossibleName =mPossibleName.replace(".ovpn", "");
+ mPossibleName =mPossibleName.replace(".conf", "");
+ }
+ }
+ InputStream is = getContentResolver().openInputStream(data);
+ mPathsegments = data.getPathSegments();
+
+ 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);
+ 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);
+ }
+
+ if (isOldCNFormat())
+ findViewById(R.id.correcttls).setVisibility(View.VISIBLE);
+ }
+
+ private boolean isOldCNFormat() {
+ return mResult.mCheckRemoteCN && mResult.mRemoteCN.contains("/") && ! mResult.mRemoteCN.contains("_");
+ }
+
+ private void log(int ressourceId, Object... formatArgs) {
+ log(getString(ressourceId,formatArgs));
+ }
+}
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
index 3255c0b4..0d650991 100644
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ b/src/de/blinkt/openvpn/VpnProfile.java
@@ -319,7 +319,7 @@ public class VpnProfile implements Serializable{
if(mRemoteCN == null || mRemoteCN.equals("") )
cfg+="tls-remote " + mServerName + "\n";
else
- cfg += "tls-remote " + mRemoteCN + "\n";
+ cfg += "tls-remote " + openVpnEscape(mRemoteCN) + "\n";
}
if(mExpectTLSCert)
cfg += "remote-cert-tls server\n";