Improve validator for IPv6.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jeroen Leenarts 2018-08-15 22:52:37 +02:00
parent 15cb942368
commit 91daed0c80
4 changed files with 39 additions and 67 deletions

View File

@ -34,15 +34,18 @@ struct Endpoint {
var addressType: AddressType var addressType: AddressType
init?(endpointString: String) throws { init?(endpointString: String) throws {
let parts = endpointString.split(separator: ":") guard let range = endpointString.range(of: ":", options: .backwards, range: nil, locale: nil) else {
guard parts.count == 2 else {
throw EndpointValidationError.noIpAndPort(endpointString) throw EndpointValidationError.noIpAndPort(endpointString)
} }
guard let port = Int32(parts[1]), port > 0 else {
throw EndpointValidationError.invalidPort(String(parts[1])) let ipString = endpointString[..<range.lowerBound].replacingOccurrences(of: "[", with: "").replacingOccurrences(of: "]", with: "")
let portString = endpointString[range.upperBound...]
guard let port = Int32(portString), port > 0 else {
throw EndpointValidationError.invalidPort(String(portString/*parts[1]*/))
} }
ipAddress = String(parts[0]) ipAddress = String(ipString)
let addressType = validateIpAddress(ipToValidate: ipAddress) let addressType = validateIpAddress(ipToValidate: ipAddress)
guard addressType == .IPv4 || addressType == .IPv6 else { guard addressType == .IPv4 || addressType == .IPv6 else {
throw EndpointValidationError.invalidIP(ipAddress) throw EndpointValidationError.invalidIP(ipAddress)

View File

@ -17,7 +17,6 @@
4A4BACEB20B5F1BF00F12B28 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BACE920B5F1BF00F12B28 /* Main.storyboard */; }; 4A4BACEB20B5F1BF00F12B28 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BACE920B5F1BF00F12B28 /* Main.storyboard */; };
4A4BACED20B5F1C100F12B28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BACEC20B5F1C100F12B28 /* Assets.xcassets */; }; 4A4BACED20B5F1C100F12B28 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BACEC20B5F1C100F12B28 /* Assets.xcassets */; };
4A4BACF020B5F1C100F12B28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BACEE20B5F1C100F12B28 /* LaunchScreen.storyboard */; }; 4A4BACF020B5F1C100F12B28 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BACEE20B5F1C100F12B28 /* LaunchScreen.storyboard */; };
4A4BACFB20B5F1C100F12B28 /* WireGuardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACFA20B5F1C100F12B28 /* WireGuardTests.swift */; };
4A4BAD0620B5F4B500F12B28 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0520B5F4B500F12B28 /* Settings.bundle */; }; 4A4BAD0620B5F4B500F12B28 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0520B5F4B500F12B28 /* Settings.bundle */; };
4A4BAD0C20B5F6AA00F12B28 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0B20B5F6AA00F12B28 /* AppCoordinator.swift */; }; 4A4BAD0C20B5F6AA00F12B28 /* AppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0B20B5F6AA00F12B28 /* AppCoordinator.swift */; };
4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0D20B5F6C300F12B28 /* Coordinator.swift */; }; 4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0D20B5F6C300F12B28 /* Coordinator.swift */; };
@ -89,7 +88,6 @@
4A4BACEF20B5F1C100F12B28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 4A4BACEF20B5F1C100F12B28 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
4A4BACF120B5F1C100F12B28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4A4BACF120B5F1C100F12B28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4A4BACF620B5F1C100F12B28 /* WireGuardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WireGuardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 4A4BACF620B5F1C100F12B28 /* WireGuardTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WireGuardTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
4A4BACFA20B5F1C100F12B28 /* WireGuardTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireGuardTests.swift; sourceTree = "<group>"; };
4A4BACFC20B5F1C100F12B28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 4A4BACFC20B5F1C100F12B28 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4A4BAD0520B5F4B500F12B28 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; }; 4A4BAD0520B5F4B500F12B28 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
4A4BAD0B20B5F6AA00F12B28 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; }; 4A4BAD0B20B5F6AA00F12B28 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
@ -196,7 +194,6 @@
4A4BACF920B5F1C100F12B28 /* WireGuardTests */ = { 4A4BACF920B5F1C100F12B28 /* WireGuardTests */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4A4BACFA20B5F1C100F12B28 /* WireGuardTests.swift */,
4A4BACFC20B5F1C100F12B28 /* Info.plist */, 4A4BACFC20B5F1C100F12B28 /* Info.plist */,
4A43515B21249E5700261999 /* ValidatorsTests.swift */, 4A43515B21249E5700261999 /* ValidatorsTests.swift */,
); );
@ -554,7 +551,6 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
4A43515C21249E5700261999 /* ValidatorsTests.swift in Sources */, 4A43515C21249E5700261999 /* ValidatorsTests.swift in Sources */,
4A4BACFB20B5F1C100F12B28 /* WireGuardTests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -10,47 +10,56 @@ import XCTest
@testable import WireGuard @testable import WireGuard
class ValidatorsTests: XCTestCase { class ValidatorsTests: XCTestCase {
func testIPv6Endpoint() throws { func testEndpoint() throws {
XCTFail("Still needs implementation") _ = try Endpoint(endpointString: "[2607:f938:3001:4000::aac]:12345")
}
func testIPv4Endpoint() throws {
_ = try Endpoint(endpointString: "192.168.0.1:12345") _ = try Endpoint(endpointString: "192.168.0.1:12345")
} }
func testIPv4Endpoint_invalidIP() throws { func testEndpoint_invalidIP() throws {
XCTAssertThrowsError(try Endpoint(endpointString: "12345:12345")) { (error) in func executeTest(endpointString: String, ipString: String, file: StaticString = #file, line: UInt = #line) {
guard case EndpointValidationError.invalidIP(let value) = error else { XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
return XCTFail("Unexpected error") guard case EndpointValidationError.invalidIP(let value) = error else {
return XCTFail("Unexpected error: \(error)", file: file, line: line)
}
XCTAssertEqual(value, ipString, file: file, line: line)
} }
XCTAssertEqual(value, "12345")
} }
executeTest(endpointString: "12345:12345", ipString: "12345")
executeTest(endpointString: ":12345", ipString: "")
} }
func testIPv4Endpoint_invalidPort() throws { func testEndpoint_invalidPort() throws {
XCTAssertThrowsError(try Endpoint(endpointString: "192.168.0.1:-12345")) { (error) in func executeTest(endpointString: String, portString: String, file: StaticString = #file, line: UInt = #line) {
guard case EndpointValidationError.invalidPort(let value) = error else { XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
return XCTFail("Unexpected error") guard case EndpointValidationError.invalidPort(let value) = error else {
return XCTFail("Unexpected error: \(error)", file: file, line: line)
}
XCTAssertEqual(value, portString, file: file, line: line)
} }
XCTAssertEqual(value, "-12345")
} }
executeTest(endpointString: ":", portString: "")
executeTest(endpointString: "[2607:f938:3001:4000::aac]:-12345", portString: "-12345")
executeTest(endpointString: "[2607:f938:3001:4000::aac]", portString: "aac]")
executeTest(endpointString: "[2607:f938:3001:4000::aac]:", portString: "")
executeTest(endpointString: "192.168.0.1:-12345", portString: "-12345")
executeTest(endpointString: "192.168.0.1:", portString: "")
} }
func testIPv4Endpoint_noIpAndPort() throws { func testEndpoint_noIpAndPort() throws {
func executeTest(endpointString: String) { func executeTest(endpointString: String, file: StaticString = #file, line: UInt = #line) {
XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
guard case EndpointValidationError.noIpAndPort(let value) = error else { guard case EndpointValidationError.noIpAndPort(let value) = error else {
return XCTFail("Unexpected error") return XCTFail("Unexpected error: \(error)", file: file, line: line)
} }
XCTAssertEqual(value, endpointString, file: #file, line: #line) XCTAssertEqual(value, endpointString, file: file, line: line)
} }
} }
executeTest(endpointString: ":")
executeTest(endpointString: "192.168.0.1") executeTest(endpointString: "192.168.0.1")
executeTest(endpointString: "192.168.0.1:")
executeTest(endpointString: ":12345")
executeTest(endpointString: "12345") executeTest(endpointString: "12345")
} }
} }

View File

@ -1,36 +0,0 @@
//
// WireGuardTests.swift
// WireGuardTests
//
// Created by Jeroen Leenarts on 23-05-18.
// Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All rights reserved.
//
import XCTest
@testable import WireGuard
class WireGuardTests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
}