mongo/jstests/ssl/set_parameter_ssl.js

172 lines
6.2 KiB
JavaScript

// Test changing the --sslMode and --clusterAuthMode parameters using setParameter
var SERVER_CERT = "jstests/libs/server.pem";
var CA_CERT = "jstests/libs/ca.pem";
class TransportMode {
constructor(sslName, tlsName) {
this.sslName = sslName;
this.tlsName = tlsName;
}
get sslMode() {
return this.sslName;
}
get tlsMode() {
return this.tlsName;
}
}
const invalid = new TransportMode("invalid", "invalid");
const disabled = new TransportMode("disabled", "disabled");
const allowed = new TransportMode("allowSSL", "allowTLS");
const prefered = new TransportMode("preferSSL", "preferTLS");
const required = new TransportMode("requireSSL", "requireTLS");
function testTransportTransitionStandalone(scheme, oldMode, newMode, shouldSucceed) {
var conn =
MongoRunner.runMongod({sslMode: oldMode, sslPEMKeyFile: SERVER_CERT, sslCAFile: CA_CERT});
var adminDB = conn.getDB("admin");
adminDB.createUser({user: "root", pwd: "pwd", roles: ['root']});
adminDB.auth("root", "pwd");
var res = adminDB.runCommand({"setParameter": 1, [scheme]: newMode[scheme]});
assert(res["ok"] == shouldSucceed, tojson(res));
if (!shouldSucceed) {
MongoRunner.stopMongod(conn);
return;
}
if (newMode != "requireSSL") {
MongoRunner.stopMongod(conn);
return;
}
let uri = `mongodb://localhost:${conn.port}/admin`;
let exitCode = runMongoProgram("mongo", uri, "--eval", "assert.commandWorked(db.hello())");
assert.neq(exitCode, 0, "Was able to connect without SSL when SSLMode was requireSSL");
MongoRunner.stopMongod(conn);
}
function testTransportTransitionCluster(scheme, oldMode, newMode) {
var rst = new ReplSetTest({
name: "switch",
nodes: 3,
nodeOptions: {
sslMode: oldMode,
sslAllowInvalidHostnames: "",
sslCAFile: CA_CERT,
sslPEMKeyFile: SERVER_CERT,
},
});
rst.startSet();
rst.initiate();
rst.awaitReplication();
print(`=== Switching ${scheme} from ${oldMode} to ${newMode[scheme]} for all nodes in cluster`);
for (n of rst.nodes) {
let adminDB = n.getDB("admin");
assert.commandWorked(adminDB.runCommand({"setParameter": 1, [scheme]: newMode[scheme]}));
}
rst.awaitReplication();
rst.stopSet();
}
function testTransportTransition(scheme, oldMode, newMode, shouldSucceed) {
testTransportTransitionStandalone(scheme, oldMode, newMode, shouldSucceed);
if (shouldSucceed) {
testTransportTransitionCluster(scheme, oldMode, newMode);
}
}
function testAuthModeTransition(oldMode, newMode, sslMode, shouldSucceed) {
const keyFile = 'jstests/libs/key1';
let config = {
sslMode: sslMode,
sslPEMKeyFile: SERVER_CERT,
sslCAFile: CA_CERT,
clusterAuthMode: oldMode
};
if (oldMode != 'x509') {
config.keyFile = keyFile;
}
const conn = MongoRunner.runMongod(config);
const adminDB = conn.getDB("admin");
let authAsKeyFileCluster = function() {
const authParams = {
user: '__system',
mechanism: 'SCRAM-SHA-256',
pwd: cat(keyFile).replace(/[\011-\015\040]/g, '')
};
return adminDB.auth(authParams);
};
if (oldMode != 'x509') {
assert(authAsKeyFileCluster());
}
var res = adminDB.runCommand({"setParameter": 1, "clusterAuthMode": newMode});
assert(res["ok"] == shouldSucceed, tojson(res));
if (shouldSucceed && oldMode != 'x509') {
if (newMode == 'x509') {
assert(!authAsKeyFileCluster(), "Key file cluster auth should no longer work");
} else {
assert(authAsKeyFileCluster(), "Key file cluster auth should still work");
}
}
MongoRunner.stopMongod(conn);
}
function testTransportTransitions(scheme) {
testTransportTransition(scheme, "allowSSL", invalid, false);
testTransportTransition(scheme, "allowSSL", disabled, false);
testTransportTransition(scheme, "allowSSL", allowed, false);
testTransportTransition(scheme, "allowSSL", prefered, true);
testTransportTransition(scheme, "allowSSL", required, false);
testTransportTransition(scheme, "preferSSL", invalid, false);
testTransportTransition(scheme, "preferSSL", disabled, false);
testTransportTransition(scheme, "preferSSL", allowed, false);
testTransportTransition(scheme, "preferSSL", prefered, false);
testTransportTransition(scheme, "preferSSL", required, true);
testTransportTransition(scheme, "requireSSL", invalid, false);
testTransportTransition(scheme, "requireSSL", disabled, false);
testTransportTransition(scheme, "requireSSL", allowed, false);
testTransportTransition(scheme, "requireSSL", prefered, false);
testTransportTransition(scheme, "requireSSL", required, false);
}
testTransportTransitions("sslMode");
testTransportTransitions("tlsMode");
testAuthModeTransition("sendKeyFile", "invalid", "requireSSL", false);
testAuthModeTransition("sendKeyFile", "keyFile", "requireSSL", false);
testAuthModeTransition("sendKeyFile", "sendKeyFile", "requireSSL", false);
testAuthModeTransition("sendKeyFile", "sendX509", "requireSSL", true);
testAuthModeTransition("sendKeyFile", "x509", "requireSSL", false);
testAuthModeTransition("sendX509", "invalid", "requireSSL", false);
testAuthModeTransition("sendX509", "keyFile", "requireSSL", false);
testAuthModeTransition("sendX509", "sendKeyFile", "requireSSL", false);
testAuthModeTransition("sendX509", "sendX509", "requireSSL", false);
testAuthModeTransition("sendX509", "x509", "requireSSL", true);
testAuthModeTransition("x509", "invalid", "requireSSL", false);
testAuthModeTransition("x509", "keyFile", "requireSSL", false);
testAuthModeTransition("x509", "sendKeyFile", "requireSSL", false);
testAuthModeTransition("x509", "sendX509", "requireSSL", false);
testAuthModeTransition("x509", "x509", "requireSSL", false);
testAuthModeTransition("sendKeyFile", "invalid", "allowSSL", false);
testAuthModeTransition("sendKeyFile", "keyFile", "allowSSL", false);
testAuthModeTransition("sendKeyFile", "sendKeyFile", "allowSSL", false);
testAuthModeTransition("sendKeyFile", "sendX509", "allowSSL", false);
testAuthModeTransition("sendKeyFile", "x509", "allowSSL", false);