From 39921353258118f58776e07442f866f03e426b45 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 20 Sep 2016 10:59:41 +0300 Subject: [PATCH] Move authentication return codes to gw_authenticator.h The MYSQL_* authentication return codes are now in gw_authenticator.h so that all authenticators can use them. Also dropped the MYSQL_ prefix from the return codes and added AUTH_INCOMPLETE for a generic authentication-in-progress return code. --- server/core/service.c | 4 +- server/core/users.c | 2 +- server/include/gw_authenticator.h | 13 +++++- server/modules/authenticator/cdc_plain_auth.c | 6 +-- server/modules/authenticator/mysql_auth.c | 46 +++++++++---------- .../include/mysql_client_server_protocol.h | 7 --- .../protocol/MySQLClient/mysql_client.c | 25 +++++----- server/modules/protocol/mysql_common.c | 4 +- 8 files changed, 56 insertions(+), 51 deletions(-) diff --git a/server/core/service.c b/server/core/service.c index 9cbf73ea4..10535c157 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -300,7 +300,7 @@ serviceStartPort(SERVICE *service, SERV_LISTENER *port) /** Load the authentication users before before starting the listener */ if (port->listener->authfunc.loadusers && (service->router->getCapabilities() & RCAP_TYPE_NO_USERS_INIT) == 0 && - port->listener->authfunc.loadusers(port) != AUTH_LOADUSERS_OK) + port->listener->authfunc.loadusers(port) != MXS_AUTH_LOADUSERS_OK) { MXS_ERROR("[%s] Failed to load users for listener '%s', authentication might not work.", service->name, port->name); @@ -1457,7 +1457,7 @@ int service_refresh_users(SERVICE *service) for (SERV_LISTENER *port = service->ports; port; port = port->next) { - if (port->listener->authfunc.loadusers(port) != AUTH_LOADUSERS_OK) + if (port->listener->authfunc.loadusers(port) != MXS_AUTH_LOADUSERS_OK) { MXS_ERROR("[%s] Failed to load users for listener '%s', authentication might not work.", service->name, port->name); diff --git a/server/core/users.c b/server/core/users.c index 53f7d9cd1..66ebe3001 100644 --- a/server/core/users.c +++ b/server/core/users.c @@ -224,5 +224,5 @@ int users_default_loadusers(SERV_LISTENER *port) { users_free(port->users); port->users = users_alloc(); - return AUTH_LOADUSERS_OK; + return MXS_AUTH_LOADUSERS_OK; } diff --git a/server/include/gw_authenticator.h b/server/include/gw_authenticator.h index 461126bbc..a0cae4ce7 100644 --- a/server/include/gw_authenticator.h +++ b/server/include/gw_authenticator.h @@ -64,9 +64,18 @@ typedef struct gw_authenticator const char* plugin_name; } GWAUTHENTICATOR; +/** Return values for extract and authenticate entry points */ +#define MXS_AUTH_SUCCEEDED 0 /**< Authentication was successful */ +#define MXS_AUTH_FAILED 1 /**< Authentication failed */ +#define MXS_AUTH_FAILED_DB 2 +#define MXS_AUTH_FAILED_SSL 3 +#define MXS_AUTH_INCOMPLETE 4 /**< Authentication is not yet complete */ +#define MXS_AUTH_SSL_INCOMPLETE 5 /**< SSL connection is not yet complete */ +#define MXS_AUTH_NO_SESSION 6 + /** Return values for the loadusers entry point */ -#define AUTH_LOADUSERS_OK 0 /**< Users loaded successfully */ -#define AUTH_LOADUSERS_ERROR 1 /**< Failed to load users */ +#define MXS_AUTH_LOADUSERS_OK 0 /**< Users loaded successfully */ +#define MXS_AUTH_LOADUSERS_ERROR 1 /**< Failed to load users */ /** * The GWAUTHENTICATOR version data. The following should be updated whenever diff --git a/server/modules/authenticator/cdc_plain_auth.c b/server/modules/authenticator/cdc_plain_auth.c index cc2d2d3a0..84777bdd7 100644 --- a/server/modules/authenticator/cdc_plain_auth.c +++ b/server/modules/authenticator/cdc_plain_auth.c @@ -181,7 +181,7 @@ cdc_auth_authenticate(DCB *dcb) auth_ret = cdc_auth_check(dcb, protocol, client_data->user, client_data->auth_data, client_data->flags); /* On failed authentication try to reload users and authenticate again */ - if (CDC_STATE_AUTH_OK != auth_ret && cdc_replace_users(dcb->listener) == AUTH_LOADUSERS_OK) + if (CDC_STATE_AUTH_OK != auth_ret && cdc_replace_users(dcb->listener) == MXS_AUTH_LOADUSERS_OK) { auth_ret = cdc_auth_check(dcb, protocol, client_data->user, client_data->auth_data, client_data->flags); } @@ -483,7 +483,7 @@ cdc_read_users(USERS *users, char *usersfile) */ int cdc_replace_users(SERV_LISTENER *listener) { - int rc = AUTH_LOADUSERS_ERROR; + int rc = MXS_AUTH_LOADUSERS_ERROR; USERS *newusers = users_alloc(); if (newusers) @@ -501,7 +501,7 @@ int cdc_replace_users(SERV_LISTENER *listener) /** Successfully loaded at least one user */ oldusers = listener->users; listener->users = newusers; - rc = AUTH_LOADUSERS_OK; + rc = MXS_AUTH_LOADUSERS_OK; } else if (listener->users) { diff --git a/server/modules/authenticator/mysql_auth.c b/server/modules/authenticator/mysql_auth.c index f50165b42..253b337f3 100644 --- a/server/modules/authenticator/mysql_auth.c +++ b/server/modules/authenticator/mysql_auth.c @@ -152,23 +152,23 @@ mysql_auth_authenticate(DCB *dcb) if (0 != ssl_ret) { - auth_ret = (SSL_ERROR_CLIENT_NOT_SSL == ssl_ret) ? MYSQL_FAILED_AUTH_SSL : MYSQL_FAILED_AUTH; + auth_ret = (SSL_ERROR_CLIENT_NOT_SSL == ssl_ret) ? MXS_AUTH_FAILED_SSL : MXS_AUTH_FAILED; } else if (!health_after) { - auth_ret = MYSQL_AUTH_SSL_INCOMPLETE; + auth_ret = MXS_AUTH_SSL_INCOMPLETE; } else if (!health_before && health_after) { - auth_ret = MYSQL_AUTH_SSL_INCOMPLETE; + auth_ret = MXS_AUTH_SSL_INCOMPLETE; poll_add_epollin_event_to_dcb(dcb, NULL); } else if (0 == strlen(client_data->user)) { - auth_ret = MYSQL_FAILED_AUTH; + auth_ret = MXS_AUTH_FAILED; } else @@ -181,14 +181,14 @@ mysql_auth_authenticate(DCB *dcb) /* On failed authentication try to load user table from backend database */ /* Success for service_refresh_users returns 0 */ - if (MYSQL_AUTH_SUCCEEDED != auth_ret && 0 == service_refresh_users(dcb->service)) + if (MXS_AUTH_SUCCEEDED != auth_ret && 0 == service_refresh_users(dcb->service)) { auth_ret = combined_auth_check(dcb, client_data->auth_token, client_data->auth_token_len, protocol, client_data->user, client_data->client_sha1, client_data->db); } /* on successful authentication, set user into dcb field */ - if (MYSQL_AUTH_SUCCEEDED == auth_ret) + if (MXS_AUTH_SUCCEEDED == auth_ret) { dcb->user = MXS_STRDUP_A(client_data->user); } @@ -247,7 +247,7 @@ mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf) { if (NULL == (client_data = (MYSQL_session *)MXS_CALLOC(1, sizeof(MYSQL_session)))) { - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } #if defined(SS_DEBUG) client_data->myses_chk_top = CHK_NUM_MYSQLSES; @@ -279,7 +279,7 @@ mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf) if (client_auth_packet_size < (4 + 4 + 4 + 1 + 23)) { /* Packet is not big enough */ - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } return mysql_auth_set_client_data(client_data, protocol, buf); @@ -339,7 +339,7 @@ mysql_auth_set_client_data( else { /* Packet has incomplete or too long username */ - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } if (client_auth_packet_size > (auth_packet_base_size + user_length + 1)) { @@ -364,13 +364,13 @@ mysql_auth_set_client_data( else { /* Failed to allocate space for authentication token string */ - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } } else { /* Packet was too small to contain authentication token */ - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } packet_length_used += 1 + client_data->auth_token_len; /* @@ -392,12 +392,12 @@ mysql_auth_set_client_data( { /* Packet is too short to contain database string */ /* or database string in packet is too long */ - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } } } } - return MYSQL_AUTH_SUCCEEDED; + return MXS_AUTH_SUCCEEDED; } /** @@ -615,7 +615,7 @@ gw_check_mysql_scramble_data(DCB *dcb, if ((username == NULL) || (mxs_scramble == NULL) || (stage1_hash == NULL)) { - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } /*< @@ -633,7 +633,7 @@ gw_check_mysql_scramble_data(DCB *dcb, memcpy(stage1_hash, (char *)"_", 1); } - return MYSQL_FAILED_AUTH; + return MXS_AUTH_FAILED; } if (token && token_len) @@ -649,7 +649,7 @@ gw_check_mysql_scramble_data(DCB *dcb, { /* check if the password is not set in the user table */ return memcmp(password, null_client_sha1, MYSQL_SCRAMBLE_LEN) ? - MYSQL_FAILED_AUTH : MYSQL_AUTH_SUCCEEDED; + MXS_AUTH_FAILED : MXS_AUTH_SUCCEEDED; } /*< @@ -704,7 +704,7 @@ gw_check_mysql_scramble_data(DCB *dcb, /* now compare SHA1(SHA1(gateway_password)) and check_hash: return 0 is MYSQL_AUTH_OK */ return (0 == memcmp(password, check_hash, SHA_DIGEST_LENGTH)) ? - MYSQL_AUTH_SUCCEEDED : MYSQL_FAILED_AUTH; + MXS_AUTH_SUCCEEDED : MXS_AUTH_FAILED; } /** @@ -746,14 +746,14 @@ check_db_name_after_auth(DCB *dcb, char *database, int auth_ret) db_exists = -1; } - if (db_exists == 0 && auth_ret == MYSQL_AUTH_SUCCEEDED) + if (db_exists == 0 && auth_ret == MXS_AUTH_SUCCEEDED) { - auth_ret = MYSQL_FAILED_AUTH_DB; + auth_ret = MXS_AUTH_FAILED_DB; } - if (db_exists < 0 && auth_ret == MYSQL_AUTH_SUCCEEDED) + if (db_exists < 0 && auth_ret == MXS_AUTH_SUCCEEDED) { - auth_ret = MYSQL_FAILED_AUTH; + auth_ret = MXS_AUTH_FAILED; } } @@ -830,7 +830,7 @@ mysql_auth_free_client_data(DCB *dcb) */ static int mysql_auth_load_users(SERV_LISTENER *port) { - int rc = AUTH_LOADUSERS_OK; + int rc = MXS_AUTH_LOADUSERS_OK; SERVICE *service = port->listener->service; int loaded = replace_mysql_users(port); @@ -847,7 +847,7 @@ static int mysql_auth_load_users(SERV_LISTENER *port) if ((loaded = dbusers_load(port->users, path)) == -1) { MXS_ERROR("[%s] Failed to load cached users from '%s'.", service->name, path);; - rc = AUTH_LOADUSERS_ERROR; + rc = MXS_AUTH_LOADUSERS_ERROR; } else { diff --git a/server/modules/include/mysql_client_server_protocol.h b/server/modules/include/mysql_client_server_protocol.h index e82988f39..715283ff3 100644 --- a/server/modules/include/mysql_client_server_protocol.h +++ b/server/modules/include/mysql_client_server_protocol.h @@ -97,13 +97,6 @@ #define COM_QUIT_PACKET_SIZE (4+1) struct dcb; -#define MYSQL_AUTH_SUCCEEDED 0 -#define MYSQL_FAILED_AUTH 1 -#define MYSQL_FAILED_AUTH_DB 2 -#define MYSQL_FAILED_AUTH_SSL 3 -#define MYSQL_AUTH_SSL_INCOMPLETE 4 -#define MYSQL_AUTH_NO_SESSION 5 - typedef enum { MYSQL_ALLOC, /* Initial state of protocol auth state */ diff --git a/server/modules/protocol/MySQLClient/mysql_client.c b/server/modules/protocol/MySQLClient/mysql_client.c index 3528d464c..553a86a2f 100644 --- a/server/modules/protocol/MySQLClient/mysql_client.c +++ b/server/modules/protocol/MySQLClient/mysql_client.c @@ -577,7 +577,7 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read) * data extraction succeeds, then a call is made to the actual * authenticate function to carry out the user checks. */ - if (MYSQL_AUTH_SUCCEEDED == ( + if (MXS_AUTH_SUCCEEDED == ( auth_val = dcb->authfunc.extract(dcb, read_buffer))) { /* @@ -597,7 +597,7 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read) * non-null session) then the whole process has succeeded. In all * other cases an error return is made. */ - if (MYSQL_AUTH_SUCCEEDED == auth_val) + if (MXS_AUTH_SUCCEEDED == auth_val) { SESSION *session; @@ -628,14 +628,17 @@ gw_read_do_authentication(DCB *dcb, GWBUF *read_buffer, int nbytes_read) } else { - auth_val = MYSQL_AUTH_NO_SESSION; + auth_val = MXS_AUTH_NO_SESSION; } } /** - * If we did not get success throughout, then the protocol state is updated, - * the client is notified of the failure and the DCB is closed. + * If we did not get success throughout or authentication is not yet complete, + * then the protocol state is updated, the client is notified of the failure + * and the DCB is closed. */ - if (MYSQL_AUTH_SUCCEEDED != auth_val && MYSQL_AUTH_SSL_INCOMPLETE != auth_val) + if (MXS_AUTH_SUCCEEDED != auth_val && + MXS_AUTH_INCOMPLETE != auth_val && + MXS_AUTH_SSL_INCOMPLETE != auth_val) { protocol->protocol_auth_state = MYSQL_AUTH_FAILED; mysql_client_auth_error_handling(dcb, auth_val); @@ -974,7 +977,7 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val) switch (auth_val) { - case MYSQL_AUTH_NO_SESSION: + case MXS_AUTH_NO_SESSION: MXS_DEBUG("%lu [gw_read_client_event] session " "creation failed. fd %d, " "state = MYSQL_AUTH_NO_SESSION.", @@ -987,7 +990,7 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val) 0, "failed to create new session"); break; - case MYSQL_FAILED_AUTH_DB: + case MXS_AUTH_FAILED_DB: MXS_DEBUG("%lu [gw_read_client_event] database " "specified was not valid. fd %d, " "state = MYSQL_FAILED_AUTH_DB.", @@ -1003,7 +1006,7 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val) modutil_send_mysql_err_packet(dcb, packet_number, 0, 1049, "42000", fail_str); break; - case MYSQL_FAILED_AUTH_SSL: + case MXS_AUTH_FAILED_SSL: MXS_DEBUG("%lu [gw_read_client_event] client is " "not SSL capable for SSL listener. fd %d, " "state = MYSQL_FAILED_AUTH_SSL.", @@ -1016,7 +1019,7 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val) 0, "failed to complete SSL authentication"); break; - case MYSQL_AUTH_SSL_INCOMPLETE: + case MXS_AUTH_SSL_INCOMPLETE: MXS_DEBUG("%lu [gw_read_client_event] unable to " "complete SSL authentication. fd %d, " "state = MYSQL_AUTH_SSL_INCOMPLETE.", @@ -1029,7 +1032,7 @@ mysql_client_auth_error_handling(DCB *dcb, int auth_val) 0, "failed to complete SSL authentication"); break; - case MYSQL_FAILED_AUTH: + case MXS_AUTH_FAILED: MXS_DEBUG("%lu [gw_read_client_event] authentication failed. fd %d, " "state = MYSQL_FAILED_AUTH.", pthread_self(), diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index bfef46bca..9da47aa58 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -959,7 +959,7 @@ char *create_auth_fail_str(char *username, { ferrstr = "Access denied for user '%s'@'%s' (using password: %s) to database '%s'"; } - else if (errcode == MYSQL_FAILED_AUTH_SSL) + else if (errcode == MXS_AUTH_FAILED_SSL) { ferrstr = "Access without SSL denied"; } @@ -980,7 +980,7 @@ char *create_auth_fail_str(char *username, { sprintf(errstr, ferrstr, username, hostaddr, (*sha1 == '\0' ? "NO" : "YES"), db); } - else if (errcode == MYSQL_FAILED_AUTH_SSL) + else if (errcode == MXS_AUTH_FAILED_SSL) { sprintf(errstr, "%s", ferrstr); }