summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
diff options
context:
space:
mode:
authorJonathan Reams <jbreams@mongodb.com>2018-11-05 18:22:59 -0500
committerJonathan Reams <jbreams@mongodb.com>2018-11-14 16:33:12 -0500
commita8bfcc13011c5e859a10e56ce882a0d53a0a2031 (patch)
tree576413908983b0c8d3fefa644c55b414eea7409a /src/mongo/db/auth/sasl_mechanism_registry_test.cpp
parenta6a0ca1ae81b34aab14a9c9a2a3d4a6ec7be66ba (diff)
downloadmongo-a8bfcc13011c5e859a10e56ce882a0d53a0a2031.tar.gz
SERVER-32978 Advertise SCRAM-SHA-256 authentication for the internal user
Diffstat (limited to 'src/mongo/db/auth/sasl_mechanism_registry_test.cpp')
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry_test.cpp179
1 files changed, 106 insertions, 73 deletions
diff --git a/src/mongo/db/auth/sasl_mechanism_registry_test.cpp b/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
index 2d5b9012022..26c2d3766a0 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
+++ b/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
@@ -64,38 +64,55 @@ TEST(SecurityProperty, mutualAndPlainHasAllSubsets) {
SecurityPropertySet{SecurityProperty::kMutualAuth, SecurityProperty::kNoPlainText}));
}
+template <typename Policy>
+class BaseMockMechanism : public MakeServerMechanism<Policy> {
+public:
+ explicit BaseMockMechanism(std::string authenticationDatabase)
+ : MakeServerMechanism<Policy>(std::move(authenticationDatabase)) {}
+
+protected:
+ StatusWith<std::tuple<bool, std::string>> stepImpl(OperationContext* opCtx,
+ StringData input) final {
+ return std::make_tuple(true, std::string());
+ }
+};
+
+template <typename Policy, bool argIsInternal>
+class BaseMockMechanismFactory : public MakeServerFactory<Policy> {
+public:
+ static constexpr bool isInternal = argIsInternal;
+ bool canMakeMechanismForUser(const User* user) const final {
+ return true;
+ }
+};
+
// Policy for a hypothetical "FOO" SASL mechanism.
struct FooPolicy {
static constexpr StringData getName() {
return "FOO"_sd;
}
+ static constexpr int securityLevel() {
+ return 0;
+ }
+
+ static constexpr bool isInternalAuthMech() {
+ return false;
+ }
+
// This mech is kind of dangerous, it sends plaintext passwords across the wire.
static SecurityPropertySet getProperties() {
return SecurityPropertySet{SecurityProperty::kMutualAuth};
}
};
-class FooMechanism : public MakeServerMechanism<FooPolicy> {
+class FooMechanism : public BaseMockMechanism<FooPolicy> {
public:
- explicit FooMechanism(std::string authenticationDatabase)
- : MakeServerMechanism<FooPolicy>(std::move(authenticationDatabase)) {}
-
-protected:
- StatusWith<std::tuple<bool, std::string>> stepImpl(OperationContext* opCtx,
- StringData input) final {
- return std::make_tuple(true, std::string());
- }
+ using BaseMockMechanism<FooPolicy>::BaseMockMechanism;
};
template <bool argIsInternal>
-class FooMechanismFactory : public MakeServerFactory<FooMechanism> {
-public:
- static constexpr bool isInternal = argIsInternal;
- bool canMakeMechanismForUser(const User* user) const final {
- return true;
- }
-};
+class FooMechanismFactory : public BaseMockMechanismFactory<FooMechanism, argIsInternal> {};
// Policy for a hypothetical "BAR" SASL mechanism.
struct BarPolicy {
@@ -103,32 +120,53 @@ struct BarPolicy {
return "BAR"_sd;
}
+ static constexpr int securityLevel() {
+ return 1;
+ }
+
+ static constexpr bool isInternalAuthMech() {
+ return false;
+ }
+
static SecurityPropertySet getProperties() {
return SecurityPropertySet{SecurityProperty::kMutualAuth, SecurityProperty::kNoPlainText};
}
};
-class BarMechanism : public MakeServerMechanism<BarPolicy> {
+class BarMechanism : public BaseMockMechanism<BarPolicy> {
public:
- explicit BarMechanism(std::string authenticationDatabase)
- : MakeServerMechanism<BarPolicy>(std::move(authenticationDatabase)) {}
-
-protected:
- StatusWith<std::tuple<bool, std::string>> stepImpl(OperationContext* opCtx,
- StringData input) final {
- return std::make_tuple(true, std::string());
- }
+ using BaseMockMechanism<BarPolicy>::BaseMockMechanism;
};
template <bool argIsInternal>
-class BarMechanismFactory : public MakeServerFactory<BarMechanism> {
-public:
- static constexpr bool isInternal = argIsInternal;
- bool canMakeMechanismForUser(const User* user) const final {
+class BarMechanismFactory : public BaseMockMechanismFactory<BarMechanism, argIsInternal> {};
+
+// Policy for a hypothetical "InternalAuth" SASL mechanism.
+struct InternalAuthPolicy {
+ static constexpr StringData getName() {
+ return "InternalAuth"_sd;
+ }
+
+ static constexpr int securityLevel() {
+ return 2;
+ }
+
+ static constexpr bool isInternalAuthMech() {
return true;
}
+
+ static SecurityPropertySet getProperties() {
+ return SecurityPropertySet{SecurityProperty::kMutualAuth, SecurityProperty::kNoPlainText};
+ }
};
+class InternalAuthMechanism : public BaseMockMechanism<InternalAuthPolicy> {
+public:
+ using BaseMockMechanism<InternalAuthPolicy>::BaseMockMechanism;
+};
+
+class InternalAuthMechanismFactory : public BaseMockMechanismFactory<InternalAuthMechanism, true> {
+};
class MechanismRegistryTest : public ServiceContextTest {
public:
@@ -137,7 +175,9 @@ public:
authManagerExternalState(new AuthzManagerExternalStateMock()),
authManager(new AuthorizationManagerImpl(
std::unique_ptr<AuthzManagerExternalStateMock>(authManagerExternalState),
- AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{})) {
+ AuthorizationManagerImpl::InstallMockForTestingOrAuthImpl{})),
+ // By default the registry is initialized with all mechanisms enabled.
+ registry({"FOO", "BAR", "InternalAuth"}) {
AuthorizationManager::set(getServiceContext(),
std::unique_ptr<AuthorizationManager>(authManager));
@@ -180,6 +220,17 @@ public:
<< "roles"
<< BSONArray()),
BSONObj()));
+
+ internalSecurity.user = std::make_shared<User>(UserName("__system", "local"));
+ }
+
+ BSONObj getMechsFor(const UserName user) {
+ BSONObjBuilder builder;
+ registry.advertiseMechanismNamesForUser(
+ opCtx.get(),
+ BSON("isMaster" << 1 << "saslSupportedMechs" << user.getUnambiguousName()),
+ &builder);
+ return builder.obj();
}
ServiceContext::UniqueOperationContext opCtx;
@@ -187,6 +238,9 @@ public:
AuthorizationManager* authManager;
SASLServerMechanismRegistry registry;
+
+ const UserName internalSajack = {"sajack"_sd, "test"_sd};
+ const UserName externalSajack = {"sajack"_sd, "$external"_sd};
};
TEST_F(MechanismRegistryTest, acquireInternalMechanism) {
@@ -226,14 +280,7 @@ TEST_F(MechanismRegistryTest, invalidUserCantAdvertiseMechs) {
registry.registerFactory<FooMechanismFactory<true>>(
SASLServerMechanismRegistry::kNoValidateGlobalMechanisms);
- BSONObjBuilder builder;
-
- registry.advertiseMechanismNamesForUser(opCtx.get(),
- BSON("isMaster" << 1 << "saslSupportedMechs"
- << "test.noSuchUser"),
- &builder);
-
- ASSERT_BSONOBJ_EQ(BSONObj(), builder.obj());
+ ASSERT_BSONOBJ_EQ(BSONObj(), getMechsFor(UserName("noSuchUser"_sd, "test"_sd)));
}
TEST_F(MechanismRegistryTest, strongMechCanAdvertise) {
@@ -242,56 +289,42 @@ TEST_F(MechanismRegistryTest, strongMechCanAdvertise) {
registry.registerFactory<BarMechanismFactory<false>>(
SASLServerMechanismRegistry::kNoValidateGlobalMechanisms);
- BSONObjBuilder builder;
- registry.advertiseMechanismNamesForUser(opCtx.get(),
- BSON("isMaster" << 1 << "saslSupportedMechs"
- << "test.sajack"),
- &builder);
-
- BSONObj obj = builder.done();
- ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("BAR")), obj);
-
- BSONObjBuilder builderExternal;
- registry.advertiseMechanismNamesForUser(opCtx.get(),
- BSON("isMaster" << 1 << "saslSupportedMechs"
- << "$external.sajack"),
- &builderExternal);
-
- BSONObj objExternal = builderExternal.done();
- ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("BAR")), objExternal);
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("BAR")), getMechsFor(internalSajack));
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("BAR")), getMechsFor(externalSajack));
}
TEST_F(MechanismRegistryTest, weakMechCannotAdvertiseOnInternal) {
registry.registerFactory<FooMechanismFactory<true>>(
SASLServerMechanismRegistry::kNoValidateGlobalMechanisms);
- BSONObjBuilder builder;
- registry.advertiseMechanismNamesForUser(opCtx.get(),
- BSON("isMaster" << 1 << "saslSupportedMechs"
- << "test.sajack"),
- &builder);
-
-
- BSONObj obj = builder.done();
-
- ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSONArray()), obj);
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSONArray()), getMechsFor(internalSajack));
}
TEST_F(MechanismRegistryTest, weakMechCanAdvertiseOnExternal) {
registry.registerFactory<FooMechanismFactory<false>>(
SASLServerMechanismRegistry::kNoValidateGlobalMechanisms);
- BSONObjBuilder builder;
- registry.advertiseMechanismNamesForUser(opCtx.get(),
- BSON("isMaster" << 1 << "saslSupportedMechs"
- << "$external.sajack"),
- &builder);
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("FOO")), getMechsFor(externalSajack));
+}
- BSONObj obj = builder.done();
+TEST_F(MechanismRegistryTest, internalAuth) {
+ registry.setEnabledMechanisms({"BAR"});
- ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("FOO")), obj);
+ registry.registerFactory<BarMechanismFactory<true>>(
+ SASLServerMechanismRegistry::kValidateGlobalMechanisms);
+ registry.registerFactory<InternalAuthMechanismFactory>(
+ SASLServerMechanismRegistry::kValidateGlobalMechanisms);
+
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("BAR")), getMechsFor(internalSajack));
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("InternalAuth"
+ << "BAR")),
+ getMechsFor(internalSecurity.user->getName()));
+
+ registry.setEnabledMechanisms({"BAR", "InternalAuth"});
+ ASSERT_BSONOBJ_EQ(BSON("saslSupportedMechs" << BSON_ARRAY("InternalAuth"
+ << "BAR")),
+ getMechsFor(internalSajack));
}
-
} // namespace
} // namespace mongo