Improve some things about OpenVPN.Configuration
- Treat empty passphrase as no passphrase - Parse authentication requirement from --auth-user-pass - Overload ConfigurationParser with String parameter - Move OpenVPN fallbacks inline with builder Give a withFallbacks: option to initialize basic fields rather than leaving them nil.
This commit is contained in:
parent
88544e4877
commit
c019cecbe0
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- Parse OpenVPN authentication requirement from `--auth-user-pass`.
|
||||
|
||||
## 4.1.0 (2022-02-09)
|
||||
|
||||
### Added
|
||||
|
|
|
@ -242,6 +242,9 @@ extension OpenVPN {
|
|||
/// The tunnel MTU.
|
||||
public var mtu: Int?
|
||||
|
||||
/// Requires username authentication.
|
||||
public var authUserPass: Bool?
|
||||
|
||||
// MARK: Server
|
||||
|
||||
/// The auth-token returned by the server.
|
||||
|
@ -300,7 +303,18 @@ extension OpenVPN {
|
|||
/// Policies for redirecting traffic through the VPN gateway.
|
||||
public var routingPolicies: [RoutingPolicy]?
|
||||
|
||||
public init() {
|
||||
/**
|
||||
Creates a `ConfigurationBuilder`.
|
||||
|
||||
- Parameter withFallbacks: If `true`, initializes builder with fallback values rather than nil.
|
||||
*/
|
||||
public init(withFallbacks: Bool = false) {
|
||||
if withFallbacks {
|
||||
cipher = Fallback.cipher
|
||||
digest = Fallback.digest
|
||||
compressionFraming = Fallback.compressionFraming
|
||||
compressionAlgorithm = Fallback.compressionAlgorithm
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -332,6 +346,7 @@ extension OpenVPN {
|
|||
randomizeEndpoint: randomizeEndpoint,
|
||||
usesPIAPatches: usesPIAPatches,
|
||||
mtu: mtu,
|
||||
authUserPass: authUserPass,
|
||||
authToken: authToken,
|
||||
peerId: peerId,
|
||||
ipv4: ipv4,
|
||||
|
@ -348,24 +363,6 @@ extension OpenVPN {
|
|||
routingPolicies: routingPolicies
|
||||
)
|
||||
}
|
||||
|
||||
// MARK: Shortcuts
|
||||
|
||||
public var fallbackCipher: Cipher {
|
||||
return cipher ?? Fallback.cipher
|
||||
}
|
||||
|
||||
public var fallbackDigest: Digest {
|
||||
return digest ?? Fallback.digest
|
||||
}
|
||||
|
||||
public var fallbackCompressionFraming: CompressionFraming {
|
||||
return compressionFraming ?? Fallback.compressionFraming
|
||||
}
|
||||
|
||||
public var fallbackCompressionAlgorithm: CompressionAlgorithm {
|
||||
return compressionAlgorithm ?? Fallback.compressionAlgorithm
|
||||
}
|
||||
}
|
||||
|
||||
/// The immutable configuration for `OpenVPNSession`.
|
||||
|
@ -437,6 +434,9 @@ extension OpenVPN {
|
|||
/// - Seealso: `ConfigurationBuilder.mtu`
|
||||
public let mtu: Int?
|
||||
|
||||
/// - Seealso: `ConfigurationBuilder.authUserPass`
|
||||
public let authUserPass: Bool?
|
||||
|
||||
/// - Seealso: `ConfigurationBuilder.authToken`
|
||||
public let authToken: String?
|
||||
|
||||
|
@ -502,15 +502,16 @@ extension OpenVPN.Configuration {
|
|||
/**
|
||||
Returns a `ConfigurationBuilder` to use this configuration as a starting point for a new one.
|
||||
|
||||
- Parameter withFallbacks: If `true`, initializes builder with fallback values rather than nil.
|
||||
- Returns: An editable `ConfigurationBuilder` initialized with this configuration.
|
||||
*/
|
||||
public func builder() -> OpenVPN.ConfigurationBuilder {
|
||||
public func builder(withFallbacks: Bool = false) -> OpenVPN.ConfigurationBuilder {
|
||||
var builder = OpenVPN.ConfigurationBuilder()
|
||||
builder.cipher = cipher
|
||||
builder.cipher = cipher ?? (withFallbacks ? OpenVPN.Fallback.cipher : nil)
|
||||
builder.dataCiphers = dataCiphers
|
||||
builder.digest = digest
|
||||
builder.compressionFraming = compressionFraming
|
||||
builder.compressionAlgorithm = compressionAlgorithm
|
||||
builder.digest = digest ?? (withFallbacks ? OpenVPN.Fallback.digest : nil)
|
||||
builder.compressionFraming = compressionFraming ?? (withFallbacks ? OpenVPN.Fallback.compressionFraming : nil)
|
||||
builder.compressionAlgorithm = compressionAlgorithm ?? (withFallbacks ? OpenVPN.Fallback.compressionAlgorithm : nil)
|
||||
builder.ca = ca
|
||||
builder.clientCertificate = clientCertificate
|
||||
builder.clientKey = clientKey
|
||||
|
@ -527,6 +528,7 @@ extension OpenVPN.Configuration {
|
|||
builder.randomizeEndpoint = randomizeEndpoint
|
||||
builder.usesPIAPatches = usesPIAPatches
|
||||
builder.mtu = mtu
|
||||
builder.authUserPass = authUserPass
|
||||
builder.authToken = authToken
|
||||
builder.peerId = peerId
|
||||
builder.ipv4 = ipv4
|
||||
|
@ -549,7 +551,6 @@ extension OpenVPN.Configuration {
|
|||
// MARK: Encoding
|
||||
|
||||
extension OpenVPN.Configuration {
|
||||
|
||||
public func print() {
|
||||
guard let endpointProtocols = endpointProtocols else {
|
||||
fatalError("No sessionConfiguration.endpointProtocols set")
|
||||
|
@ -558,6 +559,7 @@ extension OpenVPN.Configuration {
|
|||
log.info("\tCipher: \(fallbackCipher)")
|
||||
log.info("\tDigest: \(fallbackDigest)")
|
||||
log.info("\tCompression framing: \(fallbackCompressionFraming)")
|
||||
log.info("\tUsername authentication: \(authUserPass ?? false)")
|
||||
if let compressionAlgorithm = compressionAlgorithm, compressionAlgorithm != .disabled {
|
||||
log.info("\tCompression algorithm: \(compressionAlgorithm)")
|
||||
} else {
|
||||
|
|
|
@ -78,6 +78,8 @@ extension OpenVPN {
|
|||
|
||||
static let remote = NSRegularExpression("^remote +[^ ]+( +\\d+)?( +(udp[46]?|tcp[46]?))?")
|
||||
|
||||
static let authUserPass = NSRegularExpression("^auth-user-pass")
|
||||
|
||||
static let eku = NSRegularExpression("^remote-cert-tls +server")
|
||||
|
||||
static let remoteRandom = NSRegularExpression("^remote-random")
|
||||
|
@ -178,7 +180,7 @@ extension OpenVPN {
|
|||
}
|
||||
|
||||
/**
|
||||
Parses an .ovpn file from an URL.
|
||||
Parses a configuration from a .ovpn file.
|
||||
|
||||
- Parameter url: The URL of the configuration file.
|
||||
- Parameter passphrase: The optional passphrase for encrypted data.
|
||||
|
@ -187,8 +189,39 @@ extension OpenVPN {
|
|||
- Throws: `ConfigurationError` if the configuration file is wrong or incomplete.
|
||||
*/
|
||||
public static func parsed(fromURL url: URL, passphrase: String? = nil, returnsStripped: Bool = false) throws -> Result {
|
||||
let lines = try String(contentsOf: url).trimmedLines()
|
||||
return try parsed(fromLines: lines, isClient: true, passphrase: passphrase, originalURL: url, returnsStripped: returnsStripped)
|
||||
let contents = try String(contentsOf: url)
|
||||
return try parsed(
|
||||
fromContents: contents,
|
||||
passphrase: passphrase,
|
||||
originalURL: url,
|
||||
returnsStripped: returnsStripped
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Parses a configuration from a string.
|
||||
|
||||
- Parameter contents: The contents of the configuration file.
|
||||
- Parameter passphrase: The optional passphrase for encrypted data.
|
||||
- Parameter originalURL: The optional original URL of the configuration file.
|
||||
- Parameter returnsStripped: When `true`, stores the stripped file into `Result.strippedLines`. Defaults to `false`.
|
||||
- Returns: The `Result` outcome of the parsing.
|
||||
- Throws: `ConfigurationError` if the configuration file is wrong or incomplete.
|
||||
*/
|
||||
public static func parsed(
|
||||
fromContents contents: String,
|
||||
passphrase: String? = nil,
|
||||
originalURL: URL? = nil,
|
||||
returnsStripped: Bool = false
|
||||
) throws -> Result {
|
||||
let lines = contents.trimmedLines()
|
||||
return try parsed(
|
||||
fromLines: lines,
|
||||
isClient: true,
|
||||
passphrase: passphrase,
|
||||
originalURL: originalURL,
|
||||
returnsStripped: returnsStripped
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,7 +235,13 @@ extension OpenVPN {
|
|||
- Returns: The `Result` outcome of the parsing.
|
||||
- Throws: `ConfigurationError` if the configuration file is wrong or incomplete.
|
||||
*/
|
||||
public static func parsed(fromLines lines: [String], isClient: Bool = false, passphrase: String? = nil, originalURL: URL? = nil, returnsStripped: Bool = false) throws -> Result {
|
||||
public static func parsed(
|
||||
fromLines lines: [String],
|
||||
isClient: Bool = false,
|
||||
passphrase: String? = nil,
|
||||
originalURL: URL? = nil,
|
||||
returnsStripped: Bool = false
|
||||
) throws -> Result {
|
||||
var optStrippedLines: [String]? = returnsStripped ? [] : nil
|
||||
var optWarning: ConfigurationError?
|
||||
var unsupportedError: ConfigurationError?
|
||||
|
@ -229,6 +268,7 @@ extension OpenVPN {
|
|||
var optDefaultProto: SocketType?
|
||||
var optDefaultPort: UInt16?
|
||||
var optRemotes: [(String, UInt16?, SocketType?)] = [] // address, port, socket
|
||||
var authUserPass = false
|
||||
var optChecksEKU: Bool?
|
||||
var optRandomizeEndpoint: Bool?
|
||||
var optMTU: Int?
|
||||
|
@ -537,6 +577,10 @@ extension OpenVPN {
|
|||
}
|
||||
optMTU = Int(str)
|
||||
}
|
||||
Regex.authUserPass.enumerateComponents(in: line) { _ in
|
||||
isHandled = true
|
||||
authUserPass = true
|
||||
}
|
||||
|
||||
// MARK: Server
|
||||
|
||||
|
@ -687,10 +731,11 @@ extension OpenVPN {
|
|||
sessionBuilder.compressionAlgorithm = optCompressionAlgorithm
|
||||
sessionBuilder.ca = optCA
|
||||
sessionBuilder.clientCertificate = optClientCertificate
|
||||
sessionBuilder.authUserPass = authUserPass
|
||||
|
||||
if let clientKey = optClientKey, clientKey.isEncrypted {
|
||||
// FIXME: remove dependency on TLSBox
|
||||
guard let passphrase = passphrase else {
|
||||
guard let passphrase = passphrase, !passphrase.isEmpty else {
|
||||
throw ConfigurationError.encryptionPassphrase
|
||||
}
|
||||
do {
|
||||
|
@ -746,6 +791,7 @@ extension OpenVPN {
|
|||
sessionBuilder.hostname = nil
|
||||
}
|
||||
|
||||
sessionBuilder.authUserPass = authUserPass
|
||||
sessionBuilder.checksEKU = optChecksEKU
|
||||
sessionBuilder.randomizeEndpoint = optRandomizeEndpoint
|
||||
sessionBuilder.mtu = optMTU
|
||||
|
|
Loading…
Reference in New Issue