diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2018-04-26 13:12:35 -0400 |
---|---|---|
committer | Billy Donahue <billy.donahue@mongodb.com> | 2018-04-27 11:22:20 -0400 |
commit | ac1e34979ac20b9bb722449ed888a679a62b1252 (patch) | |
tree | f2b21aca43429af00433695f636c1e21f69c3eaa | |
parent | 580d395d40e935adb8453ba7420cdc28e6f601a1 (diff) | |
download | mongo-ac1e34979ac20b9bb722449ed888a679a62b1252.tar.gz |
SERVER-34698 cleanup physical structure of CmdAuthenticate
-rw-r--r-- | src/mongo/db/auth/sasl_commands.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 172 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.h | 52 |
3 files changed, 111 insertions, 117 deletions
diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp index ef9bcc68285..fdf625b4979 100644 --- a/src/mongo/db/auth/sasl_commands.cpp +++ b/src/mongo/db/auth/sasl_commands.cpp @@ -352,8 +352,8 @@ bool CmdSaslContinue::run(OperationContext* opCtx, // The CyrusSaslCommands Enterprise initializer is dependent on PreSaslCommands MONGO_INITIALIZER(PreSaslCommands) (InitializerContext*) { - if (!sequenceContains(saslGlobalParams.authenticationMechanisms, "MONGODB-X509")) - CmdAuthenticate::disableAuthMechanism("MONGODB-X509"); + if (!sequenceContains(saslGlobalParams.authenticationMechanisms, kX509AuthMechanism)) + disableAuthMechanism(kX509AuthMechanism); return Status::OK(); } diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index f701d2f760b..189416ee125 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -45,6 +45,7 @@ #include "mongo/db/auth/privilege.h" #include "mongo/db/auth/sasl_options.h" #include "mongo/db/auth/security_key.h" +#include "mongo/db/auth/user_name.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/commands/test_commands_enabled.h" @@ -59,21 +60,102 @@ #include "mongo/util/text.h" namespace mongo { - -using std::hex; -using std::string; -using std::stringstream; +namespace { 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-X509") { - _isX509AuthDisabled = true; +#ifdef MONGO_CONFIG_SSL +Status _authenticateX509(OperationContext* opCtx, const UserName& user, const BSONObj& cmdObj) { + if (!getSSLManager()) { + return Status(ErrorCodes::ProtocolError, + "SSL support is required for the MONGODB-X509 mechanism."); + } + if (user.getDB() != "$external") { + return Status(ErrorCodes::ProtocolError, + "X.509 authentication must always use the $external database."); + } + + Client* client = Client::getCurrent(); + AuthorizationSession* authorizationSession = AuthorizationSession::get(client); + auto clientName = SSLPeerInfo::forSession(client->session()).subjectName; + + if (!getSSLManager()->getSSLConfiguration().hasCA) { + return Status(ErrorCodes::AuthenticationFailed, + "Unable to verify x.509 certificate, as no CA has been provided."); + } else if (user.getUser() != clientName) { + return Status(ErrorCodes::AuthenticationFailed, + "There is no x.509 client certificate matching the user."); + } else { + // Handle internal cluster member auth, only applies to server-server connections + if (getSSLManager()->getSSLConfiguration().isClusterMember(clientName)) { + int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); + if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_undefined || + clusterAuthMode == ServerGlobalParams::ClusterAuthMode_keyFile) { + return Status(ErrorCodes::AuthenticationFailed, + "The provided certificate " + "can only be used for cluster authentication, not client " + "authentication. The current configuration does not allow " + "x.509 cluster authentication, check the --clusterAuthMode flag"); + } + authorizationSession->grantInternalAuthorization(); + } + // Handle normal client authentication, only applies to client-server connections + else { + if (_isX509AuthDisabled) { + return Status(ErrorCodes::BadValue, _x509AuthenticationDisabledMessage); + } + Status status = authorizationSession->addAndAuthorizeUser(opCtx, user); + if (!status.isOK()) { + return status; + } + } + return Status::OK(); } } +#endif // MONGO_CONFIG_SSL + +class CmdAuthenticate : public BasicCommand { +public: + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kAlways; + } + std::string help() const override { + return "internal"; + } + virtual bool supportsWriteConcern(const BSONObj& cmd) const override { + return false; + } + virtual void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) const {} // No auth required + + CmdAuthenticate() : BasicCommand("authenticate") {} + bool run(OperationContext* opCtx, + const std::string& dbname, + const BSONObj& cmdObj, + BSONObjBuilder& result); + +private: + /** + * Completes the authentication of "user" using "mechanism" and parameters from "cmdObj". + * + * Returns Status::OK() on success. All other statuses indicate failed authentication. The + * entire status returned here may always be used for logging. However, if the code is + * AuthenticationFailed, the "reason" field of the return status may contain information + * that should not be revealed to the connected client. + * + * Other than AuthenticationFailed, common returns are BadValue, indicating unsupported + * mechanism, and ProtocolError, indicating an error in the use of the authentication + * protocol. + */ + Status _authenticate(OperationContext* opCtx, + const std::string& mechanism, + const UserName& user, + const BSONObj& cmdObj); +} cmdAuthenticate; /** * Returns a random 64-bit nonce. @@ -119,12 +201,12 @@ public: } bool run(OperationContext* opCtx, - const string&, + const std::string&, const BSONObj& cmdObj, BSONObjBuilder& result) final { auto n = getNextNonce(); - stringstream ss; - ss << hex << n; + std::stringstream ss; + ss << std::hex << n; result.append("nonce", ss.str()); return true; } @@ -140,7 +222,7 @@ private: } cmdGetNonce; bool CmdAuthenticate::run(OperationContext* opCtx, - const string& dbname, + const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { if (!serverGlobalParams.quiet.load()) { @@ -155,7 +237,7 @@ bool CmdAuthenticate::run(OperationContext* opCtx, } UserName user; auto& sslPeerInfo = SSLPeerInfo::forSession(opCtx->getClient()->session()); - if (mechanism == "MONGODB-X509" && !cmdObj.hasField("user")) { + if (mechanism == kX509AuthMechanism && !cmdObj.hasField("user")) { user = UserName(sslPeerInfo.subjectName, dbname); } else { user = UserName(cmdObj.getStringField("user"), dbname); @@ -199,66 +281,13 @@ Status CmdAuthenticate::_authenticate(OperationContext* opCtx, const UserName& user, const BSONObj& cmdObj) { #ifdef MONGO_CONFIG_SSL - if (mechanism == "MONGODB-X509") { + if (mechanism == kX509AuthMechanism) { return _authenticateX509(opCtx, user, cmdObj); } #endif return Status(ErrorCodes::BadValue, "Unsupported mechanism: " + mechanism); } -#ifdef MONGO_CONFIG_SSL -Status CmdAuthenticate::_authenticateX509(OperationContext* opCtx, - const UserName& user, - const BSONObj& cmdObj) { - if (!getSSLManager()) { - return Status(ErrorCodes::ProtocolError, - "SSL support is required for the MONGODB-X509 mechanism."); - } - if (user.getDB() != "$external") { - return Status(ErrorCodes::ProtocolError, - "X.509 authentication must always use the $external database."); - } - - Client* client = Client::getCurrent(); - AuthorizationSession* authorizationSession = AuthorizationSession::get(client); - auto clientName = SSLPeerInfo::forSession(client->session()).subjectName; - - if (!getSSLManager()->getSSLConfiguration().hasCA) { - return Status(ErrorCodes::AuthenticationFailed, - "Unable to verify x.509 certificate, as no CA has been provided."); - } else if (user.getUser() != clientName) { - return Status(ErrorCodes::AuthenticationFailed, - "There is no x.509 client certificate matching the user."); - } else { - // Handle internal cluster member auth, only applies to server-server connections - if (getSSLManager()->getSSLConfiguration().isClusterMember(clientName)) { - int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); - if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_undefined || - clusterAuthMode == ServerGlobalParams::ClusterAuthMode_keyFile) { - return Status(ErrorCodes::AuthenticationFailed, - "The provided certificate " - "can only be used for cluster authentication, not client " - "authentication. The current configuration does not allow " - "x.509 cluster authentication, check the --clusterAuthMode flag"); - } - authorizationSession->grantInternalAuthorization(); - } - // Handle normal client authentication, only applies to client-server connections - else { - if (_isX509AuthDisabled) { - return Status(ErrorCodes::BadValue, _x509AuthenticationDisabledMessage); - } - Status status = authorizationSession->addAndAuthorizeUser(opCtx, user); - if (!status.isOK()) { - return status; - } - } - return Status::OK(); - } -} -#endif -CmdAuthenticate cmdAuthenticate; - class CmdLogout : public BasicCommand { public: AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { @@ -275,7 +304,7 @@ public: } CmdLogout() : BasicCommand("logout") {} bool run(OperationContext* opCtx, - const string& dbname, + const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) { AuthorizationSession* authSession = AuthorizationSession::get(Client::getCurrent()); @@ -291,4 +320,13 @@ public: return true; } } cmdLogout; + +} // namespace + +void disableAuthMechanism(StringData authMechanism) { + if (authMechanism == kX509AuthMechanism) { + _isX509AuthDisabled = true; + } } + +} // namespace mongo diff --git a/src/mongo/db/commands/authentication_commands.h b/src/mongo/db/commands/authentication_commands.h index c2c74665eeb..bbac9e94d50 100644 --- a/src/mongo/db/commands/authentication_commands.h +++ b/src/mongo/db/commands/authentication_commands.h @@ -28,56 +28,12 @@ #pragma once -#include <string> - -#include "mongo/base/status.h" -#include "mongo/db/auth/user_name.h" -#include "mongo/db/commands.h" +#include "mongo/base/string_data.h" namespace mongo { -class CmdAuthenticate : public BasicCommand { -public: - static void disableAuthMechanism(std::string authMechanism); - - AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { - return AllowedOnSecondary::kAlways; - } - std::string help() const override { - return "internal"; - } - virtual bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const {} // No auth required - - CmdAuthenticate() : BasicCommand("authenticate") {} - bool run(OperationContext* opCtx, - const std::string& dbname, - const BSONObj& cmdObj, - BSONObjBuilder& result); +constexpr StringData kX509AuthMechanism = "MONGODB-X509"_sd; -private: - /** - * Completes the authentication of "user" using "mechanism" and parameters from "cmdObj". - * - * Returns Status::OK() on success. All other statuses indicate failed authentication. The - * entire status returned here may always be used for logging. However, if the code is - * AuthenticationFailed, the "reason" field of the return status may contain information - * that should not be revealed to the connected client. - * - * Other than AuthenticationFailed, common returns are BadValue, indicating unsupported - * mechanism, and ProtocolError, indicating an error in the use of the authentication - * protocol. - */ - Status _authenticate(OperationContext* opCtx, - const std::string& mechanism, - const UserName& user, - const BSONObj& cmdObj); - Status _authenticateX509(OperationContext* opCtx, const UserName& user, const BSONObj& cmdObj); -}; +void disableAuthMechanism(StringData authMechanism); -extern CmdAuthenticate cmdAuthenticate; -} +} // namespace mongo |