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:
Davide De Rosa 2019-04-04 11:06:00 +02:00
parent 10adc7086f
commit 7aec0637b2
8 changed files with 225 additions and 184 deletions

View File

@ -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(

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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 {

View File

@ -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)

View File

@ -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)
])