mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 01:05:19 +00:00
Runtime-verified whether Apple's URLSession honors connectionProxyDictionary SOCKS settings for Nostr relay traffic (plain HTTPS + URLSessionWebSocketTask), since the app routes all Nostr traffic through Arti's local SOCKS5 proxy solely via those keys and Apple does not officially support SOCKS for URLSession on iOS. Verification harness (scripts/tor-egress-verification/): a minimal SOCKS5 CONNECT proxy that logs arriving connections, plus a Swift probe that runs an HTTPS GET and a WebSocket ping through a URLSession configured with the proxy dict. Result: on macOS (kCFNetworkProxiesSOCKS* constants) and the iOS simulator (raw "SOCKSProxy"/"SOCKSPort" string keys, the exact app path) BOTH HTTP and WebSocket are proxied, do remote DNS through the proxy, and the proxied session is fail-closed (every request errors when the SOCKS proxy is down). The feared direct-egress leak did not reproduce on the tested platforms. Defense-in-depth for the platform Apple does not guarantee (physical iOS): add TorEgressVerifier, which performs a canary request through the proxied session and asserts the exit is a Tor node (check.torproject.org IsTor==true), positively detecting a direct egress even if the OS silently ignored the proxy. Policy: verifiedTor allows (cached for a TTL); notTor refuses (leak detected, never open relays); unreachable allows-with-warning (session stays fail-closed by construction). Wired into TorManager.awaitEgressReady() and required by both NostrRelayManager and GeoRelayDirectory before opening connections. Cache is invalidated on Tor restart/dormant/shutdown. Never falls back to a direct connection. Probe is injected so the policy/caching is unit-tested offline; the live-network harness lives under scripts/ and is not run by CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
49 lines
1.3 KiB
Swift
49 lines
1.3 KiB
Swift
// swift-tools-version:5.9
|
|
import PackageDescription
|
|
|
|
let package = Package(
|
|
name: "Tor", // Keep name "Tor" for drop-in compatibility
|
|
platforms: [
|
|
.iOS(.v16),
|
|
.macOS(.v13),
|
|
],
|
|
products: [
|
|
.library(
|
|
name: "Tor",
|
|
targets: ["Tor"]
|
|
),
|
|
],
|
|
dependencies: [
|
|
.package(path: "../BitLogger"),
|
|
],
|
|
targets: [
|
|
// Main Swift target
|
|
.target(
|
|
name: "Tor",
|
|
dependencies: [
|
|
"arti",
|
|
.product(name: "BitLogger", package: "BitLogger"),
|
|
],
|
|
path: "Sources",
|
|
exclude: ["C"],
|
|
sources: [
|
|
"TorManager.swift",
|
|
"TorURLSession.swift",
|
|
"TorNotifications.swift",
|
|
"TorEgressVerifier.swift",
|
|
],
|
|
linkerSettings: [
|
|
.linkedLibrary("resolv"),
|
|
.linkedLibrary("z"),
|
|
.linkedLibrary("sqlite3"),
|
|
]
|
|
),
|
|
// Binary framework containing the Rust static library.
|
|
// Provenance and rebuild steps: repo-root docs/ARTI-BINARY-PROVENANCE.md
|
|
.binaryTarget(
|
|
name: "arti",
|
|
path: "Frameworks/arti.xcframework"
|
|
),
|
|
]
|
|
)
|