summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openvpn/src/openvpn/jniglue.c18
-rw-r--r--openvpn/src/openvpn/jniglue.h3
-rw-r--r--openvpn/src/openvpn/options.c6
-rw-r--r--openvpn/src/openvpn/tun.c7
-rw-r--r--openvpn/src/openvpn/tun.h3
-rw-r--r--res/layout/basic_settings.xml56
-rw-r--r--res/values-de/arrays.xml7
-rw-r--r--res/values/arrays.xml7
-rw-r--r--res/values/strings.xml6
-rw-r--r--res/xml/vpn_authentification.xml27
-rw-r--r--src/de/blinkt/openvpn/BasicSettings.java71
-rw-r--r--src/de/blinkt/openvpn/FileSelectLayout.java11
-rw-r--r--src/de/blinkt/openvpn/LogWindow.java151
-rw-r--r--src/de/blinkt/openvpn/OpenVPN.java31
-rw-r--r--src/de/blinkt/openvpn/OpenVPNClient.java383
-rw-r--r--src/de/blinkt/openvpn/OpenVpnService.java33
-rw-r--r--src/de/blinkt/openvpn/ProfileManager.java23
-rw-r--r--src/de/blinkt/openvpn/Settings_Authentication.java60
-rw-r--r--src/de/blinkt/openvpn/Settings_IP.java4
-rw-r--r--src/de/blinkt/openvpn/VPNConfigPreference.java7
-rw-r--r--src/de/blinkt/openvpn/VPNDatabase.java0
-rw-r--r--src/de/blinkt/openvpn/VPNPreferences.java57
-rw-r--r--src/de/blinkt/openvpn/VPNProfileList.java99
-rw-r--r--src/de/blinkt/openvpn/VpnProfile.java62
24 files changed, 495 insertions, 637 deletions
diff --git a/openvpn/src/openvpn/jniglue.c b/openvpn/src/openvpn/jniglue.c
index 2d529365..686092bc 100644
--- a/openvpn/src/openvpn/jniglue.c
+++ b/openvpn/src/openvpn/jniglue.c
@@ -143,6 +143,24 @@ int android_open_tun () {
}
+void android_set_dns(const char* dns) {
+ jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "addDns",
+ "(Ljava/lang/String;)V");
+ jstring jdns = (*openvpnjenv)->NewStringUTF(openvpnjenv,dns);
+ (*openvpnjenv)->CallStaticVoidMethod(openvpnjenv,openvpnclass,aMethodID,jdns);
+
+
+}
+
+void android_set_domain(const char* domain) {
+ jmethodID aMethodID = (*openvpnjenv)->GetStaticMethodID(openvpnjenv, openvpnclass, "addDomain",
+ "(Ljava/lang/String;)V");
+ jstring jdomain = (*openvpnjenv)->NewStringUTF(openvpnjenv,domain);
+ (*openvpnjenv)->CallStaticVoidMethod(openvpnjenv,openvpnclass,aMethodID,jdomain);
+
+
+}
+
void addRouteInformation(const char* dest, const char* mask, const char* gw) {
jstring jmask = (*openvpnjenv)->NewStringUTF(openvpnjenv, mask);
diff --git a/openvpn/src/openvpn/jniglue.h b/openvpn/src/openvpn/jniglue.h
index cb3ae410..7c723ef5 100644
--- a/openvpn/src/openvpn/jniglue.h
+++ b/openvpn/src/openvpn/jniglue.h
@@ -14,6 +14,7 @@ void addRouteInformation(const char* dest, const char* mask, const char* gw);
void addInterfaceInformation(int mtu,const char* ifconfig_local, const char* ifconfig_remote);
void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,const char* m1);
void android_openvpn_exit(int status);
-
+void android_set_dns(const char* dns);
+void android_set_domain(const char* domain);
#endif
diff --git a/openvpn/src/openvpn/options.c b/openvpn/src/openvpn/options.c
index fcf436c4..b74e559b 100644
--- a/openvpn/src/openvpn/options.c
+++ b/openvpn/src/openvpn/options.c
@@ -1134,7 +1134,9 @@ show_tuntap_options (const struct tuntap_options *o)
}
#endif
+#endif
+#if defined(WIN32) || defined(TARGET_ANDROID)
static void
dhcp_option_address_parse (const char *name, const char *parm, in_addr_t *array, int *len, int msglevel)
{
@@ -5999,6 +6001,8 @@ add_option (struct options *options,
to->ip_win32_type = index;
to->ip_win32_defined = true;
}
+#endif
+#if defined(WIN32) || defined(TARGET_ANDROID)
else if (streq (p[0], "dhcp-option") && p[1])
{
struct tuntap_options *o = &options->tuntap_options;
@@ -6050,6 +6054,8 @@ add_option (struct options *options,
}
o->dhcp_options = true;
}
+#endif
+#ifdef WIN32
else if (streq (p[0], "show-adapters"))
{
VERIFY_PERMISSION (OPT_P_GENERAL);
diff --git a/openvpn/src/openvpn/tun.c b/openvpn/src/openvpn/tun.c
index db8104d4..58e9bc53 100644
--- a/openvpn/src/openvpn/tun.c
+++ b/openvpn/src/openvpn/tun.c
@@ -1378,6 +1378,13 @@ close_tun_generic (struct tuntap *tt)
void
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt)
{
+ struct gc_arena gc = gc_new ();
+ int i;
+ for (i = 0; i < tt->options.dns_len; ++i) {
+ android_set_dns(print_in_addr_t(tt->options.dns[i], 0, &gc));
+ }
+ if(tt->options.domain)
+ android_set_domain(tt->options.domain);
tt->fd = android_open_tun();
}
diff --git a/openvpn/src/openvpn/tun.h b/openvpn/src/openvpn/tun.h
index 63ab8721..6754c726 100644
--- a/openvpn/src/openvpn/tun.h
+++ b/openvpn/src/openvpn/tun.h
@@ -38,7 +38,7 @@
#include "proto.h"
#include "misc.h"
-#ifdef WIN32
+#if defined(WIN32) || defined(TARGET_ANDROID)
#define TUN_ADAPTER_INDEX_INVALID ((DWORD)-1)
@@ -76,6 +76,7 @@ struct tuntap_options {
int netbios_node_type; /* NBT 1,2,4,8 (46) */
+
#define N_DHCP_ADDR 4 /* Max # of addresses allowed for
DNS, WINS, etc. */
diff --git a/res/layout/basic_settings.xml b/res/layout/basic_settings.xml
index 4e6f549f..f6673491 100644
--- a/res/layout/basic_settings.xml
+++ b/res/layout/basic_settings.xml
@@ -212,60 +212,10 @@
style="@style/item"/>
</LinearLayout>
- <CheckBox
- android:id="@+id/show_advanced"
- style="@style/item"
- android:text="@string/show_advanced" />
-
- <LinearLayout
- android:id="@+id/advanced_options"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone" >
+
- <CheckBox
- android:id="@+id/useTLSAuth"
- style="@style/item"
- android:text="@string/useTLSAuth" />
-
- <LinearLayout
- android:id="@+id/tlsauth_options"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"
- android:layout_marginLeft="20sp" >
-
- <de.blinkt.openvpn.FileSelectLayout
- android:id="@+id/tlsAuth"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- blinkt:title="@string/tlsauth" />
-
- <TextView
- style="@style/item"
- android:text="@string/tls_direction"
- android:textAppearance="?android:attr/textAppearanceSmall" />
-
-
- <Spinner
- android:id="@+id/tls_direction"
- style="@style/item"
- android:entries="@array/tls_directions"
- android:prompt="@string/tls_direction" />
- </LinearLayout>
- </LinearLayout>
-
- <Button
- android:id="@+id/connect"
- style="@style/item"
- android:text="@string/connect" />
-
- <Button
- android:id="@+id/about"
- style="@style/item"
- android:text="@string/about" />
+
+
</LinearLayout>
</ScrollView> \ No newline at end of file
diff --git a/res/values-de/arrays.xml b/res/values-de/arrays.xml
index 4c09d9e3..80244f3f 100644
--- a/res/values-de/arrays.xml
+++ b/res/values-de/arrays.xml
@@ -1,12 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <string-array name="vpn_types">
- <item>Zertifikate</item>
- <item>PKCS12 Datei</item>
- <item>Android Keystore </item>
- <!-- <item>Shared Secret</item> -->
- </string-array>
-
<string-array name="tls_directions">
<item>0</item>
<item>1</item>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 41d523e3..51b727e4 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -23,5 +23,12 @@
<item>Unspecified</item>
</string-array>
+ <string-array name="tls_directions_entries">
+ <item>0</item>
+ <item>1</item>
+ <item>GNA</item>
+ </string-array>
+
+
</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ee2a4113..89159094 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -97,6 +97,8 @@
<string name="add_profile_name_prompt">Enter a name identifying the new Profile</string>
<string name="duplicate_profile_name">Duplicate Profile Name</string>
<string name="profilename">Profile Name</string>
-
-
+ <string name="no_keystore_cert_selected">No User certificate selected.</string>
+ <string name="no_error_found">No error found</string>
+ <string name="config_error_found">Error in Configuration</string>
+ <string name="config_error_message">An error has been found in your VPN configuration:</string>
</resources>
diff --git a/res/xml/vpn_authentification.xml b/res/xml/vpn_authentification.xml
index 3781211f..0444831b 100644
--- a/res/xml/vpn_authentification.xml
+++ b/res/xml/vpn_authentification.xml
@@ -12,8 +12,29 @@
<EditTextPreference
android:dependency="checkRemoteCN"
- android:dialogMessage="Enter the String against which the remote Server is checked. Openvpn will use prefix matching. &quot;Server&quot; matches &quot;Server-1&quot; and &quot;Server-2&quot;"
- android:title="Remote Hostname(CN)"
- android:key="remotecn"/>
+ android:dialogMessage="Enter the String against which the remote Server is checked. Openvpn will use prefix matching. &quot;Server&quot; matches &quot;Server-1&quot; and &quot;Server-2&quot;\nLeave empty to check the CN against the server hostname."
+ android:key="remotecn"
+ android:title="Remote Hostname(CN)" />
+
+ <PreferenceCategory android:title="TLS Authentication" >
+ <SwitchPreference
+ android:key="useTLSAuth"
+ android:summary="Enables the TLS Key Authentication"
+ android:title="@string/useTLSAuth" />
+
+ <Preference
+ android:dependency="useTLSAuth"
+ android:key="tlsAuthFile"
+ android:title="Title Auth File" />
+
+ <ListPreference
+ android:dependency="useTLSAuth"
+ android:dialogMessage="Select the direction for TLS Auth."
+ android:entries="@array/tls_directions"
+ android:entryValues="@array/tls_directions_entries"
+ android:key="tls_direction"
+ android:title="TLS Direction"
+ android:persistent="false"/>
+ </PreferenceCategory>
</PreferenceScreen> \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/BasicSettings.java b/src/de/blinkt/openvpn/BasicSettings.java
index e80651e5..7c39eb94 100644
--- a/src/de/blinkt/openvpn/BasicSettings.java
+++ b/src/de/blinkt/openvpn/BasicSettings.java
@@ -19,6 +19,7 @@ package de.blinkt.openvpn;
import java.util.HashMap;
import android.app.Fragment;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
@@ -31,15 +32,16 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;
+
+import com.lamerman.FileDialog;
+
import de.blinkt.openvpn.R.id;
-public class BasicSettings extends Fragment implements View.OnClickListener, OnItemSelectedListener, Callback, OnCheckedChangeListener {
+public class BasicSettings extends Fragment implements View.OnClickListener, OnItemSelectedListener, Callback {
private static final int CHOOSE_FILE_OFFSET = 1000;
private static final int UPDATE_ALIAS = 20;
@@ -60,20 +62,12 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
private Handler mHandler;
- private CheckBox mUseTlsAuth;
-
-
- private CheckBox mShowAdvanced;
-
- private FileSelectLayout mTlsFile;
+
private HashMap<Integer, FileSelectLayout> fileselects = new HashMap<Integer, FileSelectLayout>();
- private Spinner mTLSDirection;
-
-
private EditText mUserName;
@@ -91,7 +85,7 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
private void addFileSelectLayout (FileSelectLayout fsl) {
int i = fileselects.size() + CHOOSE_FILE_OFFSET;
fileselects.put(i, fsl);
- fsl.setActivity(getActivity(),i);
+ fsl.setFragment(this,i);
}
@@ -120,11 +114,7 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
mType = (Spinner) mView.findViewById(R.id.type);
mPKCS12Password = (TextView) mView.findViewById(R.id.pkcs12password);
mAliasName = (TextView) mView.findViewById(R.id.aliasname);
- mUseTlsAuth = (CheckBox) mView.findViewById(R.id.useTLSAuth);
- mTLSDirection = (Spinner) mView.findViewById(R.id.tls_direction);
- mShowAdvanced = (CheckBox) mView.findViewById(R.id.show_advanced);
- mTlsFile = (FileSelectLayout) mView.findViewById(R.id.tlsAuth);
mUserName = (EditText) mView.findViewById(R.id.auth_username);
mPassword = (EditText) mView.findViewById(R.id.auth_password);
@@ -134,20 +124,14 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
addFileSelectLayout(mCaCert);
addFileSelectLayout(mClientCert);
addFileSelectLayout(mClientKey);
- addFileSelectLayout(mTlsFile);
addFileSelectLayout(mpkcs12);
loadPreferences();
mType.setOnItemSelectedListener(this);
- mShowAdvanced.setOnCheckedChangeListener(this);
- mUseTlsAuth.setOnCheckedChangeListener(this);
-
-
mView.findViewById(R.id.select_keystore_button).setOnClickListener(this);
- mView.findViewById(R.id.about).setOnClickListener(this);
- mView.findViewById(R.id.connect).setOnClickListener(this);
+
if (mHandler == null) {
mHandler = new Handler(this);
@@ -155,6 +139,18 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
return mView;
}
+
+
+ @Override
+ public void onActivityResult(int request, int result, Intent data) {
+ if (request >= CHOOSE_FILE_OFFSET) {
+ String filepath = data.getStringExtra(FileDialog.RESULT_PATH);
+ FileSelectLayout fsl = fileselects.get(request);
+ fsl.setData(filepath);
+ }
+ savePreferences();
+ }
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
@@ -213,18 +209,11 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
mpkcs12.setData(mProfile.mPKCS12Filename);
mPKCS12Password.setText(mProfile.mPKCS12Password);
- mUseTlsAuth.setChecked(mProfile.mUseTLSAuth);
- onCheckedChanged(mUseTlsAuth,mUseTlsAuth.isChecked());
-
- mTlsFile.setData(mProfile.mTLSAuthFilename);
- mTLSDirection.setSelection(mProfile.mTLSAuthDirection);
setAlias();
}
void savePreferences() {
- // We need an Editor object to make preference changes.
- // All objects are from android.context.Context
mProfile.mName = mProfileName.getText().toString();
mProfile.mCaFilename = mCaCert.getData();
@@ -239,10 +228,7 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
mProfile.mAuthenticationType = mType.getSelectedItemPosition();
mProfile.mPKCS12Filename = mpkcs12.getData();
mProfile.mPKCS12Password = mPKCS12Password.getText().toString();
- mProfile.mUseTLSAuth =mUseTlsAuth.isChecked();
- mProfile.mTLSAuthFilename= mTlsFile.getData();
- mProfile.mTLSAuthDirection =mTLSDirection.getSelectedItemPosition();
- // Commit the edits!
+
}
@@ -295,19 +281,4 @@ public class BasicSettings extends Fragment implements View.OnClickListener, OnI
}
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- int visibility;
- if(isChecked)
- visibility =View.VISIBLE;
- else
- visibility =View.GONE;
-
- if(buttonView==mShowAdvanced) {
- mView.findViewById(R.id.advanced_options).setVisibility(visibility);
- } else if (buttonView == mUseTlsAuth) {
- mView.findViewById(R.id.tlsauth_options).setVisibility(visibility);
- }
-
- }
}
diff --git a/src/de/blinkt/openvpn/FileSelectLayout.java b/src/de/blinkt/openvpn/FileSelectLayout.java
index 71fd0fe4..2eba9515 100644
--- a/src/de/blinkt/openvpn/FileSelectLayout.java
+++ b/src/de/blinkt/openvpn/FileSelectLayout.java
@@ -1,6 +1,6 @@
package de.blinkt.openvpn;
-import android.app.Activity;
+import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
@@ -17,7 +17,7 @@ import com.lamerman.SelectionMode;
public class FileSelectLayout extends LinearLayout implements OnClickListener {
private TextView mData;
- private Activity mActivity;
+ private Fragment mFragment;
private int mTaskId;
private Button mSelectButton;
@@ -38,10 +38,10 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
}
- public void setActivity(Activity a, int i)
+ public void setFragment(Fragment fragment, int i)
{
mTaskId = i;
- mActivity = a;
+ mFragment = fragment;
}
public void getCertificateFileDialog() {
@@ -49,7 +49,7 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
startFC.putExtra(FileDialog.START_PATH, "/sdcard");
startFC.putExtra(FileDialog.SELECTION_MODE, SelectionMode.MODE_OPEN);
- mActivity.startActivityForResult(startFC,mTaskId);
+ mFragment.startActivityForResult(startFC,mTaskId);
}
@@ -70,5 +70,4 @@ public class FileSelectLayout extends LinearLayout implements OnClickListener {
}
-
}
diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java
index a26da2ba..6c3e1ff7 100644
--- a/src/de/blinkt/openvpn/LogWindow.java
+++ b/src/de/blinkt/openvpn/LogWindow.java
@@ -1,37 +1,150 @@
package de.blinkt.openvpn;
+import java.util.Vector;
+
import android.app.ListActivity;
+import android.database.DataSetObserver;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.Message;
import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ArrayAdapter;
+import android.view.ViewGroup;
+import android.widget.ListAdapter;
import android.widget.ListView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+import de.blinkt.openvpn.OpenVPN.LogListener;
+
+public class LogWindow extends ListActivity {
+
+ class LogWindowListAdapter implements ListAdapter,LogListener, Callback {
+
+ private static final int LIST_CHANGED = 0;
+
+ private Vector<String> myEntries=new Vector<String>();
+
+ private Handler mHandler;
+
+ private Vector<DataSetObserver> observers=new Vector<DataSetObserver>();
+
+ public LogWindowListAdapter() {
+ for (String litem : OpenVPN.getlogbuffer()) {
+ myEntries.add(litem);
+ }
+
+ if (mHandler == null) {
+ mHandler = new Handler(this);
+ }
+
+ OpenVPN.addLogListener(this);
+ }
+
+ @Override
+ public void registerDataSetObserver(DataSetObserver observer) {
+ observers.add(observer);
+
+ }
+
+ @Override
+ public void unregisterDataSetObserver(DataSetObserver observer) {
+ observers.remove(observer);
+ }
+
+ @Override
+ public int getCount() {
+ return myEntries.size();
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return myEntries.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return true;
+ }
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView v;
+ if(convertView==null)
+ v = new TextView(getBaseContext());
+ else
+ v = (TextView) convertView;
+ v.setText(myEntries.get(position));
+ return v;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return 0;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+ @Override
+ public boolean isEmpty() {
+ return myEntries.isEmpty();
+
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return true;
+ }
+
+ @Override
+ public void newLog(String logmessage) {
+ Message msg = Message.obtain();
+ Bundle mbundle=new Bundle();
+ mbundle.putString("logmessage", logmessage);
+ msg.setData(mbundle);
+ mHandler.sendMessage(msg);
+ }
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ // We have been called
+ String logmessage = msg.getData().getString("logmessage");
+ myEntries.add(logmessage);
+
+ for (DataSetObserver observer : observers) {
+ observer.onChanged();
+ }
+
+
+ return true;
+ }
+
+ }
-public class LogWindow extends ListActivity implements OnItemClickListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- //setListAdapter(new ArrayAdapter<String>(this, R.layout.log_entry, COUNTRIES));
- setListAdapter(new ArrayAdapter<String>(this, R.layout.log_entry, OpenVPN.getlogbuffer()));
- //setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, OpenVPN.logbuffer));
-
+
ListView lv = getListView();
- lv.setTextFilterEnabled(true);
+ //lv.setTextFilterEnabled(true);
+ LogWindowListAdapter adapter = new LogWindowListAdapter();
+ lv.setAdapter(adapter);
- lv.setOnItemClickListener(this);
}
+
+
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // When clicked, show a toast with the TextView text
- //Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
- //Toast.LENGTH_SHORT).show();
-
- setListAdapter(new ArrayAdapter<String>(this, R.layout.log_entry, OpenVPN.getlogbuffer()));
- }
}
diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java
index b49bdf68..bca276c9 100644
--- a/src/de/blinkt/openvpn/OpenVPN.java
+++ b/src/de/blinkt/openvpn/OpenVPN.java
@@ -1,6 +1,7 @@
package de.blinkt.openvpn;
import java.util.LinkedList;
+import java.util.Vector;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -17,6 +18,11 @@ public class OpenVPN {
public static LinkedList<String> logbuffer = new LinkedList<String>();
private static int counter=0;
+ private static Vector<LogListener> logListener=new Vector<OpenVPN.LogListener>();
+
+ public interface LogListener {
+ void newLog(String logmessage);
+ }
static {
System.loadLibrary("crypto");
@@ -40,6 +46,19 @@ public class OpenVPN {
// Force GC how and then to kill loose ends
if(counter++ % 50==0)
System.gc();
+
+ for (LogListener ll : logListener) {
+ ll.newLog(prefix + " " + message);
+ }
+
+ }
+
+ synchronized static void addLogListener(LogListener ll){
+ logListener.add(ll);
+ }
+
+ synchronized static void removeLogListener(LogListener ll) {
+ logListener.remove(ll);
}
@@ -48,6 +67,18 @@ public class OpenVPN {
Log.i("openvpn","Got interface info M" + mtu + " L: " + local + "R: " + remote);
localip=local;
}
+
+ static void addDns(String dns) {
+ Log.i("openvpn","Got DNS Server: " + dns);
+ mOpenVpnService.addDNS(dns);
+ }
+
+
+ static void addDomain(String domain) {
+ Log.i("openvpn","Got DNS Domain: " + domain);
+ mOpenVpnService.setDomain(domain);
+ }
+
public static void setCallback(OpenVpnService openVpnService) {
mOpenVpnService = openVpnService;
diff --git a/src/de/blinkt/openvpn/OpenVPNClient.java b/src/de/blinkt/openvpn/OpenVPNClient.java
deleted file mode 100644
index db6dd95a..00000000
--- a/src/de/blinkt/openvpn/OpenVPNClient.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package de.blinkt.openvpn;
-
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.cert.X509Certificate;
-import java.util.HashMap;
-
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.VpnService;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Handler.Callback;
-import android.os.Message;
-import android.security.KeyChain;
-import android.security.KeyChainAliasCallback;
-import android.util.Log;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.ToggleButton;
-
-import com.lamerman.FileDialog;
-
-import de.blinkt.openvpn.R.id;
-
-public class OpenVPNClient extends Activity implements View.OnClickListener, OnItemSelectedListener, Callback, OnCheckedChangeListener {
- private static final String TAG = "OpenVpnClient";
-
-
- private static final int START_OPENVPN = 0;
- private static final int CHOOSE_FILE_OFFSET = 1000;
- private static final int UPDATE_ALIAS = 20;
-
- private static final String PREFS_NAME = "OVPN_SERVER";
-
-
-
- private TextView mServerAddress;
- private TextView mServerPort;
- private FileSelectLayout mClientCert;
- private FileSelectLayout mCaCert;
- private FileSelectLayout mClientKey;
- private TextView mAliasName;
- private CheckBox mUseLzo;
- private ToggleButton mTcpUdp;
- private Spinner mType;
- private String certalias;
- private FileSelectLayout mpkcs12;
- private TextView mPKCS12Password;
-
- private Handler mHandler;
-
-
- private CheckBox mUseTlsAuth;
-
-
- private CheckBox mShowAdvanced;
-
-
- private FileSelectLayout mTlsFile;
-
- private HashMap<Integer, FileSelectLayout> fileselects = new HashMap<Integer, FileSelectLayout>();
-
-
- private Spinner mTLSDirection;
-
-
- private EditText mUserName;
-
-
- private EditText mPassword;
-
- @Override
- protected void onStop(){
- super.onStop();
- savePreferences();
- }
-
-
-
- private void addFileSelectLayout (FileSelectLayout fsl) {
- int i = fileselects.size() + CHOOSE_FILE_OFFSET;
- fileselects.put(i, fsl);
- fsl.setActivity(this,i);
- }
-
-
-
-
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.basic_settings);
-
- // Forces early JNI Load
- OpenVPN.foo();
-
- mServerAddress = (TextView) findViewById(R.id.address);
- mServerPort = (TextView) findViewById(R.id.port);
- mClientCert = (FileSelectLayout) findViewById(R.id.certselect);
- mClientKey = (FileSelectLayout) findViewById(R.id.keyselect);
- mCaCert = (FileSelectLayout) findViewById(R.id.caselect);
- mpkcs12 = (FileSelectLayout) findViewById(R.id.pkcs12select);
- mUseLzo = (CheckBox) findViewById(R.id.lzo);
- mTcpUdp = (ToggleButton) findViewById(id.tcpudp);
- mType = (Spinner) findViewById(R.id.type);
- mPKCS12Password = (TextView) findViewById(R.id.pkcs12password);
- mAliasName = (TextView) findViewById(R.id.aliasname);
- mUseTlsAuth = (CheckBox) findViewById(R.id.useTLSAuth);
- mTLSDirection = (Spinner) findViewById(R.id.tls_direction);
-
- mShowAdvanced = (CheckBox) findViewById(R.id.show_advanced);
- mTlsFile = (FileSelectLayout) findViewById(R.id.tlsAuth);
- mUserName = (EditText) findViewById(R.id.auth_username);
- mPassword = (EditText) findViewById(R.id.auth_password);
-
-
- addFileSelectLayout(mCaCert);
- addFileSelectLayout(mClientCert);
- addFileSelectLayout(mClientKey);
- addFileSelectLayout(mTlsFile);
- addFileSelectLayout(mpkcs12);
-
- loadPreferences();
-
- mType.setOnItemSelectedListener(this);
-
- mShowAdvanced.setOnCheckedChangeListener(this);
- mUseTlsAuth.setOnCheckedChangeListener(this);
-
-
- findViewById(R.id.select_keystore_button).setOnClickListener(this);
- findViewById(R.id.about).setOnClickListener(this);
- findViewById(R.id.connect).setOnClickListener(this);
-
- if (mHandler == null) {
- mHandler = new Handler(this);
- }
- }
-
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- if (parent == mType) {
- changeType(position);
- }
- }
-
-
-
- private void changeType(int type){
- // hide everything
- findViewById(R.id.pkcs12).setVisibility(View.GONE);
- findViewById(R.id.certs).setVisibility(View.GONE);
- findViewById(R.id.statickeys).setVisibility(View.GONE);
- findViewById(R.id.keystore).setVisibility(View.GONE);
-
- switch(type) {
- case VpnProfile.TYPE_CERTIFICATES:
- findViewById(R.id.certs).setVisibility(View.VISIBLE);
- break;
- case VpnProfile.TYPE_PKCS12:
- findViewById(R.id.pkcs12).setVisibility(View.VISIBLE);
- break;
- case VpnProfile.TYPE_STATICKEYS:
- findViewById(R.id.statickeys).setVisibility(View.VISIBLE);
- break;
- case VpnProfile.TYPE_KEYSTORE:
- findViewById(R.id.keystore).setVisibility(View.VISIBLE);
- break;
-
- case VpnProfile.TYPE_USERPASS:
- findViewById(R.id.userpassword).setVisibility(View.VISIBLE);
- }
-
-
- }
-
- private void loadPreferences() {
- SharedPreferences settings = getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE);
-
- mClientCert.setData(settings.getString("clientcert", ""));
- mClientKey.setData(settings.getString("clientkey", ""));
- mCaCert.setData(settings.getString("ca", ""));
-
- mUseLzo.setChecked(settings.getBoolean("useLzo", true));
- mServerPort.setText(settings.getString("port", "1194"));
- mServerAddress.setText(settings.getString("server", "openvpn.blinkt.de"));
- mTcpUdp.setChecked(settings.getBoolean("udp", true));
- mType.setSelection(settings.getInt("type", VpnProfile.TYPE_PKCS12));
- mpkcs12.setData(settings.getString("pkcs12file", ""));
- mPKCS12Password.setText(settings.getString("pkcs12password", ""));
- certalias = settings.getString("alias", null);
- mUseTlsAuth.setChecked(settings.getBoolean("tlsauth", false));
- onCheckedChanged(mUseTlsAuth,mUseTlsAuth.isChecked());
-
- mTlsFile.setData(settings.getString("tlsfile",""));
- mTLSDirection.setSelection(settings.getInt("tls-direction", 2)); // Unspecified
- setAlias();
-
- }
-
- private void savePreferences() {
- // We need an Editor object to make preference changes.
- // All objects are from android.context.Context
- SharedPreferences settings = getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE);
- SharedPreferences.Editor editor = settings.edit();
-
-
- editor.putString("ca" , mCaCert.getData());
- editor.putString("clientcert", mClientCert.getData());
- editor.putString("clientkey", mClientKey.getData());
-
- editor.putBoolean("useLzo",mUseLzo.isChecked());
- editor.putString("port", mServerPort.getText().toString());
- editor.putString("server", mServerAddress.getText().toString());
- editor.putBoolean("udp", mTcpUdp.isChecked());
-
- editor.putInt("type",mType.getSelectedItemPosition());
- editor.putString("pkcs12file", mpkcs12.getData());
- editor.putString("pkcs12password", mPKCS12Password.getText().toString());
- editor.putString("alias", certalias);
- editor.putBoolean("tlsauth", mUseTlsAuth.isChecked());
- editor.putString("tlsfile", mTlsFile.getData());
- editor.putInt("tls-direction", mTLSDirection.getSelectedItemPosition());
- // Commit the edits!
- editor.commit();
- }
-
-
- private void setAlias() {
- if(certalias == null) {
- mAliasName.setText(R.string.client_no_certificate);
- } else {
- mAliasName.setText(certalias);
- }
- }
-
- public void showCertDialog () {
- KeyChain.choosePrivateKeyAlias(this,
- new KeyChainAliasCallback() {
-
- public void alias(String alias) {
- // Credential alias selected. Remember the alias selection for future use.
- certalias=alias;
- mHandler.sendEmptyMessage(UPDATE_ALIAS);
- }
-
-
- },
- new String[] {"RSA", "DSA"}, // List of acceptable key types. null for any
- null, // issuer, null for any
- "internal.example.com", // host name of server requesting the cert, null if unavailable
- 443, // port of server requesting the cert, -1 if unavailable
- null); // alias to preselect, null if unavailable
- }
-
-
-
- public void testGetallCerts() throws NoSuchAlgorithmException, KeyStoreException {
- TrustManagerFactory tmf = TrustManagerFactory
- .getInstance(TrustManagerFactory.getDefaultAlgorithm());
-
- tmf.init((KeyStore) null);
- X509TrustManager xtm = (X509TrustManager) tmf.getTrustManagers()[0];
-
- X509Certificate[] foo = xtm.getAcceptedIssuers();
- for (X509Certificate cert : xtm.getAcceptedIssuers()) {
- String certStr = "S:" + cert.getSubjectDN().getName() + "\nI:"
- + cert.getIssuerDN().getName();
- Log.d(TAG, certStr);
- }
- System.out.println(foo);
- }
-
- @Override
- public void onClick(View v) {
- if(v == findViewById(R.id.connect)) {
- Intent intent = VpnService.prepare(this);
- if (intent != null) {
- startActivityForResult(intent, 0);
- } else {
- onActivityResult(START_OPENVPN, RESULT_OK, null);
- }
- } else if (v == findViewById(R.id.about)) {
- //Intent intent = new Intent(getBaseContext(),AboutActivity.class);
- Intent intent = new Intent(getBaseContext(),VPNPreferences.class);
- intent.putExtra("foo","der bar war hier!");
- startActivity(intent);
- } else if (v == findViewById(R.id.select_keystore_button)) {
- showCertDialog();
- }
- }
-
-
-
- /* (non-Javadoc)
- * @see android.app.Activity#onActivityResult(int, int, android.content.Intent)
- */
- @Override
- protected void onActivityResult(int request, int result, Intent data) {
- if (request== START_OPENVPN) {
- if (result == RESULT_OK) {
- // It always crashes and never saves ;)
- savePreferences();
- new startOpenVpnThread().start();
- }
-
- } else if (request >= CHOOSE_FILE_OFFSET) {
- String filepath = data.getStringExtra(FileDialog.RESULT_PATH);
- FileSelectLayout fsl = fileselects.get(request);
- fsl.setData(filepath);
- }
- savePreferences();
- }
-
-
-
- private class startOpenVpnThread extends Thread {
-
- @Override
- public void run() {
- // startOpenVpn();
- }
-
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- }
-
-
- @Override
- public boolean handleMessage(Message msg) {
- setAlias();
- return true;
- }
-
-
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- int visibility;
- if(isChecked)
- visibility =View.VISIBLE;
- else
- visibility =View.GONE;
-
- if(buttonView==mShowAdvanced) {
- findViewById(R.id.advanced_options).setVisibility(visibility);
- } else if (buttonView == mUseTlsAuth) {
- findViewById(R.id.tlsauth_options).setVisibility(visibility);
- }
- }
-}
diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java
index 4aad9318..1cc5b2ec 100644
--- a/src/de/blinkt/openvpn/OpenVpnService.java
+++ b/src/de/blinkt/openvpn/OpenVpnService.java
@@ -19,6 +19,7 @@ package de.blinkt.openvpn;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.Arrays;
+import java.util.Vector;
import android.app.PendingIntent;
import android.content.Intent;
@@ -41,6 +42,12 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
private ParcelFileDescriptor mInterface;
+ private Vector<String> mDnslist=new Vector<String>();
+
+ private VpnProfile mProfile;
+
+ private String mDomain=null;
+
@Override
public void onRevoke() {
managmentCommand("signal SIGINT\n");
@@ -106,6 +113,9 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
mThread = new Thread(this, "OpenVPNThread");
mThread.start();
+ String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
+ mProfile = ProfileManager.get(profileUUID);
+
if(intent.hasExtra(prefix +".PKCS12PASS"))
{
try {
@@ -211,9 +221,14 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
Builder builder = new Builder();
builder.addRoute("0.0.0.0", 0);
builder.addAddress(localip, 24 );
- builder.addDnsServer("131.234.137.23");
- builder.addSearchDomain("blinkt.de");
- builder.setSession("OpenVPN - " + localip);
+ for (String dns : mDnslist ) {
+ builder.addDnsServer(dns);
+ }
+
+ if(mDomain!=null)
+ builder.addSearchDomain(mDomain);
+
+ builder.setSession(mProfile.mName + " - " + localip);
Intent intent = new Intent(getBaseContext(),LogWindow.class);
PendingIntent startLW = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
builder.setConfigureIntent(startLW);
@@ -221,4 +236,16 @@ public class OpenVpnService extends VpnService implements Handler.Callback, Runn
return mInterface;
}
+
+
+ public void addDNS(String dns) {
+ mDnslist.add(dns);
+ }
+
+
+ public void setDomain(String domain) {
+ if(mDomain==null) {
+ mDomain=domain;
+ }
+ }
}
diff --git a/src/de/blinkt/openvpn/ProfileManager.java b/src/de/blinkt/openvpn/ProfileManager.java
index 078403e1..5e6b7912 100644
--- a/src/de/blinkt/openvpn/ProfileManager.java
+++ b/src/de/blinkt/openvpn/ProfileManager.java
@@ -3,6 +3,7 @@ package de.blinkt.openvpn;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.Collection;
import java.util.HashMap;
@@ -66,6 +67,28 @@ public class ProfileManager {
profiles.put(profile.getUUID().toString(),profile);
}
+
+
+ public void saveProfile(Context context,VpnProfile profile) {
+ // First let basic settings save its state
+
+ ObjectOutputStream vpnfile;
+ try {
+ vpnfile = new ObjectOutputStream(context.openFileOutput((profile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE));
+
+ vpnfile.writeObject(profile);
+ vpnfile.flush();
+ vpnfile.close();
+ } catch (FileNotFoundException e) {
+
+ e.printStackTrace();
+ } catch (IOException e) {
+
+ e.printStackTrace();
+ }
+ }
+
+
void loadVPNList(Context context) {
profiles = new HashMap<String, VpnProfile>();
SharedPreferences settings =context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE);
diff --git a/src/de/blinkt/openvpn/Settings_Authentication.java b/src/de/blinkt/openvpn/Settings_Authentication.java
index 1f96c6ca..f3ebb36d 100644
--- a/src/de/blinkt/openvpn/Settings_Authentication.java
+++ b/src/de/blinkt/openvpn/Settings_Authentication.java
@@ -1,17 +1,29 @@
package de.blinkt.openvpn;
+import com.lamerman.FileDialog;
+import com.lamerman.SelectionMode;
+
+import android.app.Activity;
+import android.content.Intent;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
+import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
+import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
+import android.preference.SwitchPreference;
-public class Settings_Authentication extends PreferenceFragment implements OnPreferenceChangeListener {
+public class Settings_Authentication extends PreferenceFragment implements OnPreferenceChangeListener, OnPreferenceClickListener {
+ private static final int SELECT_TLS_FILE = 23223232;
private CheckBoxPreference mExpectTLSCert;
private CheckBoxPreference mCheckRemoteCN;
private EditTextPreference mRemoteCN;
private VpnProfile mProfile;
+ private ListPreference mTLSAuthDirection;
+ private Preference mTLSAuthFile;
+ private SwitchPreference mUseTLSAuth;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -24,9 +36,15 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre
mCheckRemoteCN = (CheckBoxPreference) findPreference("checkRemoteCN");
mRemoteCN = (EditTextPreference) findPreference("remotecn");
mRemoteCN.setOnPreferenceChangeListener(this);
+
+ mUseTLSAuth = (SwitchPreference) findPreference("useTLSAuth" );
+ mTLSAuthFile = findPreference("tlsAuthFile");
+ mTLSAuthDirection = (ListPreference) findPreference("tls_direction");
+
String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID");
mProfile = ProfileManager.get(profileUUID);
-
+ mTLSAuthFile.setOnPreferenceClickListener(this);
+
loadSettings();
}
@@ -38,12 +56,26 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre
mRemoteCN.setText(mProfile.mRemoteCN);
onPreferenceChange(mRemoteCN, mProfile.mRemoteCN);
+ mUseTLSAuth.setChecked(mProfile.mUseTLSAuth);
+ mTLSAuthFile.setSummary(mProfile.mTLSAuthFilename);
+ //mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection);
}
private void saveSettings() {
mProfile.mExpectTLSCert=mExpectTLSCert.isChecked();
mProfile.mCheckRemoteCN=mCheckRemoteCN.isChecked();
mProfile.mRemoteCN=mRemoteCN.getText();
+
+ mProfile.mUseTLSAuth = mUseTLSAuth.isChecked();
+ if(mTLSAuthFile.getSummary()==null)
+ mProfile.mTLSAuthFilename=null;
+ else
+ mProfile.mTLSAuthFilename = mTLSAuthFile.getSummary().toString();
+
+ if(mTLSAuthDirection.getEntry()==null)
+ mProfile.mTLSAuthDirection=null;
+ else
+ mProfile.mTLSAuthDirection = mTLSAuthDirection.getEntry().toString();
}
@Override
@@ -60,7 +92,29 @@ public class Settings_Authentication extends PreferenceFragment implements OnPre
else
preference.setSummary((String)newValue);
}
- saveSettings();
return true;
}
+ void startFileDialog() {
+ Intent startFC = new Intent(getActivity(),FileDialog.class);
+ startFC.putExtra(FileDialog.START_PATH, "/sdcard");
+ startFC.putExtra(FileDialog.SELECTION_MODE, SelectionMode.MODE_OPEN);
+
+ startActivityForResult(startFC,SELECT_TLS_FILE);
+ }
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ startFileDialog();
+ return true;
+
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if(requestCode==SELECT_TLS_FILE && resultCode == Activity.RESULT_OK){
+ String filepath = data.getStringExtra(FileDialog.RESULT_PATH);
+ mTLSAuthFile.setSummary(filepath);
+
+ }
+ }
} \ No newline at end of file
diff --git a/src/de/blinkt/openvpn/Settings_IP.java b/src/de/blinkt/openvpn/Settings_IP.java
index a1bb16e0..c2b1ed71 100644
--- a/src/de/blinkt/openvpn/Settings_IP.java
+++ b/src/de/blinkt/openvpn/Settings_IP.java
@@ -120,6 +120,10 @@ public class Settings_IP extends PreferenceFragment implements OnPreferenceChang
preference.setSummary((String)newValue);
if(preference== mUsePull || preference == mOverrideDNS)
+ if(preference==mOverrideDNS)
+ // Set so the function gets the right value
+ mOverrideDNS.setChecked((Boolean) newValue);
+
setDNSState();
saveSettings();
diff --git a/src/de/blinkt/openvpn/VPNConfigPreference.java b/src/de/blinkt/openvpn/VPNConfigPreference.java
index aebc8bc0..d1a3346e 100644
--- a/src/de/blinkt/openvpn/VPNConfigPreference.java
+++ b/src/de/blinkt/openvpn/VPNConfigPreference.java
@@ -1,6 +1,5 @@
package de.blinkt.openvpn;
-import android.os.Bundle;
import android.preference.Preference;
import android.view.View;
import android.view.View.OnClickListener;
@@ -25,7 +24,7 @@ public class VPNConfigPreference extends Preference implements OnClickListener {
private ImageView mQuickPrefButton;
- public VPNConfigPreference(VPNProfileList vpnProfileList, Bundle args) {
+ public VPNConfigPreference(VPNProfileList vpnProfileList) {
super(vpnProfileList.getActivity());
setLayoutResource(R.layout.vpn_preference_layout);
@@ -43,8 +42,6 @@ public class VPNConfigPreference extends Preference implements OnClickListener {
mQuickPrefButton = (ImageView) view.findViewById(R.id.quickedit_settings);
mQuickPrefButton.setOnClickListener(this);
- // Quick Fix, until I know what really goes wrong here :(
- //view.findViewById(android.R.id.widget_frame).setOnClickListener(this);
}
@@ -70,6 +67,6 @@ public class VPNConfigPreference extends Preference implements OnClickListener {
public void onClick(View v) {
mOnQuickSettingsListener.onQuickSettingsClick(this);
}
-
+
}
diff --git a/src/de/blinkt/openvpn/VPNDatabase.java b/src/de/blinkt/openvpn/VPNDatabase.java
deleted file mode 100644
index e69de29b..00000000
--- a/src/de/blinkt/openvpn/VPNDatabase.java
+++ /dev/null
diff --git a/src/de/blinkt/openvpn/VPNPreferences.java b/src/de/blinkt/openvpn/VPNPreferences.java
index 75788d74..4b1c7377 100644
--- a/src/de/blinkt/openvpn/VPNPreferences.java
+++ b/src/de/blinkt/openvpn/VPNPreferences.java
@@ -1,12 +1,7 @@
package de.blinkt.openvpn;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
import java.util.List;
-import android.app.Activity;
-import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.widget.Button;
@@ -14,7 +9,7 @@ import android.widget.Button;
public class VPNPreferences extends PreferenceActivity {
- private VpnProfile mProfile;
+ private String mProfileUUID;
private BasicSettings mBS;
public void setmBS(BasicSettings mBS) {
this.mBS = mBS;
@@ -28,7 +23,8 @@ public class VPNPreferences extends PreferenceActivity {
protected void onPause() {
super.onPause();
- saveSettings();
+ if(mBS!=null)
+ mBS.savePreferences();
}
@@ -39,43 +35,11 @@ public class VPNPreferences extends PreferenceActivity {
};
- private void saveSettings() {
- // First let basic settings save its state
- if(mBS!=null)
- mBS.savePreferences();
-
- ObjectOutputStream vpnfile;
- try {
- vpnfile = new ObjectOutputStream(openFileOutput((mProfile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE));
-
- vpnfile.writeObject(mProfile);
- vpnfile.flush();
- vpnfile.close();
- } catch (FileNotFoundException e) {
-
- e.printStackTrace();
- } catch (IOException e) {
-
- e.printStackTrace();
- }
- }
-
- @Override
- protected void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putSerializable(getPackageName() + ".VpnProfile",mProfile);
- }
-
- @Override
- protected void onRestoreInstanceState(Bundle state) {
- super.onRestoreInstanceState(state);
- mProfile = (VpnProfile) state.getSerializable(getPackageName() + ".VpnProfile");
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
- mProfile = (VpnProfile) getIntent().getSerializableExtra(getPackageName() + ".VpnProfile");
+ // profileUUID
+ mProfileUUID = getIntent().getStringExtra(getPackageName() + ".profileUUID");
super.onCreate(savedInstanceState);
@@ -94,11 +58,14 @@ public class VPNPreferences extends PreferenceActivity {
for (Header header : target) {
if(header.fragmentArguments==null)
header.fragmentArguments = new Bundle();
- header.fragmentArguments.putString(getPackageName() + ".profileUUID",mProfile.getUUID().toString());
- if(header.extras==null)
- header.extras = new Bundle();
- header.extras.putString(getPackageName() + ".profileUUID",mProfile.getUUID().toString());
+ header.fragmentArguments.putString(getPackageName() + ".profileUUID",mProfileUUID);
}
}
+
+ @Override
+ public void onBackPressed() {
+ setResult(RESULT_OK, getIntent());
+ super.onBackPressed();
+ }
}
diff --git a/src/de/blinkt/openvpn/VPNProfileList.java b/src/de/blinkt/openvpn/VPNProfileList.java
index 48c7a7a2..f77c8639 100644
--- a/src/de/blinkt/openvpn/VPNProfileList.java
+++ b/src/de/blinkt/openvpn/VPNProfileList.java
@@ -1,9 +1,5 @@
package de.blinkt.openvpn;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
@@ -24,7 +20,8 @@ import de.blinkt.openvpn.VPNConfigPreference.VpnPreferencesClickListener;
public class VPNProfileList extends PreferenceFragment implements VpnPreferencesClickListener {
private static final int MENU_ADD_PROFILE = Menu.FIRST;
- private static final int START_VPN_PROFILECONFIG = 70;
+ private static final int START_VPN_PROFILE= 70;
+ private static final int START_VPN_CONFIG = 92;
private VpnProfile mSelectedVPN;
@@ -34,17 +31,12 @@ public class VPNProfileList extends PreferenceFragment implements VpnPreference
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.vpn_profile_list);
setHasOptionsMenu(true);
-
- }
-
- @Override
- public void onResume() {
- super.onResume();
refreshList();
-
-
+ // Debug load JNI
+ OpenVPN.foo();
}
+
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.add(0, MENU_ADD_PROFILE, 0, R.string.menu_add_profile)
@@ -109,27 +101,11 @@ public class VPNProfileList extends PreferenceFragment implements VpnPreference
private void addProfile(VpnProfile profile) {
getPM().addProfile(profile);
getPM().saveProfileList(getActivity());
- saveProfile(profile);
+ getPM().saveProfile(getActivity(),profile);
}
- private void saveProfile(VpnProfile profile) {
- ObjectOutputStream vpnfile;
- try {
- vpnfile = new ObjectOutputStream(getActivity().openFileOutput((profile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE));
-
- vpnfile.writeObject(profile);
- vpnfile.flush();
- vpnfile.close();
- } catch (FileNotFoundException e) {
-
- e.printStackTrace();
- } catch (IOException e) {
-
- e.printStackTrace();
- }
- }
@@ -140,19 +116,14 @@ public class VPNProfileList extends PreferenceFragment implements VpnPreference
getPM().loadVPNList(getActivity());
for (VpnProfile vpnprofile: getPM().getProfiles()) {
- Bundle args = new Bundle();
- //TODO
String profileuuid = vpnprofile.getUUID().toString();
- args.putSerializable(getActivity().getPackageName() + ".VpnProfile", vpnprofile);
- //args.putString("name", vpnentry);
- VPNConfigPreference vpref = new VPNConfigPreference(this, args);
+ VPNConfigPreference vpref = new VPNConfigPreference(this);
vpref.setKey(profileuuid);
vpref.setTitle(vpnprofile.getName());
vpref.setPersistent(false);
- // vpref.setSelectable(true);
vpref.setOnQuickSettingsClickListener(this);
plist.addPreference(vpref);
}
@@ -174,9 +145,9 @@ public class VPNProfileList extends PreferenceFragment implements VpnPreference
VpnProfile vprofile = ProfileManager.get(key);
Intent vprefintent = new Intent(getActivity(),VPNPreferences.class)
- .putExtra(getActivity().getPackageName() + ".VpnProfile", vprofile);
+ .putExtra(getActivity().getPackageName() + ".profileUUID", vprofile.getUUID().toString());
- startActivityForResult(vprefintent,START_VPN_PROFILECONFIG);
+ startActivityForResult(vprefintent,START_VPN_CONFIG);
return true;
}
@@ -187,9 +158,16 @@ public class VPNProfileList extends PreferenceFragment implements VpnPreference
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if(requestCode==START_VPN_PROFILECONFIG) {
- new startOpenVpnThread().start();;
+ if(requestCode==START_VPN_PROFILE && resultCode == Activity.RESULT_OK) {
+ new startOpenVpnThread().start();
+
+ } else if (requestCode == START_VPN_CONFIG && resultCode == Activity.RESULT_OK) {
+ String configuredVPN = data.getStringExtra(getActivity().getPackageName() + ".profileUUID");
+ VpnProfile profile = ProfileManager.get(configuredVPN);
+ getPM().saveProfile(getActivity(), profile);
+ // Name could be modified
+ refreshList();
}
}
@@ -202,27 +180,56 @@ public class VPNProfileList extends PreferenceFragment implements VpnPreference
}
void startOpenVpn() {
- Intent startVPN = mSelectedVPN.prepareIntent(getActivity());
-
- getActivity().startService(startVPN);
Intent startLW = new Intent(getActivity().getBaseContext(),LogWindow.class);
startActivity(startLW);
+
+
+ OpenVPN.logMessage(0, "", "Building confugration...");
+
+ Intent startVPN = mSelectedVPN.prepareIntent(getActivity());
+
+ getActivity().startService(startVPN);
getActivity().finish();
+
}
}
+
+ void showConfigErrorDialog(int vpnok) {
+
+ AlertDialog.Builder d = new AlertDialog.Builder(getActivity());
+
+ d.setTitle(R.string.config_error_found);
+
+ d.setMessage(vpnok);
+
+
+ d.setPositiveButton("Ok", null);
+
+ d.show();
+ }
@Override
public void onStartVPNClick(VPNConfigPreference preference) {
+ getPM();
// Query the System for permission
- mSelectedVPN = getPM().get(preference.getKey());
+ mSelectedVPN = ProfileManager.get(preference.getKey());
+
+ int vpnok = mSelectedVPN.checkProfile();
+ if(vpnok!= R.string.no_error_found) {
+ showConfigErrorDialog(vpnok);
+ return;
+ }
+
+
+ getPM().saveProfile(getActivity(), mSelectedVPN);
Intent intent = VpnService.prepare(getActivity());
if (intent != null) {
// Start the query
intent.putExtra("FOO", "WAR BIER");
- startActivityForResult(intent, 0);
+ startActivityForResult(intent, START_VPN_PROFILE);
} else {
- onActivityResult(START_VPN_PROFILECONFIG, Activity.RESULT_OK, null);
+ onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null);
}
}
diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java
index c199cf8b..e17fb8ff 100644
--- a/src/de/blinkt/openvpn/VpnProfile.java
+++ b/src/de/blinkt/openvpn/VpnProfile.java
@@ -46,7 +46,7 @@ public class VpnProfile implements Serializable{
public String mName;
public String mAlias;
public String mClientCertFilename;
- public int mTLSAuthDirection=2;
+ public String mTLSAuthDirection="";
public String mTLSAuthFilename;
public String mClientKeyFilename;
public String mCaFilename;
@@ -84,7 +84,7 @@ public class VpnProfile implements Serializable{
out.writeString(mName);
out.writeString(mAlias);
out.writeString(mClientCertFilename);
- out.writeInt(mTLSAuthDirection);
+ out.writeString(mTLSAuthDirection);
out.writeString(mTLSAuthFilename);
out.writeString(mClientKeyFilename);
out.writeString(mCaFilename);
@@ -103,7 +103,7 @@ public class VpnProfile implements Serializable{
mName = in.readString();
mAlias = in.readString();
mClientCertFilename = in.readString();
- mTLSAuthDirection = in.readInt();
+ mTLSAuthDirection = in.readString();
mTLSAuthFilename = in.readString();
mClientKeyFilename = in.readString();
mCaFilename = in.readString();
@@ -156,7 +156,16 @@ public class VpnProfile implements Serializable{
- cfg+="client\n";
+ boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS);
+
+ if(useTLSClient && mUsePull)
+ cfg+="client\n";
+ else if (mUsePull)
+ cfg+="pull\n";
+ else if(useTLSClient)
+ cfg+="tls-client";
+
+
cfg+="verb 2\n";
@@ -224,14 +233,35 @@ public class VpnProfile implements Serializable{
if(mUseTLSAuth) {
cfg+="tls-auth ";
cfg+=mTLSAuthFilename;
- int tlsdir= mTLSAuthDirection;
- // 2 is unspecified
- if(tlsdir == 0 || tlsdir==1) {
- cfg+=" ";
- cfg+=new Integer(tlsdir).toString();
- }
+ cfg+=" ";
+ cfg+= mTLSAuthDirection;
cfg+="\n";
}
+
+ // Basic Settings
+ if(!mUsePull ) {
+ cfg +="ifconfig " + mIPv4Address + " 255.255.255.255\n";
+ }
+
+ if(mOverrideDNS || !mUsePull) {
+ if(!mDNS1.equals("") && mDNS1!=null)
+ cfg+="dhcp-option DNS " + mDNS1 + "\n";
+ if(!mDNS2.equals("") && mDNS2!=null)
+ cfg+="dhcp-option DNS " + mDNS2 + "\n";
+
+ }
+
+
+
+ // Authentication
+ if(mCheckRemoteCN) {
+ if(mRemoteCN == null || mRemoteCN.equals("") )
+ cfg+="tls-remote " + mServerName + "\n";
+ else
+ cfg += "tls-remote " + mRemoteCN + "\n";
+ }
+ if(mExpectTLSCert)
+ cfg += "remote-cert-tls server\n";
return cfg;
}
@@ -280,6 +310,8 @@ public class VpnProfile implements Serializable{
intent.putExtra(prefix + ".PASSWORD", mPassword);
}
+ intent.putExtra(prefix + ".profileUUID", mUuid.toString());
+
try {
FileWriter cfg = new FileWriter(activity.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE);
cfg.write(getConfigFile(activity.getCacheDir()));
@@ -337,6 +369,16 @@ public class VpnProfile implements Serializable{
return "ERROR";
}
+ //! Return an error if somethign is wrong
+ int checkProfile() {
+ if(mAuthenticationType==TYPE_KEYSTORE && mAlias==null)
+ return R.string.no_keystore_cert_selected;
+
+
+ // Everything okay
+ return R.string.no_error_found;
+
+ }
}