Add the SASL PLAIN verification exchange

fedserv now handles the SASL exchange an ircd relays over ENCAP (modes H/S/C/D):
on PLAIN it answers the empty challenge, decodes the client payload, and verifies
the credentials against the account store, replying D S or D F. Wiring the
account login on success and advertising the mechanism list to the ircd are the
remaining integration steps.
This commit is contained in:
Jean Chevronnet 2026-07-11 21:18:42 +00:00
parent 18a28ed49b
commit 63028d99e5
No known key found for this signature in database
5 changed files with 96 additions and 1 deletions

View file

@ -98,6 +98,27 @@ impl Protocol for InspIrcd {
vec![]
}
}
// ENCAP <target> <subcmd> … — we only care about relayed SASL:
// ENCAP <target> SASL <client> <agent> <mode> [data…]
"ENCAP" => {
let _target = tokens.next();
match tokens.next().map(|s| s.to_ascii_uppercase()).as_deref() {
Some("SASL") => {
let p: Vec<&str> = tokens.collect();
if p.len() >= 3 {
vec![NetEvent::Sasl {
client: p[0].to_string(),
agent: p[1].to_string(),
mode: p[2].to_string(),
data: p[3..].iter().map(|s| s.to_string()).collect(),
}]
} else {
vec![]
}
}
_ => vec![NetEvent::Unknown { line: line.to_string() }],
}
}
_ => vec![NetEvent::Unknown { line: line.to_string() }],
}
}
@ -129,6 +150,15 @@ impl Protocol for InspIrcd {
reqid, kind, account, status, code, message
))]
}
// ENCAP * SASL <agent> <client> <mode> [data…]
NetAction::Sasl { agent, client, mode, data } => {
let mut line = format!("ENCAP * SASL {} {} {}", agent, client, mode);
for d in data {
line.push(' ');
line.push_str(d);
}
vec![self.from_us(line)]
}
NetAction::Raw(s) => vec![s.clone()],
}
}