]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: sasl-server - Create new per-instance mechanism registry
authorStephan Bosch <stephan.bosch@open-xchange.com>
Sun, 26 Mar 2023 15:47:08 +0000 (17:47 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Thu, 9 Oct 2025 08:41:22 +0000 (08:41 +0000)
src/auth/sasl-server-mech.c
src/auth/sasl-server-private.h
src/auth/sasl-server-protected.h
src/auth/sasl-server.h

index c91dbadb74857870108db01c9cd96e650e9f2d89..e5ff69c32c9d6a840ffd961ffcca9a098fc90a20 100644 (file)
@@ -1,9 +1,35 @@
 /* Copyright (c) 2023 Dovecot authors, see the included COPYING file */
 
 #include "auth-common.h"
+#include "llist.h"
 
 #include "sasl-server-private.h"
 
+/*
+ * Accessors
+ */
+
+const char *sasl_server_mech_get_name(const struct sasl_server_mech *mech)
+{
+       return mech->def->name;
+}
+
+enum sasl_mech_security_flags
+sasl_server_mech_get_security_flags(const struct sasl_server_mech *mech)
+{
+       return mech->def->flags;
+}
+
+enum sasl_mech_passdb_need
+sasl_server_mech_get_passdb_need(const struct sasl_server_mech *mech)
+{
+       return mech->def->passdb_need;
+}
+
+/*
+ * Common functions
+ */
+
 void sasl_server_mech_generic_auth_initial(
        struct sasl_server_mech_request *mreq,
        const unsigned char *data, size_t data_size)
@@ -18,3 +44,138 @@ void sasl_server_mech_generic_auth_initial(
                mech->funcs->auth_continue(mreq, data, data_size);
        }
 }
+
+/*
+ * Registry
+ */
+
+static struct sasl_server_mech_reg *
+sasl_server_mech_reg_find(struct sasl_server_instance *sinst, const char *name)
+{
+       struct sasl_server_mech_reg *mech_reg;
+       name = t_str_ucase(name);
+
+       for (mech_reg = sinst->mechs_head; mech_reg != NULL;
+            mech_reg = mech_reg->next) {
+               if (strcmp(mech_reg->mech->def->name, name) == 0)
+                       return mech_reg;
+       }
+       return NULL;
+}
+
+static struct sasl_server_mech *
+sasl_server_mech_create(struct sasl_server_instance *sinst,
+                       const struct sasl_server_mech_def *def)
+{
+       struct sasl_server_mech *mech;
+
+       mech = p_new(sinst->pool, struct sasl_server_mech, 1);
+       mech->pool = sinst->pool;
+       mech->sinst = sinst;
+       mech->def = def;
+
+       mech->event = event_create(sinst->event);
+       event_drop_parent_log_prefixes(mech->event, 1);
+       event_set_append_log_prefix(mech->event,
+               t_strdup_printf("sasl(%s): ", t_str_lcase(def->name)));
+
+       return mech;
+}
+
+static void sasl_server_mech_free(struct sasl_server_mech *mech)
+{
+       event_unref(&mech->event);
+       mech->def = NULL;
+}
+
+static struct sasl_server_mech *
+sasl_server_mech_register_common(struct sasl_server_instance *sinst,
+                                const struct sasl_server_mech_def *def)
+{
+       struct sasl_server_mech_reg *mech_reg;
+       struct sasl_server_mech *mech;
+
+       i_assert(sasl_server_mech_reg_find(sinst, def->name) == NULL);
+
+       mech_reg = p_new(sinst->pool, struct sasl_server_mech_reg, 1);
+
+       mech = sasl_server_mech_create(sinst, def);
+       mech->reg = mech_reg;
+       mech_reg->mech = mech;
+
+       return mech;
+}
+
+struct sasl_server_mech *
+sasl_server_mech_register(struct sasl_server_instance *sinst,
+                         const struct sasl_server_mech_def *def)
+{
+       struct sasl_server_mech *mech;
+
+       mech = sasl_server_mech_register_common(sinst, def);
+       DLLIST2_APPEND(&sinst->mechs_head, &sinst->mechs_tail, mech->reg);
+
+       return mech;
+}
+
+struct sasl_server_mech *
+sasl_server_mech_register_hidden(struct sasl_server_instance *sinst,
+                                const struct sasl_server_mech_def *def)
+{
+       struct sasl_server_mech *mech;
+
+       mech = sasl_server_mech_register_common(sinst, def);
+       DLLIST_PREPEND(&sinst->mechs_hidden, mech->reg);
+
+       return mech;
+}
+
+const struct sasl_server_mech *
+sasl_server_mech_find(struct sasl_server_instance *sinst, const char *name)
+{
+       struct sasl_server_mech_reg *mech_reg;
+
+       mech_reg = sasl_server_mech_reg_find(sinst, name);
+       if (mech_reg == NULL)
+               return NULL;
+       return mech_reg->mech;
+}
+
+static struct sasl_server_mech_reg *
+sasl_server_mech_reg_list_find(struct sasl_server_mech_reg *mech_reg_list,
+                              const struct sasl_server_mech_def *def)
+{
+       struct sasl_server_mech_reg *mech_reg;
+
+       mech_reg = mech_reg_list;
+       while (mech_reg != NULL) {
+               struct sasl_server_mech_reg *mech_reg_next = mech_reg->next;
+
+               if (mech_reg->mech->def == def)
+                       return mech_reg;
+               mech_reg = mech_reg_next;
+       }
+       return NULL;
+}
+
+void sasl_server_mech_unregister(struct sasl_server_instance *sinst,
+                                const struct sasl_server_mech_def *def)
+{
+       struct sasl_server_mech_reg *mech_reg;
+
+       mech_reg = sasl_server_mech_reg_list_find(sinst->mechs_head, def);
+       if (mech_reg != NULL) {
+               DLLIST2_REMOVE(&sinst->mechs_head,
+                              &sinst->mechs_tail, mech_reg);
+       } else {
+               mech_reg = sasl_server_mech_reg_list_find(
+                       sinst->mechs_hidden, def);
+               if (mech_reg != NULL)
+                       DLLIST_REMOVE(&sinst->mechs_hidden, mech_reg);
+       }
+
+       if (mech_reg == NULL)
+               return;
+
+       sasl_server_mech_free(mech_reg->mech);
+}
index 6ef13ebb51f5c6034a393d5f9da0bf35997df691..dbb5677baf7bfb34013b0c3de48de61f45914dcd 100644 (file)
@@ -19,6 +19,11 @@ struct sasl_server_request {
        sasl_server_mech_passdb_callback_t *passdb_callback;
 };
 
+struct sasl_server_mech_reg {
+       struct sasl_server_mech *mech;
+       struct sasl_server_mech_reg *prev, *next;
+};
+
 struct sasl_server_instance {
        struct sasl_server *server;
        pool_t pool;
@@ -27,6 +32,9 @@ struct sasl_server_instance {
        struct event *event;
        struct sasl_server_settings set;
 
+       struct sasl_server_mech_reg *mechs_head, *mechs_tail;
+       struct sasl_server_mech_reg *mechs_hidden;
+
        unsigned int requests;
 };
 
index 35fe5b30bf33f35ac9283d99625bd3ad86103dea..af042fd6ceaace7f381cdd35411bcd84debadb60 100644 (file)
@@ -46,6 +46,15 @@ struct mechanisms_register {
        buffer_t *handshake_cbind;
 };
 
+struct sasl_server_mech {
+       struct sasl_server_instance *sinst;
+       struct sasl_server_mech_reg *reg;
+       pool_t pool;
+       struct event *event;
+
+       const struct sasl_server_mech_def *def;
+};
+
 struct sasl_server_mech_request {
        pool_t pool;
        const struct sasl_server_mech_def *mech;
@@ -68,6 +77,15 @@ struct sasl_server_mech_request {
 
 extern const struct sasl_server_mech_def mech_dovecot_token;
 
+struct sasl_server_mech * ATTR_NOWARN_UNUSED_RESULT
+sasl_server_mech_register(struct sasl_server_instance *sinst,
+                         const struct sasl_server_mech_def *def);
+struct sasl_server_mech * ATTR_NOWARN_UNUSED_RESULT
+sasl_server_mech_register_hidden(struct sasl_server_instance *sinst,
+                                const struct sasl_server_mech_def *def);
+void sasl_server_mech_unregister(struct sasl_server_instance *sinst,
+                                const struct sasl_server_mech_def *def);
+
 void mech_register_module(const struct sasl_server_mech_def *module);
 void mech_unregister_module(const struct sasl_server_mech_def *module);
 const struct sasl_server_mech_def *mech_module_find(const char *name);
index 0ed6e3b5bf9339d4290b8c8e993759f80b7fb7a6..5f4a22ec8eda644097c9cc6f5b4b36514a63a11a 100644 (file)
@@ -5,6 +5,7 @@
 
 struct sasl_passdb_result;
 struct sasl_server_mech_def;
+struct sasl_server_mech;
 struct sasl_server_request;
 struct sasl_server_req_ctx;
 struct sasl_server_instance;
@@ -148,6 +149,20 @@ void sasl_server_request_input(struct sasl_server_req_ctx *rctx,
 void sasl_server_request_test_set_authid(struct sasl_server_req_ctx *rctx,
                                         const char *authid);
 
+/*
+ * Mechanism
+ */
+
+const char * ATTR_PURE
+sasl_server_mech_get_name(const struct sasl_server_mech *mech);
+enum sasl_mech_security_flags ATTR_PURE
+sasl_server_mech_get_security_flags(const struct sasl_server_mech *mech);
+enum sasl_mech_passdb_need ATTR_PURE
+sasl_server_mech_get_passdb_need(const struct sasl_server_mech *mech);
+
+const struct sasl_server_mech *
+sasl_server_mech_find(struct sasl_server_instance *sinst, const char *name);
+
 /*
  * Instance
  */