Skip to content

Commit 0fab563

Browse files
authored
XDB-402 decode password (#206)
1 parent a57eae0 commit 0fab563

3 files changed

Lines changed: 100 additions & 3 deletions

File tree

fdbcli/fdbcli.actor.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ enum {
105105
OPT_DEBUG_TLS,
106106
OPT_API_VERSION,
107107
OPT_MEMORY,
108-
OPT_USE_FUTURE_PROTOCOL_VERSION
108+
OPT_USE_FUTURE_PROTOCOL_VERSION,
109+
OPT_ENCRYPT
109110
};
110111

111112
CSimpleOpt::SOption g_rgOptions[] = { { OPT_CONNFILE, "-C", SO_REQ_SEP },
@@ -132,6 +133,7 @@ CSimpleOpt::SOption g_rgOptions[] = { { OPT_CONNFILE, "-C", SO_REQ_SEP },
132133
{ OPT_API_VERSION, "--api-version", SO_REQ_SEP },
133134
{ OPT_MEMORY, "--memory", SO_REQ_SEP },
134135
{ OPT_USE_FUTURE_PROTOCOL_VERSION, "--use-future-protocol-version", SO_NONE },
136+
{ OPT_ENCRYPT, "--encrypt", SO_REQ_SEP },
135137
TLS_OPTION_FLAGS,
136138
SO_END_OF_OPTIONS };
137139

@@ -506,6 +508,11 @@ static void printProgramUsage(const char* name) {
506508
" --use-future-protocol-version\n"
507509
" Use the simulated future protocol version to connect to the cluster.\n"
508510
" This option can be used testing purposes only!\n"
511+
" --encrypt PASSWORD\n"
512+
" Encrypts the specified password and prints the encrypted password\n"
513+
" with the `encrypted:' prefix. The encrypted password can be used\n"
514+
" with --tls-password option. This option causes fdbcli to encrypt\n"
515+
" the password and exit.\n"
509516
" -v, --version Print FoundationDB CLI version information and exit.\n"
510517
" -h, --help Display this help and exit.\n");
511518
}
@@ -906,7 +913,6 @@ void LogCommand(std::string line, UID randomID, std::string errMsg) {
906913
printf("%s\n", errMsg.c_str());
907914
TraceEvent(SevInfo, "CLICommandLog", randomID).detail("Command", line).detail("Error", errMsg);
908915
}
909-
910916
struct CLIOptions {
911917
std::string program_name;
912918
int exit_code = -1;
@@ -932,6 +938,7 @@ struct CLIOptions {
932938
std::string tlsPassword;
933939
bool tlsDisablePlainTextConnection = false;
934940
uint64_t memLimit = 8uLL << 30;
941+
Optional<std::string> encrypt;
935942

936943
std::vector<std::pair<std::string, std::string>> knobs;
937944

@@ -1077,6 +1084,9 @@ struct CLIOptions {
10771084
knobs.emplace_back(knobName.get(), args.OptionArg());
10781085
break;
10791086
}
1087+
case OPT_ENCRYPT:
1088+
encrypt = args.OptionArg();
1089+
break;
10801090
case OPT_DEBUG_TLS:
10811091
debugTLS = true;
10821092
break;
@@ -2430,6 +2440,16 @@ int main(int argc, char** argv) {
24302440
if (opt.exit_code != -1)
24312441
return opt.exit_code;
24322442

2443+
if (opt.encrypt.present()) {
2444+
std::string encrypted;
2445+
if (!TLSConfig::encodePassword(opt.encrypt.get(), encrypted)) {
2446+
fprintf(stderr, "ERROR: Failed to encrypt password\n");
2447+
return 1;
2448+
}
2449+
printf("%s\n", encrypted.c_str());
2450+
return 0;
2451+
}
2452+
24332453
if (opt.trace) {
24342454
if (opt.traceDir.empty())
24352455
setNetworkOption(FDBNetworkOptions::TRACE_ENABLE);

flow/TLSConfig.actor.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,3 +1037,78 @@ bool TLSPolicy::verify_peer(bool preverified, X509_STORE_CTX* store_ctx, const N
10371037

10381038
return verifier.isOk();
10391039
}
1040+
struct CryptoLibHandle {
1041+
void* lib = nullptr;
1042+
void* func = nullptr;
1043+
1044+
CryptoLibHandle(std::string_view funcName) {
1045+
const char* libName = "libnscipher-crypto.so";
1046+
lib = loadLibrary(libName);
1047+
if (!lib) {
1048+
TraceEvent(SevError, "ExternalLibLoadError").detail("Library", libName);
1049+
return;
1050+
}
1051+
func = loadFunction(lib, funcName.data());
1052+
if (!func) {
1053+
TraceEvent(SevError, "ExternalLibFunctionLoadError")
1054+
.detail("Function", funcName)
1055+
.detail("Library", libName);
1056+
fprintf(stderr, "ERROR: Failed to load '%s' function\n", funcName.data());
1057+
closeLibrary(lib);
1058+
lib = nullptr;
1059+
}
1060+
}
1061+
explicit operator bool() const { return func != nullptr; }
1062+
~CryptoLibHandle() {
1063+
if (lib)
1064+
closeLibrary(lib);
1065+
}
1066+
};
1067+
1068+
static bool processWithCrypto(std::string_view funcName, const std::string& input, std::string& output) {
1069+
constexpr int bufLen = 1024; // Assume max size of encrypted and decrypted password is 1024
1070+
CryptoLibHandle cryptoHandle(funcName);
1071+
1072+
if (!cryptoHandle) {
1073+
return false;
1074+
}
1075+
1076+
int outputLen = bufLen;
1077+
1078+
char buf[bufLen]{};
1079+
1080+
auto func = reinterpret_cast<int (*)(const char*, char*, int*)>(cryptoHandle.func);
1081+
if (int rc = func(input.c_str(), buf, &outputLen); rc != 0) {
1082+
fprintf(stderr, "ERROR: Failed to exec function (rc=%d)\n", rc);
1083+
TraceEvent(SevError, "ErrorExecFunction").detail("ReturnCode", rc);
1084+
return false;
1085+
}
1086+
output.assign(buf, outputLen);
1087+
return true;
1088+
}
1089+
1090+
constexpr std::string_view encryptedPrefix = "encrypted:";
1091+
1092+
bool TLSConfig::encodePassword(const std::string& plainPassword, std::string& encoded) {
1093+
if (processWithCrypto("crypt", plainPassword, encoded)) {
1094+
encoded.insert(0, encryptedPrefix);
1095+
return true;
1096+
}
1097+
return false;
1098+
}
1099+
1100+
void TLSConfig::setPassword(const std::string& password) {
1101+
if (password.size() > encryptedPrefix.size() && password.starts_with(encryptedPrefix)) {
1102+
1103+
std::string decoded;
1104+
1105+
if (processWithCrypto("decrypt", password.substr(encryptedPrefix.size()), decoded)) {
1106+
tlsPassword = std::move(decoded);
1107+
} else {
1108+
tlsPassword.clear();
1109+
TraceEvent(SevError, "FailedToDecryptPassword");
1110+
}
1111+
} else {
1112+
tlsPassword = password;
1113+
}
1114+
}

flow/include/flow/TLSConfig.actor.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,9 @@ class TLSConfig {
184184

185185
void setDisablePlainTextConnection(const bool val) { tlsDisablePlainTextConnection = val; }
186186

187-
void setPassword(const std::string& password) { tlsPassword = password; }
187+
void setPassword(const std::string& password);
188+
189+
static bool encodePassword(const std::string& plainPassword, std::string& encoded);
188190

189191
void clearVerifyPeers() { tlsVerifyPeers.clear(); }
190192

0 commit comments

Comments
 (0)