Added first support for user@x.y.z.%
Added first support for user@x.y.z.%
This commit is contained in:
		@ -313,29 +313,53 @@ getUsers(SERVICE *service, struct users *users)
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		char ret_ip[INET_ADDRSTRLEN + 1]="";
 | 
							char ret_ip[INET_ADDRSTRLEN + 1]="";
 | 
				
			||||||
		const char *rc;
 | 
							const char *rc;
 | 
				
			||||||
 | 
							int found_range=0;
 | 
				
			||||||
 | 
							int found_any=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* prepare the user@host data struct */
 | 
							/* prepare the user@host data struct */
 | 
				
			||||||
		memset(&serv_addr, 0, sizeof(serv_addr));
 | 
							memset(&serv_addr, 0, sizeof(serv_addr));
 | 
				
			||||||
		memset(&key, 0, sizeof(key));
 | 
							memset(&key, 0, sizeof(key));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* if host == '%', 0 is passed */
 | 
							/* set user */
 | 
				
			||||||
		if (setipaddress(&serv_addr.sin_addr, strcmp(row[1], "%") ? row[1] : "0.0.0.0")) {
 | 
							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) {
 | 
								continue;
 | 
				
			||||||
				LOGIF(LE, (skygw_log_write_flush(
 | 
							}
 | 
				
			||||||
					LOGFILE_ERROR,
 | 
					 | 
				
			||||||
					"%lu [getUsers()] strdup() failed for user %s",
 | 
					 | 
				
			||||||
					pthread_self(),
 | 
					 | 
				
			||||||
					row[0])));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				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));
 | 
								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 */
 | 
								/* 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])) {
 | 
								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) {
 | 
						if (entry->ipv4.sin_addr.s_addr == INADDR_ANY) {
 | 
				
			||||||
		snprintf(mysql_user, mysql_user_len, "%s@%%", entry->user);
 | 
							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 {
 | 
						} else {
 | 
				
			||||||
		strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN);
 | 
							strncpy(mysql_user, entry->user, MYSQL_USER_MAXLEN);
 | 
				
			||||||
		strcat(mysql_user, "@");
 | 
							strcat(mysql_user, "@");
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,6 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <gw.h>
 | 
					 | 
				
			||||||
#include "mysql_client_server_protocol.h"
 | 
					#include "mysql_client_server_protocol.h"
 | 
				
			||||||
#include <skygw_types.h>
 | 
					#include <skygw_types.h>
 | 
				
			||||||
#include <skygw_utils.h>
 | 
					#include <skygw_utils.h>
 | 
				
			||||||
@ -742,7 +741,6 @@ int gw_do_connect_to_backend(
 | 
				
			|||||||
	struct sockaddr_in serv_addr;
 | 
						struct sockaddr_in serv_addr;
 | 
				
			||||||
	int rv;
 | 
						int rv;
 | 
				
			||||||
	int so = 0;
 | 
						int so = 0;
 | 
				
			||||||
	int	bufsize;
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
	memset(&serv_addr, 0, sizeof serv_addr);
 | 
						memset(&serv_addr, 0, sizeof serv_addr);
 | 
				
			||||||
	serv_addr.sin_family = AF_INET;
 | 
						serv_addr.sin_family = AF_INET;
 | 
				
			||||||
@ -766,10 +764,6 @@ int gw_do_connect_to_backend(
 | 
				
			|||||||
	/* prepare for connect */
 | 
						/* prepare for connect */
 | 
				
			||||||
	setipaddress(&serv_addr.sin_addr, host);
 | 
						setipaddress(&serv_addr.sin_addr, host);
 | 
				
			||||||
	serv_addr.sin_port = htons(port);
 | 
						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 */
 | 
						/* set socket to as non-blocking here */
 | 
				
			||||||
	setnonblocking(so);
 | 
						setnonblocking(so);
 | 
				
			||||||
        rv = connect(so, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
 | 
					        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);
 | 
					        user_password = mysql_users_fetch(service->users, &key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!user_password) {
 | 
					        if (!user_password) {
 | 
				
			||||||
 | 
							int lastbyte=0;
 | 
				
			||||||
		/* The user is not authenticated @ current host */
 | 
							/* The user is not authenticated @ current host */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* 1) Check for localhost first.
 | 
							/* 1) Check for localhost first.
 | 
				
			||||||
@ -1369,15 +1364,32 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
 | 
				
			|||||||
			return 1;
 | 
								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
 | 
							 * Return 1 if no match
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		memset(&key.ipv4, 0, sizeof(struct sockaddr_in));
 | 
							memset(&key.ipv4, 0, sizeof(struct sockaddr_in));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		LOGIF(LD,
 | 
							LOGIF(LE,
 | 
				
			||||||
			(skygw_log_write_flush(
 | 
								(skygw_log_write_flush(
 | 
				
			||||||
				LOGFILE_DEBUG,
 | 
									LOGFILE_ERROR,
 | 
				
			||||||
				"%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]",
 | 
									"%lu [MySQL Client Auth], checking user [%s@%s] with wildcard host [%%]",
 | 
				
			||||||
				pthread_self(),
 | 
									pthread_self(),
 | 
				
			||||||
				key.user,
 | 
									key.user,
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user