Use new authentication for reauthentication
This fixes the reauthentication of users that was missing from the new implementation. Now COM_CHANGE_USER should work properly.
This commit is contained in:
@ -80,8 +80,9 @@ typedef struct mxs_authenticator
|
|||||||
/** This entry point was added to avoid calling authenticator functions
|
/** This entry point was added to avoid calling authenticator functions
|
||||||
* directly when a COM_CHANGE_USER command is executed. */
|
* directly when a COM_CHANGE_USER command is executed. */
|
||||||
int (*reauthenticate)(struct dcb *, const char *user,
|
int (*reauthenticate)(struct dcb *, const char *user,
|
||||||
uint8_t *token, size_t token_len,
|
uint8_t *token, size_t token_len, /**< Client auth token */
|
||||||
uint8_t *scramble, size_t scramble_len);
|
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;
|
} MXS_AUTHENTICATOR;
|
||||||
|
|
||||||
/** Return values for extract and authenticate entry points */
|
/** Return values for extract and authenticate entry points */
|
||||||
|
@ -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
|
* @brief Verify the user has access to the database
|
||||||
*
|
*
|
||||||
* @param auth Authenticator session
|
* @param handle SQLite handle to MySQLAuth user database
|
||||||
* @param dcb Client DCB
|
* @param dcb Client DCB
|
||||||
* @param session MySQL session
|
* @param session Shared MySQL session
|
||||||
* @param pw Client password
|
* @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
|
* @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 +
|
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;
|
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)
|
if (res.ok)
|
||||||
{
|
{
|
||||||
|
/** Found a matching row */
|
||||||
if (session->auth_token_len)
|
if (session->auth_token_len)
|
||||||
{
|
{
|
||||||
/** If authentication fails, this will trigger the right
|
/** 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] = '_';
|
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,
|
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 */
|
/** Password is OK, check that the database exists */
|
||||||
rval = check_database(handle, session->db);
|
rval = check_database(handle, session->db);
|
||||||
|
@ -60,7 +60,8 @@ static int mysql_auth_set_client_data(
|
|||||||
|
|
||||||
int mysql_auth_reauthenticate(DCB *dcb, const char *user,
|
int mysql_auth_reauthenticate(DCB *dcb, const char *user,
|
||||||
uint8_t *token, size_t token_len,
|
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
|
* The module entry point routine. It is this routine that
|
||||||
* must populate the structure that is referred to as the
|
* 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;
|
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)
|
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 */
|
/* 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,
|
int mysql_auth_reauthenticate(DCB *dcb, const char *user,
|
||||||
uint8_t *token, size_t token_len,
|
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;
|
MYSQL_session *client_data = (MYSQL_session *)dcb->data;
|
||||||
return gw_check_mysql_scramble_data(dcb, token, token_len, scramble, scramble_len,
|
MYSQL_session temp;
|
||||||
user, client_data->client_sha1);
|
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;
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,7 @@ int gw_find_mysql_user_password_sha1(
|
|||||||
const char *username,
|
const char *username,
|
||||||
uint8_t *gateway_password,
|
uint8_t *gateway_password,
|
||||||
DCB *dcb);
|
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
|
MXS_END_DECLS
|
||||||
|
@ -1537,7 +1537,8 @@ static int gw_change_user(DCB *backend,
|
|||||||
auth_ret = dcb->authfunc.reauthenticate(dcb, username,
|
auth_ret = dcb->authfunc.reauthenticate(dcb, username,
|
||||||
auth_token, auth_token_len,
|
auth_token, auth_token_len,
|
||||||
client_protocol->scramble,
|
client_protocol->scramble,
|
||||||
sizeof(client_protocol->scramble));
|
sizeof(client_protocol->scramble),
|
||||||
|
client_sha1, sizeof(client_sha1));
|
||||||
|
|
||||||
strcpy(current_session->db, current_database);
|
strcpy(current_session->db, current_database);
|
||||||
|
|
||||||
@ -1552,7 +1553,8 @@ static int gw_change_user(DCB *backend,
|
|||||||
auth_ret = dcb->authfunc.reauthenticate(dcb, username,
|
auth_ret = dcb->authfunc.reauthenticate(dcb, username,
|
||||||
auth_token, auth_token_len,
|
auth_token, auth_token_len,
|
||||||
client_protocol->scramble,
|
client_protocol->scramble,
|
||||||
sizeof(client_protocol->scramble));
|
sizeof(client_protocol->scramble),
|
||||||
|
client_sha1, sizeof(client_sha1));
|
||||||
|
|
||||||
strcpy(current_session->db, current_database);
|
strcpy(current_session->db, current_database);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user