Skip to content

Commit 4b8e2da

Browse files
committed
Test incorrect SASL <challenge>s during FAST
1 parent d375abd commit 4b8e2da

3 files changed

Lines changed: 63 additions & 4 deletions

File tree

packages/sasl-ht-sha-256-none/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ Mechanism.prototype.Mechanism = Mechanism;
99
Mechanism.prototype.name = "HT-SHA-256-NONE";
1010
Mechanism.prototype.clientFirst = true;
1111

12+
Mechanism.prototype.challenge = async function challenge(_) {
13+
throw new Error(`${this.name} does not support SASL challenges`);
14+
}
15+
1216
Mechanism.prototype.response = async function response({ username, password }) {
1317
this.key = await crypto.subtle.importKey(
1418
"raw",

packages/sasl2/index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ async function authenticate({
4646
if (element.getNS() !== NS) return;
4747

4848
if (element.name === "challenge") {
49-
if (!mech.challenge) {
50-
throw new Error("${mech.name} does not support SASL challenges");
51-
}
5249
await mech.challenge(decode(element.text()));
5350
const resp = await mech.response(creds);
5451
await entity.send(
@@ -118,6 +115,11 @@ export default function sasl2({ streamFeatures, saslFactory }, onAuthenticate) {
118115

119116
async function done(credentials, mechanism, userAgent) {
120117
// Try fast
118+
let err;
119+
entity.on("error", (_err) => {
120+
// catch internal/protocol errors in fast.auth()
121+
err = _err;
122+
})
121123
const success = await fast.auth({
122124
authenticate,
123125
entity,
@@ -126,7 +128,7 @@ export default function sasl2({ streamFeatures, saslFactory }, onAuthenticate) {
126128
features,
127129
credentials,
128130
});
129-
if (success) return;
131+
if (success || err) return;
130132

131133
// fast.auth may mutate streamFeatures to request a token
132134

packages/sasl2/test.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,56 @@ test("use ANONYMOUS if username and password are not provided", async () => {
224224
const result = await promise(entity, "send");
225225
expect(result.attrs.mechanism).toEqual("ANONYMOUS");
226226
});
227+
228+
test("fail if server sends a challenge during FAST login", async () => {
229+
const mech = "HT-SHA-256-NONE";
230+
231+
function onAuthenticate(authenticate, mechanisms, fast) {
232+
expect(mechanisms).toEqual([]);
233+
expect(fast.mechanism).toEqual(mech);
234+
return authenticate(
235+
{
236+
token: {
237+
token: "hai",
238+
mechanism: fast.mechanism,
239+
},
240+
},
241+
null,
242+
userAgent,
243+
);
244+
}
245+
246+
const { entity } = mockClient({ credentials: onAuthenticate });
247+
248+
entity.mockInput(
249+
<features xmlns="http://etherx.jabber.org/streams">
250+
<authentication xmlns="urn:xmpp:sasl:2">
251+
<inline>
252+
<fast xmlns="urn:xmpp:fast:0">
253+
<mechanism>{mech}</mechanism>
254+
</fast>
255+
</inline>
256+
</authentication>
257+
</features>,
258+
);
259+
260+
expect(await promise(entity, "send")).toEqual(
261+
<authenticate xmlns="urn:xmpp:sasl:2" mechanism={mech}>
262+
<initial-response>
263+
bnVsbACNMNimsTBnxS04m8x7wgKjBHdDUL/nXPU4J4vqxqjBIg==
264+
</initial-response>
265+
{userAgent}
266+
<fast xmlns="urn:xmpp:fast:0" />
267+
</authenticate>,
268+
);
269+
270+
entity.mockInput(
271+
<challenge xmlns="urn:xmpp:sasl:2">
272+
aGVyZXNhYnVuY2hvZmJhZGNoYWxsZW5nZWRhdGEK
273+
</challenge>,
274+
);
275+
276+
const error = await promise(entity, "error");
277+
expect(error instanceof Error).toBe(true);
278+
expect(error.message).toBe("HT-SHA-256-NONE does not support SASL challenges");
279+
});

0 commit comments

Comments
 (0)