Authenticator API extract-entrypoint returns bool

Extraction either succeeds or fails, it does not need to return
defined integer values.
This commit is contained in:
Esa Korhonen
2017-08-07 13:21:54 +03:00
parent f336cb63cf
commit 7ba0533cc8
21 changed files with 83 additions and 93 deletions

View File

@ -46,8 +46,10 @@ struct servlistener;
* `dcb->authenticator_data`. If a module does not implement
* this entry point, `dcb->authenticator_data` will be set to NULL.
*
* extract Extract the data from a buffer and place in a structure
* shared at the session level, stored in `dcb->data`
* extract Extract client or backend data from a buffer and place it
* in a structure shared at the session level, stored in
* `dcb->data`. Typically, this is called just before the
* authenticate-entrypoint.
*
* connectSSL Determine whether the connection can support SSL
*
@ -76,7 +78,7 @@ typedef struct mxs_authenticator
{
void* (*initialize)(char **options);
void* (*create)(void* instance);
int (*extract)(struct dcb *, GWBUF *);
bool (*extract)(struct dcb *, GWBUF *);
bool (*connectssl)(struct dcb *);
int (*authenticate)(struct dcb *);
void (*free)(struct dcb *);
@ -149,7 +151,7 @@ typedef enum
* the MXS_AUTHENTICATOR structure is changed. See the rules defined in modinfo.h
* that define how these numbers should change.
*/
#define MXS_AUTHENTICATOR_VERSION {1, 1, 0}
#define MXS_AUTHENTICATOR_VERSION {2, 1, 0}
bool authenticator_init(void **instance, const char *authenticator, const char *options);

View File

@ -55,7 +55,7 @@ typedef enum
*
* The rules for changing these values are:
*
* Any change that affects an inexisting call in the API in question,
* Any change that affects an existing call in the API,
* making the new API no longer compatible with the old,
* must increment the major version.
*

View File

@ -46,7 +46,7 @@
const char CDC_USERS_FILENAME[] = "cdcusers";
static int cdc_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool cdc_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool cdc_auth_is_client_ssl_capable(DCB *dcb);
static int cdc_auth_authenticate(DCB *dcb);
static void cdc_auth_free_client_data(DCB *dcb);
@ -62,7 +62,7 @@ static int cdc_auth_check(
unsigned int *flags
);
static int cdc_auth_set_client_data(
static bool cdc_auth_set_client_data(
CDC_session *client_data,
CDC_protocol *protocol,
uint8_t *client_auth_packet,
@ -284,10 +284,9 @@ cdc_auth_authenticate(DCB *dcb)
*
* @param dcb Request handler DCB connected to the client
* @param buffer Pointer to pointer to buffer containing data from client
* @return Authentication status
* @note Authentication status codes are defined in cdc.h
* @return True on success, false on error
*/
static int
static bool
cdc_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
uint8_t *client_auth_packet = GWBUF_DATA(buf);
@ -301,7 +300,7 @@ cdc_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
if (NULL == (client_data = (CDC_session *)MXS_CALLOC(1, sizeof(CDC_session))))
{
return CDC_STATE_AUTH_ERR;
return false;
}
dcb->data = client_data;
}
@ -327,10 +326,9 @@ cdc_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
* @param protocol The protocol structure for this connection
* @param client_auth_packet The data from the buffer received from client
* @param client_auth_packet size An integer giving the size of the data
* @return Authentication status
* @note Authentication status codes are defined in cdc.h
* @return True on success, false on error
*/
static int
static bool
cdc_auth_set_client_data(CDC_session *client_data,
CDC_protocol *protocol,
uint8_t *client_auth_packet,
@ -342,7 +340,7 @@ cdc_auth_set_client_data(CDC_session *client_data,
client_auth_packet_size--;
}
int rval = CDC_STATE_AUTH_ERR;
bool rval = false;
int decoded_size = client_auth_packet_size / 2;
char decoded_buffer[decoded_size + 1]; // Extra for terminating null
@ -364,7 +362,7 @@ cdc_auth_set_client_data(CDC_session *client_data,
{
strcpy(client_data->user, decoded_buffer);
memcpy(client_data->auth_data, tmp_ptr, auth_len);
rval = CDC_STATE_AUTH_OK;
rval = true;
}
}
else

View File

@ -272,24 +272,23 @@ static void copy_client_information(DCB *dcb, GWBUF *buffer)
*
* @param dcb Client DCB
* @param read_buffer Buffer containing the client's response
* @return MXS_AUTH_SUCCEEDED if authentication can continue, MXS_AUTH_FAILED if
* authentication failed
* @return True if authentication can continue, false if not
*/
static int gssapi_auth_extract(DCB *dcb, GWBUF *read_buffer)
static bool gssapi_auth_extract(DCB *dcb, GWBUF *read_buffer)
{
int rval = MXS_AUTH_FAILED;
int rval = false;
gssapi_auth_t *auth = (gssapi_auth_t*)dcb->authenticator_data;
switch (auth->state)
{
case GSSAPI_AUTH_INIT:
copy_client_information(dcb, read_buffer);
rval = MXS_AUTH_SUCCEEDED;
rval = true;
break;
case GSSAPI_AUTH_DATA_SENT:
store_client_token(dcb, read_buffer);
rval = MXS_AUTH_SUCCEEDED;
rval = true;
break;
default:

View File

@ -199,17 +199,17 @@ bool extract_principal_name(DCB *dcb, GWBUF *buffer)
* @brief Extract data from a MySQL packet
* @param dcb Backend DCB
* @param buffer Buffer containing a complete packet
* @return MXS_AUTH_INCOMPLETE if authentication is ongoing, MXS_AUTH_SUCCEEDED
* if authentication is complete and MXS_AUTH_FAILED if authentication failed.
* @return True if authentication is ongoing or complete,
* false if authentication failed.
*/
static int gssapi_backend_auth_extract(DCB *dcb, GWBUF *buffer)
static bool gssapi_backend_auth_extract(DCB *dcb, GWBUF *buffer)
{
int rval = MXS_AUTH_FAILED;
bool rval = false;
gssapi_auth_t *auth = (gssapi_auth_t*)dcb->authenticator_data;
if (auth->state == GSSAPI_AUTH_INIT && extract_principal_name(dcb, buffer))
{
rval = MXS_AUTH_INCOMPLETE;
rval = true;
}
else if (auth->state == GSSAPI_AUTH_DATA_SENT)
{
@ -217,7 +217,7 @@ static int gssapi_backend_auth_extract(DCB *dcb, GWBUF *buffer)
if (mxs_mysql_is_ok_packet(buffer))
{
auth->state = GSSAPI_AUTH_OK;
rval = MXS_AUTH_SUCCEEDED;
rval = true;
}
}

View File

@ -36,7 +36,7 @@
#include <maxscale/secrets.h>
#include <maxscale/users.h>
static int http_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool http_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool http_auth_is_client_ssl_capable(DCB *dcb);
static int http_auth_authenticate(DCB *dcb);
static void http_auth_free_client_data(DCB *dcb);
@ -122,17 +122,17 @@ http_auth_authenticate(DCB *dcb)
* @brief Transfer data from the authentication request to the DCB.
*
* Expects a buffer containing a Base64 encoded username and password
* contatenated together by a semicolon as is specificed by HTTP Basic
* concatenated together by a semicolon as is specified by HTTP Basic
* Access authentication.
*
* @param dcb Request handler DCB connected to the client
* @param buffer Pointer to pointer to buffers containing data from client
* @return Authentication status - 0 for success, 1 for failure
* @return Authentication status - true for success, false for failure
*/
static int
static bool
http_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
int rval = 1;
bool rval = false;
char* value = (char*)GWBUF_DATA(buf);
char* tok = strstr(value, "Basic");
tok = tok ? strchr(tok, ' ') : NULL;
@ -162,7 +162,7 @@ http_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
ses->user = user;
ses->pw = pw;
dcb->data = ses;
rval = 0;
rval = true;
}
else
{

View File

@ -36,7 +36,7 @@
#include <maxscale/adminusers.h>
#include <maxscale/users.h>
static int max_admin_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool max_admin_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool max_admin_auth_is_client_ssl_capable(DCB *dcb);
static int max_admin_auth_authenticate(DCB *dcb);
static void max_admin_auth_free_client_data(DCB *dcb);
@ -108,9 +108,9 @@ max_admin_auth_authenticate(DCB *dcb)
*
* @param dcb Request handler DCB connected to the client
* @param buffer Pointer to pointer to buffers containing data from client
* @return Authentication status - 0 for success, 1 for failure
* @return Authentication status - true for success, false for failure
*/
static int
static bool
max_admin_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
ADMIN_session *session_data;
@ -132,10 +132,10 @@ max_admin_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
if (admin_linux_account_enabled(session_data->user))
{
session_data->validated = true;
return 0;
return true;
}
}
return 1;
return false;
}
/**

View File

@ -36,7 +36,7 @@
#include <maxscale/utils.h>
static void* mysql_auth_init(char **options);
static int mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool mysql_auth_is_client_ssl_capable(DCB *dcb);
static int mysql_auth_authenticate(DCB *dcb);
static void mysql_auth_free_client_data(DCB *dcb);
@ -53,7 +53,7 @@ static int combined_auth_check(
uint8_t *stage1_hash,
char *database
);
static int mysql_auth_set_client_data(
static bool mysql_auth_set_client_data(
MYSQL_session *client_data,
MySQLProtocol *protocol,
GWBUF *buffer);
@ -359,11 +359,9 @@ mysql_auth_authenticate(DCB *dcb)
*
* @param dcb Request handler DCB connected to the client
* @param buffer Pointer to pointer to buffer containing data from client
* @return Authentication status
* @note Authentication status codes are defined in maxscale/protocol/mysql.h
* @see https://dev.mysql.com/doc/internals/en/client-server-protocol.html
* @return True on success, false on error
*/
static int
static bool
mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
MySQLProtocol *protocol = NULL;
@ -378,7 +376,7 @@ mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
if (!open_client_database(path, &auth_ses->handle))
{
return MXS_AUTH_FAILED;
return false;
}
}
@ -406,7 +404,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 MXS_AUTH_FAILED;
return false;
}
return mysql_auth_set_client_data(client_data, protocol, buf);
@ -423,11 +421,9 @@ mysql_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
* @param protocol The protocol structure for this connection
* @param client_auth_packet The data from the buffer received from client
* @param client_auth_packet size An integer giving the size of the data
* @return Authentication status
* @note Authentication status codes are defined in maxscale/protocol/mysql.h
* @see https://dev.mysql.com/doc/internals/en/client-server-protocol.html
* @return True on success, false on error
*/
static int
static bool
mysql_auth_set_client_data(
MYSQL_session *client_data,
MySQLProtocol *protocol,
@ -475,17 +471,17 @@ mysql_auth_set_client_data(
else
{
/* Failed to allocate space for authentication token string */
return MXS_AUTH_FAILED;
return false;
}
}
else
{
/* Packet was too small to contain authentication token */
return MXS_AUTH_FAILED;
return false;
}
}
}
return MXS_AUTH_SUCCEEDED;
return true;
}
/**

View File

@ -82,13 +82,12 @@ void auth_backend_destroy(void *data)
*
* @param dcb Request handler DCB connected to the client
* @param buffer Buffer containing data from client
* @return Authentication status
* @return True on success, false on error
* @see authenticator.h
* @see https://dev.mysql.com/doc/internals/en/client-server-protocol.html
*/
static int auth_backend_extract(DCB *dcb, GWBUF *buf)
static bool auth_backend_extract(DCB *dcb, GWBUF *buf)
{
int rval = MXS_AUTH_FAILED;
bool rval = false;
mysql_backend_auth_t *mba = (mysql_backend_auth_t*)dcb->authenticator_data;
switch (mba->state)
@ -96,7 +95,7 @@ static int auth_backend_extract(DCB *dcb, GWBUF *buf)
case MBA_NEED_OK:
if (mxs_mysql_is_ok_packet(buf))
{
rval = MXS_AUTH_SUCCEEDED;
rval = true;
mba->state = MBA_AUTH_OK;
}
else

View File

@ -38,7 +38,7 @@
/** MXS-1026: Without MySQL protocol data structures, the NullAuth authenticator will crash. */
#include <maxscale/protocol/mysql.h>
static int null_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool null_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool null_auth_is_client_ssl_capable(DCB *dcb);
static int null_auth_authenticate(DCB *dcb);
static void null_auth_free_client_data(DCB *dcb);
@ -111,17 +111,16 @@ null_auth_authenticate(DCB *dcb)
*
* @param dcb Request handler DCB connected to the client
* @param buffer Pointer to pointer to buffer containing data from client
* @return Authentication status - always 0 to indicate success
* @return Always true
*/
static int
static bool
null_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
/** MXS-1026: This will just prevent a crash when the NullAuth authenticator
* is used. This does not provide a way to use MaxScale with no authentication. */
dcb->data = calloc(1, sizeof(MYSQL_session));
dcb->protocol = mysql_protocol_init(dcb, dcb->fd);
return 0;
return true;
}
/**

View File

@ -35,7 +35,7 @@
#include <maxscale/buffer.h>
#include <maxscale/users.h>
static int null_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool null_auth_set_protocol_data(DCB *dcb, GWBUF *buf);
static bool null_auth_is_client_ssl_capable(DCB *dcb);
static int null_auth_authenticate(DCB *dcb);
static void null_auth_free_client_data(DCB *dcb);
@ -108,12 +108,12 @@ null_auth_authenticate(DCB *dcb)
*
* @param dcb Request handler DCB connected to the client
* @param buffer Pointer to pointer to buffer containing data from client
* @return Authentication status - always 0 to indicate success
* @return Always true
*/
static int
static bool
null_auth_set_protocol_data(DCB *dcb, GWBUF *buf)
{
return 0;
return true;
}
/**

View File

@ -59,10 +59,10 @@ static void pam_auth_free(void *data)
* @param dcb Client DCB
* @param read_buffer Buffer containing the client's response
*
* @return MXS_AUTH_SUCCEEDED if authentication can continue, MXS_AUTH_FAILED if
* @return True if authentication can continue, false if
* authentication failed
*/
static int pam_auth_extract(DCB *dcb, GWBUF *read_buffer)
static bool pam_auth_extract(DCB *dcb, GWBUF *read_buffer)
{
PamClientSession *pses = static_cast<PamClientSession*>(dcb->authenticator_data);
return pses->extract(dcb, read_buffer);

View File

@ -344,22 +344,22 @@ int PamClientSession::authenticate(DCB* dcb)
return rval;
}
int PamClientSession::extract(DCB *dcb, GWBUF *buffer)
bool PamClientSession::extract(DCB *dcb, GWBUF *buffer)
{
gwbuf_copy_data(buffer, MYSQL_SEQ_OFFSET, 1, &m_sequence);
m_sequence++;
int rval = MXS_AUTH_FAILED;
bool rval = false;
switch (m_state)
{
case PAM_AUTH_INIT:
// The buffer doesn't have any PAM-specific data yet
rval = MXS_AUTH_SUCCEEDED;
rval = true;
break;
case PAM_AUTH_DATA_SENT:
store_client_password(dcb, buffer);
rval = MXS_AUTH_SUCCEEDED;
rval = true;
break;
default:

View File

@ -30,7 +30,7 @@ public:
static PamClientSession* create(const PamInstance& inst);
~PamClientSession();
int authenticate(DCB* client);
int extract(DCB *dcb, GWBUF *read_buffer);
bool extract(DCB *dcb, GWBUF *read_buffer);
private:
PamClientSession(sqlite3* dbhandle, const PamInstance& instance);
void get_pam_user_services(const DCB* dcb, const MYSQL_session* session,

View File

@ -38,7 +38,7 @@ static void pam_backend_auth_free(void *data)
* @return MXS_AUTH_INCOMPLETE if authentication is ongoing, MXS_AUTH_SUCCEEDED
* if authentication is complete and MXS_AUTH_FAILED if authentication failed.
*/
static int pam_backend_auth_extract(DCB *dcb, GWBUF *buffer)
static bool pam_backend_auth_extract(DCB *dcb, GWBUF *buffer)
{
PamBackendSession *pses = static_cast<PamBackendSession*>(dcb->authenticator_data);
return pses->extract(dcb, buffer);

View File

@ -104,15 +104,15 @@ bool PamBackendSession::send_client_password(DCB *dcb)
return dcb_write(dcb, gwbuf_alloc_and_load(buflen, bufferdata));
}
int PamBackendSession::extract(DCB *dcb, GWBUF *buffer)
bool PamBackendSession::extract(DCB *dcb, GWBUF *buffer)
{
gwbuf_copy_data(buffer, MYSQL_SEQ_OFFSET, 1, &m_sequence);
m_sequence++;
int rval = MXS_AUTH_FAILED;
bool rval = false;
if (m_state == PAM_AUTH_INIT && check_auth_switch_request(dcb, buffer))
{
rval = MXS_AUTH_INCOMPLETE;
rval = true;
}
else if (m_state == PAM_AUTH_DATA_SENT)
{
@ -122,7 +122,7 @@ int PamBackendSession::extract(DCB *dcb, GWBUF *buffer)
MXS_DEBUG("pam_backend_auth_extract received ok packet from '%s'.",
dcb->server->unique_name);
m_state = PAM_AUTH_OK;
rval = MXS_AUTH_SUCCEEDED;
rval = true;
}
else
{
@ -131,7 +131,7 @@ int PamBackendSession::extract(DCB *dcb, GWBUF *buffer)
}
}
if (rval == MXS_AUTH_FAILED)
if (!rval)
{
MXS_DEBUG("pam_backend_auth_extract to backend '%s' failed for user '%s'.",
dcb->server->unique_name, dcb->user);

View File

@ -25,7 +25,7 @@ class PamBackendSession
PamBackendSession& operator=(const PamBackendSession&);
public:
PamBackendSession();
int extract(DCB *dcb, GWBUF *buffer);
bool extract(DCB *dcb, GWBUF *buffer);
int authenticate(DCB *dcb);
private:

View File

@ -122,8 +122,9 @@ cdc_read_event(DCB* dcb)
{
MXS_SESSION *session = dcb->session;
CDC_protocol *protocol = (CDC_protocol *) dcb->protocol;
int n, auth_val, rc = 0;
int n, rc = 0;
GWBUF *head = NULL;
int auth_val = CDC_STATE_AUTH_FAILED;
CDC_session *client_data = (CDC_session *) dcb->data;
if ((n = dcb_read(dcb, &head, 0)) > 0)
@ -131,9 +132,8 @@ cdc_read_event(DCB* dcb)
switch (protocol->state)
{
case CDC_STATE_WAIT_FOR_AUTH:
if (CDC_STATE_AUTH_OK == (
/* Fill CDC_session from incoming packet */
auth_val = dcb->authfunc.extract(dcb, head)))
if (dcb->authfunc.extract(dcb, head))
{
/* Call protocol authentication */
auth_val = dcb->authfunc.authenticate(dcb);

View File

@ -343,9 +343,7 @@ mxs_auth_state_t handle_server_response(DCB *dcb, GWBUF *buffer)
mxs_auth_state_t rval = proto->protocol_auth_state == MXS_AUTH_STATE_CONNECTED ?
MXS_AUTH_STATE_HANDSHAKE_FAILED : MXS_AUTH_STATE_FAILED;
int rc = dcb->authfunc.extract(dcb, buffer);
if (rc == MXS_AUTH_SUCCEEDED || rc == MXS_AUTH_INCOMPLETE)
if (dcb->authfunc.extract(dcb, buffer))
{
switch (dcb->authfunc.authenticate(dcb))
{

View File

@ -658,9 +658,8 @@ 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.
*/
int auth_val = dcb->authfunc.extract(dcb, read_buffer);
if (MXS_AUTH_SUCCEEDED == auth_val)
int auth_val = MXS_AUTH_FAILED;
if (dcb->authfunc.extract(dcb, read_buffer))
{
auth_val = dcb->authfunc.authenticate(dcb);
}

View File

@ -93,7 +93,7 @@ static bool authenticate_unix_socket(MAXSCALED *protocol, DCB *dcb)
strcpy((char*)GWBUF_DATA(username), protocol->username);
/* Authenticate the user */
if (dcb->authfunc.extract(dcb, username) == 0 &&
if (dcb->authfunc.extract(dcb, username) &&
dcb->authfunc.authenticate(dcb) == 0)
{
dcb_printf(dcb, MAXADMIN_AUTH_SUCCESS_REPLY);