From 98433306a1dafe3ddb29b7ad87c00c182f8f2f63 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Thu, 8 Aug 2019 01:56:17 +0200 Subject: [PATCH] login-common: sasl-server - Add means to filter the available SASL mechanisms. This is accessible as a new client vfunc, so it can be used by protocol login services and their plugins. --- src/login-common/client-common.h | 2 ++ src/login-common/sasl-server.c | 33 +++++++++++++++++++++++++++----- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/login-common/client-common.h b/src/login-common/client-common.h index 68257ac3f8..bbbb1f5bf1 100644 --- a/src/login-common/client-common.h +++ b/src/login-common/client-common.h @@ -110,6 +110,8 @@ struct client_vfuncs { bool success, const char *text); void (*starttls)(struct client *client); void (*input)(struct client *client); + bool (*sasl_filter_mech)(struct client *client, + struct auth_mech_desc *mech); void (*auth_send_challenge)(struct client *client, const char *data); void (*auth_parse_response)(struct client *client); void (*auth_result)(struct client *client, diff --git a/src/login-common/sasl-server.c b/src/login-common/sasl-server.c index a84cbea759..0f0ad9de83 100644 --- a/src/login-common/sasl-server.c +++ b/src/login-common/sasl-server.c @@ -31,6 +31,15 @@ struct anvil_request { unsigned char cookie[MASTER_AUTH_COOKIE_SIZE]; }; +static bool +sasl_server_filter_mech(struct client *client, struct auth_mech_desc *mech) +{ + if (client->v.sasl_filter_mech != NULL && + !client->v.sasl_filter_mech(client, mech)) + return FALSE; + return TRUE; +} + const struct auth_mech_desc * sasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r) { @@ -47,29 +56,43 @@ sasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r) ret_mech = t_new(struct auth_mech_desc, count); for (i = j = 0; i < count; i++) { + struct auth_mech_desc fmech = mech[i]; + + if (!sasl_server_filter_mech(client, &fmech)) + continue; + /* a) transport is secured b) auth mechanism isn't plaintext c) we allow insecure authentication */ - if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 && + if ((fmech.flags & MECH_SEC_PRIVATE) == 0 && (client->secured || !client->set->disable_plaintext_auth || - (mech[i].flags & MECH_SEC_PLAINTEXT) == 0)) - ret_mech[j++] = mech[i]; + (fmech.flags & MECH_SEC_PLAINTEXT) == 0)) + ret_mech[j++] = fmech; } *count_r = j; return ret_mech; } const struct auth_mech_desc * -sasl_server_find_available_mech(struct client *client ATTR_UNUSED, - const char *name) +sasl_server_find_available_mech(struct client *client, const char *name) { const struct auth_mech_desc *mech; + struct auth_mech_desc fmech; mech = auth_client_find_mech(auth_client, name); if (mech == NULL) return NULL; + fmech = *mech; + if (!sasl_server_filter_mech(client, &fmech)) + return NULL; + if (memcmp(&fmech, mech, sizeof(fmech)) != 0) { + struct auth_mech_desc *nmech = t_new(struct auth_mech_desc, 1); + + *nmech = fmech; + mech = nmech; + } return mech; } -- 2.47.3