]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Use the new sasl-server instance-level mechanism registration API
authorStephan Bosch <stephan.bosch@open-xchange.com>
Thu, 26 Oct 2023 01:40:24 +0000 (03:40 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Thu, 9 Oct 2025 08:41:22 +0000 (08:41 +0000)
27 files changed:
src/auth/Makefile.am
src/auth/auth-sasl-gssapi.h [new file with mode: 0644]
src/auth/auth-sasl-mech-apop.c
src/auth/auth-sasl-mech-dovecot-token.c
src/auth/auth-sasl-mech-gss-spnego.c [new file with mode: 0644]
src/auth/auth-sasl-mech-gssapi.c [new file with mode: 0644]
src/auth/auth-sasl-mech-oauth2.c
src/auth/auth-sasl.c
src/auth/auth-sasl.h
src/auth/main.c
src/auth/mech.c [deleted file]
src/auth/sasl-server-gssapi.h [new file with mode: 0644]
src/auth/sasl-server-mech-anonymous.c
src/auth/sasl-server-mech-cram-md5.c
src/auth/sasl-server-mech-digest-md5.c
src/auth/sasl-server-mech-external.c
src/auth/sasl-server-mech-gssapi.c
src/auth/sasl-server-mech-login.c
src/auth/sasl-server-mech-oauth2.c
src/auth/sasl-server-mech-otp.c
src/auth/sasl-server-mech-plain.c
src/auth/sasl-server-mech-scram.c
src/auth/sasl-server-mech-winbind.c
src/auth/sasl-server-protected.h
src/auth/sasl-server.h
src/auth/test-auth.c
src/auth/test-mech.c

index fdbd60919bd13ec1a095df1d859501ab06089267..5d8740dc606e19384d704e7a680f9acee0f143d0 100644 (file)
@@ -4,7 +4,9 @@ auth_moduledir = $(moduledir)/auth
 NOPLUGIN_LDFLAGS =
 
 if GSSAPI_PLUGIN
-GSSAPI_LIB = libmech_gssapi.la
+GSSAPI_LIB = \
+       libmech_gssapi.la \
+       libmech_gss_spnego.la
 endif
 
 if HAVE_LDAP
@@ -84,7 +86,6 @@ sasl_server_mechanisms = \
        sasl-server-mech-cram-md5.c \
        sasl-server-mech-digest-md5.c \
        sasl-server-mech-external.c \
-       sasl-server-mech-gssapi.c \
        sasl-server-mech-login.c \
        sasl-server-mech-oauth2.c \
        sasl-server-mech-otp.c \
@@ -92,6 +93,12 @@ sasl_server_mechanisms = \
        sasl-server-mech-plain-common.c \
        sasl-server-mech-scram.c \
        sasl-server-mech-winbind.c
+if HAVE_GSSAPI
+if !GSSAPI_PLUGIN
+sasl_server_mechanisms += \
+       sasl-server-mech-gssapi.c
+endif
+endif
 
 sasl_sources = \
        ${sasl_server_mechanisms} \
@@ -121,7 +128,6 @@ auth_common_sources = \
        db-oauth2.c \
        db-sql.c \
        db-passwd-file.c \
-       mech.c \
        ${sasl_sources} \
        passdb.c \
        passdb-blocking.c \
@@ -142,6 +148,13 @@ auth_common_sources = \
        userdb-sql.c \
        $(ldap_sources) \
        $(lua_sources)
+if HAVE_GSSAPI
+if !GSSAPI_PLUGIN
+auth_common_sources += \
+       auth-sasl-mech-gssapi.c \
+       auth-sasl-mech-gss-spnego.c
+endif
+endif
 
 headers = \
        auth.h \
@@ -156,6 +169,7 @@ headers = \
        auth-request-handler-private.h \
        auth-request-var-expand.h \
        auth-sasl.h \
+       auth-sasl-gssapi.h \
        auth-sasl-oauth2.h \
        auth-settings.h \
        auth-fields.h \
@@ -171,7 +185,9 @@ headers = \
        mech-otp.h \
        mech-digest-md5-private.h \
        sasl-server.h \
+       sasl-server-gssapi.h \
        sasl-server-oauth2.h \
+       sasl-server-private.h \
        sasl-server-protected.h \
        sasl-server-mech-plain-common.h \
        sasl-server-mech-scram.h \
@@ -185,7 +201,16 @@ if GSSAPI_PLUGIN
 libmech_gssapi_la_LDFLAGS = -module -avoid-version
 libmech_gssapi_la_LIBADD = $(KRB5_LIBS)
 libmech_gssapi_la_CPPFLAGS = $(AM_CPPFLAGS) $(KRB5_CFLAGS) -DPLUGIN_BUILD
-libmech_gssapi_la_SOURCES = sasl-server-mech-gssapi.c
+libmech_gssapi_la_SOURCES = \
+       sasl-server-mech-gssapi.c \
+       auth-sasl-mech-gssapi.c
+
+libmech_gss_spnego_la_LDFLAGS = -module -avoid-version
+libmech_gss_spnego_la_LIBADD = $(KRB5_LIBS)
+libmech_gss_spnego_la_CPPFLAGS = $(AM_CPPFLAGS) $(KRB5_CFLAGS) -DPLUGIN_BUILD
+libmech_gss_spnego_la_SOURCES = \
+       sasl-server-mech-gssapi.c \
+       auth-sasl-mech-gss-spnego.c
 endif
 
 if HAVE_LDAP
diff --git a/src/auth/auth-sasl-gssapi.h b/src/auth/auth-sasl-gssapi.h
new file mode 100644 (file)
index 0000000..71f6107
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef AUTH_SASL_MECH_GSSAPI_H
+#define AUTH_SASL_MECH_GSSAPI_H
+
+#ifdef BUILTIN_GSSAPI
+void auth_sasl_mech_gssapi_register(void);
+void auth_sasl_mech_gss_spnego_register(void);
+#endif
+
+#endif
index 6a7b4ad8836694e9bf4bd2b31ee6bbdba6584cf0..72e9fcc81253241762737a8d0b38b0d54a3e180b 100644 (file)
@@ -163,7 +163,7 @@ static const struct sasl_server_mech_funcs mech_apop_funcs = {
        .auth_initial = mech_apop_auth_initial,
 };
 
-const struct sasl_server_mech_def mech_apop = {
+static const struct sasl_server_mech_def mech_apop = {
        .name = AUTH_SASL_MECH_NAME_APOP,
 
        .flags = SASL_MECH_SEC_PRIVATE | SASL_MECH_SEC_DICTIONARY |
@@ -172,3 +172,8 @@ const struct sasl_server_mech_def mech_apop = {
 
        .funcs = &mech_apop_funcs,
 };
+
+void auth_sasl_mech_register_apop(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_apop);
+}
index b662c25d7c87c835a698ef5f79248ed40f3c76c6..f3ecd30c92784dbca2c7097d5bf6b1099070a6e6 100644 (file)
@@ -79,7 +79,7 @@ static const struct sasl_server_mech_funcs mech_dovecot_token_funcs = {
        .auth_continue = mech_dovecot_token_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_dovecot_token = {
+static const struct sasl_server_mech_def mech_dovecot_token = {
        .name = AUTH_SASL_MECH_NAME_DOVECOT_TOKEN,
 
        .flags = SASL_MECH_SEC_PRIVATE | SASL_MECH_SEC_ALLOW_NULS,
@@ -87,3 +87,9 @@ const struct sasl_server_mech_def mech_dovecot_token = {
 
        .funcs = &mech_dovecot_token_funcs,
 };
+
+const struct sasl_server_mech *
+auth_sasl_mech_register_dovecot_token(struct sasl_server_instance *sinst)
+{
+       return sasl_server_mech_register_hidden(sinst, &mech_dovecot_token);
+}
diff --git a/src/auth/auth-sasl-mech-gss-spnego.c b/src/auth/auth-sasl-mech-gss-spnego.c
new file mode 100644 (file)
index 0000000..7871607
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright (c) 2023 Dovecot authors, see the included COPYING file */
+
+#include "auth-common.h"
+#include "sasl-server.h"
+#include "sasl-server-gssapi.h"
+#include "auth-sasl.h"
+#include "auth-sasl-gssapi.h"
+
+#ifdef HAVE_GSSAPI_SPNEGO
+
+static struct auth_sasl_mech_module mech_gss_spnego;
+
+static bool
+mech_gss_spnego_register(struct sasl_server_instance *sasl_inst,
+                        const struct auth_settings *set ATTR_UNUSED)
+{
+       sasl_server_mech_register_gss_spnego(sasl_inst);
+       return TRUE;
+}
+
+static void
+mech_gss_spnego_unregister(struct sasl_server_instance *sasl_inst)
+{
+       sasl_server_mech_unregister_gss_spnego(sasl_inst);
+}
+
+static struct auth_sasl_mech_module mech_gss_spnego = {
+       .mech_name = SASL_MECH_NAME_GSS_SPNEGO,
+
+       .mech_register = mech_gss_spnego_register,
+       .mech_unregister = mech_gss_spnego_unregister,
+};
+
+#ifdef BUILTIN_GSSAPI
+void auth_sasl_mech_gss_spnego_register(void)
+{
+       auth_sasl_mech_register_module(&mech_gss_spnego);
+}
+#else
+void mech_gss_spnego_init(void);
+void mech_gss_spnego_deinit(void);
+
+void mech_gss_spnego_init(void)
+{
+       auth_sasl_mech_register_module(&mech_gss_spnego);
+}
+
+void mech_gss_spnego_deinit(void)
+{
+       auth_sasl_mech_unregister_module(&mech_gss_spnego);
+}
+#endif
+
+#endif
diff --git a/src/auth/auth-sasl-mech-gssapi.c b/src/auth/auth-sasl-mech-gssapi.c
new file mode 100644 (file)
index 0000000..3a04022
--- /dev/null
@@ -0,0 +1,48 @@
+/* Copyright (c) 2023 Dovecot authors, see the included COPYING file */
+
+#include "auth-common.h"
+#include "sasl-server.h"
+#include "sasl-server-gssapi.h"
+#include "auth-sasl.h"
+#include "auth-sasl-gssapi.h"
+
+static bool
+mech_gssapi_register(struct sasl_server_instance *sasl_inst,
+                    const struct auth_settings *set ATTR_UNUSED)
+{
+       sasl_server_mech_register_gssapi(sasl_inst);
+       return TRUE;
+}
+
+static void
+mech_gssapi_unregister(struct sasl_server_instance *sasl_inst)
+{
+       sasl_server_mech_unregister_gssapi(sasl_inst);
+}
+
+static struct auth_sasl_mech_module mech_gssapi = {
+       .mech_name = SASL_MECH_NAME_GSSAPI,
+
+       .mech_register = mech_gssapi_register,
+       .mech_unregister = mech_gssapi_unregister,
+};
+
+#ifdef BUILTIN_GSSAPI
+void auth_sasl_mech_gssapi_register(void)
+{
+       auth_sasl_mech_register_module(&mech_gssapi);
+}
+#else
+void mech_gssapi_init(void);
+void mech_gssapi_deinit(void);
+
+void mech_gssapi_init(void)
+{
+       auth_sasl_mech_register_module(&mech_gssapi);
+}
+
+void mech_gssapi_deinit(void)
+{
+       auth_sasl_mech_unregister_module(&mech_gssapi);
+}
+#endif
index a537fedfc19a07a36eaa3ef43a4dce3eb26fa213..d8979803e7dae924c8a06deccf38243ea655f594 100644 (file)
@@ -7,6 +7,10 @@
 
 #include "auth-sasl-oauth2.h"
 
+/*
+ * Token verification
+ */
+
 static void
 oauth2_verify_finish(enum passdb_result result,
                     struct auth_request *auth_request)
index c985041e3ec825a270533519e81caa83805e5268..17237d34ebae4ff4d94afac15b6caf27b381447c 100644 (file)
@@ -3,10 +3,12 @@
 #include "lib.h"
 #include "str.h"
 #include "settings-parser.h"
-#include "sasl-server-protected.h" // FIXME: remove
+#include "llist.h"
+#include "sasl-server.h"
 #include "auth.h"
 #include "auth-common.h"
 #include "auth-sasl.h"
+#include "auth-sasl-gssapi.h"
 #include "auth-sasl-oauth2.h"
 #include "auth-request.h"
 #include "auth-request-handler.h"
@@ -331,54 +333,293 @@ void auth_sasl_request_continue(struct auth_request *request,
  */
 
 struct auth_sasl_mech_module_list {
-       struct auth_sasl_mech_module_list *next;
+       struct auth_sasl_mech_module_list *prev, *next;
 
-       struct auth_sasl_mech_module module;
+       const struct auth_sasl_mech_module *module;
+
+       bool mech_registered:1;
 };
 
-static struct auth_sasl_mech_module_list *auth_sasl_mech_modules;
+static struct auth_sasl_mech_module_list *mech_modules = NULL;
+static struct auth_sasl_mech_module_list *mech_modules_loaded_head = NULL;
+static struct auth_sasl_mech_module_list *mech_modules_loaded_tail = NULL;
+
+const struct auth_sasl_mech_module *
+auth_sasl_mech_module_find(const char *name)
+{
+       struct auth_sasl_mech_module_list *list;
+
+       name = t_str_ucase(name);
+       for (list = mech_modules; list != NULL; list = list->next) {
+               if (strcmp(list->module->mech_name, name) == 0)
+                       return list->module;
+       }
+       return NULL;
+}
 
 void auth_sasl_mech_register_module(
        const struct auth_sasl_mech_module *module)
 {
+       const struct auth_sasl_mech_module *existing;
        struct auth_sasl_mech_module_list *list;
 
        i_assert(strcmp(module->mech_name,
                        t_str_ucase(module->mech_name)) == 0);
 
+       existing = auth_sasl_mech_module_find(module->mech_name);
+       if (existing != NULL) {
+               i_assert(existing == module);
+               return;
+       }
+
        list = i_new(struct auth_sasl_mech_module_list, 1);
-       list->module = *module;
+       list->module = module;
 
-       list->next = auth_sasl_mech_modules;
-       auth_sasl_mech_modules = list;
+       DLLIST_PREPEND(&mech_modules, list);
 }
 
 void auth_sasl_mech_unregister_module(
        const struct auth_sasl_mech_module *module)
 {
-       struct auth_sasl_mech_module_list **pos, *list;
+       struct auth_sasl_mech_module_list *list;
 
-       for (pos = &auth_sasl_mech_modules; *pos != NULL; pos = &(*pos)->next) {
-               if (strcmp((*pos)->module.mech_name, module->mech_name) == 0) {
-                       list = *pos;
-                       *pos = (*pos)->next;
-                       i_free(list);
-                       break;
-               }
+       for (list = mech_modules; list != NULL; list = list->next) {
+               if (list->module != module)
+                       continue;
+
+               DLLIST_REMOVE(&mech_modules, list);
+               i_free(list);
+               break;
        }
 }
 
-const struct auth_sasl_mech_module *
-auth_sasl_mech_module_find(const char *name)
+static void
+auth_sasl_mech_module_add_loaded(const struct auth_sasl_mech_module *module)
+{
+       struct auth_sasl_mech_module_list *list;
+
+       for (list = mech_modules_loaded_head; list != NULL; list = list->next) {
+               if (list->module == module)
+                       return;
+       }
+
+       list = i_new(struct auth_sasl_mech_module_list, 1);
+       list->module = module;
+
+       DLLIST2_APPEND(&mech_modules_loaded_head, &mech_modules_loaded_tail,
+                      list);
+}
+
+static bool auth_sasl_mech_module_load(const char *name)
 {
        struct auth_sasl_mech_module_list *list;
+
        name = t_str_ucase(name);
+       for (list = mech_modules; list != NULL; list = list->next) {
+               if (strcmp(list->module->mech_name, name) == 0) {
+                       auth_sasl_mech_module_add_loaded(list->module);
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
 
-       for (list = auth_sasl_mech_modules; list != NULL; list = list->next) {
-               if (strcmp(list->module.mech_name, name) == 0)
-                       return &list->module;
+static void auth_sasl_mechs_deinit(void)
+{
+       struct auth_sasl_mech_module_list *list, *list_next;
+
+       list = mech_modules;
+       while (list != NULL) {
+               list_next = list->next;
+
+               i_free(list);
+               list = list_next;
        }
-       return NULL;
+
+       list = mech_modules_loaded_head;
+       while (list != NULL) {
+               list_next = list->next;
+
+               i_free(list);
+               list = list_next;
+       }
+}
+
+/*
+ * Built-in Mechanisms
+ */
+
+#define MECH_SIMPLE_REGISTER__TEMPLATE(mech) \
+static bool \
+mech_ ## mech ## _register(struct sasl_server_instance *sasl_inst, \
+                          const struct auth_settings *set ATTR_UNUSED) \
+{ \
+       sasl_server_mech_register_ ## mech(sasl_inst); \
+       return TRUE; \
+}
+
+MECH_SIMPLE_REGISTER__TEMPLATE(anonymous)
+MECH_SIMPLE_REGISTER__TEMPLATE(cram_md5)
+MECH_SIMPLE_REGISTER__TEMPLATE(digest_md5)
+MECH_SIMPLE_REGISTER__TEMPLATE(external)
+MECH_SIMPLE_REGISTER__TEMPLATE(login)
+MECH_SIMPLE_REGISTER__TEMPLATE(oauthbearer)
+MECH_SIMPLE_REGISTER__TEMPLATE(xoauth2)
+MECH_SIMPLE_REGISTER__TEMPLATE(otp)
+MECH_SIMPLE_REGISTER__TEMPLATE(plain)
+MECH_SIMPLE_REGISTER__TEMPLATE(scram_sha1)
+MECH_SIMPLE_REGISTER__TEMPLATE(scram_sha1_plus)
+MECH_SIMPLE_REGISTER__TEMPLATE(scram_sha256)
+MECH_SIMPLE_REGISTER__TEMPLATE(scram_sha256_plus)
+
+static bool
+mech_winbind_ntlm_register(struct sasl_server_instance *sasl_inst,
+                          const struct auth_settings *set ATTR_UNUSED)
+{
+       sasl_server_mech_register_winbind_ntlm(sasl_inst);
+       return TRUE;
+}
+
+static bool
+mech_winbind_gss_spnego_register(struct sasl_server_instance *sasl_inst,
+                                const struct auth_settings *set ATTR_UNUSED)
+{
+       sasl_server_mech_register_winbind_gss_spnego(sasl_inst);
+       return TRUE;
+}
+
+static bool
+mech_apop_register(struct sasl_server_instance *sasl_inst,
+                  const struct auth_settings *set ATTR_UNUSED)
+{
+       auth_sasl_mech_register_apop(sasl_inst);
+       return TRUE;
+}
+
+static const struct auth_sasl_mech_module mech_anonymous = {
+       .mech_name = SASL_MECH_NAME_ANONYMOUS,
+
+       .mech_register = mech_anonymous_register,
+};
+
+static const struct auth_sasl_mech_module mech_cram_md5 = {
+       .mech_name = SASL_MECH_NAME_CRAM_MD5,
+
+       .mech_register = mech_cram_md5_register,
+};
+
+static const struct auth_sasl_mech_module mech_digest_md5 = {
+       .mech_name = SASL_MECH_NAME_DIGEST_MD5,
+
+       .mech_register = mech_digest_md5_register,
+};
+
+static const struct auth_sasl_mech_module mech_external = {
+       .mech_name = SASL_MECH_NAME_EXTERNAL,
+
+       .mech_register = mech_external_register,
+};
+
+static const struct auth_sasl_mech_module mech_login = {
+       .mech_name = SASL_MECH_NAME_LOGIN,
+
+       .mech_register = mech_login_register,
+};
+
+static const struct auth_sasl_mech_module mech_oauthbearer = {
+       .mech_name = SASL_MECH_NAME_OAUTHBEARER,
+
+       .mech_register = mech_oauthbearer_register,
+};
+
+static const struct auth_sasl_mech_module mech_otp = {
+       .mech_name = SASL_MECH_NAME_OTP,
+
+       .mech_register = mech_otp_register,
+};
+
+static const struct auth_sasl_mech_module mech_plain = {
+       .mech_name = SASL_MECH_NAME_PLAIN,
+
+       .mech_register = mech_plain_register,
+};
+
+static const struct auth_sasl_mech_module mech_scram_sha1 = {
+       .mech_name = SASL_MECH_NAME_SCRAM_SHA_1,
+
+       .mech_register = mech_scram_sha1_register,
+};
+
+static const struct auth_sasl_mech_module mech_scram_sha1_plus = {
+       .mech_name = SASL_MECH_NAME_SCRAM_SHA_1_PLUS,
+
+       .mech_register = mech_scram_sha1_plus_register,
+};
+
+static const struct auth_sasl_mech_module mech_scram_sha256 = {
+       .mech_name = SASL_MECH_NAME_SCRAM_SHA_256,
+
+       .mech_register = mech_scram_sha256_register,
+};
+
+static const struct auth_sasl_mech_module mech_scram_sha256_plus = {
+       .mech_name = SASL_MECH_NAME_SCRAM_SHA_256_PLUS,
+
+       .mech_register = mech_scram_sha256_plus_register,
+};
+
+static const struct auth_sasl_mech_module mech_winbind_ntlm = {
+       .mech_name = SASL_MECH_NAME_NTLM,
+
+       .mech_register = mech_winbind_ntlm_register,
+};
+
+static const struct auth_sasl_mech_module mech_winbind_gss_spnego = {
+       .mech_name = SASL_MECH_NAME_GSS_SPNEGO,
+
+       .mech_register = mech_winbind_gss_spnego_register,
+};
+
+static const struct auth_sasl_mech_module mech_xoauth2 = {
+       .mech_name = SASL_MECH_NAME_XOAUTH2,
+
+       .mech_register = mech_xoauth2_register,
+};
+
+static const struct auth_sasl_mech_module mech_apop = {
+       .mech_name = AUTH_SASL_MECH_NAME_APOP,
+
+       .mech_register = mech_apop_register,
+};
+
+static void auth_sasl_mechs_init(const struct auth_settings *set)
+{
+       auth_sasl_mech_register_module(&mech_anonymous);
+       auth_sasl_mech_register_module(&mech_cram_md5);
+       auth_sasl_mech_register_module(&mech_digest_md5);
+       auth_sasl_mech_register_module(&mech_external);
+#ifdef BUILTIN_GSSAPI
+       auth_sasl_mech_gssapi_register();
+#endif
+       if (set->use_winbind)
+               auth_sasl_mech_register_module(&mech_winbind_gss_spnego);
+#ifdef BUILTIN_GSSAPI
+       else
+               auth_sasl_mech_gss_spnego_register();
+#endif
+       auth_sasl_mech_register_module(&mech_login);
+       if (set->use_winbind)
+               auth_sasl_mech_register_module(&mech_winbind_ntlm);
+       auth_sasl_mech_register_module(&mech_oauthbearer);
+       auth_sasl_mech_register_module(&mech_otp);
+       auth_sasl_mech_register_module(&mech_plain);
+       auth_sasl_mech_register_module(&mech_scram_sha1);
+       auth_sasl_mech_register_module(&mech_scram_sha1_plus);
+       auth_sasl_mech_register_module(&mech_scram_sha256);
+       auth_sasl_mech_register_module(&mech_scram_sha256_plus);
+       auth_sasl_mech_register_module(&mech_xoauth2);
+
+       auth_sasl_mech_register_module(&mech_apop);
 }
 
 const char *auth_sasl_mechs_get_handshake(void)
@@ -395,8 +636,6 @@ const char *auth_sasl_mechs_get_handshake_cbind(void)
  * Instance
  */
 
-static const char *auth_sasl_mech_get_plugin_name(const char *name);
-
 void auth_sasl_instance_init(struct auth *auth,
                             const struct auth_settings *set)
 {
@@ -409,34 +648,18 @@ void auth_sasl_instance_init(struct auth *auth,
        auth->sasl_inst =
                sasl_server_instance_create(auth_sasl_server, &sasl_set);
 
-       const struct sasl_server_mech_def *mech;
-       const char *name;
-
-       if (array_is_empty(&set->mechanisms))
-               i_fatal("No authentication mechanisms configured");
+       struct auth_sasl_mech_module_list *list;
 
-       array_foreach_elem(&set->mechanisms, name) {
-               name = t_str_ucase(name);
+       for (list = mech_modules_loaded_head; list != NULL;
+            list = list->next) {
+               const struct auth_sasl_mech_module *mech = list->module;
 
-               if (strcmp(name, SASL_MECH_NAME_ANONYMOUS) == 0) {
-                       if (*set->anonymous_username == '\0') {
-                               i_fatal("ANONYMOUS listed in mechanisms, "
-                                       "but anonymous_username not set");
-                       }
-               }
-               mech = mech_module_find(name);
-               if (mech == NULL) {
-                       /* maybe it's a plugin. try to load it. */
-                       auth_module_load(auth_sasl_mech_get_plugin_name(name));
-                       mech = mech_module_find(name);
-               }
-               if (mech == NULL)
-                       i_fatal("Unknown authentication mechanism '%s'", name);
-               sasl_server_mech_register(auth->sasl_inst, mech);
+               list->mech_registered =
+                       mech->mech_register(auth->sasl_inst, set);
        }
 
        auth->sasl_mech_dovecot_token =
-               sasl_server_mech_register(auth->sasl_inst, &mech_dovecot_token);
+               auth_sasl_mech_register_dovecot_token(auth->sasl_inst);
 }
 
 static bool
@@ -490,6 +713,16 @@ void auth_sasl_instance_verify(const struct auth *auth)
 
 void auth_sasl_instance_deinit(struct auth *auth)
 {
+       struct auth_sasl_mech_module_list *list;
+
+       for (list = mech_modules_loaded_head; list != NULL;
+            list = list->next) {
+               const struct auth_sasl_mech_module *mech = list->module;
+
+               if (list->mech_registered && mech->mech_unregister != NULL)
+                       mech->mech_unregister(auth->sasl_inst);
+       }
+
        sasl_server_instance_unref(&auth->sasl_inst);
 }
 
@@ -557,11 +790,38 @@ static const char *auth_sasl_mech_get_plugin_name(const char *name)
        return str_c(str);
 }
 
-void auth_sasl_preinit(void)
+void auth_sasl_preinit(const struct auth_settings *set)
 {
        auth_sasl_oauth2_initialize();
        auth_sasl_server = sasl_server_init(auth_event,
                                            &auth_sasl_request_funcs);
+
+       auth_sasl_mechs_init(set);
+
+       const char *name;
+
+       if (array_is_empty(&set->mechanisms))
+               i_fatal("No authentication mechanisms configured");
+
+       array_foreach_elem(&set->mechanisms, name) {
+               name = t_str_ucase(name);
+
+               if (strcmp(name, SASL_MECH_NAME_ANONYMOUS) == 0) {
+                       if (*set->anonymous_username == '\0') {
+                               i_fatal("ANONYMOUS listed in mechanisms, "
+                                       "but anonymous_username not set");
+                       }
+               }
+               if (!auth_sasl_mech_module_load(name)) {
+                       /* maybe it's a plugin. try to load it. */
+                       auth_module_load(auth_sasl_mech_get_plugin_name(name));
+               }
+               if (!auth_sasl_mech_module_load(name))
+                       i_fatal("Unknown authentication mechanism '%s'", name);
+       }
+
+       if (mech_modules_loaded_head == NULL)
+               i_fatal("No authentication mechanisms configured");
 }
 
 void auth_sasl_init(void)
@@ -572,5 +832,6 @@ void auth_sasl_init(void)
 void auth_sasl_deinit(void)
 {
        sasl_server_deinit(&auth_sasl_server);
+       auth_sasl_mechs_deinit();
        auth_sasl_mechs_handshake_deinit();
 }
index f99c983199331c7f9c3ab23eba6058d5ac98efd9..9a2789e65ee989a5387e17c39cb25d5a60d8a793 100644 (file)
@@ -12,6 +12,10 @@ struct auth_settings;
 
 struct auth_sasl_mech_module {
        const char *mech_name;
+
+       bool (*mech_register)(struct sasl_server_instance *sasl_inst,
+                             const struct auth_settings *set);
+       void (*mech_unregister)(struct sasl_server_instance *sasl_inst);
 };
 
 /*
@@ -30,6 +34,10 @@ void auth_sasl_request_continue(struct auth_request *request,
  * Mechanisms
  */
 
+void auth_sasl_mech_register_apop(struct sasl_server_instance *sinst);
+const struct sasl_server_mech *
+auth_sasl_mech_register_dovecot_token(struct sasl_server_instance *sinst);
+
 void auth_sasl_mech_register_module(
        const struct auth_sasl_mech_module *module);
 void auth_sasl_mech_unregister_module(
@@ -53,7 +61,7 @@ void auth_sasl_instance_deinit(struct auth *auth);
  * Global
  */
 
-void auth_sasl_preinit(void);
+void auth_sasl_preinit(const struct auth_settings *set);
 void auth_sasl_init(void);
 void auth_sasl_deinit(void);
 
index 4dd6b511b432089291c6ff7da6ad31823d0c1f9b..de3633b13f3917648f6a3f9fcb214d6b20f05f75 100644 (file)
@@ -19,7 +19,7 @@
 #include "dict.h"
 #include "password-scheme.h"
 #include "passdb-cache.h"
-#include "sasl-server-protected.h"
+#include "sasl-server.h"
 #include "otp.h"
 #include "mech-otp.h"
 #include "auth.h"
@@ -179,7 +179,7 @@ static void main_preinit(void)
                auth_penalty = auth_penalty_init(AUTH_PENALTY_ANVIL_PATH);
 
        dict_drivers_register_builtin();
-       auth_sasl_preinit();
+       auth_sasl_preinit(global_auth_settings);
        auths_preinit(NULL, global_auth_settings, protocols);
 
        listeners_init();
@@ -276,7 +276,6 @@ static void main_deinit(void)
        auths_free();
 
        mech_otp_deinit();
-       mech_deinit(global_auth_settings);
 
        /* allow modules to unregister their dbs/drivers/etc. before freeing
           the whole data structures containing them. */
diff --git a/src/auth/mech.c b/src/auth/mech.c
deleted file mode 100644 (file)
index 4ff3829..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
-
-#include "auth-common.h"
-#include "ioloop.h"
-#include "str.h"
-#include "strfuncs.h"
-#include "passdb.h"
-
-#include "sasl-server-private.h"
-
-#include <ctype.h>
-
-static struct mech_module_list *mech_modules;
-
-void mech_register_module(const struct sasl_server_mech_def *module)
-{
-       struct mech_module_list *list;
-       i_assert(strcmp(module->name, t_str_ucase(module->name)) == 0);
-
-       list = i_new(struct mech_module_list, 1);
-       list->module = module;
-
-       list->next = mech_modules;
-       mech_modules = list;
-}
-
-void mech_unregister_module(const struct sasl_server_mech_def *module)
-{
-       struct mech_module_list **pos, *list;
-
-       for (pos = &mech_modules; *pos != NULL; pos = &(*pos)->next) {
-               if (strcmp((*pos)->module->name, module->name) == 0) {
-                       list = *pos;
-                       *pos = (*pos)->next;
-                       i_free(list);
-                       break;
-               }
-       }
-}
-
-const struct sasl_server_mech_def *mech_module_find(const char *name)
-{
-       struct mech_module_list *list;
-       name = t_str_ucase(name);
-
-       for (list = mech_modules; list != NULL; list = list->next) {
-               if (strcmp(list->module->name, name) == 0)
-                       return list->module;
-       }
-       return NULL;
-}
-
-extern const struct sasl_server_mech_def mech_plain;
-extern const struct sasl_server_mech_def mech_login;
-extern const struct sasl_server_mech_def mech_apop;
-extern const struct sasl_server_mech_def mech_cram_md5;
-extern const struct sasl_server_mech_def mech_digest_md5;
-extern const struct sasl_server_mech_def mech_external;
-extern const struct sasl_server_mech_def mech_otp;
-extern const struct sasl_server_mech_def mech_scram_sha1;
-extern const struct sasl_server_mech_def mech_scram_sha1_plus;
-extern const struct sasl_server_mech_def mech_scram_sha256;
-extern const struct sasl_server_mech_def mech_scram_sha256_plus;
-extern const struct sasl_server_mech_def mech_anonymous;
-#ifdef HAVE_GSSAPI
-extern const struct sasl_server_mech_def mech_gssapi;
-#endif
-#ifdef HAVE_GSSAPI_SPNEGO
-extern const struct sasl_server_mech_def mech_gssapi_spnego;
-#endif
-extern const struct sasl_server_mech_def mech_winbind_ntlm;
-extern const struct sasl_server_mech_def mech_winbind_spnego;
-extern const struct sasl_server_mech_def mech_oauthbearer;
-extern const struct sasl_server_mech_def mech_xoauth2;
-
-void mech_init(const struct auth_settings *set)
-{
-       mech_register_module(&mech_plain);
-       mech_register_module(&mech_login);
-       mech_register_module(&mech_apop);
-       mech_register_module(&mech_cram_md5);
-       mech_register_module(&mech_digest_md5);
-       mech_register_module(&mech_external);
-       if (set->use_winbind) {
-               mech_register_module(&mech_winbind_ntlm);
-               mech_register_module(&mech_winbind_spnego);
-       } else {
-#if defined(HAVE_GSSAPI_SPNEGO) && defined(BUILTIN_GSSAPI)
-               mech_register_module(&mech_gssapi_spnego);
-#endif
-       }
-       mech_register_module(&mech_otp);
-       mech_register_module(&mech_scram_sha1);
-       mech_register_module(&mech_scram_sha1_plus);
-       mech_register_module(&mech_scram_sha256);
-       mech_register_module(&mech_scram_sha256_plus);
-       mech_register_module(&mech_anonymous);
-#ifdef BUILTIN_GSSAPI
-       mech_register_module(&mech_gssapi);
-#endif
-       mech_register_module(&mech_oauthbearer);
-       mech_register_module(&mech_xoauth2);
-}
-
-void mech_deinit(const struct auth_settings *set)
-{
-       mech_unregister_module(&mech_plain);
-       mech_unregister_module(&mech_login);
-       mech_unregister_module(&mech_apop);
-       mech_unregister_module(&mech_cram_md5);
-       mech_unregister_module(&mech_digest_md5);
-       mech_unregister_module(&mech_external);
-       if (set->use_winbind) {
-               mech_unregister_module(&mech_winbind_ntlm);
-               mech_unregister_module(&mech_winbind_spnego);
-       } else {
-#if defined(HAVE_GSSAPI_SPNEGO) && defined(BUILTIN_GSSAPI)
-               mech_unregister_module(&mech_gssapi_spnego);
-#endif
-       }
-       mech_unregister_module(&mech_otp);
-       mech_unregister_module(&mech_scram_sha1);
-       mech_unregister_module(&mech_scram_sha1_plus);
-       mech_unregister_module(&mech_scram_sha256);
-       mech_unregister_module(&mech_scram_sha256_plus);
-       mech_unregister_module(&mech_anonymous);
-#ifdef BUILTIN_GSSAPI
-       mech_unregister_module(&mech_gssapi);
-#endif
-       mech_unregister_module(&mech_oauthbearer);
-       mech_unregister_module(&mech_xoauth2);
-}
diff --git a/src/auth/sasl-server-gssapi.h b/src/auth/sasl-server-gssapi.h
new file mode 100644 (file)
index 0000000..e21533e
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef SASL_SERVER_GSSAPI_H
+#define SASL_SERVER_GSSAPI_H
+
+void sasl_server_mech_register_gssapi(struct sasl_server_instance *sinst);
+void sasl_server_mech_unregister_gssapi(struct sasl_server_instance *sinst);
+
+void sasl_server_mech_register_gss_spnego(struct sasl_server_instance *sinst);
+void sasl_server_mech_unregister_gss_spnego(struct sasl_server_instance *sinst);
+
+#endif
index 17fdea0fa45ef2f1ee0ca593e6c2271fc0151c5e..24a97ec24e5469560e57f0cda47247b6daae8320 100644 (file)
@@ -23,7 +23,7 @@ static const struct sasl_server_mech_funcs mech_anonymous_funcs = {
        .auth_continue = mech_anonymous_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_anonymous = {
+static const struct sasl_server_mech_def mech_anonymous = {
        .name = SASL_MECH_NAME_ANONYMOUS,
 
        .flags = SASL_MECH_SEC_ANONYMOUS | SASL_MECH_SEC_ALLOW_NULS,
@@ -31,3 +31,8 @@ const struct sasl_server_mech_def mech_anonymous = {
 
        .funcs = &mech_anonymous_funcs,
 };
+
+void sasl_server_mech_register_anonymous(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_anonymous);
+}
index a1701aa279f8f65b7c7b54da086171ec26d386df..d271b3524d7ae539d99d6b79336d73d4173063e6 100644 (file)
@@ -181,7 +181,7 @@ static const struct sasl_server_mech_funcs mech_cram_md5_funcs = {
        .auth_continue = mech_cram_md5_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_cram_md5 = {
+static const struct sasl_server_mech_def mech_cram_md5 = {
        .name = SASL_MECH_NAME_CRAM_MD5,
 
        .flags = SASL_MECH_SEC_DICTIONARY | SASL_MECH_SEC_ACTIVE,
@@ -189,3 +189,8 @@ const struct sasl_server_mech_def mech_cram_md5 = {
 
        .funcs = &mech_cram_md5_funcs,
 };
+
+void sasl_server_mech_register_cram_md5(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_cram_md5);
+}
index b5f70e0eadfd0181711b6099f295adc328032d2d..339f569da1536012ca5a9caeeff3d958c53a1661 100644 (file)
@@ -612,7 +612,7 @@ static const struct sasl_server_mech_funcs mech_digest_md5_funcs = {
        .auth_continue = mech_digest_md5_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_digest_md5 = {
+static const struct sasl_server_mech_def mech_digest_md5 = {
        .name = SASL_MECH_NAME_DIGEST_MD5,
 
        .flags = SASL_MECH_SEC_DICTIONARY | SASL_MECH_SEC_ACTIVE |
@@ -622,6 +622,11 @@ const struct sasl_server_mech_def mech_digest_md5 = {
        .funcs = &mech_digest_md5_funcs,
 };
 
+void sasl_server_mech_register_digest_md5(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_digest_md5);
+}
+
 void mech_digest_test_set_nonce(struct auth_request *auth_request,
                                const char *nonce)
 {
index 34548552307f8c7ca578692868bb73625e347590..b4be06a2b4816d2005f4c11a5344bba5d56e40c0 100644 (file)
@@ -33,7 +33,7 @@ static const struct sasl_server_mech_funcs mech_external_funcs = {
        .auth_continue = mech_external_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_external = {
+static const struct sasl_server_mech_def mech_external = {
        .name = SASL_MECH_NAME_EXTERNAL,
 
        .flags = 0,
@@ -41,3 +41,8 @@ const struct sasl_server_mech_def mech_external = {
 
        .funcs = &mech_external_funcs,
 };
+
+void sasl_server_mech_register_external(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_external);
+}
index 405c0f898412bb167ae9f2fb674ae563dbe0ed4c..afe8fce8d9d18143cea2cef378c36833395bfd02 100644 (file)
@@ -20,6 +20,7 @@
 #include "safe-memset.h"
 
 #include "sasl-server-protected.h"
+#include "sasl-server-gssapi.h"
 
 #if defined(BUILTIN_GSSAPI) || defined(PLUGIN_BUILD)
 
@@ -680,7 +681,7 @@ static const struct sasl_server_mech_funcs mech_gssapi_funcs = {
        .auth_free = mech_gssapi_auth_free,
 };
 
-const struct sasl_server_mech_def mech_gssapi = {
+static const struct sasl_server_mech_def mech_gssapi = {
        .name = SASL_MECH_NAME_GSSAPI,
 
        .flags = SASL_MECH_SEC_ALLOW_NULS,
@@ -692,7 +693,7 @@ const struct sasl_server_mech_def mech_gssapi = {
 /* MIT Kerberos v1.5+ and Heimdal v0.7+ support SPNEGO for Kerberos tickets
    internally. Nothing else needs to be done here. Note, however, that this does
    not support SPNEGO when the only available credential is NTLM. */
-const struct sasl_server_mech_def mech_gssapi_spnego = {
+static const struct sasl_server_mech_def mech_gss_spnego = {
        .name = SASL_MECH_NAME_GSS_SPNEGO,
 
        .flags = SASL_MECH_SEC_ALLOW_NULS,
@@ -716,31 +717,24 @@ static void mech_gssapi_initialize(const struct auth_settings *set)
        }
 }
 
-#ifndef BUILTIN_GSSAPI
-void mech_gssapi_init(void);
-void mech_gssapi_deinit(void);
+void sasl_server_mech_register_gssapi(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_gssapi);
+}
 
-void mech_gssapi_init(void)
+void sasl_server_mech_unregister_gssapi(struct sasl_server_instance *sinst)
 {
-       mech_register_module(&mech_gssapi);
-#ifdef HAVE_GSSAPI_SPNEGO
-       /* load if we already didn't load it using winbind */
-       if (mech_module_find(mech_gssapi_spnego.name) == NULL)
-               mech_register_module(&mech_gssapi_spnego);
-#endif
+       sasl_server_mech_unregister(sinst, &mech_gssapi);
 }
 
-void mech_gssapi_deinit(void)
+void sasl_server_mech_register_gss_spnego(struct sasl_server_instance *sinst)
 {
-#ifdef HAVE_GSSAPI_SPNEGO
-       const struct sasl_server_mech_def *mech;
+       sasl_server_mech_register(sinst, &mech_gss_spnego);
+}
 
-       mech = mech_module_find(mech_gssapi_spnego.name);
-       if (mech != NULL && mech == &mech_gssapi_spnego)
-               mech_unregister_module(&mech_gssapi_spnego);
-#endif
-       mech_unregister_module(&mech_gssapi);
+void sasl_server_mech_unregister_gss_spnego(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_unregister(sinst, &mech_gss_spnego);
 }
-#endif
 
 #endif
index 873be0e383bab4fd30e17cd1f4a81b7100eade3c..3dcd40d14e4652e5e7adc6063f90621bed5ada0a 100644 (file)
@@ -56,7 +56,7 @@ static const struct sasl_server_mech_funcs mech_login_funcs = {
        .auth_continue = mech_login_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_login = {
+static const struct sasl_server_mech_def mech_login = {
        .name = SASL_MECH_NAME_LOGIN,
 
        .flags = SASL_MECH_SEC_PLAINTEXT,
@@ -64,3 +64,8 @@ const struct sasl_server_mech_def mech_login = {
 
        .funcs = &mech_login_funcs,
 };
+
+void sasl_server_mech_register_login(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_login);
+}
index 624b297e6bb6dd16a9b39b1398d213426c0aa09c..78b42d473846817b280f6cf1e829e6ca6b6ba361 100644 (file)
@@ -24,8 +24,8 @@ struct oauth2_auth_request {
        bool verifying_token:1;
 };
 
-const struct sasl_server_mech_def mech_oauthbearer;
-const struct sasl_server_mech_def mech_xoauth2;
+static const struct sasl_server_mech_def mech_oauthbearer;
+static const struct sasl_server_mech_def mech_xoauth2;
 
 static struct db_oauth2 *db_oauth2 = NULL;
 
@@ -321,7 +321,7 @@ static const struct sasl_server_mech_funcs mech_oauthbearer_funcs = {
        .auth_continue = mech_oauthbearer_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_oauthbearer = {
+static const struct sasl_server_mech_def mech_oauthbearer = {
        .name = SASL_MECH_NAME_OAUTHBEARER,
 
        /* while this does not transfer plaintext password,
@@ -338,7 +338,7 @@ static const struct sasl_server_mech_funcs mech_xoauth2_funcs = {
        .auth_continue = mech_xoauth2_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_xoauth2 = {
+static const struct sasl_server_mech_def mech_xoauth2 = {
        .name = SASL_MECH_NAME_XOAUTH2,
 
        .flags = SASL_MECH_SEC_PLAINTEXT,
@@ -346,3 +346,13 @@ const struct sasl_server_mech_def mech_xoauth2 = {
 
        .funcs = &mech_xoauth2_funcs,
 };
+
+void sasl_server_mech_register_oauthbearer(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_oauthbearer);
+}
+
+void sasl_server_mech_register_xoauth2(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_xoauth2);
+}
index 3d5551249b5e0fb7e145d888a994cf98ef92d343..98790a787cf86188017dbf2ca962c1c951540eae 100644 (file)
@@ -319,7 +319,7 @@ static const struct sasl_server_mech_funcs mech_otp_funcs = {
        .auth_free = mech_otp_auth_free,
 };
 
-const struct sasl_server_mech_def mech_otp = {
+static const struct sasl_server_mech_def mech_otp = {
        .name = SASL_MECH_NAME_OTP,
 
        .flags = SASL_MECH_SEC_DICTIONARY | SASL_MECH_SEC_ACTIVE |
@@ -333,3 +333,8 @@ void mech_otp_deinit(void)
 {
        otp_lock_deinit();
 }
+
+void sasl_server_mech_register_otp(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_otp);
+}
index 2959ab8d494909f9475e08041cf7ee221f9076bc..b928b551e5a14b999476f17f1c5c80156db67fc9 100644 (file)
@@ -67,7 +67,7 @@ static const struct sasl_server_mech_funcs mech_plain_funcs = {
        .auth_continue = mech_plain_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_plain = {
+static const struct sasl_server_mech_def mech_plain = {
        .name = SASL_MECH_NAME_PLAIN,
 
        .flags = SASL_MECH_SEC_PLAINTEXT | SASL_MECH_SEC_ALLOW_NULS,
@@ -75,3 +75,8 @@ const struct sasl_server_mech_def mech_plain = {
 
        .funcs = &mech_plain_funcs,
 };
+
+void sasl_server_mech_register_plain(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_plain);
+}
index 4df5b8cdfa6277321c8ff452a60c7a1b3af982a6..0f98549eec51b25fa0387a0443e5f0f52d1899da 100644 (file)
@@ -244,7 +244,7 @@ static const struct sasl_server_mech_funcs mech_scram_sha1_funcs = {
        .auth_free = mech_scram_auth_free,
 };
 
-const struct sasl_server_mech_def mech_scram_sha1 = {
+static const struct sasl_server_mech_def mech_scram_sha1 = {
        .name = SASL_MECH_NAME_SCRAM_SHA_1,
 
        .flags = SASL_MECH_SEC_MUTUAL_AUTH,
@@ -253,7 +253,7 @@ const struct sasl_server_mech_def mech_scram_sha1 = {
        .funcs = &mech_scram_sha1_funcs,
 };
 
-const struct sasl_server_mech_def mech_scram_sha1_plus = {
+static const struct sasl_server_mech_def mech_scram_sha1_plus = {
        .name = SASL_MECH_NAME_SCRAM_SHA_1_PLUS,
 
        .flags = SASL_MECH_SEC_MUTUAL_AUTH | SASL_MECH_SEC_CHANNEL_BINDING,
@@ -269,7 +269,7 @@ static const struct sasl_server_mech_funcs mech_scram_sha256_funcs = {
        .auth_free = mech_scram_auth_free,
 };
 
-const struct sasl_server_mech_def mech_scram_sha256 = {
+static const struct sasl_server_mech_def mech_scram_sha256 = {
        .name = SASL_MECH_NAME_SCRAM_SHA_256,
 
        .flags = SASL_MECH_SEC_MUTUAL_AUTH,
@@ -278,7 +278,7 @@ const struct sasl_server_mech_def mech_scram_sha256 = {
        .funcs = &mech_scram_sha256_funcs,
 };
 
-const struct sasl_server_mech_def mech_scram_sha256_plus = {
+static const struct sasl_server_mech_def mech_scram_sha256_plus = {
        .name = SASL_MECH_NAME_SCRAM_SHA_256_PLUS,
 
        .flags = SASL_MECH_SEC_MUTUAL_AUTH | SASL_MECH_SEC_CHANNEL_BINDING,
@@ -286,3 +286,27 @@ const struct sasl_server_mech_def mech_scram_sha256_plus = {
 
        .funcs = &mech_scram_sha256_funcs,
 };
+
+void sasl_server_mech_register_scram_sha1(
+       struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_scram_sha1);
+}
+
+void sasl_server_mech_register_scram_sha1_plus(
+       struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_scram_sha1_plus);
+}
+
+void sasl_server_mech_register_scram_sha256(
+       struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_scram_sha256);
+}
+
+void sasl_server_mech_register_scram_sha256_plus(
+       struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_scram_sha256_plus);
+}
index 6afadc837678d945e3236228e511c2500fca12e0..a4e2884a9dc74ee78f1177be29a483ae05204cc5 100644 (file)
@@ -327,46 +327,57 @@ do_auth_new(pool_t pool, struct winbind_helper *winbind)
 }
 
 static struct sasl_server_mech_request *
-mech_winbind_ntlm_auth_new(const struct sasl_server_mech *mech ATTR_UNUSED,
-                          pool_t pool)
+mech_winbind_ntlm_auth_new(
+       const struct sasl_server_mech *mech ATTR_UNUSED, pool_t pool)
 {
        return do_auth_new(pool, &winbind_ntlm_context);
 }
 
 static struct sasl_server_mech_request *
-mech_winbind_spnego_auth_new(const struct sasl_server_mech *mech ATTR_UNUSED,
-                            pool_t pool)
+mech_winbind_gss_spnego_auth_new(
+       const struct sasl_server_mech *mech ATTR_UNUSED, pool_t pool)
 {
        return do_auth_new(pool, &winbind_spnego_context);
 }
 
-static const struct sasl_server_mech_funcs mech_winbind_ntlm_funcs = {
+static const struct sasl_server_mech_funcs mech_ntlm_funcs = {
        .auth_new = mech_winbind_ntlm_auth_new,
        .auth_initial = mech_winbind_auth_initial,
        .auth_continue = mech_winbind_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_winbind_ntlm = {
+static const struct sasl_server_mech_def mech_ntlm = {
        .name = SASL_MECH_NAME_NTLM,
 
        .flags = SASL_MECH_SEC_DICTIONARY | SASL_MECH_SEC_ACTIVE |
                 SASL_MECH_SEC_ALLOW_NULS,
        .passdb_need = SASL_MECH_PASSDB_NEED_NOTHING,
 
-       .funcs = &mech_winbind_ntlm_funcs,
+       .funcs = &mech_ntlm_funcs,
 };
 
-static const struct sasl_server_mech_funcs mech_winbind_spnego_funcs = {
-       .auth_new = mech_winbind_spnego_auth_new,
+static const struct sasl_server_mech_funcs mech_gss_spnego_funcs = {
+       .auth_new = mech_winbind_gss_spnego_auth_new,
        .auth_initial = mech_winbind_auth_initial,
        .auth_continue = mech_winbind_auth_continue,
 };
 
-const struct sasl_server_mech_def mech_winbind_spnego = {
+static const struct sasl_server_mech_def mech_gss_spnego = {
        .name = SASL_MECH_NAME_GSS_SPNEGO,
 
        .flags = SASL_MECH_SEC_ALLOW_NULS,
        .passdb_need = SASL_MECH_PASSDB_NEED_NOTHING,
 
-       .funcs = &mech_winbind_spnego_funcs,
+       .funcs = &mech_gss_spnego_funcs,
 };
+
+void sasl_server_mech_register_winbind_ntlm(struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_ntlm);
+}
+
+void sasl_server_mech_register_winbind_gss_spnego(
+       struct sasl_server_instance *sinst)
+{
+       sasl_server_mech_register(sinst, &mech_gss_spnego);
+}
index 5cfb9600c7c235b1cd67ae55061e91f32bad5fe8..393e179ecd04274618c40d13e4ef90c1333d5a29 100644 (file)
@@ -41,21 +41,6 @@ struct sasl_server_mech_def {
        const struct sasl_server_mech_funcs *funcs;
 };
 
-struct mech_module_list {
-       struct mech_module_list *next;
-
-       const struct sasl_server_mech_def *module;
-};
-
-struct mechanisms_register {
-       pool_t pool;
-       const struct auth_settings *set;
-
-       struct mech_module_list *modules;
-       buffer_t *handshake;
-       buffer_t *handshake_cbind;
-};
-
 struct sasl_server_mech_data {
        struct sasl_server *server;
        pool_t pool;
@@ -93,8 +78,6 @@ struct sasl_server_mech_request {
  * Mechanism
  */
 
-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);
@@ -104,17 +87,10 @@ sasl_server_mech_register_hidden(struct sasl_server_instance *sinst,
 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);
-
 void sasl_server_mech_generic_auth_initial(
        struct sasl_server_mech_request *mreq,
        const unsigned char *data, size_t data_size);
 
-void mech_init(const struct auth_settings *set);
-void mech_deinit(const struct auth_settings *set);
-
 /*
  * Request
  */
index 4d40edbd000960f1e5d7dd30b1f43625757617d4..67aff3d942c9e8aa9e7decc53f49cc53af46e66f 100644 (file)
@@ -167,6 +167,40 @@ sasl_server_request_has_failed(const struct sasl_server_req_ctx *rctx);
 void sasl_server_request_test_set_authid(struct sasl_server_req_ctx *rctx,
                                         const char *authid);
 
+/*
+ * Mechanism definitions
+ */
+
+void sasl_server_mech_register_anonymous(struct sasl_server_instance *sinst);
+void sasl_server_mech_register_cram_md5(struct sasl_server_instance *sinst);
+void sasl_server_mech_register_digest_md5(struct sasl_server_instance *sinst);
+void sasl_server_mech_register_external(struct sasl_server_instance *sinst);
+void sasl_server_mech_register_login(struct sasl_server_instance *sinst);
+void sasl_server_mech_register_plain(struct sasl_server_instance *sinst);
+
+void sasl_server_mech_register_scram_sha1(
+       struct sasl_server_instance *sinst);
+void sasl_server_mech_register_scram_sha1_plus(
+       struct sasl_server_instance *sinst);
+void sasl_server_mech_register_scram_sha256(
+       struct sasl_server_instance *sinst);
+void sasl_server_mech_register_scram_sha256_plus(
+       struct sasl_server_instance *sinst);
+
+void sasl_server_mech_register_otp(struct sasl_server_instance *sinst);
+
+/* OAUTH2 */
+
+void sasl_server_mech_register_oauthbearer(struct sasl_server_instance *sinst);
+void sasl_server_mech_register_xoauth2(struct sasl_server_instance *sinst);
+
+/* Winbind */
+
+void sasl_server_mech_register_winbind_ntlm(
+       struct sasl_server_instance *sinst);
+void sasl_server_mech_register_winbind_gss_spnego(
+       struct sasl_server_instance *sinst);
+
 /*
  * Mechanism
  */
index 17d9c316c6aa03490adb957d33722c769050a415..fc13d178fb006304a4d722cd20b8439b5887f7bf 100644 (file)
@@ -6,7 +6,7 @@
 #include "auth-settings.h"
 #include "auth-token.h"
 #include "auth-penalty.h"
-#include "sasl-server-protected.h" // FIXME: remove
+#include "sasl-server.h"
 #include "otp.h"
 #include "mech-otp.h"
 #include "db-oauth2.h"
@@ -55,14 +55,13 @@ void test_auth_init(void)
                                                     &auth_setting_parser_info);
        /* this is needed to get oauth2 initialized */
        auth_event = simple_set.event;
-       mech_init(global_auth_settings);
        passdbs_init();
        userdbs_init();
        passdb_mock_mod_init();
        password_schemes_register_all();
        password_schemes_allow_weak(TRUE);
 
-       auth_sasl_preinit();
+       auth_sasl_preinit(global_auth_settings);
        auths_preinit(simple_set.event, global_auth_settings, protocols);
        auths_init();
        auth_token_init();
@@ -83,7 +82,6 @@ void test_auth_deinit(void)
        passdbs_deinit();
        userdbs_deinit();
        event_unref(&auth_event);
-       mech_deinit(global_auth_settings);
        auths_free();
        auth_sasl_deinit();
        settings_free(global_auth_settings);
index eebe0ffa5fd19233f4c76b9b714ba9b7205864bb..692c346568eee961a4d6b10b25ed370075a84e32 100644 (file)
@@ -5,7 +5,6 @@
 #include "str.h"
 #include "ioloop.h"
 #include "master-service.h"
-#include "sasl-server-private.h" // FIXME: remove
 #include "auth-common.h"
 #include "auth-sasl.h"
 #include "auth-request.h"