main.c revision 296acbaddb68301e5ae3579a1da9325064c4dca8
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#define AUTH_CLIENT_IDLE_TIMEOUT_MSECS (1000*60)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct login_module_register login_module_register;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst struct login_settings *global_login_settings;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenconst struct master_service_ssl_settings *global_ssl_settings;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenunsigned int login_source_ips_idx, login_source_ips_count;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic const char *post_login_socket;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_access_lookup_next(struct login_access_lookup *lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool get_first_client(struct client **client_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen client = login_proxies_get_first_detached_client();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (!global_login_settings->verbose_proctitle)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* clients_get_count() includes all the clients being served.
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen Inside that there are 3 groups:
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen 1. pre-login clients
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen 2. post-login clients being proxied to remote hosts
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen 3. post-login clients being proxied to post-login processes
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen Currently the post-login proxying is done only for SSL/TLS
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen connections, so we're assuming that they're the same. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* no clients */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else if (clients_get_count() > 1 || !get_first_client(&client)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_printfa(str, "[%u pre-login", clients_get_count() -
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* show detached proxies only if they exist, so
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen non-proxy servers don't unnecessarily show them. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* show post-login proxies only if they exist, so
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen proxy-only servers don't unnecessarily show them. */
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainenstatic void auth_client_idle_timeout(struct auth_client *auth_client)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth_client_disconnect(auth_client, "idle disconnect");
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen if (clients == NULL && auth_client_to == NULL) {
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen auth_client_to = timeout_add(AUTH_CLIENT_IDLE_TIMEOUT_MSECS,
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenstatic void login_die(void)
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen /* we don't have auth client, and we might never get one */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenclient_connected_finish(const struct master_service_connection *conn)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const struct master_service_ssl_settings *ssl_set;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pool = pool_alloconly_create("login client", 8*1024);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen set = login_settings_read(pool, &conn->local_ip,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen &conn->remote_ip, NULL, &ssl_set, &other_sets);
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen client = client_alloc(conn->fd, pool, conn, set, ssl_set);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_client_connection_destroyed(master_service);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_access_lookup_free(struct login_access_lookup *lookup)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_client_connection_destroyed(master_service);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen p_strsplit_free(default_pool, lookup->sockets);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_access_callback(bool success, void *context)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Boschstatic void login_access_lookup_next(struct login_access_lookup *lookup)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch /* last one */
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch lookup->access = access_lookup(*lookup->next_socket, lookup->conn.fd,
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Boschstatic void client_input_error(struct login_access_lookup *lookup)
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch i_info("access(%s): Client disconnected during lookup (rip=%s)",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* actual input. stop listening until lookup is done. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void client_connected(struct master_service_connection *conn)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_client_connection_accept(conn);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* log the connection's IP address in case we crash. it's of
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen course possible that another earlier client causes the
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen crash, but this is better than nothing. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* make sure we're connected (or attempting to connect) to auth */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* no access checks */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lookup = i_new(struct login_access_lookup, 1);
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " ");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen /* auth disconnected without having ever succeeded, so the
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen auth process is probably misconfigured. no point in
e25c9a57d651456a5f446a98e677c8c472c4ce98Timo Sirainen keeping the client connections hanging. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen clients_destroy_all_reason("Disconnected: Auth process broken");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* we got disconnected from anvil. we can't reconnect to it since we're
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen chrooted, so just die after we've finished handling the current
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen connections. */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_stop_new_connections(master_service);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen anvil = anvil_client_init("anvil", anvil_reconnect_callback, 0);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic const struct ip_addr *
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenparse_login_source_ips(const char *ips_str, unsigned int *count_r)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *const *tmp;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i, tmp_ips_count;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* try binding to the IP immediately. if it doesn't
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen work, skip it. (this allows using the same config file for
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen all the servers.) */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (tmp = t_strsplit_spaces(ips_str, ", "); *tmp != NULL; tmp++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret = net_gethostbyname(*tmp, &tmp_ips, &tmp_ips_count);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_error("login_source_ips: net_gethostbyname(%s) failed: %s",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (i = 0; i < tmp_ips_count; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (skip_nonworking && net_try_bind(&tmp_ips[i]) < 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_load_modules(void)
d368aabf3ff5411afee1b4af8261163296723e19Timo Sirainen if (global_login_settings->login_plugins[0] == '\0')
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen mod_set.binary_name = login_binary->process_name;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen modules = module_dir_load(global_login_settings->login_plugin_dir,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void login_ssl_init(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (strcmp(global_ssl_settings->ssl, "no") == 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen master_service_ssl_settings_to_iostream_set(global_ssl_settings,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen MASTER_SERVICE_SSL_SETTINGS_TYPE_SERVER, &ssl_set);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (io_stream_ssl_global_init(&ssl_set, &error) < 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_fatal("Failed to initialize SSL library: %s", error);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void main_preinit(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int max_fds;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* Initialize SSL proxy so it can read certificate and private
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* set the number of fds we want to use. it may get increased or
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen decreased. leave a couple of extra fds for auth sockets and such.
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen worst case each connection can use:
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen - 1 for client
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen - 1 for login proxy
00b706a9ea136a5945f4ebafaa4ba958b641635dTimo Sirainen - 2 for client-side ssl proxy
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen - 2 for server-side ssl proxy (with login proxy)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen However, login process nowadays supports plugins, there are rawlogs
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen and so on. Don't enforce the fd limit anymore, but use this value
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for optimizing the ioloop's fd table size.
if (login_source_ips_count > 0) {
if (login_debug)
FALSE);
static void main_deinit(void)
char **strp;
const char *login_socket;
return FATAL_DEFAULT;
main_preinit();
main_deinit();