curtain/Tests/CurtainSharedTests/NetstatParseTests.swift
Aric Camarata 8c19e960d2 Detection root-cause fix + audit batch: netstat path, UDP activator, settings coherence, refactor, docs
Detection: netstat lives at /usr/sbin/netstat, not /usr/bin — the hardcoded wrong
path silently killed the ESTABLISHED-TCP activator (root cause of the failed live
test). Fixed and live-verified. Added peered-UDP activator (5900-5902) for
High-Performance sessions, per-signal transition logging, unconditional error
logging for dead probe helpers, and probe v2 with full CGSession dictionary
diffing. 7 new parser tests (32 total).

Fixes from a full audit + adversarial review: idle source setting honored
(default now Remote session activity), cover scope reduced to a coherent
two-mode model with legacy migration (per-display toggle was inverted in
onlyMarked and dead in all), curtain test no longer schedules a teardown over a
live session, specific-display password box placement gets a real picker,
refuse-to-arm enforced, activation notification posts a real banner, menu
password gate bypassed when the event tap is dead, shared single-decoder aerial
player with stale-task guard and async playability check, password buffer zeroed
on successful unlock and Esc, XPC interruption/invalidation handlers, modern
Accessibility settings URL, launchPath modernized, codesign failures now abort
release.sh, monotonic CFBundleVersion, install.sh temp cleanup, dead
armDisarmHotkey setting removed.

Refactor: Curtain.swift and PreferencesWindow.swift split into focused files
(largest now 479 lines). Wiki, README, and contributing docs updated to match.
Build clean at 0 warnings, 32/32 tests pass.
2026-06-09 20:36:30 -04:00

128 lines
4.9 KiB
Swift

import XCTest
@testable import CurtainShared
final class NetstatParseTests: XCTestCase {
func testListenOnlyIsFalse() {
let out = """
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 *.5900 *.* LISTEN
"""
XCTAssertFalse(NetstatParse.hasEstablishedVNC(out))
}
func testEstablishedInboundIsTrue() {
let out = """
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 192.168.1.20.5900 192.168.1.55.51234 ESTABLISHED
"""
XCTAssertTrue(NetstatParse.hasEstablishedVNC(out))
}
func testEstablishedDifferentPortIsFalse() {
let out = """
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 192.168.1.20.22 192.168.1.55.51234 ESTABLISHED
"""
XCTAssertFalse(NetstatParse.hasEstablishedVNC(out))
}
func testForeignWildcardIsFalse() {
let out = """
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 192.168.1.20.5900 *.* ESTABLISHED
"""
XCTAssertFalse(NetstatParse.hasEstablishedVNC(out))
}
func testOutboundFiveNineHundredIsFalse() {
// 5900 appears in the FOREIGN column (we are the client) not an inbound VNC session.
let out = """
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 192.168.1.20.51234 192.168.1.55.5900 ESTABLISHED
"""
XCTAssertFalse(NetstatParse.hasEstablishedVNC(out))
}
func testEmptyOutputIsFalse() {
XCTAssertFalse(NetstatParse.hasEstablishedVNC(""))
}
func testEstablishedAmongNoiseIsTrue() {
let out = """
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 *.5900 *.* LISTEN
tcp4 0 0 192.168.1.20.22 10.0.0.9.4421 ESTABLISHED
tcp4 0 0 192.168.1.20.5900 10.0.0.9.62000 ESTABLISHED
"""
XCTAssertTrue(NetstatParse.hasEstablishedVNC(out))
}
func testRealMacOS26ListenFormatIsFalse() {
// Verbatim from `netstat -an` on macOS 26.5 with Screen Sharing enabled,
// no session: LISTEN rows only must never read as established.
let out = """
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp4 0 0 *.5900 *.* LISTEN
tcp6 0 0 *.5900 *.* LISTEN
"""
XCTAssertFalse(NetstatParse.hasEstablishedVNC(out))
XCTAssertFalse(NetstatParse.hasPeeredUDPVNC(out))
}
// MARK: - Peered UDP (High-Performance transport)
func testPeeredUDPOn5900IsTrue() {
let out = """
Proto Recv-Q Send-Q Local Address Foreign Address
udp4 0 0 192.168.1.20.5900 192.168.1.55.61234
"""
XCTAssertTrue(NetstatParse.hasPeeredUDPVNC(out))
}
func testPeeredUDPOn5901And5902IsTrue() {
let out5901 = """
udp4 0 0 192.168.1.20.5901 192.168.1.55.61234
"""
let out5902 = """
udp6 0 0 fe80::1%en0.5902 fe80::2%en0.61234
"""
XCTAssertTrue(NetstatParse.hasPeeredUDPVNC(out5901))
XCTAssertTrue(NetstatParse.hasPeeredUDPVNC(out5902))
}
func testWildcardUDPListenerIsFalse() {
// An unconnected UDP listener (foreign *.*) is just Screen Sharing being
// enabled it must NEVER activate (the overnight false-positive class).
let out = """
udp4 0 0 *.5900 *.*
udp4 0 0 192.168.1.20.5900 *.*
"""
XCTAssertFalse(NetstatParse.hasPeeredUDPVNC(out))
}
func testPeeredUDPOnOtherPortIsFalse() {
let out = """
udp4 0 0 192.168.1.20.5353 192.168.1.55.5353
udp4 0 0 192.168.1.20.59000 10.0.0.9.443
"""
XCTAssertFalse(NetstatParse.hasPeeredUDPVNC(out))
}
func testPeeredUDPIsNotEstablishedTCP() {
// The two detectors must not bleed into each other.
let udpOnly = """
udp4 0 0 192.168.1.20.5900 192.168.1.55.61234
"""
let tcpOnly = """
tcp4 0 0 192.168.1.20.5900 192.168.1.55.61234 ESTABLISHED
"""
XCTAssertFalse(NetstatParse.hasEstablishedVNC(udpOnly))
XCTAssertFalse(NetstatParse.hasPeeredUDPVNC(tcpOnly))
}
func testEmptyOutputUDPIsFalse() {
XCTAssertFalse(NetstatParse.hasPeeredUDPVNC(""))
}
}