diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2018-01-12 11:28:09 -0500 |
---|---|---|
committer | Sara Golemon <sara.golemon@mongodb.com> | 2018-01-25 16:00:57 -0500 |
commit | 5fad9e0f17e5987d5b523327862653f982108723 (patch) | |
tree | 6e4c2dc2be7912dbc68d55b6eab07b9a4b022dec /src/mongo/client | |
parent | 298f7758a070630917fe6c67603a2951cab29322 (diff) | |
download | mongo-5fad9e0f17e5987d5b523327862653f982108723.tar.gz |
SERVER-32793 Refactor SCRAMSHA1ClientCache to be block independent
Diffstat (limited to 'src/mongo/client')
-rw-r--r-- | src/mongo/client/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/client/native_sasl_client_session.cpp | 2 | ||||
-rw-r--r-- | src/mongo/client/sasl_scramsha1_client_conversation.cpp | 2 | ||||
-rw-r--r-- | src/mongo/client/sasl_scramsha1_client_conversation.h | 2 | ||||
-rw-r--r-- | src/mongo/client/scram_client_cache.h (renamed from src/mongo/client/scram_sha1_client_cache.h) | 51 | ||||
-rw-r--r-- | src/mongo/client/scram_sha1_client_cache.cpp | 70 |
6 files changed, 47 insertions, 81 deletions
diff --git a/src/mongo/client/SConscript b/src/mongo/client/SConscript index 8b92c437ea5..35cd948c207 100644 --- a/src/mongo/client/SConscript +++ b/src/mongo/client/SConscript @@ -85,7 +85,6 @@ saslClientSource = [ 'sasl_client_session.cpp', 'sasl_plain_client_conversation.cpp', 'sasl_scramsha1_client_conversation.cpp', - 'scram_sha1_client_cache.cpp', ] # Add in actual sasl dependencies if sasl is enabled, otherwise diff --git a/src/mongo/client/native_sasl_client_session.cpp b/src/mongo/client/native_sasl_client_session.cpp index 8f8d4fe91af..e87997c9af1 100644 --- a/src/mongo/client/native_sasl_client_session.cpp +++ b/src/mongo/client/native_sasl_client_session.cpp @@ -33,7 +33,7 @@ #include "mongo/client/sasl_client_conversation.h" #include "mongo/client/sasl_plain_client_conversation.h" #include "mongo/client/sasl_scramsha1_client_conversation.h" -#include "mongo/client/scram_sha1_client_cache.h" +#include "mongo/client/scram_client_cache.h" #include "mongo/util/mongoutils/str.h" namespace mongo { diff --git a/src/mongo/client/sasl_scramsha1_client_conversation.cpp b/src/mongo/client/sasl_scramsha1_client_conversation.cpp index 0dc84fc0818..9f7e0da6121 100644 --- a/src/mongo/client/sasl_scramsha1_client_conversation.cpp +++ b/src/mongo/client/sasl_scramsha1_client_conversation.cpp @@ -34,7 +34,7 @@ #include "mongo/base/parse_number.h" #include "mongo/client/sasl_client_session.h" -#include "mongo/client/scram_sha1_client_cache.h" +#include "mongo/client/scram_client_cache.h" #include "mongo/platform/random.h" #include "mongo/util/base64.h" #include "mongo/util/mongoutils/str.h" diff --git a/src/mongo/client/sasl_scramsha1_client_conversation.h b/src/mongo/client/sasl_scramsha1_client_conversation.h index fa6dbc4e6a6..1d262dc9f10 100644 --- a/src/mongo/client/sasl_scramsha1_client_conversation.h +++ b/src/mongo/client/sasl_scramsha1_client_conversation.h @@ -35,11 +35,11 @@ #include "mongo/base/status.h" #include "mongo/base/string_data.h" #include "mongo/client/sasl_client_conversation.h" +#include "mongo/client/scram_client_cache.h" #include "mongo/crypto/mechanism_scram.h" namespace mongo { -class SCRAMSHA1ClientCache; /** * Client side authentication session for SASL PLAIN. */ diff --git a/src/mongo/client/scram_sha1_client_cache.h b/src/mongo/client/scram_client_cache.h index 84f03397cfd..0f8d6f8a55a 100644 --- a/src/mongo/client/scram_sha1_client_cache.h +++ b/src/mongo/client/scram_client_cache.h @@ -60,7 +60,12 @@ namespace mongo { * reauthentication. This might be useful for mobile clients where * CPU usage is a concern." */ -class SCRAMSHA1ClientCache { +template <typename HashBlock> +class SCRAMClientCache { +private: + using HostToSecretsPair = std::pair<scram::Presecrets<HashBlock>, scram::Secrets<HashBlock>>; + using HostToSecretsMap = stdx::unordered_map<HostAndPort, HostToSecretsPair>; + public: /** * Returns precomputed SCRAMSecrets, if one has already been @@ -68,21 +73,53 @@ public: * match those recorded for the hostname. Otherwise, no secrets * are returned. */ - scram::SHA1Secrets getCachedSecrets(const HostAndPort& target, - const scram::SHA1Presecrets& presecrets) const; + scram::Secrets<HashBlock> getCachedSecrets( + const HostAndPort& target, const scram::Presecrets<HashBlock>& presecrets) const { + const stdx::lock_guard<stdx::mutex> lock(_hostToSecretsMutex); + + // Search the cache for a record associated with the host we're trying to connect to. + auto foundSecret = _hostToSecrets.find(target); + if (foundSecret == _hostToSecrets.end()) { + return {}; + } + + // Presecrets contain parameters provided by the server, which may change. If the + // cached presecrets don't match the presecrets we have on hand, we must not return the + // stale cached secrets. We'll need to rerun the SCRAM computation. + const auto& foundPresecrets = foundSecret->second.first; + if (foundPresecrets == presecrets) { + return foundSecret->second.second; + } else { + return {}; + } + } /** * Records a set of precomputed SCRAMSecrets for the specified * host, along with the presecrets used to generate them. */ void setCachedSecrets(HostAndPort target, - scram::SHA1Presecrets presecrets, - scram::SHA1Secrets secrets); + scram::Presecrets<HashBlock> presecrets, + scram::Secrets<HashBlock> secrets) { + const stdx::lock_guard<stdx::mutex> lock(_hostToSecretsMutex); + + typename HostToSecretsMap::iterator it; + bool insertionSuccessful; + auto cacheRecord = std::make_pair(std::move(presecrets), std::move(secrets)); + // Insert the presecrets, and the secrets we computed for them into the cache + std::tie(it, insertionSuccessful) = _hostToSecrets.emplace(std::move(target), cacheRecord); + // If there was already a cache entry for the target HostAndPort, we should overwrite it. + // We have fresher presecrets and secrets. + if (!insertionSuccessful) { + it->second = std::move(cacheRecord); + } + } private: mutable stdx::mutex _hostToSecretsMutex; - stdx::unordered_map<HostAndPort, std::pair<scram::SHA1Presecrets, scram::SHA1Secrets>> - _hostToSecrets; + HostToSecretsMap _hostToSecrets; }; +using SCRAMSHA1ClientCache = SCRAMClientCache<SHA1Block>; + } // namespace mongo diff --git a/src/mongo/client/scram_sha1_client_cache.cpp b/src/mongo/client/scram_sha1_client_cache.cpp deleted file mode 100644 index 87f72c011da..00000000000 --- a/src/mongo/client/scram_sha1_client_cache.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/** - * Copyright (C) 2017 MongoDB Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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 - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * 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 GNU Affero General 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/scram_sha1_client_cache.h" - -namespace mongo { - -scram::SHA1Secrets SCRAMSHA1ClientCache::getCachedSecrets( - const HostAndPort& target, const scram::SHA1Presecrets& presecrets) const { - const stdx::lock_guard<stdx::mutex> lock(_hostToSecretsMutex); - - // Search the cache for a record associated with the host we're trying to connect to. - auto foundSecret = _hostToSecrets.find(target); - if (foundSecret != _hostToSecrets.end()) { - // Presecrets contain parameters provided by the server, which may change. If the - // cached presecrets don't match the presecrets we have on hand, we must not return the - // stale cached secrets. We'll need to rerun the SCRAM computation. - const scram::SHA1Presecrets& foundPresecrets = foundSecret->second.first; - if (foundPresecrets == presecrets) { - return foundSecret->second.second; - } - } - return {}; -} - -void SCRAMSHA1ClientCache::setCachedSecrets(HostAndPort target, - scram::SHA1Presecrets presecrets, - scram::SHA1Secrets secrets) { - const stdx::lock_guard<stdx::mutex> lock(_hostToSecretsMutex); - - decltype(_hostToSecrets)::iterator it; - bool insertionSuccessful; - auto cacheRecord = std::make_pair(std::move(presecrets), std::move(secrets)); - // Insert the presecrets, and the secrets we computed for them into the cache - std::tie(it, insertionSuccessful) = _hostToSecrets.emplace(std::move(target), cacheRecord); - // If there was already a cache entry for the target HostAndPort, we should overwrite it. - // We have fresher presecrets and secrets. - if (!insertionSuccessful) { - it->second = std::move(cacheRecord); - } -} - -} // namespace mongo |