mirror of
https://github.com/moparisthebest/k-9
synced 2025-02-25 07:01:50 -05:00
Remove trusted socket factory statics
This commit is contained in:
parent
27e0c75021
commit
16f8a3ef14
@ -30,6 +30,8 @@ import com.fsck.k9.mail.MessagingException;
|
|||||||
import com.fsck.k9.mail.Store;
|
import com.fsck.k9.mail.Store;
|
||||||
import com.fsck.k9.mail.Folder.FolderClass;
|
import com.fsck.k9.mail.Folder.FolderClass;
|
||||||
import com.fsck.k9.mail.filter.Base64;
|
import com.fsck.k9.mail.filter.Base64;
|
||||||
|
import com.fsck.k9.mail.ssl.DefaultTrustedSocketFactory;
|
||||||
|
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
||||||
import com.fsck.k9.mail.store.RemoteStore;
|
import com.fsck.k9.mail.store.RemoteStore;
|
||||||
import com.fsck.k9.mail.store.StoreConfig;
|
import com.fsck.k9.mail.store.StoreConfig;
|
||||||
import com.fsck.k9.mailstore.StorageManager;
|
import com.fsck.k9.mailstore.StorageManager;
|
||||||
@ -890,6 +892,11 @@ public class Account implements BaseAccount, StoreConfig {
|
|||||||
return Uri.parse("content://accounts/" + getUuid());
|
return Uri.parse("content://accounts/" + getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TrustedSocketFactory trustedSocketFactory() {
|
||||||
|
return new DefaultTrustedSocketFactory(K9.app);
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized String getStoreUri() {
|
public synchronized String getStoreUri() {
|
||||||
return mStoreUri;
|
return mStoreUri;
|
||||||
}
|
}
|
||||||
|
169
src/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java
Normal file
169
src/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
package com.fsck.k9.mail.ssl;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.fsck.k9.mail.MessagingException;
|
||||||
|
|
||||||
|
import javax.net.ssl.KeyManager;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter and reorder list of cipher suites and TLS versions.
|
||||||
|
*/
|
||||||
|
public class DefaultTrustedSocketFactory implements TrustedSocketFactory {
|
||||||
|
protected static final String ENABLED_CIPHERS[];
|
||||||
|
protected static final String ENABLED_PROTOCOLS[];
|
||||||
|
|
||||||
|
// Order taken from OpenSSL 1.0.1c
|
||||||
|
protected static final String ORDERED_KNOWN_CIPHERS[] = {
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_RSA_WITH_AES_256_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||||
|
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
|
||||||
|
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
|
||||||
|
"TLS_ECDH_RSA_WITH_RC4_128_SHA",
|
||||||
|
"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
|
||||||
|
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
|
||||||
|
"SSL_RSA_WITH_RC4_128_SHA",
|
||||||
|
"SSL_RSA_WITH_RC4_128_MD5",
|
||||||
|
};
|
||||||
|
|
||||||
|
protected static final String[] BLACKLISTED_CIPHERS = {
|
||||||
|
"SSL_RSA_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
|
||||||
|
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
|
||||||
|
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
||||||
|
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
||||||
|
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
|
||||||
|
};
|
||||||
|
|
||||||
|
protected static final String ORDERED_KNOWN_PROTOCOLS[] = {
|
||||||
|
"TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"
|
||||||
|
};
|
||||||
|
|
||||||
|
static {
|
||||||
|
String[] enabledCiphers = null;
|
||||||
|
String[] supportedProtocols = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
|
sslContext.init(null, null, null);
|
||||||
|
SSLSocketFactory sf = sslContext.getSocketFactory();
|
||||||
|
SSLSocket sock = (SSLSocket) sf.createSocket();
|
||||||
|
enabledCiphers = sock.getEnabledCipherSuites();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retrieve all supported protocols, not just the (default) enabled
|
||||||
|
* ones. TLSv1.1 & TLSv1.2 are supported on API levels 16+, but are
|
||||||
|
* only enabled by default on API levels 20+.
|
||||||
|
*/
|
||||||
|
supportedProtocols = sock.getSupportedProtocols();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOG_TAG, "Error getting information about available SSL/TLS ciphers and " +
|
||||||
|
"protocols", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENABLED_CIPHERS = (enabledCiphers == null) ? null :
|
||||||
|
reorder(enabledCiphers, ORDERED_KNOWN_CIPHERS, BLACKLISTED_CIPHERS);
|
||||||
|
|
||||||
|
ENABLED_PROTOCOLS = (supportedProtocols == null) ? null :
|
||||||
|
reorder(supportedProtocols, ORDERED_KNOWN_PROTOCOLS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultTrustedSocketFactory(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String[] reorder(String[] enabled, String[] known, String[] blacklisted) {
|
||||||
|
List<String> unknown = new ArrayList<String>();
|
||||||
|
Collections.addAll(unknown, enabled);
|
||||||
|
|
||||||
|
// Remove blacklisted items
|
||||||
|
if (blacklisted != null) {
|
||||||
|
for (String item : blacklisted) {
|
||||||
|
unknown.remove(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Order known items
|
||||||
|
List<String> result = new ArrayList<String>();
|
||||||
|
for (String item : known) {
|
||||||
|
if (unknown.remove(item)) {
|
||||||
|
result.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add unknown items at the end. This way security won't get worse when unknown ciphers
|
||||||
|
// start showing up in the future.
|
||||||
|
result.addAll(unknown);
|
||||||
|
|
||||||
|
return result.toArray(new String[result.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public Socket createSocket(Socket socket, String host, int port, String clientCertificateAlias)
|
||||||
|
throws NoSuchAlgorithmException, KeyManagementException, MessagingException, IOException {
|
||||||
|
|
||||||
|
TrustManager[] trustManagers = new TrustManager[] { TrustManagerFactory.get(host, port) };
|
||||||
|
KeyManager[] keyManagers = null;
|
||||||
|
if (!TextUtils.isEmpty(clientCertificateAlias)) {
|
||||||
|
keyManagers = new KeyManager[] { new KeyChainKeyManager(context, clientCertificateAlias) };
|
||||||
|
}
|
||||||
|
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
|
sslContext.init(keyManagers, trustManagers, null);
|
||||||
|
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
|
||||||
|
Socket trustedSocket;
|
||||||
|
if (socket == null) {
|
||||||
|
trustedSocket = socketFactory.createSocket();
|
||||||
|
} else {
|
||||||
|
trustedSocket = socketFactory.createSocket(socket, host, port, true);
|
||||||
|
}
|
||||||
|
hardenSocket((SSLSocket) trustedSocket);
|
||||||
|
return trustedSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void hardenSocket(SSLSocket sock) {
|
||||||
|
if (ENABLED_CIPHERS != null) {
|
||||||
|
sock.setEnabledCipherSuites(ENABLED_CIPHERS);
|
||||||
|
}
|
||||||
|
if (ENABLED_PROTOCOLS != null) {
|
||||||
|
sock.setEnabledProtocols(ENABLED_PROTOCOLS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,168 +1,13 @@
|
|||||||
package com.fsck.k9.mail.ssl;
|
package com.fsck.k9.mail.ssl;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.fsck.k9.K9;
|
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
|
|
||||||
import javax.net.ssl.KeyManager;
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.SSLSocket;
|
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
|
public interface TrustedSocketFactory {
|
||||||
|
Socket createSocket(Socket socket, String host, int port, String clientCertificateAlias)
|
||||||
|
throws NoSuchAlgorithmException, KeyManagementException, MessagingException, IOException;
|
||||||
/**
|
|
||||||
* Filter and reorder list of cipher suites and TLS versions.
|
|
||||||
*/
|
|
||||||
public class TrustedSocketFactory {
|
|
||||||
protected static final String ENABLED_CIPHERS[];
|
|
||||||
protected static final String ENABLED_PROTOCOLS[];
|
|
||||||
|
|
||||||
// Order taken from OpenSSL 1.0.1c
|
|
||||||
protected static final String ORDERED_KNOWN_CIPHERS[] = {
|
|
||||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_RSA_WITH_AES_256_CBC_SHA",
|
|
||||||
"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_RSA_WITH_AES_128_CBC_SHA",
|
|
||||||
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
|
|
||||||
"TLS_ECDH_RSA_WITH_RC4_128_SHA",
|
|
||||||
"TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
|
|
||||||
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
|
|
||||||
"SSL_RSA_WITH_RC4_128_SHA",
|
|
||||||
"SSL_RSA_WITH_RC4_128_MD5",
|
|
||||||
};
|
|
||||||
|
|
||||||
protected static final String[] BLACKLISTED_CIPHERS = {
|
|
||||||
"SSL_RSA_WITH_DES_CBC_SHA",
|
|
||||||
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
|
|
||||||
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
|
|
||||||
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
|
|
||||||
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
|
||||||
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
|
|
||||||
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
|
|
||||||
};
|
|
||||||
|
|
||||||
protected static final String ORDERED_KNOWN_PROTOCOLS[] = {
|
|
||||||
"TLSv1.2", "TLSv1.1", "TLSv1", "SSLv3"
|
|
||||||
};
|
|
||||||
|
|
||||||
static {
|
|
||||||
String[] enabledCiphers = null;
|
|
||||||
String[] supportedProtocols = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
|
||||||
sslContext.init(null, null, null);
|
|
||||||
SSLSocketFactory sf = sslContext.getSocketFactory();
|
|
||||||
SSLSocket sock = (SSLSocket) sf.createSocket();
|
|
||||||
enabledCiphers = sock.getEnabledCipherSuites();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Retrieve all supported protocols, not just the (default) enabled
|
|
||||||
* ones. TLSv1.1 & TLSv1.2 are supported on API levels 16+, but are
|
|
||||||
* only enabled by default on API levels 20+.
|
|
||||||
*/
|
|
||||||
supportedProtocols = sock.getSupportedProtocols();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOG_TAG, "Error getting information about available SSL/TLS ciphers and " +
|
|
||||||
"protocols", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
ENABLED_CIPHERS = (enabledCiphers == null) ? null :
|
|
||||||
reorder(enabledCiphers, ORDERED_KNOWN_CIPHERS, BLACKLISTED_CIPHERS);
|
|
||||||
|
|
||||||
ENABLED_PROTOCOLS = (supportedProtocols == null) ? null :
|
|
||||||
reorder(supportedProtocols, ORDERED_KNOWN_PROTOCOLS, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String[] reorder(String[] enabled, String[] known, String[] blacklisted) {
|
|
||||||
List<String> unknown = new ArrayList<String>();
|
|
||||||
Collections.addAll(unknown, enabled);
|
|
||||||
|
|
||||||
// Remove blacklisted items
|
|
||||||
if (blacklisted != null) {
|
|
||||||
for (String item : blacklisted) {
|
|
||||||
unknown.remove(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order known items
|
|
||||||
List<String> result = new ArrayList<String>();
|
|
||||||
for (String item : known) {
|
|
||||||
if (unknown.remove(item)) {
|
|
||||||
result.add(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add unknown items at the end. This way security won't get worse when unknown ciphers
|
|
||||||
// start showing up in the future.
|
|
||||||
result.addAll(unknown);
|
|
||||||
|
|
||||||
return result.toArray(new String[result.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Socket createSocket(String host, int port, String clientCertificateAlias)
|
|
||||||
throws IOException, MessagingException, KeyManagementException, NoSuchAlgorithmException {
|
|
||||||
|
|
||||||
return createSocket(null, host, port, clientCertificateAlias);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Socket createSocket(Socket socket, String host, int port, String clientCertificateAlias)
|
|
||||||
throws NoSuchAlgorithmException, KeyManagementException, MessagingException, IOException {
|
|
||||||
|
|
||||||
TrustManager[] trustManagers = new TrustManager[] { TrustManagerFactory.get(host, port) };
|
|
||||||
KeyManager[] keyManagers = null;
|
|
||||||
if (clientCertificateAlias != null && !clientCertificateAlias.isEmpty()) {
|
|
||||||
keyManagers = new KeyManager[] { new KeyChainKeyManager(K9.app, clientCertificateAlias) };
|
|
||||||
}
|
|
||||||
|
|
||||||
SSLContext context = SSLContext.getInstance("TLS");
|
|
||||||
context.init(keyManagers, trustManagers, null);
|
|
||||||
SSLSocketFactory socketFactory = context.getSocketFactory();
|
|
||||||
Socket trustedSocket;
|
|
||||||
if (socket == null) {
|
|
||||||
trustedSocket = socketFactory.createSocket();
|
|
||||||
} else {
|
|
||||||
trustedSocket = socketFactory.createSocket(socket, host, port, true);
|
|
||||||
}
|
|
||||||
hardenSocket((SSLSocket) trustedSocket);
|
|
||||||
return trustedSocket;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void hardenSocket(SSLSocket sock) {
|
|
||||||
if (ENABLED_CIPHERS != null) {
|
|
||||||
sock.setEnabledCipherSuites(ENABLED_CIPHERS);
|
|
||||||
}
|
|
||||||
if (ENABLED_PROTOCOLS != null) {
|
|
||||||
sock.setEnabledProtocols(ENABLED_PROTOCOLS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -84,10 +84,10 @@ import com.fsck.k9.mail.internet.MimeHeader;
|
|||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
import com.fsck.k9.mail.internet.MimeMultipart;
|
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||||
import com.fsck.k9.mail.internet.MimeUtility;
|
import com.fsck.k9.mail.internet.MimeUtility;
|
||||||
|
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
||||||
import com.fsck.k9.mail.store.ImapResponseParser.ImapList;
|
import com.fsck.k9.mail.store.ImapResponseParser.ImapList;
|
||||||
import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse;
|
import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse;
|
||||||
import com.fsck.k9.mail.transport.imap.ImapSettings;
|
import com.fsck.k9.mail.transport.imap.ImapSettings;
|
||||||
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
|
||||||
|
|
||||||
import com.beetstra.jutf7.CharsetProvider;
|
import com.beetstra.jutf7.CharsetProvider;
|
||||||
import com.jcraft.jzlib.JZlib;
|
import com.jcraft.jzlib.JZlib;
|
||||||
@ -682,7 +682,7 @@ public class ImapStore extends RemoteStore {
|
|||||||
@Override
|
@Override
|
||||||
public void checkSettings() throws MessagingException {
|
public void checkSettings() throws MessagingException {
|
||||||
try {
|
try {
|
||||||
ImapConnection connection = new ImapConnection(new StoreImapSettings());
|
ImapConnection connection = new ImapConnection(new StoreImapSettings(), mStoreConfig.trustedSocketFactory());
|
||||||
connection.open();
|
connection.open();
|
||||||
autoconfigureFolders(connection);
|
autoconfigureFolders(connection);
|
||||||
connection.close();
|
connection.close();
|
||||||
@ -697,7 +697,7 @@ public class ImapStore extends RemoteStore {
|
|||||||
*/
|
*/
|
||||||
private ImapConnection getConnection() throws MessagingException {
|
private ImapConnection getConnection() throws MessagingException {
|
||||||
synchronized (mConnections) {
|
synchronized (mConnections) {
|
||||||
ImapConnection connection = null;
|
ImapConnection connection;
|
||||||
while ((connection = mConnections.poll()) != null) {
|
while ((connection = mConnections.poll()) != null) {
|
||||||
try {
|
try {
|
||||||
connection.executeSimpleCommand("NOOP");
|
connection.executeSimpleCommand("NOOP");
|
||||||
@ -707,7 +707,7 @@ public class ImapStore extends RemoteStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (connection == null) {
|
if (connection == null) {
|
||||||
connection = new ImapConnection(new StoreImapSettings());
|
connection = new ImapConnection(new StoreImapSettings(), mStoreConfig.trustedSocketFactory());
|
||||||
}
|
}
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
@ -2315,6 +2315,7 @@ public class ImapStore extends RemoteStore {
|
|||||||
* A cacheable class that stores the details for a single IMAP connection.
|
* A cacheable class that stores the details for a single IMAP connection.
|
||||||
*/
|
*/
|
||||||
public static class ImapConnection {
|
public static class ImapConnection {
|
||||||
|
private final TrustedSocketFactory socketFactory;
|
||||||
private Socket mSocket;
|
private Socket mSocket;
|
||||||
private PeekableInputStream mIn;
|
private PeekableInputStream mIn;
|
||||||
private OutputStream mOut;
|
private OutputStream mOut;
|
||||||
@ -2324,8 +2325,9 @@ public class ImapStore extends RemoteStore {
|
|||||||
|
|
||||||
private ImapSettings mSettings;
|
private ImapSettings mSettings;
|
||||||
|
|
||||||
public ImapConnection(final ImapSettings settings) {
|
public ImapConnection(final ImapSettings settings, TrustedSocketFactory socketFactory) {
|
||||||
this.mSettings = settings;
|
this.mSettings = settings;
|
||||||
|
this.socketFactory = socketFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getLogId() {
|
protected String getLogId() {
|
||||||
@ -2405,8 +2407,11 @@ public class ImapStore extends RemoteStore {
|
|||||||
mSettings.getPort());
|
mSettings.getPort());
|
||||||
|
|
||||||
if (connectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
if (connectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
||||||
mSocket = TrustedSocketFactory.createSocket(mSettings.getHost(),
|
mSocket = socketFactory.createSocket(
|
||||||
mSettings.getPort(), mSettings.getClientCertificateAlias());
|
null,
|
||||||
|
mSettings.getHost(),
|
||||||
|
mSettings.getPort(),
|
||||||
|
mSettings.getClientCertificateAlias());
|
||||||
} else {
|
} else {
|
||||||
mSocket = new Socket();
|
mSocket = new Socket();
|
||||||
}
|
}
|
||||||
@ -2455,8 +2460,10 @@ public class ImapStore extends RemoteStore {
|
|||||||
// STARTTLS
|
// STARTTLS
|
||||||
executeSimpleCommand("STARTTLS");
|
executeSimpleCommand("STARTTLS");
|
||||||
|
|
||||||
mSocket = TrustedSocketFactory.createSocket(mSocket,
|
mSocket = socketFactory.createSocket(
|
||||||
mSettings.getHost(), mSettings.getPort(),
|
mSocket,
|
||||||
|
mSettings.getHost(),
|
||||||
|
mSettings.getPort(),
|
||||||
mSettings.getClientCertificateAlias());
|
mSettings.getClientCertificateAlias());
|
||||||
mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
||||||
mIn = new PeekableInputStream(new BufferedInputStream(mSocket
|
mIn = new PeekableInputStream(new BufferedInputStream(mSocket
|
||||||
|
@ -8,7 +8,6 @@ import com.fsck.k9.mail.filter.Base64;
|
|||||||
import com.fsck.k9.mail.filter.Hex;
|
import com.fsck.k9.mail.filter.Hex;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
import com.fsck.k9.mail.CertificateValidationException;
|
import com.fsck.k9.mail.CertificateValidationException;
|
||||||
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
|
||||||
import com.fsck.k9.mail.MessageRetrievalListener;
|
import com.fsck.k9.mail.MessageRetrievalListener;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
@ -303,7 +302,7 @@ public class Pop3Store extends RemoteStore {
|
|||||||
try {
|
try {
|
||||||
SocketAddress socketAddress = new InetSocketAddress(mHost, mPort);
|
SocketAddress socketAddress = new InetSocketAddress(mHost, mPort);
|
||||||
if (mConnectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
if (mConnectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
||||||
mSocket = TrustedSocketFactory.createSocket(mHost, mPort, mClientCertificateAlias);
|
mSocket = mStoreConfig.trustedSocketFactory().createSocket(null, mHost, mPort, mClientCertificateAlias);
|
||||||
} else {
|
} else {
|
||||||
mSocket = new Socket();
|
mSocket = new Socket();
|
||||||
}
|
}
|
||||||
@ -325,7 +324,10 @@ public class Pop3Store extends RemoteStore {
|
|||||||
if (mCapabilities.stls) {
|
if (mCapabilities.stls) {
|
||||||
executeSimpleCommand(STLS_COMMAND);
|
executeSimpleCommand(STLS_COMMAND);
|
||||||
|
|
||||||
mSocket = TrustedSocketFactory.createSocket(mSocket, mHost, mPort,
|
mSocket = mStoreConfig.trustedSocketFactory().createSocket(
|
||||||
|
mSocket,
|
||||||
|
mHost,
|
||||||
|
mPort,
|
||||||
mClientCertificateAlias);
|
mClientCertificateAlias);
|
||||||
mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
|
||||||
mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
|
mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.fsck.k9.mail.store;
|
package com.fsck.k9.mail.store;
|
||||||
|
|
||||||
|
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
||||||
|
|
||||||
public interface StoreConfig {
|
public interface StoreConfig {
|
||||||
String getStoreUri();
|
String getStoreUri();
|
||||||
String getTransportUri();
|
String getTransportUri();
|
||||||
@ -28,4 +30,6 @@ public interface StoreConfig {
|
|||||||
int getDisplayCount();
|
int getDisplayCount();
|
||||||
|
|
||||||
int getIdleRefreshMinutes();
|
int getIdleRefreshMinutes();
|
||||||
|
|
||||||
|
TrustedSocketFactory trustedSocketFactory();
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ import com.fsck.k9.mail.filter.PeekableInputStream;
|
|||||||
import com.fsck.k9.mail.filter.SmtpDataStuffing;
|
import com.fsck.k9.mail.filter.SmtpDataStuffing;
|
||||||
import com.fsck.k9.mail.internet.CharsetSupport;
|
import com.fsck.k9.mail.internet.CharsetSupport;
|
||||||
import com.fsck.k9.mail.CertificateValidationException;
|
import com.fsck.k9.mail.CertificateValidationException;
|
||||||
import com.fsck.k9.mail.store.StoreConfig;
|
|
||||||
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
import com.fsck.k9.mail.ssl.TrustedSocketFactory;
|
||||||
|
import com.fsck.k9.mail.store.StoreConfig;
|
||||||
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
|
|
||||||
@ -30,6 +30,8 @@ import static com.fsck.k9.mail.K9MailLib.LOG_TAG;
|
|||||||
import static com.fsck.k9.mail.CertificateValidationException.Reason.MissingCapability;
|
import static com.fsck.k9.mail.CertificateValidationException.Reason.MissingCapability;
|
||||||
|
|
||||||
public class SmtpTransport extends Transport {
|
public class SmtpTransport extends Transport {
|
||||||
|
private TrustedSocketFactory mTrustedSocketFactory;
|
||||||
|
|
||||||
public static final String TRANSPORT_TYPE = "SMTP";
|
public static final String TRANSPORT_TYPE = "SMTP";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,6 +203,7 @@ public class SmtpTransport extends Transport {
|
|||||||
mUsername = settings.username;
|
mUsername = settings.username;
|
||||||
mPassword = settings.password;
|
mPassword = settings.password;
|
||||||
mClientCertificateAlias = settings.clientCertificateAlias;
|
mClientCertificateAlias = settings.clientCertificateAlias;
|
||||||
|
mTrustedSocketFactory = storeConfig.trustedSocketFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -212,7 +215,7 @@ public class SmtpTransport extends Transport {
|
|||||||
try {
|
try {
|
||||||
SocketAddress socketAddress = new InetSocketAddress(addresses[i], mPort);
|
SocketAddress socketAddress = new InetSocketAddress(addresses[i], mPort);
|
||||||
if (mConnectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
if (mConnectionSecurity == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
||||||
mSocket = TrustedSocketFactory.createSocket(mHost, mPort, mClientCertificateAlias);
|
mSocket = mTrustedSocketFactory.createSocket(null, mHost, mPort, mClientCertificateAlias);
|
||||||
mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
|
mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
|
||||||
secureConnection = true;
|
secureConnection = true;
|
||||||
} else {
|
} else {
|
||||||
@ -266,7 +269,10 @@ public class SmtpTransport extends Transport {
|
|||||||
if (extensions.containsKey("STARTTLS")) {
|
if (extensions.containsKey("STARTTLS")) {
|
||||||
executeSimpleCommand("STARTTLS");
|
executeSimpleCommand("STARTTLS");
|
||||||
|
|
||||||
mSocket = TrustedSocketFactory.createSocket(mSocket, mHost, mPort,
|
mSocket = mTrustedSocketFactory.createSocket(
|
||||||
|
mSocket,
|
||||||
|
mHost,
|
||||||
|
mPort,
|
||||||
mClientCertificateAlias);
|
mClientCertificateAlias);
|
||||||
|
|
||||||
mIn = new PeekableInputStream(new BufferedInputStream(mSocket.getInputStream(),
|
mIn = new PeekableInputStream(new BufferedInputStream(mSocket.getInputStream(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user