auth = default
# Space separated list of wanted authentication mechanisms:
-# plain digest-md5
+# plain digest-md5 anonymous
auth_mechanisms = plain
# Space separated list of realms for SASL authentication mechanisms that need
# set this value to empty.
#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
+# Username to use for users logging in with ANONYMOUS SASL mechanism
+#auth_anonymous_username = anonymous
+
# More verbose logging. Useful for figuring out why authentication isn't
# working.
#auth_verbose = no
master-connection.c \
md5crypt.c \
mech.c \
+ mech-anonymous.c \
mech-cyrus-sasl2.c \
mech-plain.c \
mech-digest-md5.c \
enum auth_mech {
AUTH_MECH_PLAIN = 0x01,
AUTH_MECH_DIGEST_MD5 = 0x02,
+ AUTH_MECH_ANONYMOUS = 0x04,
AUTH_MECH_COUNT
};
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 }
+ { AUTH_MECH_DIGEST_MD5, "DIGEST-MD5", FALSE, TRUE },
+ { AUTH_MECH_ANONYMOUS, "ANONYMOUS", FALSE, TRUE }
};
#endif
--- /dev/null
+/* Copyright (C) 2002 Timo Sirainen */
+
+#include "common.h"
+#include "mech.h"
+
+static int
+mech_anonymous_auth_continue(struct auth_request *auth_request,
+ struct auth_login_request_continue *request,
+ const unsigned char *data,
+ mech_callback_t *callback)
+{
+ i_assert(anonymous_username != NULL);
+
+ if (verbose) {
+ i_info("mech-anonymous: login by %s",
+ t_strndup(data, request->data_size));
+ }
+
+ auth_request->callback = callback;
+ auth_request->user = p_strdup(auth_request->pool, anonymous_username);
+ mech_auth_finish(auth_request, NULL, 0, TRUE);
+ return TRUE;
+}
+
+static void
+mech_anonymous_auth_free(struct auth_request *auth_request)
+{
+ pool_unref(auth_request->pool);
+}
+
+static struct auth_request *
+mech_anonymous_auth_new(struct login_connection *conn, unsigned int id,
+ mech_callback_t *callback)
+{
+ struct auth_request *auth_request;
+ struct auth_login_reply reply;
+ pool_t pool;
+
+ pool = pool_alloconly_create("anonymous_auth_request", 256);
+ auth_request = p_new(pool, struct auth_request, 1);
+ auth_request->pool = pool;
+ auth_request->auth_continue = mech_anonymous_auth_continue;
+ auth_request->auth_free = mech_anonymous_auth_free;
+
+ /* initialize reply */
+ memset(&reply, 0, sizeof(reply));
+ reply.id = id;
+ reply.result = AUTH_LOGIN_RESULT_CONTINUE;
+
+ callback(&reply, NULL, conn);
+ return auth_request;
+}
+
+struct mech_module mech_anonymous = {
+ AUTH_MECH_ANONYMOUS,
+ mech_anonymous_auth_new
+};
enum auth_mech auth_mechanisms;
const char *const *auth_realms;
const char *default_realm;
+const char *anonymous_username;
char username_chars[256];
static int set_use_cyrus_sasl;
extern struct mech_module mech_plain;
extern struct mech_module mech_digest_md5;
+extern struct mech_module mech_anonymous;
void mech_init(void)
{
memset(&failure_reply, 0, sizeof(failure_reply));
failure_reply.result = AUTH_LOGIN_RESULT_FAILURE;
+ anonymous_username = getenv("ANONYMOUS_USERNAME");
+ if (anonymous_username != NULL && *anonymous_username == '\0')
+ anonymous_username = NULL;
+
/* register wanted mechanisms */
env = getenv("MECHANISMS");
if (env == NULL || *env == '\0')
mech_register_module(&mech_plain);
else if (strcasecmp(*mechanisms, "DIGEST-MD5") == 0)
mech_register_module(&mech_digest_md5);
- else {
+ else if (strcasecmp(*mechanisms, "ANONYMOUS") == 0) {
+ if (anonymous_username == NULL) {
+ i_fatal("ANONYMOUS listed in mechanisms, "
+ "but anonymous_username not given");
+ }
+ mech_register_module(&mech_anonymous);
+ } else {
i_fatal("Unknown authentication mechanism '%s'",
*mechanisms);
}
}
set_use_cyrus_sasl = getenv("USE_CYRUS_SASL") != NULL;
-
#ifdef USE_CYRUS_SASL2
if (set_use_cyrus_sasl)
mech_cyrus_sasl_init_lib();
{
mech_unregister_module(&mech_plain);
mech_unregister_module(&mech_digest_md5);
+ mech_unregister_module(&mech_anonymous);
}
extern enum auth_mech auth_mechanisms;
extern const char *const *auth_realms;
extern const char *default_realm;
+extern const char *anonymous_username;
extern char username_chars[256];
void mech_register_module(struct mech_module *module);
env_put(t_strconcat("USERDB=", group->set->userdb, NULL));
env_put(t_strconcat("PASSDB=", group->set->passdb, NULL));
env_put(t_strconcat("USERNAME_CHARS=", group->set->username_chars, NULL));
+ env_put(t_strconcat("ANONYMOUS_USERNAME=",
+ group->set->anonymous_username, NULL));
if (group->set->use_cyrus_sasl)
env_put("USE_CYRUS_SASL=1");
DEF(SET_STR, executable),
DEF(SET_STR, user),
DEF(SET_STR, chroot),
+ DEF(SET_STR, username_chars),
+ DEF(SET_STR, anonymous_username),
DEF(SET_BOOL, use_cyrus_sasl),
DEF(SET_BOOL, verbose),
MEMBER(user) "root",
MEMBER(chroot) NULL,
MEMBER(username_chars) "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@",
+ MEMBER(anonymous_username) "anonymous",
MEMBER(use_cyrus_sasl) FALSE,
MEMBER(verbose) FALSE,
const char *user;
const char *chroot;
const char *username_chars;
+ const char *anonymous_username;
int use_cyrus_sasl, verbose;