mirror of
https://github.com/moparisthebest/k-9
synced 2024-12-02 14:02:17 -05:00
Implement pruning of old certificates from LocalKeyStore
Certificates are deleted whenever server settings are changed or an account is deleted.
This commit is contained in:
parent
40404c3700
commit
8eef43c282
@ -15,6 +15,7 @@ import android.util.Log;
|
|||||||
import com.fsck.k9.mail.Store;
|
import com.fsck.k9.mail.Store;
|
||||||
import com.fsck.k9.preferences.Editor;
|
import com.fsck.k9.preferences.Editor;
|
||||||
import com.fsck.k9.preferences.Storage;
|
import com.fsck.k9.preferences.Storage;
|
||||||
|
import com.fsck.k9.security.LocalKeyStore;
|
||||||
|
|
||||||
public class Preferences {
|
public class Preferences {
|
||||||
|
|
||||||
@ -128,6 +129,7 @@ public class Preferences {
|
|||||||
Store.removeAccount(account);
|
Store.removeAccount(account);
|
||||||
|
|
||||||
account.delete(this);
|
account.delete(this);
|
||||||
|
LocalKeyStore.getInstance().deleteCertificates(account);
|
||||||
|
|
||||||
if (newAccount == account) {
|
if (newAccount == account) {
|
||||||
newAccount = null;
|
newAccount = null;
|
||||||
|
@ -364,13 +364,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
try {
|
try {
|
||||||
Uri uri = null;
|
LocalKeyStore.getInstance().addCertificate(mAccount, mDirection, chain[0]);
|
||||||
if (mDirection.equals(CheckDirection.INCOMING)) {
|
|
||||||
uri = Uri.parse(mAccount.getStoreUri());
|
|
||||||
} else {
|
|
||||||
uri = Uri.parse(mAccount.getTransportUri());
|
|
||||||
}
|
|
||||||
LocalKeyStore.getInstance().addCertificate(uri.getHost(), uri.getPort(), chain[0]);
|
|
||||||
} catch (CertificateException e) {
|
} catch (CertificateException e) {
|
||||||
showErrorDialog(
|
showErrorDialog(
|
||||||
R.string.account_setup_failed_dlg_certificate_message_fmt,
|
R.string.account_setup_failed_dlg_certificate_message_fmt,
|
||||||
|
@ -26,6 +26,7 @@ import com.fsck.k9.mail.store.Pop3Store;
|
|||||||
import com.fsck.k9.mail.store.WebDavStore;
|
import com.fsck.k9.mail.store.WebDavStore;
|
||||||
import com.fsck.k9.mail.store.ImapStore.ImapStoreSettings;
|
import com.fsck.k9.mail.store.ImapStore.ImapStoreSettings;
|
||||||
import com.fsck.k9.mail.store.WebDavStore.WebDavStoreSettings;
|
import com.fsck.k9.mail.store.WebDavStore.WebDavStoreSettings;
|
||||||
|
import com.fsck.k9.security.LocalKeyStore;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -428,6 +429,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
mWebdavMailboxPathView.getText().toString());
|
mWebdavMailboxPathView.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalKeyStore.getInstance().deleteCertificate(mAccount, host, port, CheckDirection.INCOMING);
|
||||||
ServerSettings settings = new ServerSettings(mStoreType, host, port,
|
ServerSettings settings = new ServerSettings(mStoreType, host, port,
|
||||||
connectionSecurity, authType, username, password, extra);
|
connectionSecurity, authType, username, password, extra);
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import com.fsck.k9.activity.K9Activity;
|
|||||||
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
||||||
import com.fsck.k9.helper.Utility;
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.transport.SmtpTransport;
|
import com.fsck.k9.mail.transport.SmtpTransport;
|
||||||
|
import com.fsck.k9.security.LocalKeyStore;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@ -309,8 +310,10 @@ public class AccountSetupOutgoing extends K9Activity implements OnClickListener,
|
|||||||
if (mRequireLoginView.isChecked()) {
|
if (mRequireLoginView.isChecked()) {
|
||||||
userInfo = usernameEnc + ":" + passwordEnc + ":" + authType;
|
userInfo = usernameEnc + ":" + passwordEnc + ":" + authType;
|
||||||
}
|
}
|
||||||
uri = new URI(smtpSchemes[securityType], userInfo, mServerView.getText().toString(),
|
String newHost = mServerView.getText().toString();
|
||||||
Integer.parseInt(mPortView.getText().toString()), null, null, null);
|
int newPort = Integer.parseInt(mPortView.getText().toString());
|
||||||
|
uri = new URI(smtpSchemes[securityType], userInfo, newHost, newPort, null, null, null);
|
||||||
|
LocalKeyStore.getInstance().deleteCertificate(mAccount, newHost, newPort, CheckDirection.OUTGOING);
|
||||||
mAccount.setTransportUri(uri.toString());
|
mAccount.setTransportUri(uri.toString());
|
||||||
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
|
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.OUTGOING);
|
||||||
} catch (UnsupportedEncodingException enc) {
|
} catch (UnsupportedEncodingException enc) {
|
||||||
|
@ -14,9 +14,12 @@ import java.security.cert.X509Certificate;
|
|||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.activity.setup.AccountSetupCheckSettings.CheckDirection;
|
||||||
|
|
||||||
public class LocalKeyStore {
|
public class LocalKeyStore {
|
||||||
private static final LocalKeyStore sInstance = new LocalKeyStore();
|
private static final LocalKeyStore sInstance = new LocalKeyStore();
|
||||||
@ -81,9 +84,18 @@ public class LocalKeyStore {
|
|||||||
throw new CertificateException(
|
throw new CertificateException(
|
||||||
"Certificate not added because key store not initialized");
|
"Certificate not added because key store not initialized");
|
||||||
}
|
}
|
||||||
java.io.OutputStream keyStoreStream = null;
|
|
||||||
try {
|
try {
|
||||||
mKeyStore.setCertificateEntry(getCertKey(host, port), certificate);
|
mKeyStore.setCertificateEntry(getCertKey(host, port), certificate);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
throw new CertificateException(
|
||||||
|
"Failed to add certificate to local key store", e);
|
||||||
|
}
|
||||||
|
writeCertificateFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeCertificateFile() throws CertificateException {
|
||||||
|
java.io.OutputStream keyStoreStream = null;
|
||||||
|
try {
|
||||||
keyStoreStream = new java.io.FileOutputStream(mKeyStoreFile);
|
keyStoreStream = new java.io.FileOutputStream(mKeyStoreFile);
|
||||||
mKeyStore.store(keyStoreStream, "".toCharArray());
|
mKeyStore.store(keyStoreStream, "".toCharArray());
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
@ -106,8 +118,19 @@ public class LocalKeyStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean isValidCertificate(Certificate certificate, String host,
|
public void addCertificate(Account account, CheckDirection direction,
|
||||||
int port) {
|
X509Certificate certificate) throws CertificateException {
|
||||||
|
Uri uri = null;
|
||||||
|
if (direction.equals(CheckDirection.INCOMING)) {
|
||||||
|
uri = Uri.parse(account.getStoreUri());
|
||||||
|
} else {
|
||||||
|
uri = Uri.parse(account.getTransportUri());
|
||||||
|
}
|
||||||
|
addCertificate(uri.getHost(), uri.getPort(), certificate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized boolean isValidCertificate(Certificate certificate,
|
||||||
|
String host, int port) {
|
||||||
if (mKeyStore == null) {
|
if (mKeyStore == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -123,4 +146,52 @@ public class LocalKeyStore {
|
|||||||
private static String getCertKey(String host, int port) {
|
private static String getCertKey(String host, int port) {
|
||||||
return host + ":" + port;
|
return host + ":" + port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void deleteCertificate(String oldHost, int oldPort) {
|
||||||
|
if (mKeyStore == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mKeyStore.deleteEntry(getCertKey(oldHost, oldPort));
|
||||||
|
writeCertificateFile();
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
// Ignore: most likely there was no cert. found
|
||||||
|
} catch (CertificateException e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error updating the local key store file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examine the existing settings for an account. If the old host/port is different from
|
||||||
|
* the new host/port, then try and delete any (possibly non-existent) certificate stored
|
||||||
|
* for the old host/port.
|
||||||
|
* @param account
|
||||||
|
* @param newHost
|
||||||
|
* @param newPort
|
||||||
|
* @param direction
|
||||||
|
*/
|
||||||
|
public void deleteCertificate(Account account, String newHost, int newPort, CheckDirection direction) {
|
||||||
|
Uri uri = null;
|
||||||
|
if (direction.equals(CheckDirection.INCOMING)) {
|
||||||
|
uri = Uri.parse(account.getStoreUri());
|
||||||
|
} else {
|
||||||
|
uri = Uri.parse(account.getTransportUri());
|
||||||
|
}
|
||||||
|
String oldHost = uri.getHost();
|
||||||
|
int oldPort = uri.getPort();
|
||||||
|
if (!newHost.equals(oldHost) || newPort != oldPort) {
|
||||||
|
deleteCertificate(oldHost, oldPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examine the settings for the account and attempt to delete (possibly non-existent)
|
||||||
|
* certificates for the incoming and outgoing servers.
|
||||||
|
* @param account
|
||||||
|
*/
|
||||||
|
public void deleteCertificates(Account account) {
|
||||||
|
Uri uri = Uri.parse(account.getStoreUri());
|
||||||
|
deleteCertificate(uri.getHost(), uri.getPort());
|
||||||
|
uri = Uri.parse(account.getTransportUri());
|
||||||
|
deleteCertificate(uri.getHost(), uri.getPort()); }
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user