Retry auth once without local options
Hack around picky server implementations. Fixes #95
This commit is contained in:
parent
14b7f08fb5
commit
037f08ed62
|
@ -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/),
|
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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Authentication failure due to local options. [#95](https://github.com/keeshux/tunnelkit/issues/95)
|
||||||
|
|
||||||
## 1.7.0 (2019-04-28)
|
## 1.7.0 (2019-04-28)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -66,6 +66,8 @@ extension SessionProxy {
|
||||||
|
|
||||||
let password: ZeroingData?
|
let password: ZeroingData?
|
||||||
|
|
||||||
|
var withLocalOptions: Bool
|
||||||
|
|
||||||
init(_ username: String?, _ password: String?) throws {
|
init(_ username: String?, _ password: String?) throws {
|
||||||
preMaster = try SecureRandom.safeData(length: CoreConfiguration.preMasterLength)
|
preMaster = try SecureRandom.safeData(length: CoreConfiguration.preMasterLength)
|
||||||
random1 = try SecureRandom.safeData(length: CoreConfiguration.randomLength)
|
random1 = try SecureRandom.safeData(length: CoreConfiguration.randomLength)
|
||||||
|
@ -80,6 +82,8 @@ extension SessionProxy {
|
||||||
self.password = nil
|
self.password = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withLocalOptions = true
|
||||||
|
|
||||||
controlBuffer = Z()
|
controlBuffer = Z()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +99,12 @@ extension SessionProxy {
|
||||||
raw.append(random2)
|
raw.append(random2)
|
||||||
|
|
||||||
// options string
|
// options string
|
||||||
|
let optsString: String
|
||||||
|
if withLocalOptions {
|
||||||
var opts = [
|
var opts = [
|
||||||
"V4",
|
"V4",
|
||||||
"dev-type tun"
|
"dev-type tun"
|
||||||
]
|
]
|
||||||
//////
|
|
||||||
if let comp = options.compressionFraming {
|
if let comp = options.compressionFraming {
|
||||||
switch comp {
|
switch comp {
|
||||||
case .compLZO:
|
case .compLZO:
|
||||||
|
@ -123,7 +128,10 @@ extension SessionProxy {
|
||||||
}
|
}
|
||||||
opts.append("key-method 2")
|
opts.append("key-method 2")
|
||||||
opts.append("tls-client")
|
opts.append("tls-client")
|
||||||
let optsString = opts.joined(separator: ",")
|
optsString = opts.joined(separator: ",")
|
||||||
|
} else {
|
||||||
|
optsString = "V0 UNDEF"
|
||||||
|
}
|
||||||
log.debug("TLS.auth: Local options: \(optsString)")
|
log.debug("TLS.auth: Local options: \(optsString)")
|
||||||
raw.appendSized(Z(optsString, nullTerminated: true))
|
raw.appendSized(Z(optsString, nullTerminated: true))
|
||||||
|
|
||||||
|
|
|
@ -106,6 +106,8 @@ public class SessionProxy {
|
||||||
|
|
||||||
private var tlsObserver: NSObjectProtocol?
|
private var tlsObserver: NSObjectProtocol?
|
||||||
|
|
||||||
|
private var withLocalOptions: Bool
|
||||||
|
|
||||||
private var keys: [UInt8: SessionKey]
|
private var keys: [UInt8: SessionKey]
|
||||||
|
|
||||||
private var oldKeys: [SessionKey]
|
private var oldKeys: [SessionKey]
|
||||||
|
@ -190,6 +192,7 @@ public class SessionProxy {
|
||||||
self.configuration = configuration
|
self.configuration = configuration
|
||||||
self.cachesURL = cachesURL
|
self.cachesURL = cachesURL
|
||||||
|
|
||||||
|
withLocalOptions = true
|
||||||
keys = [:]
|
keys = [:]
|
||||||
oldKeys = []
|
oldKeys = []
|
||||||
negotiationKeyIdx = 0
|
negotiationKeyIdx = 0
|
||||||
|
@ -676,6 +679,7 @@ public class SessionProxy {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
authenticator = try Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password)
|
authenticator = try Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password)
|
||||||
|
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 {
|
||||||
deferStop(.shutdown, e)
|
deferStop(.shutdown, e)
|
||||||
|
@ -908,6 +912,15 @@ public class SessionProxy {
|
||||||
// Ruby: handle_ctrl_msg
|
// Ruby: handle_ctrl_msg
|
||||||
private func handleControlMessage(_ message: String) {
|
private func handleControlMessage(_ message: String) {
|
||||||
guard !message.hasPrefix("AUTH_FAILED") else {
|
guard !message.hasPrefix("AUTH_FAILED") else {
|
||||||
|
|
||||||
|
// XXX: retry without client options
|
||||||
|
if authenticator?.withLocalOptions ?? false {
|
||||||
|
log.warning("Authentication failure, retrying without local options")
|
||||||
|
withLocalOptions = false
|
||||||
|
deferStop(.reconnect, SessionError.badCredentials)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
deferStop(.shutdown, SessionError.badCredentials)
|
deferStop(.shutdown, SessionError.badCredentials)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue