Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

NODE-1435: move all auth to connect #406

Merged
merged 8 commits into from
Feb 22, 2019
8 changes: 3 additions & 5 deletions lib/auth/auth_provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ class AuthProvider {

// If we have an error
if (err) {
errorObject = err;
} else if (r.result && r.result['$err']) {
errorObject = r.result;
} else if (r.result && r.result['errmsg']) {
errorObject = r.result;
errorObject = new MongoError(err);
} else if (r && (r.$err || r.errmsg)) {
errorObject = new MongoError(r);
} else {
numberOfValidConnections = numberOfValidConnections + 1;
}
Expand Down
8 changes: 3 additions & 5 deletions lib/auth/gssapi.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,10 @@ var MongoDBGSSAPIFirstStep = function(
};

// Write the commmand on the connection
sendAuthCommand(connection, '$external.$cmd', command, (err, r) => {
sendAuthCommand(connection, '$external.$cmd', command, (err, doc) => {
if (err) return callback(err, false);
var doc = r.result;
// Execute mongodb transition
mongo_auth_process.transition(r.result.payload, function(err, payload) {
mongo_auth_process.transition(doc.payload, function(err, payload) {
if (err) return callback(err, false);

// MongoDB API Second Step
Expand Down Expand Up @@ -177,9 +176,8 @@ var MongoDBGSSAPISecondStep = function(

// Execute the command
// Write the commmand on the connection
sendAuthCommand(connection, '$external.$cmd', command, (err, r) => {
sendAuthCommand(connection, '$external.$cmd', command, (err, doc) => {
if (err) return callback(err, false);
var doc = r.result;
// Call next transition for kerberos
mongo_auth_process.transition(doc.payload, function(err, payload) {
if (err) return callback(err, false);
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/mongocr.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class MongoCR extends AuthProvider {

// Get nonce
if (err == null) {
nonce = r.result.nonce;
nonce = r.nonce;
// Use node md5 generator
let md5 = crypto.createHash('md5');
// Generate keys used for authentication
Expand Down
18 changes: 7 additions & 11 deletions lib/auth/scram.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ class ScramSHA extends AuthProvider {
return err;
}

if (r.result['$err'] || r.result['errmsg']) {
return r.result;
if (r.$err || r.errmsg) {
return new MongoError(r);
}
}

Expand Down Expand Up @@ -177,7 +177,7 @@ class ScramSHA extends AuthProvider {
return callback(tmpError, null);
}

const dict = parsePayload(r.result.payload.value());
const dict = parsePayload(r.payload.value());
const iterations = parseInt(dict.i, 10);
const salt = dict.s;
const rnonce = dict.r;
Expand All @@ -198,29 +198,25 @@ class ScramSHA extends AuthProvider {

const clientKey = HMAC(cryptoMethod, saltedPassword, 'Client Key');
const storedKey = H(cryptoMethod, clientKey);
const authMessage = [
firstBare,
r.result.payload.value().toString('base64'),
withoutProof
].join(',');
const authMessage = [firstBare, r.payload.value().toString('base64'), withoutProof].join(',');

const clientSignature = HMAC(cryptoMethod, storedKey, authMessage);
const clientProof = `p=${xor(clientKey, clientSignature)}`;
const clientFinal = [withoutProof, clientProof].join(',');
const saslContinueCmd = {
saslContinue: 1,
conversationId: r.result.conversationId,
conversationId: r.conversationId,
payload: new Binary(Buffer.from(clientFinal))
};

sendAuthCommand(connection, `${db}.$cmd`, saslContinueCmd, (err, r) => {
if (!r || r.result.done !== false) {
if (!r || r.done !== false) {
return callback(err, r);
}

const retrySaslContinueCmd = {
saslContinue: 1,
conversationId: r.result.conversationId,
conversationId: r.conversationId,
payload: Buffer.alloc(0)
};

Expand Down
6 changes: 2 additions & 4 deletions lib/auth/sspi.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,8 @@ function SSIPAuthenticate(
autoAuthorize: 1
};

authCommand(command, (err, result) => {
authCommand(command, (err, doc) => {
if (err) return callback(err, false);
const doc = result.result;

authProcess.transition(doc.payload, (err, payload) => {
if (err) return callback(err, false);
Expand All @@ -102,9 +101,8 @@ function SSIPAuthenticate(
payload
};

authCommand(command, (err, result) => {
authCommand(command, (err, doc) => {
if (err) return callback(err, false);
const doc = result.result;

authProcess.transition(doc.payload, (err, payload) => {
if (err) return callback(err, false);
Expand Down
29 changes: 29 additions & 0 deletions lib/connection/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@ const Connection = require('./connection');
const Query = require('./commands').Query;
const createClientInfo = require('../topologies/shared').createClientInfo;
const MongoError = require('../error').MongoError;
const defaultAuthProviders = require('../auth/defaultAuthProviders').defaultAuthProviders;
let AUTH_PROVIDERS;

function connect(options, callback) {
if (AUTH_PROVIDERS == null) {
AUTH_PROVIDERS = defaultAuthProviders(options.bson);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double checking that we do not allow people to change their BSON impl on the fly

}

if (options.family !== void 0) {
makeConnection(options.family, options, (err, socket) => {
if (err) {
Expand Down Expand Up @@ -132,6 +138,14 @@ function performInitialHandshake(conn, options, callback) {
// relocated, or at very least restructured.
conn.ismaster = ismaster;
conn.lastIsMasterMS = new Date().getTime() - start;

const credentials = options.credentials;
if (credentials) {
credentials.resolveAuthMechanism(ismaster);
authenticate(conn, credentials, callback);
return;
}

callback(null, conn);
});
}
Expand Down Expand Up @@ -260,6 +274,7 @@ function makeConnection(family, options, callback) {

const CONNECTION_ERROR_EVENTS = ['error', 'close', 'timeout', 'parseError'];
function runCommand(conn, ns, command, options, callback) {
if (typeof options === 'function') (callback = options), (options = {});
const socketTimeout = typeof options.socketTimeout === 'number' ? options.socketTimeout : 360000;
const bson = conn.options.bson;
const query = new Query(bson, ns, command, {
Expand Down Expand Up @@ -293,4 +308,18 @@ function runCommand(conn, ns, command, options, callback) {
conn.write(query.toBin());
}

function authenticate(conn, credentials, callback) {
const mechanism = credentials.mechanism;
if (!AUTH_PROVIDERS[mechanism]) {
callback(new MongoError(`authMechanism '${mechanism}' not supported`));
return;
}

const provider = AUTH_PROVIDERS[mechanism];
provider.auth(runCommand, [conn], credentials, err => {
if (err) return callback(err);
callback(null, conn);
});
}

module.exports = connect;
Loading