Add SASL EXTERNAL
This commit is contained in:
parent
831f538a98
commit
a382ac8ad3
3 changed files with 264 additions and 5 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use crate::engine::db::Db;
|
||||
use crate::engine::db::{CertError, Db};
|
||||
use crate::engine::service::{Sender, Service, ServiceCtx};
|
||||
use crate::proto::RegReply;
|
||||
|
||||
|
|
@ -48,11 +48,75 @@ impl Service for NickServ {
|
|||
None => ctx.notice(me, from.uid, "Invalid password."),
|
||||
}
|
||||
}
|
||||
Some("HELP") => {
|
||||
ctx.notice(me, from.uid, "Commands: REGISTER <password> [email], IDENTIFY <password>.")
|
||||
}
|
||||
Some("CERT") => self.cert(from, &args, ctx, db),
|
||||
Some("HELP") => ctx.notice(
|
||||
me,
|
||||
from.uid,
|
||||
"Commands: REGISTER <password> [email], IDENTIFY <password>, CERT ADD|DEL|LIST <password> [fingerprint].",
|
||||
),
|
||||
Some(other) => ctx.notice(me, from.uid, format!("Unknown command: {}. Try HELP.", other)),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NickServ {
|
||||
// CERT ADD|DEL|LIST <password> [fingerprint]: manage the TLS certificate
|
||||
// fingerprints that may log in to your account via SASL EXTERNAL. Gated by
|
||||
// the account password, so it needs no separate identified-session state.
|
||||
fn cert(&self, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db: &mut Db) {
|
||||
let me = self.uid.as_str();
|
||||
// All subcommands authenticate the sender's nick's account by password.
|
||||
let auth = |db: &Db, password: &str| db.authenticate(from.nick, password).map(str::to_string);
|
||||
match args.get(1).map(|s| s.to_ascii_uppercase()).as_deref() {
|
||||
Some("LIST") => {
|
||||
let Some(password) = args.get(2) else {
|
||||
ctx.notice(me, from.uid, "Syntax: CERT LIST <password>");
|
||||
return;
|
||||
};
|
||||
let Some(account) = auth(db, password) else {
|
||||
ctx.notice(me, from.uid, "Invalid password.");
|
||||
return;
|
||||
};
|
||||
let fps = db.certfps(&account);
|
||||
if fps.is_empty() {
|
||||
ctx.notice(me, from.uid, "No certificate fingerprints are registered to your account.");
|
||||
} else {
|
||||
ctx.notice(me, from.uid, format!("Registered fingerprints: {}", fps.join(", ")));
|
||||
}
|
||||
}
|
||||
Some("ADD") => {
|
||||
let (Some(password), Some(fp)) = (args.get(2), args.get(3)) else {
|
||||
ctx.notice(me, from.uid, "Syntax: CERT ADD <password> <fingerprint>");
|
||||
return;
|
||||
};
|
||||
let Some(account) = auth(db, password) else {
|
||||
ctx.notice(me, from.uid, "Invalid password.");
|
||||
return;
|
||||
};
|
||||
match db.certfp_add(&account, fp) {
|
||||
Ok(()) => ctx.notice(me, from.uid, format!("Added fingerprint \x02{fp}\x02. You can now log in with SASL EXTERNAL.")),
|
||||
Err(CertError::InUse) => ctx.notice(me, from.uid, "That fingerprint is already registered."),
|
||||
Err(CertError::Invalid) => ctx.notice(me, from.uid, "That does not look like a certificate fingerprint."),
|
||||
Err(CertError::NoAccount | CertError::Internal) => ctx.notice(me, from.uid, "Could not add the fingerprint, please try again later."),
|
||||
}
|
||||
}
|
||||
Some("DEL") | Some("REMOVE") => {
|
||||
let (Some(password), Some(fp)) = (args.get(2), args.get(3)) else {
|
||||
ctx.notice(me, from.uid, "Syntax: CERT DEL <password> <fingerprint>");
|
||||
return;
|
||||
};
|
||||
let Some(account) = auth(db, password) else {
|
||||
ctx.notice(me, from.uid, "Invalid password.");
|
||||
return;
|
||||
};
|
||||
match db.certfp_del(&account, fp) {
|
||||
Ok(true) => ctx.notice(me, from.uid, format!("Removed fingerprint \x02{fp}\x02.")),
|
||||
Ok(false) => ctx.notice(me, from.uid, "No such fingerprint is registered to your account."),
|
||||
Err(_) => ctx.notice(me, from.uid, "Could not remove the fingerprint, please try again later."),
|
||||
}
|
||||
}
|
||||
_ => ctx.notice(me, from.uid, "Syntax: CERT ADD|DEL|LIST <password> [fingerprint]"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue