client: fix GUI RPC password generation bug on Win

Apparently when Win runs in a VM, the random number generation functions
(e.g. CryptGenRandom()) don't work.
We weren't checking for this, resulting in a garbage (and guessable) password.

Also change function names to indicate that string is not just random,
but also hard to guess.
This commit is contained in:
David Anderson 2019-11-28 00:50:31 -08:00
parent 7cc24a102b
commit 10fdef0cdd
7 changed files with 45 additions and 27 deletions

View File

@ -142,17 +142,7 @@ void GUI_RPC_CONN_SET::get_password() {
// if no password file, make a random password
//
retval = make_random_string(password);
if (retval) {
if (cc_config.os_random_only) {
msg_printf(
NULL, MSG_INTERNAL_ERROR,
"OS random string generation failed, exiting"
);
exit(1);
}
gstate.host_info.make_random_string("guirpc", password);
}
make_secure_random_string(password);
// try to write it to the file.
// if fail, just return

View File

@ -1377,7 +1377,7 @@ void handle_get_auth_id(MIOFILE& fout) {
AUTH_INFO ai;
ai.id = id++;
ai.seqno = 0;
make_random_string(ai.salt);
make_secure_random_string(ai.salt);
auth_infos.push_back(ai);
fout.printf("<auth_id>%d</auth_id>\n<auth_salt>%s</auth_salt>\n", ai.id, ai.salt);
}

View File

@ -53,6 +53,7 @@
#include "util.h"
#include "client_msgs.h"
#include "client_state.h"
#include "hostinfo.h"
@ -119,6 +120,20 @@ void HOST_INFO::make_random_string(const char* salt, char* out) {
md5_block((const unsigned char*) buf, (int)strlen(buf), out);
}
void make_secure_random_string(char* out) {
int retval = make_secure_random_string_os(out);
if (retval) {
if (cc_config.os_random_only) {
msg_printf(
NULL, MSG_INTERNAL_ERROR,
"OS random string generation failed, exiting"
);
exit(1);
}
gstate.host_info.make_random_string("guirpc", out);
}
}
// make a host cross-project ID.
// Should be unique across hosts with very high probability
//

View File

@ -192,8 +192,8 @@ static void init_core_client(int argc, char** argv) {
#ifdef _WIN32
if (!cc_config.allow_multiple_clients && !gstate.cmdline_dir) {
chdir_to_data_dir();
#endif
}
#endif
#ifndef _WIN32
if (g_use_sandbox)

View File

@ -104,7 +104,10 @@ public:
bool host_is_running_on_batteries();
#ifdef __APPLE__
bool users_idle(bool check_all_logins, double idle_time_to_run, double *actual_idle_time=NULL);
bool users_idle(
bool check_all_logins, double idle_time_to_run,
double *actual_idle_time=NULL
);
#else
bool users_idle(bool check_all_logins, double idle_time_to_run);
#endif
@ -120,14 +123,26 @@ public:
void clear_host_info();
void make_random_string(const char* salt, char* out);
void generate_host_cpid();
static bool parse_linux_os_info(FILE* file, const LINUX_OS_INFO_PARSER parser,
char* os_name, const int os_name_size, char* os_version, const int os_version_size);
static bool parse_linux_os_info(const std::string& line, const LINUX_OS_INFO_PARSER parser,
char* os_name, const int os_name_size, char* os_version, const int os_version_size);
static bool parse_linux_os_info(const std::vector<std::string>& lines, const LINUX_OS_INFO_PARSER parser,
char* os_name, const int os_name_size, char* os_version, const int os_version_size);
static bool parse_linux_os_info(
FILE* file, const LINUX_OS_INFO_PARSER parser,
char* os_name, const int os_name_size, char* os_version,
const int os_version_size
);
static bool parse_linux_os_info(
const std::string& line, const LINUX_OS_INFO_PARSER parser,
char* os_name, const int os_name_size, char* os_version,
const int os_version_size
);
static bool parse_linux_os_info(
const std::vector<std::string>& lines,
const LINUX_OS_INFO_PARSER parser,
char* os_name, const int os_name_size, char* os_version,
const int os_version_size
);
};
extern void make_secure_random_string(char*);
#ifdef _WIN64
int get_wsl_information(bool& wsl_available, WSLS& wsls);
#endif

View File

@ -125,10 +125,10 @@ std::string md5_string(const unsigned char* data, int nbytes) {
return std::string(output);
}
// make a random 32-char string
// (the MD5 of some quasi-random bits)
// make a secure (i.e. hard to guess)
// 32-char string using OS-supplied random bits
//
int make_random_string(char* out) {
int make_secure_random_string_os(char* out) {
char buf[256];
#ifdef _WIN32
HCRYPTPROV hCryptProv;
@ -144,9 +144,7 @@ int make_random_string(char* out) {
CryptReleaseContext(hCryptProv, 0);
#elif defined ANDROID
// /dev/random not available on Android, using stdlib function instead
int i = rand();
snprintf(buf, sizeof(buf), "%d", i);
return -1;
#else
#ifndef _USING_FCGI_
FILE* f = fopen("/dev/random", "r");

View File

@ -41,5 +41,5 @@ inline std::string md5_string(std::string const& data) {
return md5_string((const unsigned char*) data.c_str(), (int)data.size());
}
extern int make_random_string(char*);
extern int make_secure_random_string_os(char*);
#endif