Move endpoints inside SessionProxy.Configuration
Make optional. TunnelKitProvider still gets hostname from .serverAddress rather than SessionProxy.Configuration Also drop useless Equatable implementations.
This commit is contained in:
parent
10adc7086f
commit
7aec0637b2
|
@ -59,11 +59,13 @@ class ConnectionStrategy {
|
|||
prefersResolvedAddresses = configuration.prefersResolvedAddresses
|
||||
resolvedAddresses = configuration.resolvedAddresses
|
||||
|
||||
if configuration.sessionConfiguration.randomizeEndpoint ?? false {
|
||||
endpointProtocols = configuration.endpointProtocols.shuffled()
|
||||
} else {
|
||||
endpointProtocols = configuration.endpointProtocols
|
||||
guard var endpointProtocols = configuration.sessionConfiguration.endpointProtocols else {
|
||||
fatalError("No endpoints defined")
|
||||
}
|
||||
if configuration.sessionConfiguration.randomizeEndpoint ?? false {
|
||||
endpointProtocols.shuffle()
|
||||
}
|
||||
self.endpointProtocols = endpointProtocols
|
||||
}
|
||||
|
||||
func createSocket(
|
||||
|
|
|
@ -52,24 +52,29 @@ extension TunnelKitProvider {
|
|||
public static let defaults = Configuration(
|
||||
prefersResolvedAddresses: false,
|
||||
resolvedAddresses: nil,
|
||||
endpointProtocols: [EndpointProtocol(.udp, 1194)],
|
||||
mtu: 1250,
|
||||
sessionConfiguration: SessionProxy.Configuration(
|
||||
cipher: .aes128cbc,
|
||||
digest: .sha1,
|
||||
ca: CryptoContainer(pem: ""),
|
||||
compressionFraming: .disabled,
|
||||
compressionAlgorithm: nil,
|
||||
ca: nil,
|
||||
clientCertificate: nil,
|
||||
clientKey: nil,
|
||||
checksEKU: false,
|
||||
compressionFraming: .disabled,
|
||||
compressionAlgorithm: .disabled,
|
||||
tlsWrap: nil,
|
||||
keepAliveInterval: nil,
|
||||
renegotiatesAfter: nil,
|
||||
hostname: nil,
|
||||
endpointProtocols: nil,
|
||||
checksEKU: nil,
|
||||
randomizeEndpoint: nil,
|
||||
usesPIAPatches: nil,
|
||||
authToken: nil,
|
||||
peerId: nil,
|
||||
ipv4: nil,
|
||||
ipv6: nil,
|
||||
dnsServers: nil,
|
||||
searchDomain: nil,
|
||||
randomizeEndpoint: false,
|
||||
usesPIAPatches: nil
|
||||
searchDomain: nil
|
||||
),
|
||||
shouldDebug: false,
|
||||
debugLogFormat: nil,
|
||||
|
@ -84,9 +89,6 @@ extension TunnelKitProvider {
|
|||
/// Resolved addresses in case DNS fails or `prefersResolvedAddresses` is `true`.
|
||||
public var resolvedAddresses: [String]?
|
||||
|
||||
/// The accepted communication protocols. Must be non-empty.
|
||||
public var endpointProtocols: [EndpointProtocol]
|
||||
|
||||
/// The MTU of the link.
|
||||
public var mtu: Int
|
||||
|
||||
|
@ -114,7 +116,6 @@ extension TunnelKitProvider {
|
|||
public init(sessionConfiguration: SessionProxy.Configuration) {
|
||||
prefersResolvedAddresses = ConfigurationBuilder.defaults.prefersResolvedAddresses
|
||||
resolvedAddresses = nil
|
||||
endpointProtocols = ConfigurationBuilder.defaults.endpointProtocols
|
||||
mtu = ConfigurationBuilder.defaults.mtu
|
||||
self.sessionConfiguration = sessionConfiguration
|
||||
shouldDebug = ConfigurationBuilder.defaults.shouldDebug
|
||||
|
@ -127,15 +128,6 @@ extension TunnelKitProvider {
|
|||
|
||||
prefersResolvedAddresses = providerConfiguration[S.prefersResolvedAddresses] as? Bool ?? ConfigurationBuilder.defaults.prefersResolvedAddresses
|
||||
resolvedAddresses = providerConfiguration[S.resolvedAddresses] as? [String]
|
||||
guard let endpointProtocolsStrings = providerConfiguration[S.endpointProtocols] as? [String], !endpointProtocolsStrings.isEmpty else {
|
||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.endpointProtocols)] is nil or empty")
|
||||
}
|
||||
endpointProtocols = try endpointProtocolsStrings.map {
|
||||
guard let ep = EndpointProtocol(rawValue: $0) else {
|
||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.endpointProtocols)] has a badly formed element")
|
||||
}
|
||||
return ep
|
||||
}
|
||||
mtu = providerConfiguration[S.mtu] as? Int ?? ConfigurationBuilder.defaults.mtu
|
||||
|
||||
//
|
||||
|
@ -166,7 +158,8 @@ extension TunnelKitProvider {
|
|||
clientKey = nil
|
||||
}
|
||||
|
||||
var sessionConfigurationBuilder = SessionProxy.ConfigurationBuilder(ca: ca)
|
||||
var sessionConfigurationBuilder = SessionProxy.ConfigurationBuilder()
|
||||
sessionConfigurationBuilder.ca = ca
|
||||
sessionConfigurationBuilder.cipher = cipher
|
||||
sessionConfigurationBuilder.digest = digest
|
||||
sessionConfigurationBuilder.clientCertificate = clientCertificate
|
||||
|
@ -190,6 +183,15 @@ extension TunnelKitProvider {
|
|||
}
|
||||
sessionConfigurationBuilder.keepAliveInterval = providerConfiguration[S.keepAlive] as? TimeInterval ?? ConfigurationBuilder.defaults.sessionConfiguration.keepAliveInterval
|
||||
sessionConfigurationBuilder.renegotiatesAfter = providerConfiguration[S.renegotiatesAfter] as? TimeInterval ?? ConfigurationBuilder.defaults.sessionConfiguration.renegotiatesAfter
|
||||
guard let endpointProtocolsStrings = providerConfiguration[S.endpointProtocols] as? [String], !endpointProtocolsStrings.isEmpty else {
|
||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.endpointProtocols)] is nil or empty")
|
||||
}
|
||||
sessionConfigurationBuilder.endpointProtocols = try endpointProtocolsStrings.map {
|
||||
guard let ep = EndpointProtocol(rawValue: $0) else {
|
||||
throw ProviderConfigurationError.parameter(name: "protocolConfiguration.providerConfiguration[\(S.endpointProtocols)] has a badly formed element")
|
||||
}
|
||||
return ep
|
||||
}
|
||||
sessionConfigurationBuilder.checksEKU = providerConfiguration[S.checksEKU] as? Bool ?? ConfigurationBuilder.defaults.sessionConfiguration.checksEKU
|
||||
sessionConfigurationBuilder.dnsServers = providerConfiguration[S.dnsServers] as? [String]
|
||||
sessionConfigurationBuilder.searchDomain = providerConfiguration[S.searchDomain] as? String
|
||||
|
@ -217,7 +219,6 @@ extension TunnelKitProvider {
|
|||
return Configuration(
|
||||
prefersResolvedAddresses: prefersResolvedAddresses,
|
||||
resolvedAddresses: resolvedAddresses,
|
||||
endpointProtocols: endpointProtocols,
|
||||
mtu: mtu,
|
||||
sessionConfiguration: sessionConfiguration,
|
||||
shouldDebug: shouldDebug,
|
||||
|
@ -236,8 +237,6 @@ extension TunnelKitProvider {
|
|||
|
||||
static let resolvedAddresses = "ResolvedAddresses"
|
||||
|
||||
static let endpointProtocols = "EndpointProtocols"
|
||||
|
||||
static let mtu = "MTU"
|
||||
|
||||
// MARK: SessionConfiguration
|
||||
|
@ -260,6 +259,8 @@ extension TunnelKitProvider {
|
|||
|
||||
static let keepAlive = "KeepAlive"
|
||||
|
||||
static let endpointProtocols = "EndpointProtocols"
|
||||
|
||||
static let renegotiatesAfter = "RenegotiatesAfter"
|
||||
|
||||
static let checksEKU = "ChecksEKU"
|
||||
|
@ -287,9 +288,6 @@ extension TunnelKitProvider {
|
|||
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.resolvedAddresses`
|
||||
public let resolvedAddresses: [String]?
|
||||
|
||||
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.endpointProtocols`
|
||||
public let endpointProtocols: [EndpointProtocol]
|
||||
|
||||
/// - Seealso: `TunnelKitProvider.ConfigurationBuilder.mtu`
|
||||
public let mtu: Int
|
||||
|
||||
|
@ -417,29 +415,33 @@ extension TunnelKitProvider {
|
|||
public func generatedProviderConfiguration(appGroup: String) -> [String: Any] {
|
||||
let S = Keys.self
|
||||
|
||||
guard let ca = sessionConfiguration.ca else {
|
||||
fatalError("No sessionConfiguration.ca set")
|
||||
}
|
||||
guard let endpointProtocols = sessionConfiguration.endpointProtocols else {
|
||||
fatalError("No sessionConfiguration.endpointProtocols set")
|
||||
}
|
||||
|
||||
var dict: [String: Any] = [
|
||||
S.appGroup: appGroup,
|
||||
S.prefersResolvedAddresses: prefersResolvedAddresses,
|
||||
S.endpointProtocols: endpointProtocols.map { $0.rawValue },
|
||||
S.cipherAlgorithm: sessionConfiguration.cipher.rawValue,
|
||||
S.digestAlgorithm: sessionConfiguration.digest.rawValue,
|
||||
S.ca: sessionConfiguration.ca.pem,
|
||||
S.compressionFraming: sessionConfiguration.compressionFraming.rawValue,
|
||||
S.ca: ca.pem,
|
||||
S.endpointProtocols: endpointProtocols.map { $0.rawValue },
|
||||
S.mtu: mtu,
|
||||
S.debug: shouldDebug
|
||||
]
|
||||
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm?.rawValue {
|
||||
dict[S.compressionAlgorithm] = compressionAlgorithm
|
||||
}
|
||||
if let clientCertificate = sessionConfiguration.clientCertificate {
|
||||
dict[S.clientCertificate] = clientCertificate.pem
|
||||
}
|
||||
if let clientKey = sessionConfiguration.clientKey {
|
||||
dict[S.clientKey] = clientKey.pem
|
||||
}
|
||||
if let resolvedAddresses = resolvedAddresses {
|
||||
dict[S.resolvedAddresses] = resolvedAddresses
|
||||
}
|
||||
dict[S.compressionFraming] = sessionConfiguration.compressionFraming.rawValue
|
||||
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm?.rawValue {
|
||||
dict[S.compressionAlgorithm] = compressionAlgorithm
|
||||
}
|
||||
if let tlsWrapData = sessionConfiguration.tlsWrap?.serialized() {
|
||||
dict[S.tlsWrap] = tlsWrapData
|
||||
}
|
||||
|
@ -452,17 +454,21 @@ extension TunnelKitProvider {
|
|||
if let checksEKU = sessionConfiguration.checksEKU {
|
||||
dict[S.checksEKU] = checksEKU
|
||||
}
|
||||
if let randomizeEndpoint = sessionConfiguration.randomizeEndpoint {
|
||||
dict[S.randomizeEndpoint] = randomizeEndpoint
|
||||
}
|
||||
if let usesPIAPatches = sessionConfiguration.usesPIAPatches {
|
||||
dict[S.usesPIAPatches] = usesPIAPatches
|
||||
}
|
||||
if let dnsServers = sessionConfiguration.dnsServers {
|
||||
dict[S.dnsServers] = dnsServers
|
||||
}
|
||||
if let searchDomain = sessionConfiguration.searchDomain {
|
||||
dict[S.searchDomain] = searchDomain
|
||||
}
|
||||
if let randomizeEndpoint = sessionConfiguration.randomizeEndpoint {
|
||||
dict[S.randomizeEndpoint] = randomizeEndpoint
|
||||
}
|
||||
if let usesPIAPatches = sessionConfiguration.usesPIAPatches {
|
||||
dict[S.usesPIAPatches] = usesPIAPatches
|
||||
//
|
||||
if let resolvedAddresses = resolvedAddresses {
|
||||
dict[S.resolvedAddresses] = resolvedAddresses
|
||||
}
|
||||
if let debugLogFormat = debugLogFormat {
|
||||
dict[S.debugLogFormat] = debugLogFormat
|
||||
|
@ -504,6 +510,10 @@ extension TunnelKitProvider {
|
|||
}
|
||||
|
||||
func print(appVersion: String?) {
|
||||
guard let endpointProtocols = sessionConfiguration.endpointProtocols else {
|
||||
fatalError("No sessionConfiguration.endpointProtocols set")
|
||||
}
|
||||
|
||||
if let appVersion = appVersion {
|
||||
log.info("App version: \(appVersion)")
|
||||
}
|
||||
|
@ -511,23 +521,22 @@ extension TunnelKitProvider {
|
|||
log.info("\tProtocols: \(endpointProtocols)")
|
||||
log.info("\tCipher: \(sessionConfiguration.cipher)")
|
||||
log.info("\tDigest: \(sessionConfiguration.digest)")
|
||||
if let _ = sessionConfiguration.clientCertificate {
|
||||
log.info("\tClient verification: enabled")
|
||||
} else {
|
||||
log.info("\tClient verification: disabled")
|
||||
}
|
||||
if sessionConfiguration.checksEKU ?? false {
|
||||
log.info("\tServer EKU verification: enabled")
|
||||
} else {
|
||||
log.info("\tServer EKU verification: disabled")
|
||||
}
|
||||
log.info("\tMTU: \(mtu)")
|
||||
log.info("\tCompression framing: \(sessionConfiguration.compressionFraming)")
|
||||
if let compressionAlgorithm = sessionConfiguration.compressionAlgorithm, compressionAlgorithm != .disabled {
|
||||
log.info("\tCompression algorithm: \(compressionAlgorithm)")
|
||||
} else {
|
||||
log.info("\tCompression algorithm: disabled")
|
||||
}
|
||||
if let _ = sessionConfiguration.clientCertificate {
|
||||
log.info("\tClient verification: enabled")
|
||||
} else {
|
||||
log.info("\tClient verification: disabled")
|
||||
}
|
||||
if let tlsWrap = sessionConfiguration.tlsWrap {
|
||||
log.info("\tTLS wrapping: \(tlsWrap.strategy)")
|
||||
} else {
|
||||
log.info("\tTLS wrapping: disabled")
|
||||
}
|
||||
if let keepAliveSeconds = sessionConfiguration.keepAliveInterval, keepAliveSeconds > 0 {
|
||||
log.info("\tKeep-alive: \(keepAliveSeconds) seconds")
|
||||
} else {
|
||||
|
@ -538,20 +547,21 @@ extension TunnelKitProvider {
|
|||
} else {
|
||||
log.info("\tRenegotiation: never")
|
||||
}
|
||||
if let tlsWrap = sessionConfiguration.tlsWrap {
|
||||
log.info("\tTLS wrapping: \(tlsWrap.strategy)")
|
||||
if sessionConfiguration.checksEKU ?? false {
|
||||
log.info("\tServer EKU verification: enabled")
|
||||
} else {
|
||||
log.info("\tTLS wrapping: disabled")
|
||||
}
|
||||
if let dnsServers = sessionConfiguration.dnsServers {
|
||||
log.info("\tCustom DNS servers: \(dnsServers.maskedDescription)")
|
||||
}
|
||||
if let searchDomain = sessionConfiguration.searchDomain {
|
||||
log.info("\tCustom search domain: \(searchDomain.maskedDescription)")
|
||||
log.info("\tServer EKU verification: disabled")
|
||||
}
|
||||
if sessionConfiguration.randomizeEndpoint ?? false {
|
||||
log.info("\tRandomize endpoint: true")
|
||||
}
|
||||
if let dnsServers = sessionConfiguration.dnsServers {
|
||||
log.info("\tDNS servers: \(dnsServers.maskedDescription)")
|
||||
}
|
||||
if let searchDomain = sessionConfiguration.searchDomain {
|
||||
log.info("\tSearch domain: \(searchDomain.maskedDescription)")
|
||||
}
|
||||
log.info("\tMTU: \(mtu)")
|
||||
log.info("\tDebug: \(shouldDebug)")
|
||||
log.info("\tMasks private data: \(masksPrivateData ?? true)")
|
||||
}
|
||||
|
@ -560,7 +570,7 @@ extension TunnelKitProvider {
|
|||
|
||||
// MARK: Modification
|
||||
|
||||
extension TunnelKitProvider.Configuration: Equatable {
|
||||
extension TunnelKitProvider.Configuration {
|
||||
|
||||
/**
|
||||
Returns a `TunnelKitProvider.ConfigurationBuilder` to use this configuration as a starting point for a new one.
|
||||
|
@ -569,22 +579,11 @@ extension TunnelKitProvider.Configuration: Equatable {
|
|||
*/
|
||||
public func builder() -> TunnelKitProvider.ConfigurationBuilder {
|
||||
var builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionConfiguration)
|
||||
builder.endpointProtocols = endpointProtocols
|
||||
builder.mtu = mtu
|
||||
builder.shouldDebug = shouldDebug
|
||||
builder.debugLogFormat = debugLogFormat
|
||||
return builder
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
public static func ==(lhs: TunnelKitProvider.Configuration, rhs: TunnelKitProvider.Configuration) -> Bool {
|
||||
return (
|
||||
(lhs.endpointProtocols == rhs.endpointProtocols) &&
|
||||
(lhs.mtu == rhs.mtu) &&
|
||||
(lhs.sessionConfiguration == rhs.sessionConfiguration)
|
||||
// XXX: tlsWrap not copied
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// :nodoc:
|
||||
|
|
|
@ -38,19 +38,16 @@ public class ConfigurationParser {
|
|||
/// Original URL of the configuration file, if parsed from an URL.
|
||||
public let url: URL?
|
||||
|
||||
/// The main endpoint hostname.
|
||||
public let hostname: String
|
||||
|
||||
/// The list of `EndpointProtocol` to which the client can connect to.
|
||||
public let protocols: [EndpointProtocol]
|
||||
|
||||
/// The overall parsed `SessionProxy.Configuration`.
|
||||
public let configuration: SessionProxy.Configuration
|
||||
|
||||
/// - Seealso: `OptionsBundle.init(...)`
|
||||
/// The lines of the configuration file stripped of any sensitive data. Lines that
|
||||
/// the parser does not recognize are discarded in the first place.
|
||||
///
|
||||
/// - Seealso: `ConfigurationParser.parsed(...)`
|
||||
public let strippedLines: [String]?
|
||||
|
||||
/// - Seealso: `OptionsBundle.warning`
|
||||
/// Holds an optional `OptionsError` that didn't block the parser, but it would be worth taking care of.
|
||||
public let warning: OptionsError?
|
||||
}
|
||||
|
||||
|
@ -103,7 +100,8 @@ public class ConfigurationParser {
|
|||
optClientKey = options.clientKey
|
||||
}
|
||||
|
||||
var sessionBuilder = SessionProxy.ConfigurationBuilder(ca: ca)
|
||||
var sessionBuilder = SessionProxy.ConfigurationBuilder()
|
||||
sessionBuilder.ca = ca
|
||||
sessionBuilder.cipher = options.cipher ?? .aes128cbc
|
||||
sessionBuilder.digest = options.digest ?? .sha1
|
||||
sessionBuilder.compressionFraming = options.compressionFraming ?? .disabled
|
||||
|
@ -111,6 +109,8 @@ public class ConfigurationParser {
|
|||
sessionBuilder.tlsWrap = options.tlsWrap
|
||||
sessionBuilder.clientCertificate = options.clientCertificate
|
||||
sessionBuilder.clientKey = optClientKey
|
||||
sessionBuilder.hostname = hostname
|
||||
sessionBuilder.endpointProtocols = endpointProtocols
|
||||
sessionBuilder.checksEKU = options.checksEKU
|
||||
sessionBuilder.keepAliveInterval = options.keepAliveSeconds
|
||||
sessionBuilder.renegotiatesAfter = options.renegotiateAfterSeconds
|
||||
|
@ -120,8 +120,6 @@ public class ConfigurationParser {
|
|||
|
||||
return ParsingResult(
|
||||
url: originalURL,
|
||||
hostname: hostname,
|
||||
protocols: endpointProtocols,
|
||||
configuration: sessionBuilder.build(),
|
||||
strippedLines: options.strippedLines,
|
||||
warning: options.warning
|
||||
|
|
|
@ -109,13 +109,8 @@ public struct OptionsBundle {
|
|||
case subnet
|
||||
}
|
||||
|
||||
/// The lines of the configuration file stripped of any sensitive data. Lines that
|
||||
/// the parser does not recognize are discarded in the first place.
|
||||
///
|
||||
/// - Seealso: `OptionsBundle.init(...)`
|
||||
public let strippedLines: [String]?
|
||||
|
||||
/// Holds an optional `OptionsError` that didn't block the parser, but it would be worth taking care of.
|
||||
public let warning: OptionsError?
|
||||
|
||||
// MARK: General
|
||||
|
@ -684,10 +679,10 @@ public struct OptionsBundle {
|
|||
}
|
||||
|
||||
/// Encapsulates the IPv4 settings for the tunnel.
|
||||
public struct IPv4Settings: CustomStringConvertible {
|
||||
public struct IPv4Settings: Codable, CustomStringConvertible {
|
||||
|
||||
/// Represents an IPv4 route in the routing table.
|
||||
public struct Route: CustomStringConvertible {
|
||||
public struct Route: Codable, CustomStringConvertible {
|
||||
|
||||
/// The destination host or subnet.
|
||||
public let destination: String
|
||||
|
@ -733,10 +728,10 @@ public struct IPv4Settings: CustomStringConvertible {
|
|||
}
|
||||
|
||||
/// Encapsulates the IPv6 settings for the tunnel.
|
||||
public struct IPv6Settings: CustomStringConvertible {
|
||||
public struct IPv6Settings: Codable, CustomStringConvertible {
|
||||
|
||||
/// Represents an IPv6 route in the routing table.
|
||||
public struct Route: CustomStringConvertible {
|
||||
public struct Route: Codable, CustomStringConvertible {
|
||||
|
||||
/// The destination host or subnet.
|
||||
public let destination: String
|
||||
|
|
|
@ -135,68 +135,100 @@ extension SessionProxy {
|
|||
/// The way to create a `SessionProxy.Configuration` object for a `SessionProxy`.
|
||||
public struct ConfigurationBuilder {
|
||||
|
||||
/// - Seealso: `OptionsBundle.cipher`
|
||||
public var cipher: Cipher
|
||||
// MARK: General
|
||||
|
||||
/// - Seealso: `OptionsBundle.digest`
|
||||
public var digest: Digest
|
||||
/// The cipher algorithm for data encryption.
|
||||
public var cipher: SessionProxy.Cipher
|
||||
|
||||
/// - Seealso: `OptionsBundle.ca`
|
||||
public let ca: CryptoContainer
|
||||
/// The digest algorithm for HMAC.
|
||||
public var digest: SessionProxy.Digest
|
||||
|
||||
/// - Seealso: `OptionsBundle.clientCertificate`
|
||||
/// Compression framing, disabled by default.
|
||||
public var compressionFraming: SessionProxy.CompressionFraming
|
||||
|
||||
/// Compression algorithm, disabled by default.
|
||||
public var compressionAlgorithm: SessionProxy.CompressionAlgorithm?
|
||||
|
||||
/// The CA for TLS negotiation (PEM format).
|
||||
public var ca: CryptoContainer?
|
||||
|
||||
/// The optional client certificate for TLS negotiation (PEM format).
|
||||
public var clientCertificate: CryptoContainer?
|
||||
|
||||
/// - Seealso: `OptionsBundle.clientKey`
|
||||
/// The private key for the certificate in `clientCertificate` (PEM format).
|
||||
public var clientKey: CryptoContainer?
|
||||
|
||||
/// - Seealso: `OptionsBundle.checksEKU`
|
||||
public var checksEKU: Bool?
|
||||
/// The optional TLS wrapping.
|
||||
public var tlsWrap: SessionProxy.TLSWrap?
|
||||
|
||||
/// - Seealso: `OptionsBundle.compressionFraming`
|
||||
public var compressionFraming: CompressionFraming
|
||||
|
||||
/// - Seealso: `OptionsBundle.compressionAlgorithm`
|
||||
public var compressionAlgorithm: CompressionAlgorithm?
|
||||
|
||||
/// - Seealso: `OptionsBundle.tlsWrap`
|
||||
public var tlsWrap: TLSWrap?
|
||||
|
||||
/// - Seealso: `OptionsBundle.keepAliveInterval`
|
||||
/// Sends periodical keep-alive packets if set.
|
||||
public var keepAliveInterval: TimeInterval?
|
||||
|
||||
/// - Seealso: `OptionsBundle.renegotiatesAfter`
|
||||
/// The number of seconds after which a renegotiation should be initiated. If `nil`, the client will never initiate a renegotiation.
|
||||
public var renegotiatesAfter: TimeInterval?
|
||||
|
||||
/// - Seealso: `OptionsBundle.dnsServers`
|
||||
public var dnsServers: [String]?
|
||||
// MARK: Client
|
||||
|
||||
/// - Seealso: `OptionsBundle.searchDomain`
|
||||
public var searchDomain: String?
|
||||
/// The server hostname (picked from first remote).
|
||||
public var hostname: String?
|
||||
|
||||
/// - Seealso: `OptionsBundle.randomizeEndpoint`
|
||||
/// The list of server endpoints.
|
||||
public var endpointProtocols: [EndpointProtocol]?
|
||||
|
||||
/// If true, checks EKU of server certificate.
|
||||
public var checksEKU: Bool?
|
||||
|
||||
/// Picks endpoint from `remotes` randomly.
|
||||
public var randomizeEndpoint: Bool?
|
||||
|
||||
/// Server is patched for the PIA VPN provider.
|
||||
public var usesPIAPatches: Bool?
|
||||
|
||||
// MARK: Server
|
||||
|
||||
/// The auth-token returned by the server.
|
||||
public var authToken: String?
|
||||
|
||||
/// The peer-id returned by the server.
|
||||
public var peerId: UInt32?
|
||||
|
||||
// MARK: Routing
|
||||
|
||||
/// The settings for IPv4.
|
||||
public var ipv4: IPv4Settings?
|
||||
|
||||
/// The settings for IPv6.
|
||||
public var ipv6: IPv6Settings?
|
||||
|
||||
/// The DNS servers.
|
||||
public var dnsServers: [String]?
|
||||
|
||||
/// The search domain.
|
||||
public var searchDomain: String?
|
||||
|
||||
/// :nodoc:
|
||||
public init(ca: CryptoContainer) {
|
||||
public init() {
|
||||
cipher = .aes128cbc
|
||||
digest = .sha1
|
||||
self.ca = ca
|
||||
compressionFraming = .disabled
|
||||
compressionAlgorithm = nil
|
||||
ca = nil
|
||||
clientCertificate = nil
|
||||
clientKey = nil
|
||||
checksEKU = false
|
||||
compressionFraming = .disabled
|
||||
compressionAlgorithm = .disabled
|
||||
tlsWrap = nil
|
||||
keepAliveInterval = nil
|
||||
renegotiatesAfter = nil
|
||||
dnsServers = nil
|
||||
searchDomain = nil
|
||||
hostname = nil
|
||||
endpointProtocols = nil
|
||||
checksEKU = false
|
||||
randomizeEndpoint = false
|
||||
usesPIAPatches = false
|
||||
authToken = nil
|
||||
peerId = nil
|
||||
ipv4 = nil
|
||||
ipv6 = nil
|
||||
dnsServers = nil
|
||||
searchDomain = nil
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,25 +240,31 @@ extension SessionProxy {
|
|||
return Configuration(
|
||||
cipher: cipher,
|
||||
digest: digest,
|
||||
compressionFraming: compressionFraming,
|
||||
compressionAlgorithm: compressionAlgorithm,
|
||||
ca: ca,
|
||||
clientCertificate: clientCertificate,
|
||||
clientKey: clientKey,
|
||||
checksEKU: checksEKU,
|
||||
compressionFraming: compressionFraming,
|
||||
compressionAlgorithm: compressionAlgorithm,
|
||||
tlsWrap: tlsWrap,
|
||||
keepAliveInterval: keepAliveInterval,
|
||||
renegotiatesAfter: renegotiatesAfter,
|
||||
dnsServers: dnsServers,
|
||||
searchDomain: searchDomain,
|
||||
hostname: hostname,
|
||||
endpointProtocols: endpointProtocols,
|
||||
checksEKU: checksEKU,
|
||||
randomizeEndpoint: randomizeEndpoint,
|
||||
usesPIAPatches: usesPIAPatches
|
||||
usesPIAPatches: usesPIAPatches,
|
||||
authToken: authToken,
|
||||
peerId: peerId,
|
||||
ipv4: ipv4,
|
||||
ipv6: ipv6,
|
||||
dnsServers: dnsServers,
|
||||
searchDomain: searchDomain
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// The immutable configuration for `SessionProxy`.
|
||||
public struct Configuration: Codable, Equatable {
|
||||
public struct Configuration: Codable {
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.cipher`
|
||||
public let cipher: Cipher
|
||||
|
@ -234,8 +272,14 @@ extension SessionProxy {
|
|||
/// - Seealso: `SessionProxy.ConfigurationBuilder.digest`
|
||||
public let digest: Digest
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionFraming`
|
||||
public let compressionFraming: CompressionFraming
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionAlgorithm`
|
||||
public let compressionAlgorithm: CompressionAlgorithm?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.ca`
|
||||
public let ca: CryptoContainer
|
||||
public let ca: CryptoContainer?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.clientCertificate`
|
||||
public let clientCertificate: CryptoContainer?
|
||||
|
@ -243,15 +287,6 @@ extension SessionProxy {
|
|||
/// - Seealso: `SessionProxy.ConfigurationBuilder.clientKey`
|
||||
public let clientKey: CryptoContainer?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.checksEKU`
|
||||
public let checksEKU: Bool?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionFraming`
|
||||
public let compressionFraming: CompressionFraming
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.compressionAlgorithm`
|
||||
public let compressionAlgorithm: CompressionAlgorithm?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.tlsWrap`
|
||||
public var tlsWrap: TLSWrap?
|
||||
|
||||
|
@ -261,11 +296,14 @@ extension SessionProxy {
|
|||
/// - Seealso: `SessionProxy.ConfigurationBuilder.renegotiatesAfter`
|
||||
public let renegotiatesAfter: TimeInterval?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.dnsServers`
|
||||
public let dnsServers: [String]?
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.hostname`
|
||||
public var hostname: String?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.searchDomain`
|
||||
public let searchDomain: String?
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.endpointProtocols`
|
||||
public var endpointProtocols: [EndpointProtocol]?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.checksEKU`
|
||||
public let checksEKU: Bool?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.randomizeEndpoint`
|
||||
public let randomizeEndpoint: Bool?
|
||||
|
@ -273,49 +311,52 @@ extension SessionProxy {
|
|||
/// - Seealso: `SessionProxy.ConfigurationBuilder.usesPIAPatches`
|
||||
public let usesPIAPatches: Bool?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.authToken`
|
||||
public let authToken: String?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.peerId`
|
||||
public let peerId: UInt32?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.ipv4`
|
||||
public let ipv4: IPv4Settings?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.ipv6`
|
||||
public let ipv6: IPv6Settings?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.dnsServers`
|
||||
public let dnsServers: [String]?
|
||||
|
||||
/// - Seealso: `SessionProxy.ConfigurationBuilder.searchDomain`
|
||||
public let searchDomain: String?
|
||||
|
||||
/**
|
||||
Returns a `SessionProxy.ConfigurationBuilder` to use this configuration as a starting point for a new one.
|
||||
|
||||
- Returns: An editable `SessionProxy.ConfigurationBuilder` initialized with this configuration.
|
||||
*/
|
||||
public func builder() -> SessionProxy.ConfigurationBuilder {
|
||||
var builder = SessionProxy.ConfigurationBuilder(ca: ca)
|
||||
var builder = SessionProxy.ConfigurationBuilder()
|
||||
builder.cipher = cipher
|
||||
builder.digest = digest
|
||||
builder.clientCertificate = clientCertificate
|
||||
builder.clientKey = clientKey
|
||||
builder.checksEKU = checksEKU
|
||||
builder.compressionFraming = compressionFraming
|
||||
builder.compressionAlgorithm = compressionAlgorithm
|
||||
builder.ca = ca
|
||||
builder.clientCertificate = clientCertificate
|
||||
builder.clientKey = clientKey
|
||||
builder.tlsWrap = tlsWrap
|
||||
builder.keepAliveInterval = keepAliveInterval
|
||||
builder.renegotiatesAfter = renegotiatesAfter
|
||||
builder.dnsServers = dnsServers
|
||||
builder.searchDomain = searchDomain
|
||||
builder.endpointProtocols = endpointProtocols
|
||||
builder.checksEKU = checksEKU
|
||||
builder.randomizeEndpoint = randomizeEndpoint
|
||||
builder.usesPIAPatches = usesPIAPatches
|
||||
builder.authToken = authToken
|
||||
builder.peerId = peerId
|
||||
builder.ipv4 = ipv4
|
||||
builder.ipv6 = ipv6
|
||||
builder.dnsServers = dnsServers
|
||||
builder.searchDomain = searchDomain
|
||||
return builder
|
||||
}
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
/// :nodoc:
|
||||
public static func ==(lhs: Configuration, rhs: Configuration) -> Bool {
|
||||
return
|
||||
(lhs.cipher == rhs.cipher) &&
|
||||
(lhs.digest == rhs.digest) &&
|
||||
(lhs.ca == rhs.ca) &&
|
||||
(lhs.clientCertificate == rhs.clientCertificate) &&
|
||||
(lhs.clientKey == rhs.clientKey) &&
|
||||
(lhs.checksEKU == rhs.checksEKU) &&
|
||||
(lhs.compressionFraming == rhs.compressionFraming) &&
|
||||
(lhs.compressionAlgorithm == rhs.compressionAlgorithm) &&
|
||||
(lhs.keepAliveInterval == rhs.keepAliveInterval) &&
|
||||
(lhs.renegotiatesAfter == rhs.renegotiatesAfter) &&
|
||||
(lhs.dnsServers == rhs.dnsServers) &&
|
||||
(lhs.searchDomain == rhs.searchDomain) &&
|
||||
(lhs.randomizeEndpoint == rhs.randomizeEndpoint) &&
|
||||
(lhs.usesPIAPatches == rhs.usesPIAPatches)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,10 @@ public class SessionProxy {
|
|||
- Parameter configuration: The `SessionProxy.Configuration` to use for this session.
|
||||
*/
|
||||
public init(queue: DispatchQueue, configuration: Configuration, cachesURL: URL) throws {
|
||||
guard let ca = configuration.ca else {
|
||||
throw OptionsError.missingConfiguration(option: "ca")
|
||||
}
|
||||
|
||||
self.queue = queue
|
||||
self.configuration = configuration
|
||||
self.cachesURL = cachesURL
|
||||
|
@ -203,7 +207,7 @@ public class SessionProxy {
|
|||
|
||||
// cache PEMs locally (mandatory for OpenSSL)
|
||||
let fm = FileManager.default
|
||||
try configuration.ca.pem.write(to: caURL, atomically: true, encoding: .ascii)
|
||||
try ca.pem.write(to: caURL, atomically: true, encoding: .ascii)
|
||||
if let container = configuration.clientCertificate {
|
||||
try container.pem.write(to: clientCertificateURL, atomically: true, encoding: .ascii)
|
||||
} else {
|
||||
|
|
|
@ -60,9 +60,11 @@ class AppExtensionTests: XCTestCase {
|
|||
let hostname = "example.com"
|
||||
let credentials = SessionProxy.Credentials("foo", "bar")
|
||||
|
||||
var sessionBuilder = SessionProxy.ConfigurationBuilder(ca: CryptoContainer(pem: "abcdef"))
|
||||
var sessionBuilder = SessionProxy.ConfigurationBuilder()
|
||||
sessionBuilder.ca = CryptoContainer(pem: "abcdef")
|
||||
sessionBuilder.cipher = .aes128cbc
|
||||
sessionBuilder.digest = .sha256
|
||||
sessionBuilder.endpointProtocols = []
|
||||
builder = TunnelKitProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
|
||||
XCTAssertNotNil(builder)
|
||||
|
||||
|
@ -84,7 +86,7 @@ class AppExtensionTests: XCTestCase {
|
|||
XCTAssertEqual(proto?.providerConfiguration?[K.appGroup] as? String, appGroup)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.cipherAlgorithm] as? String, cfg.sessionConfiguration.cipher.rawValue)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.digestAlgorithm] as? String, cfg.sessionConfiguration.digest.rawValue)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.ca] as? String, cfg.sessionConfiguration.ca.pem)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.ca] as? String, cfg.sessionConfiguration.ca?.pem)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.mtu] as? Int, cfg.mtu)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.renegotiatesAfter] as? TimeInterval, cfg.sessionConfiguration.renegotiatesAfter)
|
||||
XCTAssertEqual(proto?.providerConfiguration?[K.debug] as? Bool, cfg.shouldDebug)
|
||||
|
|
|
@ -39,10 +39,10 @@ class ConfigurationParserTests: XCTestCase {
|
|||
|
||||
func testPIA() throws {
|
||||
let file = try ConfigurationParser.parsed(fromURL: url(withName: "pia-hungary"))
|
||||
XCTAssertEqual(file.hostname, "hungary.privateinternetaccess.com")
|
||||
XCTAssertEqual(file.configuration.hostname, "hungary.privateinternetaccess.com")
|
||||
XCTAssertEqual(file.configuration.cipher, .aes128cbc)
|
||||
XCTAssertEqual(file.configuration.digest, .sha1)
|
||||
XCTAssertEqual(file.protocols, [
|
||||
XCTAssertEqual(file.configuration.endpointProtocols, [
|
||||
EndpointProtocol(.udp, 1198),
|
||||
EndpointProtocol(.tcp, 502)
|
||||
])
|
||||
|
|
Loading…
Reference in New Issue