From 4b3d0b37be5eb07608b315ecb35453d0df39ec0c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 2 Aug 2026 23:29:37 -0700 Subject: [PATCH] test(android): consolidate connection TLS fixtures (#118532) --- .../app/node/ConnectionManagerTest.kt | 418 ++++-------------- 1 file changed, 80 insertions(+), 338 deletions(-) diff --git a/apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt b/apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt index 6d517bce41d3..0077eaea9fd1 100644 --- a/apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt +++ b/apps/android/app/src/test/java/ai/openclaw/app/node/ConnectionManagerTest.kt @@ -3,6 +3,7 @@ package ai.openclaw.app.node import ai.openclaw.app.LocationMode import ai.openclaw.app.SecurePrefs import ai.openclaw.app.gateway.GatewayEndpoint +import ai.openclaw.app.gateway.GatewayTlsParams import ai.openclaw.app.gateway.isLocalCleartextGatewayHost import ai.openclaw.app.gateway.isLoopbackGatewayHost import ai.openclaw.app.protocol.OpenClawCallLogCommand @@ -26,268 +27,62 @@ import org.robolectric.RuntimeEnvironment @RunWith(RobolectricTestRunner::class) class ConnectionManagerTest { @Test - fun resolveTlsParamsForEndpoint_prefersStoredPinOverAdvertisedFingerprint() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", + fun resolveTlsParamsForEndpoint_prefersStoredPinOverAdvertisedFingerprint() = + assertTls( + resolveDiscoveredTls( host = "10.0.0.2", - port = 18789, - tlsEnabled = true, - tlsFingerprintSha256 = "attacker", - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, storedFingerprint = "legit", - manualTlsEnabled = false, - ) - - assertEquals("legit", params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + tlsEnabled = true, + advertisedFingerprint = "attacker", + ), + expectedFingerprint = "legit", + ) @Test - fun resolveTlsParamsForEndpoint_doesNotTrustAdvertisedFingerprintWhenNoStoredPin() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", + fun resolveTlsParamsForEndpoint_doesNotTrustAdvertisedFingerprintWhenNoStoredPin() = + assertTls( + resolveDiscoveredTls( host = "10.0.0.2", - port = 18789, tlsEnabled = true, - tlsFingerprintSha256 = "attacker", - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + advertisedFingerprint = "attacker", + ), + ) @Test fun resolveTlsParamsForEndpoint_manualRespectsManualTlsToggle() { - val endpoint = GatewayEndpoint.manual(host = "127.0.0.1", port = 443) - - val off = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - assertNull(off) - - val on = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = true, - ) - assertNull(on?.expectedFingerprint) - assertEquals(false, on?.allowTOFU) + assertNull(resolveManualTls(host = "127.0.0.1", port = 443)) + assertTls(resolveManualTls(host = "127.0.0.1", port = 443, manualTlsEnabled = true)) } @Test - fun resolveTlsParamsForEndpoint_manualNonLoopbackForcesTlsWhenToggleIsOff() { - val endpoint = GatewayEndpoint.manual(host = "example.com", port = 443) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_manualNonLoopbackForcesTlsWhenToggleIsOff() = assertTlsRequired(resolveManualTls(host = "example.com", port = 443)) @Test - fun resolveTlsParamsForEndpoint_manualPrivateLanRespectsManualTlsToggle() { - val endpoint = GatewayEndpoint.manual(host = "192.168.1.20", port = 18789) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_manualPrivateLanRespectsManualTlsToggle() = assertNull(resolveManualTls("192.168.1.20")) @Test - fun resolveTlsParamsForEndpoint_manualMdnsRespectsManualTlsToggle() { - val endpoint = GatewayEndpoint.manual(host = "gateway.local", port = 18789) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_manualMdnsRespectsManualTlsToggle() = assertNull(resolveManualTls("gateway.local")) @Test - fun resolveTlsParamsForEndpoint_manualPrivateLanCleartextCanOverrideStoredPin() { - val endpoint = GatewayEndpoint.manual(host = "192.168.1.20", port = 18789) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = "pinned", - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_manualPrivateLanCleartextCanOverrideStoredPin() = assertNull(resolveManualTls(host = "192.168.1.20", storedFingerprint = "pinned")) @Test - fun resolveTlsParamsForEndpoint_discoveryTailnetWithoutHintsStillRequiresTls() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "100.64.0.9", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_discoveryTailnetWithoutHintsStillRequiresTls() = assertDiscoveredHostRequiresTls("100.64.0.9") @Test - fun resolveTlsParamsForEndpoint_discoveryPrivateLanWithoutHintsStillRequiresTls() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "192.168.1.20", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_discoveryPrivateLanWithoutHintsStillRequiresTls() = assertDiscoveredHostRequiresTls("192.168.1.20") @Test - fun resolveTlsParamsForEndpoint_discoveryMdnsWithoutHintsStillRequiresTls() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "gateway.local", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_discoveryMdnsWithoutHintsStillRequiresTls() = assertDiscoveredHostRequiresTls("gateway.local") @Test - fun resolveTlsParamsForEndpoint_discoveryLoopbackWithoutHintsCanStayCleartext() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "127.0.0.1", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_discoveryLoopbackWithoutHintsCanStayCleartext() = assertDiscoveredHostCanStayCleartext("127.0.0.1") @Test - fun resolveTlsParamsForEndpoint_discoveryLocalhostWithoutHintsCanStayCleartext() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "localhost", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_discoveryLocalhostWithoutHintsCanStayCleartext() = assertDiscoveredHostCanStayCleartext("localhost") @Test - fun resolveTlsParamsForEndpoint_discoveryAndroidEmulatorWithoutHintsCanStayCleartext() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "10.0.2.2", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_discoveryAndroidEmulatorWithoutHintsCanStayCleartext() = assertDiscoveredHostCanStayCleartext("10.0.2.2") @Test fun isLoopbackGatewayHost_onlyTreatsEmulatorBridgeAsLocalWhenAllowed() { @@ -311,120 +106,19 @@ class ConnectionManagerTest { } @Test - fun resolveTlsParamsForEndpoint_discoveryIpv6LoopbackWithoutHintsCanStayCleartext() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "::1", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_discoveryIpv6LoopbackWithoutHintsCanStayCleartext() = assertDiscoveredHostCanStayCleartext("::1") @Test - fun resolveTlsParamsForEndpoint_discoveryMappedIpv4LoopbackWithoutHintsCanStayCleartext() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "::ffff:127.0.0.1", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertNull(params) - } + fun resolveTlsParamsForEndpoint_discoveryMappedIpv4LoopbackWithoutHintsCanStayCleartext() = assertDiscoveredHostCanStayCleartext("::ffff:127.0.0.1") @Test - fun resolveTlsParamsForEndpoint_discoveryNonLoopbackIpv6WithoutHintsRequiresTls() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "2001:db8::1", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_discoveryNonLoopbackIpv6WithoutHintsRequiresTls() = assertDiscoveredHostRequiresTls("2001:db8::1") @Test - fun resolveTlsParamsForEndpoint_discoveryUnspecifiedIpv4WithoutHintsRequiresTls() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "0.0.0.0", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_discoveryUnspecifiedIpv4WithoutHintsRequiresTls() = assertDiscoveredHostRequiresTls("0.0.0.0") @Test - fun resolveTlsParamsForEndpoint_discoveryUnspecifiedIpv6WithoutHintsRequiresTls() { - val endpoint = - GatewayEndpoint( - stableId = "_openclaw-gw._tcp.|local.|Test", - name = "Test", - host = "::", - port = 18789, - tlsEnabled = false, - tlsFingerprintSha256 = null, - ) - - val params = - ConnectionManager.resolveTlsParamsForEndpoint( - endpoint, - storedFingerprint = null, - manualTlsEnabled = false, - ) - - assertEquals(true, params?.required) - assertNull(params?.expectedFingerprint) - assertEquals(false, params?.allowTOFU) - } + fun resolveTlsParamsForEndpoint_discoveryUnspecifiedIpv6WithoutHintsRequiresTls() = assertDiscoveredHostRequiresTls("::") @Test fun buildOperatorConnectOptions_requestsNativeClientOperatorScopes() { @@ -650,6 +344,54 @@ class ConnectionManagerTest { assertEquals(permissionSnapshot.gatewayPermissions(), options.permissions) } + private fun resolveDiscoveredTls( + host: String, + storedFingerprint: String? = null, + tlsEnabled: Boolean = false, + advertisedFingerprint: String? = null, + ): GatewayTlsParams? = + ConnectionManager.resolveTlsParamsForEndpoint( + GatewayEndpoint( + stableId = "_openclaw-gw._tcp.|local.|Test", + name = "Test", + host = host, + port = 18789, + tlsEnabled = tlsEnabled, + tlsFingerprintSha256 = advertisedFingerprint, + ), + storedFingerprint = storedFingerprint, + manualTlsEnabled = false, + ) + + private fun resolveManualTls( + host: String, + port: Int = 18789, + storedFingerprint: String? = null, + manualTlsEnabled: Boolean = false, + ): GatewayTlsParams? = + ConnectionManager.resolveTlsParamsForEndpoint( + GatewayEndpoint.manual(host = host, port = port), + storedFingerprint = storedFingerprint, + manualTlsEnabled = manualTlsEnabled, + ) + + private fun assertTls( + params: GatewayTlsParams?, + expectedFingerprint: String? = null, + ) { + assertEquals(expectedFingerprint, params?.expectedFingerprint) + assertEquals(false, params?.allowTOFU) + } + + private fun assertTlsRequired(params: GatewayTlsParams?) { + assertEquals(true, params?.required) + assertTls(params) + } + + private fun assertDiscoveredHostRequiresTls(host: String) = assertTlsRequired(resolveDiscoveredTls(host)) + + private fun assertDiscoveredHostCanStayCleartext(host: String) = assertNull(resolveDiscoveredTls(host)) + private fun newManager( cameraEnabled: Boolean = false, locationMode: LocationMode = LocationMode.Off,