1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "login-common.h"
4 #include "ioloop.h"
5 #include "array.h"
6 #include "str.h"
7 #include "randgen.h"
8 #include "module-dir.h"
9 #include "process-title.h"
10 #include "restrict-access.h"
11 #include "restrict-process-size.h"
12 #include "master-auth.h"
13 #include "master-service.h"
14 #include "master-interface.h"
15 #include "iostream-ssl.h"
16 #include "client-common.h"
17 #include "access-lookup.h"
18 #include "anvil-client.h"
19 #include "auth-client.h"
20 #include "dsasl-client.h"
21 #include "master-service-ssl-settings.h"
22 #include "login-proxy.h"
23 
24 #include <unistd.h>
25 #include <syslog.h>
26 
27 #define AUTH_CLIENT_IDLE_TIMEOUT_MSECS (1000*60)
28 
29 struct login_access_lookup {
30 	struct master_service_connection conn;
31 	struct io *io;
32 
33 	char **sockets, **next_socket;
34 	struct access_lookup *access;
35 };
36 
37 struct event *event_auth;
38 static struct event_category event_category_auth = {
39 	.name = "auth",
40 };
41 
42 struct login_binary *login_binary;
43 struct auth_client *auth_client;
44 struct master_auth *master_auth;
45 bool closing_down, login_debug;
46 struct anvil_client *anvil;
47 const char *login_rawlog_dir = NULL;
48 unsigned int initial_service_count;
49 struct login_module_register login_module_register;
50 ARRAY_TYPE(string) global_alt_usernames;
51 bool login_ssl_initialized;
52 
53 const struct login_settings *global_login_settings;
54 const struct master_service_ssl_settings *global_ssl_settings;
55 const struct master_service_ssl_server_settings *global_ssl_server_settings;
56 void **global_other_settings;
57 
58 static ARRAY(struct ip_addr) login_source_ips_array;
59 const struct ip_addr *login_source_ips;
60 unsigned int login_source_ips_idx, login_source_ips_count;
61 
62 static struct module *modules;
63 static struct timeout *auth_client_to;
64 static const char *post_login_socket;
65 static bool shutting_down = FALSE;
66 static bool ssl_connections = FALSE;
67 static bool auth_connected_once = FALSE;
68 
69 static void login_access_lookup_next(struct login_access_lookup *lookup);
70 
get_first_client(struct client ** client_r)71 static bool get_first_client(struct client **client_r)
72 {
73 	struct client *client = clients;
74 
75 	if (client == NULL)
76 		client = login_proxies_get_first_detached_client();
77 	if (client == NULL)
78 		client = clients_get_first_fd_proxy();
79 	*client_r = client;
80 	return client != NULL;
81 }
82 
login_refresh_proctitle(void)83 void login_refresh_proctitle(void)
84 {
85 	struct client *client;
86 	const char *addr;
87 
88 	if (!global_login_settings->verbose_proctitle)
89 		return;
90 
91 	/* clients_get_count() includes all the clients being served.
92 	   Inside that there are 3 groups:
93 	   1. pre-login clients
94 	   2. post-login clients being proxied to remote hosts
95 	   3. post-login clients being proxied to post-login processes
96 	   Currently the post-login proxying is done only for SSL/TLS
97 	   connections, so we're assuming that they're the same. */
98 	string_t *str = t_str_new(64);
99 	if (clients_get_count() == 0) {
100 		/* no clients */
101 	} else if (clients_get_count() > 1 || !get_first_client(&client)) {
102 		str_printfa(str, "[%u pre-login", clients_get_count() -
103 			    login_proxies_get_detached_count() -
104 			    clients_get_fd_proxies_count());
105 		if (login_proxies_get_detached_count() > 0) {
106 			/* show detached proxies only if they exist, so
107 			   non-proxy servers don't unnecessarily show them. */
108 			str_printfa(str, " + %u proxies",
109 				    login_proxies_get_detached_count());
110 		}
111 		if (clients_get_fd_proxies_count() > 0) {
112 			/* show post-login proxies only if they exist, so
113 			   proxy-only servers don't unnecessarily show them. */
114 			str_printfa(str, " + %u TLS proxies",
115 				    clients_get_fd_proxies_count());
116 		}
117 		str_append_c(str, ']');
118 	} else {
119 		str_append_c(str, '[');
120 		addr = net_ip2addr(&client->ip);
121 		if (addr[0] != '\0')
122 			str_printfa(str, "%s ", addr);
123 		if (client->fd_proxying)
124 			str_append(str, "TLS proxy");
125 		else if (client->destroyed)
126 			str_append(str, "proxy");
127 		else
128 			str_append(str, "pre-login");
129 		str_append_c(str, ']');
130 	}
131 	process_title_set(str_c(str));
132 }
133 
auth_client_idle_timeout(struct auth_client * auth_client)134 static void auth_client_idle_timeout(struct auth_client *auth_client)
135 {
136 	i_assert(clients == NULL);
137 
138 	auth_client_disconnect(auth_client, "idle disconnect");
139 	timeout_remove(&auth_client_to);
140 }
141 
login_client_destroyed(void)142 void login_client_destroyed(void)
143 {
144 	if (clients == NULL && auth_client_to == NULL) {
145 		auth_client_to = timeout_add(AUTH_CLIENT_IDLE_TIMEOUT_MSECS,
146 					     auth_client_idle_timeout,
147 					     auth_client);
148 	}
149 }
150 
login_die(void)151 static void login_die(void)
152 {
153 	shutting_down = TRUE;
154 	login_proxy_kill_idle();
155 
156 	if (!auth_client_is_connected(auth_client)) {
157 		/* we don't have auth client, and we might never get one */
158 		clients_destroy_all();
159 	}
160 }
161 
162 static void
client_connected_finish(const struct master_service_connection * conn)163 client_connected_finish(const struct master_service_connection *conn)
164 {
165 	struct client *client;
166 	const struct login_settings *set;
167 	const struct master_service_ssl_settings *ssl_set;
168 	const struct master_service_ssl_server_settings *ssl_server_set;
169 	pool_t pool;
170 	void **other_sets;
171 
172 	pool = pool_alloconly_create("login client", 8*1024);
173 	set = login_settings_read(pool, &conn->local_ip,
174 				  &conn->remote_ip, NULL,
175 				  &ssl_set, &ssl_server_set, &other_sets);
176 
177 	client = client_alloc(conn->fd, pool, conn, set,
178 			      ssl_set, ssl_server_set);
179 	if (ssl_connections || conn->ssl) {
180 		if (client_init_ssl(client) < 0) {
181 			client_unref(&client);
182 			net_disconnect(conn->fd);
183 			master_service_client_connection_destroyed(master_service);
184 			return;
185 		}
186 	}
187 	client_init(client, other_sets);
188 
189 	timeout_remove(&auth_client_to);
190 }
191 
login_access_lookup_free(struct login_access_lookup * lookup)192 static void login_access_lookup_free(struct login_access_lookup *lookup)
193 {
194 	io_remove(&lookup->io);
195 	if (lookup->access != NULL)
196 		access_lookup_destroy(&lookup->access);
197 	if (lookup->conn.fd != -1) {
198 		if (close(lookup->conn.fd) < 0)
199 			i_error("close(client) failed: %m");
200 		master_service_client_connection_destroyed(master_service);
201 	}
202 
203 	p_strsplit_free(default_pool, lookup->sockets);
204 	i_free(lookup);
205 }
206 
login_access_callback(bool success,void * context)207 static void login_access_callback(bool success, void *context)
208 {
209 	struct login_access_lookup *lookup = context;
210 
211 	if (!success) {
212 		i_info("access(%s): Client refused (rip=%s)",
213 		       *lookup->next_socket,
214 		       net_ip2addr(&lookup->conn.remote_ip));
215 		login_access_lookup_free(lookup);
216 	} else {
217 		lookup->next_socket++;
218 		login_access_lookup_next(lookup);
219 	}
220 }
221 
login_access_lookup_next(struct login_access_lookup * lookup)222 static void login_access_lookup_next(struct login_access_lookup *lookup)
223 {
224 	if (*lookup->next_socket == NULL) {
225 		/* last one */
226 		io_remove(&lookup->io);
227 		client_connected_finish(&lookup->conn);
228 		lookup->conn.fd = -1;
229 		login_access_lookup_free(lookup);
230 		return;
231 	}
232 	lookup->access = access_lookup(*lookup->next_socket, lookup->conn.fd,
233 				       login_binary->protocol,
234 				       login_access_callback, lookup);
235 	if (lookup->access == NULL)
236 		login_access_lookup_free(lookup);
237 }
238 
client_input_error(struct login_access_lookup * lookup)239 static void client_input_error(struct login_access_lookup *lookup)
240 {
241 	char c;
242 	int ret;
243 
244 	ret = recv(lookup->conn.fd, &c, 1, MSG_PEEK);
245 	if (ret <= 0) {
246 		i_info("access(%s): Client disconnected during lookup (rip=%s)",
247 		       *lookup->next_socket,
248 		       net_ip2addr(&lookup->conn.remote_ip));
249 		login_access_lookup_free(lookup);
250 	} else {
251 		/* actual input. stop listening until lookup is done. */
252 		io_remove(&lookup->io);
253 	}
254 }
255 
client_connected(struct master_service_connection * conn)256 static void client_connected(struct master_service_connection *conn)
257 {
258 	const char *access_sockets =
259 		global_login_settings->login_access_sockets;
260 	struct login_access_lookup *lookup;
261 
262 	master_service_client_connection_accept(conn);
263 	if (conn->remote_ip.family != 0) {
264 		/* log the connection's IP address in case we crash. it's of
265 		   course possible that another earlier client causes the
266 		   crash, but this is better than nothing. */
267 		i_set_failure_send_ip(&conn->remote_ip);
268 	}
269 
270 	/* make sure we're connected (or attempting to connect) to auth */
271 	auth_client_connect(auth_client);
272 
273 	if (*access_sockets == '\0') {
274 		/* no access checks */
275 		client_connected_finish(conn);
276 		return;
277 	}
278 
279 	lookup = i_new(struct login_access_lookup, 1);
280 	lookup->conn = *conn;
281 	lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup);
282 	lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " ");
283 	lookup->next_socket = lookup->sockets;
284 
285 	login_access_lookup_next(lookup);
286 }
287 
auth_connect_notify(struct auth_client * client ATTR_UNUSED,bool connected,void * context ATTR_UNUSED)288 static void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
289 				bool connected, void *context ATTR_UNUSED)
290 {
291 	if (connected) {
292 		auth_connected_once = TRUE;
293 		clients_notify_auth_connected();
294 	} else if (shutting_down)
295 		clients_destroy_all();
296 	else if (!auth_connected_once) {
297 		/* auth disconnected without having ever succeeded, so the
298 		   auth process is probably misconfigured. no point in
299 		   keeping the client connections hanging. */
300 		clients_destroy_all_reason("Auth process broken");
301 	}
302 }
303 
anvil_reconnect_callback(void)304 static bool anvil_reconnect_callback(void)
305 {
306 	/* we got disconnected from anvil. we can't reconnect to it since we're
307 	   chrooted, so just die after we've finished handling the current
308 	   connections. */
309 	master_service_stop_new_connections(master_service);
310 	return FALSE;
311 }
312 
login_anvil_init(void)313 void login_anvil_init(void)
314 {
315 	if (anvil != NULL)
316 		return;
317 
318 	anvil = anvil_client_init("anvil", anvil_reconnect_callback, 0);
319 	if (anvil_client_connect(anvil, TRUE) < 0)
320 		i_fatal("Couldn't connect to anvil");
321 }
322 
323 static void
parse_login_source_ips(const char * ips_str)324 parse_login_source_ips(const char *ips_str)
325 {
326 	const char *const *tmp;
327 	struct ip_addr *tmp_ips;
328 	bool skip_nonworking = FALSE;
329 	unsigned int i, tmp_ips_count;
330 	int ret;
331 
332 	if (ips_str[0] == '?') {
333 		/* try binding to the IP immediately. if it doesn't
334 		   work, skip it. (this allows using the same config file for
335 		   all the servers.) */
336 		skip_nonworking = TRUE;
337 		ips_str++;
338 	}
339 	i_array_init(&login_source_ips_array, 4);
340 	for (tmp = t_strsplit_spaces(ips_str, ", "); *tmp != NULL; tmp++) {
341 		ret = net_gethostbyname(*tmp, &tmp_ips, &tmp_ips_count);
342 		if (ret != 0) {
343 			i_error("login_source_ips: net_gethostbyname(%s) failed: %s",
344 				*tmp, net_gethosterror(ret));
345 			continue;
346 		}
347 		for (i = 0; i < tmp_ips_count; i++) {
348 			if (skip_nonworking && net_try_bind(&tmp_ips[i]) < 0)
349 				continue;
350 			array_push_back(&login_source_ips_array, &tmp_ips[i]);
351 		}
352 	}
353 
354 	/* make the array contents easily accessible */
355 	login_source_ips = array_get(&login_source_ips_array,
356 				     &login_source_ips_count);
357 }
358 
login_load_modules(void)359 static void login_load_modules(void)
360 {
361 	struct module_dir_load_settings mod_set;
362 
363 	if (global_login_settings->login_plugins[0] == '\0')
364 		return;
365 
366 	i_zero(&mod_set);
367 	mod_set.abi_version = DOVECOT_ABI_VERSION;
368 	mod_set.binary_name = login_binary->process_name;
369 	mod_set.setting_name = "login_plugins";
370 	mod_set.require_init_funcs = TRUE;
371 	mod_set.debug = login_debug;
372 
373 	modules = module_dir_load(global_login_settings->login_plugin_dir,
374 				  global_login_settings->login_plugins,
375 				  &mod_set);
376 	module_dir_init(modules);
377 }
378 
login_ssl_init(void)379 static void login_ssl_init(void)
380 {
381 	struct ssl_iostream_settings ssl_set;
382 	const char *error;
383 
384 	if (strcmp(global_ssl_settings->ssl, "no") == 0)
385 		return;
386 
387 	master_service_ssl_server_settings_to_iostream_set(global_ssl_settings,
388 		global_ssl_server_settings, pool_datastack_create(), &ssl_set);
389 	if (io_stream_ssl_global_init(&ssl_set, &error) < 0)
390 		i_fatal("Failed to initialize SSL library: %s", error);
391 	login_ssl_initialized = TRUE;
392 }
393 
main_preinit(void)394 static void main_preinit(void)
395 {
396 	unsigned int max_fds;
397 
398 	/* Initialize SSL proxy so it can read certificate and private
399 	   key file. */
400 	login_ssl_init();
401 	dsasl_clients_init();
402 	client_common_init();
403 
404 	/* set the number of fds we want to use. it may get increased or
405 	   decreased. leave a couple of extra fds for auth sockets and such.
406 
407 	   worst case each connection can use:
408 
409 	    - 1 for client
410 	    - 1 for login proxy
411 	    - 2 for client-side ssl proxy
412 	    - 2 for server-side ssl proxy (with login proxy)
413 
414 	   However, login process nowadays supports plugins, there are rawlogs
415 	   and so on. Don't enforce the fd limit anymore, but use this value
416 	   for optimizing the ioloop's fd table size.
417 	*/
418 	max_fds = MASTER_LISTEN_FD_FIRST + 16 +
419 		master_service_get_socket_count(master_service) +
420 		master_service_get_client_limit(master_service)*6;
421 	io_loop_set_max_fd_count(current_ioloop, max_fds);
422 
423 	i_assert(strcmp(global_ssl_settings->ssl, "no") == 0 ||
424 		 login_ssl_initialized);
425 
426 	if (global_login_settings->mail_max_userip_connections > 0)
427 		login_anvil_init();
428 
429 	/* read the login_source_ips before chrooting so it can access
430 	   /etc/hosts */
431 	parse_login_source_ips(global_login_settings->login_source_ips);
432 	if (login_source_ips_count > 0) {
433 		/* randomize the initial index in case service_count=1
434 		   (although in that case it's unlikely this setting is
435 		   even used..) */
436 		login_source_ips_idx = i_rand_limit(login_source_ips_count);
437 	}
438 
439 	login_load_modules();
440 
441 	restrict_access_by_env(0, NULL);
442 	if (login_debug)
443 		restrict_access_allow_coredumps(TRUE);
444 	initial_service_count = master_service_get_service_count(master_service);
445 
446 	if (restrict_access_get_current_chroot() == NULL) {
447 		if (chdir("login") < 0)
448 			i_fatal("chdir(login) failed: %m");
449 	}
450 
451 	if (login_rawlog_dir != NULL &&
452 	    access(login_rawlog_dir, W_OK | X_OK) < 0) {
453 		i_error("access(%s, wx) failed: %m - disabling rawlog",
454 			login_rawlog_dir);
455 		login_rawlog_dir = NULL;
456 	}
457 }
458 
main_init(const char * login_socket)459 static void main_init(const char *login_socket)
460 {
461 	/* make sure we can't fork() */
462 	restrict_process_count(1);
463 
464 	event_auth = event_create(NULL);
465 	event_set_forced_debug(event_auth, global_login_settings->auth_debug);
466 	event_add_category(event_auth, &event_category_auth);
467 
468 	i_array_init(&global_alt_usernames, 4);
469 	master_service_set_avail_overflow_callback(master_service,
470 						   client_destroy_oldest);
471 	master_service_set_die_callback(master_service, login_die);
472 
473 	auth_client = auth_client_init(login_socket, (unsigned int)getpid(),
474 				       FALSE);
475 	auth_client_connect(auth_client);
476         auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
477 	master_auth = master_auth_init(master_service, post_login_socket);
478 
479 	login_binary->init();
480 
481 	login_proxy_init(global_login_settings->login_proxy_notify_path);
482 }
483 
main_deinit(void)484 static void main_deinit(void)
485 {
486 	client_destroy_fd_proxies();
487 	ssl_iostream_context_cache_free();
488 	login_proxy_deinit();
489 
490 	login_binary->deinit();
491 	module_dir_unload(&modules);
492 	auth_client_deinit(&auth_client);
493 	master_auth_deinit(&master_auth);
494 
495 	char *str;
496 	array_foreach_elem(&global_alt_usernames, str)
497 		i_free(str);
498 	array_free(&global_alt_usernames);
499 
500 	if (anvil != NULL)
501 		anvil_client_deinit(&anvil);
502 	timeout_remove(&auth_client_to);
503 	client_common_deinit();
504 	dsasl_clients_deinit();
505 	login_settings_deinit();
506 	event_unref(&event_auth);
507 }
508 
login_binary_run(struct login_binary * binary,int argc,char * argv[])509 int login_binary_run(struct login_binary *binary,
510 		     int argc, char *argv[])
511 {
512 	enum master_service_flags service_flags =
513 		MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN |
514 		MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE |
515 		MASTER_SERVICE_FLAG_HAVE_STARTTLS |
516 		MASTER_SERVICE_FLAG_NO_SSL_INIT;
517 	pool_t set_pool;
518 	const char *login_socket;
519 	int c;
520 
521 	login_binary = binary;
522 	login_socket = binary->default_login_socket != NULL ?
523 		binary->default_login_socket : LOGIN_DEFAULT_SOCKET;
524 	post_login_socket = binary->protocol;
525 
526 	master_service = master_service_init(login_binary->process_name,
527 					     service_flags, &argc, &argv,
528 					     "Dl:R:S");
529 	master_service_init_log(master_service);
530 
531 	while ((c = master_getopt(master_service)) > 0) {
532 		switch (c) {
533 		case 'D':
534 			login_debug = TRUE;
535 			break;
536 		case 'l':
537 			post_login_socket = optarg;
538 			break;
539 		case 'R':
540 			login_rawlog_dir = optarg;
541 			break;
542 		case 'S':
543 			ssl_connections = TRUE;
544 			break;
545 		default:
546 			return FATAL_DEFAULT;
547 		}
548 	}
549 	if (argv[optind] != NULL)
550 		login_socket = argv[optind];
551 
552 	login_binary->preinit();
553 
554 	set_pool = pool_alloconly_create("global login settings", 4096);
555 	global_login_settings =
556 		login_settings_read(set_pool, NULL, NULL, NULL,
557 				    &global_ssl_settings,
558 				    &global_ssl_server_settings,
559 				    &global_other_settings);
560 
561 	main_preinit();
562 	main_init(login_socket);
563 
564 	master_service_init_finish(master_service);
565 	master_service_run(master_service, client_connected);
566 	main_deinit();
567 	array_free(&login_source_ips_array);
568 	pool_unref(&set_pool);
569 	master_service_deinit(&master_service);
570         return 0;
571 }
572