Add Validator for Endpoints.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
04454b8451
commit
9037b90747
|
@ -0,0 +1,71 @@
|
||||||
|
//
|
||||||
|
// IPValidator.swift
|
||||||
|
// WireGuard
|
||||||
|
//
|
||||||
|
// Created by Jeroen Leenarts on 15-08-18.
|
||||||
|
// Copyright © 2018 WireGuard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum AddressType {
|
||||||
|
case IPv6, IPv4, other
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum EndpointValidationError: Error {
|
||||||
|
case noIpAndPort(String)
|
||||||
|
case invalidIP(String)
|
||||||
|
case invalidPort(String)
|
||||||
|
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
case .noIpAndPort:
|
||||||
|
return NSLocalizedString("EndpointValidationError.noIpAndPort", comment: "Error message for malformed endpoint.")
|
||||||
|
case .invalidIP:
|
||||||
|
return NSLocalizedString("EndpointValidationError.invalidIP", comment: "Error message for invalid endpoint ip.")
|
||||||
|
case .invalidPort:
|
||||||
|
return NSLocalizedString("EndpointValidationError.invalidPort", comment: "Error message invalid endpoint port.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct Endpoint {
|
||||||
|
var ipAddress: String
|
||||||
|
var port: Int32
|
||||||
|
var addressType: AddressType
|
||||||
|
|
||||||
|
init?(endpointString: String) throws {
|
||||||
|
let parts = endpointString.split(separator: ":")
|
||||||
|
guard parts.count == 2 else {
|
||||||
|
throw EndpointValidationError.noIpAndPort(endpointString)
|
||||||
|
}
|
||||||
|
guard let port = Int32(parts[1]), port > 0 else {
|
||||||
|
throw EndpointValidationError.invalidPort(String(parts[1]))
|
||||||
|
}
|
||||||
|
|
||||||
|
ipAddress = String(parts[0])
|
||||||
|
let addressType = validateIpAddress(ipToValidate: ipAddress)
|
||||||
|
guard addressType == .IPv4 || addressType == .IPv6 else {
|
||||||
|
throw EndpointValidationError.invalidIP(ipAddress)
|
||||||
|
}
|
||||||
|
self.addressType = addressType
|
||||||
|
|
||||||
|
self.port = port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateIpAddress(ipToValidate: String) -> AddressType {
|
||||||
|
|
||||||
|
var sin = sockaddr_in()
|
||||||
|
if ipToValidate.withCString({ cstring in inet_pton(AF_INET, cstring, &sin.sin_addr) }) == 1 {
|
||||||
|
// IPv4 peer.
|
||||||
|
return .IPv4
|
||||||
|
}
|
||||||
|
|
||||||
|
var sin6 = sockaddr_in6()
|
||||||
|
if ipToValidate.withCString({ cstring in inet_pton(AF_INET6, cstring, &sin6.sin6_addr) }) == 1 {
|
||||||
|
// IPv6 peer.
|
||||||
|
return .IPv6
|
||||||
|
}
|
||||||
|
|
||||||
|
return .other
|
||||||
|
}
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
48CF751B34E9703133F1B1AF /* Pods_WireGuard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 861983CAE8FDC13BC83E7E04 /* Pods_WireGuard.framework */; };
|
48CF751B34E9703133F1B1AF /* Pods_WireGuard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 861983CAE8FDC13BC83E7E04 /* Pods_WireGuard.framework */; };
|
||||||
|
4A4351592124956200261999 /* Validators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4351582124956200261999 /* Validators.swift */; };
|
||||||
|
4A43515A2124956200261999 /* Validators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4351582124956200261999 /* Validators.swift */; };
|
||||||
|
4A43515C21249E5700261999 /* ValidatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A43515B21249E5700261999 /* ValidatorsTests.swift */; };
|
||||||
4A4BA6D820B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BA6D720B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift */; };
|
4A4BA6D820B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BA6D720B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift */; };
|
||||||
4A4BACE620B5F1BF00F12B28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACE520B5F1BF00F12B28 /* AppDelegate.swift */; };
|
4A4BACE620B5F1BF00F12B28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACE520B5F1BF00F12B28 /* AppDelegate.swift */; };
|
||||||
4A4BACE820B5F1BF00F12B28 /* TunnelsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACE720B5F1BF00F12B28 /* TunnelsTableViewController.swift */; };
|
4A4BACE820B5F1BF00F12B28 /* TunnelsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACE720B5F1BF00F12B28 /* TunnelsTableViewController.swift */; };
|
||||||
|
@ -75,6 +78,8 @@
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
0CE52E030FAA93F3BF5747B2 /* Pods-WireGuard.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WireGuard.release.xcconfig"; path = "Pods/Target Support Files/Pods-WireGuard/Pods-WireGuard.release.xcconfig"; sourceTree = "<group>"; };
|
0CE52E030FAA93F3BF5747B2 /* Pods-WireGuard.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WireGuard.release.xcconfig"; path = "Pods/Target Support Files/Pods-WireGuard/Pods-WireGuard.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
25E2BE31A33C8CCE6E79B6EF /* Pods-WireGuard.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WireGuard.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WireGuard/Pods-WireGuard.debug.xcconfig"; sourceTree = "<group>"; };
|
25E2BE31A33C8CCE6E79B6EF /* Pods-WireGuard.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WireGuard.debug.xcconfig"; path = "Pods/Target Support Files/Pods-WireGuard/Pods-WireGuard.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
4A4351582124956200261999 /* Validators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Validators.swift; sourceTree = "<group>"; };
|
||||||
|
4A43515B21249E5700261999 /* ValidatorsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidatorsTests.swift; sourceTree = "<group>"; };
|
||||||
4A4BA6D720B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelConfigurationTableViewController.swift; sourceTree = "<group>"; };
|
4A4BA6D720B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelConfigurationTableViewController.swift; sourceTree = "<group>"; };
|
||||||
4A4BACE220B5F1BF00F12B28 /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
4A4BACE220B5F1BF00F12B28 /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4A4BACE520B5F1BF00F12B28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
4A4BACE520B5F1BF00F12B28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
@ -193,6 +198,7 @@
|
||||||
children = (
|
children = (
|
||||||
4A4BACFA20B5F1C100F12B28 /* WireGuardTests.swift */,
|
4A4BACFA20B5F1C100F12B28 /* WireGuardTests.swift */,
|
||||||
4A4BACFC20B5F1C100F12B28 /* Info.plist */,
|
4A4BACFC20B5F1C100F12B28 /* Info.plist */,
|
||||||
|
4A43515B21249E5700261999 /* ValidatorsTests.swift */,
|
||||||
);
|
);
|
||||||
path = WireGuardTests;
|
path = WireGuardTests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -259,6 +265,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
4AC086822120B9F900CEE5ED /* ProviderConfigurationKeys.swift */,
|
4AC086822120B9F900CEE5ED /* ProviderConfigurationKeys.swift */,
|
||||||
|
4A4351582124956200261999 /* Validators.swift */,
|
||||||
);
|
);
|
||||||
path = Shared;
|
path = Shared;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -528,6 +535,7 @@
|
||||||
4A4BAD1A20B5F8FF00F12B28 /* Tunnel+CoreDataClass.swift in Sources */,
|
4A4BAD1A20B5F8FF00F12B28 /* Tunnel+CoreDataClass.swift in Sources */,
|
||||||
4A4BACE820B5F1BF00F12B28 /* TunnelsTableViewController.swift in Sources */,
|
4A4BACE820B5F1BF00F12B28 /* TunnelsTableViewController.swift in Sources */,
|
||||||
4A4BAD1020B5F6EC00F12B28 /* RootCoordinator.swift in Sources */,
|
4A4BAD1020B5F6EC00F12B28 /* RootCoordinator.swift in Sources */,
|
||||||
|
4A4351592124956200261999 /* Validators.swift in Sources */,
|
||||||
4AC5462E2116306F00749D21 /* Tunnel+Extension.swift in Sources */,
|
4AC5462E2116306F00749D21 /* Tunnel+Extension.swift in Sources */,
|
||||||
4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */,
|
4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */,
|
||||||
4A4BA6D820B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift in Sources */,
|
4A4BA6D820B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift in Sources */,
|
||||||
|
@ -545,6 +553,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
4A43515C21249E5700261999 /* ValidatorsTests.swift in Sources */,
|
||||||
4A4BACFB20B5F1C100F12B28 /* WireGuardTests.swift in Sources */,
|
4A4BACFB20B5F1C100F12B28 /* WireGuardTests.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -556,6 +565,7 @@
|
||||||
4AD095CC20DC42CD000E9CF5 /* WireGuardGoWrapper.m in Sources */,
|
4AD095CC20DC42CD000E9CF5 /* WireGuardGoWrapper.m in Sources */,
|
||||||
4AC086852120BCB500CEE5ED /* ProviderConfigurationKeys.swift in Sources */,
|
4AC086852120BCB500CEE5ED /* ProviderConfigurationKeys.swift in Sources */,
|
||||||
4AC086862120BD5800CEE5ED /* PacketTunnelProvider.swift in Sources */,
|
4AC086862120BD5800CEE5ED /* PacketTunnelProvider.swift in Sources */,
|
||||||
|
4A43515A2124956200261999 /* Validators.swift in Sources */,
|
||||||
4AEAC32920F14B3B007B67AB /* Log.swift in Sources */,
|
4AEAC32920F14B3B007B67AB /* Log.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
//
|
||||||
|
// ValidatorsTests.swift
|
||||||
|
// WireGuardTests
|
||||||
|
//
|
||||||
|
// Created by Jeroen Leenarts on 15-08-18.
|
||||||
|
// Copyright © 2018 WireGuard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
@testable import WireGuard
|
||||||
|
|
||||||
|
class ValidatorsTests: XCTestCase {
|
||||||
|
func testIPv6Endpoint() throws {
|
||||||
|
XCTFail("Still needs implementation")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIPv4Endpoint() throws {
|
||||||
|
_ = try Endpoint(endpointString: "192.168.0.1:12345")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIPv4Endpoint_invalidIP() throws {
|
||||||
|
XCTAssertThrowsError(try Endpoint(endpointString: "12345:12345")) { (error) in
|
||||||
|
guard case EndpointValidationError.invalidIP(let value) = error else {
|
||||||
|
return XCTFail("Unexpected error")
|
||||||
|
}
|
||||||
|
XCTAssertEqual(value, "12345")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIPv4Endpoint_invalidPort() throws {
|
||||||
|
XCTAssertThrowsError(try Endpoint(endpointString: "192.168.0.1:-12345")) { (error) in
|
||||||
|
guard case EndpointValidationError.invalidPort(let value) = error else {
|
||||||
|
return XCTFail("Unexpected error")
|
||||||
|
}
|
||||||
|
XCTAssertEqual(value, "-12345")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testIPv4Endpoint_noIpAndPort() throws {
|
||||||
|
|
||||||
|
func executeTest(endpointString: String) {
|
||||||
|
XCTAssertThrowsError(try Endpoint(endpointString: endpointString)) { (error) in
|
||||||
|
guard case EndpointValidationError.noIpAndPort(let value) = error else {
|
||||||
|
return XCTFail("Unexpected error")
|
||||||
|
}
|
||||||
|
XCTAssertEqual(value, endpointString, file: #file, line: #line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
executeTest(endpointString: ":")
|
||||||
|
executeTest(endpointString: "192.168.0.1")
|
||||||
|
executeTest(endpointString: "192.168.0.1:")
|
||||||
|
executeTest(endpointString: ":12345")
|
||||||
|
executeTest(endpointString: "12345")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue