diff options
-rw-r--r-- | src/mongo/client/SConscript | 11 | ||||
-rw-r--r-- | src/mongo/client/authenticate.h | 1 | ||||
-rw-r--r-- | src/mongo/client/cyrus_sasl_client_session.cpp | 2 | ||||
-rw-r--r-- | src/mongo/client/mongo_uri_connect.cpp | 10 | ||||
-rw-r--r-- | src/mongo/client/native_sasl_client_session.cpp | 7 | ||||
-rw-r--r-- | src/mongo/client/sasl_client_authenticate_impl.cpp | 11 | ||||
-rw-r--r-- | src/mongo/client/sasl_client_session.h | 1 | ||||
-rw-r--r-- | src/mongo/client/sasl_iam_client_conversation.cpp | 110 | ||||
-rw-r--r-- | src/mongo/client/sasl_iam_client_conversation.h | 78 | ||||
-rw-r--r-- | src/mongo/client/sasl_iam_client_options.h | 53 | ||||
-rw-r--r-- | src/mongo/client/sasl_iam_client_options.idl | 16 | ||||
-rw-r--r-- | src/mongo/client/sasl_iam_client_protocol.cpp | 34 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_command_constants.h | 3 | ||||
-rw-r--r-- | src/mongo/db/auth/sasl_mechanism_policies.h | 19 | ||||
-rw-r--r-- | src/mongo/shell/dbshell.cpp | 13 |
15 files changed, 344 insertions, 25 deletions
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript index cd456d7bba1..09fdd610b1d 100644 --- a/src/mongo/client/SConscript +++ b/src/mongo/client/SConscript @@ -1,6 +1,7 @@ # -*- mode: python -*- Import('env') +Import("get_option") env = env.Clone() @@ -85,6 +86,12 @@ saslClientSource = [ 'sasl_scram_client_conversation.cpp', ] +if get_option('ssl') == 'on': + saslClientSource.extend([ + 'sasl_iam_client_conversation.cpp', + env.Idlc('sasl_iam_client_options.idl')[0], + ]) + # Add in actual sasl dependencies if sasl is enabled, otherwise # leave library empty so other targets can link to it unconditionally # without needing to first test MONGO_BUILD_SASL_CLIENT. @@ -104,6 +111,7 @@ saslClientEnv.Library( target='sasl_client', source=saslClientSource, LIBDEPS=[ + "sasl_iam_client" if get_option('ssl') == 'on' else '', '$BUILD_DIR/mongo/base/secure_allocator', '$BUILD_DIR/mongo/bson/util/bson_extract', '$BUILD_DIR/mongo/executor/remote_command', @@ -114,6 +122,9 @@ saslClientEnv.Library( '$BUILD_DIR/mongo/util/net/network', '$BUILD_DIR/mongo/util/options_parser/options_parser', ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/util/net/http_client', + ], SYSLIBDEPS=saslLibs, ) diff --git a/src/mongo/client/authenticate.h b/src/mongo/client/authenticate.h index 15c9cd0b9b4..8900b70810c 100644 --- a/src/mongo/client/authenticate.h +++ b/src/mongo/client/authenticate.h @@ -64,6 +64,7 @@ constexpr auto kMechanismSaslPlain = "PLAIN"_sd; constexpr auto kMechanismGSSAPI = "GSSAPI"_sd; constexpr auto kMechanismScramSha1 = "SCRAM-SHA-1"_sd; constexpr auto kMechanismScramSha256 = "SCRAM-SHA-256"_sd; +constexpr auto kMechanismMongoIAM = "MONGODB-IAM"_sd; constexpr auto kInternalAuthFallbackMechanism = kMechanismScramSha1; /** diff --git a/src/mongo/client/cyrus_sasl_client_session.cpp b/src/mongo/client/cyrus_sasl_client_session.cpp index 85c8c575ca1..9c0c8e207c0 100644 --- a/src/mongo/client/cyrus_sasl_client_session.cpp +++ b/src/mongo/client/cyrus_sasl_client_session.cpp @@ -47,7 +47,7 @@ void saslSetError(sasl_conn_t* conn, const std::string& msg) { } SaslClientSession* createCyrusSaslClientSession(const std::string& mech) { - if ((mech == "SCRAM-SHA-1") || (mech == "SCRAM-SHA-256")) { + if ((mech == "SCRAM-SHA-1") || (mech == "SCRAM-SHA-256") || mech == "MONGODB-IAM") { return new NativeSaslClientSession(); } return new CyrusSaslClientSession(); diff --git a/src/mongo/client/mongo_uri_connect.cpp b/src/mongo/client/mongo_uri_connect.cpp index e9505e42bcc..b636571d391 100644 --- a/src/mongo/client/mongo_uri_connect.cpp +++ b/src/mongo/client/mongo_uri_connect.cpp @@ -54,10 +54,12 @@ const char kAuthMechanismPropertiesKey[] = "mechanism_properties"; // CANONICALIZE_HOST_NAME is currently unsupported const char kAuthServiceName[] = "SERVICE_NAME"; const char kAuthServiceRealm[] = "SERVICE_REALM"; +const char kAuthAwsSessionToken[] = "AWS_SESSION_TOKEN"; const char kAuthMechDefault[] = "DEFAULT"; -const char* const kSupportedAuthMechanismProperties[] = {kAuthServiceName, kAuthServiceRealm}; +const char* const kSupportedAuthMechanismProperties[] = { + kAuthServiceName, kAuthServiceRealm, kAuthAwsSessionToken}; BSONObj parseAuthMechanismProperties(const std::string& propStr) { BSONObjBuilder bob; @@ -105,7 +107,7 @@ boost::optional<BSONObj> MongoURI::_makeAuthObjFromOptions( it = _options.find("authMechanism"); if (it != _options.end()) { bob.append(saslCommandMechanismFieldName, it->second); - if (it->second == auth::kMechanismMongoX509) { + if (it->second == auth::kMechanismMongoX509 || it->second == auth::kMechanismMongoIAM) { usernameRequired = false; } } else if (!saslMechsForAuth.empty()) { @@ -155,6 +157,10 @@ boost::optional<BSONObj> MongoURI::_makeAuthObjFromOptions( } username.append("@").append(parsed[kAuthServiceRealm].String()); } + + if (parsed.hasField(kAuthAwsSessionToken)) { + bob.append(saslCommandIamSessionToken, parsed[kAuthAwsSessionToken].String()); + } } it = _options.find("gssapiServiceName"); diff --git a/src/mongo/client/native_sasl_client_session.cpp b/src/mongo/client/native_sasl_client_session.cpp index 3fa871bda5d..0211ba72ef5 100644 --- a/src/mongo/client/native_sasl_client_session.cpp +++ b/src/mongo/client/native_sasl_client_session.cpp @@ -33,9 +33,11 @@ #include "mongo/base/init.h" #include "mongo/client/sasl_client_conversation.h" +#include "mongo/client/sasl_iam_client_conversation.h" #include "mongo/client/sasl_plain_client_conversation.h" #include "mongo/client/sasl_scram_client_conversation.h" #include "mongo/client/scram_client_cache.h" +#include "mongo/config.h" #include "mongo/crypto/sha1_block.h" #include "mongo/crypto/sha256_block.h" #include "mongo/util/str.h" @@ -77,6 +79,11 @@ Status NativeSaslClientSession::initialize() { } else if (mechanism == "SCRAM-SHA-256") { _saslConversation.reset( new SaslSCRAMClientConversationImpl<SHA256Block>(this, scramsha256ClientCache)); +#ifdef MONGO_CONFIG_SSL + // IAM depends on kms-message which depends on ssl libraries + } else if (mechanism == "MONGODB-IAM") { + _saslConversation.reset(new SaslIAMClientConversation(this)); +#endif } else { return Status(ErrorCodes::BadValue, str::stream() << "SASL mechanism " << mechanism << " is not supported"); diff --git a/src/mongo/client/sasl_client_authenticate_impl.cpp b/src/mongo/client/sasl_client_authenticate_impl.cpp index 4d19e5597d2..8a5794f95e0 100644 --- a/src/mongo/client/sasl_client_authenticate_impl.cpp +++ b/src/mongo/client/sasl_client_authenticate_impl.cpp @@ -144,9 +144,11 @@ Status configureSession(SaslClientSession* session, session->setParameter(SaslClientSession::parameterServiceHostAndPort, hostname.toString()); status = bsonExtractStringField(saslParameters, saslCommandUserFieldName, &value); - if (!status.isOK()) + if (status.isOK()) { + session->setParameter(SaslClientSession::parameterUser, value); + } else if ((targetDatabase != "$external") || (mechanism != "MONGODB-IAM")) { return status; - session->setParameter(SaslClientSession::parameterUser, value); + } const bool digestPasswordDefault = (mechanism == "SCRAM-SHA-1"); bool digestPassword; @@ -163,6 +165,11 @@ Status configureSession(SaslClientSession* session, return status; } + status = bsonExtractStringField(saslParameters, saslCommandIamSessionToken, &value); + if (status.isOK()) { + session->setParameter(SaslClientSession::parameterIamSessionToken, value); + } + return session->initialize(); } diff --git a/src/mongo/client/sasl_client_session.h b/src/mongo/client/sasl_client_session.h index ae384359e20..7e5442b6f51 100644 --- a/src/mongo/client/sasl_client_session.h +++ b/src/mongo/client/sasl_client_session.h @@ -69,6 +69,7 @@ public: parameterMechanism, parameterUser, parameterPassword, + parameterIamSessionToken, numParameters // Must be last }; diff --git a/src/mongo/client/sasl_iam_client_conversation.cpp b/src/mongo/client/sasl_iam_client_conversation.cpp new file mode 100644 index 00000000000..5aec283b5a7 --- /dev/null +++ b/src/mongo/client/sasl_iam_client_conversation.cpp @@ -0,0 +1,110 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * 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 Server Side 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/platform/basic.h" + +#include "mongo/client/sasl_iam_client_conversation.h" + +#include <string> +#include <time.h> + +#include "mongo/base/string_data.h" +#include "mongo/bson/json.h" +#include "mongo/bson/util/bson_extract.h" +#include "mongo/client/sasl_iam_client_options.h" +#include "mongo/client/sasl_iam_client_protocol.h" +#include "mongo/client/sasl_iam_client_protocol_gen.h" +#include "mongo/util/net/http_client.h" + +namespace mongo { +namespace iam { +SASLIamClientGlobalParams saslIamClientGlobalParams; +} // namespace iam + +std::string getDefaultHost() { + return iam::saslIamClientGlobalParams.awsEC2InstanceMetadataUrl; +} + +SaslIAMClientConversation::SaslIAMClientConversation(SaslClientSession* saslClientSession) + : SaslClientConversation(saslClientSession) {} + +iam::AWSCredentials SaslIAMClientConversation::_getCredentials() const { + return _getUserCredentials(); +} + +iam::AWSCredentials SaslIAMClientConversation::_getUserCredentials() const { + if (_saslClientSession->hasParameter(SaslClientSession::parameterIamSessionToken)) { + return iam::AWSCredentials( + _saslClientSession->getParameter(SaslClientSession::parameterUser).toString(), + _saslClientSession->getParameter(SaslClientSession::parameterPassword).toString(), + _saslClientSession->getParameter(SaslClientSession::parameterIamSessionToken) + .toString()); + } + + return iam::AWSCredentials( + _saslClientSession->getParameter(SaslClientSession::parameterUser).toString(), + _saslClientSession->getParameter(SaslClientSession::parameterPassword).toString()); +} + +StatusWith<bool> SaslIAMClientConversation::step(StringData inputData, std::string* outputData) { + if (_step > 2) { + return Status(ErrorCodes::AuthenticationFailed, + str::stream() << "Invalid IAM authentication step: " << _step); + } + + _step++; + + try { + if (_step == 1) { + return _firstStep(outputData); + } + + return _secondStep(inputData, outputData); + } catch (...) { + return exceptionToStatus(); + } +} + +StatusWith<bool> SaslIAMClientConversation::_firstStep(std::string* outputData) { + + *outputData = iam::generateClientFirst(&_clientNonce); + + return false; +} + +StatusWith<bool> SaslIAMClientConversation::_secondStep(StringData inputData, + std::string* outputData) { + auto credentials = _getCredentials(); + + *outputData = iam::generateClientSecond(inputData, _clientNonce, credentials); + + return true; +} + +} // namespace mongo diff --git a/src/mongo/client/sasl_iam_client_conversation.h b/src/mongo/client/sasl_iam_client_conversation.h new file mode 100644 index 00000000000..0579ea567c2 --- /dev/null +++ b/src/mongo/client/sasl_iam_client_conversation.h @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * 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 Server Side 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 <string> +#include <vector> + +#include "mongo/base/status.h" +#include "mongo/base/string_data.h" +#include "mongo/client/sasl_client_conversation.h" +#include "mongo/client/sasl_client_session.h" +#include "mongo/client/sasl_iam_protocol_common.h" + +namespace mongo { +/** + * Client side authentication session for MONGODB-IAM SASL. + */ +class SaslIAMClientConversation : public SaslClientConversation { + SaslIAMClientConversation(const SaslIAMClientConversation&) = delete; + SaslIAMClientConversation& operator=(const SaslIAMClientConversation&) = delete; + +public: + explicit SaslIAMClientConversation(SaslClientSession* saslClientSession); + + virtual ~SaslIAMClientConversation() = default; + + StatusWith<bool> step(StringData inputData, std::string* outputData) override; + +private: + /** + * Get AWS credentials either from the SASL session or a local HTTP server. + */ + iam::AWSCredentials _getCredentials() const; + + /** + * Get AWS credentials from SASL session. + */ + iam::AWSCredentials _getUserCredentials() const; + + StatusWith<bool> _firstStep(std::string* outputData); + StatusWith<bool> _secondStep(StringData inputData, std::string* outputData); + +private: + // Step of protocol - either 1 or 2 + std::uint32_t _step{0}; + + // Client nonce + std::vector<char> _clientNonce; +}; + +} // namespace mongo diff --git a/src/mongo/client/sasl_iam_client_options.h b/src/mongo/client/sasl_iam_client_options.h new file mode 100644 index 00000000000..02535a15af0 --- /dev/null +++ b/src/mongo/client/sasl_iam_client_options.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2019-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * 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 + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * 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 Server Side 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 <string> + +namespace mongo { +namespace iam { +/** + * SASL IAM Client parameters + */ +struct SASLIamClientGlobalParams { + /** + * EC2 Instance metadata endpoint. + */ + std::string awsEC2InstanceMetadataUrl; + + /** + * AWS Session Token. + */ + std::string awsSessionToken; +}; + +extern SASLIamClientGlobalParams saslIamClientGlobalParams; +} // namespace iam +} // namespace mongo diff --git a/src/mongo/client/sasl_iam_client_options.idl b/src/mongo/client/sasl_iam_client_options.idl new file mode 100644 index 00000000000..29b188414f9 --- /dev/null +++ b/src/mongo/client/sasl_iam_client_options.idl @@ -0,0 +1,16 @@ +# Copyright (C) 2019-present MongoDB, Inc. + +global: + cpp_namespace: "mongo::iam" + configs: + section: 'IAM AWS Options' + source: [ cli ] + cpp_includes: + - mongo/client/sasl_iam_client_options.h + +configs: + awsIamSessionToken: + description: "AWS Session Token for temporary credentials" + arg_vartype: String + cpp_varname: saslIamClientGlobalParams.awsSessionToken + diff --git a/src/mongo/client/sasl_iam_client_protocol.cpp b/src/mongo/client/sasl_iam_client_protocol.cpp index 466acc4f795..e20cb99834f 100644 --- a/src/mongo/client/sasl_iam_client_protocol.cpp +++ b/src/mongo/client/sasl_iam_client_protocol.cpp @@ -53,7 +53,7 @@ SecureRandom saslIAMClientGen; std::vector<char> generateClientNonce() { std::vector<char> ret; - ret.resize(iam::kClientFirstNonceLength); + ret.resize(kClientFirstNonceLength); { stdx::lock_guard<Latch> lk(saslIAMClientMutex); @@ -108,14 +108,14 @@ AWSCredentials parseCredentials(StringData data) { } // namespace -std::string iam::generateClientFirst(std::vector<char>* clientNonce) { +std::string generateClientFirst(std::vector<char>* clientNonce) { *clientNonce = generateClientNonce(); IamClientFirst first; first.setNonce(*clientNonce); first.setGs2_cb_flag(static_cast<int>('n')); - return iam::convertToByteString(first); + return convertToByteString(first); } #define uassertKmsRequest(X) uassertKmsRequestInternal(request.get(), __FILE__, __LINE__, (X)); @@ -128,19 +128,19 @@ std::string generateClientSecond(StringData serverFirstBase64, uassert(51298, "Nonce must be 64 bytes", - serverFirst.getServerNonce().length() == iam::kServerFirstNonceLength); + serverFirst.getServerNonce().length() == kServerFirstNonceLength); uassert(51297, "First part of nonce must match client", std::equal(serverFirst.getServerNonce().data(), - serverFirst.getServerNonce().data() + iam::kClientFirstNonceLength, + serverFirst.getServerNonce().data() + kClientFirstNonceLength, clientNonce.begin(), clientNonce.end()) == true); uassert(51296, "Host name length is incorrect", !serverFirst.getStsHost().empty() && - serverFirst.getStsHost().size() < iam::kMaxStsHostNameLength); + serverFirst.getStsHost().size() < kMaxStsHostNameLength); uassert(51295, "Host name is not allowed to have a empty DNS name part.", @@ -157,7 +157,7 @@ std::string generateClientSecond(StringData serverFirstBase64, kms_request_set_region(request.get(), getRegionFromHost(serverFirst.getStsHost()).c_str())); // sts is always the name of the service - uassertKmsRequest(kms_request_set_service(request.get(), iam::kAwsServiceName.rawData())); + uassertKmsRequest(kms_request_set_service(request.get(), kAwsServiceName.rawData())); uassertKmsRequest(kms_request_add_header_field( request.get(), "Host", serverFirst.getStsHost().toString().c_str())); @@ -165,11 +165,11 @@ std::string generateClientSecond(StringData serverFirstBase64, auto serverNonce = serverFirst.getServerNonce(); uassertKmsRequest(kms_request_add_header_field( request.get(), - iam::kMongoServerNonceHeader.rawData(), + kMongoServerNonceHeader.rawData(), base64::encode(serverNonce.data(), serverNonce.length()).c_str())); uassertKmsRequest(kms_request_add_header_field( - request.get(), iam::kMongoGS2CBHeader.rawData(), iam::kMongoDefaultGS2CBFlag.rawData())); + request.get(), kMongoGS2CBHeader.rawData(), kMongoDefaultGS2CBFlag.rawData())); uassertKmsRequest( kms_request_set_access_key_id(request.get(), credentials.accessKeyId.c_str())); @@ -192,17 +192,17 @@ std::string generateClientSecond(StringData serverFirstBase64, second.setXAmzDate(kms_request_get_canonical_header(request.get(), kXAmzDateHeader.rawData())); - return iam::convertToByteString(second); + return convertToByteString(second); } -std::string iam::getRegionFromHost(StringData host) { - if (host == iam::kAwsDefaultStsHost) { - return iam::kAwsDefaultRegion.toString(); +std::string getRegionFromHost(StringData host) { + if (host == kAwsDefaultStsHost) { + return kAwsDefaultRegion.toString(); } size_t firstPeriod = host.find('.'); if (firstPeriod == std::string::npos) { - return iam::kAwsDefaultRegion.toString(); + return kAwsDefaultRegion.toString(); } size_t secondPeriod = host.find('.', firstPeriod + 1); @@ -213,7 +213,7 @@ std::string iam::getRegionFromHost(StringData host) { return host.substr(firstPeriod + 1, secondPeriod - firstPeriod - 1).toString(); } -std::string iam::parseRoleFromEC2IamSecurityCredentials(StringData data) { +std::string parseRoleFromEC2IamSecurityCredentials(StringData data) { size_t pos = data.find('\n'); uassert( @@ -221,11 +221,11 @@ std::string iam::parseRoleFromEC2IamSecurityCredentials(StringData data) { return data.substr(0, pos).toString(); } -AWSCredentials iam::parseCredentialsFromEC2IamSecurityCredentials(StringData data) { +AWSCredentials parseCredentialsFromEC2IamSecurityCredentials(StringData data) { return parseCredentials<Ec2SecurityCredentials>(data); } -AWSCredentials iam::parseCredentialsFromECSTaskIamCredentials(StringData data) { +AWSCredentials parseCredentialsFromECSTaskIamCredentials(StringData data) { return parseCredentials<EcsTaskSecurityCredentials>(data); } diff --git a/src/mongo/db/auth/sasl_command_constants.h b/src/mongo/db/auth/sasl_command_constants.h index 64bbb6446be..03eb2e21d2d 100644 --- a/src/mongo/db/auth/sasl_command_constants.h +++ b/src/mongo/db/auth/sasl_command_constants.h @@ -89,4 +89,7 @@ constexpr auto saslDefaultServiceName = "mongodb"_sd; // be digested. constexpr auto saslCommandDigestPasswordFieldName = "digestPassword"_sd; +/// Field containing optional session token information for MONGODB-IAM sasl mechanism. +constexpr auto saslCommandIamSessionToken = "awsIamSessionToken"_sd; + } // namespace mongo diff --git a/src/mongo/db/auth/sasl_mechanism_policies.h b/src/mongo/db/auth/sasl_mechanism_policies.h index 5406a98b821..5e19e46eb09 100644 --- a/src/mongo/db/auth/sasl_mechanism_policies.h +++ b/src/mongo/db/auth/sasl_mechanism_policies.h @@ -35,6 +35,21 @@ namespace mongo { +struct IAMPolicy { + static constexpr StringData getName() { + return "MONGODB-IAM"_sd; + } + static SecurityPropertySet getProperties() { + return SecurityPropertySet{SecurityProperty::kNoPlainText}; + } + static int securityLevel() { + return 1; + } + static constexpr bool isInternalAuthMech() { + return false; + } +}; + struct PLAINPolicy { static constexpr StringData getName() { return "PLAIN"_sd; @@ -60,7 +75,7 @@ struct SCRAMSHA1Policy { return SecurityPropertySet{SecurityProperty::kNoPlainText, SecurityProperty::kMutualAuth}; } static int securityLevel() { - return 1; + return 2; } static constexpr bool isInternalAuthMech() { return true; @@ -77,7 +92,7 @@ struct SCRAMSHA256Policy { return SecurityPropertySet{SecurityProperty::kNoPlainText, SecurityProperty::kMutualAuth}; } static int securityLevel() { - return true; + return 2; } static constexpr bool isInternalAuthMech() { return true; diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp index 3e59edfbfb1..b07914b7996 100644 --- a/src/mongo/shell/dbshell.cpp +++ b/src/mongo/shell/dbshell.cpp @@ -47,7 +47,10 @@ #include "mongo/base/init.h" #include "mongo/base/initializer.h" #include "mongo/base/status.h" +#include "mongo/client/authenticate.h" #include "mongo/client/mongo_uri.h" +#include "mongo/client/sasl_iam_client_options.h" +#include "mongo/config.h" #include "mongo/db/auth/sasl_command_constants.h" #include "mongo/db/client.h" #include "mongo/db/commands/test_commands_enabled.h" @@ -691,7 +694,8 @@ static void edit(const std::string& whatToEdit) { namespace { bool mechanismRequiresPassword(const MongoURI& uri) { if (const auto authMechanisms = uri.getOption("authMechanism")) { - constexpr std::array<StringData, 2> passwordlessMechanisms{"GSSAPI"_sd, "MONGODB-X509"_sd}; + constexpr std::array<StringData, 3> passwordlessMechanisms{ + auth::kMechanismGSSAPI, auth::kMechanismMongoX509, auth::kMechanismMongoIAM}; const std::string& authMechanism = authMechanisms.get(); for (const auto& mechanism : passwordlessMechanisms) { if (mechanism.toString() == authMechanism) { @@ -792,6 +796,13 @@ int _main(int argc, char* argv[], char** envp) { parsedURI.setOptionIfNecessary("authSource"s, shellGlobalParams.authenticationDatabase); parsedURI.setOptionIfNecessary("gssapiServiceName"s, shellGlobalParams.gssapiServiceName); parsedURI.setOptionIfNecessary("gssapiHostName"s, shellGlobalParams.gssapiHostName); +#ifdef MONGO_CONFIG_SSL + if (!iam::saslIamClientGlobalParams.awsSessionToken.empty()) { + parsedURI.setOptionIfNecessary("authmechanismproperties"s, + std::string("AWS_SESSION_TOKEN:") + + iam::saslIamClientGlobalParams.awsSessionToken); + } +#endif if (const auto authMechanisms = parsedURI.getOption("authMechanism")) { std::stringstream ss; |