From: Timo Sirainen Date: Sat, 13 Mar 2010 20:23:58 +0000 (+0200) Subject: auth: Moved mechanism list out of struct auth. X-Git-Tag: 2.0.beta4~66 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=21c317a20c4c3784b54fb3e90ee3751870afdcc3;p=thirdparty%2Fdovecot%2Fcore.git auth: Moved mechanism list out of struct auth. It could have been good there, except mechanism list is sent before there's any knowledge of what type of client is on the other side. Maybe in future different mechanism list could be given based on the unix socket name. --HG-- branch : HEAD --- diff --git a/src/auth/auth-client-connection.c b/src/auth/auth-client-connection.c index b815ef8e20..b17a21e8bf 100644 --- a/src/auth/auth-client-connection.c +++ b/src/auth/auth-client-connection.c @@ -13,6 +13,7 @@ #include "randgen.h" #include "safe-memset.h" #include "master-service.h" +#include "mech.h" #include "auth-stream.h" #include "auth-request-handler.h" #include "auth-client-interface.h" @@ -289,8 +290,7 @@ auth_client_connection_create(struct auth *auth, int fd) str_printfa(str, "VERSION\t%u\t%u\n%sSPID\t%s\nCUID\t%u\nCOOKIE\t", AUTH_CLIENT_PROTOCOL_MAJOR_VERSION, AUTH_CLIENT_PROTOCOL_MINOR_VERSION, - str_c(conn->auth->mech_handshake), - my_pid, conn->connect_uid); + str_c(auth->reg->handshake), my_pid, conn->connect_uid); binary_to_hex_append(str, conn->cookie, sizeof(conn->cookie)); str_append(str, "\nDONE\n"); diff --git a/src/auth/auth.c b/src/auth/auth.c index 7f624028f5..e9a535f2bc 100644 --- a/src/auth/auth.c +++ b/src/auth/auth.c @@ -50,7 +50,8 @@ auth_userdb_preinit(struct auth *auth, const struct auth_userdb_settings *set) userdb_preinit(auth->pool, set->driver, set->args); } -struct auth *auth_preinit(struct auth_settings *set) +struct auth * +auth_preinit(struct auth_settings *set, const struct mechanisms_register *reg) { struct auth_passdb_settings *const *passdbs; struct auth_userdb_settings *const *userdbs; @@ -62,6 +63,7 @@ struct auth *auth_preinit(struct auth_settings *set) auth = p_new(pool, struct auth, 1); auth->pool = pool; auth->set = set; + auth->reg = reg; if (array_is_created(&set->passdbs)) passdbs = array_get(&set->passdbs, &db_count); @@ -108,46 +110,6 @@ struct auth *auth_preinit(struct auth_settings *set) return auth; } -const string_t *auth_mechanisms_get_list(struct auth *auth) -{ - struct mech_module_list *list; - string_t *str; - - str = t_str_new(128); - for (list = auth->mech_modules; list != NULL; list = list->next) - str_append(str, list->module.mech_name); - - return str; -} - -static void auth_mech_register(struct auth *auth, const struct mech_module *mech) -{ - struct mech_module_list *list; - - list = p_new(auth->pool, struct mech_module_list, 1); - list->module = *mech; - - str_printfa(auth->mech_handshake, "MECH\t%s", mech->mech_name); - if ((mech->flags & MECH_SEC_PRIVATE) != 0) - str_append(auth->mech_handshake, "\tprivate"); - if ((mech->flags & MECH_SEC_ANONYMOUS) != 0) - str_append(auth->mech_handshake, "\tanonymous"); - if ((mech->flags & MECH_SEC_PLAINTEXT) != 0) - str_append(auth->mech_handshake, "\tplaintext"); - if ((mech->flags & MECH_SEC_DICTIONARY) != 0) - str_append(auth->mech_handshake, "\tdictionary"); - if ((mech->flags & MECH_SEC_ACTIVE) != 0) - str_append(auth->mech_handshake, "\tactive"); - if ((mech->flags & MECH_SEC_FORWARD_SECRECY) != 0) - str_append(auth->mech_handshake, "\tforward-secrecy"); - if ((mech->flags & MECH_SEC_MUTUAL_AUTH) != 0) - str_append(auth->mech_handshake, "\tmutual-auth"); - str_append_c(auth->mech_handshake, '\n'); - - list->next = auth->mech_modules; - auth->mech_modules = list; -} - static bool auth_passdb_list_have_verify_plain(struct auth *auth) { struct auth_passdb *passdb; @@ -210,7 +172,7 @@ static void auth_mech_list_verify_passdb(struct auth *auth) { struct mech_module_list *list; - for (list = auth->mech_modules; list != NULL; list = list->next) { + for (list = auth->reg->modules; list != NULL; list = list->next) { if (!auth_mech_verify_passdb(auth, list)) break; } @@ -230,8 +192,6 @@ void auth_init(struct auth *auth) { struct auth_passdb *passdb; struct auth_userdb *userdb; - const struct mech_module *mech; - const char *const *mechanisms; for (passdb = auth->masterdbs; passdb != NULL; passdb = passdb->next) passdb_init(passdb->passdb); @@ -244,29 +204,6 @@ void auth_init(struct auth *auth) if (!worker) passdb_cache_init(auth->set); - auth->mech_handshake = str_new(auth->pool, 512); - - /* register wanted mechanisms */ - mechanisms = t_strsplit_spaces(auth->set->mechanisms, " "); - while (*mechanisms != NULL) { - if (strcasecmp(*mechanisms, "ANONYMOUS") == 0) { - if (*auth->set->anonymous_username == '\0') { - i_fatal("ANONYMOUS listed in mechanisms, " - "but anonymous_username not set"); - } - } - mech = mech_module_find(*mechanisms); - if (mech == NULL) { - i_fatal("Unknown authentication mechanism '%s'", - *mechanisms); - } - auth_mech_register(auth, mech); - - mechanisms++; - } - - if (auth->mech_modules == NULL) - i_fatal("No authentication mechanisms configured"); auth_mech_list_verify_passdb(auth); } diff --git a/src/auth/auth.h b/src/auth/auth.h index c7497c17fc..14128394ee 100644 --- a/src/auth/auth.h +++ b/src/auth/auth.h @@ -23,17 +23,14 @@ struct auth { pool_t pool; const struct auth_settings *set; - struct mech_module_list *mech_modules; - buffer_t *mech_handshake; - + const struct mechanisms_register *reg; struct auth_passdb *masterdbs; struct auth_passdb *passdbs; struct auth_userdb *userdbs; }; -const string_t *auth_mechanisms_get_list(struct auth *auth); - -struct auth *auth_preinit(struct auth_settings *set); +struct auth * +auth_preinit(struct auth_settings *set, const struct mechanisms_register *reg); void auth_init(struct auth *auth); void auth_deinit(struct auth **auth); diff --git a/src/auth/main.c b/src/auth/main.c index 24833c8b65..4decdf4b19 100644 --- a/src/auth/main.c +++ b/src/auth/main.c @@ -39,6 +39,7 @@ struct auth_penalty *auth_penalty; static struct module *modules = NULL; static struct auth *auth; +static struct mechanisms_register *mech_reg; static ARRAY_DEFINE(listen_fd_types, enum auth_socket_type); static void main_preinit(void) @@ -65,7 +66,9 @@ static void main_preinit(void) modules = module_dir_load(AUTH_MODULE_DIR, NULL, &mod_set); module_dir_init(modules); - auth = auth_preinit(global_auth_settings); + mech_init(global_auth_settings); + mech_reg = mech_register_init(global_auth_settings); + auth = auth_preinit(global_auth_settings, mech_reg); auth_penalty = auth_penalty_init(AUTH_PENALTY_ANVIL_PATH); /* Password lookups etc. may require roots, allow it. */ @@ -84,7 +87,6 @@ static void main_init(void) lib_signals_ignore(SIGUSR2, TRUE); child_wait_init(); - mech_init(auth->set); password_schemes_init(); auth_worker_server_init(); auth_init(auth); @@ -112,6 +114,7 @@ static void main_deinit(void) mech_deinit(auth->set); auth_deinit(&auth); + mech_register_deinit(&mech_reg); auth_penalty_deinit(&auth_penalty); /* allow modules to unregister their dbs/drivers/etc. before freeing diff --git a/src/auth/mech.c b/src/auth/mech.c index a3b0c726c9..bbcff3bd68 100644 --- a/src/auth/mech.c +++ b/src/auth/mech.c @@ -83,6 +83,78 @@ extern const struct mech_module mech_gssapi_spnego; extern const struct mech_module mech_winbind_ntlm; extern const struct mech_module mech_winbind_spnego; +static void mech_register_add(struct mechanisms_register *reg, + const struct mech_module *mech) +{ + struct mech_module_list *list; + + list = p_new(reg->pool, struct mech_module_list, 1); + list->module = *mech; + + str_printfa(reg->handshake, "MECH\t%s", mech->mech_name); + if ((mech->flags & MECH_SEC_PRIVATE) != 0) + str_append(reg->handshake, "\tprivate"); + if ((mech->flags & MECH_SEC_ANONYMOUS) != 0) + str_append(reg->handshake, "\tanonymous"); + if ((mech->flags & MECH_SEC_PLAINTEXT) != 0) + str_append(reg->handshake, "\tplaintext"); + if ((mech->flags & MECH_SEC_DICTIONARY) != 0) + str_append(reg->handshake, "\tdictionary"); + if ((mech->flags & MECH_SEC_ACTIVE) != 0) + str_append(reg->handshake, "\tactive"); + if ((mech->flags & MECH_SEC_FORWARD_SECRECY) != 0) + str_append(reg->handshake, "\tforward-secrecy"); + if ((mech->flags & MECH_SEC_MUTUAL_AUTH) != 0) + str_append(reg->handshake, "\tmutual-auth"); + str_append_c(reg->handshake, '\n'); + + list->next = reg->modules; + reg->modules = list; +} + +struct mechanisms_register * +mech_register_init(const struct auth_settings *set) +{ + struct mechanisms_register *reg; + const struct mech_module *mech; + const char *const *mechanisms; + pool_t pool; + + pool = pool_alloconly_create("mechanisms register", 1024); + reg = p_new(pool, struct mechanisms_register, 1); + reg->pool = pool; + reg->set = set; + reg->handshake = str_new(pool, 512); + + mechanisms = t_strsplit_spaces(set->mechanisms, " "); + for (; *mechanisms != NULL; mechanisms++) { + if (strcasecmp(*mechanisms, "ANONYMOUS") == 0) { + if (*set->anonymous_username == '\0') { + i_fatal("ANONYMOUS listed in mechanisms, " + "but anonymous_username not set"); + } + } + mech = mech_module_find(*mechanisms); + if (mech == NULL) { + i_fatal("Unknown authentication mechanism '%s'", + *mechanisms); + } + mech_register_add(reg, mech); + } + + if (reg->modules == NULL) + i_fatal("No authentication mechanisms configured"); + return reg; +} + +void mech_register_deinit(struct mechanisms_register **_reg) +{ + struct mechanisms_register *reg = *_reg; + + *_reg = NULL; + pool_unref(®->pool); +} + void mech_init(const struct auth_settings *set) { mech_register_module(&mech_plain); diff --git a/src/auth/mech.h b/src/auth/mech.h index b86b6f3036..b8bb416291 100644 --- a/src/auth/mech.h +++ b/src/auth/mech.h @@ -56,6 +56,14 @@ struct mech_module_list { struct mech_module module; }; +struct mechanisms_register { + pool_t pool; + const struct auth_settings *set; + + struct mech_module_list *modules; + buffer_t *handshake; +}; + void mech_register_module(const struct mech_module *module); void mech_unregister_module(const struct mech_module *module); const struct mech_module *mech_module_find(const char *name); @@ -64,6 +72,10 @@ void mech_generic_auth_initial(struct auth_request *request, const unsigned char *data, size_t data_size); void mech_generic_auth_free(struct auth_request *request); +struct mechanisms_register * +mech_register_init(const struct auth_settings *set); +void mech_register_deinit(struct mechanisms_register **reg); + void mech_init(const struct auth_settings *set); void mech_deinit(const struct auth_settings *set);