1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
2
3 #include "login-common.h"
4 #include "array.h"
5 #include "hostpid.h"
6 #include "llist.h"
7 #include "istream.h"
8 #include "ostream.h"
9 #include "iostream.h"
10 #include "iostream-ssl.h"
11 #include "iostream-proxy.h"
12 #include "iostream-rawlog.h"
13 #include "process-title.h"
14 #include "hook-build.h"
15 #include "buffer.h"
16 #include "str.h"
17 #include "strescape.h"
18 #include "base64.h"
19 #include "str-sanitize.h"
20 #include "safe-memset.h"
21 #include "time-util.h"
22 #include "var-expand.h"
23 #include "master-interface.h"
24 #include "master-service.h"
25 #include "master-service-ssl-settings.h"
26 #include "master-auth.h"
27 #include "anvil-client.h"
28 #include "auth-client.h"
29 #include "dsasl-client.h"
30 #include "login-proxy.h"
31 #include "client-common.h"
32
33 struct client *clients = NULL;
34 struct client *destroyed_clients = NULL;
35 static struct client *last_client = NULL;
36 static unsigned int clients_count = 0;
37
38 static struct client *client_fd_proxies = NULL;
39 static unsigned int client_fd_proxies_count = 0;
40
41 struct login_client_module_hooks {
42 struct module *module;
43 const struct login_client_hooks *hooks;
44 };
45
46 static ARRAY(struct login_client_module_hooks) module_hooks = ARRAY_INIT;
47
48 static const char *client_get_log_str(struct client *client, const char *msg);
49
login_client_hooks_add(struct module * module,const struct login_client_hooks * hooks)50 void login_client_hooks_add(struct module *module,
51 const struct login_client_hooks *hooks)
52 {
53 struct login_client_module_hooks *hook;
54
55 hook = array_append_space(&module_hooks);
56 hook->module = module;
57 hook->hooks = hooks;
58 }
59
login_client_hooks_remove(const struct login_client_hooks * hooks)60 void login_client_hooks_remove(const struct login_client_hooks *hooks)
61 {
62 const struct login_client_module_hooks *module_hook;
63 unsigned int idx = UINT_MAX;
64
65 array_foreach(&module_hooks, module_hook) {
66 if (module_hook->hooks == hooks) {
67 idx = array_foreach_idx(&module_hooks, module_hook);
68 break;
69 }
70 }
71 i_assert(idx != UINT_MAX);
72
73 array_delete(&module_hooks, idx, 1);
74 }
75
hook_login_client_allocated(struct client * client)76 static void hook_login_client_allocated(struct client *client)
77 {
78 const struct login_client_module_hooks *module_hook;
79 struct hook_build_context *ctx;
80
81 ctx = hook_build_init((void *)&client->v, sizeof(client->v));
82 client->vlast = &client->v;
83 array_foreach(&module_hooks, module_hook) {
84 if (module_hook->hooks->client_allocated != NULL) T_BEGIN {
85 module_hook->hooks->client_allocated(client);
86 hook_build_update(ctx, client->vlast);
87 } T_END;
88 }
89 client->vlast = NULL;
90 hook_build_deinit(&ctx);
91 }
92
client_idle_disconnect_timeout(struct client * client)93 static void client_idle_disconnect_timeout(struct client *client)
94 {
95 const char *user_reason, *destroy_reason;
96 unsigned int secs;
97
98 if (client->master_tag != 0) {
99 secs = ioloop_time - client->auth_finished;
100 user_reason = "Timeout while finishing login.";
101 destroy_reason = t_strdup_printf(
102 "Timeout while finishing login (waited %u secs)", secs);
103 e_error(client->event, "%s", destroy_reason);
104 } else if (client->auth_request != NULL) {
105 user_reason =
106 "Disconnected for inactivity during authentication.";
107 destroy_reason = "Inactivity during authentication";
108 } else if (client->login_proxy != NULL) {
109 secs = ioloop_time - client->created.tv_sec;
110 user_reason = "Timeout while finishing login.";
111 destroy_reason = t_strdup_printf(
112 "Logging in timed out "
113 "(state=%s, duration=%us)",
114 client_proxy_get_state(client), secs);
115 e_error(login_proxy_get_event(client->login_proxy),
116 "%s", destroy_reason);
117 } else {
118 user_reason = "Disconnected for inactivity.";
119 destroy_reason = "Inactivity";
120 }
121 client_notify_disconnect(client, CLIENT_DISCONNECT_TIMEOUT, user_reason);
122 client_destroy(client, destroy_reason);
123 }
124
client_open_streams(struct client * client)125 static void client_open_streams(struct client *client)
126 {
127 client->input = i_stream_create_fd(client->fd, LOGIN_MAX_INBUF_SIZE);
128 client->output = o_stream_create_fd(client->fd, LOGIN_MAX_OUTBUF_SIZE);
129 o_stream_set_no_error_handling(client->output, TRUE);
130
131 if (login_rawlog_dir != NULL) {
132 if (iostream_rawlog_create(login_rawlog_dir, &client->input,
133 &client->output) < 0)
134 login_rawlog_dir = NULL;
135 }
136 }
137
138 static const char *
client_log_msg_callback(struct client * client,enum log_type log_type ATTR_UNUSED,const char * message)139 client_log_msg_callback(struct client *client,
140 enum log_type log_type ATTR_UNUSED,
141 const char *message)
142 {
143 return client_get_log_str(client, message);
144 }
145
client_is_trusted(struct client * client)146 static bool client_is_trusted(struct client *client)
147 {
148 const char *const *net;
149 struct ip_addr net_ip;
150 unsigned int bits;
151
152 if (client->set->login_trusted_networks == NULL)
153 return FALSE;
154
155 net = t_strsplit_spaces(client->set->login_trusted_networks, ", ");
156 for (; *net != NULL; net++) {
157 if (net_parse_range(*net, &net_ip, &bits) < 0) {
158 e_error(client->event, "login_trusted_networks: "
159 "Invalid network '%s'", *net);
160 break;
161 }
162
163 if (net_is_in_network(&client->ip, &net_ip, bits))
164 return TRUE;
165 }
166 return FALSE;
167 }
168
169 struct client *
client_alloc(int fd,pool_t pool,const struct master_service_connection * conn,const struct login_settings * set,const struct master_service_ssl_settings * ssl_set,const struct master_service_ssl_server_settings * ssl_server_set)170 client_alloc(int fd, pool_t pool,
171 const struct master_service_connection *conn,
172 const struct login_settings *set,
173 const struct master_service_ssl_settings *ssl_set,
174 const struct master_service_ssl_server_settings *ssl_server_set)
175 {
176 struct client *client;
177
178 i_assert(fd != -1);
179
180 client = login_binary->client_vfuncs->alloc(pool);
181 client->v = *login_binary->client_vfuncs;
182 if (client->v.auth_send_challenge == NULL)
183 client->v.auth_send_challenge = client_auth_send_challenge;
184 if (client->v.auth_parse_response == NULL)
185 client->v.auth_parse_response = client_auth_parse_response;
186
187 client->created = ioloop_timeval;
188 client->refcount = 1;
189
190 client->pool = pool;
191 client->preproxy_pool = pool_alloconly_create(MEMPOOL_GROWING"preproxy pool", 256);
192 client->set = set;
193 client->ssl_set = ssl_set;
194 client->ssl_server_set = ssl_server_set;
195 p_array_init(&client->module_contexts, client->pool, 5);
196
197 client->fd = fd;
198 client->local_ip = conn->local_ip;
199 client->local_port = conn->local_port;
200 client->ip = conn->remote_ip;
201 client->remote_port = conn->remote_port;
202 client->real_local_ip = conn->real_local_ip;
203 client->real_local_port = conn->real_local_port;
204 client->real_remote_ip = conn->real_remote_ip;
205 client->real_remote_port = conn->real_remote_port;
206 client->listener_name = p_strdup(client->pool, conn->name);
207 client->trusted = client_is_trusted(client);
208
209 if (conn->proxied) {
210 client->proxied_ssl = conn->proxy.ssl;
211 client->secured = conn->proxy.ssl || client->trusted;
212 client->ssl_secured = conn->proxy.ssl;
213 client->local_name = conn->proxy.hostname;
214 client->client_cert_common_name = conn->proxy.cert_common_name;
215 } else {
216 client->secured = client->trusted ||
217 net_ip_compare(&conn->real_remote_ip, &conn->real_local_ip);
218 }
219 client->proxy_ttl = LOGIN_PROXY_TTL;
220
221 client->event = event_create(NULL);
222 event_add_category(client->event, &login_binary->event_category);
223 event_add_str(client->event, "local_ip", net_ip2addr(&conn->local_ip));
224 event_add_int(client->event, "local_port", conn->local_port);
225 event_add_str(client->event, "remote_ip", net_ip2addr(&conn->remote_ip));
226 event_add_int(client->event, "remote_port", conn->remote_port);
227 event_set_log_message_callback(client->event, client_log_msg_callback,
228 client);
229
230 client_open_streams(client);
231 return client;
232 }
233
client_init(struct client * client,void ** other_sets)234 void client_init(struct client *client, void **other_sets)
235 {
236 if (last_client == NULL)
237 last_client = client;
238 client->list_type = CLIENT_LIST_TYPE_ACTIVE;
239 DLLIST_PREPEND(&clients, client);
240 clients_count++;
241
242 client->to_disconnect =
243 timeout_add(CLIENT_LOGIN_TIMEOUT_MSECS,
244 client_idle_disconnect_timeout, client);
245
246 hook_login_client_allocated(client);
247 client->v.create(client, other_sets);
248 client->create_finished = TRUE;
249
250 if (auth_client_is_connected(auth_client))
251 client_notify_auth_ready(client);
252 else
253 client_set_auth_waiting(client);
254
255 login_refresh_proctitle();
256 }
257
client_disconnect(struct client * client,const char * reason,bool add_disconnected_prefix)258 void client_disconnect(struct client *client, const char *reason,
259 bool add_disconnected_prefix)
260 {
261 if (client->disconnected)
262 return;
263 client->disconnected = TRUE;
264
265 if (!client->login_success &&
266 !client->no_extra_disconnect_reason && reason != NULL) {
267 const char *extra_reason =
268 client_get_extra_disconnect_reason(client);
269 if (extra_reason[0] != '\0')
270 reason = t_strconcat(reason, " ", extra_reason, NULL);
271 }
272 if (reason != NULL) {
273 struct event *event = client->login_proxy == NULL ?
274 client->event :
275 login_proxy_get_event(client->login_proxy);
276 if (add_disconnected_prefix)
277 e_info(event, "Disconnected: %s", reason);
278 else
279 e_info(event, "%s", reason);
280 }
281
282 if (client->output != NULL)
283 o_stream_uncork(client->output);
284 if (!client->login_success) {
285 io_remove(&client->io);
286 ssl_iostream_destroy(&client->ssl_iostream);
287 iostream_proxy_unref(&client->iostream_fd_proxy);
288 i_stream_close(client->input);
289 o_stream_close(client->output);
290 i_close_fd(&client->fd);
291 } else {
292 /* Login was successful. We may now be proxying the connection,
293 so don't disconnect the client until client_unref(). */
294 if (client->iostream_fd_proxy != NULL) {
295 i_assert(!client->fd_proxying);
296 client->fd_proxying = TRUE;
297 i_assert(client->list_type == CLIENT_LIST_TYPE_DESTROYED);
298 DLLIST_REMOVE(&destroyed_clients, client);
299 client->list_type = CLIENT_LIST_TYPE_FD_PROXY;
300 DLLIST_PREPEND(&client_fd_proxies, client);
301 client_fd_proxies_count++;
302 }
303 }
304 }
305
client_destroy(struct client * client,const char * reason)306 void client_destroy(struct client *client, const char *reason)
307 {
308 i_assert(client->create_finished);
309
310 if (client->destroyed)
311 return;
312 client->destroyed = TRUE;
313
314 if (last_client == client)
315 last_client = client->prev;
316 /* move to destroyed_clients linked list before it's potentially
317 added to client_fd_proxies. */
318 i_assert(!client->fd_proxying);
319 i_assert(client->list_type == CLIENT_LIST_TYPE_ACTIVE);
320 DLLIST_REMOVE(&clients, client);
321 client->list_type = CLIENT_LIST_TYPE_DESTROYED;
322 DLLIST_PREPEND(&destroyed_clients, client);
323
324 client_disconnect(client, reason, !client->login_success);
325
326 pool_unref(&client->preproxy_pool);
327
328 if (client->master_tag != 0) {
329 i_assert(client->auth_request == NULL);
330 i_assert(client->authenticating);
331 i_assert(client->refcount > 1);
332 client->authenticating = FALSE;
333 master_auth_request_abort(master_auth, client->master_tag);
334 client->refcount--;
335 } else if (client->auth_request != NULL ||
336 client->anvil_query != NULL) {
337 i_assert(client->authenticating);
338 sasl_server_auth_abort(client);
339 }
340 i_assert(!client->authenticating);
341 i_assert(client->auth_request == NULL);
342 i_assert(client->anvil_query == NULL);
343
344 timeout_remove(&client->to_disconnect);
345 timeout_remove(&client->to_auth_waiting);
346 str_free(&client->auth_response);
347
348 if (client->proxy_password != NULL) {
349 safe_memset(client->proxy_password, 0,
350 strlen(client->proxy_password));
351 i_free_and_null(client->proxy_password);
352 }
353
354 if (client->proxy_sasl_client != NULL)
355 dsasl_client_free(&client->proxy_sasl_client);
356 if (client->login_proxy != NULL)
357 login_proxy_free(&client->login_proxy);
358 if (client->v.destroy != NULL)
359 client->v.destroy(client);
360 if (client_unref(&client) && initial_service_count == 1) {
361 /* as soon as this connection is done with proxying
362 (or whatever), the process will die. there's no need for
363 authentication anymore, so close the connection.
364 do this only with initial service_count=1, in case there
365 are other clients with pending authentications */
366 auth_client_disconnect(auth_client, "unnecessary connection");
367 }
368 login_client_destroyed();
369 login_refresh_proctitle();
370 }
371
client_destroy_iostream_error(struct client * client)372 void client_destroy_iostream_error(struct client *client)
373 {
374 const char *reason =
375 io_stream_get_disconnect_reason(client->input, client->output);
376 client_destroy(client, reason);
377 }
378
client_destroy_success(struct client * client,const char * reason)379 void client_destroy_success(struct client *client, const char *reason)
380 {
381 client->login_success = TRUE;
382 client_destroy(client, reason);
383 }
384
client_ref(struct client * client)385 void client_ref(struct client *client)
386 {
387 client->refcount++;
388 }
389
client_unref(struct client ** _client)390 bool client_unref(struct client **_client)
391 {
392 struct client *client = *_client;
393
394 *_client = NULL;
395
396 i_assert(client->refcount > 0);
397 if (--client->refcount > 0)
398 return TRUE;
399
400 if (!client->create_finished) {
401 i_stream_unref(&client->input);
402 o_stream_unref(&client->output);
403 pool_unref(&client->preproxy_pool);
404 event_unref(&client->event);
405 pool_unref(&client->pool);
406 return FALSE;
407 }
408
409 i_assert(client->destroyed);
410 i_assert(client->login_proxy == NULL);
411
412 if (client->v.free != NULL)
413 client->v.free(client);
414
415 ssl_iostream_destroy(&client->ssl_iostream);
416 iostream_proxy_unref(&client->iostream_fd_proxy);
417 if (client->fd_proxying) {
418 i_assert(client->list_type == CLIENT_LIST_TYPE_FD_PROXY);
419 DLLIST_REMOVE(&client_fd_proxies, client);
420 i_assert(client_fd_proxies_count > 0);
421 client_fd_proxies_count--;
422 } else {
423 i_assert(client->list_type == CLIENT_LIST_TYPE_DESTROYED);
424 DLLIST_REMOVE(&destroyed_clients, client);
425 }
426 client->list_type = CLIENT_LIST_TYPE_NONE;
427 i_stream_unref(&client->input);
428 o_stream_unref(&client->output);
429 i_close_fd(&client->fd);
430 event_unref(&client->event);
431
432 i_free(client->proxy_user);
433 i_free(client->proxy_master_user);
434 i_free(client->virtual_user);
435 i_free(client->virtual_user_orig);
436 i_free(client->virtual_auth_user);
437 i_free(client->auth_mech_name);
438 i_free(client->master_data_prefix);
439 pool_unref(&client->pool);
440
441 i_assert(clients_count > 0);
442 clients_count--;
443
444 master_service_client_connection_destroyed(master_service);
445 login_refresh_proctitle();
446 return FALSE;
447 }
448
client_common_default_free(struct client * client ATTR_UNUSED)449 void client_common_default_free(struct client *client ATTR_UNUSED)
450 {
451 }
452
client_destroy_oldest(bool kill,struct timeval * created_r)453 bool client_destroy_oldest(bool kill, struct timeval *created_r)
454 {
455 struct client *client;
456
457 if (last_client == NULL) {
458 /* we have no clients */
459 return FALSE;
460 }
461
462 /* destroy the last client that hasn't successfully authenticated yet.
463 this is usually the last client, but don't kill it if it's just
464 waiting for master to finish its job. Also prefer to kill clients
465 that can immediately be killed (i.e. refcount=1) */
466 for (client = last_client; client != NULL; client = client->prev) {
467 if (client->master_tag == 0 && client->refcount == 1)
468 break;
469 }
470 if (client == NULL)
471 client = last_client;
472
473 *created_r = client->created;
474 if (!kill)
475 return TRUE;
476
477 client_notify_disconnect(client, CLIENT_DISCONNECT_RESOURCE_CONSTRAINT,
478 "Connection queue full");
479 client_ref(client);
480 client_destroy(client, "Connection queue full");
481 /* return TRUE only if the client was actually freed */
482 i_assert(client->create_finished);
483 return !client_unref(&client);
484 }
485
clients_destroy_all_reason(const char * reason)486 void clients_destroy_all_reason(const char *reason)
487 {
488 struct client *client, *next;
489
490 for (client = clients; client != NULL; client = next) {
491 next = client->next;
492 client_notify_disconnect(client,
493 CLIENT_DISCONNECT_SYSTEM_SHUTDOWN, reason);
494 client_destroy(client, reason);
495 }
496 }
497
clients_destroy_all(void)498 void clients_destroy_all(void)
499 {
500 clients_destroy_all_reason("Shutting down");
501 }
502
client_sni_callback(const char * name,const char ** error_r,void * context)503 static int client_sni_callback(const char *name, const char **error_r,
504 void *context)
505 {
506 struct client *client = context;
507 struct ssl_iostream_context *ssl_ctx;
508 struct ssl_iostream_settings ssl_set;
509 void **other_sets;
510 const char *error;
511
512 if (client->ssl_servername_settings_read)
513 return 0;
514 client->ssl_servername_settings_read = TRUE;
515
516 client->local_name = p_strdup(client->pool, name);
517 client->set = login_settings_read(client->pool, &client->local_ip,
518 &client->ip, name,
519 &client->ssl_set,
520 &client->ssl_server_set, &other_sets);
521
522 master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
523 client->ssl_server_set, pool_datastack_create(), &ssl_set);
524 if (ssl_iostream_server_context_cache_get(&ssl_set, &ssl_ctx, &error) < 0) {
525 *error_r = t_strdup_printf(
526 "Failed to initialize SSL server context: %s", error);
527 return -1;
528 }
529 ssl_iostream_change_context(client->ssl_iostream, ssl_ctx);
530 ssl_iostream_context_unref(&ssl_ctx);
531 return 0;
532 }
533
client_init_ssl(struct client * client)534 int client_init_ssl(struct client *client)
535 {
536 struct ssl_iostream_context *ssl_ctx;
537 struct ssl_iostream_settings ssl_set;
538 const char *error;
539
540 i_assert(client->fd != -1);
541
542 if (strcmp(client->ssl_set->ssl, "no") == 0) {
543 e_info(client->event, "SSL is disabled (ssl=no)");
544 return -1;
545 }
546
547 master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
548 client->ssl_server_set, pool_datastack_create(), &ssl_set);
549 /* If the client cert is invalid, we'll reply NO to the login
550 command. */
551 ssl_set.allow_invalid_cert = TRUE;
552 if (ssl_iostream_server_context_cache_get(&ssl_set, &ssl_ctx, &error) < 0) {
553 e_error(client->event,
554 "Failed to initialize SSL server context: %s", error);
555 return -1;
556 }
557 if (io_stream_create_ssl_server(ssl_ctx, &ssl_set,
558 &client->input, &client->output,
559 &client->ssl_iostream, &error) < 0) {
560 e_error(client->event,
561 "Failed to initialize SSL connection: %s", error);
562 ssl_iostream_context_unref(&ssl_ctx);
563 return -1;
564 }
565 ssl_iostream_context_unref(&ssl_ctx);
566 ssl_iostream_set_sni_callback(client->ssl_iostream,
567 client_sni_callback, client);
568
569 client->tls = TRUE;
570 client->secured = TRUE;
571 client->ssl_secured = TRUE;
572
573 if (client->starttls) {
574 io_remove(&client->io);
575 if (!client_does_custom_io(client)) {
576 client->io = io_add_istream(client->input,
577 client_input, client);
578 }
579 }
580 return 0;
581 }
582
client_start_tls(struct client * client)583 static void client_start_tls(struct client *client)
584 {
585 client->starttls = TRUE;
586 if (client_init_ssl(client) < 0) {
587 client_notify_disconnect(client,
588 CLIENT_DISCONNECT_INTERNAL_ERROR,
589 "TLS initialization failed.");
590 client_destroy(client, "TLS initialization failed.");
591 return;
592 }
593 login_refresh_proctitle();
594
595 client->v.starttls(client);
596 }
597
client_output_starttls(struct client * client)598 static int client_output_starttls(struct client *client)
599 {
600 int ret;
601
602 if ((ret = o_stream_flush(client->output)) < 0) {
603 client_destroy_iostream_error(client);
604 return 1;
605 }
606
607 if (ret > 0) {
608 o_stream_unset_flush_callback(client->output);
609 client_start_tls(client);
610 }
611 return 1;
612 }
613
client_cmd_starttls(struct client * client)614 void client_cmd_starttls(struct client *client)
615 {
616 if (client->tls) {
617 client->v.notify_starttls(client, FALSE, "TLS is already active.");
618 return;
619 }
620
621 if (!client_is_tls_enabled(client)) {
622 client->v.notify_starttls(client, FALSE, "TLS support isn't enabled.");
623 return;
624 }
625
626 /* remove input handler, SSL proxy gives us a new fd. we also have to
627 remove it in case we have to wait for buffer to be flushed */
628 io_remove(&client->io);
629
630 client->v.notify_starttls(client, TRUE, "Begin TLS negotiation now.");
631
632 /* uncork the old fd */
633 o_stream_uncork(client->output);
634
635 if (o_stream_flush(client->output) <= 0) {
636 /* the buffer has to be flushed */
637 o_stream_set_flush_pending(client->output, TRUE);
638 o_stream_set_flush_callback(client->output,
639 client_output_starttls, client);
640 } else {
641 client_start_tls(client);
642 }
643 }
644
645 static void
iostream_fd_proxy_finished(enum iostream_proxy_side side ATTR_UNUSED,enum iostream_proxy_status status ATTR_UNUSED,struct client * client)646 iostream_fd_proxy_finished(enum iostream_proxy_side side ATTR_UNUSED,
647 enum iostream_proxy_status status ATTR_UNUSED,
648 struct client *client)
649 {
650 /* Destroy the proxy now. The other side of the proxy is still
651 unfinished and we don't want to get back here and unreference
652 the client twice. */
653 iostream_proxy_unref(&client->iostream_fd_proxy);
654 client_unref(&client);
655 }
656
client_get_plaintext_fd(struct client * client,int * fd_r,bool * close_fd_r)657 int client_get_plaintext_fd(struct client *client, int *fd_r, bool *close_fd_r)
658 {
659 int fds[2];
660
661 if (!client->tls) {
662 /* Plaintext connection - We can send the fd directly to
663 the post-login process without any proxying. */
664 *fd_r = client->fd;
665 *close_fd_r = FALSE;
666 return 0;
667 }
668
669 /* We'll have to start proxying from now on until either side
670 disconnects. Create a socketpair where login process is proxying on
671 one side and the other side is sent to the post-login process. */
672 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
673 e_error(client->event, "socketpair() failed: %m");
674 return -1;
675 }
676 fd_set_nonblock(fds[0], TRUE);
677 fd_set_nonblock(fds[1], TRUE);
678
679 struct ostream *output = o_stream_create_fd(fds[0], IO_BLOCK_SIZE);
680 struct istream *input =
681 i_stream_create_fd_autoclose(&fds[0], IO_BLOCK_SIZE);
682 o_stream_set_no_error_handling(output, TRUE);
683
684 i_assert(client->io == NULL);
685
686 client_ref(client);
687 client->iostream_fd_proxy =
688 iostream_proxy_create(input, output,
689 client->input, client->output);
690 i_stream_unref(&input);
691 o_stream_unref(&output);
692
693 iostream_proxy_set_completion_callback(client->iostream_fd_proxy,
694 iostream_fd_proxy_finished,
695 client);
696 iostream_proxy_start(client->iostream_fd_proxy);
697
698 *fd_r = fds[1];
699 *close_fd_r = TRUE;
700 return 0;
701 }
702
clients_get_count(void)703 unsigned int clients_get_count(void)
704 {
705 return clients_count;
706 }
707
clients_get_fd_proxies_count(void)708 unsigned int clients_get_fd_proxies_count(void)
709 {
710 return client_fd_proxies_count;
711 }
712
clients_get_first_fd_proxy(void)713 struct client *clients_get_first_fd_proxy(void)
714 {
715 return client_fd_proxies;
716 }
717
client_add_forward_field(struct client * client,const char * key,const char * value)718 void client_add_forward_field(struct client *client, const char *key,
719 const char *value)
720 {
721 if (client->forward_fields == NULL)
722 client->forward_fields = str_new(client->preproxy_pool, 32);
723 else
724 str_append_c(client->forward_fields, '\t');
725 /* prefixing is done by auth process */
726 str_append_tabescaped(client->forward_fields, key);
727 str_append_c(client->forward_fields, '=');
728 str_append_tabescaped(client->forward_fields, value);
729 }
730
client_get_session_id(struct client * client)731 const char *client_get_session_id(struct client *client)
732 {
733 buffer_t *buf, *base64_buf;
734 struct timeval tv;
735 uint64_t timestamp;
736 unsigned int i;
737
738 if (client->session_id != NULL)
739 return client->session_id;
740
741 buf = t_buffer_create(24);
742 base64_buf = t_buffer_create(24*2);
743
744 i_gettimeofday(&tv);
745 timestamp = tv.tv_usec + (long long)tv.tv_sec * 1000ULL*1000ULL;
746
747 /* add lowest 48 bits of the timestamp. this gives us a bit less than
748 9 years until it wraps */
749 for (i = 0; i < 48; i += 8)
750 buffer_append_c(buf, (timestamp >> i) & 0xff);
751
752 buffer_append_c(buf, client->remote_port & 0xff);
753 buffer_append_c(buf, (client->remote_port >> 8) & 0xff);
754 if (IPADDR_IS_V6(&client->ip))
755 buffer_append(buf, &client->ip.u.ip6, sizeof(client->ip.u.ip6));
756 else
757 buffer_append(buf, &client->ip.u.ip4, sizeof(client->ip.u.ip4));
758 base64_encode(buf->data, buf->used, base64_buf);
759 client->session_id = p_strdup(client->pool, str_c(base64_buf));
760 return client->session_id;
761 }
762
763 static struct var_expand_table login_var_expand_empty_tab[] = {
764 { 'u', NULL, "user" },
765 { 'n', NULL, "username" },
766 { 'd', NULL, "domain" },
767
768 { 's', NULL, "service" },
769 { 'h', NULL, "home" },
770 { 'l', NULL, "lip" },
771 { 'r', NULL, "rip" },
772 { 'p', NULL, "pid" },
773 { 'm', NULL, "mech" },
774 { 'a', NULL, "lport" },
775 { 'b', NULL, "rport" },
776 { 'c', NULL, "secured" },
777 { 'k', NULL, "ssl_security" },
778 { 'e', NULL, "mail_pid" },
779 { '\0', NULL, "session" },
780 { '\0', NULL, "real_lip" },
781 { '\0', NULL, "real_rip" },
782 { '\0', NULL, "real_lport" },
783 { '\0', NULL, "real_rport" },
784 { '\0', NULL, "orig_user" },
785 { '\0', NULL, "orig_username" },
786 { '\0', NULL, "orig_domain" },
787 { '\0', NULL, "auth_user" },
788 { '\0', NULL, "auth_username" },
789 { '\0', NULL, "auth_domain" },
790 { '\0', NULL, "listener" },
791 { '\0', NULL, "local_name" },
792
793 /* aliases: */
794 { '\0', NULL, "local_ip" },
795 { '\0', NULL, "remote_ip" },
796 { '\0', NULL, "local_port" },
797 { '\0', NULL, "remote_port" },
798 { '\0', NULL, "real_local_ip" },
799 { '\0', NULL, "real_remote_ip" },
800 { '\0', NULL, "real_local_port" },
801 { '\0', NULL, "real_remote_port" },
802 { '\0', NULL, "mechanism" },
803 { '\0', NULL, "original_user" },
804 { '\0', NULL, "original_username" },
805 { '\0', NULL, "original_domain" },
806
807 { '\0', NULL, NULL }
808 };
809
810 static void
get_var_expand_users(struct var_expand_table * tab,const char * user)811 get_var_expand_users(struct var_expand_table *tab, const char *user)
812 {
813 unsigned int i;
814
815 tab[0].value = user;
816 tab[1].value = t_strcut(user, '@');
817 tab[2].value = i_strchr_to_next(user, '@');
818
819 for (i = 0; i < 3; i++)
820 tab[i].value = str_sanitize(tab[i].value, 80);
821 }
822
823 static const struct var_expand_table *
get_var_expand_table(struct client * client)824 get_var_expand_table(struct client *client)
825 {
826 struct var_expand_table *tab;
827
828 tab = t_malloc_no0(sizeof(login_var_expand_empty_tab));
829 memcpy(tab, login_var_expand_empty_tab,
830 sizeof(login_var_expand_empty_tab));
831
832 if (client->virtual_user != NULL)
833 get_var_expand_users(tab, client->virtual_user);
834 tab[3].value = login_binary->protocol;
835 tab[4].value = getenv("HOME");
836 tab[27].value = tab[5].value = net_ip2addr(&client->local_ip);
837 tab[28].value = tab[6].value = net_ip2addr(&client->ip);
838 tab[7].value = my_pid;
839 tab[35].value = tab[8].value = client->auth_mech_name == NULL ? NULL :
840 str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
841 tab[29].value = tab[9].value = dec2str(client->local_port);
842 tab[30].value = tab[10].value = dec2str(client->remote_port);
843 if (!client->tls) {
844 tab[11].value = client->secured ? "secured" : NULL;
845 tab[12].value = "";
846 } else if (client->proxied_ssl) {
847 tab[11].value = "TLS";
848 tab[12].value = "(proxied)";
849 } else {
850 const char *ssl_state =
851 ssl_iostream_is_handshaked(client->ssl_iostream) ?
852 "TLS" : "TLS handshaking";
853 const char *ssl_error =
854 ssl_iostream_get_last_error(client->ssl_iostream);
855
856 tab[11].value = ssl_error == NULL ? ssl_state :
857 t_strdup_printf("%s: %s", ssl_state, ssl_error);
858 tab[12].value =
859 ssl_iostream_get_security_string(client->ssl_iostream);
860 }
861 tab[13].value = client->mail_pid == 0 ? "" :
862 dec2str(client->mail_pid);
863 tab[14].value = client_get_session_id(client);
864 tab[31].value = tab[15].value = net_ip2addr(&client->real_local_ip);
865 tab[32].value = tab[16].value = net_ip2addr(&client->real_remote_ip);
866 tab[33].value = tab[17].value = dec2str(client->real_local_port);
867 tab[34].value = tab[18].value = dec2str(client->real_remote_port);
868 if (client->virtual_user_orig != NULL)
869 get_var_expand_users(tab+19, client->virtual_user_orig);
870 else {
871 tab[36].value = tab[19].value = tab[0].value;
872 tab[37].value = tab[20].value = tab[1].value;
873 tab[38].value = tab[21].value = tab[2].value;
874 }
875 if (client->virtual_auth_user != NULL)
876 get_var_expand_users(tab+22, client->virtual_auth_user);
877 else {
878 tab[22].value = tab[19].value;
879 tab[23].value = tab[20].value;
880 tab[24].value = tab[21].value;
881 }
882 tab[25].value = client->listener_name;
883 tab[26].value = str_sanitize(client->local_name, 256);
884 return tab;
885 }
886
have_username_key(const char * str)887 static bool have_username_key(const char *str)
888 {
889 char key;
890
891 for (; *str != '\0'; str++) {
892 if (str[0] == '%' && str[1] != '\0') {
893 str++;
894 key = var_get_key(str);
895 if (key == 'u' || key == 'n')
896 return TRUE;
897 }
898 }
899 return FALSE;
900 }
901
902 static int
client_var_expand_func_passdb(const char * data,void * context,const char ** value_r,const char ** error_r ATTR_UNUSED)903 client_var_expand_func_passdb(const char *data, void *context,
904 const char **value_r,
905 const char **error_r ATTR_UNUSED)
906 {
907 struct client *client = context;
908 const char *field_name = data;
909 unsigned int i;
910 size_t field_name_len;
911
912 *value_r = NULL;
913
914 if (client->auth_passdb_args == NULL)
915 return 1;
916
917 field_name_len = strlen(field_name);
918 for (i = 0; client->auth_passdb_args[i] != NULL; i++) {
919 if (strncmp(client->auth_passdb_args[i], field_name,
920 field_name_len) == 0 &&
921 client->auth_passdb_args[i][field_name_len] == '=') {
922 *value_r = client->auth_passdb_args[i] + field_name_len+1;
923 return 1;
924 }
925 }
926 return 1;
927 }
928
929 static const char *
client_get_log_str(struct client * client,const char * msg)930 client_get_log_str(struct client *client, const char *msg)
931 {
932 static const struct var_expand_func_table func_table[] = {
933 { "passdb", client_var_expand_func_passdb },
934 { NULL, NULL }
935 };
936 static bool expand_error_logged = FALSE;
937 const struct var_expand_table *var_expand_table;
938 char *const *e;
939 const char *error;
940 string_t *str, *str2;
941 unsigned int pos;
942
943 var_expand_table = get_var_expand_table(client);
944
945 str = t_str_new(256);
946 str2 = t_str_new(128);
947 for (e = client->set->log_format_elements_split; *e != NULL; e++) {
948 pos = str_len(str);
949 if (var_expand_with_funcs(str, *e, var_expand_table,
950 func_table, client, &error) <= 0 &&
951 !expand_error_logged) {
952 /* NOTE: Don't log via client->event - it would cause
953 recursion */
954 i_error("Failed to expand log_format_elements=%s: %s",
955 *e, error);
956 expand_error_logged = TRUE;
957 }
958 if (have_username_key(*e)) {
959 /* username is added even if it's empty */
960 } else {
961 str_truncate(str2, 0);
962 if (var_expand(str2, *e, login_var_expand_empty_tab,
963 &error) <= 0) {
964 /* we just logged this error above. no need
965 to do it again. */
966 }
967 if (strcmp(str_c(str)+pos, str_c(str2)) == 0) {
968 /* empty %variables, don't add */
969 str_truncate(str, pos);
970 continue;
971 }
972 }
973
974 if (str_len(str) > 0)
975 str_append(str, ", ");
976 }
977
978 if (str_len(str) > 0)
979 str_truncate(str, str_len(str)-2);
980
981 const struct var_expand_table tab[3] = {
982 { 's', t_strdup(str_c(str)), NULL },
983 { '$', msg, NULL },
984 { '\0', NULL, NULL }
985 };
986
987 str_truncate(str, 0);
988 if (var_expand(str, client->set->login_log_format, tab, &error) <= 0) {
989 /* NOTE: Don't log via client->event - it would cause
990 recursion */
991 i_error("Failed to expand login_log_format=%s: %s",
992 client->set->login_log_format, error);
993 expand_error_logged = TRUE;
994 }
995 return str_c(str);
996 }
997
client_is_tls_enabled(struct client * client)998 bool client_is_tls_enabled(struct client *client)
999 {
1000 return login_ssl_initialized && strcmp(client->ssl_set->ssl, "no") != 0;
1001 }
1002
client_get_extra_disconnect_reason(struct client * client)1003 const char *client_get_extra_disconnect_reason(struct client *client)
1004 {
1005 unsigned int auth_secs = client->auth_first_started == 0 ? 0 :
1006 ioloop_time - client->auth_first_started;
1007
1008 if (client->set->auth_ssl_require_client_cert &&
1009 client->ssl_iostream != NULL) {
1010 if (ssl_iostream_has_broken_client_cert(client->ssl_iostream))
1011 return "(client sent an invalid cert)";
1012 if (!ssl_iostream_has_valid_client_cert(client->ssl_iostream))
1013 return "(client didn't send a cert)";
1014 }
1015
1016 if (!client->notified_auth_ready)
1017 return t_strdup_printf(
1018 "(disconnected before auth was ready, waited %u secs)",
1019 (unsigned int)(ioloop_time - client->created.tv_sec));
1020
1021 if (client->auth_attempts == 0) {
1022 if (!client->banner_sent) {
1023 /* disconnected by a plugin */
1024 return "";
1025 }
1026 return t_strdup_printf("(no auth attempts in %u secs)",
1027 (unsigned int)(ioloop_time - client->created.tv_sec));
1028 }
1029
1030 /* some auth attempts without SSL/TLS */
1031 if (client->set->auth_ssl_require_client_cert &&
1032 client->ssl_iostream == NULL)
1033 return "(cert required, client didn't start TLS)";
1034
1035 if (client->auth_waiting && client->auth_attempts == 1) {
1036 return t_strdup_printf("(client didn't finish SASL auth, "
1037 "waited %u secs)", auth_secs);
1038 }
1039 if (client->auth_request != NULL && client->auth_attempts == 1) {
1040 return t_strdup_printf("(disconnected while authenticating, "
1041 "waited %u secs)", auth_secs);
1042 }
1043 if (client->authenticating && client->auth_attempts == 1) {
1044 return t_strdup_printf("(disconnected while finishing login, "
1045 "waited %u secs)", auth_secs);
1046 }
1047 if (client->auth_try_aborted && client->auth_attempts == 1)
1048 return "(aborted authentication)";
1049 if (client->auth_process_comm_fail)
1050 return "(auth process communication failure)";
1051
1052 if (client->proxy_auth_failed)
1053 return "(proxy dest auth failed)";
1054 if (client->auth_successes > 0) {
1055 return t_strdup_printf("(internal failure, %u successful auths)",
1056 client->auth_successes);
1057 }
1058
1059 switch (client->last_auth_fail) {
1060 case CLIENT_AUTH_FAIL_CODE_AUTHZFAILED:
1061 return t_strdup_printf(
1062 "(authorization failed, %u attempts in %u secs)",
1063 client->auth_attempts, auth_secs);
1064 case CLIENT_AUTH_FAIL_CODE_TEMPFAIL:
1065 return "(auth service reported temporary failure)";
1066 case CLIENT_AUTH_FAIL_CODE_USER_DISABLED:
1067 return "(user disabled)";
1068 case CLIENT_AUTH_FAIL_CODE_PASS_EXPIRED:
1069 return "(password expired)";
1070 case CLIENT_AUTH_FAIL_CODE_INVALID_BASE64:
1071 return "(sent invalid base64 in response)";
1072 case CLIENT_AUTH_FAIL_CODE_LOGIN_DISABLED:
1073 return "(login disabled)";
1074 case CLIENT_AUTH_FAIL_CODE_MECH_INVALID:
1075 return "(tried to use unsupported auth mechanism)";
1076 case CLIENT_AUTH_FAIL_CODE_MECH_SSL_REQUIRED:
1077 return "(tried to use disallowed plaintext auth)";
1078 default:
1079 break;
1080 }
1081
1082 return t_strdup_printf("(auth failed, %u attempts in %u secs)",
1083 client->auth_attempts, auth_secs);
1084 }
1085
client_notify_disconnect(struct client * client,enum client_disconnect_reason reason,const char * text)1086 void client_notify_disconnect(struct client *client,
1087 enum client_disconnect_reason reason,
1088 const char *text)
1089 {
1090 if (!client->notified_disconnect) {
1091 if (client->v.notify_disconnect != NULL)
1092 client->v.notify_disconnect(client, reason, text);
1093 client->notified_disconnect = TRUE;
1094 }
1095 }
1096
client_notify_auth_ready(struct client * client)1097 void client_notify_auth_ready(struct client *client)
1098 {
1099 if (!client->notified_auth_ready) {
1100 if (client->v.notify_auth_ready != NULL)
1101 client->v.notify_auth_ready(client);
1102 client->notified_auth_ready = TRUE;
1103 }
1104 }
1105
client_notify_status(struct client * client,bool bad,const char * text)1106 void client_notify_status(struct client *client, bool bad, const char *text)
1107 {
1108 if (client->v.notify_status != NULL)
1109 client->v.notify_status(client, bad, text);
1110 }
1111
client_common_send_raw_data(struct client * client,const void * data,size_t size)1112 void client_common_send_raw_data(struct client *client,
1113 const void *data, size_t size)
1114 {
1115 ssize_t ret;
1116
1117 ret = o_stream_send(client->output, data, size);
1118 if (ret < 0 || (size_t)ret != size) {
1119 /* either disconnection or buffer full. in either case we want
1120 this connection destroyed. however destroying it here might
1121 break things if client is still tried to be accessed without
1122 being referenced.. */
1123 i_stream_close(client->input);
1124 }
1125 }
1126
client_send_raw_data(struct client * client,const void * data,size_t size)1127 void client_send_raw_data(struct client *client, const void *data, size_t size)
1128 {
1129 client->v.send_raw_data(client, data, size);
1130 }
1131
client_send_raw(struct client * client,const char * data)1132 void client_send_raw(struct client *client, const char *data)
1133 {
1134 client_send_raw_data(client, data, strlen(data));
1135 }
1136
client_read(struct client * client)1137 bool client_read(struct client *client)
1138 {
1139 switch (i_stream_read(client->input)) {
1140 case -2:
1141 /* buffer full */
1142 client_notify_disconnect(client,
1143 CLIENT_DISCONNECT_RESOURCE_CONSTRAINT,
1144 "Input buffer full, aborting");
1145 client_destroy(client, "Input buffer full");
1146 return FALSE;
1147 case -1:
1148 /* disconnected */
1149 client_destroy_iostream_error(client);
1150 return FALSE;
1151 case 0:
1152 /* nothing new read */
1153 return i_stream_get_data_size(client->input) > 0;
1154 default:
1155 /* something was read */
1156 return TRUE;
1157 }
1158 }
1159
client_input(struct client * client)1160 void client_input(struct client *client)
1161 {
1162 i_assert(client->v.input != NULL);
1163 client->v.input(client);
1164 }
1165
client_common_init(void)1166 void client_common_init(void)
1167 {
1168 i_array_init(&module_hooks, 32);
1169 }
1170
client_destroy_fd_proxies(void)1171 void client_destroy_fd_proxies(void)
1172 {
1173 while (client_fd_proxies != NULL) {
1174 struct client *client = client_fd_proxies;
1175 client_unref(&client);
1176 }
1177 i_assert(client_fd_proxies_count == 0);
1178 }
1179
client_common_deinit(void)1180 void client_common_deinit(void)
1181 {
1182 i_assert(destroyed_clients == NULL);
1183 array_free(&module_hooks);
1184 }
1185