diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/svr/InternalSvrPlaygroundViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/svr/InternalSvrPlaygroundViewModel.kt index 4deb36ce2c..5ecdfe1804 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/svr/InternalSvrPlaygroundViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/svr/InternalSvrPlaygroundViewModel.kt @@ -105,7 +105,7 @@ class InternalSvrPlaygroundViewModel : ViewModel() { private fun SvrImplementation.toImplementation(): SecureValueRecovery { return when (this) { SvrImplementation.SVR2 -> AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV2(BuildConfig.SVR2_MRENCLAVE) - SvrImplementation.SVR3 -> AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV3(AppDependencies.libsignalNetwork.network, TestShareSetStorage()) + SvrImplementation.SVR3 -> AppDependencies.signalServiceAccountManager.getSecureValueRecoveryV3(AppDependencies.libsignalNetwork, TestShareSetStorage()) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt index 1f4974c547..6c327d37fb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt @@ -9,6 +9,7 @@ import io.reactivex.rxjava3.subjects.Subject import okhttp3.OkHttpClient import org.signal.core.util.concurrent.DeadlockDetector import org.signal.core.util.resettableLazy +import org.signal.libsignal.net.Network import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations import org.thoughtcrime.securesms.components.TypingStatusRepository @@ -50,7 +51,6 @@ import org.whispersystems.signalservice.api.services.DonationsService import org.whispersystems.signalservice.api.services.ProfileService import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration -import org.whispersystems.signalservice.internal.websocket.LibSignalNetwork import java.util.function.Supplier /** @@ -249,7 +249,7 @@ object AppDependencies { get() = networkModule.incomingMessageObserver @JvmStatic - val libsignalNetwork: LibSignalNetwork + val libsignalNetwork: Network get() = networkModule.libsignalNetwork @JvmStatic @@ -330,7 +330,7 @@ object AppDependencies { fun provideSignalCallManager(): SignalCallManager fun providePendingRetryReceiptManager(): PendingRetryReceiptManager fun providePendingRetryReceiptCache(): PendingRetryReceiptCache - fun provideSignalWebSocket(signalServiceConfigurationSupplier: Supplier, libSignalNetworkSupplier: Supplier): SignalWebSocket + fun provideSignalWebSocket(signalServiceConfigurationSupplier: Supplier, libSignalNetworkSupplier: Supplier): SignalWebSocket fun provideProtocolStore(): SignalServiceDataStoreImpl fun provideGiphyMp4Cache(): GiphyMp4Cache fun provideExoPlayerPool(): SimpleExoPlayerPool @@ -341,6 +341,6 @@ object AppDependencies { fun provideDeadlockDetector(): DeadlockDetector fun provideClientZkReceiptOperations(signalServiceConfiguration: SignalServiceConfiguration): ClientZkReceiptOperations fun provideScheduledMessageManager(): ScheduledMessageManager - fun provideLibsignalNetwork(config: SignalServiceConfiguration): LibSignalNetwork + fun provideLibsignalNetwork(config: SignalServiceConfiguration): Network } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index c0c082e8b5..7459585794 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -92,7 +92,7 @@ import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.websocket.WebSocketFactory; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; -import org.whispersystems.signalservice.internal.websocket.LibSignalNetwork; +import org.whispersystems.signalservice.internal.websocket.LibSignalNetworkExtensions; import org.whispersystems.signalservice.internal.websocket.ShadowingWebSocketConnection; import org.whispersystems.signalservice.internal.websocket.WebSocketConnection; import org.whispersystems.signalservice.internal.websocket.LibSignalChatConnection; @@ -237,8 +237,10 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { } @Override - public @NonNull LibSignalNetwork provideLibsignalNetwork(@NonNull SignalServiceConfiguration config) { - return new LibSignalNetwork(new Network(BuildConfig.LIBSIGNAL_NET_ENV, StandardUserAgentInterceptor.USER_AGENT), config); + public @NonNull Network provideLibsignalNetwork(@NonNull SignalServiceConfiguration config) { + Network network = new Network(BuildConfig.LIBSIGNAL_NET_ENV, StandardUserAgentInterceptor.USER_AGENT); + LibSignalNetworkExtensions.applyConfiguration(network, config); + return network; } @Override @@ -294,7 +296,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { } @Override - public @NonNull SignalWebSocket provideSignalWebSocket(@NonNull Supplier signalServiceConfigurationSupplier, @NonNull Supplier libSignalNetworkSupplier) { + public @NonNull SignalWebSocket provideSignalWebSocket(@NonNull Supplier signalServiceConfigurationSupplier, @NonNull Supplier libSignalNetworkSupplier) { SleepTimer sleepTimer = !SignalStore.account().isFcmEnabled() || SignalStore.internalValues().isWebsocketModeForced() ? new AlarmSleepTimer(context) : new UptimeSleepTimer() ; SignalWebSocketHealthMonitor healthMonitor = new SignalWebSocketHealthMonitor(context, sleepTimer); WebSocketShadowingBridge bridge = new DefaultWebSocketShadowingBridge(context); @@ -407,7 +409,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { @NonNull WebSocketFactory provideWebSocketFactory(@NonNull Supplier signalServiceConfigurationSupplier, @NonNull SignalWebSocketHealthMonitor healthMonitor, - @NonNull Supplier libSignalNetworkSupplier, + @NonNull Supplier libSignalNetworkSupplier, @NonNull WebSocketShadowingBridge bridge) { return new WebSocketFactory() { @@ -432,16 +434,16 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { BuildConfig.SIGNAL_AGENT, healthMonitor, Stories.isFeatureEnabled(), - libSignalNetworkSupplier.get().createChatService(null), + LibSignalNetworkExtensions.createChatService(libSignalNetworkSupplier.get(), null), shadowPercentage, bridge ); } if (FeatureFlags.libSignalWebSocketEnabled()) { - LibSignalNetwork network = libSignalNetworkSupplier.get(); + Network network = libSignalNetworkSupplier.get(); return new LibSignalChatConnection( "libsignal-unauth", - network.createChatService(null), + LibSignalNetworkExtensions.createChatService(network, null), healthMonitor, false); } else { diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt index 750d2c3328..12912c31ce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt @@ -12,6 +12,7 @@ import io.reactivex.rxjava3.subjects.Subject import okhttp3.ConnectionSpec import okhttp3.OkHttpClient import org.signal.core.util.resettableLazy +import org.signal.libsignal.net.Network import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations import org.thoughtcrime.securesms.crypto.storage.SignalServiceDataStoreImpl import org.thoughtcrime.securesms.groups.GroupsV2Authorization @@ -35,7 +36,6 @@ import org.whispersystems.signalservice.api.util.Tls12SocketFactory import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState import org.whispersystems.signalservice.internal.util.BlacklistingTrustManager import org.whispersystems.signalservice.internal.util.Util -import org.whispersystems.signalservice.internal.websocket.LibSignalNetwork import java.security.KeyManagementException import java.security.NoSuchAlgorithmException import javax.net.ssl.SSLContext @@ -75,7 +75,7 @@ class NetworkDependenciesModule( provider.provideSignalServiceAccountManager(signalServiceNetworkAccess.getConfiguration(), groupsV2Operations) } - val libsignalNetwork: LibSignalNetwork by lazy { + val libsignalNetwork: Network by lazy { provider.provideLibsignalNetwork(signalServiceNetworkAccess.getConfiguration()) } diff --git a/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java b/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java index 8dd3ad67d7..02e21f158f 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java +++ b/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.java @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.dependencies; import androidx.annotation.NonNull; import org.signal.core.util.concurrent.DeadlockDetector; +import org.signal.libsignal.net.Network; import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations; import org.thoughtcrime.securesms.components.TypingStatusRepository; @@ -42,7 +43,6 @@ import org.whispersystems.signalservice.api.services.CallLinksService; import org.whispersystems.signalservice.api.services.DonationsService; import org.whispersystems.signalservice.api.services.ProfileService; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; -import org.whispersystems.signalservice.internal.websocket.LibSignalNetwork; import java.util.function.Supplier; @@ -181,7 +181,7 @@ public class MockApplicationDependencyProvider implements AppDependencies.Provid } @Override - public @NonNull SignalWebSocket provideSignalWebSocket(@NonNull Supplier signalServiceConfigurationSupplier, @NonNull Supplier libSignalNetworkSupplier) { + public @NonNull SignalWebSocket provideSignalWebSocket(@NonNull Supplier signalServiceConfigurationSupplier, @NonNull Supplier libSignalNetworkSupplier) { return null; } @@ -235,7 +235,7 @@ public class MockApplicationDependencyProvider implements AppDependencies.Provid } @Override - public @NonNull LibSignalNetwork provideLibsignalNetwork(@NonNull SignalServiceConfiguration config) { + public @NonNull Network provideLibsignalNetwork(@NonNull SignalServiceConfiguration config) { return null; } } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java index a5f3e60304..d9eeaaa126 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java @@ -88,7 +88,6 @@ import org.whispersystems.signalservice.internal.util.StaticCredentialsProvider; import org.whispersystems.signalservice.internal.util.Util; import org.whispersystems.signalservice.internal.websocket.DefaultResponseMapper; import org.signal.core.util.Base64; -import org.whispersystems.signalservice.internal.websocket.LibSignalNetwork; import java.io.IOException; import java.security.MessageDigest; @@ -371,7 +370,7 @@ public class SignalServiceAccountManager { Optional token, String mrEnclave, Long timeoutMs, - @Nullable LibSignalNetwork libsignalNetwork, + @Nullable Network libsignalNetwork, Consumer tokenSaver) throws IOException { diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java index 7d796c51da..e6e8b83d22 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CdsiV2Service.java @@ -19,13 +19,11 @@ import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulRespons import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.ServiceResponse; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; -import org.whispersystems.signalservice.internal.websocket.LibSignalNetwork; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.lang.IllegalArgumentException; import java.nio.ByteBuffer; -import java.time.Duration; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -57,7 +55,7 @@ public final class CdsiV2Service { private final CdsiRequestHandler cdsiRequestHandler; - public CdsiV2Service(SignalServiceConfiguration configuration, String mrEnclave, @Nullable LibSignalNetwork network) { + public CdsiV2Service(SignalServiceConfiguration configuration, String mrEnclave, @Nullable Network network) { if (network != null) { this.cdsiRequestHandler = (username, password, request, tokenSaver) -> { diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalNetwork.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalNetwork.kt deleted file mode 100644 index f36be5c9be..0000000000 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalNetwork.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2024 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.signalservice.internal.websocket - -import org.signal.core.util.orNull -import org.signal.libsignal.internal.CompletableFuture -import org.signal.libsignal.net.CdsiLookupRequest -import org.signal.libsignal.net.CdsiLookupResponse -import org.signal.libsignal.net.ChatService -import org.signal.libsignal.net.Network -import org.whispersystems.signalservice.api.util.CredentialsProvider -import org.whispersystems.signalservice.internal.configuration.SignalProxy -import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration -import java.io.IOException -import java.util.concurrent.ExecutionException -import java.util.function.Consumer - -/** - * Makes Network API more ergonomic to use with Android client types - */ -class LibSignalNetwork(val network: Network, config: SignalServiceConfiguration) { - init { - resetSettings(config) - } - - fun createChatService( - credentialsProvider: CredentialsProvider? = null - ): ChatService { - val username = credentialsProvider?.username ?: "" - val password = credentialsProvider?.password ?: "" - return network.createChatService(username, password) - } - - fun resetSettings(config: SignalServiceConfiguration) { - resetProxy(config.signalProxy.orNull()) - } - - private fun resetProxy(proxy: SignalProxy?) { - if (proxy == null) { - network.clearProxy() - } else { - network.setProxy(proxy.host, proxy.port) - } - } - - // Delegates - @Throws(IOException::class, InterruptedException::class, ExecutionException::class) - fun cdsiLookup( - username: String?, - password: String?, - request: CdsiLookupRequest?, - tokenConsumer: Consumer - ): CompletableFuture? { - return network.cdsiLookup(username, password, request, tokenConsumer) - } -} diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalNetworkExtensions.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalNetworkExtensions.kt new file mode 100644 index 0000000000..4e73fc7228 --- /dev/null +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalNetworkExtensions.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ +@file:JvmName("LibSignalNetworkExtensions") + +package org.whispersystems.signalservice.internal.websocket + +import org.signal.core.util.orNull +import org.signal.libsignal.net.ChatService +import org.signal.libsignal.net.Network +import org.whispersystems.signalservice.api.util.CredentialsProvider +import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration + +/** + * Helper method to create a ChatService with optional credentials. + */ +fun Network.createChatService( + credentialsProvider: CredentialsProvider? = null +): ChatService { + val username = credentialsProvider?.username ?: "" + val password = credentialsProvider?.password ?: "" + return this.createChatService(username, password) +} + +/** + * Helper method to apply settings from the SignalServiceConfiguration. + */ +fun Network.applyConfiguration(config: SignalServiceConfiguration) { + val proxy = config.signalProxy.orNull() + + if (proxy == null) { + this.clearProxy() + } else { + this.setProxy(proxy.host, proxy.port) + } +}