forked from CringeStudios/gamja
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
@ -1,5 +1,4 @@
|
|||||||
import * as irc from "./irc.js";
|
import * as irc from "./irc.js";
|
||||||
import * as base64 from "./base64.js";
|
|
||||||
|
|
||||||
// Static list of capabilities that are always requested when supported by the
|
// Static list of capabilities that are always requested when supported by the
|
||||||
// server
|
// server
|
||||||
@ -467,18 +466,16 @@ export default class Client extends EventTarget {
|
|||||||
console.log(`Starting SASL ${mechanism} authentication`);
|
console.log(`Starting SASL ${mechanism} authentication`);
|
||||||
|
|
||||||
// Send the first SASL response immediately to avoid a roundtrip
|
// Send the first SASL response immediately to avoid a roundtrip
|
||||||
let initialResp = null;
|
let initialResp;
|
||||||
switch (mechanism) {
|
switch (mechanism) {
|
||||||
case "PLAIN":
|
case "PLAIN":
|
||||||
let respStr = base64.encode("\0" + params.username + "\0" + params.password);
|
initialResp = "\0" + params.username + "\0" + params.password;
|
||||||
initialResp = { command: "AUTHENTICATE", params: [respStr] };
|
|
||||||
break;
|
break;
|
||||||
case "EXTERNAL":
|
case "EXTERNAL":
|
||||||
initialResp = { command: "AUTHENTICATE", params: ["+"] };
|
initialResp = "";
|
||||||
break;
|
break;
|
||||||
case "OAUTHBEARER":
|
case "OAUTHBEARER":
|
||||||
let raw = "n,,\x01auth=Bearer " + params.token + "\x01\x01";
|
initialResp = "n,,\x01auth=Bearer " + params.token + "\x01\x01";
|
||||||
initialResp = { command: "AUTHENTICATE", params: [base64.encode(raw)] };
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown authentication mechanism '${mechanism}'`);
|
throw new Error(`Unknown authentication mechanism '${mechanism}'`);
|
||||||
@ -497,7 +494,9 @@ export default class Client extends EventTarget {
|
|||||||
throw new IRCError(msg);
|
throw new IRCError(msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.send(initialResp);
|
for (let msg of irc.generateAuthenticateMessages(initialResp)) {
|
||||||
|
this.send(msg);
|
||||||
|
}
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
lib/irc.js
18
lib/irc.js
@ -1,3 +1,5 @@
|
|||||||
|
import * as base64 from "./base64.js";
|
||||||
|
|
||||||
// RFC 1459
|
// RFC 1459
|
||||||
export const RPL_WELCOME = "001";
|
export const RPL_WELCOME = "001";
|
||||||
export const RPL_YOURHOST = "002";
|
export const RPL_YOURHOST = "002";
|
||||||
@ -942,3 +944,19 @@ export class CapRegistry {
|
|||||||
return { command: "CAP", params: ["REQ", l.join(" ")] };
|
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…
x
Reference in New Issue
Block a user