MXS-862: Add initialize entry point to GSSAPIAuth

The GSSAPIAuth module now creates an instance and stores the configured
service principal name there.
This commit is contained in:
Markus Makela 2016-10-11 22:46:01 +03:00
parent 9d8c5cd410
commit 4a4c65577c

View File

@ -17,6 +17,58 @@
#include <mysql_client_server_protocol.h>
#include "gssapi_auth.h"
typedef struct gssapi_instance
{
char *principal_name;
}GSSAPI_INSTANCE;
/**
* @brief Initialize the GSSAPI authenticator
*
* This function processes the service principal name that is given to the client.
*
* @param listener Listener port
* @param options Listener options
* @return Authenticator instance
*/
void* gssapi_auth_init(char **options)
{
GSSAPI_INSTANCE *instance = MXS_MALLOC(sizeof(GSSAPI_INSTANCE));
if (instance)
{
instance->principal_name = NULL;
for (int i = 0; options[i]; i++)
{
if (strstr(options[i], "principal_name"))
{
char *ptr = strchr(options[i], '=');
if (ptr)
{
ptr++;
instance->principal_name = MXS_STRDUP_A(ptr);
}
}
else
{
MXS_ERROR("Unknown option: %s", options[i]);
MXS_FREE(instance->principal_name);
MXS_FREE(instance);
return NULL;
}
}
if (instance->principal_name == NULL)
{
instance->principal_name = MXS_STRDUP_A(default_princ_name);
MXS_NOTICE("Using default principal name: %s", instance->principal_name);
}
}
return instance;
}
/**
* @brief Create a AuthSwitchRequest packet
*
@ -29,10 +81,10 @@
* @see https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
* @see https://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-user/What-is-a-Kerberos-Principal_003f.html
*/
static GWBUF* create_auth_change_packet()
static GWBUF* create_auth_change_packet(GSSAPI_INSTANCE *instance)
{
size_t plen = sizeof(auth_plugin_name) + 1 + sizeof(default_princ_name) - 1;
size_t principal_name_len = strlen(instance->principal_name);
size_t plen = sizeof(auth_plugin_name) + 1 + principal_name_len;
GWBUF *buffer = gwbuf_alloc(plen + MYSQL_HEADER_LEN);
if (buffer)
@ -44,7 +96,7 @@ static GWBUF* create_auth_change_packet()
*data++ = 0xfe; // AuthSwitchRequest command
memcpy(data, auth_plugin_name, sizeof(auth_plugin_name)); // Plugin name
data += sizeof(auth_plugin_name);
memcpy(data, default_princ_name, sizeof(default_princ_name) - 1); // Plugin data
memcpy(data, instance->principal_name, principal_name_len); // Plugin data
}
return buffer;
@ -232,13 +284,14 @@ int gssapi_auth_authenticate(DCB *dcb)
{
int rval = MXS_AUTH_FAILED;
gssapi_auth_t *auth = (gssapi_auth_t*)dcb->authenticator_data;
GSSAPI_INSTANCE *instance = (GSSAPI_INSTANCE*)dcb->listener->auth_instance;
if (auth->state == GSSAPI_AUTH_INIT)
{
/** We need to send the authentication switch packet to change the
* authentication to something other than the 'mysql_native_password'
* method */
GWBUF *buffer = create_auth_change_packet();
GWBUF *buffer = create_auth_change_packet(instance);
if (buffer && dcb->func.write(dcb, buffer))
{
@ -294,7 +347,7 @@ int gssapi_auth_load_users(SERV_LISTENER *listener)
*/
static GWAUTHENTICATOR MyObject =
{
NULL, /* TODO: implement initialize entry point */
gssapi_auth_init, /* Initialize authenticator */
gssapi_auth_alloc, /* Allocate authenticator data */
gssapi_auth_extract, /* Extract data into structure */
gssapi_auth_connectssl, /* Check if client supports SSL */