From 717f24ce4898bd228a5bb2c906b6cbf34f82041b Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Thu, 25 Sep 2014 13:08:12 +0200 Subject: [PATCH] Added first support for user@x.y.z.% Added first support for user@x.y.z.% --- server/core/dbusers.c | 50 +++++++++++++++++++------- server/modules/protocol/mysql_common.c | 32 +++++++++++------ 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 4f8de392b..5bb8bc320 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -313,29 +313,53 @@ getUsers(SERVICE *service, struct users *users) char ret_ip[INET_ADDRSTRLEN + 1]=""; const char *rc; + int found_range=0; + int found_any=0; /* prepare the user@host data struct */ memset(&serv_addr, 0, sizeof(serv_addr)); memset(&key, 0, sizeof(key)); - /* if host == '%', 0 is passed */ - if (setipaddress(&serv_addr.sin_addr, strcmp(row[1], "%") ? row[1] : "0.0.0.0")) { + /* set user */ + key.user = strdup(row[0]); - key.user = strdup(row[0]); + if(key.user == NULL) { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "%lu [getUsers()] strdup() failed for user %s", + pthread_self(), + row[0]))); - if(key.user == NULL) { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "%lu [getUsers()] strdup() failed for user %s", - pthread_self(), - row[0]))); + continue; + } - continue; + /* handle ANY, Class C */ + + /* if host == '%', 0 serv_addrkeeps its 0 */ + if (strcmp(row[1], "%") == 0) { + strcpy(ret_ip, "0.0.0.0"); + found_any = 1; + } else { + char *tmp; + strcpy(ret_ip, row[1]); + if ((tmp = strrchr(ret_ip, '%')) != NULL) { + // found class C + found_range = 1; + // set fake 1 + *tmp = '1'; } + } + + if (setipaddress(&serv_addr.sin_addr, ret_ip)) { memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); - - rc = inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN); + + if (found_range) { + /* let's zero the last IP byte: a.b.c.0 */ + key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; + } + + rc = inet_ntop(AF_INET, &(key.ipv4).sin_addr, ret_ip, INET_ADDRSTRLEN); /* add user@host as key and passwd as value in the MySQL users hash table */ if (mysql_users_add(users, &key, strlen(row[2]) ? row[2]+1 : row[2])) { @@ -563,6 +587,8 @@ char *mysql_format_user_entry(void *data) if (entry->ipv4.sin_addr.s_addr == INADDR_ANY) { snprintf(mysql_user, mysql_user_len, "%s@%%", entry->user); + } else if ( (entry->ipv4.sin_addr.s_addr & 0xFF000000) == 0) { + snprintf(mysql_user, mysql_user_len, "%s@%i.%i.%i.%%", entry->user, entry->ipv4.sin_addr.s_addr & 0x000000FF, (entry->ipv4.sin_addr.s_addr & 0x0000FF00) / (256), (entry->ipv4.sin_addr.s_addr & 0x00FF0000) / (256 * 256)); } else { strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN); strcat(mysql_user, "@"); diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 78e82cb86..280b07708 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -34,7 +34,6 @@ * */ -#include #include "mysql_client_server_protocol.h" #include #include @@ -742,7 +741,6 @@ int gw_do_connect_to_backend( struct sockaddr_in serv_addr; int rv; int so = 0; - int bufsize; memset(&serv_addr, 0, sizeof serv_addr); serv_addr.sin_family = AF_INET; @@ -766,10 +764,6 @@ int gw_do_connect_to_backend( /* prepare for connect */ setipaddress(&serv_addr.sin_addr, host); serv_addr.sin_port = htons(port); - bufsize = GW_CLIENT_SO_SNDBUF; - setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)); - bufsize = GW_CLIENT_SO_RCVBUF; - setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)); /* set socket to as non-blocking here */ setnonblocking(so); rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); @@ -1350,6 +1344,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, user_password = mysql_users_fetch(service->users, &key); if (!user_password) { + int lastbyte=0; /* The user is not authenticated @ current host */ /* 1) Check for localhost first. @@ -1368,16 +1363,33 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, return 1; } - - /* 2) Continue and check for wildcard host, user@% + + /* + * 2) try class C + * continue to wildcard if no match + */ + lastbyte = key.ipv4.sin_addr.s_addr & 0xFF000000; + + key.ipv4.sin_addr.s_addr &= 0x00FFFFFF; + + user_password = mysql_users_fetch(service->users, &key); + + if (user_password) { + if (strlen(user_password)) + gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2); + + return 0; + } + + /* 3) Continue and check for wildcard host, user@% * Return 1 if no match */ memset(&key.ipv4, 0, sizeof(struct sockaddr_in)); - LOGIF(LD, + LOGIF(LE, (skygw_log_write_flush( - LOGFILE_DEBUG, + LOGFILE_ERROR, "%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]", pthread_self(), key.user,