am cb41032d: Merge change 26186 into eclair

Merge commit 'cb41032d85e2538c0a0a85f72656891c6203dc9b' into eclair-plus-aosp

* commit 'cb41032d85e2538c0a0a85f72656891c6203dc9b':
  Settings: revise VpnSettings.
This commit is contained in:
Chia-chi Yeh
2009-09-22 09:07:54 -07:00
committed by Android Git Automerger
2 changed files with 56 additions and 75 deletions

View File

@@ -24,7 +24,8 @@ import android.preference.EditTextPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceGroup; import android.preference.PreferenceGroup;
import android.security.CertTool; import android.security.Credentials;
import android.security.KeyStore;
import android.text.TextUtils; import android.text.TextUtils;
/** /**
@@ -33,6 +34,8 @@ import android.text.TextUtils;
class L2tpIpsecEditor extends L2tpEditor { class L2tpIpsecEditor extends L2tpEditor {
private static final String TAG = L2tpIpsecEditor.class.getSimpleName(); private static final String TAG = L2tpIpsecEditor.class.getSimpleName();
private KeyStore mKeyStore = KeyStore.getInstance();
private ListPreference mUserCertificate; private ListPreference mUserCertificate;
private ListPreference mCaCertificate; private ListPreference mCaCertificate;
@@ -67,7 +70,7 @@ class L2tpIpsecEditor extends L2tpEditor {
mUserCertificate = createListPreference(c, mUserCertificate = createListPreference(c,
R.string.vpn_user_certificate_title, R.string.vpn_user_certificate_title,
mProfile.getUserCertificate(), mProfile.getUserCertificate(),
CertTool.getInstance().getAllUserCertificateKeys(), mKeyStore.saw(Credentials.USER_CERTIFICATE),
new Preference.OnPreferenceChangeListener() { new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange( public boolean onPreferenceChange(
Preference pref, Object newValue) { Preference pref, Object newValue) {
@@ -86,7 +89,7 @@ class L2tpIpsecEditor extends L2tpEditor {
mCaCertificate = createListPreference(c, mCaCertificate = createListPreference(c,
R.string.vpn_ca_certificate_title, R.string.vpn_ca_certificate_title,
mProfile.getCaCertificate(), mProfile.getCaCertificate(),
CertTool.getInstance().getAllCaCertificateKeys(), mKeyStore.saw(Credentials.CA_CERTIFICATE),
new Preference.OnPreferenceChangeListener() { new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange( public boolean onPreferenceChange(
Preference pref, Object newValue) { Preference pref, Object newValue) {

View File

@@ -47,8 +47,8 @@ import android.preference.PreferenceCategory;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceClickListener; import android.preference.Preference.OnPreferenceClickListener;
import android.security.CertTool; import android.security.Credentials;
import android.security.Keystore; import android.security.KeyStore;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
@@ -109,9 +109,8 @@ public class VpnSettings extends PreferenceActivity implements
private static final int NO_ERROR = VpnManager.VPN_ERROR_NO_ERROR; private static final int NO_ERROR = VpnManager.VPN_ERROR_NO_ERROR;
private static final String NAMESPACE_VPN = "vpn"; private static final String KEY_PREFIX_IPSEC_PSK = Credentials.VPN + 'i';
private static final String KEY_PREFIX_IPSEC_PSK = "ipsk000"; private static final String KEY_PREFIX_L2TP_SECRET = Credentials.VPN + 'l';
private static final String KEY_PREFIX_L2TP_SECRET = "lscrt000";
private PreferenceScreen mAddVpn; private PreferenceScreen mAddVpn;
private PreferenceCategory mVpnListContainer; private PreferenceCategory mVpnListContainer;
@@ -129,6 +128,8 @@ public class VpnSettings extends PreferenceActivity implements
// states saved for unlocking keystore // states saved for unlocking keystore
private Runnable mUnlockAction; private Runnable mUnlockAction;
private KeyStore mKeyStore = KeyStore.getInstance();
private VpnManager mVpnManager = new VpnManager(this); private VpnManager mVpnManager = new VpnManager(this);
private ConnectivityReceiver mConnectivityReceiver = private ConnectivityReceiver mConnectivityReceiver =
@@ -172,7 +173,7 @@ public class VpnSettings extends PreferenceActivity implements
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
if ((mUnlockAction != null) && isKeystoreUnlocked()) { if ((mUnlockAction != null) && isKeyStoreUnlocked()) {
Runnable action = mUnlockAction; Runnable action = mUnlockAction;
mUnlockAction = null; mUnlockAction = null;
runOnUiThread(action); runOnUiThread(action);
@@ -402,13 +403,13 @@ public class VpnSettings extends PreferenceActivity implements
return; return;
} }
if (needKeystoreToSave(p)) { if (needKeyStoreToSave(p)) {
Runnable action = new Runnable() { Runnable action = new Runnable() {
public void run() { public void run() {
onActivityResult(requestCode, resultCode, data); onActivityResult(requestCode, resultCode, data);
} }
}; };
if (!unlockKeystore(p, action)) return; if (!unlockKeyStore(p, action)) return;
} }
try { try {
@@ -610,22 +611,26 @@ public class VpnSettings extends PreferenceActivity implements
startActivityForResult(intent, REQUEST_SELECT_VPN_TYPE); startActivityForResult(intent, REQUEST_SELECT_VPN_TYPE);
} }
private boolean isKeystoreUnlocked() { private boolean isKeyStoreUnlocked() {
return (Keystore.getInstance().getState() == Keystore.UNLOCKED); return mKeyStore.test() == KeyStore.NO_ERROR;
}
// Returns true if the profile needs to access keystore
private boolean needKeystoreToSave(VpnProfile p) {
return needKeystoreToConnect(p);
} }
// Returns true if the profile needs to access keystore // Returns true if the profile needs to access keystore
private boolean needKeystoreToEdit(VpnProfile p) { private boolean needKeyStoreToSave(VpnProfile p) {
switch (p.getType()) { switch (p.getType()) {
case L2TP_IPSEC:
case L2TP_IPSEC_PSK: case L2TP_IPSEC_PSK:
return true; L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p;
String presharedKey = pskProfile.getPresharedKey();
if (!TextUtils.isEmpty(presharedKey)) return true;
// pass through
case L2TP:
L2tpProfile l2tpProfile = (L2tpProfile) p;
if (l2tpProfile.isSecretEnabled() &&
!TextUtils.isEmpty(l2tpProfile.getSecretString())) {
return true;
}
// pass through
default: default:
return false; return false;
@@ -633,7 +638,7 @@ public class VpnSettings extends PreferenceActivity implements
} }
// Returns true if the profile needs to access keystore // Returns true if the profile needs to access keystore
private boolean needKeystoreToConnect(VpnProfile p) { private boolean needKeyStoreToConnect(VpnProfile p) {
switch (p.getType()) { switch (p.getType()) {
case L2TP_IPSEC: case L2TP_IPSEC:
case L2TP_IPSEC_PSK: case L2TP_IPSEC_PSK:
@@ -648,37 +653,27 @@ public class VpnSettings extends PreferenceActivity implements
} }
// Returns true if keystore is unlocked or keystore is not a concern // Returns true if keystore is unlocked or keystore is not a concern
private boolean unlockKeystore(VpnProfile p, Runnable action) { private boolean unlockKeyStore(VpnProfile p, Runnable action) {
if (isKeystoreUnlocked()) return true; if (isKeyStoreUnlocked()) return true;
mUnlockAction = action; mUnlockAction = action;
startActivity( Credentials.getInstance().unlock(this);
new Intent(Keystore.ACTION_UNLOCK_CREDENTIAL_STORAGE));
return false; return false;
} }
private void startVpnEditor(final VpnProfile profile) { private void startVpnEditor(final VpnProfile profile) {
if (needKeystoreToEdit(profile)) {
Runnable action = new Runnable() {
public void run() {
startVpnEditor(profile);
}
};
if (!unlockKeystore(profile, action)) return;
}
Intent intent = new Intent(this, VpnEditor.class); Intent intent = new Intent(this, VpnEditor.class);
intent.putExtra(KEY_VPN_PROFILE, (Parcelable) profile); intent.putExtra(KEY_VPN_PROFILE, (Parcelable) profile);
startActivityForResult(intent, REQUEST_ADD_OR_EDIT_PROFILE); startActivityForResult(intent, REQUEST_ADD_OR_EDIT_PROFILE);
} }
private synchronized void connect(final VpnProfile p) { private synchronized void connect(final VpnProfile p) {
if (needKeystoreToConnect(p)) { if (needKeyStoreToConnect(p)) {
Runnable action = new Runnable() { Runnable action = new Runnable() {
public void run() { public void run() {
connect(p); connect(p);
} }
}; };
if (!unlockKeystore(p, action)) return; if (!unlockKeyStore(p, action)) return;
} }
if (!checkSecrets(p)) return; if (!checkSecrets(p)) return;
@@ -888,43 +883,32 @@ public class VpnSettings extends PreferenceActivity implements
return mVpnManager.createVpnProfile(Enum.valueOf(VpnType.class, type)); return mVpnManager.createVpnProfile(Enum.valueOf(VpnType.class, type));
} }
private String keyNameForDaemon(String keyName) {
return NAMESPACE_VPN + "_" + keyName;
}
private boolean checkSecrets(VpnProfile p) { private boolean checkSecrets(VpnProfile p) {
Keystore ks = Keystore.getInstance();
HashSet<String> secretSet = new HashSet<String>();
boolean secretMissing = false; boolean secretMissing = false;
if (p instanceof L2tpIpsecProfile) { if (p instanceof L2tpIpsecProfile) {
L2tpIpsecProfile certProfile = (L2tpIpsecProfile) p; L2tpIpsecProfile certProfile = (L2tpIpsecProfile) p;
CertTool certTool = CertTool.getInstance();
Collections.addAll(secretSet, certTool.getAllCaCertificateKeys());
String cert = certProfile.getCaCertificate(); String cert = certProfile.getCaCertificate();
if (TextUtils.isEmpty(cert) || !secretSet.contains(cert)) { if (TextUtils.isEmpty(cert) ||
!mKeyStore.contains(Credentials.CA_CERTIFICATE + cert)) {
certProfile.setCaCertificate(null); certProfile.setCaCertificate(null);
secretMissing = true; secretMissing = true;
} }
secretSet.clear();
Collections.addAll(secretSet, certTool.getAllUserCertificateKeys());
cert = certProfile.getUserCertificate(); cert = certProfile.getUserCertificate();
if (TextUtils.isEmpty(cert) || !secretSet.contains(cert)) { if (TextUtils.isEmpty(cert) ||
!mKeyStore.contains(Credentials.USER_CERTIFICATE + cert)) {
certProfile.setUserCertificate(null); certProfile.setUserCertificate(null);
secretMissing = true; secretMissing = true;
} }
} }
secretSet.clear();
Collections.addAll(secretSet, ks.listKeys(NAMESPACE_VPN));
if (p instanceof L2tpIpsecPskProfile) { if (p instanceof L2tpIpsecPskProfile) {
L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p; L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p;
String presharedKey = pskProfile.getPresharedKey(); String presharedKey = pskProfile.getPresharedKey();
String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); String key = KEY_PREFIX_IPSEC_PSK + p.getId();
if (TextUtils.isEmpty(presharedKey) if (TextUtils.isEmpty(presharedKey) || !mKeyStore.contains(key)) {
|| !secretSet.contains(keyName)) {
pskProfile.setPresharedKey(null); pskProfile.setPresharedKey(null);
secretMissing = true; secretMissing = true;
} }
@@ -934,9 +918,8 @@ public class VpnSettings extends PreferenceActivity implements
L2tpProfile l2tpProfile = (L2tpProfile) p; L2tpProfile l2tpProfile = (L2tpProfile) p;
if (l2tpProfile.isSecretEnabled()) { if (l2tpProfile.isSecretEnabled()) {
String secret = l2tpProfile.getSecretString(); String secret = l2tpProfile.getSecretString();
String keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); String key = KEY_PREFIX_L2TP_SECRET + p.getId();
if (TextUtils.isEmpty(secret) if (TextUtils.isEmpty(secret) || !mKeyStore.contains(key)) {
|| !secretSet.contains(keyName)) {
l2tpProfile.setSecretString(null); l2tpProfile.setSecretString(null);
secretMissing = true; secretMissing = true;
} }
@@ -953,35 +936,30 @@ public class VpnSettings extends PreferenceActivity implements
} }
private void processSecrets(VpnProfile p) { private void processSecrets(VpnProfile p) {
Keystore ks = Keystore.getInstance();
switch (p.getType()) { switch (p.getType()) {
case L2TP_IPSEC_PSK: case L2TP_IPSEC_PSK:
L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p; L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p;
String presharedKey = pskProfile.getPresharedKey(); String presharedKey = pskProfile.getPresharedKey();
String keyName = KEY_PREFIX_IPSEC_PSK + p.getId(); String key = KEY_PREFIX_IPSEC_PSK + p.getId();
if (!TextUtils.isEmpty(presharedKey)) { if (!TextUtils.isEmpty(presharedKey) &&
int ret = ks.put(NAMESPACE_VPN, keyName, presharedKey); !mKeyStore.put(key, presharedKey)) {
if (ret != 0) { Log.e(TAG, "keystore write failed: key=" + key);
Log.e(TAG, "keystore write failed: key=" + keyName);
}
} }
pskProfile.setPresharedKey(keyNameForDaemon(keyName)); pskProfile.setPresharedKey(key);
// pass through // pass through
case L2TP: case L2TP:
L2tpProfile l2tpProfile = (L2tpProfile) p; L2tpProfile l2tpProfile = (L2tpProfile) p;
keyName = KEY_PREFIX_L2TP_SECRET + p.getId(); key = KEY_PREFIX_L2TP_SECRET + p.getId();
if (l2tpProfile.isSecretEnabled()) { if (l2tpProfile.isSecretEnabled()) {
String secret = l2tpProfile.getSecretString(); String secret = l2tpProfile.getSecretString();
if (!TextUtils.isEmpty(secret)) { if (!TextUtils.isEmpty(secret) &&
int ret = ks.put(NAMESPACE_VPN, keyName, secret); !mKeyStore.put(key, secret)) {
if (ret != 0) { Log.e(TAG, "keystore write failed: key=" + key);
Log.e(TAG, "keystore write failed: key=" + keyName);
}
} }
l2tpProfile.setSecretString(keyNameForDaemon(keyName)); l2tpProfile.setSecretString(key);
} else { } else {
ks.remove(NAMESPACE_VPN, keyName); mKeyStore.delete(key);
} }
break; break;
} }