Merge branch 'fix-127' into feature-MAX-2
Conflicts: server/core/dbusers.c server/core/service.c server/core/users.c server/include/dbusers.h server/include/users.h server/modules/protocol/mysql_client.c server/modules/protocol/mysql_common.c
This commit is contained in:
@ -243,7 +243,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
switch (receive_rc) {
|
||||
case -1:
|
||||
backend_protocol->state = MYSQL_AUTH_FAILED;
|
||||
|
||||
|
||||
LOGIF(LE, (skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"Error : backend server didn't "
|
||||
@ -300,6 +300,9 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
gwbuf_length(dcb->delayq));
|
||||
}
|
||||
|
||||
/* try reload users' table for next connection */
|
||||
service_refresh_users(dcb->session->client->service);
|
||||
|
||||
while (session->state != SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
ss_dassert(
|
||||
@ -882,6 +885,14 @@ static int gw_change_user(DCB *backend, SERVER *server, SESSION *in_session, GWB
|
||||
// Note: if auth_token_len == 0 && auth_token == NULL, user is without password
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client, auth_token, auth_token_len, client_protocol->scramble, sizeof(client_protocol->scramble), username, client_sha1);
|
||||
|
||||
if (auth_ret != 0) {
|
||||
if (!service_refresh_users(backend->session->client->service)) {
|
||||
/* Try authentication again with new repository data */
|
||||
/* Note: if no auth client authentication will fail */
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client, auth_token, auth_token_len, client_protocol->scramble, sizeof(client_protocol->scramble), username, client_sha1);
|
||||
}
|
||||
}
|
||||
|
||||
// let's free the auth_token now
|
||||
if (auth_token)
|
||||
free(auth_token);
|
||||
@ -891,6 +902,7 @@ static int gw_change_user(DCB *backend, SERVER *server, SESSION *in_session, GWB
|
||||
|
||||
// send the error packet
|
||||
mysql_send_auth_error(backend->session->client, 1, 0, "Authorization failed on change_user");
|
||||
rv = 1;
|
||||
|
||||
} else {
|
||||
// get db name
|
||||
|
||||
@ -29,7 +29,10 @@
|
||||
* 24/06/2013 Massimiliano Pinto Added: fetch passwords from service users' hashtable
|
||||
* 02/09/2013 Massimiliano Pinto Added: session refcount
|
||||
* 16/12/2013 Massimiliano Pinto Added: client closed socket detection with recv(..., MSG_PEEK)
|
||||
* 07/02/2014 Massimiliano Pinto Added: client IPv4 in dcb->ipv4 and inet_ntop for string representation
|
||||
* 24/02/2014 Massimiliano Pinto Added: on failed authentication a new users' table is loaded with time and frequency limitations
|
||||
* If current user is authenticated the new users' table will replace the old one
|
||||
* 28/02/2014 Massimiliano Pinto Added: client IPv4 in dcb->ipv4 and inet_ntop for string representation
|
||||
*
|
||||
*/
|
||||
|
||||
#include <skygw_utils.h>
|
||||
@ -445,6 +448,15 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
||||
username,
|
||||
stage1_hash);
|
||||
|
||||
/* On failed auth try to load users' table from backend database */
|
||||
if (auth_ret != 0) {
|
||||
if (!service_refresh_users(dcb->service)) {
|
||||
/* Try authentication again with new repository data */
|
||||
/* Note: if no auth client authentication will fail */
|
||||
auth_ret = gw_check_mysql_scramble_data(dcb, auth_token, auth_token_len, protocol->scramble, sizeof(protocol->scramble), username, stage1_hash);
|
||||
}
|
||||
}
|
||||
|
||||
/* let's free the auth_token now */
|
||||
if (auth_token)
|
||||
free(auth_token);
|
||||
|
||||
@ -257,13 +257,17 @@ int gw_decode_mysql_server_handshake(MySQLProtocol *conn, uint8_t *payload) {
|
||||
payload+=2;
|
||||
|
||||
// get scramble len
|
||||
scramble_len = payload[0] -1;
|
||||
ss_dassert(scramble_len > GW_SCRAMBLE_LENGTH_323);
|
||||
ss_dassert(scramble_len <= GW_MYSQL_SCRAMBLE_SIZE);
|
||||
if (payload[0] > 0) {
|
||||
scramble_len = payload[0] -1;
|
||||
ss_dassert(scramble_len > GW_SCRAMBLE_LENGTH_323);
|
||||
ss_dassert(scramble_len <= GW_MYSQL_SCRAMBLE_SIZE);
|
||||
|
||||
if ( (scramble_len < GW_SCRAMBLE_LENGTH_323) || scramble_len > GW_MYSQL_SCRAMBLE_SIZE) {
|
||||
/* log this */
|
||||
return -2;
|
||||
if ( (scramble_len < GW_SCRAMBLE_LENGTH_323) || scramble_len > GW_MYSQL_SCRAMBLE_SIZE) {
|
||||
/* log this */
|
||||
return -2;
|
||||
}
|
||||
} else {
|
||||
scramble_len = GW_MYSQL_SCRAMBLE_SIZE;
|
||||
}
|
||||
|
||||
// skip 10 zero bytes
|
||||
@ -403,7 +407,7 @@ int gw_send_authentication_to_backend(
|
||||
uint8_t client_capabilities[4];
|
||||
uint32_t server_capabilities;
|
||||
uint32_t final_capabilities;
|
||||
char dbpass[129]="";
|
||||
char dbpass[MYSQL_USER_MAXLEN + 1]="";
|
||||
GWBUF *buffer;
|
||||
DCB *dcb;
|
||||
|
||||
@ -814,7 +818,7 @@ int gw_send_change_user_to_backend(char *dbname, char *user, uint8_t *passwd, My
|
||||
uint8_t client_capabilities[4];
|
||||
uint32_t server_capabilities;
|
||||
uint32_t final_capabilities;
|
||||
char dbpass[129]="";
|
||||
char dbpass[MYSQL_USER_MAXLEN + 1]="";
|
||||
GWBUF *buffer;
|
||||
DCB *dcb;
|
||||
|
||||
@ -981,12 +985,12 @@ int gw_send_change_user_to_backend(char *dbname, char *user, uint8_t *passwd, My
|
||||
* Check authentication token received against stage1_hash and scramble
|
||||
*
|
||||
* @param dcb The current dcb
|
||||
* @param token The token sent by the client in the authentication request
|
||||
* @param token_len The token size in bytes
|
||||
* @param scramble The scramble data sent by the server during handshake
|
||||
* @param scramble_len The scrable size in bytes
|
||||
* @param username The current username in the authentication request
|
||||
* @param stage1_hash The SHA1(candidate_password) decoded by this routine
|
||||
* @param token The token sent by the client in the authentication request
|
||||
* @param token_len The token size in bytes
|
||||
* @param scramble The scramble data sent by the server during handshake
|
||||
* @param scramble_len The scrable size in bytes
|
||||
* @param username The current username in the authentication request
|
||||
* @param stage1_hash The SHA1(candidate_password) decoded by this routine
|
||||
* @return 0 on succesful check or != 0 on failure
|
||||
*
|
||||
*/
|
||||
@ -1007,7 +1011,7 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
|
||||
* please note 'real_password' is unknown!
|
||||
*/
|
||||
|
||||
ret_val = gw_find_mysql_user_password_sha1(username, password, (DCB *) dcb);
|
||||
ret_val = gw_find_mysql_user_password_sha1(username, password, dcb);
|
||||
|
||||
if (ret_val) {
|
||||
return 1;
|
||||
@ -1087,25 +1091,27 @@ int gw_check_mysql_scramble_data(DCB *dcb, uint8_t *token, unsigned int token_le
|
||||
/**
|
||||
* gw_find_mysql_user_password_sha1
|
||||
*
|
||||
* The routine fetches look for an user int he Gateway users' tableg
|
||||
* If found the HEX passwotd, representing sha1(sha1(password)), is converted in binary data and
|
||||
* The routine fetches look for an user int he Gateway users' table
|
||||
* 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
|
||||
* copied into gateway_password
|
||||
*
|
||||
* @param username The user to look for
|
||||
* @param gateway_password The related SHA1(SHA1(password)), the pointer must be preallocated
|
||||
* @param repository The pointer to users' table data, passed as void *
|
||||
* @param username The user to look for
|
||||
* @param gateway_password The related SHA1(SHA1(password)), the pointer must be preallocated
|
||||
* @param dcb Current DCB
|
||||
* @return 1 if user is not found or 0 if the user exists
|
||||
*
|
||||
*/
|
||||
|
||||
int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password, void *repository) {
|
||||
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;
|
||||
DCB *dcb = (DCB *)repository;
|
||||
MYSQL_USER_HOST key;
|
||||
|
||||
service = (SERVICE *) ((DCB *)repository)->service;
|
||||
service = (SERVICE *) dcb->service;
|
||||
client = (struct sockaddr_in *) &dcb->ipv4;
|
||||
|
||||
key.user = username;
|
||||
|
||||
Reference in New Issue
Block a user