Redeem website login keycards over SASL
All checks were successful
CI / check (push) Successful in 3m52s
All checks were successful
CI / check (push) Successful in 3m52s
A member already authenticated on tchatou.fr connects with a single-use kc_… keycard instead of their password (the m_apiauth module that used to validate it was retired in the Anope->echo cutover, so these logins had started failing as "wrong password"). The SASL PLAIN handler now recognises a kc_-prefixed credential and emits NetAction::DeferKeycard; the link layer redeems it off the engine lock — a localhost round-trip to Django's login-token endpoint via keycard::redeem — and completes the login exactly like a password auth. Config: [keycard] url + api_key; absent, kc_ credentials are simply not honoured.
This commit is contained in:
parent
bad17a184e
commit
f2fd80694d
9 changed files with 359 additions and 4 deletions
|
|
@ -59,13 +59,30 @@ impl Engine {
|
|||
// Decode, then defer the verify off the lock (the login
|
||||
// finish lands in Engine::complete_authenticate).
|
||||
match decode_plain(&response) {
|
||||
// A website login keycard (`kc_…`), not a password: it can't be
|
||||
// SCRAM-verified, so redeem it off-lock (link.rs) against Django.
|
||||
Some((authcid, passwd)) if passwd.starts_with("kc_") => {
|
||||
let account = match self.db.resolve_account(&authcid) {
|
||||
Some(a) => a.to_string(),
|
||||
None => authcid,
|
||||
};
|
||||
vec![NetAction::DeferKeycard {
|
||||
token: passwd,
|
||||
account: account.clone(),
|
||||
then: AuthThen::Sasl { agent: agent.clone(), client: client.clone(), account },
|
||||
}]
|
||||
}
|
||||
Some((authcid, passwd)) => match self.scram_verifier(&authcid) {
|
||||
Some((account, verifier)) => vec![NetAction::DeferAuthenticate {
|
||||
verifier,
|
||||
password: passwd,
|
||||
then: AuthThen::Sasl { agent: agent.clone(), client: client.clone(), account },
|
||||
}],
|
||||
None => mk("D", vec!["F".to_string()]),
|
||||
None => {
|
||||
let mut out = mk("D", vec!["F".to_string()]);
|
||||
out.extend(self.feed("AUTH", format!("\x0304✗\x03 {} — SASL PLAIN failed for \x02{authcid}\x02 (unknown account)", self.who(&client))));
|
||||
out
|
||||
}
|
||||
},
|
||||
None => mk("D", vec!["F".to_string()]),
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue