diff options
author | Jonathan Reams <jbreams@mongodb.com> | 2018-10-31 12:39:31 -0400 |
---|---|---|
committer | Jonathan Reams <jbreams@mongodb.com> | 2018-11-07 10:20:26 -0500 |
commit | 8c2c95edbdf32e88868396cf6927a9346bbc85e4 (patch) | |
tree | 93c9d6a919005c1063efb272c1c216c53e2b2b01 /src/mongo/db/auth/sasl_scram_server_conversation.cpp | |
parent | 514873667fbb5fa62a245a936826bc71f73b87e8 (diff) | |
download | mongo-8c2c95edbdf32e88868396cf6927a9346bbc85e4.tar.gz |
SERVER-37833 Retry internal auth with alternate key during keyfile rollover
Diffstat (limited to 'src/mongo/db/auth/sasl_scram_server_conversation.cpp')
-rw-r--r-- | src/mongo/db/auth/sasl_scram_server_conversation.cpp | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/src/mongo/db/auth/sasl_scram_server_conversation.cpp b/src/mongo/db/auth/sasl_scram_server_conversation.cpp index 8919f51dd96..0e11a6238bf 100644 --- a/src/mongo/db/auth/sasl_scram_server_conversation.cpp +++ b/src/mongo/db/auth/sasl_scram_server_conversation.cpp @@ -204,9 +204,9 @@ StatusWith<std::tuple<bool, std::string>> SaslSCRAMServerMechanism<Policy>::_fir User::CredentialData credentials = userObj->getCredentials(); UserName userName = userObj->getName(); - _scramCredentials = credentials.scram<HashBlock>(); + auto scramCredentials = credentials.scram<HashBlock>(); - if (!_scramCredentials.isValid()) { + if (!scramCredentials.isValid()) { // Check for authentication attempts of the __system user on // systems started without a keyfile. if (userName == internalSecurity.user->getName()) { @@ -220,9 +220,16 @@ StatusWith<std::tuple<bool, std::string>> SaslSCRAMServerMechanism<Policy>::_fir } } - _secrets = scram::Secrets<HashBlock>("", - base64::decode(_scramCredentials.storedKey), - base64::decode(_scramCredentials.serverKey)); + _secrets.push_back(scram::Secrets<HashBlock>("", + base64::decode(scramCredentials.storedKey), + base64::decode(scramCredentials.serverKey))); + + if (userName == internalSecurity.user->getName() && internalSecurity.alternateCredentials) { + auto altCredentials = internalSecurity.alternateCredentials->scram<HashBlock>(); + _secrets.push_back(scram::Secrets<HashBlock>("", + base64::decode(altCredentials.storedKey), + base64::decode(altCredentials.serverKey))); + } // Generate server-first-message // Create text-based nonce as base64 encoding of a binary blob of length multiple of 3 @@ -238,8 +245,8 @@ StatusWith<std::tuple<bool, std::string>> SaslSCRAMServerMechanism<Policy>::_fir _nonce = clientNonce + base64::encode(reinterpret_cast<char*>(binaryNonce), sizeof(binaryNonce)); StringBuilder sb; - sb << "r=" << _nonce << ",s=" << _scramCredentials.salt - << ",i=" << _scramCredentials.iterationCount; + sb << "r=" << _nonce << ",s=" << scramCredentials.salt + << ",i=" << scramCredentials.iterationCount; std::string outputData = sb.str(); // add client-first-message-bare and server-first-message to _authMessage @@ -327,14 +334,25 @@ StatusWith<std::tuple<bool, std::string>> SaslSCRAMServerMechanism<Policy>::_sec // ClientKey := ClientSignature XOR ClientProof // ServerSignature := HMAC(ServerKey, AuthMessage) - if (!_secrets.verifyClientProof(_authMessage, base64::decode(proof.toString()))) { + const auto decodedProof = base64::decode(proof.toString()); + std::string serverSignature; + const auto checkSecret = [&](const scram::Secrets<HashBlock>& secret) { + if (!secret.verifyClientProof(_authMessage, decodedProof)) + return false; + + serverSignature = secret.generateServerSignature(_authMessage); + return true; + }; + + if (!std::any_of(_secrets.begin(), _secrets.end(), checkSecret)) { return Status(ErrorCodes::AuthenticationFailed, "SCRAM authentication failed, storedKey mismatch"); } + invariant(!serverSignature.empty()); StringBuilder sb; // ServerSignature := HMAC(ServerKey, AuthMessage) - sb << "v=" << _secrets.generateServerSignature(_authMessage); + sb << "v=" << serverSignature; return std::make_tuple(false, sb.str()); } |