]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
login-common: sasl-server - Add means to filter the available SASL mechanisms.
authorStephan Bosch <stephan.bosch@open-xchange.com>
Wed, 7 Aug 2019 23:56:17 +0000 (01:56 +0200)
committerStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 13 Aug 2019 22:46:26 +0000 (00:46 +0200)
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
src/login-common/sasl-server.c

index 68257ac3f851d958127ec73f86e1b6d2e90034fe..bbbb1f5bf1c2f3fc670db403da9daa0c072e83ee 100644 (file)
@@ -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,
index a84cbea759f7e3f7c98f4b42bb8d597a2d0d1f01..0f0ad9de8377ff7ea24d703eb2fb57956c1d662f 100644 (file)
@@ -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;
 }