diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2017-12-08 18:54:23 -0500 |
---|---|---|
committer | Sara Golemon <sara.golemon@mongodb.com> | 2017-12-18 23:11:00 -0500 |
commit | a0c66e6e12e445d2253e85a9bb36a6fc24d77cdb (patch) | |
tree | 90ab8f5cb136796abd21f9a464b926ac7a0b9997 | |
parent | 01c39d416435f930d249701ccb71744b519873b5 (diff) | |
download | mongo-a0c66e6e12e445d2253e85a9bb36a6fc24d77cdb.tar.gz |
SERVER-32279 Remove support for authenticating via MONGODB-CR
-rw-r--r-- | jstests/auth/auth-fail-client-addr.js | 15 | ||||
-rw-r--r-- | jstests/auth/auth_helpers.js | 5 | ||||
-rw-r--r-- | src/mongo/db/auth/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/auth/authentication_session.h | 3 | ||||
-rw-r--r-- | src/mongo/db/auth/mongo_authentication_session.cpp | 37 | ||||
-rw-r--r-- | src/mongo/db/auth/mongo_authentication_session.h | 57 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_commands.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_options.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/commands/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 178 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.h | 1 | ||||
-rw-r--r-- | src/mongo/shell/db.js | 5 | ||||
-rw-r--r-- | src/mongo/shell/utils.js | 2 |
13 files changed, 41 insertions, 279 deletions
diff --git a/jstests/auth/auth-fail-client-addr.js b/jstests/auth/auth-fail-client-addr.js deleted file mode 100644 index 426821545bc..00000000000 --- a/jstests/auth/auth-fail-client-addr.js +++ /dev/null @@ -1,15 +0,0 @@ -// Verify that client IP address is included in MONGODB-CR auth failure response - -function runTest(m) { - db = m.getDB("test"); - db.auth({user: "root", pwd: "periwinkle", mechanism: "MONGODB-CR"}); - - assert.soon(function() { - var log = cat(m.fullOptions.logFile); - return /Failed to authenticate root@test from client 127\.0\.0\.1:\d+/.test(log); - }, "Authentication failure message not encountered or missing client IP", 30 * 1000, 5 * 1000); -} - -print("START auth-fail-client-addr.js"); -runTest(MongoRunner.runMongod({useHostname: false, useLogFiles: true})); -print("SUCCESS auth-fail-client-addr.js"); diff --git a/jstests/auth/auth_helpers.js b/jstests/auth/auth_helpers.js index fd2775cc463..dc2bd3d1a95 100644 --- a/jstests/auth/auth_helpers.js +++ b/jstests/auth/auth_helpers.js @@ -6,9 +6,6 @@ const conn = MongoRunner.runMongod({smallfiles: ""}); const admin = conn.getDB('admin'); - // In order to test MONGODB-CR we need to "reset" the authSchemaVersion to - // 26Final "3" or else the user won't get MONGODB-CR credentials. - admin.system.version.save({"_id": "authSchema", "currentVersion": 3}); admin.createUser({user: 'andy', pwd: 'a', roles: jsTest.adminUserRoles}); assert(admin.auth({user: 'andy', pwd: 'a'})); assert(admin.logout()); @@ -20,8 +17,6 @@ assert(admin.logout()); assert(admin.auth({mechanism: 'SCRAM-SHA-1', user: 'andy', pwd: 'a'})); assert(admin.logout()); - assert(admin.auth({mechanism: 'MONGODB-CR', user: 'andy', pwd: 'a'})); - assert(admin.logout()); // Invalid mechanisms shouldn't lead to authentication, but also shouldn't crash. assert(!admin.auth({mechanism: 'this-mechanism-is-fake', user: 'andy', pwd: 'a'})); diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index f70297efbf3..5e18c13d4b1 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -4,8 +4,6 @@ Import("env") env = env.Clone() -env.Library('serverauth', ['mongo_authentication_session.cpp']) - generateActionTypes = env.Command( target=['action_type.h', 'action_type.cpp'], source=['generate_action_types.py', 'action_types.txt'], diff --git a/src/mongo/db/auth/authentication_session.h b/src/mongo/db/auth/authentication_session.h index 52ee521e298..ed7404dc58d 100644 --- a/src/mongo/db/auth/authentication_session.h +++ b/src/mongo/db/auth/authentication_session.h @@ -45,8 +45,7 @@ class AuthenticationSession { public: enum SessionType { - SESSION_TYPE_MONGO, // The mongo-specific challenge-response authentication mechanism. - SESSION_TYPE_SASL // SASL authentication mechanism. + SESSION_TYPE_SASL // SASL authentication mechanism. }; /** diff --git a/src/mongo/db/auth/mongo_authentication_session.cpp b/src/mongo/db/auth/mongo_authentication_session.cpp deleted file mode 100644 index 2e25b4f561c..00000000000 --- a/src/mongo/db/auth/mongo_authentication_session.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 2012 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#include "mongo/db/auth/mongo_authentication_session.h" - -namespace mongo { - -MongoAuthenticationSession::MongoAuthenticationSession(nonce64 nonce) - : AuthenticationSession(AuthenticationSession::SESSION_TYPE_MONGO), _nonce(nonce) {} - -MongoAuthenticationSession::~MongoAuthenticationSession() {} - -} // namespace mongo diff --git a/src/mongo/db/auth/mongo_authentication_session.h b/src/mongo/db/auth/mongo_authentication_session.h deleted file mode 100644 index e60bcf6ac85..00000000000 --- a/src/mongo/db/auth/mongo_authentication_session.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright 2012 10gen Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ - -#pragma once - -#include "mongo/db/auth/authentication_session.h" - -namespace mongo { - -typedef unsigned long long nonce64; - -/** - * Authentication session data for a nonce-challenge-response authentication of the - * type used in the Mongo nonce-authenticate protocol. - * - * The only session data is the nonce sent to the client. - */ -class MongoAuthenticationSession : public AuthenticationSession { - MONGO_DISALLOW_COPYING(MongoAuthenticationSession); - -public: - explicit MongoAuthenticationSession(nonce64 nonce); - virtual ~MongoAuthenticationSession(); - - nonce64 getNonce() const { - return _nonce; - } - -private: - const nonce64 _nonce; -}; - -} // namespace mongo diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp index f489e3792c6..bd4e4e04c5f 100644 --- a/src/mongo/db/auth/sasl_commands.cpp +++ b/src/mongo/db/auth/sasl_commands.cpp @@ -42,7 +42,6 @@ #include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/authz_manager_external_state_mock.h" #include "mongo/db/auth/authz_session_external_state_mock.h" -#include "mongo/db/auth/mongo_authentication_session.h" #include "mongo/db/auth/sasl_authentication_session.h" #include "mongo/db/auth/sasl_options.h" #include "mongo/db/client.h" @@ -351,19 +350,9 @@ bool CmdSaslContinue::run(OperationContext* opCtx, // The CyrusSaslCommands Enterprise initializer is dependent on PreSaslCommands MONGO_INITIALIZER_WITH_PREREQUISITES(PreSaslCommands, ("NativeSaslServerCore")) (InitializerContext*) { - if (!sequenceContains(saslGlobalParams.authenticationMechanisms, "MONGODB-CR")) - CmdAuthenticate::disableAuthMechanism("MONGODB-CR"); - if (!sequenceContains(saslGlobalParams.authenticationMechanisms, "MONGODB-X509")) CmdAuthenticate::disableAuthMechanism("MONGODB-X509"); - // For backwards compatibility, in 3.0 we are letting MONGODB-CR imply general - // challenge-response auth and hence SCRAM-SHA-1 is enabled by either specifying - // SCRAM-SHA-1 or MONGODB-CR in the authenticationMechanism server parameter. - if (!sequenceContains(saslGlobalParams.authenticationMechanisms, "SCRAM-SHA-1") && - sequenceContains(saslGlobalParams.authenticationMechanisms, "MONGODB-CR")) - saslGlobalParams.authenticationMechanisms.push_back("SCRAM-SHA-1"); - return Status::OK(); } diff --git a/src/mongo/db/auth/sasl_options.cpp b/src/mongo/db/auth/sasl_options.cpp index 278d1037ca9..a2a1296e057 100644 --- a/src/mongo/db/auth/sasl_options.cpp +++ b/src/mongo/db/auth/sasl_options.cpp @@ -46,7 +46,6 @@ const int minimumScramIterationCount = 5000; SASLGlobalParams::SASLGlobalParams() { // Authentication mechanisms supported by default. - authenticationMechanisms.push_back("MONGODB-CR"); authenticationMechanisms.push_back("MONGODB-X509"); authenticationMechanisms.push_back("SCRAM-SHA-1"); @@ -65,7 +64,7 @@ Status addSASLOptions(moe::OptionSection* options) { "", moe::StringVector, "List of supported authentication mechanisms. " - "Default is MONGODB-CR, SCRAM-SHA-1 and MONGODB-X509.") + "Default is SCRAM-SHA-1 and MONGODB-X509.") .setSources(moe::SourceYAMLConfig); saslOptions diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript index be6e31bbda2..2535f8e05cd 100644 --- a/src/mongo/db/commands/SConscript +++ b/src/mongo/db/commands/SConscript @@ -82,7 +82,6 @@ env.Library( '$BUILD_DIR/mongo/db/audit', '$BUILD_DIR/mongo/db/auth/authcommon', '$BUILD_DIR/mongo/db/auth/authorization_manager_global', - '$BUILD_DIR/mongo/db/auth/serverauth', '$BUILD_DIR/mongo/db/commands', '$BUILD_DIR/mongo/db/commands/test_commands_enabled', '$BUILD_DIR/mongo/db/common', diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index c5229b8daa3..244244c3a3f 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -41,26 +41,18 @@ #include "mongo/client/sasl_client_authenticate.h" #include "mongo/config.h" #include "mongo/db/audit.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" -#include "mongo/db/auth/authorization_manager_global.h" #include "mongo/db/auth/authorization_session.h" -#include "mongo/db/auth/mongo_authentication_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/auth/sasl_options.h" #include "mongo/db/auth/security_key.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" -#include "mongo/db/jsobj.h" #include "mongo/db/operation_context.h" -#include "mongo/db/server_options.h" #include "mongo/platform/random.h" #include "mongo/stdx/memory.h" #include "mongo/transport/session.h" #include "mongo/util/concurrency/mutex.h" #include "mongo/util/log.h" -#include "mongo/util/md5.hpp" #include "mongo/util/net/ssl_manager.h" #include "mongo/util/text.h" @@ -70,64 +62,73 @@ using std::hex; using std::string; using std::stringstream; -static bool _isCRAuthDisabled; static bool _isX509AuthDisabled; static const char _nonceAuthenticationDisabledMessage[] = "Challenge-response authentication using getnonce and authenticate commands is disabled."; static const char _x509AuthenticationDisabledMessage[] = "x.509 authentication is disabled."; void CmdAuthenticate::disableAuthMechanism(std::string authMechanism) { - if (authMechanism == "MONGODB-CR") { - _isCRAuthDisabled = true; - } if (authMechanism == "MONGODB-X509") { _isX509AuthDisabled = true; } } -/* authentication - - system.users contains - { user : <username>, pwd : <pwd_digest>, ... } - - getnonce sends nonce to client - - client then sends { authenticate:1, nonce64:<nonce_str>, user:<username>, key:<key> } - - where <key> is md5(<nonce_str><username><pwd_digest_str>) as a string -*/ - +/** + * Returns a random 64-bit nonce. + * + * Previously, this command would have been called prior to {authenticate: ...} + * when using the MONGODB-CR authentication mechanism. + * Since that mechanism has been removed from MongoDB 3.8, + * it is nominally no longer required. + * + * Unfortunately, mongo-tools uses a connection library + * which optimistically invokes {getnonce: 1} upon connection + * under the assumption that it will eventually be used as part + * of "classic" authentication. + * If the command dissapeared, then all of mongo-tools would + * fail to connect, despite using SCRAM-SHA-1 or another valid + * auth mechanism. Thus, we have to keep this command around for now. + * + * Note that despite nonces being available, they are not bound + * to the AuthorizationSession anymore, and the authenticate + * command doesn't acknowledge their existence. + */ class CmdGetNonce : public BasicCommand { public: CmdGetNonce() : BasicCommand("getnonce"), _random(SecureRandom::create()) {} - virtual bool slaveOk() const { + bool slaveOk() const final { return true; } - void help(stringstream& h) const { + + void help(stringstream& h) const final { h << "internal"; } - virtual bool supportsWriteConcern(const BSONObj& cmd) const override { + + bool supportsWriteConcern(const BSONObj& cmd) const final { return false; } - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) {} // No auth required + + void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) final { + // No auth required since this command was explicitly part + // of an authentication workflow. + } + bool run(OperationContext* opCtx, const string&, const BSONObj& cmdObj, - BSONObjBuilder& result) { - nonce64 n = getNextNonce(); + BSONObjBuilder& result) final { + auto n = getNextNonce(); stringstream ss; ss << hex << n; result.append("nonce", ss.str()); - AuthenticationSession::set(Client::getCurrent(), - stdx::make_unique<MongoAuthenticationSession>(n)); return true; } private: - nonce64 getNextNonce() { + int64_t getNextNonce() { stdx::lock_guard<SimpleMutex> lk(_randMutex); return _random->nextInt64(); } @@ -136,31 +137,18 @@ private: std::unique_ptr<SecureRandom> _random; } cmdGetNonce; -void CmdAuthenticate::redactForLogging(mutablebson::Document* cmdObj) { - namespace mmb = mutablebson; - static const int numRedactedFields = 2; - static const char* redactedFields[numRedactedFields] = {"key", "nonce"}; - for (int i = 0; i < numRedactedFields; ++i) { - for (mmb::Element element = mmb::findFirstChildNamed(cmdObj->root(), redactedFields[i]); - element.ok(); - element = mmb::findElementNamed(element.rightSibling(), redactedFields[i])) { - element.setValueString("xxx").transitional_ignore(); - } - } -} - bool CmdAuthenticate::run(OperationContext* opCtx, const string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { if (!serverGlobalParams.quiet.load()) { mutablebson::Document cmdToLog(cmdObj, mutablebson::Document::kInPlaceDisabled); - redactForLogging(&cmdToLog); log() << " authenticate db: " << dbname << " " << cmdToLog; } std::string mechanism = cmdObj.getStringField("mechanism"); if (mechanism.empty()) { - mechanism = "MONGODB-CR"; + appendCommandStatus(result, {ErrorCodes::BadValue, "Auth mechanism not specified"}); + return false; } UserName user; auto& sslPeerInfo = SSLPeerInfo::forSession(opCtx->getClient()->session()); @@ -206,9 +194,6 @@ Status CmdAuthenticate::_authenticate(OperationContext* opCtx, const std::string& mechanism, const UserName& user, const BSONObj& cmdObj) { - if (mechanism == "MONGODB-CR") { - return _authenticateCR(opCtx, user, cmdObj); - } #ifdef MONGO_CONFIG_SSL if (mechanism == "MONGODB-X509") { return _authenticateX509(opCtx, user, cmdObj); @@ -217,93 +202,6 @@ Status CmdAuthenticate::_authenticate(OperationContext* opCtx, return Status(ErrorCodes::BadValue, "Unsupported mechanism: " + mechanism); } -Status CmdAuthenticate::_authenticateCR(OperationContext* opCtx, - const UserName& user, - const BSONObj& cmdObj) { - if (user == internalSecurity.user->getName() && - serverGlobalParams.clusterAuthMode.load() == ServerGlobalParams::ClusterAuthMode_x509) { - return Status(ErrorCodes::AuthenticationFailed, - "Mechanism x509 is required for internal cluster authentication"); - } - - if (_isCRAuthDisabled) { - // SERVER-8461, MONGODB-CR must be enabled for authenticating the internal user, so that - // cluster members may communicate with each other. - if (user != internalSecurity.user->getName()) { - return Status(ErrorCodes::BadValue, _nonceAuthenticationDisabledMessage); - } - } - - string key = cmdObj.getStringField("key"); - string received_nonce = cmdObj.getStringField("nonce"); - - if (user.getUser().empty() || key.empty() || received_nonce.empty()) { - sleepmillis(10); - return Status(ErrorCodes::ProtocolError, - "field missing/wrong type in received authenticate command"); - } - - stringstream digestBuilder; - - { - Client* client = Client::getCurrent(); - std::unique_ptr<AuthenticationSession> session; - AuthenticationSession::swap(client, session); - if (!session || session->getType() != AuthenticationSession::SESSION_TYPE_MONGO) { - sleepmillis(30); - return Status(ErrorCodes::ProtocolError, "No pending nonce"); - } else { - nonce64 nonce = static_cast<MongoAuthenticationSession*>(session.get())->getNonce(); - digestBuilder << hex << nonce; - if (digestBuilder.str() != received_nonce) { - sleepmillis(30); - return Status(ErrorCodes::AuthenticationFailed, "Received wrong nonce."); - } - } - } - - User* userObj; - Status status = getGlobalAuthorizationManager()->acquireUser(opCtx, user, &userObj); - if (!status.isOK()) { - // Failure to find the privilege document indicates no-such-user, a fact that we do not - // wish to reveal to the client. So, we return AuthenticationFailed rather than passing - // through the returned status. - return Status(ErrorCodes::AuthenticationFailed, status.toString()); - } - string pwd = userObj->getCredentials().password; - getGlobalAuthorizationManager()->releaseUser(userObj); - - if (pwd.empty()) { - return Status(ErrorCodes::AuthenticationFailed, - "MONGODB-CR credentials missing in the user document"); - } - - md5digest d; - { - digestBuilder << user.getUser() << pwd; - string done = digestBuilder.str(); - - md5_state_t st; - md5_init(&st); - md5_append(&st, (const md5_byte_t*)done.c_str(), done.size()); - md5_finish(&st, d); - } - - string computed = digestToString(d); - - if (key != computed) { - return Status(ErrorCodes::AuthenticationFailed, "key mismatch"); - } - - AuthorizationSession* authorizationSession = AuthorizationSession::get(Client::getCurrent()); - status = authorizationSession->addAndAuthorizeUser(opCtx, user); - if (!status.isOK()) { - return status; - } - - return Status::OK(); -} - #ifdef MONGO_CONFIG_SSL Status CmdAuthenticate::_authenticateX509(OperationContext* opCtx, const UserName& user, diff --git a/src/mongo/db/commands/authentication_commands.h b/src/mongo/db/commands/authentication_commands.h index bbb837e4015..c40d8a3d4d1 100644 --- a/src/mongo/db/commands/authentication_commands.h +++ b/src/mongo/db/commands/authentication_commands.h @@ -52,7 +52,6 @@ public: virtual void addRequiredPrivileges(const std::string& dbname, const BSONObj& cmdObj, std::vector<Privilege>* out) {} // No auth required - virtual void redactForLogging(mutablebson::Document* cmdObj); CmdAuthenticate() : BasicCommand("authenticate") {} bool run(OperationContext* opCtx, diff --git a/src/mongo/shell/db.js b/src/mongo/shell/db.js index 799d1a1e348..e99f5046df2 100644 --- a/src/mongo/shell/db.js +++ b/src/mongo/shell/db.js @@ -1568,11 +1568,6 @@ var DB; if (this._defaultAuthenticationMechanism != null) return this._defaultAuthenticationMechanism; - // Use MONGODB-CR for v2.6 and earlier. - maxWireVersion = this.isMaster().maxWireVersion; - if (maxWireVersion == undefined || maxWireVersion < 3) { - return "MONGODB-CR"; - } return "SCRAM-SHA-1"; }; diff --git a/src/mongo/shell/utils.js b/src/mongo/shell/utils.js index f7ec71ed8b6..6b7252888cd 100644 --- a/src/mongo/shell/utils.js +++ b/src/mongo/shell/utils.js @@ -299,7 +299,7 @@ jsTest.authenticate = function(conn) { // back into authenticate. conn.authenticated = true; print("Authenticating as user " + jsTestOptions().authUser + " with mechanism " + - DB.prototype._defaultAuthenticationMechanism + " on connection: " + conn); + DB.prototype._getDefaultAuthenticationMechanism() + " on connection: " + conn); conn.authenticated = conn.getDB(jsTestOptions().authenticationDatabase).auth({ user: jsTestOptions().authUser, pwd: jsTestOptions().authPassword, |