mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 17:10:48 +01:00
SERVER-17991 Refactor security key file reading / support base64 padding.
This commit is contained in:
parent
deb117ad90
commit
b057c6a2a2
@ -36,6 +36,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "mongo/base/status_with.h"
|
||||
#include "mongo/client/sasl_client_authenticate.h"
|
||||
#include "mongo/crypto/mechanism_scram.h"
|
||||
#include "mongo/db/auth/action_set.h"
|
||||
@ -51,73 +52,25 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
using std::endl;
|
||||
using std::string;
|
||||
|
||||
bool setUpSecurityKey(const string& filename) {
|
||||
struct stat stats;
|
||||
|
||||
// check obvious file errors
|
||||
if (stat(filename.c_str(), &stats) == -1) {
|
||||
log() << "error getting file " << filename << ": " << strerror(errno) << endl;
|
||||
StatusWith<std::string> keyString = readSecurityFile(filename);
|
||||
if (!keyString.isOK()) {
|
||||
log() << keyString.getStatus().reason();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
// check permissions: must be X00, where X is >= 4
|
||||
if ((stats.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
|
||||
log() << "permissions on " << filename << " are too open" << endl;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
if (!file) {
|
||||
log() << "error opening file: " << filename << ": " << strerror(errno) << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
string str = "";
|
||||
|
||||
// strip key file
|
||||
const unsigned long long fileLength = stats.st_size;
|
||||
unsigned long long read = 0;
|
||||
while (read < fileLength) {
|
||||
char buf;
|
||||
int readLength = fread(&buf, 1, 1, file);
|
||||
if (readLength < 1) {
|
||||
log() << "error reading file " << filename << endl;
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
read++;
|
||||
|
||||
// check for whitespace
|
||||
if ((buf >= '\x09' && buf <= '\x0D') || buf == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check valid base64
|
||||
if ((buf < 'A' || buf > 'Z') && (buf < 'a' || buf > 'z') && (buf < '0' || buf > '9') &&
|
||||
buf != '+' && buf != '/') {
|
||||
log() << "invalid char in key file " << filename << ": " << buf << endl;
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
str += buf;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
std::string str = std::move(keyString.getValue());
|
||||
const unsigned long long keyLength = str.size();
|
||||
if (keyLength < 6 || keyLength > 1024) {
|
||||
log() << " security key in " << filename << " has length " << keyLength
|
||||
<< ", must be between 6 and 1024 chars" << endl;
|
||||
<< ", must be between 6 and 1024 chars";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate MONGODB-CR and SCRAM credentials for the internal user based on the keyfile.
|
||||
// Generate MONGODB-CR and SCRAM credentials for the internal user based on
|
||||
// the keyfile.
|
||||
User::CredentialData credentials;
|
||||
credentials.password =
|
||||
mongo::createPasswordDigest(internalSecurity.user->getName().getUser().toString(), str);
|
||||
@ -141,7 +94,70 @@ bool setUpSecurityKey(const string& filename) {
|
||||
<< internalSecurity.user->getName().getUser() << saslCommandPasswordFieldName
|
||||
<< credentials.password << saslCommandDigestPasswordFieldName << false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
StatusWith<std::string> readSecurityFile(const std::string& filename) {
|
||||
struct stat stats;
|
||||
|
||||
// check obvious file errors
|
||||
if (stat(filename.c_str(), &stats) == -1) {
|
||||
return StatusWith<std::string>(ErrorCodes::InvalidPath,
|
||||
str::stream() << "error getting file " << filename << ": "
|
||||
<< strerror(errno));
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
// check permissions: must be X00, where X is >= 4
|
||||
if ((stats.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
|
||||
return StatusWith<std::string>(ErrorCodes::InvalidPath,
|
||||
str::stream() << "permissions on " << filename
|
||||
<< " are too open");
|
||||
}
|
||||
#endif
|
||||
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
if (!file) {
|
||||
return StatusWith<std::string>(ErrorCodes::InvalidPath,
|
||||
str::stream() << "error opening file: " << filename << ": "
|
||||
<< strerror(errno));
|
||||
}
|
||||
|
||||
string str = "";
|
||||
|
||||
// strip key file
|
||||
const unsigned long long fileLength = stats.st_size;
|
||||
unsigned long long read = 0;
|
||||
while (read < fileLength) {
|
||||
char buf;
|
||||
int readLength = fread(&buf, 1, 1, file);
|
||||
if (readLength < 1) {
|
||||
fclose(file);
|
||||
return StatusWith<std::string>(ErrorCodes::UnsupportedFormat,
|
||||
str::stream() << "error reading file: " << filename);
|
||||
}
|
||||
read++;
|
||||
|
||||
// check for whitespace
|
||||
if ((buf >= '\x09' && buf <= '\x0D') || buf == ' ') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check valid base64
|
||||
if ((buf < 'A' || buf > 'Z') && (buf < 'a' || buf > 'z') && (buf < '0' || buf > '9') &&
|
||||
buf != '+' && buf != '/' && buf != '=') {
|
||||
fclose(file);
|
||||
return StatusWith<std::string>(ErrorCodes::UnsupportedFormat,
|
||||
str::stream() << "invalid char in key file " << filename
|
||||
<< ": " << buf);
|
||||
}
|
||||
|
||||
str += buf;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return StatusWith<std::string>(str);
|
||||
}
|
||||
|
||||
} // namespace mongo
|
||||
|
@ -31,6 +31,9 @@
|
||||
#include <string>
|
||||
|
||||
namespace mongo {
|
||||
template <class T>
|
||||
class StatusWith;
|
||||
|
||||
/**
|
||||
* This method checks the validity of filename as a security key, hashes its
|
||||
* contents, and stores it in the internalSecurity variable. Prints an
|
||||
@ -40,4 +43,10 @@ namespace mongo {
|
||||
*/
|
||||
bool setUpSecurityKey(const std::string& filename);
|
||||
|
||||
/**
|
||||
* This method takes in a filename and returns the contents as a string.
|
||||
* It checks that the contents are valid base 64 characters.
|
||||
*/
|
||||
StatusWith<std::string> readSecurityFile(const std::string& filename);
|
||||
|
||||
} // namespace mongo
|
||||
|
Loading…
Reference in New Issue
Block a user