1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
2
3 #include "login-common.h"
4 #include "str.h"
5 #include "base64.h"
6 #include "buffer.h"
7 #include "hex-binary.h"
8 #include "ioloop.h"
9 #include "istream.h"
10 #include "write-full.h"
11 #include "strescape.h"
12 #include "str-sanitize.h"
13 #include "anvil-client.h"
14 #include "auth-client.h"
15 #include "iostream-ssl.h"
16 #include "master-service.h"
17 #include "master-service-ssl-settings.h"
18 #include "master-interface.h"
19 #include "master-auth.h"
20 #include "client-common.h"
21
22 #include <unistd.h>
23
24 #define ERR_TOO_MANY_USERIP_CONNECTIONS \
25 "Maximum number of connections from user+IP exceeded " \
26 "(mail_max_userip_connections=%u)"
27
28 struct anvil_request {
29 struct client *client;
30 unsigned int auth_pid;
31 unsigned char cookie[MASTER_AUTH_COOKIE_SIZE];
32 };
33
34 static bool
sasl_server_filter_mech(struct client * client,struct auth_mech_desc * mech)35 sasl_server_filter_mech(struct client *client, struct auth_mech_desc *mech)
36 {
37 if (client->v.sasl_filter_mech != NULL &&
38 !client->v.sasl_filter_mech(client, mech))
39 return FALSE;
40 return ((mech->flags & MECH_SEC_ANONYMOUS) == 0 ||
41 login_binary->anonymous_login_acceptable);
42 }
43
44 const struct auth_mech_desc *
sasl_server_get_advertised_mechs(struct client * client,unsigned int * count_r)45 sasl_server_get_advertised_mechs(struct client *client, unsigned int *count_r)
46 {
47 const struct auth_mech_desc *mech;
48 struct auth_mech_desc *ret_mech;
49 unsigned int i, j, count;
50
51 mech = auth_client_get_available_mechs(auth_client, &count);
52 if (count == 0 || (!client->secured &&
53 strcmp(client->ssl_set->ssl, "required") == 0)) {
54 *count_r = 0;
55 return NULL;
56 }
57
58 ret_mech = t_new(struct auth_mech_desc, count);
59 for (i = j = 0; i < count; i++) {
60 struct auth_mech_desc fmech = mech[i];
61
62 if (!sasl_server_filter_mech(client, &fmech))
63 continue;
64
65 /* a) transport is secured
66 b) auth mechanism isn't plaintext
67 c) we allow insecure authentication
68 */
69 if ((fmech.flags & MECH_SEC_PRIVATE) == 0 &&
70 (client->secured || !client->set->disable_plaintext_auth ||
71 (fmech.flags & MECH_SEC_PLAINTEXT) == 0))
72 ret_mech[j++] = fmech;
73 }
74 *count_r = j;
75 return ret_mech;
76 }
77
78 const struct auth_mech_desc *
sasl_server_find_available_mech(struct client * client,const char * name)79 sasl_server_find_available_mech(struct client *client, const char *name)
80 {
81 const struct auth_mech_desc *mech;
82 struct auth_mech_desc fmech;
83
84 mech = auth_client_find_mech(auth_client, name);
85 if (mech == NULL)
86 return NULL;
87
88 fmech = *mech;
89 if (!sasl_server_filter_mech(client, &fmech))
90 return NULL;
91 if (memcmp(&fmech, mech, sizeof(fmech)) != 0) {
92 struct auth_mech_desc *nmech = t_new(struct auth_mech_desc, 1);
93
94 *nmech = fmech;
95 mech = nmech;
96 }
97 return mech;
98 }
99
100 static enum auth_request_flags
client_get_auth_flags(struct client * client)101 client_get_auth_flags(struct client *client)
102 {
103 enum auth_request_flags auth_flags = 0;
104
105 if (client->ssl_iostream != NULL &&
106 ssl_iostream_has_valid_client_cert(client->ssl_iostream))
107 auth_flags |= AUTH_REQUEST_FLAG_VALID_CLIENT_CERT;
108 if (client->tls || client->proxied_ssl)
109 auth_flags |= AUTH_REQUEST_FLAG_TRANSPORT_SECURITY_TLS;
110 if (client->secured)
111 auth_flags |= AUTH_REQUEST_FLAG_SECURED;
112 if (login_binary->sasl_support_final_reply)
113 auth_flags |= AUTH_REQUEST_FLAG_SUPPORT_FINAL_RESP;
114 return auth_flags;
115 }
116
117 static void ATTR_NULL(3, 4)
call_client_callback(struct client * client,enum sasl_server_reply reply,const char * data,const char * const * args)118 call_client_callback(struct client *client, enum sasl_server_reply reply,
119 const char *data, const char *const *args)
120 {
121 sasl_server_callback_t *sasl_callback;
122
123 i_assert(reply != SASL_SERVER_REPLY_CONTINUE);
124
125 sasl_callback = client->sasl_callback;
126 client->sasl_callback = NULL;
127
128 sasl_callback(client, reply, data, args);
129 /* NOTE: client may be destroyed now */
130 }
131
132 static void
master_auth_callback(const struct master_auth_reply * reply,void * context)133 master_auth_callback(const struct master_auth_reply *reply, void *context)
134 {
135 struct client *client = context;
136 enum sasl_server_reply sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
137 const char *data = NULL;
138
139 client->master_tag = 0;
140 client->authenticating = FALSE;
141 if (reply != NULL) {
142 switch (reply->status) {
143 case MASTER_AUTH_STATUS_OK:
144 sasl_reply = SASL_SERVER_REPLY_SUCCESS;
145 break;
146 case MASTER_AUTH_STATUS_INTERNAL_ERROR:
147 sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
148 break;
149 }
150 client->mail_pid = reply->mail_pid;
151 } else {
152 auth_client_send_cancel(auth_client, client->master_auth_id);
153 }
154 call_client_callback(client, sasl_reply, data, NULL);
155 }
156
master_send_request(struct anvil_request * anvil_request)157 static int master_send_request(struct anvil_request *anvil_request)
158 {
159 struct client *client = anvil_request->client;
160 struct master_auth_request_params params;
161 struct master_auth_request req;
162 const unsigned char *data;
163 size_t size;
164 buffer_t *buf;
165 const char *session_id = client_get_session_id(client);
166 int fd;
167 bool close_fd;
168
169 if (client_get_plaintext_fd(client, &fd, &close_fd) < 0)
170 return -1;
171
172 i_zero(&req);
173 req.auth_pid = anvil_request->auth_pid;
174 req.auth_id = client->master_auth_id;
175 req.local_ip = client->local_ip;
176 req.remote_ip = client->ip;
177 req.local_port = client->local_port;
178 req.remote_port = client->remote_port;
179 req.client_pid = getpid();
180 if (client->ssl_iostream != NULL &&
181 ssl_iostream_get_compression(client->ssl_iostream) != NULL)
182 req.flags |= MAIL_AUTH_REQUEST_FLAG_TLS_COMPRESSION;
183 if (client->secured)
184 req.flags |= MAIL_AUTH_REQUEST_FLAG_CONN_SECURED;
185 if (client->ssl_secured)
186 req.flags |= MAIL_AUTH_REQUEST_FLAG_CONN_SSL_SECURED;
187 memcpy(req.cookie, anvil_request->cookie, sizeof(req.cookie));
188
189 buf = t_buffer_create(256);
190 /* session ID */
191 buffer_append(buf, session_id, strlen(session_id)+1);
192 /* protocol specific data (e.g. IMAP tag) */
193 buffer_append(buf, client->master_data_prefix,
194 client->master_data_prefix_len);
195 /* buffered client input */
196 data = i_stream_get_data(client->input, &size);
197 buffer_append(buf, data, size);
198 req.data_size = buf->used;
199 i_stream_skip(client->input, size);
200
201 client->auth_finished = ioloop_time;
202
203 i_zero(¶ms);
204 params.client_fd = fd;
205 params.socket_path = client->postlogin_socket_path;
206 params.request = req;
207 params.data = buf->data;
208 master_auth_request_full(master_auth, ¶ms, master_auth_callback,
209 client, &client->master_tag);
210 if (close_fd)
211 i_close_fd(&fd);
212 return 0;
213 }
214
215 static void ATTR_NULL(1)
anvil_lookup_callback(const char * reply,void * context)216 anvil_lookup_callback(const char *reply, void *context)
217 {
218 struct anvil_request *req = context;
219 struct client *client = req->client;
220 const struct login_settings *set = client->set;
221 const char *errmsg;
222 unsigned int conn_count;
223 int ret;
224
225 client->anvil_query = NULL;
226 client->anvil_request = NULL;
227
228 conn_count = 0;
229 if (reply != NULL && str_to_uint(reply, &conn_count) < 0)
230 i_fatal("Received invalid reply from anvil: %s", reply);
231
232 /* reply=NULL if we didn't need to do anvil lookup,
233 or if the anvil lookup failed. allow failed anvil lookups in. */
234 if (reply == NULL || conn_count < set->mail_max_userip_connections) {
235 ret = master_send_request(req);
236 errmsg = NULL; /* client will see internal error */
237 } else {
238 ret = -1;
239 errmsg = t_strdup_printf(ERR_TOO_MANY_USERIP_CONNECTIONS,
240 set->mail_max_userip_connections);
241 }
242 if (ret < 0) {
243 client->authenticating = FALSE;
244 auth_client_send_cancel(auth_client, client->master_auth_id);
245 call_client_callback(client, SASL_SERVER_REPLY_MASTER_FAILED,
246 errmsg, NULL);
247 }
248 i_free(req);
249 }
250
251 static void
anvil_check_too_many_connections(struct client * client,struct auth_client_request * request)252 anvil_check_too_many_connections(struct client *client,
253 struct auth_client_request *request)
254 {
255 struct anvil_request *req;
256 const char *query, *cookie;
257 buffer_t buf;
258
259 req = i_new(struct anvil_request, 1);
260 req->client = client;
261 req->auth_pid = auth_client_request_get_server_pid(request);
262
263 buffer_create_from_data(&buf, req->cookie, sizeof(req->cookie));
264 cookie = auth_client_request_get_cookie(request);
265 if (strlen(cookie) == MASTER_AUTH_COOKIE_SIZE*2)
266 (void)hex_to_binary(cookie, &buf);
267
268 if (client->virtual_user == NULL ||
269 client->set->mail_max_userip_connections == 0) {
270 anvil_lookup_callback(NULL, req);
271 return;
272 }
273
274 query = t_strconcat("LOOKUP\t", login_binary->protocol, "/",
275 net_ip2addr(&client->ip), "/",
276 str_tabescape(client->virtual_user), NULL);
277 client->anvil_request = req;
278 client->anvil_query =
279 anvil_client_query(anvil, query, anvil_lookup_callback, req);
280 }
281
282 static bool
sasl_server_check_login(struct client * client)283 sasl_server_check_login(struct client *client)
284 {
285 if (client->v.sasl_check_login != NULL &&
286 !client->v.sasl_check_login(client))
287 return FALSE;
288 if (client->auth_anonymous &&
289 !login_binary->anonymous_login_acceptable) {
290 sasl_server_auth_failed(client,
291 "Anonymous login denied",
292 AUTH_CLIENT_FAIL_CODE_ANONYMOUS_DENIED);
293 return FALSE;
294 }
295 return TRUE;
296 }
297
args_parse_user(struct client * client,const char * arg)298 static bool args_parse_user(struct client *client, const char *arg)
299 {
300 if (str_begins(arg, "user=")) {
301 i_free(client->virtual_user);
302 i_free_and_null(client->virtual_user_orig);
303 i_free_and_null(client->virtual_auth_user);
304 client->virtual_user = i_strdup(arg + 5);
305 event_add_str(client->event, "user", client->virtual_user);
306 } else if (str_begins(arg, "original_user=")) {
307 i_free(client->virtual_user_orig);
308 client->virtual_user_orig = i_strdup(arg + 14);
309 } else if (str_begins(arg, "auth_user=")) {
310 i_free(client->virtual_auth_user);
311 client->virtual_auth_user = i_strdup(arg + 10);
312 } else {
313 return FALSE;
314 }
315 return TRUE;
316 }
317
318 static void
authenticate_callback(struct auth_client_request * request,enum auth_request_status status,const char * data_base64,const char * const * args,void * context)319 authenticate_callback(struct auth_client_request *request,
320 enum auth_request_status status, const char *data_base64,
321 const char *const *args, void *context)
322 {
323 struct client *client = context;
324 unsigned int i;
325 bool nologin;
326
327 if (!client->authenticating) {
328 /* client aborted */
329 i_assert(status < 0);
330 return;
331 }
332 client->auth_waiting = FALSE;
333
334 i_assert(client->auth_request == request);
335 switch (status) {
336 case AUTH_REQUEST_STATUS_CONTINUE:
337 /* continue */
338 client->sasl_callback(client, SASL_SERVER_REPLY_CONTINUE,
339 data_base64, NULL);
340 break;
341 case AUTH_REQUEST_STATUS_OK:
342 client->master_auth_id = auth_client_request_get_id(request);
343 client->auth_request = NULL;
344 client->auth_successes++;
345 client->auth_passdb_args = p_strarray_dup(client->pool, args);
346 client->postlogin_socket_path = NULL;
347
348 nologin = FALSE;
349 for (i = 0; args[i] != NULL; i++) {
350 if (args_parse_user(client, args[i]))
351 ;
352 else if (str_begins(args[i], "postlogin_socket=")) {
353 client->postlogin_socket_path =
354 p_strdup(client->pool, args[i] + 17);
355 } else if (strcmp(args[i], "nologin") == 0 ||
356 strcmp(args[i], "proxy") == 0) {
357 /* user can't login */
358 nologin = TRUE;
359 } else if (strcmp(args[i], "anonymous") == 0 ) {
360 client->auth_anonymous = TRUE;
361 } else if (str_begins(args[i], "resp=") &&
362 login_binary->sasl_support_final_reply) {
363 client->sasl_final_resp =
364 p_strdup(client->pool, args[i] + 5);
365 }
366 }
367
368 if (nologin) {
369 client->authenticating = FALSE;
370 call_client_callback(client, SASL_SERVER_REPLY_SUCCESS,
371 NULL, args);
372 } else if (!sasl_server_check_login(client)) {
373 i_assert(!client->authenticating);
374 } else {
375 anvil_check_too_many_connections(client, request);
376 }
377 break;
378 case AUTH_REQUEST_STATUS_INTERNAL_FAIL:
379 client->auth_process_comm_fail = TRUE;
380 /* fall through */
381 case AUTH_REQUEST_STATUS_FAIL:
382 case AUTH_REQUEST_STATUS_ABORT:
383 client->auth_request = NULL;
384
385 if (args != NULL) {
386 /* parse our username if it's there */
387 for (i = 0; args[i] != NULL; i++)
388 (void)args_parse_user(client, args[i]);
389 }
390
391 client->authenticating = FALSE;
392 call_client_callback(client, SASL_SERVER_REPLY_AUTH_FAILED,
393 NULL, args);
394 break;
395 }
396 }
397
get_cert_username(struct client * client,const char ** username_r,const char ** error_r)398 static bool get_cert_username(struct client *client, const char **username_r,
399 const char **error_r)
400 {
401 /* this was proxied connection, so we use the name here */
402 if (client->client_cert_common_name != NULL) {
403 *username_r = client->client_cert_common_name;
404 return TRUE;
405 }
406
407 /* no SSL */
408 if (client->ssl_iostream == NULL) {
409 *username_r = NULL;
410 return TRUE;
411 }
412
413 /* no client certificate */
414 if (!ssl_iostream_has_valid_client_cert(client->ssl_iostream)) {
415 *username_r = NULL;
416 return TRUE;
417 }
418
419 /* get peer name */
420 const char *username = ssl_iostream_get_peer_name(client->ssl_iostream);
421
422 /* if we wanted peer name, but it was not there, fail */
423 if (client->set->auth_ssl_username_from_cert &&
424 (username == NULL || *username == '\0')) {
425 if (client->set->auth_ssl_require_client_cert) {
426 *error_r = "Missing username in certificate";
427 return FALSE;
428 }
429 }
430
431 *username_r = username;
432 return TRUE;
433 }
434
sasl_server_auth_begin(struct client * client,const char * service,const char * mech_name,bool private,const char * initial_resp_base64,sasl_server_callback_t * callback)435 void sasl_server_auth_begin(struct client *client,
436 const char *service, const char *mech_name,
437 bool private, const char *initial_resp_base64,
438 sasl_server_callback_t *callback)
439 {
440 struct auth_request_info info;
441 const struct auth_mech_desc *mech;
442 const char *error;
443
444 i_assert(auth_client_is_connected(auth_client));
445
446 client->auth_attempts++;
447 client->authenticating = TRUE;
448 client->master_auth_id = 0;
449 if (client->auth_first_started == 0)
450 client->auth_first_started = ioloop_time;
451 i_free(client->auth_mech_name);
452 client->auth_mech_name = str_ucase(i_strdup(mech_name));
453 client->auth_anonymous = FALSE;
454 client->sasl_callback = callback;
455
456 mech = sasl_server_find_available_mech(client, mech_name);
457 if (mech == NULL ||
458 ((mech->flags & MECH_SEC_PRIVATE) != 0 && !private)) {
459 sasl_server_auth_failed(client,
460 "Unsupported authentication mechanism.",
461 AUTH_CLIENT_FAIL_CODE_MECH_INVALID);
462 return;
463 }
464
465 i_assert(!private || (mech->flags & MECH_SEC_PRIVATE) != 0);
466
467 if (!client->secured && client->set->disable_plaintext_auth &&
468 (mech->flags & MECH_SEC_PLAINTEXT) != 0) {
469 sasl_server_auth_failed(client,
470 "Plaintext authentication disabled.",
471 AUTH_CLIENT_FAIL_CODE_MECH_SSL_REQUIRED);
472 return;
473 }
474
475 i_zero(&info);
476 info.mech = mech->name;
477 info.service = service;
478 info.session_id = client_get_session_id(client);
479
480 if (!get_cert_username(client, &info.cert_username, &error)) {
481 e_error(client->event,
482 "Cannot get username from certificate: %s", error);
483 sasl_server_auth_failed(client,
484 "Unable to validate certificate",
485 AUTH_CLIENT_FAIL_CODE_AUTHZFAILED);
486 return;
487 }
488
489 if (client->ssl_iostream != NULL) {
490 info.cert_username = ssl_iostream_get_peer_name(client->ssl_iostream);
491 info.ssl_cipher = ssl_iostream_get_cipher(client->ssl_iostream,
492 &info.ssl_cipher_bits);
493 info.ssl_pfs = ssl_iostream_get_pfs(client->ssl_iostream);
494 info.ssl_protocol =
495 ssl_iostream_get_protocol_name(client->ssl_iostream);
496 }
497 info.flags = client_get_auth_flags(client);
498 info.local_ip = client->local_ip;
499 info.remote_ip = client->ip;
500 info.local_port = client->local_port;
501 info.local_name = client->local_name;
502 info.remote_port = client->remote_port;
503 info.real_local_ip = client->real_local_ip;
504 info.real_remote_ip = client->real_remote_ip;
505 info.real_local_port = client->real_local_port;
506 info.real_remote_port = client->real_remote_port;
507 if (client->client_id != NULL)
508 info.client_id = str_c(client->client_id);
509 if (client->forward_fields != NULL)
510 info.forward_fields = str_c(client->forward_fields);
511 info.initial_resp_base64 = initial_resp_base64;
512
513 client->auth_request =
514 auth_client_request_new(auth_client, &info,
515 authenticate_callback, client);
516 }
517
518 static void ATTR_NULL(2, 3)
sasl_server_auth_cancel(struct client * client,const char * reason,const char * code,enum sasl_server_reply reply)519 sasl_server_auth_cancel(struct client *client, const char *reason,
520 const char *code, enum sasl_server_reply reply)
521 {
522 i_assert(client->authenticating);
523
524 if (client->set->auth_verbose && reason != NULL) {
525 const char *auth_name =
526 str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
527 e_info(client->event, "Authenticate %s failed: %s",
528 auth_name, reason);
529 }
530
531 client->authenticating = FALSE;
532 if (client->auth_request != NULL)
533 auth_client_request_abort(&client->auth_request, reason);
534 if (client->master_auth_id != 0)
535 auth_client_send_cancel(auth_client, client->master_auth_id);
536
537 if (code != NULL) {
538 const char *args[2];
539
540 args[0] = t_strconcat("code=", code, NULL);
541 args[1] = NULL;
542 call_client_callback(client, reply, reason, args);
543 return;
544 }
545
546 call_client_callback(client, reply, reason, NULL);
547 }
548
sasl_server_auth_failed(struct client * client,const char * reason,const char * code)549 void sasl_server_auth_failed(struct client *client, const char *reason,
550 const char *code)
551 {
552 sasl_server_auth_cancel(client, reason, code, SASL_SERVER_REPLY_AUTH_FAILED);
553 }
554
sasl_server_auth_abort(struct client * client)555 void sasl_server_auth_abort(struct client *client)
556 {
557 client->auth_try_aborted = TRUE;
558 if (client->anvil_query != NULL) {
559 anvil_client_query_abort(anvil, &client->anvil_query);
560 i_free(client->anvil_request);
561 }
562 sasl_server_auth_cancel(client, NULL, NULL, SASL_SERVER_REPLY_AUTH_ABORTED);
563 }
564