diff --git a/include/maxscale/authenticator.h b/include/maxscale/authenticator.h index b8db5eb40..dd7d92c7c 100644 --- a/include/maxscale/authenticator.h +++ b/include/maxscale/authenticator.h @@ -80,8 +80,9 @@ typedef struct mxs_authenticator /** This entry point was added to avoid calling authenticator functions * directly when a COM_CHANGE_USER command is executed. */ int (*reauthenticate)(struct dcb *, const char *user, - uint8_t *token, size_t token_len, - uint8_t *scramble, size_t scramble_len); + uint8_t *token, size_t token_len, /**< Client auth token */ + uint8_t *scramble, size_t scramble_len, /**< Scramble sent by MaxScale to client */ + uint8_t *output, size_t output_len); /**< Hashed client password used by backend protocols */ } MXS_AUTHENTICATOR; /** Return values for extract and authenticate entry points */ diff --git a/server/modules/authenticator/MySQLAuth/dbusers.c b/server/modules/authenticator/MySQLAuth/dbusers.c index 80a464d55..a8ec1e919 100644 --- a/server/modules/authenticator/MySQLAuth/dbusers.c +++ b/server/modules/authenticator/MySQLAuth/dbusers.c @@ -445,14 +445,16 @@ static int auth_cb(void *data, int columns, char** rows, char** row_names) /** * @brief Verify the user has access to the database * - * @param auth Authenticator session - * @param dcb Client DCB - * @param session MySQL session - * @param pw Client password + * @param handle SQLite handle to MySQLAuth user database + * @param dcb Client DCB + * @param session Shared MySQL session + * @param scramble The scramble sent to the client in the initial handshake + * @param scramble_len Length of @c scramble * * @return True if the user has access to the database */ -bool validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session) +bool validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session, + uint8_t *scramble, size_t scramble_len) { size_t len = sizeof(mysqlauth_validate_user_query) + strlen(session->user) * 2 + strlen(session->db) * 2 + MYSQL_HOST_MAXLEN + session->auth_token_len * 4 + 1; @@ -491,6 +493,7 @@ bool validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session) if (res.ok) { + /** Found a matching row */ if (session->auth_token_len) { /** If authentication fails, this will trigger the right @@ -498,11 +501,8 @@ bool validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session) session->client_sha1[0] = '_'; } - /** Found a matching row */ - MySQLProtocol *proto = (MySQLProtocol*)dcb->protocol; - if (check_password(res.output, session->auth_token, session->auth_token_len, - proto->scramble, sizeof(proto->scramble), session->client_sha1)) + scramble, scramble_len, session->client_sha1)) { /** Password is OK, check that the database exists */ rval = check_database(handle, session->db); diff --git a/server/modules/authenticator/MySQLAuth/mysql_auth.c b/server/modules/authenticator/MySQLAuth/mysql_auth.c index 17ec7b644..c9d55387e 100644 --- a/server/modules/authenticator/MySQLAuth/mysql_auth.c +++ b/server/modules/authenticator/MySQLAuth/mysql_auth.c @@ -60,7 +60,8 @@ static int mysql_auth_set_client_data( int mysql_auth_reauthenticate(DCB *dcb, const char *user, uint8_t *token, size_t token_len, - uint8_t *scramble, size_t scramble_len); + uint8_t *scramble, size_t scramble_len, + uint8_t *output_token, size_t output_token_len); /** * The module entry point routine. It is this routine that * must populate the structure that is referred to as the @@ -267,11 +268,13 @@ mysql_auth_authenticate(DCB *dcb) MYSQL_AUTH *instance = (MYSQL_AUTH*)dcb->listener->auth_instance; - bool is_ok = validate_mysql_user(instance->handle, dcb, client_data); + bool is_ok = validate_mysql_user(instance->handle, dcb, client_data, + protocol->scramble, sizeof(protocol->scramble)); if (!is_ok && !instance->skip_auth && service_refresh_users(dcb->service) == 0) { - is_ok = validate_mysql_user(instance->handle, dcb, client_data); + is_ok = validate_mysql_user(instance->handle, dcb, client_data, + protocol->scramble, sizeof(protocol->scramble)); } /* on successful authentication, set user into dcb field */ @@ -888,9 +891,25 @@ static int mysql_auth_load_users(SERV_LISTENER *port) int mysql_auth_reauthenticate(DCB *dcb, const char *user, uint8_t *token, size_t token_len, - uint8_t *scramble, size_t scramble_len) + uint8_t *scramble, size_t scramble_len, + uint8_t *output_token, size_t output_token_len) { MYSQL_session *client_data = (MYSQL_session *)dcb->data; - return gw_check_mysql_scramble_data(dcb, token, token_len, scramble, scramble_len, - user, client_data->client_sha1); + MYSQL_session temp; + int rval = 1; + + memcpy(&temp, client_data, sizeof(*client_data)); + strcpy(temp.user, user); + temp.auth_token = token; + temp.auth_token_len = token_len; + + MYSQL_AUTH *instance = (MYSQL_AUTH*)dcb->listener->auth_instance; + + if (validate_mysql_user(instance->handle, dcb, &temp, scramble, scramble_len)) + { + memcpy(output_token, temp.client_sha1, output_token_len); + rval = 0; + } + + return rval; } diff --git a/server/modules/authenticator/MySQLAuth/mysql_auth.h b/server/modules/authenticator/MySQLAuth/mysql_auth.h index 1bcf70aa9..8e6713f5a 100644 --- a/server/modules/authenticator/MySQLAuth/mysql_auth.h +++ b/server/modules/authenticator/MySQLAuth/mysql_auth.h @@ -148,6 +148,7 @@ int gw_find_mysql_user_password_sha1( const char *username, uint8_t *gateway_password, DCB *dcb); -bool validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session); +bool validate_mysql_user(sqlite3 *handle, DCB *dcb, MYSQL_session *session, + uint8_t *scramble, size_t scramble_len); MXS_END_DECLS diff --git a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c index 87107179f..f59a193db 100644 --- a/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c +++ b/server/modules/protocol/MySQL/MySQLBackend/mysql_backend.c @@ -1591,7 +1591,8 @@ static int gw_change_user(DCB *backend, auth_ret = dcb->authfunc.reauthenticate(dcb, username, auth_token, auth_token_len, client_protocol->scramble, - sizeof(client_protocol->scramble)); + sizeof(client_protocol->scramble), + client_sha1, sizeof(client_sha1)); strcpy(current_session->db, current_database); spinlock_release(&in_session->ses_lock); @@ -1608,7 +1609,8 @@ static int gw_change_user(DCB *backend, auth_ret = dcb->authfunc.reauthenticate(dcb, username, auth_token, auth_token_len, client_protocol->scramble, - sizeof(client_protocol->scramble)); + sizeof(client_protocol->scramble), + client_sha1, sizeof(client_sha1)); strcpy(current_session->db, current_database); spinlock_release(&in_session->ses_lock);