Retry auth once without local options

Hack around picky server implementations.

Fixes #95
This commit is contained in:
Davide De Rosa 2019-05-01 10:37:39 +02:00
parent 14b7f08fb5
commit 037f08ed62
3 changed files with 54 additions and 27 deletions

View File

@ -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
### Fixed
- Authentication failure due to local options. [#95](https://github.com/keeshux/tunnelkit/issues/95)
## 1.7.0 (2019-04-28)
### Changed

View File

@ -66,6 +66,8 @@ extension SessionProxy {
let password: ZeroingData?
var withLocalOptions: Bool
init(_ username: String?, _ password: String?) throws {
preMaster = try SecureRandom.safeData(length: CoreConfiguration.preMasterLength)
random1 = try SecureRandom.safeData(length: CoreConfiguration.randomLength)
@ -80,6 +82,8 @@ extension SessionProxy {
self.password = nil
}
withLocalOptions = true
controlBuffer = Z()
}
@ -95,35 +99,39 @@ extension SessionProxy {
raw.append(random2)
// options string
var opts = [
"V4",
"dev-type tun"
]
//////
if let comp = options.compressionFraming {
switch comp {
case .compLZO:
opts.append("comp-lzo")
case .compress:
opts.append("compress")
default:
break
let optsString: String
if withLocalOptions {
var opts = [
"V4",
"dev-type tun"
]
if let comp = options.compressionFraming {
switch comp {
case .compLZO:
opts.append("comp-lzo")
case .compress:
opts.append("compress")
default:
break
}
}
if let direction = options.tlsWrap?.key.direction?.rawValue {
opts.append("keydir \(direction)")
}
opts.append("cipher \(options.cipher?.rawValue ?? "BF-CBC")")
opts.append("auth \(options.fallbackDigest.rawValue)")
opts.append("keysize \(options.fallbackCipher.keySize)")
if let strategy = options.tlsWrap?.strategy {
opts.append("tls-\(strategy)")
}
opts.append("key-method 2")
opts.append("tls-client")
optsString = opts.joined(separator: ",")
} else {
optsString = "V0 UNDEF"
}
if let direction = options.tlsWrap?.key.direction?.rawValue {
opts.append("keydir \(direction)")
}
opts.append("cipher \(options.cipher?.rawValue ?? "BF-CBC")")
opts.append("auth \(options.fallbackDigest.rawValue)")
opts.append("keysize \(options.fallbackCipher.keySize)")
if let strategy = options.tlsWrap?.strategy {
opts.append("tls-\(strategy)")
}
opts.append("key-method 2")
opts.append("tls-client")
let optsString = opts.joined(separator: ",")
log.debug("TLS.auth: Local options: \(optsString)")
raw.appendSized(Z(optsString, nullTerminated: true))

View File

@ -105,6 +105,8 @@ public class SessionProxy {
private let queue: DispatchQueue
private var tlsObserver: NSObjectProtocol?
private var withLocalOptions: Bool
private var keys: [UInt8: SessionKey]
@ -190,6 +192,7 @@ public class SessionProxy {
self.configuration = configuration
self.cachesURL = cachesURL
withLocalOptions = true
keys = [:]
oldKeys = []
negotiationKeyIdx = 0
@ -676,6 +679,7 @@ public class SessionProxy {
do {
authenticator = try Authenticator(credentials?.username, pushReply?.options.authToken ?? credentials?.password)
authenticator?.withLocalOptions = withLocalOptions
try authenticator?.putAuth(into: negotiationKey.tls, options: configuration)
} catch let e {
deferStop(.shutdown, e)
@ -908,6 +912,15 @@ public class SessionProxy {
// Ruby: handle_ctrl_msg
private func handleControlMessage(_ message: String) {
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)
return
}