Handle dhcp-option PROXY_BYPASS

This commit is contained in:
Davide De Rosa 2019-04-13 19:03:27 +02:00
parent b118030d43
commit 0a956f5b9f
5 changed files with 51 additions and 6 deletions

View File

@ -175,6 +175,7 @@ extension TunnelKitProvider {
}
sessionConfigurationBuilder.httpsProxy = proxy
}
sessionConfigurationBuilder.proxyBypassDomains = providerConfiguration[S.proxyBypassDomains] as? [String]
sessionConfiguration = sessionConfigurationBuilder.build()
shouldDebug = providerConfiguration[S.debug] as? Bool ?? ConfigurationBuilder.defaults.shouldDebug
@ -256,6 +257,8 @@ extension TunnelKitProvider {
static let httpsProxy = "HTTPSProxy"
static let proxyBypassDomains = "ProxyBypassDomains"
// MARK: Debugging
static let debug = "Debug"
@ -465,6 +468,9 @@ extension TunnelKitProvider {
if let httpsProxy = sessionConfiguration.httpsProxy {
dict[S.httpsProxy] = httpsProxy.rawValue
}
if let proxyBypassDomains = sessionConfiguration.proxyBypassDomains {
dict[S.proxyBypassDomains] = proxyBypassDomains
}
//
if let resolvedAddresses = resolvedAddresses {
dict[S.resolvedAddresses] = resolvedAddresses
@ -565,6 +571,9 @@ extension TunnelKitProvider {
if let httpsProxy = sessionConfiguration.httpsProxy {
log.info("\tHTTPS proxy: \(httpsProxy.maskedDescription)")
}
if let proxyBypassDomains = sessionConfiguration.proxyBypassDomains {
log.info("\tProxy bypass domains: \(proxyBypassDomains.maskedDescription)")
}
log.info("\tMTU: \(mtu)")
log.info("\tDebug: \(shouldDebug)")
log.info("\tMasks private data: \(masksPrivateData ?? true)")

View File

@ -478,7 +478,20 @@ extension TunnelKitProvider: SessionProxyDelegate {
log.info("\tDNS: not configured)")
}
log.info("\tDomain: \(reply.options.searchDomain?.maskedDescription ?? "not configured")")
if reply.options.httpProxy != nil || reply.options.httpsProxy != nil {
log.info("\tProxy:")
if let proxy = reply.options.httpProxy {
log.info("\t\tHTTP: \(proxy.maskedDescription)")
}
if let proxy = reply.options.httpsProxy {
log.info("\t\tHTTPS: \(proxy.maskedDescription)")
}
if let bypass = reply.options.proxyBypassDomains {
log.info("\t\tBypass domains: \(bypass.maskedDescription)")
}
}
bringNetworkUp(remoteAddress: remoteAddress, reply: reply) { (error) in
if let error = error {
log.error("Failed to configure tunnel: \(error)")
@ -568,6 +581,8 @@ extension TunnelKitProvider: SessionProxyDelegate {
proxySettings?.httpServer = httpProxy.neProxy()
proxySettings?.httpEnabled = true
}
// only set if there is a proxy (proxySettings set to non-nil above)
proxySettings?.exceptionList = cfg.sessionConfiguration.proxyBypassDomains ?? reply.options.proxyBypassDomains
let newSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: remoteAddress)
newSettings.ipv4Settings = ipv4Settings

View File

@ -92,7 +92,9 @@ public class ConfigurationParser {
static let domain = NSRegularExpression("^dhcp-option +DOMAIN +[^ ]+")
static let proxy = NSRegularExpression("^dhcp-option +PROXY_(HTTPS?|BYPASS) +[^ ]+ +\\d+")
static let proxy = NSRegularExpression("^dhcp-option +PROXY_(HTTPS?) +[^ ]+ +\\d+")
static let proxyBypass = NSRegularExpression("^dhcp-option +PROXY_BYPASS +.+")
// MARK: Unsupported
@ -197,6 +199,7 @@ public class ConfigurationParser {
var optSearchDomain: String?
var optHTTPProxy: Proxy?
var optHTTPSProxy: Proxy?
var optProxyBypass: [String]?
log.verbose("Configuration file:")
for line in lines {
@ -480,7 +483,7 @@ public class ConfigurationParser {
switch $0[0] {
case "PROXY_HTTPS":
optHTTPSProxy = Proxy($0[1], port)
case "PROXY_HTTP":
optHTTPProxy = Proxy($0[1], port)
@ -488,7 +491,14 @@ public class ConfigurationParser {
break
}
}
Regex.proxyBypass.enumerateArguments(in: line) {
guard !$0.isEmpty else {
return
}
optProxyBypass = $0
optProxyBypass?.removeFirst()
}
//
if let error = unsupportedError {
@ -652,6 +662,7 @@ public class ConfigurationParser {
sessionBuilder.searchDomain = optSearchDomain
sessionBuilder.httpProxy = optHTTPProxy
sessionBuilder.httpsProxy = optHTTPSProxy
sessionBuilder.proxyBypassDomains = optProxyBypass
//

View File

@ -221,6 +221,9 @@ extension SessionProxy {
/// The HTTPS proxy.
public var httpsProxy: Proxy?
/// The list of domains not passing through the proxy.
public var proxyBypassDomains: [String]?
/// :nodoc:
public init() {
}
@ -254,7 +257,8 @@ extension SessionProxy {
dnsServers: dnsServers,
searchDomain: searchDomain,
httpProxy: httpProxy,
httpsProxy: httpsProxy
httpsProxy: httpsProxy,
proxyBypassDomains: proxyBypassDomains
)
}
@ -348,6 +352,9 @@ extension SessionProxy {
/// - Seealso: `SessionProxy.ConfigurationBuilder.httpsProxy`
public var httpsProxy: Proxy?
/// - Seealso: `SessionProxy.ConfigurationBuilder.proxyBypassDomains`
public var proxyBypassDomains: [String]?
// MARK: Shortcuts
/// :nodoc:
@ -400,6 +407,7 @@ extension SessionProxy.Configuration {
builder.searchDomain = searchDomain
builder.httpProxy = httpProxy
builder.httpsProxy = httpsProxy
builder.proxyBypassDomains = proxyBypassDomains
return builder
}
}

View File

@ -58,7 +58,8 @@ class ConfigurationParserTests: XCTestCase {
"dhcp-option DNS6 ffff::1",
"dhcp-option DOMAIN example.com",
"dhcp-option PROXY_HTTP 1.2.3.4 8081",
"dhcp-option PROXY_HTTPS 7.8.9.10 8082"
"dhcp-option PROXY_HTTPS 7.8.9.10 8082",
"dhcp-option PROXY_BYPASS foo.com bar.org net.chat"
]
XCTAssertNoThrow(try ConfigurationParser.parsed(fromLines: lines))
@ -69,6 +70,7 @@ class ConfigurationParserTests: XCTestCase {
XCTAssertEqual(parsed.httpProxy?.port, 8081)
XCTAssertEqual(parsed.httpsProxy?.address, "7.8.9.10")
XCTAssertEqual(parsed.httpsProxy?.port, 8082)
XCTAssertEqual(parsed.proxyBypassDomains, ["foo.com", "bar.org", "net.chat"])
}
func testConnectionBlock() throws {