Repository: thunderbird/thunderbird-android (language: kotlin)

Issue:
Move `DefaultTrustedSocketFactory`
`DefaultTrustedSocketFactory` depends on the Android SDK and therefore should not live inside the `:mail:common` Gradle project.

Related class: `KeyChainKeyManager`


Discussion hints:
nan

Pull request: Move `DefaultTrustedSocketFactory`
Closes #6012

Test command: ./gradlew :mail:protocols:webdav:testDebugUnitTest --tests "com.fsck.k9.mail.store.webdav.WebDavStoreTest"

Fix patch:
diff --git a/app/core/src/main/java/com/fsck/k9/KoinModule.kt b/app/core/src/main/java/com/fsck/k9/KoinModule.kt
index 05c30287cc1..85cacac5b97 100644
--- a/app/core/src/main/java/com/fsck/k9/KoinModule.kt
+++ b/app/core/src/main/java/com/fsck/k9/KoinModule.kt
@@ -2,7 +2,7 @@ package com.fsck.k9
 
 import android.content.Context
 import com.fsck.k9.helper.Contacts
-import com.fsck.k9.mail.ssl.DefaultTrustedSocketFactory
+import com.fsck.k9.helper.DefaultTrustedSocketFactory
 import com.fsck.k9.mail.ssl.LocalKeyStore
 import com.fsck.k9.mail.ssl.TrustManagerFactory
 import com.fsck.k9.mail.ssl.TrustedSocketFactory
diff --git a/mail/common/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java b/app/core/src/main/java/com/fsck/k9/helper/DefaultTrustedSocketFactory.java
similarity index 97%
rename from mail/common/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java
rename to app/core/src/main/java/com/fsck/k9/helper/DefaultTrustedSocketFactory.java
index 4c9857e024a..ce046daa9e1 100644
--- a/mail/common/src/main/java/com/fsck/k9/mail/ssl/DefaultTrustedSocketFactory.java
+++ b/app/core/src/main/java/com/fsck/k9/helper/DefaultTrustedSocketFactory.java
@@ -1,4 +1,4 @@
-package com.fsck.k9.mail.ssl;
+package com.fsck.k9.helper;
 
 
 import java.io.IOException;
@@ -14,6 +14,8 @@
 import android.text.TextUtils;
 
 import com.fsck.k9.mail.MessagingException;
+import com.fsck.k9.mail.ssl.TrustManagerFactory;
+import com.fsck.k9.mail.ssl.TrustedSocketFactory;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
diff --git a/mail/common/src/main/java/com/fsck/k9/mail/ssl/KeyChainKeyManager.java b/app/core/src/main/java/com/fsck/k9/helper/KeyChainKeyManager.java
similarity index 99%
rename from mail/common/src/main/java/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
rename to app/core/src/main/java/com/fsck/k9/helper/KeyChainKeyManager.java
index bfd90c196c9..77e9fc4f834 100644
--- a/mail/common/src/main/java/com/fsck/k9/mail/ssl/KeyChainKeyManager.java
+++ b/app/core/src/main/java/com/fsck/k9/helper/KeyChainKeyManager.java
@@ -1,5 +1,5 @@
 
-package com.fsck.k9.mail.ssl;
+package com.fsck.k9.helper;
 
 import java.net.Socket;
 import java.security.Principal;
diff --git a/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt b/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt
index 8dd9438a3cc..5585a2bdcc1 100644
--- a/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt
+++ b/app/k9mail/src/main/java/com/fsck/k9/backends/KoinModule.kt
@@ -5,7 +5,9 @@ import app.k9mail.dev.developmentModuleAdditions
 import com.fsck.k9.backend.BackendManager
 import com.fsck.k9.backend.imap.BackendIdleRefreshManager
 import com.fsck.k9.backend.imap.SystemAlarmManager
+import com.fsck.k9.helper.DefaultTrustedSocketFactory
 import com.fsck.k9.mail.store.imap.IdleRefreshManager
+import com.fsck.k9.mail.store.webdav.SniHostSetter
 import org.koin.dsl.module
 
 val backendsModule = module {
@@ -30,7 +32,19 @@ val backendsModule = module {
     single<SystemAlarmManager> { AndroidAlarmManager(context = get(), alarmManager = get()) }
     single<IdleRefreshManager> { BackendIdleRefreshManager(alarmManager = get()) }
     single { Pop3BackendFactory(get(), get()) }
-    single { WebDavBackendFactory(get(), get(), get()) }
+    single {
+        WebDavBackendFactory(
+            backendStorageFactory = get(),
+            trustManagerFactory = get(),
+            sniHostSetter = get(),
+            folderRepository = get()
+        )
+    }
+    single {
+        SniHostSetter { factory, socket, hostname ->
+            DefaultTrustedSocketFactory.setSniHost(factory, socket, hostname)
+        }
+    }
 
     developmentModuleAdditions()
 }
diff --git a/app/k9mail/src/main/java/com/fsck/k9/backends/WebDavBackendFactory.kt b/app/k9mail/src/main/java/com/fsck/k9/backends/WebDavBackendFactory.kt
index 0098b96e468..0e4e588e335 100644
--- a/app/k9mail/src/main/java/com/fsck/k9/backends/WebDavBackendFactory.kt
+++ b/app/k9mail/src/main/java/com/fsck/k9/backends/WebDavBackendFactory.kt
@@ -6,6 +6,7 @@ import com.fsck.k9.backend.api.Backend
 import com.fsck.k9.backend.webdav.WebDavBackend
 import com.fsck.k9.mail.ssl.TrustManagerFactory
 import com.fsck.k9.mail.store.webdav.DraftsFolderProvider
+import com.fsck.k9.mail.store.webdav.SniHostSetter
 import com.fsck.k9.mail.store.webdav.WebDavStore
 import com.fsck.k9.mail.transport.WebDavTransport
 import com.fsck.k9.mailstore.FolderRepository
@@ -14,6 +15,7 @@ import com.fsck.k9.mailstore.K9BackendStorageFactory
 class WebDavBackendFactory(
     private val backendStorageFactory: K9BackendStorageFactory,
     private val trustManagerFactory: TrustManagerFactory,
+    private val sniHostSetter: SniHostSetter,
     private val folderRepository: FolderRepository
 ) : BackendFactory {
     override fun createBackend(account: Account): Backend {
@@ -21,8 +23,8 @@ class WebDavBackendFactory(
         val backendStorage = backendStorageFactory.createBackendStorage(account)
         val serverSettings = account.incomingServerSettings
         val draftsFolderProvider = createDraftsFolderProvider(account)
-        val webDavStore = WebDavStore(trustManagerFactory, serverSettings, draftsFolderProvider)
-        val webDavTransport = WebDavTransport(trustManagerFactory, serverSettings, draftsFolderProvider)
+        val webDavStore = WebDavStore(trustManagerFactory, sniHostSetter, serverSettings, draftsFolderProvider)
+        val webDavTransport = WebDavTransport(trustManagerFactory, sniHostSetter, serverSettings, draftsFolderProvider)
         return WebDavBackend(accountName, backendStorage, webDavStore, webDavTransport)
     }
 
diff --git a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/SniHostSetter.java b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/SniHostSetter.java
new file mode 100644
index 00000000000..df323946ac2
--- /dev/null
+++ b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/SniHostSetter.java
@@ -0,0 +1,10 @@
+package com.fsck.k9.mail.store.webdav;
+
+
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+
+public interface SniHostSetter {
+    void setSniHost(SSLSocketFactory factory, SSLSocket socket, String hostname);
+}
diff --git a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavSocketFactory.java b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavSocketFactory.java
index 20ee771fd50..36d7abd8ffa 100644
--- a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavSocketFactory.java
+++ b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavSocketFactory.java
@@ -7,7 +7,6 @@
 import java.security.KeyManagementException;
 import java.security.NoSuchAlgorithmException;
 
-import com.fsck.k9.mail.ssl.DefaultTrustedSocketFactory;
 import com.fsck.k9.mail.ssl.TrustManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocket;
@@ -22,10 +21,13 @@
  * Using two socket factories looks suspicious.
  */
 public class WebDavSocketFactory implements LayeredSocketFactory {
+    private final SniHostSetter sniHostSetter;
     private SSLSocketFactory mSocketFactory;
     private org.apache.http.conn.ssl.SSLSocketFactory mSchemeSocketFactory;
 
-    public WebDavSocketFactory(TrustManagerFactory trustManagerFactory, String host, int port) throws NoSuchAlgorithmException, KeyManagementException {
+    public WebDavSocketFactory(TrustManagerFactory trustManagerFactory, SniHostSetter sniHostSetter,
+            String host, int port) throws NoSuchAlgorithmException, KeyManagementException {
+        this.sniHostSetter = sniHostSetter;
         SSLContext sslContext = SSLContext.getInstance("TLS");
         sslContext.init(null, new TrustManager[] {
                 trustManagerFactory.getTrustManagerForDomain(host, port)
@@ -62,7 +64,7 @@ public Socket createSocket(
                 port,
                 autoClose
         );
-        DefaultTrustedSocketFactory.setSniHost(mSocketFactory, sslSocket, host);
+        sniHostSetter.setSniHost(mSocketFactory, sslSocket, host);
         //hostnameVerifier.verify(host, sslSocket);
         // verifyHostName() didn't blowup - good!
         return sslSocket;
diff --git a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java
index bad815cca93..c11282ac4ca 100644
--- a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java
+++ b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/store/webdav/WebDavStore.java
@@ -73,6 +73,7 @@ public class WebDavStore {
     private String mailboxPath;
 
     private final TrustManagerFactory trustManagerFactory;
+    private final SniHostSetter sniHostSetter;
     private final WebDavHttpClient.WebDavHttpClientFactory httpClientFactory;
     private WebDavHttpClient httpClient = null;
     private HttpContext httpContext = null;
@@ -84,16 +85,19 @@ public class WebDavStore {
     private WebDavFolder sendFolder = null;
     private Map<String, WebDavFolder> folderList = new HashMap<>();
 
-    public WebDavStore(TrustManagerFactory trustManagerFactory, ServerSettings serverSettings,
-            DraftsFolderProvider draftsFolderProvider) {
-        this(trustManagerFactory, serverSettings, draftsFolderProvider, new WebDavHttpClient.WebDavHttpClientFactory());
+    public WebDavStore(TrustManagerFactory trustManagerFactory, SniHostSetter sniHostSetter,
+            ServerSettings serverSettings, DraftsFolderProvider draftsFolderProvider) {
+        this(trustManagerFactory, sniHostSetter, serverSettings, draftsFolderProvider,
+                new WebDavHttpClient.WebDavHttpClientFactory());
     }
 
-    public WebDavStore(TrustManagerFactory trustManagerFactory, ServerSettings serverSettings,
-            DraftsFolderProvider draftsFolderProvider, WebDavHttpClientFactory clientFactory) {
+    public WebDavStore(TrustManagerFactory trustManagerFactory, SniHostSetter sniHostSetter,
+            ServerSettings serverSettings, DraftsFolderProvider draftsFolderProvider,
+            WebDavHttpClientFactory clientFactory) {
         this.draftsFolderProvider = draftsFolderProvider;
         httpClientFactory = clientFactory;
         this.trustManagerFactory = trustManagerFactory;
+        this.sniHostSetter = sniHostSetter;
 
         hostname = serverSettings.host;
         port = serverSettings.port;
@@ -765,7 +769,9 @@ public WebDavHttpClient getHttpClient() throws MessagingException {
 
             SchemeRegistry reg = httpClient.getConnectionManager().getSchemeRegistry();
             try {
-                Scheme s = new Scheme("https", new WebDavSocketFactory(trustManagerFactory, hostname, 443), 443);
+                WebDavSocketFactory socketFactory =
+                        new WebDavSocketFactory(trustManagerFactory, sniHostSetter, hostname, 443);
+                Scheme s = new Scheme("https", socketFactory, 443);
                 reg.register(s);
             } catch (NoSuchAlgorithmException nsa) {
                 Timber.e(nsa, "NoSuchAlgorithmException in getHttpClient");
diff --git a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/transport/WebDavTransport.java b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/transport/WebDavTransport.java
index a9e8cac0ac8..d133b0e740e 100644
--- a/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/transport/WebDavTransport.java
+++ b/mail/protocols/webdav/src/main/java/com/fsck/k9/mail/transport/WebDavTransport.java
@@ -10,15 +10,16 @@
 import com.fsck.k9.mail.Transport;
 import com.fsck.k9.mail.ssl.TrustManagerFactory;
 import com.fsck.k9.mail.store.webdav.DraftsFolderProvider;
+import com.fsck.k9.mail.store.webdav.SniHostSetter;
 import com.fsck.k9.mail.store.webdav.WebDavStore;
 import timber.log.Timber;
 
 public class WebDavTransport extends Transport {
     private WebDavStore store;
 
-    public WebDavTransport(TrustManagerFactory trustManagerFactory, ServerSettings serverSettings,
-            DraftsFolderProvider draftsFolderProvider) {
-        store = new WebDavStore(trustManagerFactory, serverSettings, draftsFolderProvider);
+    public WebDavTransport(TrustManagerFactory trustManagerFactory, SniHostSetter sniHostSetter,
+            ServerSettings serverSettings, DraftsFolderProvider draftsFolderProvider) {
+        store = new WebDavStore(trustManagerFactory, sniHostSetter, serverSettings, draftsFolderProvider);
 
         if (K9MailLib.isDebug())
             Timber.d(">>> New WebDavTransport creation complete");


Test patch:
diff --git a/mail/protocols/webdav/src/test/java/com/fsck/k9/mail/store/webdav/WebDavStoreTest.java b/mail/protocols/webdav/src/test/java/com/fsck/k9/mail/store/webdav/WebDavStoreTest.java
index 958ee1f1599..8cb66466e2e 100644
--- a/mail/protocols/webdav/src/test/java/com/fsck/k9/mail/store/webdav/WebDavStoreTest.java
+++ b/mail/protocols/webdav/src/test/java/com/fsck/k9/mail/store/webdav/WebDavStoreTest.java
@@ -70,6 +70,8 @@ public class WebDavStoreTest {
     @Mock
     private TrustManagerFactory trustManagerFactory;
     @Mock
+    private SniHostSetter sniHostSetter;
+    @Mock
     private DraftsFolderProvider draftsFolderProvider;
 
     private ArgumentCaptor<HttpGeneric> requestCaptor;
@@ -352,12 +354,14 @@ private ServerSettings createServerSettings(ConnectionSecurity connectionSecurit
     }
 
     private WebDavStore createWebDavStore() {
-        return new WebDavStore(trustManagerFactory, serverSettings, draftsFolderProvider, mockHttpClientFactory);
+        return new WebDavStore(trustManagerFactory, sniHostSetter, serverSettings, draftsFolderProvider,
+                mockHttpClientFactory);
     }
 
     private WebDavStore createWebDavStore(ConnectionSecurity connectionSecurity) {
         ServerSettings serverSettings = createServerSettings(connectionSecurity);
-        return new WebDavStore(trustManagerFactory, serverSettings, draftsFolderProvider, mockHttpClientFactory);
+        return new WebDavStore(trustManagerFactory, sniHostSetter, serverSettings, draftsFolderProvider,
+                mockHttpClientFactory);
     }
 
     private void configureHttpResponses(HttpResponse... responses) throws IOException {