From b7d28d3135fa298d693aa22d2f1713054c5b0751 Mon Sep 17 00:00:00 2001 From: Alena Khineika Date: Fri, 26 Jan 2024 21:51:14 +0100 Subject: [PATCH] fix(NODE-5609): node driver omits base64 padding in sasl-continue command (#3975) --- src/cmap/auth/scram.ts | 2 +- test/unit/assorted/scram_iterations.test.ts | 33 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/cmap/auth/scram.ts b/src/cmap/auth/scram.ts index 53bbf531eb..ba18e0f5c7 100644 --- a/src/cmap/auth/scram.ts +++ b/src/cmap/auth/scram.ts @@ -212,7 +212,7 @@ function parsePayload(payload: Binary) { const dict: Document = {}; const parts = payloadStr.split(','); for (let i = 0; i < parts.length; i++) { - const valueParts = parts[i].split('='); + const valueParts = (parts[i].match(/^([^=]*)=(.*)$/) ?? []).slice(1); dict[valueParts[0]] = valueParts[1]; } return dict; diff --git a/test/unit/assorted/scram_iterations.test.ts b/test/unit/assorted/scram_iterations.test.ts index a08274781a..106550ae10 100644 --- a/test/unit/assorted/scram_iterations.test.ts +++ b/test/unit/assorted/scram_iterations.test.ts @@ -129,4 +129,37 @@ describe('SCRAM Iterations Tests', function () { .to.have.property('message') .that.matches(/connection(.+)closed/); }); + + it('should preserve trailing "=" from saslStart responses that are passed to saslContinue', async function () { + const credentials = new MongoCredentials({ + mechanism: 'DEFAULT', + source: 'db', + username: 'user', + password: 'pencil', + mechanismProperties: {} + }); + let payload; + client.s.options.credentials = credentials; + + server.setMessageHandler(request => { + const doc = request.document; + if (isHello(doc)) { + return request.reply(Object.assign({}, mock.HELLO)); + } else if (doc.saslStart) { + return request.reply({ + ok: 1, + done: false, + payload: Buffer.from( + 'n=__system,r=r7RuW8nC89hmrlIPSpatiEGnZGkuGcsq,r=r7RuW8nC89hmrlIPSpatiEGnZGkuGcsquPuvfddlU3NavdfJxv/XKg==,s=b7rCae/2BRjlcsn93RoUOfqtiwaf0nrXvSKLdQ==,i=15000' + ) + }); + } else if (doc.saslContinue) { + payload = doc.payload.toString('utf8'); + request.connection.destroy(); + } + }); + + await client.connect().catch(error => error); + expect(payload).to.includes('r=r7RuW8nC89hmrlIPSpatiEGnZGkuGcsquPuvfddlU3NavdfJxv/XKg=='); + }); });