Code cleanup

Code cleanup
This commit is contained in:
MassimilianoPinto
2014-10-13 10:47:27 +02:00
parent e22f7da091
commit 273a445045
3 changed files with 269 additions and 191 deletions

View File

@ -1,5 +1,5 @@
/* /*
* This file is distributed as part of the SkySQL Gateway. It is free * This file is distributed as part of the MariaDB Corporation MaxScale. It is free
* software: you can redistribute it and/or modify it under the terms of the * 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, * GNU General Public License as published by the Free Software Foundation,
* version 2. * version 2.
@ -13,7 +13,7 @@
* this program; if not, write to the Free Software Foundation, Inc., 51 * this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright SkySQL Ab 2013 * Copyright MariaDB Corporation Ab 2013-2014
*/ */
#include "mysql_client_server_protocol.h" #include "mysql_client_server_protocol.h"
@ -27,7 +27,7 @@
* Revision History * Revision History
* Date Who Description * Date Who Description
* 14/06/2013 Mark Riddoch Initial version * 14/06/2013 Mark Riddoch Initial version
* 17/06/2013 Massimiliano Pinto Added Gateway To Backends routines * 17/06/2013 Massimiliano Pinto Added MaxScale To Backends routines
* 27/06/2013 Vilho Raatikka Added skygw_log_write command as an example * 27/06/2013 Vilho Raatikka Added skygw_log_write command as an example
* and necessary headers. * and necessary headers.
* 01/07/2013 Massimiliano Pinto Put Log Manager example code behind SS_DEBUG macros. * 01/07/2013 Massimiliano Pinto Put Log Manager example code behind SS_DEBUG macros.
@ -199,6 +199,7 @@ static int gw_read_backend_event(DCB *dcb) {
if (backend_protocol->protocol_auth_state == MYSQL_CONNECTED) if (backend_protocol->protocol_auth_state == MYSQL_CONNECTED)
{ {
/** Read cached backend handshake */
if (gw_read_backend_handshake(backend_protocol) != 0) if (gw_read_backend_handshake(backend_protocol) != 0)
{ {
backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED; backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
@ -209,11 +210,13 @@ static int gw_read_backend_event(DCB *dcb) {
"state = MYSQL_AUTH_FAILED.", "state = MYSQL_AUTH_FAILED.",
pthread_self(), pthread_self(),
backend_protocol->owner_dcb->fd))); backend_protocol->owner_dcb->fd)));
} }
else else
{ {
/* handshake decoded, send the auth credentials */ /**
* Decode password and send the auth credentials
* to backend.
*/
if (gw_send_authentication_to_backend( if (gw_send_authentication_to_backend(
current_session->db, current_session->db,
current_session->user, current_session->user,
@ -227,16 +230,16 @@ static int gw_read_backend_event(DCB *dcb) {
"gw_send_authentication_to_backend " "gw_send_authentication_to_backend "
"fd %d, state = MYSQL_AUTH_FAILED.", "fd %d, state = MYSQL_AUTH_FAILED.",
pthread_self(), pthread_self(),
backend_protocol->owner_dcb->fd))); backend_protocol->owner_dcb->fd)));
} }
else else
{ {
backend_protocol->protocol_auth_state = MYSQL_AUTH_RECV; backend_protocol->protocol_auth_state = MYSQL_AUTH_RECV;
} }
} }
} }
spinlock_release(&dcb->authlock); spinlock_release(&dcb->authlock);
} } /*< backend_protocol->protocol_auth_state == MYSQL_CONNECTED */
/* /*
* Now: * Now:
* -- check the authentication reply from backend * -- check the authentication reply from backend
@ -266,9 +269,10 @@ static int gw_read_backend_event(DCB *dcb) {
router_instance = session->service->router_instance; router_instance = session->service->router_instance;
rsession = session->router_session; rsession = session->router_session;
if (backend_protocol->protocol_auth_state == MYSQL_AUTH_RECV) { if (backend_protocol->protocol_auth_state == MYSQL_AUTH_RECV)
/*< {
* Read backed auth reply /**
* Read backed's reply to authentication message
*/ */
receive_rc = receive_rc =
gw_receive_backend_auth(backend_protocol); gw_receive_backend_auth(backend_protocol);
@ -283,7 +287,6 @@ static int gw_read_backend_event(DCB *dcb) {
"fd %d, state = MYSQL_AUTH_FAILED.", "fd %d, state = MYSQL_AUTH_FAILED.",
pthread_self(), pthread_self(),
backend_protocol->owner_dcb->fd))); backend_protocol->owner_dcb->fd)));
LOGIF(LE, (skygw_log_write_flush( LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
@ -362,8 +365,8 @@ static int gw_read_backend_event(DCB *dcb) {
0, 0,
"Authentication with backend failed. " "Authentication with backend failed. "
"Session will be closed."); "Session will be closed.");
router->handleError(router_instance, router->handleError(router_instance,
rsession, rsession,
errbuf, errbuf,
dcb, dcb,
@ -371,7 +374,6 @@ static int gw_read_backend_event(DCB *dcb) {
&succp); &succp);
ss_dassert(!succp); ss_dassert(!succp);
LOGIF(LD, (skygw_log_write( LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG, LOGFILE_DEBUG,
"%lu [gw_read_backend_event] " "%lu [gw_read_backend_event] "
@ -412,7 +414,7 @@ static int gw_read_backend_event(DCB *dcb) {
} }
} }
} /* MYSQL_AUTH_RECV || MYSQL_AUTH_FAILED */ } /* MYSQL_AUTH_RECV || MYSQL_AUTH_FAILED */
spinlock_release(&dcb->authlock); spinlock_release(&dcb->authlock);
} /* MYSQL_AUTH_RECV || MYSQL_AUTH_FAILED */ } /* MYSQL_AUTH_RECV || MYSQL_AUTH_FAILED */
@ -878,6 +880,10 @@ static int gw_create_backend_connection(
goto return_fd; goto return_fd;
} }
/** Copy client flags to backend protocol */
protocol->client_capabilities =
((MySQLProtocol *)(backend_dcb->session->client->protocol))->client_capabilities;
/*< if succeed, fd > 0, -1 otherwise */ /*< if succeed, fd > 0, -1 otherwise */
rv = gw_do_connect_to_backend(server->name, server->port, &fd); rv = gw_do_connect_to_backend(server->name, server->port, &fd);
/*< Assign protocol with backend_dcb */ /*< Assign protocol with backend_dcb */
@ -1048,6 +1054,10 @@ gw_backend_close(DCB *dcb)
mysql_protocol_done(dcb); mysql_protocol_done(dcb);
/**
* If session->state is set to STOPPING the client and the session must
* be closed too.
*/
if (session != NULL && session->state == SESSION_STATE_STOPPING) if (session != NULL && session->state == SESSION_STATE_STOPPING)
{ {
client_dcb = session->client; client_dcb = session->client;

View File

@ -1,5 +1,5 @@
/* /*
* This file is distributed as part of the SkySQL Gateway. It is free * This file is distributed as part of the MariaDB Corporation MaxScale. It is free
* software: you can redistribute it and/or modify it under the terms of the * 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, * GNU General Public License as published by the Free Software Foundation,
* version 2. * version 2.
@ -13,7 +13,7 @@
* this program; if not, write to the Free Software Foundation, Inc., 51 * this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Copyright SkySQL Ab 2013 * Copyright MariaDB Corporation Ab 2013-2014
*/ */
/** /**
@ -25,7 +25,7 @@
* Revision History * Revision History
* Date Who Description * Date Who Description
* 14/06/2013 Mark Riddoch Initial version * 14/06/2013 Mark Riddoch Initial version
* 17/06/2013 Massimiliano Pinto Added Client To Gateway routines * 17/06/2013 Massimiliano Pinto Added Client To MaxScale routines
* 24/06/2013 Massimiliano Pinto Added: fetch passwords from service users' hashtable * 24/06/2013 Massimiliano Pinto Added: fetch passwords from service users' hashtable
* 02/09/2013 Massimiliano Pinto Added: session refcount * 02/09/2013 Massimiliano Pinto Added: session refcount
* 16/12/2013 Massimiliano Pinto Added: client closed socket detection with recv(..., MSG_PEEK) * 16/12/2013 Massimiliano Pinto Added: client closed socket detection with recv(..., MSG_PEEK)
@ -35,6 +35,7 @@
* 11/03/2014 Massimiliano Pinto Added: Unix socket support * 11/03/2014 Massimiliano Pinto Added: Unix socket support
* 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake * 07/05/2014 Massimiliano Pinto Added: specific version string in server handshake
* 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path * 09/09/2014 Massimiliano Pinto Added: 777 permission for socket path
* 13/10/2014 Massimiliano Pinto Added: dbname authentication check
* *
*/ */
#include <skygw_utils.h> #include <skygw_utils.h>
@ -68,6 +69,8 @@ int mysql_send_ok(DCB *dcb, int packet_number, int in_affected_rows, const char*
int MySQLSendHandshake(DCB* dcb); int MySQLSendHandshake(DCB* dcb);
static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue); static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue);
static int route_by_statement(SESSION *, GWBUF **); static int route_by_statement(SESSION *, GWBUF **);
static char* create_auth_fail_str(GWBUF* readbuf, char* hostaddr, char* sha1);
static char* get_username_from_auth(char* ptr, uint8_t* data);
/* /*
* The "module object" for the mysqld client protocol module. * The "module object" for the mysqld client protocol module.
@ -372,9 +375,9 @@ MySQLSendHandshake(DCB* dcb)
* The useful data: user, db, client_sha1 are copied into the MYSQL_session * dcb->session->data * The useful data: user, db, client_sha1 are copied into the MYSQL_session * dcb->session->data
* client_capabilitiesa are copied into the dcb->protocol * client_capabilitiesa are copied into the dcb->protocol
* *
* @param dcb Descriptor Control Block of the client * @param dcb Descriptor Control Block of the client
* @param queue The GWBUF with data from client * @param queue The GWBUF with data from client
* @return 0 for Authentication ok, !=0 for failed autht * @return 0 If succeed, otherwise non-zero value
* *
*/ */
@ -432,12 +435,10 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
&protocol->client_capabilities); &protocol->client_capabilities);
*/ */
/* now get the user */ username = get_username_from_auth(username, client_auth_packet);
strncpy(username, (char *)(client_auth_packet + 4 + 4 + 4 + 1 + 23), MYSQL_USER_MAXLEN);
if (username == NULL)
{
/* the empty username field is not allowed */
if (!strlen(username)) {
return 1; return 1;
} }
@ -448,9 +449,9 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
if (connect_with_db) { if (connect_with_db) {
database = client_data->db; database = client_data->db;
strncpy(database, strncpy(database,
(char *)(client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) + (char *)(client_auth_packet + 4 + 4 + 4 + 1 + 23 + strlen(username) +
1 + 1 + auth_token_len), MYSQL_DATABASE_MAXLEN); 1 + 1 + auth_token_len), MYSQL_DATABASE_MAXLEN);
} }
/* allocate memory for token only if auth_token_len > 0 */ /* allocate memory for token only if auth_token_len > 0 */
@ -485,19 +486,18 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
if (auth_token) if (auth_token)
free(auth_token); free(auth_token);
if (database) { if (database) {
int i = 0; int i = 0;
int db_exists = 0; int db_exists = 0;
while(dcb->service->resources[i]) { while(dcb->service->resources[i]) {
if (strncmp(database, dcb->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) { if (strncmp(database, dcb->service->resources[i], MYSQL_DATABASE_MAXLEN) == 0) {
db_exists = 1; db_exists = 1;
}
i++;
} }
if (!db_exists) { i++;
}
if (!db_exists) {
auth_ret = 2; auth_ret = 2;
} }
} }
@ -506,12 +506,82 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
{ {
dcb->user = strdup(client_data->user); dcb->user = strdup(client_data->user);
} }
return auth_ret; return auth_ret;
} }
/** /**
* Write function for client DCB: writes data from Gateway to Client * Read username from MySQL authentication packet.
*
* @param ptr address where to write the result or NULL if memory
* is allocated here.
* @param data Address of MySQL packet.
*
* @return Pointer to a copy of the username. NULL if memory allocation
* failed or if username was empty.
*/
static char* get_username_from_auth(
char* ptr,
uint8_t* data)
{
char* first_letter;
char* rval;
first_letter = (char *)(data + 4 + 4 + 4 + 1 + 23);
if (first_letter == '\0')
{
rval = NULL;
goto retblock;
}
if (ptr == NULL)
{
if ((rval = (char *)malloc(MYSQL_USER_MAXLEN+1)) == NULL)
{
goto retblock;
}
}
else
{
rval = ptr;
}
snprintf(rval, MYSQL_USER_MAXLEN+1, "%s", first_letter);
retblock:
return rval;
}
static char* create_auth_fail_str(
GWBUF* readbuf,
char* hostaddr,
char* sha1)
{
char* errstr;
char* uname;
const char* ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
if ( (uname = get_username_from_auth(NULL, (uint8_t *)GWBUF_DATA(readbuf))) == NULL)
{
errstr = NULL;
goto retblock;
}
/** -4 comes from 2X'%s' minus terminating char */
errstr = (char *)malloc(strlen(uname)+strlen(ferrstr)+strlen(hostaddr)+strlen("YES")-6+1);
if (errstr != NULL)
{
sprintf(errstr, ferrstr, uname, hostaddr, (*sha1 == '\0' ? "NO" : "YES"));
}
retblock:
return errstr;
}
/**
* Write function for client DCB: writes data from MaxScale to Client
* *
* @param dcb The DCB of the client * @param dcb The DCB of the client
* @param queue Queue of buffers to write * @param queue Queue of buffers to write
@ -610,85 +680,91 @@ int gw_read_client_event(
case MYSQL_AUTH_SENT: case MYSQL_AUTH_SENT:
{ {
int auth_val = -1; int auth_val;
auth_val = gw_mysql_do_authentication(dcb, read_buffer); auth_val = gw_mysql_do_authentication(dcb, read_buffer);
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
ss_dassert(read_buffer == NULL || GWBUF_EMPTY(read_buffer)); if (auth_val == 0)
{
if (auth_val == 0) SESSION *session;
{
SESSION *session = NULL; protocol->protocol_auth_state = MYSQL_AUTH_RECV;
protocol->protocol_auth_state = MYSQL_AUTH_RECV; /**
/** * Create session, and a router session for it.
* Create session, and a router session for it. * If successful, there will be backend connection(s)
* If successful, there will be backend connection(s) * after this point.
* after this point. */
*/ session = session_alloc(dcb->service, dcb);
session = session_alloc(dcb->service, dcb);
if (session != NULL)
if (session != NULL) {
{ CHK_SESSION(session);
CHK_SESSION(session); ss_dassert(session->state != SESSION_STATE_ALLOC);
ss_dassert(session->state != SESSION_STATE_ALLOC);
protocol->protocol_auth_state = MYSQL_IDLE;
protocol->protocol_auth_state = MYSQL_IDLE; /**
/** * Send an AUTH_OK packet to the client,
* Send an AUTH_OK packet to the client, * packet sequence is # 2
* packet sequence is # 2 */
*/ mysql_send_ok(dcb, 2, 0, NULL);
mysql_send_ok(dcb, 2, 0, NULL); }
} else
else {
{ protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
protocol->protocol_auth_state = MYSQL_AUTH_FAILED; LOGIF(LD, (skygw_log_write(
LOGIF(LD, (skygw_log_write( LOGFILE_DEBUG,
LOGFILE_DEBUG, "%lu [gw_read_client_event] session "
"%lu [gw_read_client_event] session " "creation failed. fd %d, "
"creation failed. fd %d, " "state = MYSQL_AUTH_FAILED.",
"state = MYSQL_AUTH_FAILED.", protocol->owner_dcb->fd,
protocol->owner_dcb->fd, pthread_self())));
pthread_self())));
/** Send ERR 1045 to client */
/** Send ERR 1045 to client */ mysql_send_auth_error(
mysql_send_auth_error( dcb,
dcb, 2,
2, 0,
0, "failed to create new session");
"failed to create new session");
dcb_close(dcb);
dcb_close(dcb); }
} }
} else
else {
{ char* fail_str;
protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
LOGIF(LD, (skygw_log_write( protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
LOGFILE_DEBUG, fail_str = create_auth_fail_str(read_buffer,
"%lu [gw_read_client_event] after " dcb->remote,
"gw_mysql_do_authentication, fd %d, " (char*)((MYSQL_session *)dcb->data)->client_sha1);
"state = MYSQL_AUTH_FAILED.",
protocol->owner_dcb->fd,
pthread_self())));
/** Send ERR 1045 to client */
if (auth_val == 2) { if (auth_val == 2) {
mysql_send_auth_error( mysql_send_auth_error(
dcb, dcb,
2, 2,
0, 0,
"Database not existent"); "Database not existent");
} else { } else {
mysql_send_auth_error( /** Send error 1045 to client */
dcb, mysql_send_auth_error(
2, dcb,
0, 2,
"Authorization failed"); 0,
fail_str);
} }
dcb_close(dcb); LOGIF(LD, (skygw_log_write(
} LOGFILE_DEBUG,
} "%lu [gw_read_client_event] after "
"gw_mysql_do_authentication, fd %d, "
"state = MYSQL_AUTH_FAILED.",
protocol->owner_dcb->fd,
pthread_self())));
free(fail_str);
dcb_close(dcb);
}
read_buffer = gwbuf_consume(read_buffer, nbytes_read);
}
break; break;
case MYSQL_IDLE: case MYSQL_IDLE:
@ -826,9 +902,12 @@ int gw_read_client_event(
} }
/** succeed */ /** succeed */
if (rc) { if (rc)
{
rc = 0; /**< here '0' means success */ rc = 0; /**< here '0' means success */
} else { }
else
{
GWBUF* errbuf; GWBUF* errbuf;
bool succp; bool succp;
@ -1385,20 +1464,12 @@ gw_client_close(DCB *dcb)
CHK_SESSION(session); CHK_SESSION(session);
spinlock_acquire(&session->ses_lock); spinlock_acquire(&session->ses_lock);
if (session->state == SESSION_STATE_STOPPING) if (session->state != SESSION_STATE_STOPPING)
{ {
/** session->state = SESSION_STATE_STOPPING;
* Session is already getting closed so avoid }
* redundant calls spinlock_release(&session->ses_lock);
*/
spinlock_release(&session->ses_lock);
return 1;
}
else
{
session->state = SESSION_STATE_STOPPING;
spinlock_release(&session->ses_lock);
}
router = session->service->router; router = session->service->router;
router_instance = session->service->router_instance; router_instance = session->service->router_instance;
rsession = session->router_session; rsession = session->router_session;

View File

@ -32,7 +32,7 @@
* Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via * Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via
* user@% * user@%
* 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts: * 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts:
* x.y.z.%, x.y.%.%, x.%.%.% * x.y.z.%, x.y.%.%, x.%.%.%
* 03/10/2014 Massimiliano Pinto Added netmask for wildcard in IPv4 hosts. * 03/10/2014 Massimiliano Pinto Added netmask for wildcard in IPv4 hosts.
* *
*/ */
@ -466,6 +466,7 @@ int gw_receive_backend_auth(
bufstr))); bufstr)));
free(bufstr); free(bufstr);
free(err);
rc = -1; rc = -1;
} }
else else
@ -540,9 +541,9 @@ int gw_receive_backend_auth(
* @return 0 on success, 1 on failure * @return 0 on success, 1 on failure
*/ */
int gw_send_authentication_to_backend( int gw_send_authentication_to_backend(
char *dbname, char *dbname,
char *user, char *user,
uint8_t *passwd, uint8_t *passwd,
MySQLProtocol *conn) MySQLProtocol *conn)
{ {
int compress = 0; int compress = 0;
@ -552,8 +553,8 @@ int gw_send_authentication_to_backend(
long bytes; long bytes;
uint8_t client_scramble[GW_MYSQL_SCRAMBLE_SIZE]; uint8_t client_scramble[GW_MYSQL_SCRAMBLE_SIZE];
uint8_t client_capabilities[4]; uint8_t client_capabilities[4];
uint32_t server_capabilities; uint32_t server_capabilities = 0;
uint32_t final_capabilities; uint32_t final_capabilities = 0;
char dbpass[MYSQL_USER_MAXLEN + 1]=""; char dbpass[MYSQL_USER_MAXLEN + 1]="";
GWBUF *buffer; GWBUF *buffer;
DCB *dcb; DCB *dcb;
@ -568,17 +569,12 @@ int gw_send_authentication_to_backend(
curr_passwd = passwd; curr_passwd = passwd;
dcb = conn->owner_dcb; dcb = conn->owner_dcb;
// Zero the vars
memset(&server_capabilities, '\0', sizeof(server_capabilities));
memset(&final_capabilities, '\0', sizeof(final_capabilities));
final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities); final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities);
final_capabilities |= GW_MYSQL_CAPABILITIES_PROTOCOL_41; /** Copy client's flags to backend */
final_capabilities |= GW_MYSQL_CAPABILITIES_CLIENT; final_capabilities |= conn->client_capabilities;;
if (compress) { if (compress) {
final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS; final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS;
#ifdef DEBUG_MYSQL_CONN #ifdef DEBUG_MYSQL_CONN
fprintf(stderr, ">>>> Backend Connection with compression\n"); fprintf(stderr, ">>>> Backend Connection with compression\n");
@ -1033,19 +1029,24 @@ int mysql_send_custom_error (
* @param passwd The SHA1(real_password): Note real_password is unknown * @param passwd The SHA1(real_password): Note real_password is unknown
* @return 1 on success, 0 on failure * @return 1 on success, 0 on failure
*/ */
int gw_send_change_user_to_backend(char *dbname, char *user, uint8_t *passwd, MySQLProtocol *conn) { int gw_send_change_user_to_backend(
int compress = 0; char *dbname,
int rv; char *user,
uint8_t *payload = NULL; uint8_t *passwd,
uint8_t *payload_start = NULL; MySQLProtocol *conn)
long bytes; {
uint8_t client_scramble[GW_MYSQL_SCRAMBLE_SIZE]; int compress = 0;
uint8_t client_capabilities[4]; int rv;
uint32_t server_capabilities; uint8_t *payload = NULL;
uint32_t final_capabilities; uint8_t *payload_start = NULL;
char dbpass[MYSQL_USER_MAXLEN + 1]=""; long bytes;
GWBUF *buffer; uint8_t client_scramble[GW_MYSQL_SCRAMBLE_SIZE];
DCB *dcb; uint8_t client_capabilities[4];
uint32_t server_capabilities = 0;
uint32_t final_capabilities = 0;
char dbpass[MYSQL_USER_MAXLEN + 1]="";
GWBUF *buffer;
DCB *dcb;
char *curr_db = NULL; char *curr_db = NULL;
uint8_t *curr_passwd = NULL; uint8_t *curr_passwd = NULL;
@ -1058,14 +1059,10 @@ int gw_send_change_user_to_backend(char *dbname, char *user, uint8_t *passwd, My
dcb = conn->owner_dcb; dcb = conn->owner_dcb;
// Zero the vars final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities);
memset(&server_capabilities, '\0', sizeof(server_capabilities));
memset(&final_capabilities, '\0', sizeof(final_capabilities));
final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities); /** Copy client's flags to backend */
final_capabilities |= conn->client_capabilities;;
final_capabilities |= GW_MYSQL_CAPABILITIES_PROTOCOL_41;
final_capabilities |= GW_MYSQL_CAPABILITIES_CLIENT;
if (compress) { if (compress) {
final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS; final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS;
@ -1316,7 +1313,7 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
/** /**
* gw_find_mysql_user_password_sha1 * gw_find_mysql_user_password_sha1
* *
* The routine fetches look for an user int the MaxScale users' table * The routine fetches look for an user in the MaxScale users' table
* The users' table is dcb->service->users or a different one specified with void *repository * The users' table is dcb->service->users or a different one specified with void *repository
* *
* If found the HEX password, representing sha1(sha1(password)), is converted in binary data and * If found the HEX password, representing sha1(sha1(password)), is converted in binary data and
@ -1334,18 +1331,16 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
struct sockaddr_in *client; struct sockaddr_in *client;
char *user_password = NULL; char *user_password = NULL;
MYSQL_USER_HOST key; MYSQL_USER_HOST key;
MYSQL_session *client_data = NULL; MYSQL_session *client_data = NULL;
client_data = dcb->data;
client_data = (MYSQL_session *) dcb->data;
service = (SERVICE *) dcb->service; service = (SERVICE *) dcb->service;
client = (struct sockaddr_in *) &dcb->ipv4; client = (struct sockaddr_in *) &dcb->ipv4;
key.user = username; key.user = username;
key.resource = client_data->db;
memcpy(&key.ipv4, client, sizeof(struct sockaddr_in)); memcpy(&key.ipv4, client, sizeof(struct sockaddr_in));
key.netmask = 32; key.netmask = 32;
key.resource = client_data->db;
LOGIF(LD, LOGIF(LD,
(skygw_log_write_flush( (skygw_log_write_flush(
@ -1355,11 +1350,11 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
key.user, key.user,
dcb->remote))); dcb->remote)));
/* look for user@current_ipv4 now */ /* look for user@current_host now */
user_password = mysql_users_fetch(service->users, &key); user_password = mysql_users_fetch(service->users, &key);
if (!user_password) { if (!user_password) {
/* The user is not authenticated @ current IPv4 */ /* The user is not authenticated @ current host */
while (1) { while (1) {
/* /*
@ -1371,14 +1366,16 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
LOGIF(LE, LOGIF(LE,
(skygw_log_write_flush( (skygw_log_write_flush(
LOGFILE_ERROR, LOGFILE_ERROR,
"%lu [MySQL Client Auth], user [%s@%s] not found, please try with 'localhost_match_wildcard_host=1' in service definition", "Error : user %s@%s not found, try set "
pthread_self(), "'localhost_match_wildcard_host=1' in "
"service definition of the configuration "
"file.",
key.user, key.user,
dcb->remote))); dcb->remote)));
break; break;
} }
/* /*
* (2) check for possible IPv4 class C,B,A networks * (2) check for possible IPv4 class C,B,A networks
*/ */
@ -1388,7 +1385,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
key.netmask -= 8; key.netmask -= 8;
user_password = mysql_users_fetch(service->users, &key); user_password = mysql_users_fetch(service->users, &key);
if (user_password) { if (user_password) {
break; break;
} }
@ -1402,7 +1399,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
if (user_password) { if (user_password) {
break; break;
} }
/* Class A check */ /* Class A check */
key.ipv4.sin_addr.s_addr &= 0x000000FF; key.ipv4.sin_addr.s_addr &= 0x000000FF;
key.netmask -= 8; key.netmask -= 8;
@ -1432,7 +1429,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
if (!user_password) { if (!user_password) {
/* /*
* the user@% has not been found. * user@% not found.
*/ */
LOGIF(LD, LOGIF(LD,
@ -1456,14 +1453,12 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
* The gateway_password represents the SHA1(SHA1(real_password)). * The gateway_password represents the SHA1(SHA1(real_password)).
* Please note: the real_password is unknown and SHA1(real_password) is unknown as well * Please note: the real_password is unknown and SHA1(real_password) is unknown as well
*/ */
//char *the_password = user_password->value;
//MYSQL_USER_HOST *matched_key = (MYSQL_USER_HOST *)user_password->key; if (strlen(user_password))
gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2);
if (strlen(user_password)) return 0;
gw_hex2bin(gateway_password, user_password, SHA_DIGEST_LENGTH * 2);
return 0;
} else { } else {
return 1; return 1;
} }
@ -1514,7 +1509,7 @@ mysql_send_auth_error (
} }
mysql_errno = 1045; mysql_errno = 1045;
mysql_error_msg = "Access denied!"; mysql_error_msg = "Access denied!";
mysql_state = "2800"; mysql_state = "28000";
field_count = 0xff; field_count = 0xff;
gw_mysql_set_byte2(mysql_err, mysql_errno); gw_mysql_set_byte2(mysql_err, mysql_errno);
@ -1709,9 +1704,11 @@ void protocol_archive_srv_command(
s1 = &p->protocol_command; s1 = &p->protocol_command;
LOGIF(LT, (skygw_log_write( LOGIF(LD, (skygw_log_write(
LOGFILE_TRACE, LOGFILE_DEBUG,
"Move command %s from fd %d to command history.", "%lu [protocol_archive_srv_command] Move command %s from fd %d "
"to command history.",
pthread_self(),
STRPACKETTYPE(s1->scom_cmd), STRPACKETTYPE(s1->scom_cmd),
p->owner_dcb->fd))); p->owner_dcb->fd)));
@ -1783,8 +1780,8 @@ void protocol_add_srv_command(
p->protocol_command.scom_next = server_command_init(NULL, cmd); p->protocol_command.scom_next = server_command_init(NULL, cmd);
} }
LOGIF(LT, (skygw_log_write( LOGIF(LD, (skygw_log_write(
LOGFILE_TRACE, LOGFILE_DEBUG,
"Added command %s to fd %d.", "Added command %s to fd %d.",
STRPACKETTYPE(cmd), STRPACKETTYPE(cmd),
p->owner_dcb->fd))); p->owner_dcb->fd)));
@ -1794,8 +1791,8 @@ void protocol_add_srv_command(
while (c != NULL && c->scom_cmd != MYSQL_COM_UNDEFINED) while (c != NULL && c->scom_cmd != MYSQL_COM_UNDEFINED)
{ {
LOGIF(LT, (skygw_log_write( LOGIF(LD, (skygw_log_write(
LOGFILE_TRACE, LOGFILE_DEBUG,
"fd %d : %d %s", "fd %d : %d %s",
p->owner_dcb->fd, p->owner_dcb->fd,
c->scom_cmd, c->scom_cmd,