/* * Copyright (C) 2010 James Bottomley <James.Bottomley@suse.de> * * * * 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 com.android.settings.vpn; import com.android.settings.R; import android.content.Context; import android.content.Intent; import android.net.vpn.OpenvpnProfile; import android.os.Bundle; import android.os.Parcelable; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; import android.security.Credentials; import android.security.KeyStore; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; /** * The class for editing {@link OpenvpnProfile}. */ class OpenvpnEditor extends VpnProfileEditor { private static final String KEY_PROFILE = "openvpn_profile"; private static final int REQUEST_ADVANCED = 1; private static final String TAG = OpenvpnEditor.class.getSimpleName(); private int MENU_ID_ADVANCED; private KeyStore mKeyStore = KeyStore.getInstance(); private CheckBoxPreference mUserAuth; private ListPreference mCert; private ListPreference mCACert; public OpenvpnEditor(OpenvpnProfile p) { super(p); } @Override protected void loadExtraPreferencesTo(PreferenceGroup subpanel) { final Context c = subpanel.getContext(); final OpenvpnProfile profile = (OpenvpnProfile) getProfile(); mUserAuth = new CheckBoxPreference(c); mUserAuth.setTitle(R.string.vpn_openvpn_userauth); mUserAuth.setSummary(R.string.vpn_openvpn_userauth_summary); mUserAuth.setChecked(profile.getUserAuth()); mUserAuth.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { boolean enabled = (Boolean) newValue; profile.setUserAuth(enabled); mUserAuth.setChecked(enabled); return true; } }); subpanel.addPreference(mUserAuth); mCACert = createList(c, R.string.vpn_ca_certificate_title, profile.getCAName(), mKeyStore .saw(Credentials.CA_CERTIFICATE), new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String f = (String) newValue; profile.setCAName(f); setSummary(mCACert, R.string.vpn_ca_certificate, profile.getCAName()); return true; } }); setSummary(mCACert, R.string.vpn_ca_certificate, profile.getCAName()); subpanel.addPreference(mCACert); mCert = createList(c, R.string.vpn_user_certificate_title, profile.getCertName(), mKeyStore .saw(Credentials.USER_CERTIFICATE), new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String f = (String) newValue; profile.setCertName(f); setSummary(mCert, R.string.vpn_user_certificate, profile.getCertName()); return true; } }); setSummary(mCert, R.string.vpn_user_certificate, profile.getCertName()); subpanel.addPreference(mCert); } @Override public String validate() { String result = super.validate(); if (result != null) return result; if (!mUserAuth.isChecked()) { result = validate(mCert, R.string.vpn_a_user_certificate); if (result != null) return result; } return validate(mCACert, R.string.vpn_a_ca_certificate); } @Override protected void onCreateOptionsMenu(Menu menu, int last_item) { MENU_ID_ADVANCED = last_item + 1; menu.add(0, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced).setIcon( android.R.drawable.ic_menu_manage); } @Override protected boolean onOptionsItemSelected(PreferenceActivity p, MenuItem item) { if (item.getItemId() == MENU_ID_ADVANCED) { Intent intent = new Intent(p, AdvancedSettings.class); intent.putExtra(KEY_PROFILE, (Parcelable) getProfile()); p.startActivityForResult(intent, REQUEST_ADVANCED); return true; } else { return false; } } @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { if (requestCode != REQUEST_ADVANCED) return; OpenvpnProfile p = (OpenvpnProfile) getProfile(); OpenvpnProfile newP = data.getParcelableExtra(KEY_PROFILE); if (newP == null) { Log.e(TAG, "no profile from advanced settings"); return; } // manually copy across all advanced settings p.setPort(newP.getPort()); p.setProto(newP.getProto()); p.setDevice(newP.getDevice()); p.setUseCompLzo(newP.getUseCompLzo()); p.setRedirectGateway(newP.getRedirectGateway()); p.setSupplyAddr(newP.getSupplyAddr()); p.setLocalAddr(newP.getLocalAddr()); p.setRemoteAddr(newP.getRemoteAddr()); p.setCipher(newP.getCipher()); p.setKeySize(newP.getKeySize()); p.setExtra(newP.getExtra()); } private ListPreference createList(Context c, int titleResId, String selection, String[] keys, Preference.OnPreferenceChangeListener listener) { ListPreference pref = new ListPreference(c); pref.setTitle(titleResId); pref.setDialogTitle(titleResId); pref.setPersistent(true); pref.setEntries(keys); pref.setEntryValues(keys); pref.setValue(selection); pref.setOnPreferenceChangeListener(listener); return pref; } public static class AdvancedSettings extends PreferenceActivity { private static final String KEY_PORT = "set_port"; private static final String KEY_PROTO = "set_protocol"; private static final String KEY_DEVICE = "set_device"; private static final String KEY_COMP_LZO = "set_comp_lzo"; private static final String KEY_REDIRECT_GATEWAY = "set_redirect_gateway"; private static final String KEY_SET_ADDR = "set_addr"; private static final String KEY_LOCAL_ADDR = "set_local_addr"; private static final String KEY_REMOTE_ADDR = "set_remote_addr"; private static final String KEY_CIPHER = "set_cipher"; private static final String KEY_KEYSIZE = "set_keysize"; private static final String KEY_EXTRA = "set_extra"; private EditTextPreference mPort; private ListPreference mProto; private ListPreference mDevice; private CheckBoxPreference mCompLzo; private CheckBoxPreference mRedirectGateway; private CheckBoxPreference mSetAddr; private EditTextPreference mLocalAddr; private EditTextPreference mRemoteAddr; private EditTextPreference mCipher; private EditTextPreference mKeySize; private EditTextPreference mExtra; private OpenvpnProfile profile; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); profile = getIntent().getParcelableExtra(KEY_PROFILE); addPreferencesFromResource(R.xml.openvpn_advanced_settings); mPort = (EditTextPreference) findPreference(KEY_PORT); mProto = (ListPreference) findPreference(KEY_PROTO); mDevice = (ListPreference) findPreference(KEY_DEVICE); mCompLzo = (CheckBoxPreference) findPreference(KEY_COMP_LZO); mRedirectGateway = (CheckBoxPreference) findPreference(KEY_REDIRECT_GATEWAY); mSetAddr = (CheckBoxPreference) findPreference(KEY_SET_ADDR); mLocalAddr = (EditTextPreference) findPreference(KEY_LOCAL_ADDR); mRemoteAddr = (EditTextPreference) findPreference(KEY_REMOTE_ADDR); mCipher = (EditTextPreference) findPreference(KEY_CIPHER); mKeySize = (EditTextPreference) findPreference(KEY_KEYSIZE); mExtra = (EditTextPreference) findPreference(KEY_EXTRA); mPort.setSummary(profile.getPort()); mPort.setText(profile.getPort()); mPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setPort(name); mPort.setSummary(profile.getPort()); return true; } }); mProto.setSummary(profile.getProto()); mProto.setValue(profile.getProto()); mProto.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setProto(name); mProto.setSummary(profile.getProto()); return true; } }); mDevice.setSummary(profile.getDevice()); mDevice.setValue(profile.getDevice()); mDevice.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setDevice(name); mDevice.setSummary(profile.getDevice()); return true; } }); mCompLzo.setChecked(profile.getUseCompLzo()); mCompLzo.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { Boolean b = (Boolean) newValue; profile.setUseCompLzo(b); return true; } }); mRedirectGateway.setChecked(profile.getRedirectGateway()); mRedirectGateway.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { Boolean b = (Boolean) newValue; profile.setRedirectGateway(b); return true; } }); // This is inverted to cope with the way dependencies work mSetAddr.setChecked(!profile.getSupplyAddr()); mSetAddr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { Boolean b = (Boolean) newValue; profile.setSupplyAddr(!b); return true; } }); mLocalAddr.setSummary(profile.getLocalAddr()); mLocalAddr.setText(profile.getLocalAddr()); mLocalAddr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setLocalAddr(name); mLocalAddr.setSummary(profile.getLocalAddr()); return true; } }); mRemoteAddr.setSummary(profile.getRemoteAddr()); mRemoteAddr.setText(profile.getRemoteAddr()); mRemoteAddr.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setRemoteAddr(name); mRemoteAddr.setSummary(profile.getRemoteAddr()); return true; } }); if (profile.getCipher() == null || profile.getCipher().equals("")) mCipher.setSummary("default"); else mCipher.setSummary(profile.getCipher()); mCipher.setText(profile.getCipher()); mCipher.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setCipher(name); if (profile.getCipher().equals("")) mCipher.setSummary("default"); else mCipher.setSummary(profile.getCipher()); return true; } }); if (profile.getKeySize() == null || profile.getKeySize().equals("0")) { mKeySize.setSummary("default"); mKeySize.setText(""); } else { mKeySize.setSummary(profile.getKeySize()); mKeySize.setText(profile.getKeySize()); } mKeySize.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); if (name.equals("")) name = "0"; profile.setKeySize(name); if (profile.getKeySize().equals("0")) mKeySize.setSummary("default"); else mKeySize.setSummary(profile.getKeySize()); return true; } }); mExtra.setSummary(profile.getExtra()); mExtra.setText(profile.getExtra()); mExtra.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { public boolean onPreferenceChange(Preference pref, Object newValue) { String name = (String) newValue; name.trim(); profile.setExtra(name); mExtra.setSummary(profile.getExtra()); return true; } }); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: Intent intent = new Intent(this, VpnEditor.class); intent.putExtra(KEY_PROFILE, (Parcelable) profile); setResult(RESULT_OK, intent); finish(); return true; } return super.onKeyDown(keyCode, event); } } }