Skip to content

Commit cadebf6

Browse files
authored
XDB-402 decode password (#205)
1 parent 4b2819e commit cadebf6

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
@@ -104,7 +104,8 @@ enum {
104104
OPT_DEBUG_TLS,
105105
OPT_API_VERSION,
106106
OPT_MEMORY,
107-
OPT_USE_FUTURE_PROTOCOL_VERSION
107+
OPT_USE_FUTURE_PROTOCOL_VERSION,
108+
OPT_ENCRYPT
108109
};
109110

110111
CSimpleOpt::SOption g_rgOptions[] = { { OPT_CONNFILE, "-C", SO_REQ_SEP },
@@ -130,6 +131,7 @@ CSimpleOpt::SOption g_rgOptions[] = { { OPT_CONNFILE, "-C", SO_REQ_SEP },
130131
{ OPT_API_VERSION, "--api-version", SO_REQ_SEP },
131132
{ OPT_MEMORY, "--memory", SO_REQ_SEP },
132133
{ OPT_USE_FUTURE_PROTOCOL_VERSION, "--use-future-protocol-version", SO_NONE },
134+
{ OPT_ENCRYPT, "--encrypt", SO_REQ_SEP },
133135
TLS_OPTION_FLAGS,
134136
SO_END_OF_OPTIONS };
135137

@@ -503,6 +505,11 @@ static void printProgramUsage(const char* name) {
503505
" --use-future-protocol-version\n"
504506
" Use the simulated future protocol version to connect to the cluster.\n"
505507
" This option can be used testing purposes only!\n"
508+
" --encrypt PASSWORD\n"
509+
" Encrypts the specified password and prints the encrypted password\n"
510+
" with the `encrypted:' prefix. The encrypted password can be used\n"
511+
" with --tls-password option. This option causes fdbcli to encrypt\n"
512+
" the password and exit.\n"
506513
" -v, --version Print FoundationDB CLI version information and exit.\n"
507514
" -h, --help Display this help and exit.\n");
508515
}
@@ -903,7 +910,6 @@ void LogCommand(std::string line, UID randomID, std::string errMsg) {
903910
printf("%s\n", errMsg.c_str());
904911
TraceEvent(SevInfo, "CLICommandLog", randomID).detail("Command", line).detail("Error", errMsg);
905912
}
906-
907913
struct CLIOptions {
908914
std::string program_name;
909915
int exit_code = -1;
@@ -928,6 +934,7 @@ struct CLIOptions {
928934
std::string tlsPassword;
929935
bool tlsDisablePlainTextConnection = false;
930936
uint64_t memLimit = 8uLL << 30;
937+
Optional<std::string> encrypt;
931938

932939
std::vector<std::pair<std::string, std::string>> knobs;
933940

@@ -1070,6 +1077,9 @@ struct CLIOptions {
10701077
knobs.emplace_back(knobName.get(), args.OptionArg());
10711078
break;
10721079
}
1080+
case OPT_ENCRYPT:
1081+
encrypt = args.OptionArg();
1082+
break;
10731083
case OPT_DEBUG_TLS:
10741084
debugTLS = true;
10751085
break;
@@ -2450,6 +2460,16 @@ int main(int argc, char** argv) {
24502460
if (opt.exit_code != -1)
24512461
return opt.exit_code;
24522462

2463+
if (opt.encrypt.present()) {
2464+
std::string encrypted;
2465+
if (!TLSConfig::encodePassword(opt.encrypt.get(), encrypted)) {
2466+
fprintf(stderr, "ERROR: Failed to encrypt password\n");
2467+
return 1;
2468+
}
2469+
printf("%s\n", encrypted.c_str());
2470+
return 0;
2471+
}
2472+
24532473
if (opt.trace) {
24542474
if (opt.traceDir.empty())
24552475
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)