Reformat mysql_common.c

This commit is contained in:
Johan Wikman
2016-01-12 15:36:15 +02:00
parent da29ee0f4a
commit fd9698e705

View File

@ -24,12 +24,17 @@
* 17/06/2013 Massimiliano Pinto Common MySQL protocol routines
* 02/06/2013 Massimiliano Pinto MySQL connect asynchronous phases
* 04/09/2013 Massimiliano Pinto Added dcb NULL assert in mysql_send_custom_error
* 12/09/2013 Massimiliano Pinto Added checks in gw_decode_mysql_server_handshake and gw_read_backend_handshake
* 12/09/2013 Massimiliano Pinto Added checks in gw_decode_mysql_server_handshake and
* gw_read_backend_handshake
* 10/02/2014 Massimiliano Pinto Added MySQL Authentication with user@host
* 10/09/2014 Massimiliano Pinto Added MySQL Authentication option enabling localhost match with any host (wildcard %)
* Backend server configuration may differ so default is 0, don't match and an explicit
* localhost entry should be added for the selected user in the backends.
* Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via
* 10/09/2014 Massimiliano Pinto Added MySQL Authentication option enabling localhost
* match with any host (wildcard %)
* Backend server configuration may differ so default is 0,
* don't match and an explicit
* localhost entry should be added for the selected user
* in the backends.
* Setting to 1 allow localhost (127.0.0.1 or socket) to
* match the any host grant via
* user@%
* 29/09/2014 Massimiliano Pinto Added Mysql user@host authentication with wildcard in IPv4 hosts:
* x.y.z.%, x.y.%.%, x.%.%.%
@ -56,8 +61,7 @@ extern int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue);
extern int gw_error_backend_event(DCB *dcb);
char* get_username_from_auth(char* ptr, uint8_t* data);
static server_command_t* server_command_init(server_command_t* srvcmd,
mysql_server_cmd_t cmd);
static server_command_t* server_command_init(server_command_t* srvcmd, mysql_server_cmd_t cmd);
/**
@ -73,16 +77,15 @@ static server_command_t* server_command_init(server_command_t* srvcmd,
* connected yet.
*
*/
MySQLProtocol* mysql_protocol_init(
DCB* dcb,
int fd)
MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd)
{
MySQLProtocol* p;
p = (MySQLProtocol *) calloc(1, sizeof(MySQLProtocol));
ss_dassert(p != NULL);
if (p == NULL) {
if (p == NULL)
{
int eno = errno;
errno = 0;
char errbuf[STRERROR_BUFLEN];
@ -120,8 +123,7 @@ return_p:
* @param dcb owner DCB
*
*/
void mysql_protocol_done (
DCB* dcb)
void mysql_protocol_done(DCB* dcb)
{
MySQLProtocol* p;
server_command_t* scmd;
@ -156,8 +158,7 @@ retblock:
* @param conn MySQL protocol structure
* @return 0 on success, 1 on failure
*/
int gw_read_backend_handshake(
MySQLProtocol *conn)
int gw_read_backend_handshake(MySQLProtocol *conn)
{
GWBUF *head = NULL;
DCB *dcb = conn->owner_dcb;
@ -169,7 +170,6 @@ int gw_read_backend_handshake(
if ((n = dcb_read(dcb, &head, 0)) != -1)
{
dcb->last_read = hkheartbeat;
if (head)
@ -182,7 +182,8 @@ int gw_read_backend_handshake(
* just return with less bytes
*/
if (h_len <= 4) {
if (h_len <= 4)
{
/* log error this exit point */
conn->protocol_auth_state = MYSQL_HANDSHAKE_FAILED;
MXS_DEBUG("%lu [gw_read_backend_handshake] after "
@ -198,7 +199,7 @@ int gw_read_backend_handshake(
{
size_t len = MYSQL_GET_PACKET_LEN(payload);
uint16_t errcode = MYSQL_GET_ERRCODE(payload);
char* bufstr = strndup(&((char *)payload)[7], len-3);
char* bufstr = strndup(&((char *)payload)[7], len - 3);
conn->protocol_auth_state = MYSQL_HANDSHAKE_FAILED;
@ -223,7 +224,8 @@ int gw_read_backend_handshake(
* This will avoid filling the error log.
*/
if (errcode == 1129) {
if (errcode == 1129)
{
MXS_ERROR("Server %s has been put into maintenance mode due "
"to the server blocking connections from MaxScale. "
"Run 'mysqladmin -h %s -P %d flush-hosts' on this "
@ -241,7 +243,8 @@ int gw_read_backend_handshake(
//get mysql packet size, 3 bytes
packet_len = gw_mysql_get_byte3(payload);
if (h_len < (packet_len + 4)) {
if (h_len < (packet_len + 4))
{
/*
* data in buffer less than expected in the
* packet. Log error this exit point
@ -264,7 +267,8 @@ int gw_read_backend_handshake(
//Now decode mysql handshake
success = gw_decode_mysql_server_handshake(conn, payload);
if (success < 0) {
if (success < 0)
{
/* MySQL handshake has not been properly decoded
* we cannot continue
* log error this exit point
@ -276,7 +280,10 @@ int gw_read_backend_handshake(
"state = MYSQL_HANDSHAKE_FAILED.",
pthread_self(),
conn->owner_dcb->fd);
while((head = gwbuf_consume(head, GWBUF_LENGTH(head))));
while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))))
{
;
}
return 1;
}
@ -303,14 +310,12 @@ int gw_read_backend_handshake(
* @return 0 on success, < 0 on failure
*
*/
int gw_decode_mysql_server_handshake(
MySQLProtocol *conn,
uint8_t *payload)
int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload)
{
uint8_t *server_version_end = NULL;
uint16_t mysql_server_capabilities_one = 0;
uint16_t mysql_server_capabilities_two = 0;
unsigned long tid =0;
unsigned long tid = 0;
uint8_t scramble_data_1[GW_SCRAMBLE_LENGTH_323] = "";
uint8_t scramble_data_2[GW_MYSQL_SCRAMBLE_SIZE - GW_SCRAMBLE_LENGTH_323] = "";
uint8_t capab_ptr[4] = "";
@ -336,7 +341,7 @@ int gw_decode_mysql_server_handshake(
tid = gw_mysql_get_byte4(payload);
memcpy(&conn->tid, &tid, 4);
payload +=4;
payload += 4;
// scramble_part 1
memcpy(scramble_data_1, payload, GW_SCRAMBLE_LENGTH_323);
@ -348,7 +353,7 @@ int gw_decode_mysql_server_handshake(
mysql_server_capabilities_one = gw_mysql_get_byte2(payload);
//Get capabilities_part 1 (2 bytes) + 1 language + 2 server_status
payload +=5;
payload += 5;
mysql_server_capabilities_two = gw_mysql_get_byte2(payload);
@ -358,7 +363,7 @@ int gw_decode_mysql_server_handshake(
memcpy(&(capab_ptr[2]), &mysql_server_capabilities_two, 2);
// 2 bytes shift
payload+=2;
payload += 2;
// get scramble len
if (payload[0] > 0)
@ -401,8 +406,7 @@ int gw_decode_mysql_server_handshake(
* @return -1 in case of failure, 0 if there was nothing to read, 1 if read
* was successful.
*/
int gw_receive_backend_auth(
MySQLProtocol *protocol)
int gw_receive_backend_auth(MySQLProtocol *protocol)
{
int n = -1;
GWBUF *head = NULL;
@ -433,7 +437,7 @@ int gw_receive_backend_auth(
{
size_t len = MYSQL_GET_PACKET_LEN(ptr);
char* err = strndup(&((char *)ptr)[8], 5);
char* bufstr = strndup(&((char *)ptr)[13], len-4-5);
char* bufstr = strndup(&((char *)ptr)[13], len - 4 - 5);
MXS_DEBUG("%lu [gw_receive_backend_auth] Invalid "
"authentication message from backend dcb %p "
@ -471,7 +475,10 @@ int gw_receive_backend_auth(
/*<
* Remove data from buffer.
*/
while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL);
while ((head = gwbuf_consume(head, GWBUF_LENGTH(head))) != NULL)
{
;
}
}
else if (n == 0)
{
@ -517,8 +524,7 @@ int gw_receive_backend_auth(
* @param passwd The SHA1(real_password): Note real_password is unknown
* @return 0 on success, 1 on failure
*/
int gw_send_authentication_to_backend(
char *dbname,
int gw_send_authentication_to_backend(char *dbname,
char *user,
uint8_t *passwd,
MySQLProtocol *conn)
@ -551,10 +557,14 @@ int gw_send_authentication_to_backend(
}
if (strlen(dbname))
{
curr_db = dbname;
}
if (memcmp(passwd, null_client_sha1, MYSQL_SCRAMBLE_LEN))
{
curr_passwd = passwd;
}
dcb = conn->owner_dcb;
final_capabilities = gw_mysql_get_byte4((uint8_t *)&server_capabilities);
@ -565,14 +575,16 @@ int gw_send_authentication_to_backend(
/* get charset the client sent and use it for connection auth */
charset = conn->charset;
if (compress) {
if (compress)
{
final_capabilities |= GW_MYSQL_CAPABILITIES_COMPRESS;
#ifdef DEBUG_MYSQL_CONN
fprintf(stderr, ">>>> Backend Connection with compression\n");
#endif
}
if (curr_passwd != NULL) {
if (curr_passwd != NULL)
{
uint8_t hash1[GW_MYSQL_SCRAMBLE_SIZE]="";
uint8_t hash2[GW_MYSQL_SCRAMBLE_SIZE]="";
uint8_t new_sha[GW_MYSQL_SCRAMBLE_SIZE]="";
@ -594,10 +606,13 @@ int gw_send_authentication_to_backend(
}
if (curr_db == NULL) {
if (curr_db == NULL)
{
// without db
final_capabilities &= ~GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB;
} else {
}
else
{
final_capabilities |= GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB;
}
@ -616,19 +631,23 @@ int gw_send_authentication_to_backend(
// next will be + 1 (scramble_len) + 20 (fixed_scramble) + 1 (user NULL term) + 1 (db NULL term)
if (curr_passwd != NULL) {
if (curr_passwd != NULL)
{
bytes++;
bytes += GW_MYSQL_SCRAMBLE_SIZE;
} else {
}
else
{
bytes++;
}
if (curr_db != NULL) {
if (curr_db != NULL)
{
bytes += strlen(curr_db);
bytes++;
}
bytes +=strlen("mysql_native_password");
bytes += strlen("mysql_native_password");
bytes++;
// the packet header
@ -670,23 +689,27 @@ int gw_send_authentication_to_backend(
payload += strlen(user);
payload++;
if (curr_passwd != NULL) {
if (curr_passwd != NULL)
{
// set the auth-length
*payload = GW_MYSQL_SCRAMBLE_SIZE;
payload++;
//copy the 20 bytes scramble data after packet_buffer+36+user+NULL+1 (byte of auth-length)
//copy the 20 bytes scramble data after packet_buffer + 36 + user + NULL + 1 (byte of auth-length)
memcpy(payload, client_scramble, GW_MYSQL_SCRAMBLE_SIZE);
payload += GW_MYSQL_SCRAMBLE_SIZE;
} else {
}
else
{
// skip the auth-length and write a NULL
payload++;
}
// if the db is not NULL append it
if (curr_db != NULL) {
if (curr_db != NULL)
{
memcpy(payload, curr_db, strlen(curr_db));
payload += strlen(curr_db);
payload++;
@ -699,13 +722,16 @@ int gw_send_authentication_to_backend(
payload++;
// put here the paylod size: bytes to write - 4 bytes packet header
gw_mysql_set_byte3(payload_start, (bytes-4));
gw_mysql_set_byte3(payload_start, (bytes - 4));
rv = dcb_write(dcb, buffer);
if (rv == 0) {
if (rv == 0)
{
return 1;
} else {
}
else
{
return 0;
}
}
@ -724,10 +750,7 @@ int gw_send_authentication_to_backend(
* backend server. In failure, fd == -1 and socket is closed.
*
*/
int gw_do_connect_to_backend(
char *host,
int port,
int *fd)
int gw_do_connect_to_backend(char *host, int port, int *fd)
{
struct sockaddr_in serv_addr;
int rv;
@ -738,7 +761,8 @@ int gw_do_connect_to_backend(
serv_addr.sin_family = AF_INET;
so = socket(AF_INET,SOCK_STREAM,0);
if (so < 0) {
if (so < 0)
{
char errbuf[STRERROR_BUFLEN];
MXS_ERROR("Establishing connection to backend server "
"%s:%d failed.\n\t\t Socket creation failed "
@ -755,7 +779,7 @@ int gw_do_connect_to_backend(
serv_addr.sin_port = htons(port);
bufsize = GW_BACKEND_SO_SNDBUF;
if(setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0)
if (setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)) != 0)
{
char errbuf[STRERROR_BUFLEN];
MXS_ERROR("Failed to set socket options "
@ -771,7 +795,7 @@ int gw_do_connect_to_backend(
}
bufsize = GW_BACKEND_SO_RCVBUF;
if(setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0)
if (setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)) != 0)
{
char errbuf[STRERROR_BUFLEN];
MXS_ERROR("Failed to set socket options "
@ -787,7 +811,7 @@ int gw_do_connect_to_backend(
}
int one = 1;
if(setsockopt(so, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) != 0)
if (setsockopt(so, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)) != 0)
{
char errbuf[STRERROR_BUFLEN];
MXS_ERROR("Failed to set socket options "
@ -856,9 +880,10 @@ close_so:
* @return String representation of the state
*
*/
const char *
gw_mysql_protocol_state2string (int state) {
switch(state) {
const char* gw_mysql_protocol_state2string (int state)
{
switch(state)
{
case MYSQL_ALLOC:
return "MySQL Protocl struct allocated";
case MYSQL_PENDING_CONNECT:
@ -873,17 +898,20 @@ gw_mysql_protocol_state2string (int state) {
return "MySQL Authentication failed";
case MYSQL_IDLE:
return "MySQL authentication is succesfully done.";
case MYSQL_AUTH_SSL_REQ: return "MYSQL_AUTH_SSL_REQ";
case MYSQL_AUTH_SSL_HANDSHAKE_DONE: return "MYSQL_AUTH_SSL_HANDSHAKE_DONE";
case MYSQL_AUTH_SSL_HANDSHAKE_FAILED: return "MYSQL_AUTH_SSL_HANDSHAKE_FAILED";
case MYSQL_AUTH_SSL_HANDSHAKE_ONGOING: return "MYSQL_AUTH_SSL_HANDSHAKE_ONGOING";
case MYSQL_AUTH_SSL_REQ:
return "MYSQL_AUTH_SSL_REQ";
case MYSQL_AUTH_SSL_HANDSHAKE_DONE:
return "MYSQL_AUTH_SSL_HANDSHAKE_DONE";
case MYSQL_AUTH_SSL_HANDSHAKE_FAILED:
return "MYSQL_AUTH_SSL_HANDSHAKE_FAILED";
case MYSQL_AUTH_SSL_HANDSHAKE_ONGOING:
return "MYSQL_AUTH_SSL_HANDSHAKE_ONGOING";
default:
return "MySQL (unknown protocol state)";
}
}
GWBUF* mysql_create_com_quit(
GWBUF* bufparam,
GWBUF* mysql_create_com_quit(GWBUF* bufparam,
int packet_number)
{
uint8_t* data;
@ -915,8 +943,7 @@ GWBUF* mysql_create_com_quit(
return buf;
}
int mysql_send_com_quit(
DCB* dcb,
int mysql_send_com_quit(DCB* dcb,
int packet_number,
GWBUF* bufparam)
{
@ -949,8 +976,7 @@ int mysql_send_com_quit(
}
GWBUF* mysql_create_custom_error(
int packet_number,
GWBUF* mysql_create_custom_error(int packet_number,
int affected_rows,
const char* msg)
{
@ -974,13 +1000,15 @@ GWBUF* mysql_create_custom_error(
field_count = 0xff;
gw_mysql_set_byte2(mysql_err, mysql_errno);
mysql_statemsg[0]='#';
memcpy(mysql_statemsg+1, mysql_state, 5);
memcpy(mysql_statemsg + 1, mysql_state, 5);
if (msg != NULL) {
if (msg != NULL)
{
mysql_error_msg = msg;
}
mysql_payload_size = sizeof(field_count) +
mysql_payload_size =
sizeof(field_count) +
sizeof(mysql_err) +
sizeof(mysql_statemsg) +
strlen(mysql_error_msg);
@ -1034,8 +1062,7 @@ GWBUF* mysql_create_custom_error(
* @return 1 Non-zero if data was sent
*
*/
int mysql_send_custom_error (
DCB *dcb,
int mysql_send_custom_error(DCB *dcb,
int packet_number,
int in_affected_rows,
const char *mysql_message)
@ -1057,8 +1084,7 @@ int mysql_send_custom_error (
*
* @note the function doesn't fail
*/
GWBUF* gw_create_change_user_packet(
MYSQL_session* mses,
GWBUF* gw_create_change_user_packet(MYSQL_session* mses,
MySQLProtocol* protocol)
{
char* db;
@ -1184,8 +1210,7 @@ GWBUF* gw_create_change_user_packet(
* Set correct type to GWBUF so that it will be handled like session
* commands
*/
buffer->gwbuf_type =
GWBUF_TYPE_MYSQL|GWBUF_TYPE_SINGLE_STMT|GWBUF_TYPE_SESCMD;
buffer->gwbuf_type = GWBUF_TYPE_MYSQL|GWBUF_TYPE_SINGLE_STMT|GWBUF_TYPE_SESCMD;
payload = GWBUF_DATA(buffer);
memset(payload, '\0', bytes);
payload_start = payload;
@ -1208,7 +1233,7 @@ GWBUF* gw_create_change_user_packet(
payload++;
/**
* copy the 20 bytes scramble data after
* packet_buffer+36+user+NULL+1 (byte of auth-length)
* packet_buffer + 36 + user + NULL + 1 (byte of auth-length)
*/
memcpy(payload, client_scramble, GW_MYSQL_SCRAMBLE_SIZE);
payload += GW_MYSQL_SCRAMBLE_SIZE;
@ -1248,8 +1273,7 @@ GWBUF* gw_create_change_user_packet(
* @param passwd The SHA1(real_password)
* @return 1 on success, 0 on failure
*/
int gw_send_change_user_to_backend(
char *dbname,
int gw_send_change_user_to_backend(char *dbname,
char *user,
uint8_t *passwd,
MySQLProtocol *conn)
@ -1284,7 +1308,14 @@ int gw_send_change_user_to_backend(
* @return 0 on succesful check or 1 on failure
*
*/
int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_len, uint8_t *scramble, unsigned int scramble_len, char *username, uint8_t *stage1_hash) {
int gw_check_mysql_scramble_data(DCB *dcb,
uint8_t *token,
unsigned int token_len,
uint8_t *scramble,
unsigned int scramble_len,
char *username,
uint8_t *stage1_hash)
{
uint8_t step1[GW_MYSQL_SCRAMBLE_SIZE]="";
uint8_t step2[GW_MYSQL_SCRAMBLE_SIZE +1]="";
uint8_t check_hash[GW_MYSQL_SCRAMBLE_SIZE]="";
@ -1292,7 +1323,8 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
uint8_t password[GW_MYSQL_SCRAMBLE_SIZE]="";
int ret_val = 1;
if ((username == NULL) || (scramble == NULL) || (stage1_hash == NULL)) {
if ((username == NULL) || (scramble == NULL) || (stage1_hash == NULL))
{
return 1;
}
@ -1303,7 +1335,8 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
ret_val = gw_find_mysql_user_password_sha1(username, password, dcb);
if (ret_val) {
if (ret_val)
{
/* if password was sent, fill stage1_hash with at least 1 byte in order
* to create right error message: (using password: YES|NO)
*/
@ -1313,14 +1346,17 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
return 1;
}
if (token && token_len) {
if (token && token_len)
{
/*<
* convert in hex format: this is the content of mysql.user table.
* The field password is without the '*' prefix and it is 40 bytes long
*/
gw_bin2hex(hex_double_sha1, password, SHA_DIGEST_LENGTH);
} else {
}
else
{
/* check if the password is not set in the user table */
return memcmp(password, null_client_sha1, MYSQL_SCRAMBLE_LEN) ? 1 : 0;
}
@ -1401,7 +1437,8 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
*
*/
int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, DCB *dcb) {
int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, DCB *dcb)
{
SERVICE *service = NULL;
struct sockaddr_in *client;
char *user_password = NULL;
@ -1416,7 +1453,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
memcpy(&key.ipv4, client, sizeof(struct sockaddr_in));
key.netmask = 32;
key.resource = client_data->db;
if(strlen(dcb->remote) < MYSQL_HOST_MAXLEN)
if (strlen(dcb->remote) < MYSQL_HOST_MAXLEN)
{
strcpy(key.hostname, dcb->remote);
}
@ -1431,10 +1468,12 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
/* look for user@current_ipv4 now */
user_password = mysql_users_fetch(service->users, &key);
if (!user_password) {
if (!user_password)
{
/* The user is not authenticated @ current IPv4 */
while (1) {
while (1)
{
/*
* (1) Check for localhost first: 127.0.0.1 (IPv4 only)
*/
@ -1456,7 +1495,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
user_password = mysql_users_fetch(service->users, &key);
if (user_password) {
if (user_password)
{
break;
}
@ -1466,7 +1506,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
user_password = mysql_users_fetch(service->users, &key);
if (user_password) {
if (user_password)
{
break;
}
@ -1476,7 +1517,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
user_password = mysql_users_fetch(service->users, &key);
if (user_password) {
if (user_password)
{
break;
}
@ -1500,7 +1542,8 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
break;
}
if (!user_password) {
if (!user_password)
{
/*
* user@% not found.
*/
@ -1520,14 +1563,16 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
}
/* If user@host has been found we get the the password in binary format*/
if (user_password) {
if (user_password)
{
/*
* Convert the hex data (40 bytes) to binary (20 bytes).
* The gateway_password represents the SHA1(SHA1(real_password)).
* Please note: the real_password is unknown and SHA1(real_password) is unknown as well
*/
int passwd_len=strlen(user_password);
if (passwd_len) {
if (passwd_len)
{
passwd_len = (passwd_len <= (SHA_DIGEST_LENGTH * 2)) ? passwd_len : (SHA_DIGEST_LENGTH * 2);
gw_hex2bin(gateway_password, user_password, passwd_len);
}
@ -1550,9 +1595,7 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
* @return packet length
*
*/
int
mysql_send_auth_error (
DCB *dcb,
int mysql_send_auth_error(DCB *dcb,
int packet_number,
int in_affected_rows,
const char *mysql_message)
@ -1586,13 +1629,15 @@ mysql_send_auth_error (
field_count = 0xff;
gw_mysql_set_byte2(mysql_err, mysql_errno);
mysql_statemsg[0]='#';
memcpy(mysql_statemsg+1, mysql_state, 5);
memcpy(mysql_statemsg + 1, mysql_state, 5);
if (mysql_message != NULL) {
if (mysql_message != NULL)
{
mysql_error_msg = mysql_message;
}
mysql_payload_size = sizeof(field_count) + sizeof(mysql_err) + sizeof(mysql_statemsg) + strlen(mysql_error_msg);
mysql_payload_size =
sizeof(field_count) + sizeof(mysql_err) + sizeof(mysql_statemsg) + strlen(mysql_error_msg);
// allocate memory for packet header + payload
if ((buf = gwbuf_alloc(sizeof(mysql_packet_header) + mysql_payload_size)) == NULL)
@ -1641,8 +1686,7 @@ mysql_send_auth_error (
* @return pointer to gwbuf containing a complete packet or
* NULL if no complete packet was found.
*/
GWBUF* gw_MySQL_get_next_packet(
GWBUF** p_readbuf)
GWBUF* gw_MySQL_get_next_packet(GWBUF** p_readbuf)
{
GWBUF* packetbuf;
GWBUF* readbuf;
@ -1669,7 +1713,7 @@ GWBUF* gw_MySQL_get_next_packet(
}
totalbuflen = gwbuf_length(readbuf);
data = (uint8_t *)GWBUF_DATA((readbuf));
packetlen = MYSQL_GET_PACKET_LEN(data)+4;
packetlen = MYSQL_GET_PACKET_LEN(data) + 4;
/** packet is incomplete */
if (packetlen > totalbuflen)
@ -1691,9 +1735,9 @@ GWBUF* gw_MySQL_get_next_packet(
size_t bytestocopy;
buflen = GWBUF_LENGTH((*p_readbuf));
bytestocopy = MIN(buflen,packetlen-nbytes_copied);
bytestocopy = MIN(buflen, packetlen - nbytes_copied);
memcpy(target+nbytes_copied, src, bytestocopy);
memcpy(target + nbytes_copied, src, bytestocopy);
*p_readbuf = gwbuf_consume((*p_readbuf), bytestocopy);
totalbuflen = gwbuf_length((*p_readbuf));
nbytes_copied += bytestocopy;
@ -1707,8 +1751,7 @@ return_packetbuf:
/**
* Move <npackets> from buffer pointed to by <*p_readbuf>.
*/
GWBUF* gw_MySQL_get_packets(
GWBUF** p_srcbuf,
GWBUF* gw_MySQL_get_packets(GWBUF** p_srcbuf,
int* npackets)
{
GWBUF* packetbuf;
@ -1726,8 +1769,7 @@ GWBUF* gw_MySQL_get_packets(
}
static server_command_t* server_command_init(
server_command_t* srvcmd,
static server_command_t* server_command_init(server_command_t* srvcmd,
mysql_server_cmd_t cmd)
{
server_command_t* c;
@ -1748,11 +1790,9 @@ static server_command_t* server_command_init(
return c;
}
static server_command_t* server_command_copy(
server_command_t* srvcmd)
static server_command_t* server_command_copy(server_command_t* srvcmd)
{
server_command_t* c =
(server_command_t *)malloc(sizeof(server_command_t));
server_command_t* c = (server_command_t *)malloc(sizeof(server_command_t));
*c = *srvcmd;
return c;
@ -1760,8 +1800,7 @@ static server_command_t* server_command_copy(
#define MAX_CMD_HISTORY 10
void protocol_archive_srv_command(
MySQLProtocol* p)
void protocol_archive_srv_command(MySQLProtocol* p)
{
server_command_t* s1;
server_command_t* h1;
@ -1828,8 +1867,7 @@ retblock:
* If router expects to get separate, complete statements, add MySQL command
* to MySQLProtocol structure. It is removed when response has arrived.
*/
void protocol_add_srv_command(
MySQLProtocol* p,
void protocol_add_srv_command(MySQLProtocol* p,
mysql_server_cmd_t cmd)
{
#if defined(EXTRA_SS_DEBUG)
@ -1879,8 +1917,7 @@ retblock:
*
* Remove current (=oldest) command.
*/
void protocol_remove_srv_command(
MySQLProtocol* p)
void protocol_remove_srv_command(MySQLProtocol* p)
{
server_command_t* s;
spinlock_acquire(&p->protocol_lock);
@ -1903,8 +1940,7 @@ void protocol_remove_srv_command(
spinlock_release(&p->protocol_lock);
}
mysql_server_cmd_t protocol_get_srv_command(
MySQLProtocol* p,
mysql_server_cmd_t protocol_get_srv_command(MySQLProtocol* p,
bool removep)
{
mysql_server_cmd_t cmd;
@ -1930,8 +1966,7 @@ mysql_server_cmd_t protocol_get_srv_command(
* Fails if read buffer doesn't include enough data to read the
* packet length.
*/
void init_response_status (
GWBUF* buf,
void init_response_status(GWBUF* buf,
mysql_server_cmd_t cmd,
int* npackets,
ssize_t* nbytes_left)
@ -1951,7 +1986,8 @@ void init_response_status (
}
else
{
switch (cmd) {
switch (cmd)
{
case MYSQL_COM_STMT_PREPARE:
packet = (uint8_t *)GWBUF_DATA(buf);
/** ok + nparam + eof + nattr + eof */
@ -1992,8 +2028,7 @@ void init_response_status (
* Read how many packets are left from current response and how many bytes there
* is still to be read from the current packet.
*/
bool protocol_get_response_status (
MySQLProtocol* p,
bool protocol_get_response_status(MySQLProtocol* p,
int* npackets,
ssize_t* nbytes)
{
@ -2018,12 +2053,10 @@ bool protocol_get_response_status (
return succp;
}
void protocol_set_response_status (
MySQLProtocol* p,
void protocol_set_response_status(MySQLProtocol* p,
int npackets_left,
ssize_t nbytes)
{
CHK_PROTOCOL(p);
spinlock_acquire(&p->protocol_lock);
@ -2036,8 +2069,7 @@ void protocol_set_response_status (
spinlock_release(&p->protocol_lock);
}
char* create_auth_failed_msg(
GWBUF* readbuf,
char* create_auth_failed_msg(GWBUF*readbuf,
char* hostaddr,
uint8_t* sha1)
{
@ -2046,7 +2078,7 @@ char* create_auth_failed_msg(
const char* ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
/** -4 comes from 2X'%s' minus terminating char */
errstr = (char *)malloc(strlen(uname)+strlen(ferrstr)+strlen(hostaddr)+strlen("YES")-6 + 1);
errstr = (char *)malloc(strlen(uname) + strlen(ferrstr) + strlen(hostaddr) + strlen("YES") - 6 + 1);
if (errstr != NULL)
{
@ -2068,8 +2100,7 @@ char* create_auth_failed_msg(
* @return Pointer to a copy of the username. NULL if memory allocation
* failed or if username was empty.
*/
char* get_username_from_auth(
char* ptr,
char* get_username_from_auth(char* ptr,
uint8_t* data)
{
char* first_letter;
@ -2085,7 +2116,7 @@ char* get_username_from_auth(
if (ptr == NULL)
{
if ((rval = (char *)malloc(MYSQL_USER_MAXLEN+1)) == NULL)
if ((rval = (char *)malloc(MYSQL_USER_MAXLEN + 1)) == NULL)
{
goto retblock;
}
@ -2094,35 +2125,45 @@ char* get_username_from_auth(
{
rval = ptr;
}
snprintf(rval, MYSQL_USER_MAXLEN+1, "%s", first_letter);
snprintf(rval, MYSQL_USER_MAXLEN + 1, "%s", first_letter);
retblock:
return rval;
}
int check_db_name_after_auth(DCB *dcb, char *database, int auth_ret) {
int check_db_name_after_auth(DCB *dcb, char *database, int auth_ret)
{
int db_exists = -1;
/* check for dabase name and possible match in resource hashtable */
if (database && strlen(database)) {
if (database && strlen(database))
{
/* if database names are loaded we can check if db name exists */
if (dcb->service->resources != NULL) {
if (hashtable_fetch(dcb->service->resources, database)) {
if (dcb->service->resources != NULL)
{
if (hashtable_fetch(dcb->service->resources, database))
{
db_exists = 1;
} else {
}
else
{
db_exists = 0;
}
} else {
}
else
{
/* if database names are not loaded we don't allow connection with db name*/
db_exists = -1;
}
if (db_exists == 0 && auth_ret == 0) {
if (db_exists == 0 && auth_ret == 0)
{
auth_ret = 2;
}
if (db_exists < 0 && auth_ret == 0) {
if (db_exists < 0 && auth_ret == 0)
{
auth_ret = 1;
}
}
@ -2140,8 +2181,7 @@ int check_db_name_after_auth(DCB *dcb, char *database, int auth_ret) {
*
* @return Pointer to the allocated string or NULL on failure
*/
char *create_auth_fail_str(
char *username,
char *create_auth_fail_str(char *username,
char *hostaddr,
char *sha1,
char *db,
@ -2152,15 +2192,19 @@ char *create_auth_fail_str(
int db_len;
if (db != NULL)
{
db_len = strlen(db);
}
else
{
db_len = 0;
}
if (db_len > 0)
{
ferrstr = "Access denied for user '%s'@'%s' (using password: %s) to database '%s'";
}
else if(errcode == MYSQL_FAILED_AUTH_SSL)
else if (errcode == MYSQL_FAILED_AUTH_SSL)
{
ferrstr = "Access without SSL denied";
}
@ -2168,7 +2212,9 @@ char *create_auth_fail_str(
{
ferrstr = "Access denied for user '%s'@'%s' (using password: %s)";
}
errstr = (char *)malloc(strlen(username)+strlen(ferrstr)+strlen(hostaddr)+strlen("YES")-6 + db_len + ((db_len > 0) ? (strlen(" to database ") +2) : 0) + 1);
errstr = (char *)malloc(strlen(username) + strlen(ferrstr) +
strlen(hostaddr) + strlen("YES") - 6 +
db_len + ((db_len > 0) ? (strlen(" to database ") +2) : 0) + 1);
if (errstr == NULL)
{
@ -2182,7 +2228,7 @@ char *create_auth_fail_str(
{
sprintf(errstr, ferrstr, username, hostaddr, (*sha1 == '\0' ? "NO" : "YES"), db);
}
else if(errcode == MYSQL_FAILED_AUTH_SSL)
else if (errcode == MYSQL_FAILED_AUTH_SSL)
{
sprintf(errstr, "%s", ferrstr);
}