summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/client/SConscript11
-rw-r--r--src/mongo/client/authenticate.h1
-rw-r--r--src/mongo/client/cyrus_sasl_client_session.cpp2
-rw-r--r--src/mongo/client/mongo_uri_connect.cpp10
-rw-r--r--src/mongo/client/native_sasl_client_session.cpp7
-rw-r--r--src/mongo/client/sasl_client_authenticate_impl.cpp11
-rw-r--r--src/mongo/client/sasl_client_session.h1
-rw-r--r--src/mongo/client/sasl_iam_client_conversation.cpp110
-rw-r--r--src/mongo/client/sasl_iam_client_conversation.h78
-rw-r--r--src/mongo/client/sasl_iam_client_options.h53
-rw-r--r--src/mongo/client/sasl_iam_client_options.idl16
-rw-r--r--src/mongo/client/sasl_iam_client_protocol.cpp34
-rw-r--r--src/mongo/db/auth/sasl_command_constants.h3
-rw-r--r--src/mongo/db/auth/sasl_mechanism_policies.h19
-rw-r--r--src/mongo/shell/dbshell.cpp13
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;