From 8d0f893bb8143a6c941e8e36abc7c6bf8c3675f8 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Mon, 17 Feb 2014 16:22:52 +0100 Subject: [PATCH 1/2] Added test file for mysql authentication (user@host, passwd) Added test file for mysql authentication (user@host, passwd) make -f ./makefile.mysql_users testall --- server/core/test/makefile.mysql_users | 32 ++++ server/core/test/test_mysql_users.c | 207 ++++++++++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 server/core/test/makefile.mysql_users create mode 100644 server/core/test/test_mysql_users.c diff --git a/server/core/test/makefile.mysql_users b/server/core/test/makefile.mysql_users new file mode 100644 index 000000000..074188555 --- /dev/null +++ b/server/core/test/makefile.mysql_users @@ -0,0 +1,32 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + +include ../../../build_gateway.inc +include ../../../makefile.inc + +CC=cc +DEBUG=Y +cleantests: + - $(DEL) *.o + - $(DEL) test_mysql_users + - $(DEL) *~ + +testall: cleantests buildtests runtests + +buildtests : + $(CC) $(CFLAGS) \ + -I$(ROOT_PATH)/server/include \ + -I$(ROOT_PATH)/utils \ + -I$(ROOT_PATH)/log_manager \ + test_mysql_users.c ../secrets.o ../service.o ../gwbitmask.o ../load_utils.o ../session.o ../poll.o ../dcb.o ../utils.o ../buffer.o ../gw_utils.o ../hashtable.o ../atomic.o ../spinlock.o ../users.o ../dbusers.o ../../../utils/skygw_utils.o ../../../log_manager/log_manager.o -o test_mysql_users -L$(EMBEDDED_LIB) -lmysqlclient -lpthread -lssl -lz -lm -lcrypt -lcrypto -ldl -laio -lrt -lstdc++ +runtests: + @echo "" + @echo "-------------------------------" + @echo $(shell date) + @echo "Test MaxScale core" + @echo "-------------------------------" + @echo "" + @echo "MaxSclale Load MySQL users" + @./test_mysql_users diff --git a/server/core/test/test_mysql_users.c b/server/core/test/test_mysql_users.c new file mode 100644 index 000000000..97476b3ae --- /dev/null +++ b/server/core/test/test_mysql_users.c @@ -0,0 +1,207 @@ +/* + * This file is distributed as part of the SkySQL Gateway. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright SkySQL Ab 2013 + */ + +/** + * + * @verbatim + * Revision History + * + * Date Who Description + * 14/02/2014 Massimiliano Pinto Initial implementation + * 17/02/2014 Massimiliano Pinto Added check ipv4 + * + * @endverbatim + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +extern int setipaddress(); + +int set_and_get_single_mysql_users_ipv4(char *username, unsigned long ipv4, char *password) { + struct sockaddr_in serv_addr; + MYSQL_USER_HOST key; + MYSQL_USER_HOST find_key; + USERS *mysql_users; + char ret_ip[200]=""; + char *fetch_data; + + unsigned long fix_ipv4; + + if (ipv4 > UINT_MAX) { + fix_ipv4 = UINT_MAX; + } else { + fix_ipv4 = ipv4; + } + + mysql_users = mysql_users_alloc(); + /* prepare the user@host data struct */ + memset(&key, 0, sizeof(key)); + memset(&serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + memcpy(&(serv_addr).sin_addr.s_addr, &fix_ipv4, sizeof(ipv4)); + + key.user = username; + memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); + + inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN); + + fprintf(stderr, "IPv4 passed/fixed [%lu/%lu] is [%s]\n", ipv4,fix_ipv4, ret_ip); + + /* add user@host as key and passwd as value in the MySQL users hash table */ + if (!mysql_users_add(mysql_users, &key, password)) { + fprintf(stderr, "Failed adding %s@%s(%lu)\n", username, ret_ip, fix_ipv4); + return 1; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + memset(&find_key, 0, sizeof(find_key)); + + find_key.user = username; + memcpy(&(serv_addr).sin_addr.s_addr, &ipv4, sizeof(ipv4)); + + memcpy(&find_key.ipv4, &serv_addr, sizeof(serv_addr)); + + fetch_data = mysql_users_fetch(mysql_users, &find_key); + + users_free(mysql_users); + + if (!fetch_data) + return 1; + + return 0; +} + +int set_and_get_single_mysql_users(char *username, char *hostname, char *password) { + struct sockaddr_in serv_addr; + MYSQL_USER_HOST key; + MYSQL_USER_HOST find_key; + USERS *mysql_users; + char ret_ip[200]=""; + char *fetch_data; + + mysql_users = mysql_users_alloc(); + /* prepare the user@host data struct */ + memset(&serv_addr, 0, sizeof(serv_addr)); + memset(&key, 0, sizeof(key)); + + + if (hostname) + if(!setipaddress(&serv_addr.sin_addr, hostname)) { + fprintf(stderr, "setipaddress failed for host [%s]\n", hostname); + return 1; + } + if (username) + key.user = username; + + memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); + + inet_ntop(AF_INET, &(serv_addr).sin_addr, ret_ip, INET_ADDRSTRLEN); + + fprintf(stderr, "set/get [%s@%s]: IPV4 %lu is [%u].[%u].[%u].[%u]\n", username, hostname, (unsigned long) serv_addr.sin_addr.s_addr, serv_addr.sin_addr.s_addr&0xFF, (serv_addr.sin_addr.s_addr&0xFF00), (serv_addr.sin_addr.s_addr&0xFF0000), ((serv_addr.sin_addr.s_addr & 0xFF000000) / (256*256*256))); + + /* add user@host as key and passwd as value in the MySQL users hash table */ + if (!mysql_users_add(mysql_users, &key, password)) { + fprintf(stderr, "mysql_users_add() failed for %s@%s\n", username, hostname); + return 1; + } + + memset(&serv_addr, 0, sizeof(serv_addr)); + memset(&find_key, 0, sizeof(key)); + + if (hostname) + if(!setipaddress(&serv_addr.sin_addr, hostname)) { + fprintf(stderr, "setipaddress failed for host [%s]\n", hostname); + return 1; + } + key.user = username; + memcpy(&key.ipv4, &serv_addr, sizeof(serv_addr)); + + fetch_data = mysql_users_fetch(mysql_users, &key); + + users_free(mysql_users); + + if (!fetch_data) + return 1; + + return 0; +} + + +int main() { + int ret; + int i = 0; + int k = 0; + time_t t; + + fprintf(stderr, "----------------\n"); + + time(&t); + fprintf(stderr, "%s\n", asctime(localtime(&t))); + fprintf(stderr, ">>> Started MySQL load, set & get users@host\n"); + + ret = set_and_get_single_mysql_users("pippo", "localhost", "xyz"); + assert(ret == 0); + ret = set_and_get_single_mysql_users("pippo", "127.0.0.2", "xyz"); + assert(ret == 0); + ret = set_and_get_single_mysql_users("pippo", "%", "xyz"); + assert(ret == 1); + ret = set_and_get_single_mysql_users("rootuser", NULL, "wwwww"); + assert(ret == 0); + ret = set_and_get_single_mysql_users("nullpwd", "this_host_does_not_exists", NULL); + assert(ret == 1); + ret = set_and_get_single_mysql_users("myuser", "345.-1.5.40997", "password"); + assert(ret == 1); + ret = set_and_get_single_mysql_users(NULL, NULL, NULL); + assert(ret == 1); + ret = set_and_get_single_mysql_users_ipv4("negative", -467295, "_ncd"); + assert(ret == 1); + ret = set_and_get_single_mysql_users_ipv4("extra", 0xFFFFFFFFFUL * 100, "JJcd"); + assert(ret == 1); + ret = set_and_get_single_mysql_users_ipv4("aaapo", 0, "JJcd"); + assert(ret == 0); + ret = set_and_get_single_mysql_users_ipv4(NULL, '\0', "JJcd"); + assert(ret == 1); + + for (i = 256*256*256; i <= 256*256*256 + 5; i++) { + char user[129] = ""; + snprintf(user, 128, "user_%i", k); + ret = set_and_get_single_mysql_users_ipv4(user, i, "JJcd"); + k++; + } + + fprintf(stderr, "----------------\n"); + fprintf(stderr, "<<< Test completed\n"); + + time(&t); + fprintf(stderr, "%s\n", asctime(localtime(&t))); + + return ret; +} + From 17b328cb9a65e4af67604beb97523551ed7c5ba3 Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Fri, 21 Feb 2014 17:08:27 +0100 Subject: [PATCH 2/2] Added USERS_HASHTABLE_SIZE Added USERS_HASHTABLE_SIZE, default size is 52 --- server/core/dbusers.c | 10 +++++----- server/core/users.c | 2 +- server/include/users.h | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index fb7f4f302..832c684f9 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -228,7 +228,7 @@ getUsers(SERVICE *service, struct users *users) if(key.user == NULL) { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, - "%lu [getUsers()] strdup() failed for user %s\n", + "%lu [getUsers()] strdup() failed for user %s", pthread_self(), row[0]))); @@ -243,7 +243,7 @@ getUsers(SERVICE *service, struct users *users) if (mysql_users_add(users, &key, strlen(row[2]) ? row[2]+1 : row[2])) { LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, - "%lu [mysql_users_add()] Added user %s@%s(%s)\n", + "%lu [mysql_users_add()] Added user %s@%s(%s)", pthread_self(), row[0], row[1], @@ -253,7 +253,7 @@ getUsers(SERVICE *service, struct users *users) } else { LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, - "%lu [mysql_users_add()] Failed adding user user %s@%s(%s)\n", + "%lu [mysql_users_add()] Failed adding user %s@%s(%s)", pthread_self(), row[0], row[1], @@ -266,7 +266,7 @@ getUsers(SERVICE *service, struct users *users) /* setipaddress() failed, skip user add and log this*/ LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, - "%lu [getUsers()] setipaddress failed: user NOT added %s@%s\n", + "%lu [getUsers()] setipaddress failed: user %s@%s not added", pthread_self(), row[0], row[1]))); @@ -292,7 +292,7 @@ USERS *rval; if ((rval = calloc(1, sizeof(USERS))) == NULL) return NULL; - if ((rval->data = hashtable_alloc(52, uh_hfun, uh_cmpfun)) == NULL) { + if ((rval->data = hashtable_alloc(USERS_HASHTABLE_SIZE, uh_hfun, uh_cmpfun)) == NULL) { free(rval); return NULL; } diff --git a/server/core/users.c b/server/core/users.c index 80ef61a1e..eea12edca 100644 --- a/server/core/users.c +++ b/server/core/users.c @@ -61,7 +61,7 @@ USERS *rval; if ((rval = calloc(1, sizeof(USERS))) == NULL) return NULL; - if ((rval->data = hashtable_alloc(52, user_hash, strcmp)) == NULL) + if ((rval->data = hashtable_alloc(USERS_HASHTABLE_SIZE, user_hash, strcmp)) == NULL) { free(rval); return NULL; diff --git a/server/include/users.h b/server/include/users.h index 4969774c3..6b730224c 100644 --- a/server/include/users.h +++ b/server/include/users.h @@ -30,10 +30,13 @@ * Date Who Description * 23/06/13 Mark Riddoch Initial implementation * 14/02/14 Massimiliano Pinto Added usersCustomUserFormat, optional username format routine + * 21/02/14 Massimiliano Pinto Added USERS_HASHTABLE_SIZE * * @endverbatim */ +#define USERS_HASHTABLE_SIZE 52 + /** * The users table statistics structure */