client-common-auth.c revision 4c6ddf2491104f917d00e6900e833e80ea02c7b6
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger#include "common.h"
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen#include "istream.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "ostream.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "str.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "safe-memset.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "login-proxy.h"
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen#include "auth-client.h"
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#include "client-common.h"
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen#include <stdlib.h>
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen/* If we've been waiting auth server to respond for over this many milliseconds,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen send a "waiting" message. */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define AUTH_WAITING_TIMEOUT_MSECS (30*1000)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#define AUTH_FAILURE_DELAY_INCREASE_MSECS 5000
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen#if CLIENT_LOGIN_IDLE_TIMEOUT_MSECS < AUTH_REQUEST_TIMEOUT*1000
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen# error client idle timeout must be larger than authentication timeout
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen#endif
b624773984e35dd894db8dff976c1a2114c70782Timo Sirainen
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainenstatic void client_authfail_delay_timeout(struct client *client)
b624773984e35dd894db8dff976c1a2114c70782Timo Sirainen{
12d38e76ba7f70d6219c89ec7416fea0d5de7e02Timo Sirainen timeout_remove(&client->to_authfail_delay);
b624773984e35dd894db8dff976c1a2114c70782Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* get back to normal client input. */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_assert(client->io == NULL);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client->io = io_add(client->fd, IO_READ, client_input, client);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_input(client);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid client_auth_failed(struct client *client, bool nodelay)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
3a7113e3e2dac0e333e1a3f62af7d682896f59c6Timo Sirainen unsigned int delay_msecs;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen i_free_and_null(client->master_data_prefix);
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen
be5c76fabc7439fd33bc799bc3ab3f570799977bTimo Sirainen if (client->auth_initializing)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen return;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (client->io != NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen io_remove(&client->io);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (nodelay) {
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen client->io = io_add(client->fd, IO_READ, client_input, client);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen client_input(client);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
788a0754cfd38dcfec1902844b085e4e84cfe7e6Timo Sirainen /* increase the timeout after each unsuccessful attempt, but don't
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen increase it so high that the idle timeout would be triggered */
788a0754cfd38dcfec1902844b085e4e84cfe7e6Timo Sirainen delay_msecs = client->auth_attempts * AUTH_FAILURE_DELAY_INCREASE_MSECS;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (delay_msecs > CLIENT_LOGIN_IDLE_TIMEOUT_MSECS)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen delay_msecs = CLIENT_LOGIN_IDLE_TIMEOUT_MSECS - 1000;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen i_assert(client->to_authfail_delay == NULL);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen client->to_authfail_delay =
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen timeout_add(delay_msecs, client_authfail_delay_timeout, client);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen}
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainenstatic void client_auth_waiting_timeout(struct client *client)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen{
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_STATUS,
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen client->master_tag == 0 ?
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen AUTH_SERVER_WAITING_MSG : AUTH_MASTER_WAITING_MSG);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen timeout_remove(&client->to_auth_waiting);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid client_set_auth_waiting(struct client *client)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_assert(client->to_auth_waiting == NULL);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client->to_auth_waiting =
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen timeout_add(AUTH_WAITING_TIMEOUT_MSECS,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_auth_waiting_timeout, client);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenstatic void client_auth_parse_args(struct client *client,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const char *const *args,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen struct client_auth_reply *reply_r)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const char *key, *value, *p;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen memset(reply_r, 0, sizeof(*reply_r));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen reply_r->port = login_default_port;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen for (; *args != NULL; args++) {
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen p = strchr(*args, '=');
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (p == NULL) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen key = *args;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen value = "";
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen } else {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen key = t_strdup_until(*args, p);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen value = p + 1;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen }
83d2e37f065eabe38dc92db485c5ca39ee43ce05Timo Sirainen if (strcmp(key, "nologin") == 0)
83d2e37f065eabe38dc92db485c5ca39ee43ce05Timo Sirainen reply_r->nologin = TRUE;
83d2e37f065eabe38dc92db485c5ca39ee43ce05Timo Sirainen else if (strcmp(key, "nodelay") == 0)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen reply_r->nodelay = TRUE;
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen else if (strcmp(key, "proxy") == 0)
7569ab8537418b7fc369265f26595b0ef9e4cb35Timo Sirainen reply_r->proxy = TRUE;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen else if (strcmp(key, "temp") == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen reply_r->temp = TRUE;
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen else if (strcmp(key, "authz") == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen reply_r->authz_failure = TRUE;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen else if (strcmp(key, "reason") == 0)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen reply_r->reason = value;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen else if (strcmp(key, "host") == 0)
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen reply_r->host = value;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen else if (strcmp(key, "port") == 0)
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen reply_r->port = atoi(value);
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen else if (strcmp(key, "destuser") == 0)
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen reply_r->destuser = value;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen else if (strcmp(key, "pass") == 0)
3a7113e3e2dac0e333e1a3f62af7d682896f59c6Timo Sirainen reply_r->password = value;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen else if (strcmp(key, "master") == 0)
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen reply_r->master_user = value;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen else if (strcmp(key, "ssl") == 0) {
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen if (strcmp(value, "yes") == 0)
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen reply_r->ssl_flags |= PROXY_SSL_FLAG_YES;
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen else if (strcmp(value, "any-cert") == 0) {
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen reply_r->ssl_flags |= PROXY_SSL_FLAG_YES |
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen PROXY_SSL_FLAG_ANY_CERT;
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen }
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen } else if (strcmp(key, "starttls") == 0) {
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen reply_r->ssl_flags |= PROXY_SSL_FLAG_STARTTLS;
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen } else if (strcmp(key, "user") == 0) {
798cfe56c9871262770384da1239162b3800cce1Timo Sirainen /* already handled in login-common */
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen } else if (client->set->auth_debug)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen i_info("Ignoring unknown passdb extra field: %s", key);
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen }
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen if (reply_r->destuser == NULL)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen reply_r->destuser = client->virtual_user;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen}
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainenstatic void proxy_free_password(struct client *client)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen{
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen if (client->proxy_password == NULL)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen return;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen i_free_and_null(client->proxy_password);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen}
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid client_proxy_finish_destroy_client(struct client *client)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen string_t *str = t_str_new(128);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
31633d676642b83305b8d46da495d9bb4e2d1ff8Timo Sirainen str_printfa(str, "proxy(%s): started proxying to %s:%u",
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen client->virtual_user,
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen login_proxy_get_host(client->login_proxy),
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen login_proxy_get_port(client->login_proxy));
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen if (strcmp(client->virtual_user, client->proxy_user) != 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* remote username is different, log it */
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen str_append_c(str, '/');
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen str_append(str, client->proxy_user);
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen }
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen if (client->proxy_master_user != NULL)
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen str_printfa(str, " (master %s)", client->proxy_master_user);
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen login_proxy_detach(client->login_proxy, client->input, client->output);
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen client->login_proxy = NULL;
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen client->input = NULL;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen client->output = NULL;
5d4855d7b4dcffb6975ed8e3c9c376dac74e5c8aTimo Sirainen client->fd = -1;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client->proxying = TRUE;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen client_destroy_success(client, str_c(str));
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen}
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainenvoid client_proxy_log_failure(struct client *client, const char *line)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen string_t *str = t_str_new(128);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen str_printfa(str, "proxy(%s): Login failed to %s:%u",
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client->virtual_user,
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen login_proxy_get_host(client->login_proxy),
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen login_proxy_get_port(client->login_proxy));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (strcmp(client->virtual_user, client->proxy_user) != 0) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* remote username is different, log it */
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen str_append_c(str, '/');
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen str_append(str, client->proxy_user);
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (client->proxy_master_user != NULL)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen str_printfa(str, " (master %s)", client->proxy_master_user);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen str_append(str, ": ");
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen str_append(str, line);
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen i_info("%s", str_c(str));
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen}
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid client_proxy_failed(struct client *client, bool send_line)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen{
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (send_line) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen AUTH_TEMP_FAILED_MSG);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen }
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen login_proxy_free(&client->login_proxy);
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen proxy_free_password(client);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen i_free_and_null(client->proxy_user);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen i_free_and_null(client->proxy_master_user);
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen /* call this last - it may destroy the client */
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen client_auth_failed(client, TRUE);
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen}
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainenstatic void proxy_input(struct client *client)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen{
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen struct istream *input;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen const char *line;
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen if (client->login_proxy == NULL) {
8eb94c5190ba09bb6f6f068eec7bf96750f08d1dTimo Sirainen /* we're just freeing the proxy */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen return;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen }
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen input = login_proxy_get_istream(client->login_proxy);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (input == NULL) {
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen if (client->destroyed) {
adc409a7ac9689d3baf811712ad5a5432cab2d87Timo Sirainen /* we came here from client_destroy() */
b321df9603081896b70ec44635af96d674a9839aTimo Sirainen return;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* failed for some reason, probably server disconnected */
f968e62caa52a8924bd05ebf76ff515b5c18e17bTimo Sirainen client_proxy_failed(client, TRUE);
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen return;
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_assert(!client->destroyed);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen switch (i_stream_read(input)) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen case -2:
31633d676642b83305b8d46da495d9bb4e2d1ff8Timo Sirainen client_log_err(client, "proxy: Remote input buffer full");
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen client_proxy_failed(client, TRUE);
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen return;
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen case -1:
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen client_log_err(client, "proxy: Remote disconnected");
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen client_proxy_failed(client, TRUE);
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen return;
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen }
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen while ((line = i_stream_next_line(input)) != NULL) {
b0e9375a1ff97c9c7d40655922af5ccc73ecaa76Timo Sirainen if (client->v.proxy_parse_line(client, line) != 0)
3db05c8c00faca6ab9ac8391e1d6977365f4d1b3Timo Sirainen break;
3db05c8c00faca6ab9ac8391e1d6977365f4d1b3Timo Sirainen }
3db05c8c00faca6ab9ac8391e1d6977365f4d1b3Timo Sirainen}
b44650b0f48a4b5f0dc240ed836833a00b643b9fTimo Sirainen
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainenstatic int proxy_start(struct client *client,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const struct client_auth_reply *reply)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen{
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen i_assert(reply->destuser != NULL);
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen i_assert(!client->destroyed);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen client->v.proxy_reset(client);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (reply->password == NULL) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_log_err(client, "proxy: password not given");
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen AUTH_TEMP_FAILED_MSG);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen return -1;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen }
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_assert(client->refcount > 1);
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen if (client->destroyed) {
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen /* connection_queue_add() decided that we were the oldest
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen connection and killed us. */
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen return -1;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen if (login_proxy_is_ourself(client, reply->host, reply->port,
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen reply->destuser)) {
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen client_log_err(client, "Proxying loops to itself");
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen AUTH_TEMP_FAILED_MSG);
a8e132559a7ebe54c8269d79ce29fa3338c76199Timo Sirainen return -1;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen client->login_proxy =
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen login_proxy_new(client, reply->host, reply->port,
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen reply->ssl_flags, proxy_input, client);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen if (client->login_proxy == NULL) {
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen AUTH_TEMP_FAILED_MSG);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen return -1;
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen }
e2a700d0628e395d64cbcef4b5b4510816bf51c4Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen client->proxy_user = i_strdup(reply->destuser);
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen client->proxy_master_user = i_strdup(reply->master_user);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen client->proxy_password = i_strdup(reply->password);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen /* disable input until authentication is finished */
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen if (client->io != NULL)
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen io_remove(&client->io);
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen return 0;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen}
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainen
43358fffb1d9f3091fd94895e0ac4643c50e2388Timo Sirainenstatic bool
430c0b0c370bebeeceba2e206be76bc134742f41Timo Sirainenclient_auth_handle_reply(struct client *client,
25ee72451d16374ed27fdbf829f4ec756c778352Timo Sirainen const struct client_auth_reply *reply, bool success)
a3dd97fb6d92a89c3de0597fed2d4b044c7aeb84Timo Sirainen{
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen if (reply->proxy) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* we want to proxy the connection to another server.
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen don't do this unless authentication succeeded. with
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen master user proxying we can get FAIL with proxy still set.
484e12acec34f16e5a8adc001e23ae48f1dda8c7Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen proxy host=.. [port=..] [destuser=..] pass=.. */
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (!success)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return FALSE;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (proxy_start(client, reply) < 0)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen client_auth_failed(client, TRUE);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return TRUE;
484e12acec34f16e5a8adc001e23ae48f1dda8c7Timo Sirainen }
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen return client->v.auth_handle_reply(client, reply);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainenstatic void client_auth_input(struct client *client)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen{
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen char *line;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen if (!client_read(client))
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen return;
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen /* @UNSAFE */
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen line = i_stream_next_line(client->input);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen if (line == NULL)
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen return;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen if (strcmp(line, "*") == 0)
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen sasl_server_auth_abort(client);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen else {
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen client_set_auth_waiting(client);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen auth_client_request_continue(client->auth_request, line);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen io_remove(&client->io);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen /* clear sensitive data */
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen safe_memset(line, 0, strlen(line));
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen }
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen}
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainenvoid client_auth_send_continue(struct client *client, const char *data)
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen{
3cf67672fdc87583cb23ce088c95bb5dee60e74dTimo Sirainen struct const_iovec iov[3];
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen iov[0].iov_base = "+ ";
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen iov[0].iov_len = 2;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen iov[1].iov_base = data;
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen iov[1].iov_len = strlen(data);
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen iov[2].iov_base = "\r\n";
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen iov[2].iov_len = 2;
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainen (void)o_stream_sendv(client->output, iov, 3);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen}
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainenstatic void
35136dd2baf8dc30e4e754294ed81ff48e8c1e64Timo Sirainensasl_callback(struct client *client, enum sasl_server_reply sasl_reply,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen const char *data, const char *const *args)
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen{
137ea7ca34005345aa2304a940149b7f3774d727Timo Sirainen struct client_auth_reply reply;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen i_assert(!client->destroyed ||
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED ||
6fabfb7bbfd88d0c1de66981e52850f26067623bTimo Sirainen sasl_reply == SASL_SERVER_REPLY_MASTER_FAILED);
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen switch (sasl_reply) {
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen case SASL_SERVER_REPLY_SUCCESS:
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen if (client->to_auth_waiting != NULL)
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen timeout_remove(&client->to_auth_waiting);
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen if (args != NULL) {
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen client_auth_parse_args(client, args, &reply);
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen if (client_auth_handle_reply(client, &reply, TRUE))
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen break;
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen }
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen client_destroy_success(client, "Login");
559f278a4c54d9fa7e0f2e96ebceda30562f9009Timo Sirainen break;
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen case SASL_SERVER_REPLY_AUTH_FAILED:
88e9835c4d8973c62cd4db1ec7324ff46dd3ff15Timo Sirainen case SASL_SERVER_REPLY_AUTH_ABORTED:
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen if (client->to_auth_waiting != NULL)
0f39a57760d93cddbce3ca43096d78e0fe2f42fdTimo Sirainen timeout_remove(&client->to_auth_waiting);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (args != NULL) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_auth_parse_args(client, args, &reply);
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen reply.nologin = TRUE;
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen if (client_auth_handle_reply(client, &reply, FALSE))
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen break;
82f53ea81671bcc7b9bf24a34b04a4ba2752efd3Timo Sirainen }
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen if (sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_BAD,
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen "Authentication aborted by client.");
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen } else if (data == NULL) {
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAILED,
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen AUTH_FAILED_MSG);
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen } else {
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen client_send_line(client,
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen CLIENT_CMD_REPLY_AUTH_FAIL_REASON,
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen data);
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen }
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen if (!client->destroyed)
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen client_auth_failed(client, reply.nodelay);
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen break;
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen case SASL_SERVER_REPLY_MASTER_FAILED:
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen if (data == NULL)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_destroy_internal_failure(client);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen else {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_send_line(client,
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen CLIENT_CMD_REPLY_AUTH_FAIL_TEMP, data);
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen /* authentication itself succeeded, we just hit some
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen internal failure. */
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen client_destroy_success(client, data);
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen }
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen break;
9261dbf0675204898c6557591c7aa376e23a52b2Timo Sirainen case SASL_SERVER_REPLY_CONTINUE:
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen client->v.auth_send_continue(client, data);
31597236d79ac38a5cea7ab65a9d0a3df64ed201Timo Sirainen
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen if (client->to_auth_waiting != NULL)
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen timeout_remove(&client->to_auth_waiting);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen i_assert(client->io == NULL);
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen client->io = io_add(client->fd, IO_READ,
70c181da837ed85fc5b0426c010b65609bda5329Timo Sirainen client_auth_input, client);
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen client_auth_input(client);
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen return;
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen }
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen client_unref(client);
f0c01ca67be18ed9c8011a094db2773f8795a1ebTimo Sirainen}
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainenint client_auth_begin(struct client *client, const char *mech_name,
cd75c360f244c96b9ee10e01ee3a66fad13183c8Timo Sirainen const char *init_resp)
b42f37ae6f65ed986315b6885568d32115e589b1Timo Sirainen{
e9503210d3521a6833ed62dc332fc42ffb0e7a13Timo Sirainen if (!client->secured && strcmp(client->set->ssl, "required") == 0) {
ce6b6093957885a74fd6e85c18801dbb727d61ecTimo Sirainen if (client->set->verbose_auth) {
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen client_log(client, "Login failed: "
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen "SSL required for authentication");
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen }
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client->auth_attempts++;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_NOSSL,
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen "Authentication not allowed until SSL/TLS is enabled.");
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen return 1;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen }
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client_ref(client);
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client->auth_initializing = TRUE;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen sasl_server_auth_begin(client, login_protocol, mech_name,
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen init_resp, sasl_callback);
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client->auth_initializing = FALSE;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen if (!client->authenticating)
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen return 1;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen /* don't handle input until we get the initial auth reply */
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen if (client->io != NULL)
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen io_remove(&client->io);
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client_set_auth_waiting(client);
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen return 0;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenbool client_check_plaintext_auth(struct client *client, bool pass_sent)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (client->secured || !client->set->disable_plaintext_auth)
7cba14a4c3beb026a2862ee50d24c554fa713329Timo Sirainen return TRUE;
7cba14a4c3beb026a2862ee50d24c554fa713329Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (client->set->verbose_auth) {
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen client_log(client, "Login failed: "
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen "Plaintext authentication disabled");
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (pass_sent) {
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_STATUS_BAD,
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen "Plaintext authentication not allowed "
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen "without SSL/TLS, but your client did it anyway. "
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen "If anyone was listening, the password was exposed.");
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen }
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_NOSSL,
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen AUTH_PLAINTEXT_DISABLED_MSG);
e9371f899a3d4207a0ffd3923ea5ec7250cf5e75Timo Sirainen client->auth_tried_disabled_plaintext = TRUE;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen client->auth_attempts++;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen return FALSE;
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen}
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenvoid clients_notify_auth_connected(void)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen{
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen struct client *client;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen for (client = clients; client != NULL; client = client->next) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (client->to_auth_waiting != NULL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen timeout_remove(&client->to_auth_waiting);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (!client->greeting_sent)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen client->v.send_greeting(client);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen if (client->input_blocked) {
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen client->input_blocked = FALSE;
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen client_input(client);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen }
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen}
5afc76d0215c5f7631dec06ef864d59f0686a0a8Timo Sirainen