From: Stephan Bosch Date: Wed, 7 Aug 2019 23:56:17 +0000 (+0200) Subject: login-common: sasl-server - Add means to filter the available SASL mechanisms. X-Git-Tag: 2.3.9~319 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98433306a1dafe3ddb29b7ad87c00c182f8f2f63;p=thirdparty%2Fdovecot%2Fcore.git 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. --- 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; }