Code cleanup
Code cleanup
This commit is contained in:
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user