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