Mercurial > dovecot > original-hg > dovecot-1.2
changeset 907:218e68ab290d HEAD
Initial support for Cyrus SASL 2 library. I couldn't get it to work yet
though :)
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 05 Jan 2003 17:19:50 +0200 |
parents | b176f913d092 |
children | bc55266563cd |
files | configure.in src/auth/Makefile.am src/auth/auth-cyrus-sasl2.c src/auth/auth-digest-md5.c src/auth/auth-interface.h src/auth/auth-mech-desc.h src/auth/auth-plain.c src/auth/auth.c src/auth/auth.h src/auth/login-connection.c src/auth/userinfo.c src/login/auth-connection.c src/login/auth-connection.h src/login/client-authenticate.c src/master/auth-process.c src/master/settings.c src/master/settings.h |
diffstat | 17 files changed, 414 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Sun Jan 05 15:19:09 2003 +0200 +++ b/configure.in Sun Jan 05 17:19:50 2003 +0200 @@ -97,6 +97,15 @@ fi, want_vpopmail=yes) +AC_ARG_WITH(cyrus-sasl2, +[ --with-cyrus-sasl2 Build with Cyrus SASL 2 library support], + if test x$withval = xno; then + want_cyrus_sasl2=no + else + want_cyrus_sasl2=yes + fi, + want_cyrus_sasl2=no) + AC_ARG_WITH(rawlog, [ --with-rawlog Build support for logging user traffic], if test x$withval = xyes; then @@ -703,6 +712,18 @@ AC_SUBST(VPOPMAIL_CFLAGS) AC_SUBST(VPOPMAIL_LIBS) +if test $want_cyrus_sasl2 = yes; then + AC_CHECK_LIB(sasl2, sasl_server_start, [ + AC_CHECK_HEADER(sasl/sasl.h, [ + AC_DEFINE(USE_CYRUS_SASL2,, + Define if you want to use Cyrus SASL library) + SASL_LIBS="-lsasl2" + ]) + ]) +fi + +AC_SUBST(SASL_LIBS) + if test $need_crypt = yes; then AC_CHECK_LIB(crypt, crypt, [ USERINFO_LIBS="$USERINFO_LIBS -lcrypt"
--- a/src/auth/Makefile.am Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/Makefile.am Sun Jan 05 17:19:50 2003 +0200 @@ -9,10 +9,12 @@ imap_auth_LDADD = \ ../lib/liblib.a \ $(USERINFO_LIBS) \ + $(SASL_LIBS) \ $(VPOPMAIL_LIBS) imap_auth_SOURCES = \ auth.c \ + auth-cyrus-sasl2.c \ auth-plain.c \ auth-digest-md5.c \ cookie.c \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/auth-cyrus-sasl2.c Sun Jan 05 17:19:50 2003 +0200 @@ -0,0 +1,239 @@ +/* Copyright (C) 2003 Timo Sirainen */ + +#include "common.h" +#include "auth.h" +#include "cookie.h" + +#ifdef USE_CYRUS_SASL2 + +#include <stdlib.h> +#include <sasl/sasl.h> + +#include "auth-mech-desc.h" + +struct auth_context { + sasl_conn_t *conn; + int success; +}; + +static const char *auth_mech_to_str(enum auth_mech mech) +{ + int i; + + for (i = 0; i < AUTH_MECH_COUNT; i++) { + if (auth_mech_desc[i].mech == mech) + return auth_mech_desc[i].name; + } + + return NULL; +} + +static void auth_sasl_continue(struct cookie_data *cookie, + struct auth_continued_request_data *request, + const unsigned char *data, + AuthCallback callback, void *context) +{ + struct auth_context *ctx = cookie->context; + struct auth_reply_data reply; + const char *serverout; + unsigned int serveroutlen; + int ret; + + ret = sasl_server_step(ctx->conn, data, request->data_size, + &serverout, &serveroutlen); + + memset(&reply, 0, sizeof(reply)); + reply.id = request->id; + memcpy(reply.cookie, cookie->cookie, AUTH_COOKIE_SIZE); + + if (ret == SASL_CONTINUE) { + reply.result = AUTH_RESULT_CONTINUE; + } else if (ret == SASL_OK) { + /* success */ + reply.result = AUTH_RESULT_SUCCESS; + ctx->success = TRUE; + } else { + /* failure */ + reply.result = AUTH_RESULT_FAILURE; + cookie_remove(cookie->cookie); + } + + reply.data_size = serveroutlen; + callback(&reply, serverout, context); +} + +static int auth_sasl_fill_reply(struct cookie_data *cookie, + struct auth_cookie_reply_data *reply) +{ + struct auth_context *ctx = cookie->context; + const char *canon_user; + const struct propval *prop; + int ret; + + if (!ctx->success) + return FALSE; + + /* get our username */ + ret = sasl_getprop(ctx->conn, SASL_USERNAME, + (const void **) &canon_user); + if (ret != SASL_OK) { + i_warning("sasl_getprop() failed: %s", + sasl_errstring(ret, NULL, NULL)); + return FALSE; + } + + memset(reply, 0, sizeof(*reply)); + reply->success = TRUE; + + if (strocpy(reply->virtual_user, canon_user, + sizeof(reply->virtual_user)) < 0) + i_panic("virtual_user overflow"); + + /* get other properties */ + prop = prop_get(sasl_auxprop_getctx(ctx->conn)); + for (; prop != NULL && prop->name != NULL; prop++) { + if (prop->nvalues == 0 || prop->values[0] == NULL) + continue; + + if (strcasecmp(prop->name, SASL_AUX_UIDNUM) == 0) + reply->uid = atoi(prop->values[0]); + else if (strcasecmp(prop->name, SASL_AUX_GIDNUM) == 0) + reply->gid = atoi(prop->values[0]); + else if (strcasecmp(prop->name, SASL_AUX_HOMEDIR) == 0) { + if (strocpy(reply->home, prop->values[0], + sizeof(reply->home)) < 0) + i_panic("home overflow"); + } else if (strcasecmp(prop->name, SASL_AUX_UNIXMBX) == 0) { + if (strocpy(reply->mail, prop->values[0], + sizeof(reply->mail)) < 0) + i_panic("mail overflow"); + } + } + + return TRUE; +} + +static void auth_sasl_free(struct cookie_data *cookie) +{ + struct auth_context *ctx = cookie->context; + + sasl_dispose(&ctx->conn); + i_free(ctx); + i_free(cookie); +} + +void auth_cyrus_sasl_init(unsigned int login_pid, + struct auth_init_request_data *request, + AuthCallback callback, void *context) +{ + static const char *propnames[] = { + SASL_AUX_UIDNUM, + SASL_AUX_GIDNUM, + SASL_AUX_HOMEDIR, + SASL_AUX_UNIXMBX, + NULL + }; + struct cookie_data *cookie; + struct auth_reply_data reply; + struct auth_context *ctx; + const char *mech, *serverout; + unsigned int serveroutlen; + sasl_security_properties_t sec_props; + sasl_conn_t *conn; + int ret; + + mech = auth_mech_to_str(request->mech); + if (mech == NULL) + i_fatal("Login asked for unknown mechanism %d", request->mech); + + /* create new SASL connection */ + ret = sasl_server_new("imap", NULL, NULL, NULL, NULL, NULL, 0, &conn); + if (ret != SASL_OK) { + i_fatal("sasl_server_new() failed: %s", + sasl_errstring(ret, NULL, NULL)); + } + + /* don't allow SASL security layer */ + memset(&sec_props, 0, sizeof(sec_props)); + sec_props.min_ssf = 0; + sec_props.max_ssf = 1; + + if (sasl_setprop(conn, SASL_SEC_PROPS, &sec_props) != SASL_OK) { + i_fatal("sasl_setprop(SASL_SEC_PROPS) failed: %s", + sasl_errstring(ret, NULL, NULL)); + } + + ret = sasl_auxprop_request(conn, propnames); + if (ret != SASL_OK) { + i_fatal("sasl_auxprop_request() failed: %s", + sasl_errstring(ret, NULL, NULL)); + } + + /* initialize reply */ + memset(&reply, 0, sizeof(reply)); + reply.id = request->id; + + /* start the exchange */ + ret = sasl_server_start(conn, mech, NULL, 0, &serverout, &serveroutlen); + if (ret != SASL_CONTINUE) { + reply.result = AUTH_RESULT_FAILURE; + serverout = NULL; + serveroutlen = 0; + sasl_dispose(&conn); + } else { + cookie = i_new(struct cookie_data, 1); + cookie->login_pid = login_pid; + cookie->auth_fill_reply = auth_sasl_fill_reply; + cookie->auth_continue = auth_sasl_continue; + cookie->free = auth_sasl_free; + ctx = cookie->context = i_new(struct auth_context, 1); + ctx->conn = conn; + + cookie_add(cookie); + + reply.result = AUTH_RESULT_CONTINUE; + memcpy(reply.cookie, cookie->cookie, AUTH_COOKIE_SIZE); + } + + reply.data_size = serveroutlen; + callback(&reply, serverout, context); +} + +static int sasl_log(void *context __attr_unused__, + int level, const char *message) +{ + switch (level) { + case SASL_LOG_ERR: + i_error("SASL authentication error: %s", message); + break; + case SASL_LOG_WARN: + i_warning("SASL authentication warning: %s", message); + break; + case SASL_LOG_NOTE: + /*i_info("SASL authentication info: %s", message);*/ + break; + case SASL_LOG_FAIL: + /*i_info("SASL authentication failure: %s", message);*/ + break; + } + + return SASL_OK; +} + +static const struct sasl_callback sasl_callbacks[] = { + { SASL_CB_LOG, &sasl_log, NULL }, + { SASL_CB_LIST_END, NULL, NULL } +}; + +void auth_cyrus_sasl_init_lib(void) +{ + int ret; + + ret = sasl_server_init(sasl_callbacks, "imap-auth"); + if (ret != SASL_OK) { + i_fatal("sasl_server_init() failed: %s", + sasl_errstring(ret, NULL, NULL)); + } +} + +#endif
--- a/src/auth/auth-digest-md5.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/auth-digest-md5.c Sun Jan 05 17:19:50 2003 +0200 @@ -548,15 +548,14 @@ reply.result = AUTH_RESULT_CONTINUE; reply.data_size = strlen(auth->rspauth); - callback(&reply, (const unsigned char *) auth->rspauth, - context); + callback(&reply, auth->rspauth, context); auth->authenticated = TRUE; return; } /* failed */ reply.result = AUTH_RESULT_FAILURE; - callback(&reply, (const unsigned char *) error, context); + callback(&reply, error, context); cookie_remove(cookie->cookie); } @@ -614,12 +613,12 @@ challenge = get_digest_challenge(auth); reply.data_size = strlen(challenge); - callback(&reply, (const unsigned char *) challenge, context); + callback(&reply, challenge, context); t_pop(); } struct auth_module auth_digest_md5 = { - AUTH_METHOD_DIGEST_MD5, + AUTH_MECH_DIGEST_MD5, auth_digest_md5_init };
--- a/src/auth/auth-interface.h Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/auth-interface.h Sun Jan 05 17:19:50 2003 +0200 @@ -25,17 +25,17 @@ AUTH_RESULT_FAILURE }; -enum auth_method { - AUTH_METHOD_PLAIN = 0x01, - AUTH_METHOD_DIGEST_MD5 = 0x02, +enum auth_mech { + AUTH_MECH_PLAIN = 0x01, + AUTH_MECH_DIGEST_MD5 = 0x02, - AUTH_METHODS_COUNT = 2 + AUTH_MECH_COUNT = 2 }; /* Initialization reply, sent after client is connected */ struct auth_init_data { unsigned int auth_process; /* unique auth process identifier */ - enum auth_method auth_methods; /* valid authentication methods */ + enum auth_mech auth_mechanisms; /* valid authentication mechanisms */ }; /* Initialization handshake from client. */ @@ -47,7 +47,7 @@ struct auth_init_request_data { enum auth_request_type type; /* AUTH_REQUEST_INIT */ - enum auth_method method; + enum auth_mech mech; unsigned int id; /* AuthReplyData.id will contain this value */ };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/auth/auth-mech-desc.h Sun Jan 05 17:19:50 2003 +0200 @@ -0,0 +1,16 @@ +#ifndef __AUTH_MECH_DESC_H +#define __AUTH_MECH_DESC_H + +struct auth_mech_desc { + enum auth_mech mech; + const char *name; + int plaintext; + int advertise; +}; + +static struct auth_mech_desc auth_mech_desc[AUTH_MECH_COUNT] = { + { AUTH_MECH_PLAIN, "PLAIN", TRUE, FALSE }, + { AUTH_MECH_DIGEST_MD5, "DIGEST-MD5", FALSE, TRUE } +}; + +#endif
--- a/src/auth/auth-plain.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/auth-plain.c Sun Jan 05 17:19:50 2003 +0200 @@ -107,6 +107,6 @@ } struct auth_module auth_plain = { - AUTH_METHOD_PLAIN, + AUTH_MECH_PLAIN, auth_plain_init };
--- a/src/auth/auth.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/auth.c Sun Jan 05 17:19:50 2003 +0200 @@ -12,9 +12,10 @@ struct auth_module module; }; -enum auth_method auth_methods; +enum auth_mech auth_mechanisms; const char *const *auth_realms; +static int set_use_cyrus_sasl; static struct auth_module_list *auth_modules; static struct auth_reply_data failure_reply; @@ -22,9 +23,9 @@ { struct auth_module_list *list; - i_assert((auth_methods & module->method) == 0); + i_assert((auth_mechanisms & module->mech) == 0); - auth_methods |= module->method; + auth_mechanisms |= module->mech; list = i_new(struct auth_module_list, 1); memcpy(&list->module, module, sizeof(struct auth_module)); @@ -37,13 +38,13 @@ { struct auth_module_list **pos, *list; - if ((auth_methods & module->method) == 0) + if ((auth_mechanisms & module->mech) == 0) return; /* not registered */ - auth_methods &= ~module->method; + auth_mechanisms &= ~module->mech; for (pos = &auth_modules; *pos != NULL; pos = &(*pos)->next) { - if ((*pos)->module.method == module->method) { + if ((*pos)->module.mech == module->mech) { list = *pos; *pos = (*pos)->next; i_free(list); @@ -58,23 +59,29 @@ { struct auth_module_list *list; - if ((auth_methods & request->method) == 0) { - /* unsupported method */ + if ((auth_mechanisms & request->mech) == 0) { + /* unsupported mechanism */ i_error("BUG: imap-login requested unsupported " - "auth method %d", request->method); + "auth mechanism %d", request->mech); failure_reply.id = request->id; callback(&failure_reply, NULL, context); return; } +#ifdef USE_CYRUS_SASL2 + if (set_use_cyrus_sasl) { + auth_cyrus_sasl_init(login_pid, request, callback, context); + return; + } +#endif + for (list = auth_modules; list != NULL; list = list->next) { - if (list->module.method == request->method) { + if (list->module.mech == request->mech) { list->module.init(login_pid, request, callback, context); return; } } - i_unreached(); } @@ -103,31 +110,32 @@ void auth_init(void) { - const char *const *methods; + const char *const *mechanisms; const char *env; auth_modules = NULL; - auth_methods = 0; + auth_mechanisms = 0; memset(&failure_reply, 0, sizeof(failure_reply)); failure_reply.result = AUTH_RESULT_FAILURE; - /* register wanted methods */ - env = getenv("METHODS"); + /* register wanted mechanisms */ + env = getenv("MECHANISMS"); if (env == NULL || *env == '\0') - i_fatal("METHODS environment is unset"); + i_fatal("MECHANISMS environment is unset"); - methods = t_strsplit(env, " "); - while (*methods != NULL) { - if (strcasecmp(*methods, "plain") == 0) + mechanisms = t_strsplit(env, " "); + while (*mechanisms != NULL) { + if (strcasecmp(*mechanisms, "PLAIN") == 0) auth_register_module(&auth_plain); - else if (strcasecmp(*methods, "digest-md5") == 0) + else if (strcasecmp(*mechanisms, "DIGEST-MD5") == 0) auth_register_module(&auth_digest_md5); else { - i_fatal("Unknown authentication method '%s'", - *methods); + i_fatal("Unknown authentication mechanism '%s'", + *mechanisms); } - methods++; + + mechanisms++; } /* get our realm - note that we allocate from data stack so @@ -137,6 +145,13 @@ if (env == NULL) env = ""; auth_realms = t_strsplit(env, " "); + + set_use_cyrus_sasl = getenv("USE_CYRUS_SASL") != NULL; + +#ifdef USE_CYRUS_SASL2 + if (set_use_cyrus_sasl) + auth_cyrus_sasl_init_lib(); +#endif } void auth_deinit(void)
--- a/src/auth/auth.h Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/auth.h Sun Jan 05 17:19:50 2003 +0200 @@ -4,17 +4,17 @@ #include "auth-interface.h" typedef void (*AuthCallback)(struct auth_reply_data *reply, - const unsigned char *data, void *context); + const void *data, void *context); struct auth_module { - enum auth_method method; + enum auth_mech mech; void (*init)(unsigned int login_pid, struct auth_init_request_data *request, AuthCallback callback, void *context); }; -extern enum auth_method auth_methods; +extern enum auth_mech auth_mechanisms; extern const char *const *auth_realms; void auth_register_module(struct auth_module *module); @@ -28,6 +28,11 @@ const unsigned char *data, AuthCallback callback, void *context); +void auth_cyrus_sasl_init_lib(void); +void auth_cyrus_sasl_init(unsigned int login_pid, + struct auth_init_request_data *request, + AuthCallback callback, void *context); + void auth_init(void); void auth_deinit(void);
--- a/src/auth/login-connection.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/login-connection.c Sun Jan 05 17:19:50 2003 +0200 @@ -34,7 +34,7 @@ static struct login_connection *connections; static void request_callback(struct auth_reply_data *reply, - const unsigned char *data, void *context) + const void *data, void *context) { struct login_connection *conn = context; @@ -226,7 +226,7 @@ memset(&auth_init_data, 0, sizeof(auth_init_data)); auth_init_data.auth_process = atoi(env); - auth_init_data.auth_methods = auth_methods; + auth_init_data.auth_mechanisms = auth_mechanisms; connections = NULL; }
--- a/src/auth/userinfo.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/auth/userinfo.c Sun Jan 05 17:19:50 2003 +0200 @@ -49,10 +49,10 @@ userinfo->init(args); } - if ((auth_methods & AUTH_METHOD_PLAIN) && + if ((auth_mechanisms & AUTH_MECH_PLAIN) && userinfo->verify_plain == NULL) i_fatal("Userinfo %s doesn't support PLAIN method", name); - if ((auth_methods & AUTH_METHOD_DIGEST_MD5) && + if ((auth_mechanisms & AUTH_MECH_DIGEST_MD5) && userinfo->lookup_digest_md5 == NULL) i_fatal("Userinfo %s doesn't support DIGEST-MD5 method", name); }
--- a/src/login/auth-connection.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/login/auth-connection.c Sun Jan 05 17:19:50 2003 +0200 @@ -27,7 +27,7 @@ struct ostream *output; unsigned int auth_process; - enum auth_method available_auth_methods; + enum auth_mech available_auth_mechs; struct auth_reply_data in_reply; struct hash_table *requests; @@ -36,7 +36,7 @@ unsigned int in_reply_received:1; }; -enum auth_method available_auth_methods; +enum auth_mech available_auth_mechs; static int auth_reconnect; static unsigned int request_id_counter; @@ -140,14 +140,14 @@ } static struct auth_connection * -auth_connection_get(enum auth_method method, size_t size, const char **error) +auth_connection_get(enum auth_mech mech, size_t size, const char **error) { struct auth_connection *conn; int found; found = FALSE; for (conn = auth_connections; conn != NULL; conn = conn->next) { - if ((conn->available_auth_methods & method)) { + if ((conn->available_auth_mechs & mech)) { if (o_stream_have_space(conn->output, size) > 0) return conn; @@ -156,8 +156,8 @@ } if (!found) { - if ((available_auth_methods & method) == 0) - *error = "Unsupported authentication method"; + if ((available_auth_mechs & mech) == 0) + *error = "Unsupported authentication mechanism"; else { *error = "Authentication server isn't connected, " "try again later.."; @@ -171,23 +171,23 @@ return NULL; } -static void update_available_auth_methods(void) +static void update_available_auth_mechs(void) { struct auth_connection *conn; - available_auth_methods = 0; + available_auth_mechs = 0; for (conn = auth_connections; conn != NULL; conn = conn->next) - available_auth_methods |= conn->available_auth_methods; + available_auth_mechs |= conn->available_auth_mechs; } static void auth_handle_init(struct auth_connection *conn, struct auth_init_data *init_data) { conn->auth_process = init_data->auth_process; - conn->available_auth_methods = init_data->auth_methods; + conn->available_auth_mechs = init_data->auth_mechanisms; conn->init_received = TRUE; - update_available_auth_methods(); + update_available_auth_mechs(); } static void auth_handle_reply(struct auth_connection *conn, @@ -281,7 +281,7 @@ i_stream_skip(conn->input, conn->in_reply.data_size); } -int auth_init_request(enum auth_method method, AuthCallback callback, +int auth_init_request(enum auth_mech mech, AuthCallback callback, void *context, const char **error) { struct auth_connection *conn; @@ -291,13 +291,13 @@ if (auth_reconnect) auth_connect_missing(); - conn = auth_connection_get(method, sizeof(request_data), error); + conn = auth_connection_get(mech, sizeof(request_data), error); if (conn == NULL) return FALSE; /* create internal request structure */ request = i_new(struct auth_request, 1); - request->method = method; + request->mech = mech; request->conn = conn; request->id = ++request_id_counter; request->callback = callback; @@ -307,7 +307,7 @@ /* send request to auth */ request_data.type = AUTH_REQUEST_INIT; - request_data.method = request->method; + request_data.mech = request->mech; request_data.id = request->id; if (o_stream_send(request->conn->output, &request_data, sizeof(request_data)) < 0)
--- a/src/login/auth-connection.h Sun Jan 05 15:19:09 2003 +0200 +++ b/src/login/auth-connection.h Sun Jan 05 17:19:50 2003 +0200 @@ -11,7 +11,7 @@ size_t reply_data_size, void *context); struct auth_request { - enum auth_method method; + enum auth_mech mech; struct auth_connection *conn; unsigned int id; @@ -23,9 +23,9 @@ unsigned int init_sent:1; }; -extern enum auth_method available_auth_methods; +extern enum auth_mech available_auth_mechs; -int auth_init_request(enum auth_method method, AuthCallback callback, +int auth_init_request(enum auth_mech mech, AuthCallback callback, void *context, const char **error); void auth_continue_request(struct auth_request *request,
--- a/src/login/client-authenticate.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/login/client-authenticate.c Sun Jan 05 17:19:50 2003 +0200 @@ -9,58 +9,48 @@ #include "safe-memset.h" #include "str.h" #include "auth-connection.h" +#include "../auth/auth-mech-desc.h" #include "client.h" #include "client-authenticate.h" #include "master.h" -struct auth_method_desc { - int method; - const char *name; - int plaintext; -}; - -static enum auth_method auth_methods = 0; -static char *auth_methods_capability = NULL; - -static struct auth_method_desc auth_method_desc[AUTH_METHODS_COUNT] = { - { AUTH_METHOD_PLAIN, NULL, TRUE }, - { AUTH_METHOD_DIGEST_MD5, "DIGEST-MD5", FALSE } -}; +static enum auth_mech auth_mechs = 0; +static char *auth_mechs_capability = NULL; const char *client_authenticate_get_capabilities(void) { string_t *str; int i; - if (auth_methods == available_auth_methods) - return auth_methods_capability; + if (auth_mechs == available_auth_mechs) + return auth_mechs_capability; - auth_methods = available_auth_methods; - i_free(auth_methods_capability); + auth_mechs = available_auth_mechs; + i_free(auth_mechs_capability); str = t_str_new(128); - for (i = 0; i < AUTH_METHODS_COUNT; i++) { - if ((auth_methods & auth_method_desc[i].method) && - auth_method_desc[i].name != NULL) { + for (i = 0; i < AUTH_MECH_COUNT; i++) { + if ((auth_mechs & auth_mech_desc[i].mech) && + auth_mech_desc[i].name != NULL) { str_append_c(str, ' '); str_append(str, "AUTH="); - str_append(str, auth_method_desc[i].name); + str_append(str, auth_mech_desc[i].name); } } - auth_methods_capability = i_strdup_empty(str_c(str)); - return auth_methods_capability; + auth_mechs_capability = i_strdup_empty(str_c(str)); + return auth_mechs_capability; } -static struct auth_method_desc *auth_method_find(const char *name) +static struct auth_mech_desc *auth_mech_find(const char *name) { int i; - for (i = 0; i < AUTH_METHODS_COUNT; i++) { - if (auth_method_desc[i].name != NULL && - strcasecmp(auth_method_desc[i].name, name) == 0) - return &auth_method_desc[i]; + for (i = 0; i < AUTH_MECH_COUNT; i++) { + if (auth_mech_desc[i].name != NULL && + strcasecmp(auth_mech_desc[i].name, name) == 0) + return &auth_mech_desc[i]; } return NULL; @@ -202,8 +192,8 @@ buffer_append(client->plain_login, pass, strlen(pass)); client_ref(client); - if (auth_init_request(AUTH_METHOD_PLAIN, - login_callback, client, &error)) { + if (auth_init_request(AUTH_MECH_PLAIN, login_callback, + client, &error)) { /* don't read any input from client until login is finished */ if (client->io != NULL) { io_remove(client->io); @@ -273,29 +263,29 @@ safe_memset(buffer_free_without_data(buf), 0, bufsize); } -int cmd_authenticate(struct client *client, const char *method_name) +int cmd_authenticate(struct client *client, const char *mech_name) { - struct auth_method_desc *method; + struct auth_mech_desc *mech; const char *error; - if (*method_name == '\0') + if (*mech_name == '\0') return FALSE; - method = auth_method_find(method_name); - if (method == NULL) { + mech = auth_mech_find(mech_name); + if (mech == NULL) { client_send_tagline(client, - "NO Unsupported authentication method."); + "NO Unsupported authentication mechanism."); return TRUE; } - if (!client->tls && method->plaintext && disable_plaintext_auth) { + if (!client->tls && mech->plaintext && disable_plaintext_auth) { client_send_tagline(client, "NO Plaintext authentication disabled."); return TRUE; } client_ref(client); - if (auth_init_request(method->method, authenticate_callback, + if (auth_init_request(mech->mech, authenticate_callback, client, &error)) { /* following input data will go to authentication */ if (client->io != NULL)
--- a/src/master/auth-process.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/master/auth-process.c Sun Jan 05 17:19:50 2003 +0200 @@ -254,11 +254,13 @@ /* set other environment */ env_put(t_strconcat("AUTH_PROCESS=", dec2str(getpid()), NULL)); - env_put(t_strconcat("METHODS=", config->methods, NULL)); + env_put(t_strconcat("MECHANISMS=", config->mechanisms, NULL)); env_put(t_strconcat("REALMS=", config->realms, NULL)); env_put(t_strconcat("USERINFO=", config->userinfo, NULL)); - env_put(t_strconcat("USERINFO_ARGS=", config->userinfo_args, - NULL)); + env_put(t_strconcat("USERINFO_ARGS=", config->userinfo_args, NULL)); + + if (config->use_cyrus_sasl) + env_put("USE_CYRUS_SASL=1"); restrict_process_size(config->process_size);
--- a/src/master/settings.c Sun Jan 05 15:19:09 2003 +0200 +++ b/src/master/settings.c Sun Jan 05 17:19:50 2003 +0200 @@ -170,6 +170,18 @@ set_login_gid = pw->pw_gid; } +static const char *get_bool(const char *value, int *result) +{ + if (strcasecmp(value, "yes") == 0) + *result = TRUE; + else if (strcasecmp(value, "no") == 0) + *result = FALSE; + else + return t_strconcat("Invalid boolean: ", value, NULL); + + return NULL; +} + static void auth_settings_verify(void) { struct auth_config *auth; @@ -328,7 +340,7 @@ static void auth_config_free(struct auth_config *auth) { i_free(auth->name); - i_free(auth->methods); + i_free(auth->mechanisms); i_free(auth->realms); i_free(auth->userinfo); i_free(auth->userinfo_args); @@ -366,8 +378,10 @@ return "Authentication process name not defined yet"; /* check the easy string values first */ - if (strcmp(key, "auth_methods") == 0) - ptr = &auth->methods; + if (strcmp(key, "auth_mechanisms") == 0) + ptr = &auth->mechanisms; + else if (strcmp(key, "auth_methods") == 0) /* backwards compatibility */ + ptr = &auth->mechanisms; else if (strcmp(key, "auth_realms") == 0) ptr = &auth->realms; else if (strcmp(key, "auth_executable") == 0) @@ -400,6 +414,9 @@ return NULL; } + if (strcmp(key, "auth_cyrus_sasl") == 0) + return get_bool(value, &auth->use_cyrus_sasl); + if (strcmp(key, "auth_count") == 0) { int num; @@ -445,14 +462,7 @@ value, NULL); break; case SET_BOOL: - if (strcasecmp(value, "yes") == 0) - *((int *) set->ptr) = TRUE; - else if (strcasecmp(value, "no") == 0) - *((int *) set->ptr) = FALSE; - else - return t_strconcat("Invalid boolean: ", - value, NULL); - break; + return get_bool(value, set->ptr); } return NULL; }
--- a/src/master/settings.h Sun Jan 05 15:19:09 2003 +0200 +++ b/src/master/settings.h Sun Jan 05 17:19:50 2003 +0200 @@ -64,13 +64,15 @@ struct auth_config *next; char *name; - char *methods; + char *mechanisms; char *realms; char *userinfo, *userinfo_args; char *executable; char *user; char *chroot; + int use_cyrus_sasl; + unsigned int count; unsigned int process_size; };