SHA256Block getLogicalSessionUserDigestFor(StringData user, StringData db) { if (user.empty() && db.empty()) { return kNoAuthDigest; } const UserName un(user, db); const auto& fn = un.getFullName(); return SHA256Block::computeHash({ConstDataRange(fn.c_str(), fn.size())}); }
StatusWith<ConstDataRange> BlockCompressor::compress(ConstDataRange source) { z_stream stream; int level = Z_DEFAULT_COMPRESSION; stream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(source.data())); stream.avail_in = source.length(); // In compress.c in the zlib source, they recommend that the compression buffer be // at least 0.1% larger + 12 bytes then the source length. // We make the buffer 1% larger then the source length buffer to be on the safe side. If we are // too small, deflate returns an error. _buffer.resize(source.length() * 1.01 + 12); stream.next_out = _buffer.data(); stream.avail_out = _buffer.size(); stream.zalloc = nullptr; stream.zfree = nullptr; stream.opaque = nullptr; int err = deflateInit(&stream, level); if (err != Z_OK) { return {ErrorCodes::ZLibError, str::stream() << "deflateInit failed with " << err}; } err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { (void)deflateEnd(&stream); if (err != Z_OK) { return {ErrorCodes::ZLibError, str::stream() << "deflate failed with " << err}; } } err = deflateEnd(&stream); if (err != Z_OK) { return {ErrorCodes::ZLibError, str::stream() << "deflateEnd failed with " << err}; } return ConstDataRange(reinterpret_cast<char*>(_buffer.data()), stream.total_out); }
StatusWith<ConstDataRange> BlockCompressor::uncompress(ConstDataRange source, size_t uncompressedLength) { z_stream stream; stream.next_in = reinterpret_cast<unsigned char*>(const_cast<char*>(source.data())); stream.avail_in = source.length(); _buffer.resize(uncompressedLength); stream.next_out = _buffer.data(); stream.avail_out = _buffer.size(); stream.zalloc = nullptr; stream.zfree = nullptr; stream.opaque = nullptr; int err = inflateInit(&stream); if (err != Z_OK) { return {ErrorCodes::ZLibError, str::stream() << "inflateInit failed with " << err}; } err = inflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { (void)inflateEnd(&stream); if (err != Z_OK) { return {ErrorCodes::ZLibError, str::stream() << "inflate failed with " << err}; } } err = inflateEnd(&stream); if (err != Z_OK) { return {ErrorCodes::ZLibError, str::stream() << "inflateEnd failed with " << err}; } return ConstDataRange(reinterpret_cast<char*>(_buffer.data()), stream.total_out); }
TEST(SSLManager, MongoDBRolesParser) { /* openssl asn1parse -genconf mongodbroles.cnf -out foo.der -------- mongodbroles.cnf -------- asn1 = SET:MongoDBAuthorizationGrant [MongoDBAuthorizationGrant] grant1 = SEQUENCE:MongoDBRole [MongoDBRole] role = UTF8:role_name database = UTF8:Third field */ // Positive: Simple parsing test { unsigned char derData[] = {0x31, 0x1a, 0x30, 0x18, 0x0c, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x0c, 0x0b, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_OK(swPeer.getStatus()); auto item = *(swPeer.getValue().begin()); ASSERT_EQ(item.getRole(), "role_name"); ASSERT_EQ(item.getDB(), "Third field"); } // Positive: Very long role_name, and long form lengths { unsigned char derData[] = { 0x31, 0x82, 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x0c, 0x82, 0x01, 0x29, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x0c, 0x0b, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_OK(swPeer.getStatus()); auto item = *(swPeer.getValue().begin()); ASSERT_EQ(item.getRole(), "role_namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_" "namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_" "namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_" "namerole_namerole_namerole_namerole_namerole_namerole_namerole_namerole_name"); ASSERT_EQ(item.getDB(), "Third field"); } // Negative: Encode MAX_INT64 into a length { unsigned char derData[] = {0x31, 0x88, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x18, 0x0c, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x0c, 0x0b, 0x54, 0x68, 0x69, 0x72, 0x64, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Negative: Runt, only a tag { unsigned char derData[] = {0x31}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Negative: Runt, only a tag and short length { unsigned char derData[] = {0x31, 0x0b}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Negative: Runt, only a tag and long length with wrong missing length { unsigned char derData[] = { 0x31, 0x88, 0xff, 0xff, }; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Negative: Runt, only a tag and long length { unsigned char derData[] = { 0x31, 0x82, 0xff, 0xff, }; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Negative: Single UTF8 String { unsigned char derData[] = { 0x0c, 0x0b, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Negative: Unknown type - IAString { unsigned char derData[] = { 0x16, 0x0b, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_NOT_OK(swPeer.getStatus()); } // Positive: two roles { unsigned char derData[] = {0x31, 0x2b, 0x30, 0x0f, 0x0c, 0x06, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x0c, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x30, 0x18, 0x0c, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x41, 0x6e, 0x79, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x0c, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e}; auto swPeer = parsePeerRoles(ConstDataRange(reinterpret_cast<char*>(derData), std::extent<decltype(derData)>::value)); ASSERT_OK(swPeer.getStatus()); auto roles = getSortedRoles(swPeer.getValue()); ASSERT_EQ(roles[0].getRole(), "backup"); ASSERT_EQ(roles[0].getDB(), "admin"); ASSERT_EQ(roles[1].getRole(), "readAnyDatabase"); ASSERT_EQ(roles[1].getDB(), "admin"); } }