summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/util')
-rwxr-xr-xsrc/mongo/util/generate_icu_init_cpp.py3
-rw-r--r--src/mongo/util/net/ssl_manager.cpp155
-rw-r--r--src/mongo/util/net/ssl_manager_apple.cpp3
-rw-r--r--src/mongo/util/net/ssl_manager_openssl.cpp2
-rw-r--r--src/mongo/util/net/ssl_manager_windows.cpp3
5 files changed, 124 insertions, 42 deletions
diff --git a/src/mongo/util/generate_icu_init_cpp.py b/src/mongo/util/generate_icu_init_cpp.py
index a95740b8c75..56f11217eca 100755
--- a/src/mongo/util/generate_icu_init_cpp.py
+++ b/src/mongo/util/generate_icu_init_cpp.py
@@ -101,7 +101,8 @@ alignas(16) const uint8_t kRawData[] = {%(decimal_encoded_data)s};
} // namespace
-MONGO_INITIALIZER(LoadICUData)(InitializerContext* context) {
+MONGO_INITIALIZER_GENERAL(LoadICUData, MONGO_NO_PREREQUISITES, ("BeginStartupOptionHandling"))(
+ InitializerContext* context) {
UErrorCode status = U_ZERO_ERROR;
udata_setCommonData(kRawData, &status);
fassert(40088, U_SUCCESS(status));
diff --git a/src/mongo/util/net/ssl_manager.cpp b/src/mongo/util/net/ssl_manager.cpp
index a6c59494748..ac772a97a01 100644
--- a/src/mongo/util/net/ssl_manager.cpp
+++ b/src/mongo/util/net/ssl_manager.cpp
@@ -288,6 +288,114 @@ constexpr int kASN1TeletexString = 20;
constexpr int kASN1UniversalString = 28;
constexpr int kASN1BMPString = 30;
constexpr int kASN1OctetString = 4;
+
+void canonicalizeClusterDN(std::vector<std::string>* dn) {
+ // remove all RDNs we don't care about
+ for (size_t i = 0; i < dn->size(); i++) {
+ std::string& comp = dn->at(i);
+ boost::algorithm::trim(comp);
+ if (!mongoutils::str::startsWith(comp.c_str(), "DC=") &&
+ !mongoutils::str::startsWith(comp.c_str(), "O=") &&
+ !mongoutils::str::startsWith(comp.c_str(), "OU=")) {
+ dn->erase(dn->begin() + i);
+ i--;
+ }
+ }
+ std::stable_sort(dn->begin(), dn->end());
+}
+
+constexpr StringData kOID_DC = "0.9.2342.19200300.100.1.25"_sd;
+constexpr StringData kOID_O = "2.5.4.10"_sd;
+constexpr StringData kOID_OU = "2.5.4.11"_sd;
+
+std::vector<SSLX509Name::Entry> canonicalizeClusterDN(
+ const std::vector<std::vector<SSLX509Name::Entry>>& entries) {
+ std::vector<SSLX509Name::Entry> ret;
+
+ for (const auto& rdn : entries) {
+ for (const auto& entry : rdn) {
+ if ((entry.oid != kOID_DC) && (entry.oid != kOID_O) && (entry.oid != kOID_OU)) {
+ continue;
+ }
+ ret.push_back(entry);
+ }
+ }
+ std::stable_sort(ret.begin(), ret.end());
+ return ret;
+}
+
+class ClusterMemberDNOverride : public ServerParameter {
+public:
+ ClusterMemberDNOverride()
+ : ServerParameter(
+ ServerParameterSet::getGlobal(), "tlsX509ClusterAuthDNOverride", true, true) {}
+
+ void append(OperationContext* opCtx, BSONObjBuilder& b, const std::string& name) override {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ if (!_value) {
+ return;
+ }
+
+ b.append(name, _value->fullDN.toString());
+ }
+
+ Status set(const BSONElement& newValueElement) override {
+ if (newValueElement.type() != String) {
+ return {ErrorCodes::BadValue, "DN must be a string"};
+ }
+ return setFromString(newValueElement.String());
+ }
+
+ Status setFromString(const std::string& str) override {
+ if (str.empty()) {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ _value = boost::none;
+ return Status::OK();
+ }
+
+ auto swDN = parseDN(str);
+ if (!swDN.isOK()) {
+ return swDN.getStatus();
+ }
+ auto dn = std::move(swDN.getValue());
+ auto status = dn.normalizeStrings();
+ if (!status.isOK()) {
+ return status;
+ }
+
+ DNValue val(std::move(dn));
+ if (val.canonicalized.empty()) {
+ return {ErrorCodes::BadValue,
+ "Cluster member DN's must contain at least one O, OU, or DC component"};
+ }
+
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ _value = {std::move(val)};
+
+ return Status::OK();
+ }
+
+ boost::optional<std::vector<SSLX509Name::Entry>> getCanonical() {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ if (!_value) {
+ return boost::none;
+ }
+ return _value->canonicalized;
+ }
+
+private:
+ struct DNValue {
+ explicit DNValue(SSLX509Name dn)
+ : fullDN(std::move(dn)), canonicalized(canonicalizeClusterDN(fullDN.entries())) {}
+
+ SSLX509Name fullDN;
+ std::vector<SSLX509Name::Entry> canonicalized;
+ };
+
+ stdx::mutex _mutex;
+ boost::optional<DNValue> _value;
+} clusterMemberDNOverrideParameter;
+
} // namespace
StatusWith<SSLX509Name> parseDN(StringData sd) try {
@@ -537,43 +645,6 @@ std::string SSLX509Name::toString() const {
return os.str();
}
-namespace {
-void canonicalizeClusterDN(std::vector<std::string>* dn) {
- // remove all RDNs we don't care about
- for (size_t i = 0; i < dn->size(); i++) {
- std::string& comp = dn->at(i);
- boost::algorithm::trim(comp);
- if (!mongoutils::str::startsWith(comp.c_str(), "DC=") &&
- !mongoutils::str::startsWith(comp.c_str(), "O=") &&
- !mongoutils::str::startsWith(comp.c_str(), "OU=")) {
- dn->erase(dn->begin() + i);
- i--;
- }
- }
- std::stable_sort(dn->begin(), dn->end());
-}
-
-constexpr StringData kOID_DC = "0.9.2342.19200300.100.1.25"_sd;
-constexpr StringData kOID_O = "2.5.4.10"_sd;
-constexpr StringData kOID_OU = "2.5.4.11"_sd;
-
-std::vector<SSLX509Name::Entry> canonicalizeClusterDN(
- const std::vector<std::vector<SSLX509Name::Entry>>& entries) {
- std::vector<SSLX509Name::Entry> ret;
-
- for (const auto& rdn : entries) {
- for (const auto& entry : rdn) {
- if ((entry.oid != kOID_DC) && (entry.oid != kOID_O) && (entry.oid != kOID_OU)) {
- continue;
- }
- ret.push_back(entry);
- }
- }
- std::stable_sort(ret.begin(), ret.end());
- return ret;
-}
-} // namespace
-
Status SSLConfiguration::setServerSubjectName(SSLX509Name name) {
auto status = name.normalizeStrings();
if (!status.isOK()) {
@@ -601,8 +672,16 @@ bool SSLConfiguration::isClusterMember(SSLX509Name subject) const {
}
auto client = canonicalizeClusterDN(subject.entries());
+ if (client.empty()) {
+ return false;
+ }
+
+ if (client == _canonicalServerSubjectName) {
+ return true;
+ }
- return !client.empty() && (client == _canonicalServerSubjectName);
+ auto altClusterDN = clusterMemberDNOverrideParameter.getCanonical();
+ return (altClusterDN && (client == *altClusterDN));
}
bool SSLConfiguration::isClusterMember(StringData subjectName) const {
diff --git a/src/mongo/util/net/ssl_manager_apple.cpp b/src/mongo/util/net/ssl_manager_apple.cpp
index 30de09c63c1..702981323b8 100644
--- a/src/mongo/util/net/ssl_manager_apple.cpp
+++ b/src/mongo/util/net/ssl_manager_apple.cpp
@@ -1559,7 +1559,8 @@ std::unique_ptr<SSLManagerInterface> SSLManagerInterface::create(const SSLParams
return stdx::make_unique<SSLManagerApple>(params, isServer);
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManager, ("LoadICUData"))(InitializerContext*) {
+MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManager, ("EndStartupOptionHandling"))
+(InitializerContext*) {
kMongoDBRolesOID = ::CFStringCreateWithCString(
nullptr, mongodbRolesOID.identifier.c_str(), ::kCFStringEncodingUTF8);
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp
index 11a0ebc4dcb..61f794363eb 100644
--- a/src/mongo/util/net/ssl_manager_openssl.cpp
+++ b/src/mongo/util/net/ssl_manager_openssl.cpp
@@ -662,7 +662,7 @@ MONGO_INITIALIZER(SetupOpenSSL)(InitializerContext*) {
return Status::OK();
}
-MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManager, ("SetupOpenSSL", "LoadICUData"))
+MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManager, ("SetupOpenSSL", "EndStartupOptionHandling"))
(InitializerContext*) {
stdx::lock_guard<SimpleMutex> lck(sslManagerMtx);
if (!isSSLServer || (sslGlobalParams.sslMode.load() != SSLParams::SSLMode_disabled)) {
diff --git a/src/mongo/util/net/ssl_manager_windows.cpp b/src/mongo/util/net/ssl_manager_windows.cpp
index 7feee26e213..de9854ed536 100644
--- a/src/mongo/util/net/ssl_manager_windows.cpp
+++ b/src/mongo/util/net/ssl_manager_windows.cpp
@@ -344,7 +344,8 @@ private:
UniqueCertificate _sslClusterCertificate;
};
-MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManager, ("LoadICUData"))(InitializerContext*) {
+MONGO_INITIALIZER_WITH_PREREQUISITES(SSLManager, ("EndStartupOptionHandling"))
+(InitializerContext*) {
stdx::lock_guard<SimpleMutex> lck(sslManagerMtx);
if (!isSSLServer || (sslGlobalParams.sslMode.load() != SSLParams::SSLMode_disabled)) {
theSSLManager = new SSLManagerWindows(sslGlobalParams, isSSLServer);