mirror of https://github.com/mongodb/mongo
196 lines
7.0 KiB
JavaScript
196 lines
7.0 KiB
JavaScript
// Test for speculativeSaslStart during isMaster.
|
|
|
|
const keyFile = "jstests/libs/key1";
|
|
const mongod = MongoRunner.runMongod({auth: "", keyFile: keyFile});
|
|
const admin = mongod.getDB("admin");
|
|
|
|
admin.createUser({user: "admin", pwd: "pwd", roles: ["root"], mechanisms: ["SCRAM-SHA-1", "SCRAM-SHA-256"]});
|
|
admin.auth("admin", "pwd");
|
|
|
|
function test(uri, succeed) {
|
|
const shell = runMongoProgram("mongo", uri, "--eval", ";");
|
|
|
|
if (succeed) {
|
|
assert.eq(0, shell);
|
|
} else {
|
|
assert.neq(0, shell);
|
|
}
|
|
}
|
|
|
|
function assertStats(cb) {
|
|
const mechStats = assert.commandWorked(admin.runCommand({serverStatus: 1})).security.authentication.mechanisms;
|
|
cb(mechStats);
|
|
}
|
|
|
|
// No speculative auth attempts yet.
|
|
assertStats(function (mechStats) {
|
|
Object.keys(mechStats).forEach(function (mech) {
|
|
const stats = mechStats[mech].speculativeAuthenticate;
|
|
assert.eq(stats.received, 0);
|
|
assert.eq(stats.successful, 0);
|
|
});
|
|
});
|
|
|
|
// No "intra-cluster" auth attempts yet.
|
|
assertStats(function (mechStats) {
|
|
Object.keys(mechStats).forEach(function (mech) {
|
|
const stats = mechStats[mech].clusterAuthenticate;
|
|
assert.eq(stats.received, 0);
|
|
assert.eq(stats.successful, 0);
|
|
});
|
|
});
|
|
|
|
function expectN(mechStats, mech, N1, M1, N2 = 0, M2 = 0) {
|
|
const specStats = mechStats[mech].speculativeAuthenticate;
|
|
const clusterStats = mechStats[mech].clusterAuthenticate;
|
|
assert.eq(N1, specStats.received);
|
|
assert.eq(M1, specStats.successful);
|
|
assert.eq(N2, clusterStats.received);
|
|
assert.eq(M2, clusterStats.successful);
|
|
}
|
|
|
|
function assertSpecLog(severity, expectedAttrs, expectedCount) {
|
|
assert(checkLog.checkContainsWithCountJson(admin, 5286307, expectedAttrs, expectedCount, severity));
|
|
}
|
|
|
|
const baseOKURI = "mongodb://admin:pwd@localhost:" + mongod.port + "/admin";
|
|
|
|
// Speculate SCRAM-SHA-1
|
|
test(baseOKURI + "?authMechanism=SCRAM-SHA-1", true);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 1, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 0, 0));
|
|
|
|
// Speculate SCRAM-SHA-256
|
|
test(baseOKURI + "?authMechanism=SCRAM-SHA-256", true);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 1, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 1, 1));
|
|
|
|
// Fallback should speculate SCRAM-SHA-256
|
|
test(baseOKURI, true);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 1, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 2, 2));
|
|
|
|
const baseFAILURI = "mongodb://admin:haxx@localhost:" + mongod.port + "/admin";
|
|
// Client is impossible to match using checklog.
|
|
const speculativeSHA1AuthFailedAttrs = {
|
|
"mechanism": "SCRAM-SHA-1",
|
|
"isSpeculative": true,
|
|
"user": "admin",
|
|
"db": "admin",
|
|
"error": "AuthenticationFailed: SCRAM authentication failed, storedKey mismatch",
|
|
};
|
|
const sha1AuthFailedAttrs = {
|
|
"mechanism": "SCRAM-SHA-1",
|
|
"isSpeculative": false,
|
|
"user": "admin",
|
|
"db": "admin",
|
|
"error": "AuthenticationFailed: SCRAM authentication failed, storedKey mismatch",
|
|
};
|
|
const speculativeSHA256AuthFailedAttrs = {
|
|
"mechanism": "SCRAM-SHA-256",
|
|
"isSpeculative": true,
|
|
"user": "admin",
|
|
"db": "admin",
|
|
"error": "AuthenticationFailed: SCRAM authentication failed, storedKey mismatch",
|
|
};
|
|
const sha256AuthFailedAttrs = {
|
|
"mechanism": "SCRAM-SHA-256",
|
|
"isSpeculative": false,
|
|
"user": "admin",
|
|
"db": "admin",
|
|
"error": "AuthenticationFailed: SCRAM authentication failed, storedKey mismatch",
|
|
};
|
|
const speculativeSHA256MechUnavailableAttrs = {
|
|
"mechanism": "SCRAM-SHA-256",
|
|
"isSpeculative": true,
|
|
"user": "admin",
|
|
"db": "admin",
|
|
"error":
|
|
"MechanismUnavailable: Unable to use SCRAM-SHA-256 based authentication for user without any SCRAM-SHA-256 credentials registered",
|
|
};
|
|
const sha256MechUnavailableAttrs = {
|
|
"mechanism": "SCRAM-SHA-256",
|
|
"isSpeculative": false,
|
|
"user": "admin",
|
|
"db": "admin",
|
|
"error":
|
|
"MechanismUnavailable: Unable to use SCRAM-SHA-256 based authentication for user without any SCRAM-SHA-256 credentials registered",
|
|
};
|
|
const speculativeClusterAuthFailedAttrs = {
|
|
"mechanism": "SCRAM-SHA-256",
|
|
"isSpeculative": true,
|
|
"user": "__system",
|
|
"db": "local",
|
|
"error": "AuthenticationFailed: SCRAM authentication failed, storedKey mismatch",
|
|
};
|
|
const clusterAuthFailedAttrs = {
|
|
"mechanism": "SCRAM-SHA-256",
|
|
"isSpeculative": false,
|
|
"user": "__system",
|
|
"db": "local",
|
|
"error": "AuthenticationFailed: SCRAM authentication failed, storedKey mismatch",
|
|
};
|
|
admin.setLogLevel(5);
|
|
// Invalid password should never connect regardless of speculative auth.
|
|
test(baseFAILURI + "?authMechanism=SCRAM-SHA-1", false);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 2, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 2, 2));
|
|
assertSpecLog("I", speculativeSHA1AuthFailedAttrs, 1);
|
|
assertSpecLog("I", sha1AuthFailedAttrs, 1);
|
|
|
|
test(baseFAILURI + "?authMechanism=SCRAM-SHA-256", false);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 2, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 3, 2));
|
|
assertSpecLog("I", speculativeSHA256AuthFailedAttrs, 1);
|
|
assertSpecLog("I", sha256AuthFailedAttrs, 1);
|
|
|
|
test(baseFAILURI, false);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 2, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 4, 2));
|
|
assertSpecLog("I", speculativeSHA256AuthFailedAttrs, 2);
|
|
assertSpecLog("I", sha256AuthFailedAttrs, 2);
|
|
|
|
// Update admin use to only allow SCRAM-SHA-1
|
|
|
|
admin.updateUser("admin", {mechanisms: ["SCRAM-SHA-1"]});
|
|
|
|
// Fallback (SCRAM-SHA-256) should fail to speculate.
|
|
test(baseOKURI, true);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 2, 1));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 5, 2));
|
|
assertSpecLog("I", speculativeSHA256MechUnavailableAttrs, 1);
|
|
|
|
// Explicit SCRAM-SHA-1 should successfully speculate.
|
|
test(baseOKURI + "?authMechanism=SCRAM-SHA-1", true);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 3, 2));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 5, 2));
|
|
|
|
// Explicit SCRAM-SHA-256 should fail to speculate or connect at all.
|
|
test(baseOKURI + "?authMechanism=SCRAM-SHA-256", false);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-1", 3, 2));
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 6, 2));
|
|
assertSpecLog("I", speculativeSHA256MechUnavailableAttrs, 2);
|
|
assertSpecLog("I", sha256MechUnavailableAttrs, 1);
|
|
|
|
// Test that a user not in the admin DB can speculate
|
|
mongod.getDB("test").createUser({user: "alice", pwd: "secret", roles: []});
|
|
test("mongodb://alice:secret@localhost:" + mongod.port + "/test", true);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 7, 3));
|
|
|
|
// Test "intra-cluster" speculative authentication.
|
|
const systemPass = cat(keyFile).replace(/\s/g, "");
|
|
test(
|
|
"mongodb://__system:" + systemPass + "@localhost:" + mongod.port + "/admin" + "?authMechanism=SCRAM-SHA-256",
|
|
true,
|
|
);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 8, 4, 1, 1));
|
|
|
|
test("mongodb://__system:hunter2@localhost:" + mongod.port + "/admin" + "?authMechanism=SCRAM-SHA-256", false);
|
|
assertStats((s) => expectN(s, "SCRAM-SHA-256", 9, 4, 3, 1));
|
|
assertSpecLog("I", speculativeClusterAuthFailedAttrs, 1);
|
|
assertSpecLog("I", clusterAuthFailedAttrs, 1);
|
|
|
|
admin.setLogLevel(0);
|
|
|
|
MongoRunner.stopMongod(mongod);
|