mirror of
https://codeberg.org/emersion/gamja.git
synced 2024-11-28 02:05:41 -05:00
lib/client: add support for AUTHENTICATE chunking
SASL responses need to be split into 400 byte chunks before being sent to the server.
This commit is contained in:
parent
d9f7faad88
commit
6c324d44a1
2 changed files with 25 additions and 8 deletions
|
@ -1,5 +1,4 @@
|
|||
import * as irc from "./irc.js";
|
||||
import * as base64 from "./base64.js";
|
||||
|
||||
// Static list of capabilities that are always requested when supported by the
|
||||
// server
|
||||
|
@ -467,18 +466,16 @@ export default class Client extends EventTarget {
|
|||
console.log(`Starting SASL ${mechanism} authentication`);
|
||||
|
||||
// Send the first SASL response immediately to avoid a roundtrip
|
||||
let initialResp = null;
|
||||
let initialResp;
|
||||
switch (mechanism) {
|
||||
case "PLAIN":
|
||||
let respStr = base64.encode("\0" + params.username + "\0" + params.password);
|
||||
initialResp = { command: "AUTHENTICATE", params: [respStr] };
|
||||
initialResp = "\0" + params.username + "\0" + params.password;
|
||||
break;
|
||||
case "EXTERNAL":
|
||||
initialResp = { command: "AUTHENTICATE", params: ["+"] };
|
||||
initialResp = "";
|
||||
break;
|
||||
case "OAUTHBEARER":
|
||||
let raw = "n,,\x01auth=Bearer " + params.token + "\x01\x01";
|
||||
initialResp = { command: "AUTHENTICATE", params: [base64.encode(raw)] };
|
||||
initialResp = "n,,\x01auth=Bearer " + params.token + "\x01\x01";
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown authentication mechanism '${mechanism}'`);
|
||||
|
@ -497,7 +494,9 @@ export default class Client extends EventTarget {
|
|||
throw new IRCError(msg);
|
||||
}
|
||||
});
|
||||
this.send(initialResp);
|
||||
for (let msg of irc.generateAuthenticateMessages(initialResp)) {
|
||||
this.send(msg);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
|
18
lib/irc.js
18
lib/irc.js
|
@ -1,3 +1,5 @@
|
|||
import * as base64 from "./base64.js";
|
||||
|
||||
// RFC 1459
|
||||
export const RPL_WELCOME = "001";
|
||||
export const RPL_YOURHOST = "002";
|
||||
|
@ -942,3 +944,19 @@ export class CapRegistry {
|
|||
return { command: "CAP", params: ["REQ", l.join(" ")] };
|
||||
}
|
||||
}
|
||||
|
||||
const maxSASLLength = 400;
|
||||
|
||||
export function generateAuthenticateMessages(payload) {
|
||||
let encoded = base64.encode(payload);
|
||||
|
||||
// <= instead of < because we need to send a final empty response if the
|
||||
// last chunk is exactly 400 bytes long
|
||||
let msgs = [];
|
||||
for (let i = 0; i <= encoded.length; i += maxSASLLength) {
|
||||
let chunk = encoded.substring(i, i + 400);
|
||||
msgs.push({ command: "AUTHENTICATE", params: [chunk || "+"] });
|
||||
}
|
||||
|
||||
return msgs;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue