Merge pull request #56 from keeshux/override-dns-servers

Override DNS servers
This commit is contained in:
Davide De Rosa 2019-02-23 11:35:03 +01:00 committed by GitHub
commit 2373dc88f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 6 deletions

View File

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
### Added
- Override DNS servers client side. [#56](https://github.com/keeshux/tunnelkit/pull/56)
### Fixed ### Fixed
- Compiling errors in demo target. - Compiling errors in demo target.

View File

@ -64,7 +64,8 @@ extension TunnelKitProvider {
tlsWrap: nil, tlsWrap: nil,
keepAliveInterval: nil, keepAliveInterval: nil,
renegotiatesAfter: nil, renegotiatesAfter: nil,
usesPIAPatches: nil usesPIAPatches: nil,
dnsServers: nil
), ),
shouldDebug: false, shouldDebug: false,
debugLogKey: nil, debugLogKey: nil,

View File

@ -499,7 +499,7 @@ extension TunnelKitProvider: SessionProxyDelegate {
ipv6Settings?.excludedRoutes = [] ipv6Settings?.excludedRoutes = []
} }
let dnsSettings = NEDNSSettings(servers: reply.dnsServers) let dnsSettings = NEDNSSettings(servers: cfg.sessionConfiguration.dnsServers ?? reply.dnsServers)
let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: remoteAddress) let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: remoteAddress)
newSettings.ipv4Settings = ipv4Settings newSettings.ipv4Settings = ipv4Settings

View File

@ -91,6 +91,8 @@ public class ConfigurationParser {
static let blockEnd = NSRegularExpression("^<\\/[\\w\\-]+>") static let blockEnd = NSRegularExpression("^<\\/[\\w\\-]+>")
static let dnsRegexp = NSRegularExpression("dhcp-option DNS6? [\\d\\.a-fA-F:]+")
// unsupported // unsupported
// static let fragment = NSRegularExpression("^fragment +\\d+") // static let fragment = NSRegularExpression("^fragment +\\d+")
@ -143,6 +145,7 @@ public class ConfigurationParser {
var tlsStrategy: SessionProxy.TLSWrap.Strategy? var tlsStrategy: SessionProxy.TLSWrap.Strategy?
var tlsKeyLines: [Substring]? var tlsKeyLines: [Substring]?
var tlsWrap: SessionProxy.TLSWrap? var tlsWrap: SessionProxy.TLSWrap?
var dnsServers: [String]?
var currentBlockName: String? var currentBlockName: String?
var currentBlock: [String] = [] var currentBlock: [String] = []
@ -316,6 +319,16 @@ public class ConfigurationParser {
} }
renegotiateAfterSeconds = TimeInterval(arg) renegotiateAfterSeconds = TimeInterval(arg)
} }
Regex.dnsRegexp.enumerateArguments(in: line) {
isHandled = true
guard $0.count == 2 else {
return
}
if dnsServers == nil {
dnsServers = []
}
dnsServers?.append($0[1])
}
Regex.fragment.enumerateArguments(in: line) { (_) in Regex.fragment.enumerateArguments(in: line) { (_) in
unsupportedError = ParsingError.unsupportedConfiguration(option: "fragment") unsupportedError = ParsingError.unsupportedConfiguration(option: "fragment")
} }
@ -388,6 +401,7 @@ public class ConfigurationParser {
sessionBuilder.clientKey = clientKey sessionBuilder.clientKey = clientKey
sessionBuilder.keepAliveInterval = keepAliveSeconds sessionBuilder.keepAliveInterval = keepAliveSeconds
sessionBuilder.renegotiatesAfter = renegotiateAfterSeconds sessionBuilder.renegotiatesAfter = renegotiateAfterSeconds
sessionBuilder.dnsServers = dnsServers
return ParsingResult( return ParsingResult(
url: originalURL, url: originalURL,

View File

@ -165,6 +165,9 @@ extension SessionProxy {
/// Server is patched for the PIA VPN provider. /// Server is patched for the PIA VPN provider.
public var usesPIAPatches: Bool? public var usesPIAPatches: Bool?
/// Optionally override the server DNS entries.
public var dnsServers: [String]?
/// :nodoc: /// :nodoc:
public init(ca: CryptoContainer) { public init(ca: CryptoContainer) {
cipher = .aes128cbc cipher = .aes128cbc
@ -177,6 +180,7 @@ extension SessionProxy {
keepAliveInterval = nil keepAliveInterval = nil
renegotiatesAfter = nil renegotiatesAfter = nil
usesPIAPatches = false usesPIAPatches = false
dnsServers = nil
} }
/** /**
@ -195,7 +199,8 @@ extension SessionProxy {
tlsWrap: tlsWrap, tlsWrap: tlsWrap,
keepAliveInterval: keepAliveInterval, keepAliveInterval: keepAliveInterval,
renegotiatesAfter: renegotiatesAfter, renegotiatesAfter: renegotiatesAfter,
usesPIAPatches: usesPIAPatches usesPIAPatches: usesPIAPatches,
dnsServers: dnsServers
) )
} }
} }
@ -233,6 +238,9 @@ extension SessionProxy {
/// - Seealso: `SessionProxy.ConfigurationBuilder.usesPIAPatches` /// - Seealso: `SessionProxy.ConfigurationBuilder.usesPIAPatches`
public let usesPIAPatches: Bool? public let usesPIAPatches: Bool?
/// - Seealso: `SessionProxy.ConfigurationBuilder.dnsServers`
public let dnsServers: [String]?
/** /**
Returns a `SessionProxy.ConfigurationBuilder` to use this configuration as a starting point for a new one. Returns a `SessionProxy.ConfigurationBuilder` to use this configuration as a starting point for a new one.
@ -249,6 +257,7 @@ extension SessionProxy {
builder.keepAliveInterval = keepAliveInterval builder.keepAliveInterval = keepAliveInterval
builder.renegotiatesAfter = renegotiatesAfter builder.renegotiatesAfter = renegotiatesAfter
builder.usesPIAPatches = usesPIAPatches builder.usesPIAPatches = usesPIAPatches
builder.dnsServers = dnsServers
return builder return builder
} }
@ -265,7 +274,8 @@ extension SessionProxy {
(lhs.compressionFraming == rhs.compressionFraming) && (lhs.compressionFraming == rhs.compressionFraming) &&
(lhs.keepAliveInterval == rhs.keepAliveInterval) && (lhs.keepAliveInterval == rhs.keepAliveInterval) &&
(lhs.renegotiatesAfter == rhs.renegotiatesAfter) && (lhs.renegotiatesAfter == rhs.renegotiatesAfter) &&
(lhs.usesPIAPatches == rhs.usesPIAPatches) (lhs.usesPIAPatches == rhs.usesPIAPatches) &&
(lhs.dnsServers == rhs.dnsServers)
} }
} }
} }

View File

@ -27,6 +27,8 @@ import XCTest
import TunnelKit import TunnelKit
class ConfigurationParserTests: XCTestCase { class ConfigurationParserTests: XCTestCase {
let base: [String] = ["<ca>", "</ca>", "remote 1.2.3.4"]
override func setUp() { override func setUp() {
super.setUp() super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class. // Put setup code here. This method is called before the invocation of each test method in the class.
@ -55,8 +57,6 @@ class ConfigurationParserTests: XCTestCase {
} }
func testCompression() throws { func testCompression() throws {
let base: [String] = ["<ca>", "</ca>", "remote 1.2.3.4"]
XCTAssertNotNil(try ConfigurationParser.parsed(fromLines: base + ["comp-lzo"]).warning) XCTAssertNotNil(try ConfigurationParser.parsed(fromLines: base + ["comp-lzo"]).warning)
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: base + ["comp-lzo no"])) XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: base + ["comp-lzo no"]))
XCTAssertThrowsError(try ConfigurationParser.parsed(fromLines: base + ["comp-lzo yes"])) XCTAssertThrowsError(try ConfigurationParser.parsed(fromLines: base + ["comp-lzo yes"]))
@ -65,6 +65,14 @@ class ConfigurationParserTests: XCTestCase {
XCTAssertThrowsError(try ConfigurationParser.parsed(fromLines: base + ["compress lzo"])) XCTAssertThrowsError(try ConfigurationParser.parsed(fromLines: base + ["compress lzo"]))
} }
func testDHCPOption() throws {
let lines = base + ["dhcp-option DNS 8.8.8.8", "dhcp-option DNS6 ffff::1"]
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: lines))
let parsed = try! ConfigurationParser.parsed(fromLines: lines)
XCTAssertEqual(parsed.configuration.dnsServers, ["8.8.8.8", "ffff::1"])
}
private func url(withName name: String) -> URL { private func url(withName name: String) -> URL {
return Bundle(for: ConfigurationParserTests.self).url(forResource: name, withExtension: "ovpn")! return Bundle(for: ConfigurationParserTests.self).url(forResource: name, withExtension: "ovpn")!
} }