Make SessionProxy* top level

Drop redundant SessionReply.
This commit is contained in:
Davide De Rosa 2019-05-19 14:17:18 +02:00
parent 465e08e42f
commit 9c7ae47679
5 changed files with 1204 additions and 1210 deletions

View File

@ -28,8 +28,8 @@ custom_categories:
children: children:
- OpenVPN - OpenVPN
- SessionError - SessionError
- SessionProxy
- SessionProxyDelegate - SessionProxyDelegate
- SessionReply
- name: AppExtension - name: AppExtension
children: children:
- TunnelKitProvider - TunnelKitProvider

View File

@ -64,8 +64,8 @@
0E3B65752249253B00EFF4DA /* tunnelbear.enc.1.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B656E224923EC00EFF4DA /* tunnelbear.enc.1.ovpn */; }; 0E3B65752249253B00EFF4DA /* tunnelbear.enc.1.ovpn in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B656E224923EC00EFF4DA /* tunnelbear.enc.1.ovpn */; };
0E3B65762249253F00EFF4DA /* tunnelbear.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B65712249247E00EFF4DA /* tunnelbear.key */; }; 0E3B65762249253F00EFF4DA /* tunnelbear.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B65712249247E00EFF4DA /* tunnelbear.key */; };
0E3B65772249254000EFF4DA /* tunnelbear.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B65712249247E00EFF4DA /* tunnelbear.key */; }; 0E3B65772249254000EFF4DA /* tunnelbear.key in Resources */ = {isa = PBXBuildFile; fileRef = 0E3B65712249247E00EFF4DA /* tunnelbear.key */; };
0E3E0F212108A8CC00B371C1 /* SessionReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionReply.swift */; }; 0E3E0F212108A8CC00B371C1 /* PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* PushReply.swift */; };
0E3E0F222108A8CC00B371C1 /* SessionReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* SessionReply.swift */; }; 0E3E0F222108A8CC00B371C1 /* PushReply.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3E0F202108A8CC00B371C1 /* PushReply.swift */; };
0E411B9B2271F90700E0852C /* DNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E411B992271F90700E0852C /* DNS.h */; }; 0E411B9B2271F90700E0852C /* DNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E411B992271F90700E0852C /* DNS.h */; };
0E411B9C2271F90700E0852C /* DNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E411B992271F90700E0852C /* DNS.h */; }; 0E411B9C2271F90700E0852C /* DNS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E411B992271F90700E0852C /* DNS.h */; };
0E411B9D2271F90700E0852C /* DNS.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E411B9A2271F90700E0852C /* DNS.m */; }; 0E411B9D2271F90700E0852C /* DNS.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E411B9A2271F90700E0852C /* DNS.m */; };
@ -268,7 +268,7 @@
0E3B15C62152B05E00984B17 /* CryptoCTR.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoCTR.m; sourceTree = "<group>"; }; 0E3B15C62152B05E00984B17 /* CryptoCTR.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CryptoCTR.m; sourceTree = "<group>"; };
0E3B656E224923EC00EFF4DA /* tunnelbear.enc.1.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.enc.1.ovpn; sourceTree = "<group>"; }; 0E3B656E224923EC00EFF4DA /* tunnelbear.enc.1.ovpn */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.enc.1.ovpn; sourceTree = "<group>"; };
0E3B65712249247E00EFF4DA /* tunnelbear.key */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.key; sourceTree = "<group>"; }; 0E3B65712249247E00EFF4DA /* tunnelbear.key */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tunnelbear.key; sourceTree = "<group>"; };
0E3E0F202108A8CC00B371C1 /* SessionReply.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionReply.swift; sourceTree = "<group>"; }; 0E3E0F202108A8CC00B371C1 /* PushReply.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushReply.swift; sourceTree = "<group>"; };
0E411B992271F90700E0852C /* DNS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DNS.h; sourceTree = "<group>"; }; 0E411B992271F90700E0852C /* DNS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DNS.h; sourceTree = "<group>"; };
0E411B9A2271F90700E0852C /* DNS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DNS.m; sourceTree = "<group>"; }; 0E411B9A2271F90700E0852C /* DNS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DNS.m; sourceTree = "<group>"; };
0E411B9F2271FA3300E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; }; 0E411B9F2271FA3300E0852C /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libresolv.tbd; sourceTree = DEVELOPER_DIR; };
@ -570,13 +570,13 @@
0E48AC622271ADA8009B1A98 /* PacketStream.h */, 0E48AC622271ADA8009B1A98 /* PacketStream.h */,
0E48AC632271ADA9009B1A98 /* PacketStream.m */, 0E48AC632271ADA9009B1A98 /* PacketStream.m */,
0EFEB4382006D3C800F81029 /* ProtocolMacros.swift */, 0EFEB4382006D3C800F81029 /* ProtocolMacros.swift */,
0E3E0F202108A8CC00B371C1 /* PushReply.swift */,
0EFEB4392006D3C800F81029 /* ReplayProtector.h */, 0EFEB4392006D3C800F81029 /* ReplayProtector.h */,
0EFEB4482006D3C800F81029 /* ReplayProtector.m */, 0EFEB4482006D3C800F81029 /* ReplayProtector.m */,
0E0C2123212ED29D008AB282 /* SessionError.swift */, 0E0C2123212ED29D008AB282 /* SessionError.swift */,
0EFEB42B2006D3C800F81029 /* SessionKey.swift */, 0EFEB42B2006D3C800F81029 /* SessionKey.swift */,
0EFEB43C2006D3C800F81029 /* SessionProxy.swift */, 0EFEB43C2006D3C800F81029 /* SessionProxy.swift */,
0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */, 0E749F5E2178885500BB2701 /* SessionProxy+PIA.swift */,
0E3E0F202108A8CC00B371C1 /* SessionReply.swift */,
0EE3B3E321471C3A0027AB17 /* StaticKey.swift */, 0EE3B3E321471C3A0027AB17 /* StaticKey.swift */,
0EFEB4442006D3C800F81029 /* TLSBox.h */, 0EFEB4442006D3C800F81029 /* TLSBox.h */,
0EFEB4302006D3C800F81029 /* TLSBox.m */, 0EFEB4302006D3C800F81029 /* TLSBox.m */,
@ -1139,7 +1139,7 @@
0EFEB4672006D3C800F81029 /* SessionProxy.swift in Sources */, 0EFEB4672006D3C800F81029 /* SessionProxy.swift in Sources */,
0ED9C8642138139000621BA3 /* CompressionFraming.swift in Sources */, 0ED9C8642138139000621BA3 /* CompressionFraming.swift in Sources */,
0EFEB4722006D3C800F81029 /* ReplayProtector.m in Sources */, 0EFEB4722006D3C800F81029 /* ReplayProtector.m in Sources */,
0E3E0F212108A8CC00B371C1 /* SessionReply.swift in Sources */, 0E3E0F212108A8CC00B371C1 /* PushReply.swift in Sources */,
0ECC60D82254981A0020BEAC /* ConfigurationError.swift in Sources */, 0ECC60D82254981A0020BEAC /* ConfigurationError.swift in Sources */,
0EFEB4752006D3C800F81029 /* Errors.m in Sources */, 0EFEB4752006D3C800F81029 /* Errors.m in Sources */,
0E58BF532240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */, 0E58BF532240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */,
@ -1202,7 +1202,7 @@
0ED9C8652138139000621BA3 /* CompressionFraming.swift in Sources */, 0ED9C8652138139000621BA3 /* CompressionFraming.swift in Sources */,
0EFEB4A42006D7F300F81029 /* DataPath.m in Sources */, 0EFEB4A42006D7F300F81029 /* DataPath.m in Sources */,
0ECC60D92254981A0020BEAC /* ConfigurationError.swift in Sources */, 0ECC60D92254981A0020BEAC /* ConfigurationError.swift in Sources */,
0E3E0F222108A8CC00B371C1 /* SessionReply.swift in Sources */, 0E3E0F222108A8CC00B371C1 /* PushReply.swift in Sources */,
0E58BF542240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */, 0E58BF542240FAA6006FB157 /* CompressionAlgorithm.swift in Sources */,
0E12B2A621454F7F00B4BAE9 /* BidirectionalState.swift in Sources */, 0E12B2A621454F7F00B4BAE9 /* BidirectionalState.swift in Sources */,
0EB03E402290D310006D03A0 /* CoreConfiguration+OpenVPN.swift in Sources */, 0EB03E402290D310006D03A0 /* CoreConfiguration+OpenVPN.swift in Sources */,

View File

@ -1,5 +1,5 @@
// //
// SessionReply.swift // PushReply.swift
// TunnelKit // TunnelKit
// //
// Created by Davide De Rosa on 7/25/18. // Created by Davide De Rosa on 7/25/18.
@ -36,20 +36,16 @@
import Foundation import Foundation
/// Groups the parsed reply of a successfully started session.
public protocol SessionReply {
/// The returned options.
var options: OpenVPN.Configuration { get }
}
extension OpenVPN { extension OpenVPN {
struct PushReply: SessionReply, CustomStringConvertible {
/// Groups the parsed reply of a successfully started session.
public struct PushReply: CustomStringConvertible {
private static let prefix = "PUSH_REPLY," private static let prefix = "PUSH_REPLY,"
private let original: String private let original: String
let options: Configuration /// The pushed options as a `Configuration` object.
public let options: Configuration
init?(message: String) throws { init?(message: String) throws {
guard message.hasPrefix(PushReply.prefix) else { guard message.hasPrefix(PushReply.prefix) else {
@ -66,7 +62,8 @@ extension OpenVPN {
// MARK: CustomStringConvertible // MARK: CustomStringConvertible
var description: String { /// :nodoc:
public var description: String {
let stripped = NSMutableString(string: original) let stripped = NSMutableString(string: original)
ConfigurationParser.Regex.authToken.replaceMatches( ConfigurationParser.Regex.authToken.replaceMatches(
in: stripped, in: stripped,

View File

@ -36,7 +36,7 @@
import Foundation import Foundation
extension OpenVPN.SessionProxy { extension SessionProxy {
struct PIAHardReset { struct PIAHardReset {
private static let obfuscationKeyLength = 3 private static let obfuscationKeyLength = 3

View File

@ -48,9 +48,9 @@ public protocol SessionProxyDelegate: class {
Called after starting a session. Called after starting a session.
- Parameter remoteAddress: The address of the VPN server. - Parameter remoteAddress: The address of the VPN server.
- Parameter reply: The compound `SessionReply` containing tunnel settings. - Parameter options: The pulled tunnel settings.
*/ */
func sessionDidStart(_: OpenVPN.SessionProxy, remoteAddress: String, reply: SessionReply) func sessionDidStart(_: SessionProxy, remoteAddress: String, options: OpenVPN.PushReply)
/** /**
Called after stopping a session. Called after stopping a session.
@ -58,11 +58,9 @@ public protocol SessionProxyDelegate: class {
- Parameter shouldReconnect: When `true`, the session can/should be restarted. Usually because the stop reason was recoverable. - Parameter shouldReconnect: When `true`, the session can/should be restarted. Usually because the stop reason was recoverable.
- Seealso: `SessionProxy.reconnect(...)` - Seealso: `SessionProxy.reconnect(...)`
*/ */
func sessionDidStop(_: OpenVPN.SessionProxy, shouldReconnect: Bool) func sessionDidStop(_: SessionProxy, shouldReconnect: Bool)
} }
extension OpenVPN {
/// Provides methods to set up and maintain an OpenVPN session. /// Provides methods to set up and maintain an OpenVPN session.
public class SessionProxy { public class SessionProxy {
private enum StopMethod { private enum StopMethod {
@ -82,10 +80,10 @@ extension OpenVPN {
// MARK: Configuration // MARK: Configuration
/// The session base configuration. /// The session base configuration.
public let configuration: Configuration public let configuration: OpenVPN.Configuration
/// The optional credentials. /// The optional credentials.
public var credentials: Credentials? public var credentials: OpenVPN.Credentials?
private var keepAliveInterval: TimeInterval? { private var keepAliveInterval: TimeInterval? {
let interval: TimeInterval? let interval: TimeInterval?
@ -110,22 +108,22 @@ extension OpenVPN {
private var withLocalOptions: Bool private var withLocalOptions: Bool
private var keys: [UInt8: SessionKey] private var keys: [UInt8: OpenVPN.SessionKey]
private var oldKeys: [SessionKey] private var oldKeys: [OpenVPN.SessionKey]
private var negotiationKeyIdx: UInt8 private var negotiationKeyIdx: UInt8
private var currentKeyIdx: UInt8? private var currentKeyIdx: UInt8?
private var negotiationKey: SessionKey { private var negotiationKey: OpenVPN.SessionKey {
guard let key = keys[negotiationKeyIdx] else { guard let key = keys[negotiationKeyIdx] else {
fatalError("Keys are empty or index \(negotiationKeyIdx) not found in \(keys.keys)") fatalError("Keys are empty or index \(negotiationKeyIdx) not found in \(keys.keys)")
} }
return key return key
} }
private var currentKey: SessionKey? { private var currentKey: OpenVPN.SessionKey? {
guard let i = currentKeyIdx else { guard let i = currentKeyIdx else {
return nil return nil
} }
@ -142,7 +140,7 @@ extension OpenVPN {
private var continuatedPushReplyMessage: String? private var continuatedPushReplyMessage: String?
private var pushReply: SessionReply? private var pushReply: OpenVPN.PushReply?
private var nextPushRequestDate: Date? private var nextPushRequestDate: Date?
@ -157,9 +155,9 @@ extension OpenVPN {
// MARK: Control // MARK: Control
private var controlChannel: ControlChannel private var controlChannel: OpenVPN.ControlChannel
private var authenticator: Authenticator? private var authenticator: OpenVPN.Authenticator?
// MARK: Caching // MARK: Caching
@ -185,7 +183,7 @@ extension OpenVPN {
- Parameter queue: The `DispatchQueue` where to run the session loop. - Parameter queue: The `DispatchQueue` where to run the session loop.
- Parameter configuration: The `Configuration` to use for this session. - Parameter configuration: The `Configuration` to use for this session.
*/ */
public init(queue: DispatchQueue, configuration: Configuration, cachesURL: URL) throws { public init(queue: DispatchQueue, configuration: OpenVPN.Configuration, cachesURL: URL) throws {
guard let ca = configuration.ca else { guard let ca = configuration.ca else {
throw ConfigurationError.missingConfiguration(option: "ca") throw ConfigurationError.missingConfiguration(option: "ca")
} }
@ -204,13 +202,13 @@ extension OpenVPN {
if let tlsWrap = configuration.tlsWrap { if let tlsWrap = configuration.tlsWrap {
switch tlsWrap.strategy { switch tlsWrap.strategy {
case .auth: case .auth:
controlChannel = try ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.fallbackDigest) controlChannel = try OpenVPN.ControlChannel(withAuthKey: tlsWrap.key, digest: configuration.fallbackDigest)
case .crypt: case .crypt:
controlChannel = try ControlChannel(withCryptKey: tlsWrap.key) controlChannel = try OpenVPN.ControlChannel(withCryptKey: tlsWrap.key)
} }
} else { } else {
controlChannel = ControlChannel() controlChannel = OpenVPN.ControlChannel()
} }
// cache PEMs locally (mandatory for OpenSSL) // cache PEMs locally (mandatory for OpenSSL)
@ -583,7 +581,7 @@ extension OpenVPN {
} }
log.debug("Send ping") log.debug("Send ping")
sendDataPackets([DataPacket.pingString]) sendDataPackets([OpenVPN.DataPacket.pingString])
lastPing.outbound = Date() lastPing.outbound = Date()
scheduleNextPing() scheduleNextPing()
@ -619,7 +617,7 @@ extension OpenVPN {
continuatedPushReplyMessage = nil continuatedPushReplyMessage = nil
pushReply = nil pushReply = nil
negotiationKeyIdx = 0 negotiationKeyIdx = 0
let newKey = SessionKey(id: UInt8(negotiationKeyIdx)) let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx))
keys[negotiationKeyIdx] = newKey keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)") log.debug("Negotiation key index is \(negotiationKeyIdx)")
@ -660,8 +658,8 @@ extension OpenVPN {
} }
resetControlChannel(forNewSession: false) resetControlChannel(forNewSession: false)
negotiationKeyIdx = max(1, (negotiationKeyIdx + 1) % ProtocolMacros.numberOfKeys) negotiationKeyIdx = max(1, (negotiationKeyIdx + 1) % OpenVPN.ProtocolMacros.numberOfKeys)
let newKey = SessionKey(id: UInt8(negotiationKeyIdx)) let newKey = OpenVPN.SessionKey(id: UInt8(negotiationKeyIdx))
keys[negotiationKeyIdx] = newKey keys[negotiationKeyIdx] = newKey
log.debug("Negotiation key index is \(negotiationKeyIdx)") log.debug("Negotiation key index is \(negotiationKeyIdx)")
@ -680,7 +678,7 @@ extension OpenVPN {
negotiationKey.controlState = .preAuth negotiationKey.controlState = .preAuth
do { do {
authenticator = try Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password) authenticator = try OpenVPN.Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password)
authenticator?.withLocalOptions = withLocalOptions authenticator?.withLocalOptions = withLocalOptions
try authenticator?.putAuth(into: negotiationKey.tls, options: configuration) try authenticator?.putAuth(into: negotiationKey.tls, options: configuration)
} catch let e { } catch let e {
@ -945,9 +943,9 @@ extension OpenVPN {
} else { } else {
completeMessage = message completeMessage = message
} }
let reply: PushReply let reply: OpenVPN.PushReply
do { do {
guard let optionalReply = try PushReply(message: completeMessage) else { guard let optionalReply = try OpenVPN.PushReply(message: completeMessage) else {
return return
} }
reply = optionalReply reply = optionalReply
@ -989,7 +987,7 @@ extension OpenVPN {
guard let remoteAddress = link?.remoteAddress else { guard let remoteAddress = link?.remoteAddress else {
fatalError("Could not resolve link remote address") fatalError("Could not resolve link remote address")
} }
delegate?.sessionDidStart(self, remoteAddress: remoteAddress, reply: reply) delegate?.sessionDidStart(self, remoteAddress: remoteAddress, options: reply)
scheduleNextPing() scheduleNextPing()
} }
@ -1095,9 +1093,9 @@ extension OpenVPN {
log.info("\tNegotiated keep-alive: \(negPing) seconds") log.info("\tNegotiated keep-alive: \(negPing) seconds")
} }
let bridge: EncryptionBridge let bridge: OpenVPN.EncryptionBridge
do { do {
bridge = try EncryptionBridge( bridge = try OpenVPN.EncryptionBridge(
pushedCipher ?? configuration.fallbackCipher, pushedCipher ?? configuration.fallbackCipher,
configuration.fallbackDigest, configuration.fallbackDigest,
auth, auth,
@ -1123,7 +1121,7 @@ extension OpenVPN {
// MARK: Data // MARK: Data
// Ruby: handle_data_pkt // Ruby: handle_data_pkt
private func handleDataPackets(_ packets: [Data], key: SessionKey) { private func handleDataPackets(_ packets: [Data], key: OpenVPN.SessionKey) {
controlChannel.addReceivedDataCount(packets.flatCount) controlChannel.addReceivedDataCount(packets.flatCount)
do { do {
guard let decryptedPackets = try key.decrypt(packets: packets) else { guard let decryptedPackets = try key.decrypt(packets: packets) else {
@ -1242,7 +1240,7 @@ extension OpenVPN {
// shut down after sending exit notification if socket is unreliable (normally UDP) // shut down after sending exit notification if socket is unreliable (normally UDP)
if let link = link, !link.isReliable { if let link = link, !link.isReliable {
do { do {
guard let packets = try currentKey?.encrypt(packets: [OCCPacket.exit.serialized()]) else { guard let packets = try currentKey?.encrypt(packets: [OpenVPN.OCCPacket.exit.serialized()]) else {
completion() completion()
return return
} }
@ -1279,4 +1277,3 @@ extension OpenVPN {
delegate?.sessionDidStop(self, shouldReconnect: true) delegate?.sessionDidStop(self, shouldReconnect: true)
} }
} }
}