#11 fix SASL login failures with non-ASCII passwords
- Normalize SCRAM passwords with RFC 4013 SASLprep before the challenge response, so they match SASLprep-compliant servers (Martin hashes raw UTF-8) and PLAIN still sends the password untouched. - Capture the raw <failure/> condition with LumaSaslFailureModule and map SASL errors to actionable Russian messages instead of the cryptic OS-localized "Martin.SaslError, error 5". - Cover SASLprep and failure message mapping with unit tests and new verify.sh invariants.
This commit is contained in:
1 parent
2884810ec4
commit
fc07855036
13 files changed
+410
-28
No files matched your search
@@ -0,0 +1,47 @@
|
||||
import Foundation
|
||||
import Martin
|
||||
|
||||
/// Turns a SASL authentication failure into an actionable Russian message.
|
||||
/// The raw `<failure/>` condition (captured by `LumaSaslFailureModule`)
|
||||
/// wins over Martin's `SaslError`, because Martin maps every unknown RFC
|
||||
/// 6120 condition (e.g. `account-disabled`) to `not_authorized`.
|
||||
enum SaslFailureMessage {
|
||||
static func describe(error: Error, condition: String?, serverText: String?) -> String {
|
||||
if let serverText, !serverText.isEmpty {
|
||||
return "Сервер отклонил вход: \(serverText)"
|
||||
}
|
||||
switch condition {
|
||||
case "account-disabled":
|
||||
return "Аккаунт отключён на сервере. Обратитесь к администратору сервера."
|
||||
case "credentials-expired":
|
||||
return "Срок действия пароля истёк. Обновите пароль на сервере."
|
||||
case "encryption-required":
|
||||
return "Сервер требует шифрование канала для входа."
|
||||
case "malformed-request":
|
||||
return "Сервер не смог обработать запрос входа. Попробуйте ещё раз."
|
||||
case "restricted-connection":
|
||||
return "Сервер ограничил подключения с этого адреса."
|
||||
default:
|
||||
break
|
||||
}
|
||||
if let saslError = error as? SaslError {
|
||||
switch saslError {
|
||||
case .not_authorized:
|
||||
return "Сервер отклонил имя пользователя или пароль. Проверьте JID и пароль."
|
||||
case .temporary_auth_failure:
|
||||
return "Сервер временно не может проверить учётные данные. Попробуйте через минуту."
|
||||
case .server_not_trusted:
|
||||
return "Сервер не прошёл проверку подписи SCRAM."
|
||||
case .incorrect_encoding:
|
||||
return "Сервер не принял кодировку учётных данных."
|
||||
case .invalid_authzid:
|
||||
return "Сервер отклонил идентификатор авторизации."
|
||||
case .invalid_mechanism, .mechanism_too_weak:
|
||||
return "Сервер не поддерживает доступные способы входа."
|
||||
case .aborted:
|
||||
return "Вход прерван."
|
||||
}
|
||||
}
|
||||
return error.localizedDescription
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user