From baaea2838a4e59b8f4c49cc09f467233cfc2faa9 Mon Sep 17 00:00:00 2001 From: Stephan Bosch Date: Thu, 26 Oct 2023 03:40:24 +0200 Subject: [PATCH] auth: Use the new sasl-server instance-level mechanism registration API --- src/auth/Makefile.am | 33 ++- src/auth/auth-sasl-gssapi.h | 9 + src/auth/auth-sasl-mech-apop.c | 7 +- src/auth/auth-sasl-mech-dovecot-token.c | 8 +- src/auth/auth-sasl-mech-gss-spnego.c | 54 ++++ src/auth/auth-sasl-mech-gssapi.c | 48 ++++ src/auth/auth-sasl-mech-oauth2.c | 4 + src/auth/auth-sasl.c | 355 ++++++++++++++++++++---- src/auth/auth-sasl.h | 10 +- src/auth/main.c | 5 +- src/auth/mech.c | 132 --------- src/auth/sasl-server-gssapi.h | 10 + src/auth/sasl-server-mech-anonymous.c | 7 +- src/auth/sasl-server-mech-cram-md5.c | 7 +- src/auth/sasl-server-mech-digest-md5.c | 7 +- src/auth/sasl-server-mech-external.c | 7 +- src/auth/sasl-server-mech-gssapi.c | 36 +-- src/auth/sasl-server-mech-login.c | 7 +- src/auth/sasl-server-mech-oauth2.c | 18 +- src/auth/sasl-server-mech-otp.c | 7 +- src/auth/sasl-server-mech-plain.c | 7 +- src/auth/sasl-server-mech-scram.c | 32 ++- src/auth/sasl-server-mech-winbind.c | 33 ++- src/auth/sasl-server-protected.h | 24 -- src/auth/sasl-server.h | 34 +++ src/auth/test-auth.c | 6 +- src/auth/test-mech.c | 1 - 27 files changed, 643 insertions(+), 265 deletions(-) create mode 100644 src/auth/auth-sasl-gssapi.h create mode 100644 src/auth/auth-sasl-mech-gss-spnego.c create mode 100644 src/auth/auth-sasl-mech-gssapi.c delete mode 100644 src/auth/mech.c create mode 100644 src/auth/sasl-server-gssapi.h diff --git a/src/auth/Makefile.am b/src/auth/Makefile.am index fdbd60919b..5d8740dc60 100644 --- a/src/auth/Makefile.am +++ b/src/auth/Makefile.am @@ -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 index 0000000000..71f61071cb --- /dev/null +++ b/src/auth/auth-sasl-gssapi.h @@ -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 diff --git a/src/auth/auth-sasl-mech-apop.c b/src/auth/auth-sasl-mech-apop.c index 6a7b4ad883..72e9fcc812 100644 --- a/src/auth/auth-sasl-mech-apop.c +++ b/src/auth/auth-sasl-mech-apop.c @@ -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); +} diff --git a/src/auth/auth-sasl-mech-dovecot-token.c b/src/auth/auth-sasl-mech-dovecot-token.c index b662c25d7c..f3ecd30c92 100644 --- a/src/auth/auth-sasl-mech-dovecot-token.c +++ b/src/auth/auth-sasl-mech-dovecot-token.c @@ -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 index 0000000000..787160796f --- /dev/null +++ b/src/auth/auth-sasl-mech-gss-spnego.c @@ -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 index 0000000000..3a04022330 --- /dev/null +++ b/src/auth/auth-sasl-mech-gssapi.c @@ -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 diff --git a/src/auth/auth-sasl-mech-oauth2.c b/src/auth/auth-sasl-mech-oauth2.c index a537fedfc1..d8979803e7 100644 --- a/src/auth/auth-sasl-mech-oauth2.c +++ b/src/auth/auth-sasl-mech-oauth2.c @@ -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) diff --git a/src/auth/auth-sasl.c b/src/auth/auth-sasl.c index c985041e3e..17237d34eb 100644 --- a/src/auth/auth-sasl.c +++ b/src/auth/auth-sasl.c @@ -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(); } diff --git a/src/auth/auth-sasl.h b/src/auth/auth-sasl.h index f99c983199..9a2789e65e 100644 --- a/src/auth/auth-sasl.h +++ b/src/auth/auth-sasl.h @@ -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); diff --git a/src/auth/main.c b/src/auth/main.c index 4dd6b511b4..de3633b13f 100644 --- a/src/auth/main.c +++ b/src/auth/main.c @@ -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 index 4ff3829b5a..0000000000 --- a/src/auth/mech.c +++ /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 - -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 index 0000000000..e21533ef2e --- /dev/null +++ b/src/auth/sasl-server-gssapi.h @@ -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 diff --git a/src/auth/sasl-server-mech-anonymous.c b/src/auth/sasl-server-mech-anonymous.c index 17fdea0fa4..24a97ec24e 100644 --- a/src/auth/sasl-server-mech-anonymous.c +++ b/src/auth/sasl-server-mech-anonymous.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-cram-md5.c b/src/auth/sasl-server-mech-cram-md5.c index a1701aa279..d271b3524d 100644 --- a/src/auth/sasl-server-mech-cram-md5.c +++ b/src/auth/sasl-server-mech-cram-md5.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-digest-md5.c b/src/auth/sasl-server-mech-digest-md5.c index b5f70e0ead..339f569da1 100644 --- a/src/auth/sasl-server-mech-digest-md5.c +++ b/src/auth/sasl-server-mech-digest-md5.c @@ -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) { diff --git a/src/auth/sasl-server-mech-external.c b/src/auth/sasl-server-mech-external.c index 3454855230..b4be06a2b4 100644 --- a/src/auth/sasl-server-mech-external.c +++ b/src/auth/sasl-server-mech-external.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-gssapi.c b/src/auth/sasl-server-mech-gssapi.c index 405c0f8984..afe8fce8d9 100644 --- a/src/auth/sasl-server-mech-gssapi.c +++ b/src/auth/sasl-server-mech-gssapi.c @@ -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 diff --git a/src/auth/sasl-server-mech-login.c b/src/auth/sasl-server-mech-login.c index 873be0e383..3dcd40d14e 100644 --- a/src/auth/sasl-server-mech-login.c +++ b/src/auth/sasl-server-mech-login.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-oauth2.c b/src/auth/sasl-server-mech-oauth2.c index 624b297e6b..78b42d4738 100644 --- a/src/auth/sasl-server-mech-oauth2.c +++ b/src/auth/sasl-server-mech-oauth2.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-otp.c b/src/auth/sasl-server-mech-otp.c index 3d5551249b..98790a787c 100644 --- a/src/auth/sasl-server-mech-otp.c +++ b/src/auth/sasl-server-mech-otp.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-plain.c b/src/auth/sasl-server-mech-plain.c index 2959ab8d49..b928b551e5 100644 --- a/src/auth/sasl-server-mech-plain.c +++ b/src/auth/sasl-server-mech-plain.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-scram.c b/src/auth/sasl-server-mech-scram.c index 4df5b8cdfa..0f98549eec 100644 --- a/src/auth/sasl-server-mech-scram.c +++ b/src/auth/sasl-server-mech-scram.c @@ -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); +} diff --git a/src/auth/sasl-server-mech-winbind.c b/src/auth/sasl-server-mech-winbind.c index 6afadc8376..a4e2884a9d 100644 --- a/src/auth/sasl-server-mech-winbind.c +++ b/src/auth/sasl-server-mech-winbind.c @@ -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); +} diff --git a/src/auth/sasl-server-protected.h b/src/auth/sasl-server-protected.h index 5cfb9600c7..393e179ecd 100644 --- a/src/auth/sasl-server-protected.h +++ b/src/auth/sasl-server-protected.h @@ -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 */ diff --git a/src/auth/sasl-server.h b/src/auth/sasl-server.h index 4d40edbd00..67aff3d942 100644 --- a/src/auth/sasl-server.h +++ b/src/auth/sasl-server.h @@ -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 */ diff --git a/src/auth/test-auth.c b/src/auth/test-auth.c index 17d9c316c6..fc13d178fb 100644 --- a/src/auth/test-auth.c +++ b/src/auth/test-auth.c @@ -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); diff --git a/src/auth/test-mech.c b/src/auth/test-mech.c index eebe0ffa5f..692c346568 100644 --- a/src/auth/test-mech.c +++ b/src/auth/test-mech.c @@ -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" -- 2.47.3