diff options
author | schwabe <devnull@localhost> | 2012-04-28 19:58:02 +0200 |
---|---|---|
committer | schwabe <devnull@localhost> | 2012-04-28 19:58:02 +0200 |
commit | 63e466054c2f1d66e4618ac4d73208751f1e5bd1 (patch) | |
tree | 84a00021ec486093b406ec050087ee486f6e6958 | |
parent | 031186e74c9f174d05a09c4059def7bcbc558ac6 (diff) |
Almost ready for version 0.4
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. "Server" matches "Server-1" and "Server-2"" - 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. "Server" matches "Server-1" and "Server-2"\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; + + } } |