forked from CringeStudios/gamja
Add support for SASL EXTERNAL
Can be useful when the server is using e.g. a cookie for authentication purposes.
This commit is contained in:
parent
a890665775
commit
21a4a71542
@ -87,8 +87,8 @@ gamja default settings can be set using a `config.json` file at the root:
|
|||||||
"autojoin": "#gamja",
|
"autojoin": "#gamja",
|
||||||
// Controls how the password UI is presented to the user. Set to
|
// Controls how the password UI is presented to the user. Set to
|
||||||
// "mandatory" to require a password, "optional" to accept one but not
|
// "mandatory" to require a password, "optional" to accept one but not
|
||||||
// require it, and "disabled" to never ask for a password. Defaults to
|
// require it, "disabled" to never ask for a password, or "external" to
|
||||||
// "optional".
|
// use SASL EXTERNAL. Defaults to "optional".
|
||||||
"auth": "optional",
|
"auth": "optional",
|
||||||
// Default nickname (string).
|
// Default nickname (string).
|
||||||
"nick": "asdf",
|
"nick": "asdf",
|
||||||
|
@ -124,6 +124,7 @@ export default class App extends Component {
|
|||||||
realname: null,
|
realname: null,
|
||||||
nick: null,
|
nick: null,
|
||||||
saslPlain: null,
|
saslPlain: null,
|
||||||
|
saslExternal: false,
|
||||||
autoconnect: false,
|
autoconnect: false,
|
||||||
autojoin: [],
|
autojoin: [],
|
||||||
},
|
},
|
||||||
@ -207,6 +208,9 @@ export default class App extends Component {
|
|||||||
if (typeof config.server.autoconnect === "boolean") {
|
if (typeof config.server.autoconnect === "boolean") {
|
||||||
connectParams.autoconnect = config.server.autoconnect;
|
connectParams.autoconnect = config.server.autoconnect;
|
||||||
}
|
}
|
||||||
|
if (config.server.auth === "external") {
|
||||||
|
connectParams.saslExternal = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let autoconnect = store.autoconnect.load();
|
let autoconnect = store.autoconnect.load();
|
||||||
|
@ -61,6 +61,8 @@ export default class ConnectForm extends Component {
|
|||||||
username: params.username || params.nick,
|
username: params.username || params.nick,
|
||||||
password: this.state.password,
|
password: this.state.password,
|
||||||
};
|
};
|
||||||
|
} else if (this.props.auth === "external") {
|
||||||
|
params.saslExternal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state.autojoin.split(",").forEach(function(ch) {
|
this.state.autojoin.split(",").forEach(function(ch) {
|
||||||
@ -112,7 +114,7 @@ export default class ConnectForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let auth = null;
|
let auth = null;
|
||||||
if (this.props.auth !== "disabled") {
|
if (this.props.auth !== "disabled" && this.props.auth !== "external") {
|
||||||
auth = html`
|
auth = html`
|
||||||
<label>
|
<label>
|
||||||
Password:<br/>
|
Password:<br/>
|
||||||
|
@ -69,6 +69,7 @@ export default class Client extends EventTarget {
|
|||||||
nick: null,
|
nick: null,
|
||||||
pass: null,
|
pass: null,
|
||||||
saslPlain: null,
|
saslPlain: null,
|
||||||
|
saslExternal: false,
|
||||||
bouncerNetwork: null,
|
bouncerNetwork: null,
|
||||||
};
|
};
|
||||||
batches = new Map();
|
batches = new Map();
|
||||||
@ -498,7 +499,7 @@ export default class Client extends EventTarget {
|
|||||||
|
|
||||||
let reqCaps = [];
|
let reqCaps = [];
|
||||||
let capEnd = true;
|
let capEnd = true;
|
||||||
if (this.params.saslPlain && this.supportsSASL("PLAIN")) {
|
if ((this.params.saslPlain && this.supportsSASL("PLAIN")) || (this.params.saslExternal && this.supportsSASL("EXTERNAL"))) {
|
||||||
// CAP END is deferred after authentication finishes
|
// CAP END is deferred after authentication finishes
|
||||||
reqCaps.push("sasl");
|
reqCaps.push("sasl");
|
||||||
capEnd = false;
|
capEnd = false;
|
||||||
@ -537,6 +538,9 @@ export default class Client extends EventTarget {
|
|||||||
if (cap == "sasl" && this.params.saslPlain) {
|
if (cap == "sasl" && this.params.saslPlain) {
|
||||||
console.log("Starting SASL PLAIN authentication");
|
console.log("Starting SASL PLAIN authentication");
|
||||||
this.send({ command: "AUTHENTICATE", params: ["PLAIN"] });
|
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"] });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@ -552,15 +556,20 @@ export default class Client extends EventTarget {
|
|||||||
handleAuthenticate(msg) {
|
handleAuthenticate(msg) {
|
||||||
let challengeStr = msg.params[0];
|
let challengeStr = msg.params[0];
|
||||||
|
|
||||||
// For now only PLAIN is supported
|
|
||||||
if (challengeStr != "+") {
|
if (challengeStr != "+") {
|
||||||
this.dispatchEvent(new CustomEvent("error", { detail: "Expected an empty challenge, got: " + challengeStr }));
|
this.dispatchEvent(new CustomEvent("error", { detail: "Expected an empty challenge, got: " + challengeStr }));
|
||||||
this.send({ command: "AUTHENTICATE", params: ["*"] });
|
this.send({ command: "AUTHENTICATE", params: ["*"] });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.params.saslPlain) {
|
||||||
let respStr = btoa("\0" + this.params.saslPlain.username + "\0" + this.params.saslPlain.password);
|
let respStr = btoa("\0" + this.params.saslPlain.username + "\0" + this.params.saslPlain.password);
|
||||||
this.send({ command: "AUTHENTICATE", params: [respStr] });
|
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) {
|
send(msg) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user