1
/* Copyright (c) 2002-2012 Dovecot authors, see the included COPYING file */
1
/* Copyright (c) 2002-2013 Dovecot authors, see the included COPYING file */
3
4
#include "login-common.h"
7
8
#include "safe-memset.h"
8
10
#include "login-proxy.h"
9
11
#include "auth-client.h"
12
#include "dsasl-client.h"
13
#include "master-service-ssl-settings.h"
10
14
#include "client-common.h"
12
16
#include <stdlib.h>
14
18
#define PROXY_FAILURE_MSG "Account is temporarily unavailable."
15
#define LOGIN_DNS_CLIENT_SOCKET_PATH "dns-client"
19
#define PROXY_DEFAULT_TIMEOUT_MSECS (1000*30)
17
21
/* If we've been waiting auth server to respond for over this many milliseconds,
18
22
send a "waiting" message. */
19
23
#define AUTH_WAITING_TIMEOUT_MSECS (30*1000)
20
#define GREETING_WARNING_TIMEOUT_MSECS (10*1000)
24
#define AUTH_WAITING_WARNING_TIMEOUT_MSECS (10*1000)
22
void client_auth_failed(struct client *client)
26
static void client_auth_failed(struct client *client)
24
28
i_free_and_null(client->master_data_prefix);
25
29
if (client->auth_response != NULL)
38
42
static void client_auth_waiting_timeout(struct client *client)
40
if (!client->greeting_sent) {
44
if (!client->notified_auth_ready) {
41
45
client_log_warn(client, "Auth process not responding, "
42
"delayed sending greeting");
46
"delayed sending initial response (greeting)");
44
client_send_line(client, CLIENT_CMD_REPLY_STATUS,
45
client->master_tag == 0 ?
46
AUTH_SERVER_WAITING_MSG : AUTH_MASTER_WAITING_MSG);
48
client_notify_status(client, FALSE, client->master_tag == 0 ?
49
AUTH_SERVER_WAITING_MSG : AUTH_MASTER_WAITING_MSG);
47
50
timeout_remove(&client->to_auth_waiting);
52
55
i_assert(client->to_auth_waiting == NULL);
53
56
client->to_auth_waiting =
54
timeout_add(!client->greeting_sent ?
55
GREETING_WARNING_TIMEOUT_MSECS :
57
timeout_add(!client->notified_auth_ready ?
58
AUTH_WAITING_WARNING_TIMEOUT_MSECS :
56
59
AUTH_WAITING_TIMEOUT_MSECS,
57
60
client_auth_waiting_timeout, client);
102
105
reply_r->proxy_timeout_msecs = 1000*atoi(value);
103
106
else if (strcmp(key, "proxy_refresh") == 0)
104
107
reply_r->proxy_refresh_secs = atoi(value);
108
else if (strcmp(key, "proxy_mech") == 0)
109
reply_r->proxy_mech = value;
105
110
else if (strcmp(key, "master") == 0)
106
111
reply_r->master_user = value;
107
112
else if (strcmp(key, "ssl") == 0) {
165
170
client_destroy_success(client, str_c(str));
173
static void client_proxy_error(struct client *client, const char *text)
175
client->v.proxy_error(client, text);
168
178
void client_proxy_log_failure(struct client *client, const char *line)
170
180
string_t *str = t_str_new(128);
188
198
void client_proxy_failed(struct client *client, bool send_line)
191
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
201
client_proxy_error(client, PROXY_FAILURE_MSG);
204
if (client->proxy_sasl_client != NULL)
205
dsasl_client_free(&client->proxy_sasl_client);
195
206
login_proxy_free(&client->login_proxy);
196
207
proxy_free_password(client);
197
208
i_free_and_null(client->proxy_user);
269
output = client->output;
270
o_stream_ref(output);
271
o_stream_cork(output);
257
272
while ((line = i_stream_next_line(input)) != NULL) {
258
273
if (client->v.proxy_parse_line(client, line) != 0)
276
o_stream_uncork(output);
277
o_stream_unref(&output);
263
280
static int proxy_start(struct client *client,
264
281
const struct client_auth_reply *reply)
266
283
struct login_proxy_settings proxy_set;
284
const struct dsasl_client_mech *sasl_mech = NULL;
268
286
i_assert(reply->destuser != NULL);
269
287
i_assert(!client->destroyed);
288
i_assert(client->proxy_sasl_client == NULL);
290
client->proxy_mech = NULL;
271
291
client->v.proxy_reset(client);
273
293
if (reply->password == NULL) {
274
294
client_log_err(client, "proxy: password not given");
275
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
295
client_proxy_error(client, PROXY_FAILURE_MSG);
279
298
if (reply->host == NULL || *reply->host == '\0') {
280
299
client_log_err(client, "proxy: host not given");
281
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
300
client_proxy_error(client, PROXY_FAILURE_MSG);
304
if (reply->proxy_mech != NULL) {
305
sasl_mech = dsasl_client_mech_find(reply->proxy_mech);
306
if (sasl_mech == NULL) {
307
client_log_err(client, t_strdup_printf(
308
"proxy: Unsupported SASL mechanism %s",
310
client_proxy_error(client, PROXY_FAILURE_MSG);
313
} else if (reply->master_user != NULL) {
314
/* have to use PLAIN authentication with master user logins */
315
sasl_mech = &dsasl_client_mech_plain;
286
318
i_assert(client->refcount > 1);
288
320
if (client->destroyed) {
293
325
if (login_proxy_is_ourself(client, reply->host, reply->port,
294
326
reply->destuser)) {
295
327
client_log_err(client, "Proxying loops to itself");
296
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
328
client_proxy_error(client, PROXY_FAILURE_MSG);
304
335
net_addr2ip(reply->hostip, &proxy_set.ip) < 0)
305
336
proxy_set.ip.family = 0;
306
337
proxy_set.port = reply->port;
307
proxy_set.dns_client_socket_path = LOGIN_DNS_CLIENT_SOCKET_PATH;
308
338
proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs;
339
if (proxy_set.connect_timeout_msecs == 0)
340
proxy_set.connect_timeout_msecs = PROXY_DEFAULT_TIMEOUT_MSECS;
309
341
proxy_set.notify_refresh_secs = reply->proxy_refresh_secs;
310
342
proxy_set.ssl_flags = reply->ssl_flags;
312
344
if (login_proxy_new(client, &proxy_set, proxy_input) < 0) {
313
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
345
client_proxy_error(client, PROXY_FAILURE_MSG);
349
client->proxy_mech = sasl_mech;
318
350
client->proxy_user = i_strdup(reply->destuser);
319
351
client->proxy_master_user = i_strdup(reply->master_user);
320
352
client->proxy_password = i_strdup(reply->password);
360
static void ATTR_NULL(3, 4)
361
client_auth_result(struct client *client, enum client_auth_result result,
362
const struct client_auth_reply *reply, const char *text)
364
o_stream_cork(client->output);
365
client->v.auth_result(client, result, reply, text);
366
o_stream_uncork(client->output);
329
370
client_auth_handle_reply(struct client *client,
330
371
const struct client_auth_reply *reply, bool success)
341
382
client_auth_failed(client);
344
return client->v.auth_handle_reply(client, reply);
386
if (reply->host != NULL) {
389
if (reply->reason != NULL)
390
reason = reply->reason;
391
else if (reply->nologin)
392
reason = "Try this server instead.";
394
reason = "Logged in, but you should use this server instead.";
396
if (reply->nologin) {
397
client_auth_result(client,
398
CLIENT_AUTH_RESULT_REFERRAL_NOLOGIN,
401
client_auth_result(client,
402
CLIENT_AUTH_RESULT_REFERRAL_SUCCESS,
406
} else if (reply->nologin) {
407
/* Authentication went ok, but for some reason user isn't
408
allowed to log in. Shouldn't probably happen. */
409
if (reply->reason != NULL) {
410
client_auth_result(client,
411
CLIENT_AUTH_RESULT_AUTHFAILED_REASON,
412
reply, reply->reason);
413
} else if (reply->temp) {
414
const char *timestamp, *msg;
416
timestamp = t_strflocaltime("%Y-%m-%d %H:%M:%S", ioloop_time);
417
msg = t_strdup_printf(AUTH_TEMP_FAILED_MSG" [%s:%s]",
418
my_hostname, timestamp);
419
client_auth_result(client, CLIENT_AUTH_RESULT_TEMPFAIL,
421
} else if (reply->authz_failure) {
422
client_auth_result(client,
423
CLIENT_AUTH_RESULT_AUTHZFAILED, reply,
424
"Authorization failed");
426
client_auth_result(client,
427
CLIENT_AUTH_RESULT_AUTHFAILED, reply,
431
/* normal login/failure */
435
i_assert(reply->nologin);
437
if (!client->destroyed)
438
client_auth_failed(client);
442
void client_auth_respond(struct client *client, const char *response)
444
client->auth_waiting = FALSE;
445
client_set_auth_waiting(client);
446
auth_client_request_continue(client->auth_request, response);
447
io_remove(&client->io);
450
void client_auth_abort(struct client *client)
452
sasl_server_auth_abort(client);
455
void client_auth_fail(struct client *client, const char *text)
457
sasl_server_auth_failed(client, text);
347
460
int client_auth_read_line(struct client *client)
380
int client_auth_parse_response(struct client *client)
493
void client_auth_parse_response(struct client *client)
384
if ((ret = client_auth_read_line(client)) <= 0)
495
if (client_auth_read_line(client) <= 0)
387
498
if (strcmp(str_c(client->auth_response), "*") == 0) {
388
499
sasl_server_auth_abort(client);
394
static void client_auth_input(struct client *client)
396
if (client->v.auth_parse_response(client) <= 0)
399
client->auth_waiting = FALSE;
400
client_set_auth_waiting(client);
401
auth_client_request_continue(client->auth_request,
402
str_c(client->auth_response));
403
io_remove(&client->io);
503
client_auth_respond(client, str_c(client->auth_response));
405
504
memset(str_c_modifiable(client->auth_response), 0,
406
505
str_len(client->auth_response));
508
static void client_auth_input(struct client *client)
510
i_assert(client->v.auth_parse_response != NULL);
511
client->v.auth_parse_response(client);
409
514
void client_auth_send_challenge(struct client *client, const char *data)
411
516
struct const_iovec iov[3];
455
562
if (sasl_reply == SASL_SERVER_REPLY_AUTH_ABORTED) {
456
client_send_line(client, CLIENT_CMD_REPLY_BAD,
457
"Authentication aborted by client.");
563
client_auth_result(client, CLIENT_AUTH_RESULT_ABORTED,
564
NULL, "Authentication aborted by client.");
458
565
} else if (data == NULL) {
459
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAILED,
566
client_auth_result(client,
567
CLIENT_AUTH_RESULT_AUTHFAILED, NULL,
462
client_send_line(client,
463
CLIENT_CMD_REPLY_AUTH_FAIL_REASON,
570
client_auth_result(client,
571
CLIENT_AUTH_RESULT_AUTHFAILED_REASON, NULL,
467
575
if (!client->destroyed)
508
617
int client_auth_begin(struct client *client, const char *mech_name,
509
618
const char *init_resp)
511
if (!client->secured && strcmp(client->set->ssl, "required") == 0) {
620
if (!client->secured && strcmp(client->ssl_set->ssl, "required") == 0) {
512
621
if (client->set->auth_verbose) {
513
622
client_log(client, "Login failed: "
514
623
"SSL required for authentication");
516
625
client->auth_attempts++;
517
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_NOSSL,
626
client_auth_result(client, CLIENT_AUTH_RESULT_SSL_REQUIRED, NULL,
518
627
"Authentication not allowed until SSL/TLS is enabled.");
545
655
"Plaintext authentication disabled");
548
client_send_line(client, CLIENT_CMD_REPLY_STATUS_BAD,
658
client_notify_status(client, TRUE,
549
659
"Plaintext authentication not allowed "
550
660
"without SSL/TLS, but your client did it anyway. "
551
661
"If anyone was listening, the password was exposed.");
553
client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_NOSSL,
554
AUTH_PLAINTEXT_DISABLED_MSG);
663
client_auth_result(client, CLIENT_AUTH_RESULT_SSL_REQUIRED, NULL,
664
AUTH_PLAINTEXT_DISABLED_MSG);
555
665
client->auth_tried_disabled_plaintext = TRUE;
556
666
client->auth_attempts++;
567
677
if (client->to_auth_waiting != NULL)
568
678
timeout_remove(&client->to_auth_waiting);
569
if (!client->greeting_sent)
570
client->v.send_greeting(client);
680
client_notify_auth_ready(client);
571
682
if (client->input_blocked) {
572
683
client->input_blocked = FALSE;
573
684
client_input(client);