sasl-server.c revision b6fbc235f981b10333403e2fd6d333fd351c7a3c
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "login-common.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "str.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "base64.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "hex-binary.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "istream.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "write-full.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "strescape.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "str-sanitize.h"
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#include "anvil-client.h"
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen#include "auth-client.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "ssl-proxy.h"
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen#include "master-service.h"
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen#include "master-service-ssl-settings.h"
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen#include "master-interface.h"
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen#include "master-auth.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include "client-common.h"
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#include <unistd.h>
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen#define ERR_TOO_MANY_USERIP_CONNECTIONS \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen "Maximum number of connections from user+IP exceeded " \
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen "(mail_max_userip_connections=%u)"
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainenstruct anvil_request {
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen struct client *client;
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen unsigned int auth_pid, auth_id;
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen unsigned char cookie[MASTER_AUTH_COOKIE_SIZE];
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst struct auth_mech_desc *
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainensasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r)
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen{
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen const struct auth_mech_desc *mech;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct auth_mech_desc *ret_mech;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen unsigned int i, j, count;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mech = auth_client_get_available_mechs(auth_client, &count);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (count == 0 || (!client->secured &&
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen strcmp(client->ssl_set->ssl, "required") == 0)) {
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen *count_r = 0;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen return NULL;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret_mech = t_new(struct auth_mech_desc, count);
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen for (i = j = 0; i < count; i++) {
03739a8eaad2d8b34b9d87dbbe5b13c5d5dfa11aTimo Sirainen /* a) transport is secured
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen b) auth mechanism isn't plaintext
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen c) we allow insecure authentication
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen */
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen if ((mech[i].flags & MECH_SEC_PRIVATE) == 0 &&
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen (client->secured || !client->set->disable_plaintext_auth ||
ff7257145f317d6ca44a9402427bb74c34b999a9Timo Sirainen (mech[i].flags & MECH_SEC_PLAINTEXT) == 0))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret_mech[j++] = mech[i];
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *count_r = j;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen return ret_mech;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen}
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainenstatic enum auth_request_flags
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainenclient_get_auth_flags(struct client *client)
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen{
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen enum auth_request_flags auth_flags = 0;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen if (client->ssl_proxy != NULL &&
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen ssl_proxy_has_valid_client_cert(client->ssl_proxy))
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen auth_flags |= AUTH_REQUEST_FLAG_VALID_CLIENT_CERT;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen if (client->secured)
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen auth_flags |= AUTH_REQUEST_FLAG_SECURED;
1457d943dc2e8485d8994de14ff0115b1f67b672Timo Sirainen if (login_binary->sasl_support_final_reply)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen auth_flags |= AUTH_REQUEST_FLAG_SUPPORT_FINAL_RESP;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen return auth_flags;
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen}
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainen
c3b36993785d9567a63bdad1933031060c9460cfTimo Sirainenstatic void ATTR_NULL(3, 4)
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainencall_client_callback(struct client *client, enum sasl_server_reply reply,
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen const char *data, const char *const *args)
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen{
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen sasl_server_callback_t *sasl_callback;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(reply != SASL_SERVER_REPLY_CONTINUE);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sasl_callback = client->sasl_callback;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen client->sasl_callback = NULL;
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sasl_callback(client, reply, data, args);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* NOTE: client may be destroyed now */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmaster_auth_callback(const struct master_auth_reply *reply, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct client *client = context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum sasl_server_reply sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *data = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->master_tag = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->authenticating = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (reply != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen switch (reply->status) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case MASTER_AUTH_STATUS_OK:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sasl_reply = SASL_SERVER_REPLY_SUCCESS;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case MASTER_AUTH_STATUS_INTERNAL_ERROR:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen break;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen client->mail_pid = reply->mail_pid;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen } else {
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen auth_client_send_cancel(auth_client, client->master_auth_id);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen }
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen call_client_callback(client, sasl_reply, data, NULL);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen}
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainenstatic void master_send_request(struct anvil_request *anvil_request)
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen{
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct client *client = anvil_request->client;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct master_auth_request_params params;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen struct master_auth_request req;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const unsigned char *data;
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen size_t size;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen buffer_t *buf;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char *session_id = client_get_session_id(client);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen i_zero(&req);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen req.auth_pid = anvil_request->auth_pid;
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen req.auth_id = anvil_request->auth_id;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen req.local_ip = client->local_ip;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen req.remote_ip = client->ip;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen req.client_pid = getpid();
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen if (client->ssl_proxy != NULL &&
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen ssl_proxy_get_compression(client->ssl_proxy) != NULL)
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen req.flags |= MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen memcpy(req.cookie, anvil_request->cookie, sizeof(req.cookie));
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(), 256);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* session ID */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen buffer_append(buf, session_id, strlen(session_id)+1);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen /* protocol specific data (e.g. IMAP tag) */
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen buffer_append(buf, client->master_data_prefix,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen client->master_data_prefix_len);
4c8b1c4aa0582c6ca43a4d1cbd210741e7fff952Timo Sirainen /* buffered client input */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen data = i_stream_get_data(client->input, &size);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen buffer_append(buf, data, size);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen req.data_size = buf->used;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen client->auth_finished = ioloop_time;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client->master_auth_id = req.auth_id;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen i_zero(&params);
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen params.client_fd = client->fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen params.socket_path = client->postlogin_socket_path;
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen params.request = req;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen params.data = buf->data;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen master_auth_request_full(master_auth, &params, master_auth_callback,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client, &client->master_tag);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen}
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void ATTR_NULL(1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenanvil_lookup_callback(const char *reply, void *context)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct anvil_request *req = context;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen struct client *client = req->client;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct login_settings *set = client->set;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen const char *errmsg;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int conn_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen conn_count = 0;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen if (reply != NULL && str_to_uint(reply, &conn_count) < 0)
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen i_fatal("Received invalid reply from anvil: %s", reply);
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen /* reply=NULL if we didn't need to do anvil lookup,
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen or if the anvil lookup failed. allow failed anvil lookups in. */
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen if (reply == NULL || conn_count < set->mail_max_userip_connections)
06fb99af33bd380b382d2d4f2994cf9a5bf0bbaeTimo Sirainen master_send_request(req);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen client->authenticating = FALSE;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen auth_client_send_cancel(auth_client, req->auth_id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen errmsg = t_strdup_printf(ERR_TOO_MANY_USERIP_CONNECTIONS,
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen set->mail_max_userip_connections);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen call_client_callback(client, SASL_SERVER_REPLY_MASTER_FAILED,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen errmsg, NULL);
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen }
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen i_free(req);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenstatic void
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainenanvil_check_too_many_connections(struct client *client,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct auth_client_request *request)
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen{
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen struct anvil_request *req;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen const char *query, *cookie;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen buffer_t buf;
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen req = i_new(struct anvil_request, 1);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen req->client = client;
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen req->auth_pid = auth_client_request_get_server_pid(request);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen req->auth_id = auth_client_request_get_id(request);
5529671faac3c5672a948be93091056736c7afffTimo Sirainen
5529671faac3c5672a948be93091056736c7afffTimo Sirainen buffer_create_from_data(&buf, req->cookie, sizeof(req->cookie));
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen cookie = auth_client_request_get_cookie(request);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen if (strlen(cookie) == MASTER_AUTH_COOKIE_SIZE*2)
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen (void)hex_to_binary(cookie, &buf);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (client->virtual_user == NULL ||
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen client->set->mail_max_userip_connections == 0) {
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen anvil_lookup_callback(NULL, req);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen query = t_strconcat("LOOKUP\t", login_binary->protocol, "/",
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen net_ip2addr(&client->ip), "/",
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen str_tabescape(client->virtual_user), NULL);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen anvil_client_query(anvil, query, anvil_lookup_callback, req);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen}
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainenstatic void
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainenauthenticate_callback(struct auth_client_request *request,
8afec4d1a32b78f540257a27769b372aad753384Timo Sirainen enum auth_request_status status, const char *data_base64,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen const char *const *args, void *context)
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen{
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen struct client *client = context;
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen unsigned int i;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen bool nologin;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (!client->authenticating) {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* client aborted */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(status < 0);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen client->auth_waiting = FALSE;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen i_assert(client->auth_request == request);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen switch (status) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case AUTH_REQUEST_STATUS_CONTINUE:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* continue */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->sasl_callback(client, SASL_SERVER_REPLY_CONTINUE,
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen data_base64, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case AUTH_REQUEST_STATUS_OK:
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen client->auth_request = NULL;
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen client->auth_successes++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->auth_passdb_args = p_strarray_dup(client->pool, args);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen client->postlogin_socket_path = NULL;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen nologin = FALSE;
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen for (i = 0; args[i] != NULL; i++) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen if (strncmp(args[i], "user=", 5) == 0) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen i_free(client->virtual_user);
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen i_free_and_null(client->virtual_user_orig);
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen i_free_and_null(client->virtual_auth_user);
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen client->virtual_user = i_strdup(args[i] + 5);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (strncmp(args[i], "original_user=", 14) == 0) {
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen i_free(client->virtual_user_orig);
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen client->virtual_user_orig = i_strdup(args[i] + 14);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (strncmp(args[i], "auth_user=", 10) == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(client->virtual_auth_user);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->virtual_auth_user =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_strdup(args[i] + 10);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen } else if (strncmp(args[i], "postlogin_socket=", 17) == 0) {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen client->postlogin_socket_path =
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen p_strdup(client->pool, args[i] + 17);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen } else if (strcmp(args[i], "nologin") == 0 ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen strcmp(args[i], "proxy") == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* user can't login */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen nologin = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (strncmp(args[i], "resp=", 5) == 0 &&
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen login_binary->sasl_support_final_reply) {
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen client->sasl_final_resp =
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen p_strdup(client->pool, args[i] + 5);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if (nologin) {
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen client->authenticating = FALSE;
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen call_client_callback(client, SASL_SERVER_REPLY_SUCCESS,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen NULL, args);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen anvil_check_too_many_connections(client, request);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case AUTH_REQUEST_STATUS_INTERNAL_FAIL:
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->auth_process_comm_fail = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* fall through */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen case AUTH_REQUEST_STATUS_FAIL:
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen case AUTH_REQUEST_STATUS_ABORT:
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client->auth_request = NULL;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (args != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* parse our username if it's there */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; args[i] != NULL; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (strncmp(args[i], "user=", 5) == 0) {
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen i_free(client->virtual_user);
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen i_free_and_null(client->virtual_user_orig);
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen i_free_and_null(client->virtual_auth_user);
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen client->virtual_user =
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen i_strdup(args[i] + 5);
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen } else if (strncmp(args[i], "original_user=", 14) == 0) {
6d25922a089626f5535d51358e33d3337783a410Timo Sirainen i_free(client->virtual_user_orig);
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen client->virtual_user_orig =
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen i_strdup(args[i] + 14);
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen } else if (strncmp(args[i], "auth_user=", 10) == 0) {
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen i_free(client->virtual_auth_user);
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen client->virtual_auth_user =
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen i_strdup(args[i] + 10);
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen }
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen }
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainen client->authenticating = FALSE;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen NULL, args);
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen break;
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
06a5ffa611efd86ffb9acc8beb0fe66e7bd844e4Timo Sirainenvoid sasl_server_auth_begin(struct client *client,
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen const char *service, const char *mech_name,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *initial_resp_base64,
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen sasl_server_callback_t *callback)
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen{
24815ed8224a0647926b49b9a1f716efb2a57148Timo Sirainen struct auth_request_info info;
e107b65e7d36ae18571de61a4dbd8609b2883a21Timo Sirainen const struct auth_mech_desc *mech;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(auth_client_is_connected(auth_client));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->auth_attempts++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->authenticating = TRUE;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen if (client->auth_first_started == 0)
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen client->auth_first_started = ioloop_time;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen i_free(client->auth_mech_name);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->auth_mech_name = str_ucase(i_strdup(mech_name));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen client->sasl_callback = callback;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mech = auth_client_find_mech(auth_client, mech_name);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mech == NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sasl_server_auth_failed(client,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Unsupported authentication mechanism.",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen AUTH_CLIENT_FAIL_CODE_MECH_INVALID);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen if (!client->secured && client->set->disable_plaintext_auth &&
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (mech->flags & MECH_SEC_PLAINTEXT) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sasl_server_auth_failed(client,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Plaintext authentication disabled.",
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen AUTH_CLIENT_FAIL_CODE_MECH_SSL_REQUIRED);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_zero(&info);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.mech = mech->name;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.service = service;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.session_id = client_get_session_id(client);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (client->client_cert_common_name != NULL)
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen info.cert_username = client->client_cert_common_name;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen else if (client->ssl_proxy != NULL)
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen info.cert_username = ssl_proxy_get_peer_name(client->ssl_proxy);
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen info.flags = client_get_auth_flags(client);
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen info.local_ip = client->local_ip;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen info.remote_ip = client->ip;
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen info.local_port = client->local_port;
3776ed607821b502468bdfd5a4533af3002125d1Timo Sirainen info.local_name = client->local_name;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen info.remote_port = client->remote_port;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.real_local_ip = client->real_local_ip;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.real_remote_ip = client->real_remote_ip;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.real_local_port = client->real_local_port;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.real_remote_port = client->real_remote_port;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (client->client_id != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.client_id = str_c(client->client_id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (client->forward_fields != NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen info.forward_fields = str_c(client->forward_fields);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen info.initial_resp_base64 = initial_resp_base64;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen client->auth_request =
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen auth_client_request_new(auth_client, &info,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen authenticate_callback, client);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic void ATTR_NULL(2, 3)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainensasl_server_auth_cancel(struct client *client, const char *reason,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const char *code, enum sasl_server_reply reply)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen i_assert(client->authenticating);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen if (client->set->auth_verbose && reason != NULL) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const char *auth_name =
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen client_log(client, t_strdup_printf(
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen "Authenticate %s failed: %s", auth_name, reason));
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen }
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen client->authenticating = FALSE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (client->auth_request != NULL)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen auth_client_request_abort(&client->auth_request);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (code != NULL) {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const char *args[2];
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen args[0] = t_strconcat("code=", code, NULL);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen args[1] = NULL;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen call_client_callback(client, reply, reason, args);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen }
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen call_client_callback(client, reply, reason, NULL);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid sasl_server_auth_failed(struct client *client, const char *reason,
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen const char *code)
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen{
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen sasl_server_auth_cancel(client, reason, code, SASL_SERVER_REPLY_AUTH_FAILED);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenvoid sasl_server_auth_abort(struct client *client)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen client->auth_try_aborted = TRUE;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sasl_server_auth_cancel(client, NULL, NULL, SASL_SERVER_REPLY_AUTH_ABORTED);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen