#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,37 @@
|
||||
import Foundation
|
||||
import Martin
|
||||
|
||||
/// Observes the raw SASL `<failure/>` stanza before `SaslModule` collapses
|
||||
/// it into its `SaslError` enum, so the UI can show the real RFC 6120
|
||||
/// condition (`account-disabled`, `credentials-expired`, …) and the
|
||||
/// optional server `<text/>` instead of a catch-all "authentication
|
||||
/// failure". Registered before `SaslModule` in the module list.
|
||||
final class LumaSaslFailureModule: XmppModuleBase, XmppModule {
|
||||
static let ID = "lumaSaslFailure"
|
||||
static let saslXMLNS = "urn:ietf:params:xml:ns:xmpp-sasl"
|
||||
|
||||
struct Failure: Equatable, Sendable {
|
||||
let condition: String?
|
||||
let text: String?
|
||||
}
|
||||
|
||||
let criteria = Criteria.name("failure", xmlns: LumaSaslFailureModule.saslXMLNS)
|
||||
let features: [String] = []
|
||||
|
||||
private let lock = NSLock()
|
||||
private var stored: Failure?
|
||||
|
||||
var lastFailure: Failure? {
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
return stored
|
||||
}
|
||||
|
||||
func process(stanza: Stanza) throws {
|
||||
let condition = stanza.findChild()?.name
|
||||
let text = stanza.findChild(name: "text")?.value
|
||||
lock.lock()
|
||||
stored = Failure(condition: condition, text: text)
|
||||
lock.unlock()
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user