mech.c revision 63f168d7a6f67842872ebef8d1d3aec3d6b23939
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen#include "common.h"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#include "ioloop.h"
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen#include "buffer.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "hash.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "mech.h"
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen#include "safe-memset.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "str.h"
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen#include "str-sanitize.h"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#include "var-expand.h"
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen#include "auth-client-connection.h"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#include "auth-master-connection.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "passdb.h"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#include "passdb-cache.h"
92c49f3005f4dff1a6f576fffa8112ef6d1cae7fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include <stdlib.h>
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct auth_request_extra {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct auth_request *request;
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen string_t *str;
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen char *user_password, *password;
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen};
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenstruct mech_module_list *mech_modules;
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenbuffer_t *mech_handshake;
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainenconst char *const *auth_realms;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *default_realm;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *anonymous_username;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenchar username_chars[256], username_translation[256];
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenint ssl_require_client_cert;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenstatic buffer_t *auth_failures_buf;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenstatic struct timeout *to_auth_failures;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenvoid mech_register_module(struct mech_module *module)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen{
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen struct mech_module_list *list;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen list = i_new(struct mech_module_list, 1);
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen list->module = *module;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_printfa(mech_handshake, "MECH\t%s", module->mech_name);
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_PRIVATE) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tprivate");
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_ANONYMOUS) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tanonymous");
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_PLAINTEXT) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tplaintext");
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_DICTIONARY) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tdictionary");
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_ACTIVE) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tactive");
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_FORWARD_SECRECY) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tforward-secrecy");
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen if ((module->flags & MECH_SEC_MUTUAL_AUTH) != 0)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen str_append(mech_handshake, "\tmutual-auth");
ed16ab579bd058ec5e2b5d02bb41fdadd9e05b31Timo Sirainen str_append_c(mech_handshake, '\n');
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen list->next = mech_modules;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mech_modules = list;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mech_unregister_module(struct mech_module *module)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mech_module_list **pos, *list;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen for (pos = &mech_modules; *pos != NULL; pos = &(*pos)->next) {
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen if (strcmp((*pos)->module.mech_name, module->mech_name) == 0) {
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen list = *pos;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen *pos = (*pos)->next;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen i_free(list);
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen break;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenconst string_t *auth_mechanisms_get_list(void)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen{
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen struct mech_module_list *list;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen string_t *str;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen str = t_str_new(128);
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen for (list = mech_modules; list != NULL; list = list->next)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen str_append(str, list->module.mech_name);
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen return str;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen}
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenstruct mech_module *mech_module_find(const char *name)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen{
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen struct mech_module_list *list;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen for (list = mech_modules; list != NULL; list = list->next) {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen if (strcasecmp(list->module.mech_name, name) == 0)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen return &list->module;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen }
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen return NULL;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen}
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainenstruct auth_request *auth_request_new(struct mech_module *mech)
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen{
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen struct auth_request *request;
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen request = mech->auth_new();
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (request == NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return NULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen request->mech = mech;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen request->created = ioloop_time;
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen return request;
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen}
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainenvoid auth_request_destroy(struct auth_request *request)
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen{
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen i_assert(request->refcount > 0);
4c6ddf2491104f917d00e6900e833e80ea02c7b6Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (request->destroyed)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen request->destroyed = TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (request->conn != NULL) {
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen hash_remove(request->conn->auth_requests,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen POINTER_CAST(request->id));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_request_unref(request);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mech_auth_finish(struct auth_request *request,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const void *data, size_t data_size, int success)
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (!success) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (request->no_failure_delay) {
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* passdb specifically requested to to delay the
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen reply. */
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen request->callback(request, AUTH_CLIENT_RESULT_FAILURE,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen NULL, 0);
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen auth_request_destroy(request);
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen return;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* failure. don't announce it immediately to avoid
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen a) timing attacks, b) flooding */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (auth_failures_buf->used > 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const struct auth_request *const *requests;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen requests = auth_failures_buf->data;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen requests += auth_failures_buf->used/sizeof(*requests)-1;
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen i_assert(*requests != request);
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen buffer_append(auth_failures_buf, &request, sizeof(request));
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* make sure the request isn't found anymore */
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen auth_request_ref(request);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_request_destroy(request);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (request->conn != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen data, data_size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (request->no_login || request->conn == NULL ||
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen AUTH_MASTER_IS_DUMMY(request->conn->master)) {
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen /* we don't have master process, the request is no longer
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen needed */
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen auth_request_destroy(request);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mech_fix_username(char *username, const char **error_r)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned char *p;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (*username == '\0') {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Some PAM plugins go nuts with empty usernames */
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen *error_r = "Empty username";
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen return FALSE;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen }
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (p = (unsigned char *)username; *p != '\0'; p++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (username_translation[*p & 0xff] != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *p = username_translation[*p & 0xff];
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (username_chars[*p & 0xff] == 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *error_r = "Username contains disallowed characters";
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return FALSE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen return TRUE;
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid auth_request_ref(struct auth_request *request)
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen{
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen request->refcount++;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint auth_request_unref(struct auth_request *request)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_assert(request->refcount > 0);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (--request->refcount > 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen request->mech->auth_free(request);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return FALSE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct auth_request_extra *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenauth_request_extra_begin(struct auth_request *request,
05e55893a799de645fc8cd2203d6013f0e0f1b79Timo Sirainen const char *user_password)
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen{
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen struct auth_request_extra *extra;
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen extra = i_new(struct auth_request_extra, 1);
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen extra->request = request;
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen extra->user_password = i_strdup(user_password);
9ddd3d7d8651985e373a6c48e0ddc76b8a4ef1c7Timo Sirainen return extra;
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen}
5d2e7ec2ea725c8a6a63f56b771e746f93e782ecTimo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainenvoid auth_request_extra_next(struct auth_request_extra *extra,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *name, const char *value)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen string_t *str;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_assert(value != NULL);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (strcmp(name, "password") == 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_assert(extra->password == NULL);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen extra->password = i_strdup(value);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen }
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen if (strcmp(name, "nodelay") == 0) {
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen /* don't delay replying to client of the failure */
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen extra->request->no_failure_delay = TRUE;
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen return;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str = extra->str;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (str == NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen extra->str = str = str_new(extra->request->pool, 64);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (strcmp(name, "nologin") == 0) {
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen /* user can't actually login - don't keep this
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen reply for master */
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen extra->request->no_login = TRUE;
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen if (str_len(str) > 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(str, '\t');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(str, name);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen } else if (strcmp(name, "proxy") == 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* we're proxying authentication for this user. send
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen password back if using plaintext authentication. */
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen extra->request->proxy = TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (str_len(str) > 0)
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen str_append_c(str, '\t');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(str, name);
fa02962b74d39e8d74c4c307c0210791b2f0a1caTimo Sirainen } else {
fa02962b74d39e8d74c4c307c0210791b2f0a1caTimo Sirainen if (str_len(str) > 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(str, '\t');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, "%s=%s", name, value);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainenvoid auth_request_extra_finish(struct auth_request_extra *extra,
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen const char *cache_key)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen string_t *str;
b6b7a17731a917958b6479920b3fac5ca991db6aTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (passdb_cache != NULL && cache_key != NULL) {
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen str = t_str_new(64);
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen if (extra->str != NULL)
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen str_append_str(str, extra->str);
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen if (extra->request->no_failure_delay) {
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen if (str_len(str) > 0)
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen str_append_c(str, '\t');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(str, "nodelay");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_cache_insert(passdb_cache, extra->request, cache_key,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen t_strconcat(extra->password == NULL ? "" :
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen extra->password,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_len(str) > 0 ? "\t" : "",
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen str_c(str), NULL));
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (extra->user_password != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (extra->request->proxy) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* we're proxying - send back the password that was
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen sent by user (not the password in passdb). */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen str_printfa(extra->str, "\tpass=%s",
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen extra->user_password);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen safe_memset(extra->user_password, 0,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen strlen(extra->user_password));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(extra->user_password);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen }
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (extra->str != NULL)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen extra->request->extra_fields = str_c(extra->str);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if (extra->password != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen safe_memset(extra->password, 0, strlen(extra->password));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(extra->password);
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen i_free(extra);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic const char *escape_none(const char *str)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen return str;
73f021723bffa0841bbdf371882b463a449f1ea9Timo Sirainen}
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst struct var_expand_table *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenauth_request_get_var_expand_table(const struct auth_request *auth_request,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *(*escape_func)(const char *))
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen{
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen static struct var_expand_table static_tab[] = {
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen { 'u', NULL },
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen { 'n', NULL },
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen { 'd', NULL },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { 's', NULL },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { 'h', NULL },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { 'l', NULL },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { 'r', NULL },
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen { 'p', NULL },
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen { '\0', NULL }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen };
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct var_expand_table *tab;
5da4bfdce070b54ce8dfcd1bf6249798cda86bd6Timo Sirainen
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen if (escape_func == NULL)
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen escape_func = escape_none;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen tab = t_malloc(sizeof(static_tab));
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tab[0].value = escape_func(auth_request->user);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen tab[1].value = escape_func(t_strcut(auth_request->user, '@'));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tab[2].value = strchr(auth_request->user, '@');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (tab[2].value != NULL)
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen tab[2].value = escape_func(tab[2].value+1);
cec3230c9b2a96bac1ea42c69475e8aea4b91eabTimo Sirainen tab[3].value = auth_request->service;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* tab[4] = we have no home dir */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (auth_request->local_ip.family != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tab[5].value = net_ip2addr(&auth_request->local_ip);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (auth_request->remote_ip.family != 0)
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen tab[6].value = net_ip2addr(&auth_request->remote_ip);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen tab[7].value = dec2str(auth_request->conn->pid);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return tab;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *get_log_prefix(const struct auth_request *auth_request)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAX_LOG_USERNAME_LEN 64
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *ip;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen string_t *str;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str = t_str_new(64);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (auth_request->user == NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(str, "?");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_sanitize_append(str, auth_request->user,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAX_LOG_USERNAME_LEN);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ip = net_ip2addr(&auth_request->remote_ip);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (ip != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append_c(str, ',');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(str, ip);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return str_c(str);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid auth_failure_buf_flush(void)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct auth_request **auth_request;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen size_t i, size;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_request = buffer_get_modifyable_data(auth_failures_buf, &size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen size /= sizeof(*auth_request);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (i = 0; i < size; i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (auth_request[i]->conn != NULL) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_request[i]->callback(auth_request[i],
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen AUTH_CLIENT_RESULT_FAILURE,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen NULL, 0);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_request_destroy(auth_request[i]);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen buffer_set_used_size(auth_failures_buf, 0);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void auth_failure_timeout(void *context __attr_unused__)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen auth_failure_buf_flush();
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void mech_list_verify_passdb(struct passdb_module *passdb)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mech_module_list *list;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for (list = mech_modules; list != NULL; list = list->next) {
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen if (list->module.passdb_need_plain &&
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen passdb->verify_plain == NULL)
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen break;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen if (list->module.passdb_need_credentials &&
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen passdb->lookup_credentials == NULL)
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen break;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen }
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen if (list != NULL) {
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen i_fatal("Passdb %s doesn't support %s method",
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen passdb->name, list->module.mech_name);
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen }
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen}
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_plain;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_login;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_apop;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_cram_md5;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_digest_md5;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_ntlm;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_rpa;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenextern struct mech_module mech_anonymous;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenvoid mech_init(void)
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen{
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen const char *const *mechanisms;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen const char *env;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen mech_modules = NULL;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen mech_handshake = str_new(default_pool, 512);
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen anonymous_username = getenv("ANONYMOUS_USERNAME");
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen if (anonymous_username != NULL && *anonymous_username == '\0')
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen anonymous_username = NULL;
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen /* register wanted mechanisms */
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen env = getenv("MECHANISMS");
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen if (env == NULL || *env == '\0')
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen i_fatal("MECHANISMS environment is unset");
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen mechanisms = t_strsplit_spaces(env, " ");
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen while (*mechanisms != NULL) {
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen if (strcasecmp(*mechanisms, "PLAIN") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_plain);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "LOGIN") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_login);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "APOP") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_apop);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "CRAM-MD5") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_cram_md5);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "DIGEST-MD5") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_digest_md5);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "NTLM") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_ntlm);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "RPA") == 0)
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_rpa);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen else if (strcasecmp(*mechanisms, "ANONYMOUS") == 0) {
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen if (anonymous_username == NULL) {
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen i_fatal("ANONYMOUS listed in mechanisms, "
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen "but anonymous_username not given");
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen }
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_register_module(&mech_anonymous);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen } else {
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen i_fatal("Unknown authentication mechanism '%s'",
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen *mechanisms);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen }
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen mechanisms++;
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen }
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen if (mech_modules == NULL)
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen i_fatal("No authentication mechanisms configured");
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen mech_list_verify_passdb(passdb);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen /* get our realm - note that we allocate from data stack so
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen this function should never be called inside I/O loop or anywhere
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen else where t_pop() is called */
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen env = getenv("REALMS");
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen if (env == NULL)
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen env = "";
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen auth_realms = t_strsplit_spaces(env, " ");
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen default_realm = getenv("DEFAULT_REALM");
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen if (default_realm != NULL && *default_realm == '\0')
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen default_realm = NULL;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen env = getenv("USERNAME_CHARS");
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen if (env == NULL || *env == '\0') {
12cf3d0e03fc70fb0c8b91bc8fd83b4e14d7cdefTimo Sirainen /* all chars are allowed */
12cf3d0e03fc70fb0c8b91bc8fd83b4e14d7cdefTimo Sirainen memset(username_chars, 1, sizeof(username_chars));
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen } else {
12cf3d0e03fc70fb0c8b91bc8fd83b4e14d7cdefTimo Sirainen memset(username_chars, 0, sizeof(username_chars));
4e35bae013cee5a06d281776a347b534b958aaa4Timo Sirainen for (; *env != '\0'; env++)
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen username_chars[((unsigned char)*env) & 0xff] = 1;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen env = getenv("USERNAME_TRANSLATION");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen memset(username_translation, 0, sizeof(username_translation));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (env != NULL) {
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen for (; *env != '\0' && env[1] != '\0'; env += 2) {
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen username_translation[((unsigned char)*env) & 0xff] =
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen env[1];
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen
506e41a4efbc7f4bba93cd295ca4dba18ed3cf09Timo Sirainen ssl_require_client_cert = getenv("SSL_REQUIRE_CLIENT_CERT") != NULL;
506e41a4efbc7f4bba93cd295ca4dba18ed3cf09Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen auth_failures_buf = buffer_create_dynamic(default_pool, 1024);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen to_auth_failures = timeout_add(2000, auth_failure_timeout, NULL);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen}
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainenvoid mech_deinit(void)
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen{
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen timeout_remove(to_auth_failures);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_unregister_module(&mech_plain);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_unregister_module(&mech_login);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_unregister_module(&mech_apop);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_unregister_module(&mech_cram_md5);
b5917cf6476ffb7cdeb2e2544057ea1605ea6fdcTimo Sirainen mech_unregister_module(&mech_digest_md5);
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainen mech_unregister_module(&mech_ntlm);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen mech_unregister_module(&mech_rpa);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen mech_unregister_module(&mech_anonymous);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen str_free(mech_handshake);
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen}
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen