diff --git a/lib/core/auth/scram.js b/lib/core/auth/scram.js index b65a076cea..32fb4cd57b 100644 --- a/lib/core/auth/scram.js +++ b/lib/core/auth/scram.js @@ -236,7 +236,7 @@ class ScramSHA extends AuthProvider { }; sendAuthCommand(connection, `${db}.$cmd`, saslContinueCmd, (err, r) => { - if (r && typeof r.ok === 'number' && r.ok === 0) { + if (err || (r && typeof r.ok === 'number' && r.ok === 0)) { callback(err, r); return; } diff --git a/test/unit/core/scram_iterations.test.js b/test/unit/core/scram_iterations.test.js index 47188c8563..1464fe3b7e 100644 --- a/test/unit/core/scram_iterations.test.js +++ b/test/unit/core/scram_iterations.test.js @@ -112,4 +112,47 @@ describe('SCRAM Iterations Tests', function() { client.connect(); }); + + it('should properly handle network errors on `saslContinue`', function(_done) { + const credentials = new MongoCredentials({ + mechanism: 'default', + source: 'db', + username: 'user', + password: 'pencil' + }); + + let done = e => { + done = () => {}; + return _done(e); + }; + + test.server.setMessageHandler(request => { + const doc = request.document; + if (doc.ismaster) { + return request.reply(Object.assign({}, mock.DEFAULT_ISMASTER)); + } else if (doc.saslStart) { + return request.reply({ + ok: 1, + done: false, + payload: Buffer.from( + 'r=VNnXkRqKflB5+rmfnFiisCWzgDLzez02iRpbvE5mQjMvizb+VkSPRZZ/pDmFzLxq,s=dZTyOb+KZqoeTFdsULiqow==,i=10000' + ) + }); + } else if (doc.saslContinue) { + request.connection.destroy(); + } + }); + + const client = new Server(Object.assign({}, test.server.address(), { credentials })); + client.on('error', err => { + expect(err).to.not.be.null; + expect(err) + .to.have.property('message') + .that.matches(/failed to connect to server/); + + client.destroy(done); + }); + + client.connect(); + }); });