Add Rust E2E tests for SOCKS5 + HTTP CONNECT basic auth#41
Merged
Conversation
The real upstream-auth code lives in the Rust tun2socks crate (socks5_handshake, http_connect). Add #[tokio::test] coverage that spins up loopback TCP listeners impersonating auth-requiring SOCKS5 and HTTP CONNECT upstreams, then drives the crate's own handshake functions against them. Six cases: SOCKS5: correct creds, wrong creds, no creds vs auth-required. HTTP CONNECT: correct creds, wrong creds, no creds. Also drop the dead Kotlin LocalProxyServer + its unit tests -- ProxyDroidVpnService no longer routes through it; tun2socks talks to the upstream directly. Fix the stale comment that still referenced LocalProxyServer. cargo fmt incidentally normalized two pre-existing style nits in socks4_handshake. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The existing HostSocks5ProxyIntegrationTest only covered NO_AUTH, and no
emulator-side HTTP CONNECT test existed at all. Extend the rig so the
instrumented suite runs both protocols across {no-auth, auth-ok,
auth-wrong-creds}:
scripts/socks5_test_server.py:
- Add --auth user:pass for RFC 1929 user/password sub-negotiation.
app/src/androidTest/.../HostSocks5ProxyIntegrationTest.kt:
- Existing NO_AUTH test unchanged.
- New auth happy-path test against a user/password upstream.
- New negative test asserting wrong creds get a non-zero RFC 1929
status from the proxy.
app/src/androidTest/.../HostHttpConnectProxyIntegrationTest.kt (new):
- CONNECT through auth-less proxy returns 200.
- CONNECT through auth-required proxy with correct creds returns 200.
- Wrong creds and missing creds both return 407.
scripts/run_emulator_tests.sh:
Was a smoke script that never ran connectedAndroidTest. Rewrite to
spin up all four fake upstream proxies on the host (SOCKS5 + HTTP
CONNECT, each in no-auth and user/pass variants on ports
1080/1081/8081/8082), wait for them to bind, then invoke
connectedDebugAndroidTest with the matching instrumentation args.
Verified locally: ./gradlew :app:compileDebugAndroidTestKotlin succeeds.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PRs into feature/** branches and pushes to test/** branches were previously silent. Extend the workflow triggers so this PR (and similar follow-ups) actually run CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The real upstream-auth code lives in the Rust tun2socks crate (
socks5_handshake,http_connectinapp/src/main/rust/proxydroid-tun2socks/src/tun2socks.rs). This PR adds#[tokio::test]coverage that spins up loopback TCP listeners impersonating auth-requiring SOCKS5 and HTTP CONNECT upstreams, then drives the crate's own handshake functions against them.Test cases
SOCKS5 (
socks5_handshake)SOCKS5 auth rejected0xFF) →method not acceptedHTTP CONNECT (
http_connect)All exercise real TCP loopback against real handshakes — no mocking of the protocol code.
Drive-by cleanup
LocalProxyServer.ktandLocalHttpProxyTest.kt— dead since the VPN-first rewrite (ProxyDroidVpnServiceroutes directly throughTun2SocksHelper; nothing inmain/referencedLocalProxyServer).ProxyDroidVpnService.ktthat still mentionedLocalProxyServer.cargo fmtincidentally normalized two pre-existing style nits insocks4_handshake.Tests are IP-target only
The Rust netstack uses fake-IP NAT for DNS, so in the real data path the
Targetpassed into the handshakes is alwaysTarget::Ip(...). All six tests reflect that. TheTarget::Domainbranches in the handshakes are not exercised here — happy to add if you want defensive coverage in case fake-IP is ever bypassed.Verification
cargo fmt --all -- --check✓cargo clippy --all-targets -- -D warnings✓cargo test --lib→ 6 passed🤖 Generated with Claude Code