in Sources/NIOSSH/SSHMessages.swift [655:722]
mutating func readUserAuthRequestMessage() throws -> SSHMessage.UserAuthRequestMessage? {
try self.rewindOnNilOrError { `self` in
guard
let username = self.readSSHStringAsString(),
let service = self.readSSHStringAsString(),
let methodRawValue = self.readSSHStringAsString()
else {
return nil
}
let method: SSHMessage.UserAuthRequestMessage.Method
switch methodRawValue {
case "none":
method = .none
case "password":
guard
self.readSSHBoolean() == false,
let password = self.readSSHStringAsString()
else {
return nil
}
method = .password(password)
case "publickey":
guard
let expectSignature = self.readSSHBoolean(),
let algorithmName = self.readSSHString(),
var keyBytes = self.readSSHString()
else {
return nil
}
if NIOSSHPublicKey.knownAlgorithms.contains(where: { $0.elementsEqual(algorithmName.readableBytesView) }) {
// This is a known algorithm, we can load the key.
guard let publicKey = try keyBytes.readSSHHostKey() else {
return nil
}
guard algorithmName.readableBytesView.elementsEqual(publicKey.keyPrefix) else {
throw NIOSSHError.invalidSSHMessage(reason: "algorithm and key mismatch in user auth request")
}
if expectSignature {
guard var signatureBytes = self.readSSHString(), let signature = try signatureBytes.readSSHSignature() else {
return nil
}
method = .publicKey(.known(key: publicKey, signature: signature))
} else {
method = .publicKey(.known(key: publicKey, signature: nil))
}
} else {
// This is not an algorithm we know. Consume the signature if we're expecting it.
if expectSignature {
guard let _ = self.readSSHString() else {
return nil
}
}
method = .publicKey(.unknown)
}
default:
return nil
}
return SSHMessage.UserAuthRequestMessage(username: username, service: service, method: method)
}
}