diff options
-rw-r--r-- | jstests/libs/client-self-signed.pem | 47 | ||||
-rw-r--r-- | jstests/ssl/x509_invalid.js | 61 | ||||
-rw-r--r-- | jstests/ssl/x509_startup_warning.js | 33 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/db.cpp | 18 | ||||
-rw-r--r-- | src/mongo/util/net/ssl_manager.cpp | 1 |
6 files changed, 164 insertions, 0 deletions
diff --git a/jstests/libs/client-self-signed.pem b/jstests/libs/client-self-signed.pem new file mode 100644 index 00000000000..27fbf225059 --- /dev/null +++ b/jstests/libs/client-self-signed.pem @@ -0,0 +1,47 @@ +-----BEGIN CERTIFICATE----- +MIIDXDCCAkQCCQCDkcJhHXlrtzANBgkqhkiG9w0BAQsFADBwMQ8wDQYDVQQDDAZj +bGllbnQxEzARBgNVBAsMCktlcm5lbFVzZXIxEDAOBgNVBAoMB01vbmdvREIxFjAU +BgNVBAcMDU5ldyBZb3JrIENpdHkxETAPBgNVBAgMCE5ldyBZb3JrMQswCQYDVQQG +EwJVUzAeFw0xODA1MDgxOTA2MTdaFw0yMDA3MTcxOTA2MTdaMHAxDzANBgNVBAMM +BmNsaWVudDETMBEGA1UECwwKS2VybmVsVXNlcjEQMA4GA1UECgwHTW9uZ29EQjEW +MBQGA1UEBwwNTmV3IFlvcmsgQ2l0eTERMA8GA1UECAwITmV3IFlvcmsxCzAJBgNV +BAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxIP1BCsp6e+B +5BpefH+yDvdVwDteI3H7CKh8X0TJYAYHAy5bOJ9fS0PB50gAXYqDFTHWTnGGxTaq +67d4Hc5ZB+UgnNralBvhVYB6jFpV4oBqdht//VhcdLBq8n6aRmM63zP82dKA5Ehz +q7jhwLI0v/m3lZfkE+qKWb+E87KS47BstOHDIqAUIeUJutrC/usS7aatRhHqtmg2 +8pEVJV8/YBPL4DWZkKoqrg+hJjXNjpy7ec2GAvgk+5ZWvjmNUBTtrE+47l8Eq3nM +TLsTDqtPHqv/udZScaCltPkw2ffGMhhp/eFLF+F3E9NpZC5mpUfe4+E5iZAXL9/r +IRO4ESbI9wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQB4DscFT2z5hgzHC64SVjHk +Rpodjct0/kLkcJpaAZ/VTU6J6JI0TRDI0lsYV+UlogPxNWHgo7OGmG26tUPh61TX +XCq0Y1SbUsJFJa61d4fl30cBsA/w+eN1GRMua+eo1DTeFC8n0bVUqCjaMzumZWnX +bOR5eUUGw2r/JbCvCU2QNuL6/LKg2e2/C6pwkxQzFpKVTgvc0mq9+rifAIo0a9JV +41FIpgbJrojXCjP1gs2On3Uvr0XJsiMd9+T6duZt5MNh4M3Mfrr+tzATM61JM0Mg +VryKakzERFMLnTH3aS/JfTMGlCvUJEiMU2N9mePmSucNnJHX6wYjmOr++6RoLBhc +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxIP1BCsp6e+B5BpefH+yDvdVwDteI3H7CKh8X0TJYAYHAy5b +OJ9fS0PB50gAXYqDFTHWTnGGxTaq67d4Hc5ZB+UgnNralBvhVYB6jFpV4oBqdht/ +/VhcdLBq8n6aRmM63zP82dKA5Ehzq7jhwLI0v/m3lZfkE+qKWb+E87KS47BstOHD +IqAUIeUJutrC/usS7aatRhHqtmg28pEVJV8/YBPL4DWZkKoqrg+hJjXNjpy7ec2G +Avgk+5ZWvjmNUBTtrE+47l8Eq3nMTLsTDqtPHqv/udZScaCltPkw2ffGMhhp/eFL +F+F3E9NpZC5mpUfe4+E5iZAXL9/rIRO4ESbI9wIDAQABAoIBAEV/SUJNJYiG3E/Y +B3xOCKGEVP4jwLoWUCoSs9FZWUItP4OffEE9E41hjAyICSELoCn5swmQ2pGaML4l +50PbOt8w5+Sw/UYNyhXb1vsV43Oz6HKWbSAihKf70AasQVENPL+8+fnqmQyils2v +F593JnKSFJvB2LY2ZvEwawtoJsyAdENw+NacVnEoMbaJqn0x0XsFb0RAvV9PQaFD +U29yg3T3TxnoDHxmnPaLUhn4ht7bOc66PjeJEl2jvnhNdSwPND9dg+hF/hX966Io +vNfKyp5q5nr6dnshjMWciyAu3v0FhaQ+7MTG2pij1yR1L1XM/gxL7u65bCCw3D2d +BEiiB2ECgYEA7HoiLTImR2IN3QSkKi/j6YzLIhpZgfl1XW3P2EKXcbToghDsbZtV +81ZtPwX5R5gCSKR7c05hPOgio2ext71jomRQYDHHTFu2gbKyk0iC3fhY7u44ugRQ +KOMqQE2WZUV4Ll9QOflMoSWypDmSzgG5hYF86dSW1Leuoo8nDUnvcocCgYEA1L0/ +YNZoF+h4OsO3t7zJ38X6vmn7vwkWwlFC8puaseUmL0ENWGZxtBZzuzcVHWzSTxzk ++lpKNUloXeEE39btVWonDUx4uPajHsXE3i8/jjgOxden36cGxXxV1yWaSGTC7ikM +TPSzhtyMxlsmG7cXgIELCiWF0H2Mt+RGwTnz4hECgYEApQD/keu5O/vWUo7ngaxS +6mbcYppiNEf9Ncjmyy6D/8pMplzqq/xEd/upVN11OBiAF3H11douDVKowL4dCmky ++V/nmYeCWexwp4UqB40EC6A7ZdSBboKN8Em59I5uz5Eur6TAFQO4DYWBZgfqQKaB +bf+RSpOU/y5/w1wB0srxMkcCgYEAyq36geIDjjOWyDXLBKxCkIVoXJ1QkTKxkjQl +WkpRWYb9mCub8Uq4rWBupkDWRxB0VZcruDDpXlcvrbFCGZgEyUm3Jv5iTaX8xsaY +xy2wmWhi+q55a6UP2Hqatb1Hfg0xggFtjKvdlnDtVdVlOyZ2p6FJyULyeC4FMPW1 +S0ZRSmECgYEAyjTgEjvIUsd4NkVdMcBBHO/WKl7gMQDcUGOnlrpyEPumXC1+H2jy +GWbnBoWyXJ+SrMP3MFpCEG7BZ7P5oFjLDBJ8+xUiHWPLLGRRhp2tyySeR/urjgRO +kLX6W+WWErw2V5+KmgEJb/SpbAGcJhDyLCN56L/Osqrod9avQ4/YW60= +-----END RSA PRIVATE KEY----- diff --git a/jstests/ssl/x509_invalid.js b/jstests/ssl/x509_invalid.js new file mode 100644 index 00000000000..39605fa307c --- /dev/null +++ b/jstests/ssl/x509_invalid.js @@ -0,0 +1,61 @@ +// Test X509 auth when --sslAllowInvalidCertificates is enabled + +(function() { + 'use strict'; + + const CLIENT_NAME = 'C=US,ST=New York,L=New York City,O=MongoDB,OU=KernelUser,CN=client'; + const CLIENT_CERT = 'jstests/libs/client.pem'; + const SERVER_CERT = 'jstests/libs/server.pem'; + const CA_CERT = 'jstests/libs/ca.pem'; + const SELF_SIGNED_CERT = 'jstests/libs/client-self-signed.pem'; + + function testClient(conn, cert, name, shouldSucceed) { + let auth = {mechanism: 'MONGODB-X509'}; + if (name !== null) { + auth.name = name; + } + const script = 'assert(db.getSiblingDB(\'$external\').auth(' + tojson(auth) + '));'; + clearRawMongoProgramOutput(); + const exitCode = runMongoProgram('mongo', + '--ssl', + '--sslAllowInvalidHostnames', + '--sslPEMKeyFile', + cert, + '--sslCAFile', + CA_CERT, + '--port', + conn.port, + '--eval', + script); + + assert.eq(shouldSucceed, exitCode === 0, "exitCode = " + tojson(exitCode)); + assert.eq( + !shouldSucceed, + rawMongoProgramOutput().includes('No verified subject name available from client')); + } + + function runTest(conn) { + const admin = conn.getDB('admin'); + admin.createUser({user: "admin", pwd: "admin", roles: ["root"]}); + admin.auth('admin', 'admin'); + + const external = conn.getDB('$external'); + external.createUser({user: CLIENT_NAME, roles: [{'role': 'readWrite', 'db': 'test'}]}); + + testClient(conn, CLIENT_CERT, CLIENT_NAME, true); + testClient(conn, SELF_SIGNED_CERT, CLIENT_NAME, false); + testClient(conn, CLIENT_CERT, null, true); + testClient(conn, SELF_SIGNED_CERT, null, false); + } + + // Standalone. + const mongod = MongoRunner.runMongod({ + auth: '', + sslMode: 'requireSSL', + sslPEMKeyFile: SERVER_CERT, + sslCAFile: CA_CERT, + sslAllowInvalidCertificates: '', + }); + runTest(mongod); + MongoRunner.stopMongod(mongod); +})(); diff --git a/jstests/ssl/x509_startup_warning.js b/jstests/ssl/x509_startup_warning.js new file mode 100644 index 00000000000..888e29255e3 --- /dev/null +++ b/jstests/ssl/x509_startup_warning.js @@ -0,0 +1,33 @@ +// Test for startuo warning when X509 auth and sslAllowInvalidCertificates are enabled + +(function() { + 'use strict'; + + function runTest(opts, expectWarning) { + clearRawMongoProgramOutput(); + const mongod = MongoRunner.runMongod(Object.assign({ + auth: '', + sslMode: 'requireSSL', + sslPEMKeyFile: 'jstests/libs/server.pem', + sslCAFile: 'jstests/libs/ca.pem', + }, + opts)); + assert.eq(expectWarning, + rawMongoProgramOutput().includes( + 'WARNING: While invalid X509 certificates may be used')); + MongoRunner.stopMongod(mongod); + } + + // Don't expect a warning when we're not using both options together. + runTest({}, false); + runTest({sslAllowInvalidCertificates: '', setParameter: 'authenticationMechanisms=SCRAM-SHA-1'}, + false); + runTest({setParameter: 'authenticationMechanisms=MONGODB-X509'}, false); + runTest({clusterAuthMode: 'x509'}, false); + + // Do expect a warning when we're combining options. + runTest( + {sslAllowInvalidCertificates: '', setParameter: 'authenticationMechanisms=MONGODB-X509'}, + true); + runTest({sslAllowInvalidCertificates: '', clusterAuthMode: 'x509'}, true); +})(); diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index f6fcc301b05..1eb8569b2be 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -174,6 +174,7 @@ bool CmdAuthenticate::run(OperationContext* txn, } else { user = UserName(cmdObj.getStringField("user"), dbname); } + uassert(ErrorCodes::AuthenticationFailed, "No user name provided", !user.getUser().empty()); if (Command::testCommandsEnabled && user.getDB() == "admin" && user.getUser() == internalSecurity.user->getName().getUser()) { @@ -323,6 +324,9 @@ Status CmdAuthenticate::_authenticateX509(OperationContext* txn, Client* client = Client::getCurrent(); AuthorizationSession* authorizationSession = AuthorizationSession::get(client); auto clientName = client->session()->getX509PeerInfo().subjectName; + uassert(ErrorCodes::AuthenticationFailed, + "No verified subject name available from client", + !clientName.empty()); if (!getSSLManager()->getSSLConfiguration().hasCA) { return Status(ErrorCodes::AuthenticationFailed, diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index c6272425bf5..a99ce97d57c 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -48,6 +48,7 @@ #include "mongo/db/auth/auth_index_d.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_manager_global.h" +#include "mongo/db/auth/sasl_options.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_catalog_entry.h" #include "mongo/db/catalog/database.h" @@ -136,6 +137,7 @@ #include "mongo/util/quick_exit.h" #include "mongo/util/ramlog.h" #include "mongo/util/scopeguard.h" +#include "mongo/util/sequence_util.h" #include "mongo/util/signal_handlers.h" #include "mongo/util/stacktrace.h" #include "mongo/util/startup_test.h" @@ -144,6 +146,10 @@ #include "mongo/util/time_support.h" #include "mongo/util/version.h" +#ifdef MONGO_CONFIG_SSL +#include "mongo/util/net/ssl_options.h" +#endif + #if !defined(_WIN32) #include <sys/file.h> #endif @@ -641,6 +647,18 @@ ExitCode _initAndListen(int listenPort) { logMongodStartupWarnings(storageGlobalParams, serverGlobalParams); +#if MONGO_CONFIG_SSL + if (sslGlobalParams.sslAllowInvalidCertificates && + ((serverGlobalParams.clusterAuthMode.load() == ServerGlobalParams::ClusterAuthMode_x509) || + sequenceContains(saslGlobalParams.authenticationMechanisms, "MONGODB-X509"))) { + log() << "** WARNING: While invalid X509 certificates may be used to" << startupWarningsLog; + log() << "** connect to this server, they will not be considered" + << startupWarningsLog; + log() << "** permissible for authentication." << startupWarningsLog; + log() << startupWarningsLog; + } +#endif + { stringstream ss; ss << endl; diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp index 025f4932867..1b120a3be83 100644 --- a/src/mongo/util/net/ssl_manager.cpp +++ b/src/mongo/util/net/ssl_manager.cpp @@ -1235,6 +1235,7 @@ StatusWith<boost::optional<SSLPeerInfo>> SSLManager::parseAndValidatePeerCertifi if (_allowInvalidCertificates) { warning() << "SSL peer certificate validation failed: " << X509_verify_cert_error_string(result); + return {boost::none}; } else { str::stream msg; msg << "SSL peer certificate validation failed: " |