From 58e2574f6a27930679f976278ad9c3dbc8d4ef2a Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Mon, 23 Apr 2012 00:07:02 +0200 Subject: Doing progress on the Preference dialog chaos --- src/de/blinkt/openvpn/AboutActivity.java | 22 -- src/de/blinkt/openvpn/AboutFragment.java | 27 ++ src/de/blinkt/openvpn/AboutPreference.java | 14 + src/de/blinkt/openvpn/BasicSettings.java | 332 +++++++++++++++++++++++ src/de/blinkt/openvpn/MainActivity.java | 13 + src/de/blinkt/openvpn/OpenVPNClient.java | 3 +- src/de/blinkt/openvpn/ShowConfigFragment.java | 8 + src/de/blinkt/openvpn/VPNConfigPreference.java | 54 +++- src/de/blinkt/openvpn/VPNDatabase.java | 0 src/de/blinkt/openvpn/VPNPreferenceFragment.java | 0 src/de/blinkt/openvpn/VPNPreferences.java | 17 +- src/de/blinkt/openvpn/VPNProfileList.java | 235 +++++++++++++++- src/de/blinkt/openvpn/VpnProfile.java | 106 +++++++- 13 files changed, 787 insertions(+), 44 deletions(-) delete mode 100644 src/de/blinkt/openvpn/AboutActivity.java create mode 100644 src/de/blinkt/openvpn/AboutFragment.java create mode 100644 src/de/blinkt/openvpn/AboutPreference.java create mode 100644 src/de/blinkt/openvpn/BasicSettings.java create mode 100644 src/de/blinkt/openvpn/MainActivity.java create mode 100644 src/de/blinkt/openvpn/ShowConfigFragment.java create mode 100644 src/de/blinkt/openvpn/VPNDatabase.java create mode 100644 src/de/blinkt/openvpn/VPNPreferenceFragment.java (limited to 'src') diff --git a/src/de/blinkt/openvpn/AboutActivity.java b/src/de/blinkt/openvpn/AboutActivity.java deleted file mode 100644 index 0361d67c..00000000 --- a/src/de/blinkt/openvpn/AboutActivity.java +++ /dev/null @@ -1,22 +0,0 @@ -package de.blinkt.openvpn; - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; - -public class AboutActivity extends Activity implements OnClickListener { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.about); - - //findViewById(R.layout.about).setOnClickListener(this); - } - - @Override - public void onClick(View v) { - finish(); - } -} diff --git a/src/de/blinkt/openvpn/AboutFragment.java b/src/de/blinkt/openvpn/AboutFragment.java new file mode 100644 index 00000000..a5b5695e --- /dev/null +++ b/src/de/blinkt/openvpn/AboutFragment.java @@ -0,0 +1,27 @@ +package de.blinkt.openvpn; + +import android.app.Activity; +import android.app.Fragment; +import android.os.Bundle; +import android.preference.PreferenceFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; + +public class AboutFragment extends Fragment { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v= inflater.inflate(R.layout.about, container, false); + return v; + } + +} diff --git a/src/de/blinkt/openvpn/AboutPreference.java b/src/de/blinkt/openvpn/AboutPreference.java new file mode 100644 index 00000000..ff6c611d --- /dev/null +++ b/src/de/blinkt/openvpn/AboutPreference.java @@ -0,0 +1,14 @@ +package de.blinkt.openvpn; + +import android.content.Context; +import android.preference.Preference; +import android.util.AttributeSet; + +public class AboutPreference extends Preference { + + public AboutPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setWidgetLayoutResource(R.layout.about); + } + +} diff --git a/src/de/blinkt/openvpn/BasicSettings.java b/src/de/blinkt/openvpn/BasicSettings.java new file mode 100644 index 00000000..271b8085 --- /dev/null +++ b/src/de/blinkt/openvpn/BasicSettings.java @@ -0,0 +1,332 @@ +/* + * 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.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.HashMap; +import java.util.Random; +import java.util.Vector; + +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import android.app.Activity; +import android.app.Fragment; +import android.content.Context; +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.security.KeyChainException; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +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 { + 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 static final String OVPNCONFIGFILE = "android.conf"; + private static final String OVPNCONFIGPKCS12 = "android.pkcs12"; + + + 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 FileSelectLayout mpkcs12; + private TextView mPKCS12Password; + + private Handler mHandler; + + + private CheckBox mUseTlsAuth; + + + private CheckBox mShowAdvanced; + + + private FileSelectLayout mTlsFile; + + private HashMap fileselects = new HashMap(); + + + private Spinner mTLSDirection; + + + private EditText mUserName; + + + private EditText mPassword; + + + private View mView; + + + private VpnProfile mProfile; + + + + private void addFileSelectLayout (FileSelectLayout fsl) { + int i = fileselects.size() + CHOOSE_FILE_OFFSET; + fileselects.put(i, fsl); + fsl.setActivity(getActivity(),i); + } + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + mView = inflater.inflate(R.layout.basic_settings,container,false); + + + mServerAddress = (TextView) mView.findViewById(R.id.address); + mServerPort = (TextView) mView.findViewById(R.id.port); + mClientCert = (FileSelectLayout) mView.findViewById(R.id.certselect); + mClientKey = (FileSelectLayout) mView.findViewById(R.id.keyselect); + mCaCert = (FileSelectLayout) mView.findViewById(R.id.caselect); + mpkcs12 = (FileSelectLayout) mView.findViewById(R.id.pkcs12select); + mUseLzo = (CheckBox) mView.findViewById(R.id.lzo); + mTcpUdp = (ToggleButton) mView.findViewById(id.tcpudp); + 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); + + + 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); + } + return mView; + } + + + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + if (parent == mType) { + changeType(position); + } + } + + + + private void changeType(int type){ + // hide everything + mView.findViewById(R.id.pkcs12).setVisibility(View.GONE); + mView.findViewById(R.id.certs).setVisibility(View.GONE); + mView.findViewById(R.id.statickeys).setVisibility(View.GONE); + mView.findViewById(R.id.keystore).setVisibility(View.GONE); + + switch(type) { + case VpnProfile.TYPE_CERTIFICATES: + mView.findViewById(R.id.certs).setVisibility(View.VISIBLE); + break; + case VpnProfile.TYPE_PKCS12: + mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE); + break; + case VpnProfile.TYPE_STATICKEYS: + mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE); + break; + case VpnProfile.TYPE_KEYSTORE: + mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE); + break; + + case VpnProfile.TYPE_USERPASS: + mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); + } + + + } + + private void loadPreferences() { + mProfile = ((VPNPreferences)getActivity()).getVPNProfile(); + + mClientCert.setData(mProfile.mClientCertFilename); + mClientKey.setData(mProfile.mClientKeyFilename); + mCaCert.setData(mProfile.mCaFilename); + + mUseLzo.setChecked(mProfile.mUseLzo); + mServerPort.setText(mProfile.mServerPort); + mServerAddress.setText(mProfile.mServerName); + mTcpUdp.setChecked(mProfile.mUseUdp); + mType.setSelection(mProfile.mAuthenticationType); + 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(); + + } + + private void savePreferences() { + // We need an Editor object to make preference changes. + // All objects are from android.context.Context + + + mProfile.mCaFilename = mCaCert.getData(); + mProfile.mClientCertFilename = mClientCert.getData(); + mProfile.mClientKeyFilename = mClientKey.getData(); + + mProfile.mUseLzo = mUseLzo.isChecked(); + mProfile.mServerPort =mServerPort.getText().toString(); + mProfile.mServerName = mServerAddress.getText().toString(); + mProfile.mUseUdp = mTcpUdp.isChecked(); + + 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! + + } + + + private void setAlias() { + if(mProfile.mAlias == null) { + mAliasName.setText(R.string.client_no_certificate); + } else { + mAliasName.setText(mProfile.mAlias); + } + } + + public void showCertDialog () { + KeyChain.choosePrivateKeyAlias(getActivity(), + new KeyChainAliasCallback() { + + public void alias(String alias) { + // Credential alias selected. Remember the alias selection for future use. + mProfile.mAlias=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 + } + + @Override + public void onClick(View v) { + if (v == mView.findViewById(R.id.select_keystore_button)) { + showCertDialog(); + } + } + + + + @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) { + 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/MainActivity.java b/src/de/blinkt/openvpn/MainActivity.java new file mode 100644 index 00000000..bc823745 --- /dev/null +++ b/src/de/blinkt/openvpn/MainActivity.java @@ -0,0 +1,13 @@ +package de.blinkt.openvpn; + +import java.util.List; + +import android.preference.PreferenceActivity; +import android.preference.PreferenceActivity.Header; + +public class MainActivity extends PreferenceActivity { + @Override + public void onBuildHeaders(List
target) { + loadHeadersFromResource(R.xml.main_headers, target); + } +} diff --git a/src/de/blinkt/openvpn/OpenVPNClient.java b/src/de/blinkt/openvpn/OpenVPNClient.java index f1a32b63..5af0ae8f 100644 --- a/src/de/blinkt/openvpn/OpenVPNClient.java +++ b/src/de/blinkt/openvpn/OpenVPNClient.java @@ -250,7 +250,7 @@ public class OpenVPNClient extends Activity implements View.OnClickListener, OnI @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.config); + setContentView(R.layout.basic_settings); // Forces early JNI Load OpenVPN.foo(); @@ -490,6 +490,7 @@ public class OpenVPNClient extends Activity implements View.OnClickListener, OnI } 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(); diff --git a/src/de/blinkt/openvpn/ShowConfigFragment.java b/src/de/blinkt/openvpn/ShowConfigFragment.java new file mode 100644 index 00000000..91471e84 --- /dev/null +++ b/src/de/blinkt/openvpn/ShowConfigFragment.java @@ -0,0 +1,8 @@ +package de.blinkt.openvpn; + +import android.app.Fragment; + + +public class ShowConfigFragment extends Fragment { + +} diff --git a/src/de/blinkt/openvpn/VPNConfigPreference.java b/src/de/blinkt/openvpn/VPNConfigPreference.java index 3afcfccb..0387ebdb 100644 --- a/src/de/blinkt/openvpn/VPNConfigPreference.java +++ b/src/de/blinkt/openvpn/VPNConfigPreference.java @@ -1,15 +1,55 @@ package de.blinkt.openvpn; -import android.content.Context; -import android.preference.CheckBoxPreference; +import android.os.Bundle; import android.preference.Preference; -import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ImageView; -public class VPNConfigPreference extends Preference { +public class VPNConfigPreference extends Preference implements OnClickListener { - public VPNConfigPreference(Context context, AttributeSet attrs) { - super(context, attrs); - setWidgetLayoutResource(R.layout.vpn_preference_layout); + + private OnQuickSettingsClickListener mOnQuickSettingsListener; + private ImageView mQuickPrefButton; + + + public VPNConfigPreference(VPNProfileList vpnProfileList, Bundle args) { + + super(vpnProfileList.getActivity()); + setWidgetLayoutResource(R.layout.vpn_preference_layout); + + + } + + @Override + protected void onBindView(View view) { + super.onBindView(view); + mQuickPrefButton = (ImageView) view.findViewById(R.id.quickedit_settings); + mQuickPrefButton.setOnClickListener(this); } + public interface OnQuickSettingsClickListener { + /** + * Called when a Preference has been clicked. + * + * @param preference The Preference that was clicked. + * @return True if the click was handled. + */ + boolean onQuickSettingsClick(Preference preference); + } + + + public void setOnQuickSettingsClickListener(OnQuickSettingsClickListener onQuickSettingsListener) { + mOnQuickSettingsListener = onQuickSettingsListener; + } + + @Override + public void onClick(View v) { + if (mOnQuickSettingsListener != null) { + mOnQuickSettingsListener.onQuickSettingsClick(this); + } + + } + + } diff --git a/src/de/blinkt/openvpn/VPNDatabase.java b/src/de/blinkt/openvpn/VPNDatabase.java new file mode 100644 index 00000000..e69de29b diff --git a/src/de/blinkt/openvpn/VPNPreferenceFragment.java b/src/de/blinkt/openvpn/VPNPreferenceFragment.java new file mode 100644 index 00000000..e69de29b diff --git a/src/de/blinkt/openvpn/VPNPreferences.java b/src/de/blinkt/openvpn/VPNPreferences.java index 69485efd..6c68e444 100644 --- a/src/de/blinkt/openvpn/VPNPreferences.java +++ b/src/de/blinkt/openvpn/VPNPreferences.java @@ -2,7 +2,9 @@ package de.blinkt.openvpn; import java.util.List; +import android.content.Intent; import android.os.Bundle; +import android.os.Parcelable; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.Preference; @@ -16,6 +18,7 @@ import android.widget.Button; public class VPNPreferences extends PreferenceActivity { + private VpnProfile mProfile; public VPNPreferences() { super(); } @@ -23,6 +26,8 @@ public class VPNPreferences extends PreferenceActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mProfile = getIntent().getParcelableExtra("VpnProfile"); + if (hasHeaders()) { Button button = new Button(this); button.setText("Some action"); @@ -47,12 +52,13 @@ public class VPNPreferences extends PreferenceActivity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // Make sure default values are applied. In a real app, you would // want this in a shared function that is used to retrieve the // SharedPreferences wherever they are needed. PreferenceManager.setDefaultValues(getActivity(), R.xml.vpn_ipsettings, false); - + // Load the preferences from an XML resource addPreferencesFromResource(R.xml.vpn_ipsettings); mIPv4 = (EditTextPreference) findPreference("ipv4_address"); @@ -69,8 +75,14 @@ public class VPNPreferences extends PreferenceActivity { mDNS2.setOnPreferenceChangeListener(this); mUsePull.setOnPreferenceChangeListener(this); mOverrideDNS.setOnPreferenceChangeListener(this); + + + VpnProfile vp = ((VPNPreferences) getActivity()).getVPNProfile(); + + setDNSState(); + } @Override @@ -134,5 +146,8 @@ public class VPNPreferences extends PreferenceActivity { addPreferencesFromResource(R.xml.vpn_obscure); } } + public VpnProfile getVPNProfile() { + return mProfile; + } } diff --git a/src/de/blinkt/openvpn/VPNProfileList.java b/src/de/blinkt/openvpn/VPNProfileList.java index fb7af280..74c857d3 100644 --- a/src/de/blinkt/openvpn/VPNProfileList.java +++ b/src/de/blinkt/openvpn/VPNProfileList.java @@ -1,22 +1,233 @@ package de.blinkt.openvpn; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.StreamCorruptedException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import de.blinkt.openvpn.VPNConfigPreference.OnQuickSettingsClickListener; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; import android.os.Bundle; -import android.preference.PreferenceActivity; +import android.os.Parcelable; +import android.preference.DialogPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceFragment; +import android.preference.PreferenceScreen; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.EditText; +import android.widget.Toast; + +public class VPNProfileList extends PreferenceFragment implements OnPreferenceClickListener, OnQuickSettingsClickListener { + private static final String PREFS_NAME = "VPNList"; + + private static final int MENU_ADD_PROFILE = Menu.FIRST; + + + private HashMap profiles; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.vpn_profile_list); + setHasOptionsMenu(true); + + } + + @Override + public void onResume() { + super.onResume(); + refreshList(); + + + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.add(0, MENU_ADD_PROFILE, 0, R.string.menu_add_profile) + .setIcon(android.R.drawable.ic_menu_add) + .setAlphabeticShortcut('a') + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM + | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int itemId = item.getItemId(); + if (itemId == MENU_ADD_PROFILE) { + onAddProfileClicked(); + return true; + } else { + return super.onOptionsItemSelected(item); + } + } + + private void onAddProfileClicked() { + Context context = getActivity(); + if (context != null) { + final EditText entry = new EditText(context); + entry.setSingleLine(); + + AlertDialog.Builder dialog = new AlertDialog.Builder(context); + dialog.setTitle(R.string.menu_add_profile); + dialog.setMessage(R.string.add_profile_name_prompt); + dialog.setView(entry); + + + dialog.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String name = entry.getText().toString(); + if (getProfileByName(name)==null) { + VpnProfile profile = new VpnProfile(name); + addProfile(profile); + refreshList(); + } else { + Toast.makeText(getActivity(), R.string.duplicate_profile_name, Toast.LENGTH_LONG).show(); + } + } + + + }); + dialog.setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + }); + dialog.create().show(); + } + + } + + public VpnProfile getProfileByName(String name) { + for (VpnProfile vpnp : profiles.values()) { + if(vpnp.getName().equals(name)) { + return vpnp; + } + } + return null; + } + + private void addProfile(VpnProfile profile) { + profiles.put(profile.getUUID().toString(),profile); + Editor editor = getActivity().getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE).edit(); + editor.putStringSet("vpnlist", profiles.keySet()); + editor.commit(); + saveProfile(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(); + } + } + + private void loadVPNList() { + profiles = new HashMap(); + SharedPreferences settings =getActivity().getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); + Set vlist = settings.getStringSet("vpnlist", null); + if(vlist==null){ + vlist = new HashSet(); + } + + for (String vpnentry : vlist) { + try { + ObjectInputStream vpnfile = new ObjectInputStream(getActivity().openFileInput(vpnentry + ".vp")); + VpnProfile vp = ((VpnProfile) vpnfile.readObject()); + + profiles.put(vp.getUUID().toString(), vp); + + } catch (StreamCorruptedException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + } + + + public void refreshList() { + PreferenceScreen plist = getPreferenceScreen(); + if (plist != null) { + plist.removeAll(); + loadVPNList(); + + for (VpnProfile vpnprofile: profiles.values()) { + Bundle args = new Bundle(); + //TODO + + String profileuuid = vpnprofile.getUUID().toString(); + + + args.putParcelable("Profile", vpnprofile); + //args.putString("name", vpnentry); + VPNConfigPreference vpref = new VPNConfigPreference(this, args); + vpref.setKey(profileuuid); + vpref.setTitle(vpnprofile.getName()); + vpref.setPersistent(false); + // vpref.setSelectable(true); + vpref.setOnPreferenceClickListener(this); + vpref.setOnQuickSettingsClickListener(this); + plist.addPreference(vpref); + } + + } + } + + @Override + public boolean onPreferenceClick(Preference preference) { + String key= preference.getKey(); + + return true; -import android.app.ProfileManager; + } -public class VPNProfileList extends PreferenceActivity { - private ProfileManager mProfileManager; + @Override + public boolean onQuickSettingsClick(Preference preference) { + String key = preference.getKey(); - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + VpnProfile vprofile = profiles.get(key); - if (getPreferenceManager() != null) { - addPreferencesFromResource(R.xml.profiles_settings); - mProfileManager = (ProfileManager) getActivity().getSystemService(PROFILE_SERVICE); + Intent vprefintent = new Intent(getActivity(),VPNPreferences.class) + .putExtra("VpnProfile", (Parcelable)vprofile); - } - } + startActivity(vprefintent); + return true; + } } diff --git a/src/de/blinkt/openvpn/VpnProfile.java b/src/de/blinkt/openvpn/VpnProfile.java index 8d5fbe32..0eddabaa 100644 --- a/src/de/blinkt/openvpn/VpnProfile.java +++ b/src/de/blinkt/openvpn/VpnProfile.java @@ -1,10 +1,114 @@ package de.blinkt.openvpn; -public class VpnProfile { +import java.io.Serializable; +import java.util.UUID; + +import android.os.Parcel; +import android.os.Parcelable; + +public class VpnProfile implements Parcelable, Serializable{ + /** + * + */ + private static final long serialVersionUID = 7085688938959334563L; static final int TYPE_CERTIFICATES=0; static final int TYPE_PKCS12=1; static final int TYPE_KEYSTORE=2; public static final int TYPE_USERPASS = 3; public static final int TYPE_STATICKEYS = 4; + + // Keep in order of parceling + // Public attributes, since I got mad with getter/setter + // set members to default values + private UUID mUuid; + public int mAuthenticationType = TYPE_KEYSTORE ; + public String mName; + public String mAlias; + public String mClientCertFilename; + public int mTLSAuthDirection=2; + public String mTLSAuthFilename; + public String mClientKeyFilename; + public String mCaFilename; + public boolean mUseLzo=true; + public String mServerPort= "1194" ; + public boolean mUseUdp = true; + public String mPKCS12Filename; + public String mPKCS12Password; + public boolean mUseTLSAuth = false; + public String mServerName = "openvpn.blinkt.de" ; + + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mAuthenticationType); + out.writeLong(mUuid.getMostSignificantBits()); + out.writeLong(mUuid.getLeastSignificantBits()); + out.writeString(mName); + out.writeString(mAlias); + out.writeString(mClientCertFilename); + out.writeInt(mTLSAuthDirection); + out.writeString(mTLSAuthFilename); + out.writeString(mClientKeyFilename); + out.writeString(mCaFilename); + out.writeValue(mUseLzo); + out.writeString(mServerPort); + out.writeValue(mUseUdp); + out.writeString(mPKCS12Filename); + out.writeString(mPKCS12Password); + out.writeValue(mUseTLSAuth); + out.writeString(mServerName); + } + + private VpnProfile(Parcel in) { + mAuthenticationType = in.readInt(); + mUuid = new UUID(in.readLong(), in.readLong()); + mName = in.readString(); + mAlias = in.readString(); + mClientCertFilename = in.readString(); + mTLSAuthDirection = in.readInt(); + mTLSAuthFilename = in.readString(); + mClientKeyFilename = in.readString(); + mCaFilename = in.readString(); + mUseLzo = (Boolean) in.readValue(null); + mServerPort = in.readString(); + mUseUdp = (Boolean) in.readValue(null); + mPKCS12Filename = in.readString(); + mPKCS12Password = in.readString(); + mUseTLSAuth = (Boolean) in.readValue(null); + mServerName = in.readString(); + } + + public static final Parcelable.Creator CREATOR + = new Parcelable.Creator() { + public VpnProfile createFromParcel(Parcel in) { + return new VpnProfile(in); + } + + public VpnProfile[] newArray(int size) { + return new VpnProfile[size]; + } + }; + + public VpnProfile(String name) { + mUuid = UUID.randomUUID(); + mName = name; + } + + public UUID getUUID() { + return mUuid; + + } + + public String getName() { + // TODO Auto-generated method stub + return mName; + } + + + + } -- cgit v1.2.3