diff options
author | Andreas Nilsson <andreas.nilsson@10gen.com> | 2014-05-20 16:34:25 -0400 |
---|---|---|
committer | Dan Pasette <dan@mongodb.com> | 2014-05-23 14:57:13 -0400 |
commit | 81b9d6df4f2476f46a5896bafc1639c5899e3130 (patch) | |
tree | bd48a993bdb0f0e0eec68dad576e3d7cafb4c25e | |
parent | 7c75cf1da8fe396eb0fff8dc9c7365e539ece611 (diff) | |
download | mongo-81b9d6df4f2476f46a5896bafc1639c5899e3130.tar.gz |
SERVER-13945 Match x.509 cluster certs per attribute
(cherry picked from commit 81967a2dce1898d1f03938f0b5c27b8a37873877)
-rw-r--r-- | src/mongo/db/commands/authentication_commands.cpp | 49 | ||||
-rw-r--r-- | src/mongo/db/commands/authentication_commands.h | 1 |
2 files changed, 39 insertions, 11 deletions
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index 1c6a63bf4f9..0b462cab95d 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -28,6 +28,7 @@ #include "mongo/db/commands/authentication_commands.h" +#include <boost/algorithm/string.hpp> #include <boost/scoped_ptr.hpp> #include <string> #include <vector> @@ -52,6 +53,7 @@ #include "mongo/util/concurrency/mutex.h" #include "mongo/util/md5.hpp" #include "mongo/util/net/ssl_manager.h" +#include "mongo/util/text.h" namespace mongo { @@ -283,6 +285,39 @@ namespace mongo { } #ifdef MONGO_SSL + void canonicalizeClusterDN(std::vector<std::string>* dn) { + // remove all RDNs we don't care about + for (std::vector<string>::iterator it=dn->begin(); it != dn->end(); it++) { + boost::algorithm::trim(*it); + if (!mongoutils::str::startsWith(it->c_str(), "DC=") && + !mongoutils::str::startsWith(it->c_str(), "O=") && + !mongoutils::str::startsWith(it->c_str(), "OU=")) { + dn->erase(it--); + } + } + std::stable_sort(dn->begin(), dn->end()); + } + + bool CmdAuthenticate::_clusterIdMatch(const std::string& subjectName, + const std::string& srvSubjectName) { + std::vector<string> clientRDN = StringSplitter::split(subjectName, ","); + std::vector<string> serverRDN = StringSplitter::split(srvSubjectName, ","); + + canonicalizeClusterDN(&clientRDN); + canonicalizeClusterDN(&serverRDN); + + if (clientRDN.size() == 0 || clientRDN.size() != serverRDN.size()) { + return false; + } + + for (size_t i=0; i < serverRDN.size(); i++) { + if(clientRDN[i] != serverRDN[i]) { + return false; + } + } + return true; + } + Status CmdAuthenticate::_authenticateX509(const UserName& user, const BSONObj& cmdObj) { if (!getSSLManager()) { return Status(ErrorCodes::ProtocolError, @@ -303,18 +338,10 @@ namespace mongo { } else { std::string srvSubjectName = getSSLManager()->getServerSubjectName(); - - size_t srvClusterIdPos = srvSubjectName.find(",OU="); - size_t peerClusterIdPos = subjectName.find(",OU="); - - std::string srvClusterId = srvClusterIdPos != std::string::npos ? - srvSubjectName.substr(srvClusterIdPos) : ""; - std::string peerClusterId = peerClusterIdPos != std::string::npos ? - subjectName.substr(peerClusterIdPos) : ""; - + // Handle internal cluster member auth, only applies to server-server connections - int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); - if (srvClusterId == peerClusterId && !srvClusterId.empty()) { + if (_clusterIdMatch(subjectName, srvSubjectName)) { + int clusterAuthMode = serverGlobalParams.clusterAuthMode.load(); if (clusterAuthMode == ServerGlobalParams::ClusterAuthMode_undefined || clusterAuthMode == ServerGlobalParams::ClusterAuthMode_keyFile) { return Status(ErrorCodes::AuthenticationFailed, "The provided certificate " diff --git a/src/mongo/db/commands/authentication_commands.h b/src/mongo/db/commands/authentication_commands.h index 44db5b1b910..e7891329946 100644 --- a/src/mongo/db/commands/authentication_commands.h +++ b/src/mongo/db/commands/authentication_commands.h @@ -79,6 +79,7 @@ namespace mongo { const BSONObj& cmdObj); Status _authenticateCR(const UserName& user, const BSONObj& cmdObj); Status _authenticateX509(const UserName& user, const BSONObj& cmdObj); + bool _clusterIdMatch(const std::string& subjectName, const std::string& srvSubjectName); }; extern CmdAuthenticate cmdAuthenticate; |