diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt index bd410915a4..ca43ef2401 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt @@ -90,7 +90,8 @@ class InstrumentationApplicationDependencyProvider(val application: Application, signalProxy = Optional.empty(), zkGroupServerPublicParams = Base64.decode(BuildConfig.ZKGROUP_SERVER_PUBLIC_PARAMS), genericServerPublicParams = Base64.decode(BuildConfig.GENERIC_SERVER_PUBLIC_PARAMS), - backupServerPublicParams = Base64.decode(BuildConfig.BACKUP_SERVER_PUBLIC_PARAMS) + backupServerPublicParams = Base64.decode(BuildConfig.BACKUP_SERVER_PUBLIC_PARAMS), + censored = false ) serviceNetworkAccessMock = mock { 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 b07c19cac7..c7588711ad 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -435,8 +435,7 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { return new LibSignalChatConnection( "libsignal-unauth", LibSignalNetworkExtensions.createChatService(network, null, Stories.isFeatureEnabled()), - healthMonitor, - false); + healthMonitor); } else { return new OkHttpWebSocketConnection("unidentified", signalServiceConfigurationSupplier.get(), diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt index 1ad55df0e4..cf927e8f3b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.kt @@ -189,7 +189,8 @@ open class SignalServiceNetworkAccess(context: Context) { signalProxy = Optional.empty(), zkGroupServerPublicParams = zkGroupServerPublicParams, genericServerPublicParams = genericServerPublicParams, - backupServerPublicParams = backupServerPublicParams + backupServerPublicParams = backupServerPublicParams, + censored = true ) private val censorshipConfiguration: Map = mapOf( @@ -247,7 +248,8 @@ open class SignalServiceNetworkAccess(context: Context) { signalProxy = if (SignalStore.proxy.isProxyEnabled) Optional.ofNullable(SignalStore.proxy.proxy) else Optional.empty(), zkGroupServerPublicParams = zkGroupServerPublicParams, genericServerPublicParams = genericServerPublicParams, - backupServerPublicParams = backupServerPublicParams + backupServerPublicParams = backupServerPublicParams, + censored = false ) open fun getConfiguration(): SignalServiceConfiguration { @@ -316,7 +318,8 @@ open class SignalServiceNetworkAccess(context: Context) { signalProxy = Optional.empty(), zkGroupServerPublicParams = zkGroupServerPublicParams, genericServerPublicParams = genericServerPublicParams, - backupServerPublicParams = backupServerPublicParams + backupServerPublicParams = backupServerPublicParams, + censored = true ) } diff --git a/dependencies.gradle.kts b/dependencies.gradle.kts index 254a5bb084..45c0a8f1a2 100644 --- a/dependencies.gradle.kts +++ b/dependencies.gradle.kts @@ -15,7 +15,7 @@ dependencyResolutionManagement { version("exoplayer", "2.19.0") version("glide", "4.15.1") version("kotlin", "1.9.20") - version("libsignal-client", "0.60.1") + version("libsignal-client", "0.62.0") version("mp4parser", "1.9.39") version("android-gradle-plugin", "8.4.0") version("accompanist", "0.28.0") diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index f80d10a518..dad5d7b743 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -8971,20 +8971,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + - - + + - - - + + + - - + + diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.kt index 4a686311cd..dfad0111e8 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/configuration/SignalServiceConfiguration.kt @@ -19,7 +19,8 @@ data class SignalServiceConfiguration( val signalProxy: Optional, val zkGroupServerPublicParams: ByteArray, val genericServerPublicParams: ByteArray, - val backupServerPublicParams: ByteArray + val backupServerPublicParams: ByteArray, + val censored: Boolean ) { /** Convenience operator overload for combining the URL lists. Does not add the other fields together, as those wouldn't make sense. */ diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnection.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnection.kt index 7f2af4d010..14d4ce76c7 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnection.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnection.kt @@ -11,7 +11,9 @@ import io.reactivex.rxjava3.schedulers.Schedulers import io.reactivex.rxjava3.subjects.BehaviorSubject import io.reactivex.rxjava3.subjects.SingleSubject import org.signal.core.util.logging.Log +import org.signal.libsignal.net.AuthenticatedChatService import org.signal.libsignal.net.ChatService +import org.signal.libsignal.net.UnauthenticatedChatService import org.whispersystems.signalservice.api.websocket.HealthMonitor import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState import org.whispersystems.signalservice.internal.util.whenComplete @@ -37,8 +39,7 @@ import org.signal.libsignal.net.ChatService.Response as LibSignalResponse class LibSignalChatConnection( name: String, private val chatService: ChatService, - private val healthMonitor: HealthMonitor, - val isAuthenticated: Boolean + private val healthMonitor: HealthMonitor ) : WebSocketConnection { companion object { @@ -86,12 +87,7 @@ class LibSignalChatConnection( override fun connect(): Observable { Log.i(TAG, "$name Connecting...") state.onNext(WebSocketConnectionState.CONNECTING) - val connect = if (isAuthenticated) { - chatService::connectAuthenticated - } else { - chatService::connectUnauthenticated - } - connect() + chatService.connect() .whenComplete( onSuccess = { debugInfo -> Log.i(TAG, "$name Connected") @@ -128,12 +124,7 @@ class LibSignalChatConnection( override fun sendRequest(request: WebSocketRequestMessage): Single { val single = SingleSubject.create() val internalRequest = request.toLibSignalRequest() - val send = if (isAuthenticated) { - throw NotImplementedError("Authenticated socket is not yet supported") - } else { - chatService::unauthenticatedSend - } - send(internalRequest) + chatService.send(internalRequest) .whenComplete( onSuccess = { response -> when (response!!.status) { @@ -143,7 +134,7 @@ class LibSignalChatConnection( } // Here success means "we received the response" even if it is reporting an error. // This is consistent with the behavior of the OkHttpWebSocketConnection. - single.onSuccess(response.toWebsocketResponse(isUnidentified = !isAuthenticated)) + single.onSuccess(response.toWebsocketResponse(isUnidentified = (chatService is UnauthenticatedChatService))) }, onFailure = { throwable -> Log.i(TAG, "$name sendRequest failed", throwable) @@ -155,12 +146,7 @@ class LibSignalChatConnection( override fun sendKeepAlive() { Log.i(TAG, "$name Sending keep alive...") - val send = if (isAuthenticated) { - throw NotImplementedError("Authenticated socket is not yet supported") - } else { - chatService::unauthenticatedSendAndDebug - } - send(KEEP_ALIVE_REQUEST) + chatService.sendAndDebug(KEEP_ALIVE_REQUEST) .whenComplete( onSuccess = { debugResponse -> Log.i(TAG, "$name Keep alive - success") @@ -174,7 +160,7 @@ class LibSignalChatConnection( } in 400..599 -> { - healthMonitor.onMessageError(debugResponse.response.status, isAuthenticated) + healthMonitor.onMessageError(debugResponse.response.status, (chatService is AuthenticatedChatService)) } else -> { 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 index 35ddc77502..e17862c233 100644 --- 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 @@ -21,7 +21,11 @@ fun Network.createChatService( ): ChatService { val username = credentialsProvider?.username ?: "" val password = credentialsProvider?.password ?: "" - return this.createChatService(username, password, receiveStories) + return if (username.isEmpty() && password.isEmpty()) { + this.createUnauthChatService(null) + } else { + this.createAuthChatService(username, password, receiveStories, null) + } } /** @@ -35,4 +39,6 @@ fun Network.applyConfiguration(config: SignalServiceConfiguration) { } else { this.setProxy(proxy.host, proxy.port) } + + this.setCensorshipCircumventionEnabled(config.censored) } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/ShadowingWebSocketConnection.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/ShadowingWebSocketConnection.kt index 7d3308a013..999cfee311 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/ShadowingWebSocketConnection.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/websocket/ShadowingWebSocketConnection.kt @@ -70,7 +70,7 @@ class ShadowingWebSocketConnection( override fun connect(): Observable { executor.submit { - chatService.connectUnauthenticated().whenComplete( + chatService.connect().whenComplete( onSuccess = { canShadow.set(true) Log.i(TAG, "Shadow socket connected.") @@ -140,7 +140,7 @@ class ShadowingWebSocketConnection( ByteArray(0), KEEP_ALIVE_TIMEOUT.inWholeMilliseconds.toInt() ) - chatService.unauthenticatedSendAndDebug(request) + chatService.sendAndDebug(request) .whenComplete( onSuccess = { stats.requestsCompared.incrementAndGet() diff --git a/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnectionTest.kt b/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnectionTest.kt index 642645b7d9..ab3eb7b61a 100644 --- a/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnectionTest.kt +++ b/libsignal-service/src/test/java/org/whispersystems/signalservice/internal/websocket/LibSignalChatConnectionTest.kt @@ -25,7 +25,7 @@ class LibSignalChatConnectionTest { private val executor: ExecutorService = Executors.newSingleThreadExecutor() private val healthMonitor = mockk() private val chatService = mockk() - private val connection = LibSignalChatConnection("test", chatService, healthMonitor, isAuthenticated = false) + private val connection = LibSignalChatConnection("test", chatService, healthMonitor) @Before fun before() { @@ -38,7 +38,7 @@ class LibSignalChatConnectionTest { fun orderOfStatesOnSuccessfulConnect() { val latch = CountDownLatch(1) - every { chatService.connectUnauthenticated() } answers { + every { chatService.connect() } answers { delay { it.complete(DEBUG_INFO) latch.countDown() @@ -65,7 +65,7 @@ class LibSignalChatConnectionTest { val connectionException = RuntimeException("connect failed") val latch = CountDownLatch(1) - every { chatService.connectUnauthenticated() } answers { + every { chatService.connect() } answers { delay { it.completeExceptionally(connectionException) } @@ -91,7 +91,7 @@ class LibSignalChatConnectionTest { val connectLatch = CountDownLatch(1) val disconnectLatch = CountDownLatch(1) - every { chatService.connectUnauthenticated() } answers { + every { chatService.connect() } answers { delay { it.complete(DEBUG_INFO) connectLatch.countDown() @@ -155,7 +155,7 @@ class LibSignalChatConnectionTest { fun keepAliveSuccess() { val latch = CountDownLatch(1) - every { chatService.unauthenticatedSendAndDebug(any()) } answers { + every { chatService.sendAndDebug(any()) } answers { delay { it.complete(make_debug_response(RESPONSE_SUCCESS)) latch.countDown() @@ -179,7 +179,7 @@ class LibSignalChatConnectionTest { for (response in listOf(RESPONSE_ERROR, RESPONSE_SERVER_ERROR)) { val latch = CountDownLatch(1) - every { chatService.unauthenticatedSendAndDebug(any()) } answers { + every { chatService.sendAndDebug(any()) } answers { delay { it.complete(make_debug_response(response)) } @@ -203,7 +203,7 @@ class LibSignalChatConnectionTest { val latch = CountDownLatch(1) every { - chatService.unauthenticatedSendAndDebug(any()) + chatService.sendAndDebug(any()) } answers { delay { it.completeExceptionally(connectionFailure)