Introduce new variable admin-hash_passwords #676

New variable admin-hash_passwords , default true

When set, passwords in mysql_users are automatically hashed in runtime
when running LOAD MYSQL USERS TO RUNTIME.

For backward compatibility, passwords in mysql_users in memory and disk aren't
automatically hashed. Although, they can be easily hashed running
SAVE MYSQL USERS TO MEMORY (and eventually SAVE MYSQL USERS TO DISK)
immediately after running LOAD MYSQL USERS TO RUNTIME
pull/737/head
René Cannaò 10 years ago
parent 21fdb12e0b
commit 128ff3deda

@ -71,6 +71,7 @@ class ProxySQL_Admin {
char *telnet_admin_ifaces;
char *telnet_stats_ifaces;
bool admin_read_only;
bool hash_passwords;
char * admin_version;
#ifdef DEBUG
bool debug;

@ -54,6 +54,21 @@ char *s_strdup(char *s) {
return ret;
}
static char *sha1_pass_hex(char *sha1_pass) { // copied from MySQL_Protocol.cpp
if (sha1_pass==NULL) return NULL;
char *buff=(char *)malloc(SHA_DIGEST_LENGTH*2+2);
buff[0]='*';
buff[SHA_DIGEST_LENGTH*2+1]='\0';
int i;
uint8_t a;
for (i=0;i<SHA_DIGEST_LENGTH;i++) {
memcpy(&a,sha1_pass+i,1);
sprintf(buff+1+2*i, "%02X", a);
}
return buff;
}
static volatile int load_main_=0;
static volatile bool nostart_=false;
@ -166,6 +181,7 @@ static char * admin_variables_names[]= {
(char *)"telnet_stats_ifaces",
(char *)"refresh_interval",
(char *)"read_only",
(char *)"hash_passwords",
(char *)"version",
#ifdef DEBUG
(char *)"debug",
@ -2388,6 +2404,7 @@ ProxySQL_Admin::ProxySQL_Admin() {
//variables.telnet_admin_ifaces=strdup("127.0.0.1:6030");
//variables.telnet_stats_ifaces=strdup("127.0.0.1:6031");
variables.refresh_interval=2000;
variables.hash_passwords=true; // issue #676
variables.admin_read_only=false; // by default, the admin interface accepts writes
variables.admin_version=(char *)PROXYSQL_VERSION;
#ifdef DEBUG
@ -2919,6 +2936,9 @@ char * ProxySQL_Admin::get_variable(char *name) {
if (!strcasecmp(name,"read_only")) {
return strdup((variables.admin_read_only ? "true" : "false"));
}
if (!strcasecmp(name,"hash_passwords")) {
return strdup((variables.hash_passwords ? "true" : "false"));
}
#ifdef DEBUG
if (!strcasecmp(name,"debug")) {
return strdup((variables.debug ? "true" : "false"));
@ -3094,6 +3114,17 @@ bool ProxySQL_Admin::set_variable(char *name, char *value) { // this is the pub
return false;
}
}
if (!strcasecmp(name,"hash_passwords")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.hash_passwords=true;
return true;
}
if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) {
variables.hash_passwords=false;
return true;
}
return false;
}
if (!strcasecmp(name,"read_only")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.admin_read_only=true;
@ -3752,9 +3783,38 @@ void ProxySQL_Admin::__add_active_users(enum cred_username_type usertype) {
} else {
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
char *password=NULL;
if (variables.hash_passwords) { // We must use hashed password. See issue #676
// Admin needs to hash the password
if (r->fields[1] && strlen(r->fields[1])) {
if (r->fields[1][0]=='*') { // the password is already hashed
password=strdup(r->fields[1]);
} else { // we must hash it
uint8 hash_stage1[SHA_DIGEST_LENGTH];
uint8 hash_stage2[SHA_DIGEST_LENGTH];
SHA_CTX sha1_context;
SHA1_Init(&sha1_context);
SHA1_Update(&sha1_context, r->fields[1], strlen(r->fields[1]));
SHA1_Final(hash_stage1, &sha1_context);
SHA1_Init(&sha1_context);
SHA1_Update(&sha1_context,hash_stage1,SHA_DIGEST_LENGTH);
SHA1_Final(hash_stage2, &sha1_context);
password=sha1_pass_hex((char *)hash_stage2); // note that sha1_pass_hex() returns a new buffer
}
} else {
password=strdup((char *)""); // we also generate a new string if hash_passwords is set
}
} else {
if (r->fields[1]) {
password=r->fields[1];
} else {
password=(char *)"";
}
}
GloMyAuth->add(
r->fields[0], // username
(r->fields[1]==NULL ? (char *)"" : r->fields[1]), //password
//(r->fields[1]==NULL ? (char *)"" : r->fields[1]), //password
password, // before #676, wewere always passing the password. Now it is possible that the password can be hashed
usertype, // backend/frontend
(strcmp(r->fields[2],"1")==0 ? true : false) , // use_ssl
atoi(r->fields[3]), // default_hostgroup
@ -3765,6 +3825,9 @@ void ProxySQL_Admin::__add_active_users(enum cred_username_type usertype) {
(strcmp(r->fields[7],"1")==0 ? true : false), // fast_forward
( atoi(r->fields[8])>0 ? atoi(r->fields[8]) : 0) // max_connections
);
if (variables.hash_passwords) {
free(password); // because we always generate a new string
}
}
}
// if (error) free(error);

Loading…
Cancel
Save