diff --git a/packages/sasl-ht-sha-256-none/index.js b/packages/sasl-ht-sha-256-none/index.js
index 618794488..87acdae4d 100644
--- a/packages/sasl-ht-sha-256-none/index.js
+++ b/packages/sasl-ht-sha-256-none/index.js
@@ -9,6 +9,10 @@ Mechanism.prototype.Mechanism = Mechanism;
Mechanism.prototype.name = "HT-SHA-256-NONE";
Mechanism.prototype.clientFirst = true;
+Mechanism.prototype.challenge = async function challenge(_) {
+ throw new Error(`${this.name} does not support SASL challenges`);
+}
+
Mechanism.prototype.response = async function response({ username, password }) {
this.key = await crypto.subtle.importKey(
"raw",
diff --git a/packages/sasl2/index.js b/packages/sasl2/index.js
index 7cb819754..6c3092834 100644
--- a/packages/sasl2/index.js
+++ b/packages/sasl2/index.js
@@ -115,6 +115,11 @@ export default function sasl2({ streamFeatures, saslFactory }, onAuthenticate) {
async function done(credentials, mechanism, userAgent) {
// Try fast
+ let err;
+ entity.on("error", (_err) => {
+ // catch internal/protocol errors in fast.auth()
+ err = _err;
+ })
const success = await fast.auth({
authenticate,
entity,
@@ -123,7 +128,7 @@ export default function sasl2({ streamFeatures, saslFactory }, onAuthenticate) {
features,
credentials,
});
- if (success) return;
+ if (success || err) return;
// fast.auth may mutate streamFeatures to request a token
diff --git a/packages/sasl2/test.js b/packages/sasl2/test.js
index 07c4ce805..f608573c7 100644
--- a/packages/sasl2/test.js
+++ b/packages/sasl2/test.js
@@ -224,3 +224,56 @@ test("use ANONYMOUS if username and password are not provided", async () => {
const result = await promise(entity, "send");
expect(result.attrs.mechanism).toEqual("ANONYMOUS");
});
+
+test("fail if server sends a challenge during FAST login", async () => {
+ const mech = "HT-SHA-256-NONE";
+
+ function onAuthenticate(authenticate, mechanisms, fast) {
+ expect(mechanisms).toEqual([]);
+ expect(fast.mechanism).toEqual(mech);
+ return authenticate(
+ {
+ token: {
+ token: "hai",
+ mechanism: fast.mechanism,
+ },
+ },
+ null,
+ userAgent,
+ );
+ }
+
+ const { entity } = mockClient({ credentials: onAuthenticate });
+
+ entity.mockInput(
+
+
+
+
+ {mech}
+
+
+
+ ,
+ );
+
+ expect(await promise(entity, "send")).toEqual(
+
+
+ bnVsbACNMNimsTBnxS04m8x7wgKjBHdDUL/nXPU4J4vqxqjBIg==
+
+ {userAgent}
+
+ ,
+ );
+
+ entity.mockInput(
+
+ aGVyZXNhYnVuY2hvZmJhZGNoYWxsZW5nZWRhdGEK
+ ,
+ );
+
+ const error = await promise(entity, "error");
+ expect(error instanceof Error).toBe(true);
+ expect(error.message).toBe("HT-SHA-256-NONE does not support SASL challenges");
+});