mirror of
https://git.sr.ht/~emersion/gamja
synced 2024-12-11 00:31:26 -05:00
lib/client: remove one roundtrip during SASL auth
Instead of waiting for the server's empty challenge, send two AUTHENTICATE commands in a row.
This commit is contained in:
parent
0af40a1a8e
commit
25dd6aabf6
1 changed files with 29 additions and 26 deletions
|
@ -271,7 +271,12 @@ export default class Client extends EventTarget {
|
|||
this.handleCap(msg);
|
||||
break;
|
||||
case "AUTHENTICATE":
|
||||
this.handleAuthenticate(msg);
|
||||
// Both PLAIN and EXTERNAL expect an empty challenge
|
||||
let challengeStr = msg.params[0];
|
||||
if (challengeStr != "+") {
|
||||
this.dispatchEvent(new CustomEvent("error", { detail: "Expected an empty challenge, got: " + challengeStr }));
|
||||
this.send({ command: "AUTHENTICATE", params: ["*"] });
|
||||
}
|
||||
break;
|
||||
case irc.RPL_LOGGEDIN:
|
||||
console.log("Logged in");
|
||||
|
@ -381,6 +386,23 @@ export default class Client extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
authenticate(mechanism, params) {
|
||||
console.log(`Starting SASL ${mechanism} authentication`);
|
||||
this.send({ command: "AUTHENTICATE", params: [mechanism] });
|
||||
switch (mechanism) {
|
||||
case "PLAIN":
|
||||
let respStr = btoa("\0" + params.username + "\0" + params.password);
|
||||
this.send({ command: "AUTHENTICATE", params: [respStr] });
|
||||
break;
|
||||
case "EXTERNAL":
|
||||
this.send({ command: "AUTHENTICATE", params: [btoa("")] });
|
||||
break;
|
||||
default:
|
||||
this.send({ command: "AUTHENTICATE", params: ["*"] });
|
||||
throw new Error(`Unknown authentication mechanism '${mechanism}'`);
|
||||
}
|
||||
}
|
||||
|
||||
who(mask, options) {
|
||||
let params = [mask];
|
||||
|
||||
|
@ -580,12 +602,12 @@ export default class Client extends EventTarget {
|
|||
cap = cap.toLowerCase();
|
||||
this.enabledCaps[cap] = true;
|
||||
|
||||
if (cap == "sasl" && this.params.saslPlain) {
|
||||
console.log("Starting SASL PLAIN authentication");
|
||||
this.send({ command: "AUTHENTICATE", params: ["PLAIN"] });
|
||||
} else if (cap == "sasl" && this.params.saslExternal) {
|
||||
console.log("Starting SASL EXTERNAL authentication");
|
||||
this.send({ command: "AUTHENTICATE", params: ["EXTERNAL"] });
|
||||
if (cap === "sasl" && this.status !== Client.Status.REGISTERED) {
|
||||
if (this.params.saslPlain) {
|
||||
this.authenticate("PLAIN", this.params.saslPlain);
|
||||
} else if (this.params.saslExternal) {
|
||||
this.authenticate("EXTERNAL");
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
@ -598,25 +620,6 @@ export default class Client extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
handleAuthenticate(msg) {
|
||||
let challengeStr = msg.params[0];
|
||||
|
||||
if (challengeStr != "+") {
|
||||
this.dispatchEvent(new CustomEvent("error", { detail: "Expected an empty challenge, got: " + challengeStr }));
|
||||
this.send({ command: "AUTHENTICATE", params: ["*"] });
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.params.saslPlain) {
|
||||
let respStr = btoa("\0" + this.params.saslPlain.username + "\0" + this.params.saslPlain.password);
|
||||
this.send({ command: "AUTHENTICATE", params: [respStr] });
|
||||
} else if (this.params.saslExternal) {
|
||||
this.send({ command: "AUTHENTICATE", params: [btoa("")] });
|
||||
} else {
|
||||
throw new Error("Received AUTHENTICATE for unknown mechanism");
|
||||
}
|
||||
}
|
||||
|
||||
send(msg) {
|
||||
if (!this.ws) {
|
||||
throw new Error("Failed to send IRC message " + msg.command + ": socket is closed");
|
||||
|
|
Loading…
Reference in a new issue