mirror of
https://github.com/aculix/knotchy.git
synced 2026-10-27 07:15:53 +00:00
Initial release
This commit is contained in:
commit
4b67728cce
108 files changed
+13310
No files matched your search
@@ -0,0 +1,145 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
@testable import KnotchyCore
|
||||
|
||||
@Suite struct NetworkRouteTests {
|
||||
static let key = Data(repeating: 7, count: 32).base64EncodedString()
|
||||
static let otherKey = Data(repeating: 9, count: 32).base64EncodedString()
|
||||
|
||||
static let mullvadStyle = """
|
||||
[Interface]
|
||||
# Device: Quick Fox
|
||||
PrivateKey = \(key)
|
||||
Address = 10.64.12.34/32,fc00:bbbb:bbbb:bb01::1:c21/128
|
||||
DNS = 10.64.0.1
|
||||
|
||||
[Peer]
|
||||
PublicKey = \(otherKey)
|
||||
AllowedIPs = 0.0.0.0/0,::0/0
|
||||
Endpoint = se-got-wg-001.relays.mullvad.net:51820
|
||||
"""
|
||||
|
||||
@Test func parsesAProviderConfig() throws {
|
||||
let config = try WireGuardConfig.parse(Self.mullvadStyle)
|
||||
#expect(config.privateKey == Self.key)
|
||||
#expect(config.addresses == ["10.64.12.34/32"])
|
||||
#expect(config.dns == ["10.64.0.1"])
|
||||
#expect(config.peerPublicKey == Self.otherKey)
|
||||
#expect(config.endpointHost == "se-got-wg-001.relays.mullvad.net")
|
||||
#expect(config.endpointPort == 51820)
|
||||
#expect(config.mtu == nil)
|
||||
#expect(config.persistentKeepalive == nil)
|
||||
}
|
||||
|
||||
@Test func keysAreCaseInsensitiveAndRepeatsJoin() throws {
|
||||
let text = """
|
||||
[interface]
|
||||
privatekey=\(Self.key)
|
||||
Address = 10.2.0.2
|
||||
Address = 10.2.0.3/32
|
||||
DNS = 10.2.0.1, 1.1.1.1, example.search.domain
|
||||
MTU = 1380
|
||||
[PEER]
|
||||
publickey = \(Self.otherKey)
|
||||
PresharedKey = \(Self.key)
|
||||
endpoint = 203.0.113.9:443
|
||||
PersistentKeepalive = 15
|
||||
"""
|
||||
let config = try WireGuardConfig.parse(text)
|
||||
#expect(config.addresses == ["10.2.0.2/32", "10.2.0.3/32"])
|
||||
#expect(config.dns == ["10.2.0.1", "1.1.1.1"])
|
||||
#expect(config.mtu == 1380)
|
||||
#expect(config.presharedKey == Self.key)
|
||||
#expect(config.persistentKeepalive == 15)
|
||||
}
|
||||
|
||||
@Test func rejectsWhatTheVMCannotUse() {
|
||||
func parse(_ text: String) -> WireGuardConfig.ParseError? {
|
||||
do { _ = try WireGuardConfig.parse(text); return nil } catch { return error }
|
||||
}
|
||||
let peer = "[Peer]\nPublicKey = \(Self.otherKey)\nEndpoint = 1.2.3.4:51820\n"
|
||||
#expect(parse("[Interface]\nAddress = 10.0.0.2/32\n" + peer) == .missing("PrivateKey"))
|
||||
#expect(parse("[Interface]\nPrivateKey = nope\nAddress = 10.0.0.2/32\n" + peer) == .invalid("PrivateKey"))
|
||||
#expect(parse("[Interface]\nPrivateKey = \(Self.key)\nAddress = fd00::2/128\n" + peer) == .missing("an IPv4 Address"))
|
||||
#expect(parse("[Interface]\nPrivateKey = \(Self.key)\nAddress = 10.0.0.2/32\n") == .missing("[Peer]"))
|
||||
#expect(parse("[Interface]\nPrivateKey = \(Self.key)\nAddress = 10.0.0.2/32\n" + peer + peer) == .multiplePeers)
|
||||
let v6Endpoint = "[Peer]\nPublicKey = \(Self.otherKey)\nEndpoint = [2001:db8::1]:51820\n"
|
||||
#expect(parse("[Interface]\nPrivateKey = \(Self.key)\nAddress = 10.0.0.2/32\n" + v6Endpoint) != nil)
|
||||
let shellEndpoint = "[Peer]\nPublicKey = \(Self.otherKey)\nEndpoint = $(reboot):51820\n"
|
||||
#expect(parse("[Interface]\nPrivateKey = \(Self.key)\nAddress = 10.0.0.2/32\n" + shellEndpoint) == .invalid("Endpoint"))
|
||||
#expect(parse("[Interface]\nPrivateKey = \(Self.key)\nAddress = 10.0.0.2/32\nPostUp = rm -rf /\n" + peer) == nil)
|
||||
}
|
||||
|
||||
@Test func setconfForcesAFullTunnelAndAKeepalive() throws {
|
||||
let config = try WireGuardConfig.parse(Self.mullvadStyle)
|
||||
let setconf = config.setconf(endpointAddress: "185.213.154.66")
|
||||
#expect(setconf == """
|
||||
[Interface]
|
||||
PrivateKey = \(Self.key)
|
||||
|
||||
[Peer]
|
||||
PublicKey = \(Self.otherKey)
|
||||
Endpoint = 185.213.154.66:51820
|
||||
AllowedIPs = 0.0.0.0/0
|
||||
PersistentKeepalive = 25
|
||||
|
||||
""")
|
||||
}
|
||||
|
||||
@Test func proxyURLsEncodeCredentialsAndUseTheAddress() {
|
||||
let proxy = ProxySettings(kind: .socks5, host: "proxy.example", port: 1080, username: "me@home", password: "p:w/d@!")
|
||||
#expect(proxy.url(address: "203.0.113.7") == "socks5://me%40home:p%3Aw%2Fd%40%21@203.0.113.7:1080")
|
||||
#expect(ProxySettings(kind: .http, host: "h", port: 8080).url(address: "10.0.0.5") == "http://10.0.0.5:8080")
|
||||
#expect(ProxySettings(kind: .http, host: "h", port: 8080, username: "u").url(address: "10.0.0.5") == "http://u@10.0.0.5:8080")
|
||||
}
|
||||
|
||||
@Test func launchKeepsSecretsOutOfTheEnvironment() throws {
|
||||
var asked: [String] = []
|
||||
let resolve = { (host: String) -> String in asked.append(host); return "198.51.100.4" }
|
||||
#expect(try NetworkRoute.direct.launch(resolve: resolve) == RouteLaunch(environment: ["KNOTCHY_ROUTE=direct"], secrets: []))
|
||||
|
||||
let proxy = NetworkRoute.proxy(ProxySettings(kind: .http, host: "proxy.corp", port: 3128, username: "u", password: "p"))
|
||||
#expect(try proxy.launch(resolve: resolve) == RouteLaunch(
|
||||
environment: ["KNOTCHY_ROUTE=proxy", "KNOTCHY_PROXY_ADDR=198.51.100.4:3128"],
|
||||
secrets: ["KNOTCHY_PROXY_URL=http://u:p@198.51.100.4:3128"]
|
||||
))
|
||||
|
||||
let wireGuard = try NetworkRoute.wireGuard(WireGuardConfig.parse(Self.mullvadStyle)).launch(resolve: resolve)
|
||||
#expect(asked == ["proxy.corp", "se-got-wg-001.relays.mullvad.net"])
|
||||
#expect(wireGuard.environment == [
|
||||
"KNOTCHY_ROUTE=wireguard", "KNOTCHY_WG_ENDPOINT=198.51.100.4:51820", "KNOTCHY_WG_ADDRESS=10.64.12.34/32",
|
||||
"KNOTCHY_WG_DNS=10.64.0.1", "KNOTCHY_WG_MTU=1420",
|
||||
])
|
||||
#expect(wireGuard.environment.allSatisfy { !$0.contains(Self.key) })
|
||||
#expect(wireGuard.secrets.count == 1 && wireGuard.secrets[0].hasPrefix("KNOTCHY_WG_SETCONF="))
|
||||
#expect((wireGuard.environment + wireGuard.secrets).allSatisfy { !$0.contains("\n") })
|
||||
|
||||
#expect(throws: VMBackendError.failed("no")) { try NetworkRoute.unusable(reason: "no").launch(resolve: resolve) }
|
||||
}
|
||||
|
||||
@Test func routeLabels() throws {
|
||||
#expect(NetworkRoute.direct.label == nil)
|
||||
#expect(NetworkRoute.proxy(ProxySettings(kind: .socks5, host: "h", port: 1)).label == "SOCKS5 proxy")
|
||||
var config = try WireGuardConfig.parse(Self.mullvadStyle)
|
||||
#expect(NetworkRoute.wireGuard(config).label == "VPN")
|
||||
config.name = "sg-sin-wg-001"
|
||||
#expect(NetworkRoute.wireGuard(config).label == "sg-sin-wg-001")
|
||||
}
|
||||
|
||||
@Test func proxiesOnTheMacOrItsNetworkAreRefused() throws {
|
||||
for local in ["10.1.2.3", "127.0.0.1", "169.254.169.254", "172.20.0.1", "192.168.64.1", "100.100.1.1", "0.0.0.0"] {
|
||||
#expect(ProxySettings.isLocal(local, hostNetworks: []), "\(local)")
|
||||
}
|
||||
#expect(ProxySettings.isLocal("203.0.113.9", hostNetworks: ["203.0.113.0/24"]))
|
||||
#expect(!ProxySettings.isLocal("203.0.113.9", hostNetworks: ["198.51.100.0/24"]))
|
||||
#expect(!ProxySettings.isLocal("8.8.8.8", hostNetworks: []))
|
||||
#expect(!ProxySettings.isLocal("172.32.0.1", hostNetworks: []))
|
||||
|
||||
let proxy = NetworkRoute.proxy(ProxySettings(kind: .http, host: "proxy.lan", port: 3128))
|
||||
#expect(throws: VMBackendError.self) { try proxy.launch(resolve: { _ in "192.168.1.10" }) }
|
||||
#expect(try proxy.launch(resolve: { _ in "192.168.1.10" }, allowLocalProxy: true).environment.count == 2)
|
||||
// A local WireGuard server is fine: only wireguard-go can reach it.
|
||||
let wireGuard = NetworkRoute.wireGuard(try WireGuardConfig.parse(Self.mullvadStyle))
|
||||
#expect(try wireGuard.launch(resolve: { _ in "192.168.1.1" }).environment.contains("KNOTCHY_WG_ENDPOINT=192.168.1.1:51820"))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user