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