main.c revision a8c5a86d183db25a57bf193c06b41e092ec2e151
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz/* Copyright (c) 2002-2014 Dovecot authors, see the included COPYING file */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz#define AUTH_CLIENT_IDLE_TIMEOUT_MSECS (1000*60)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzconst struct login_settings *global_login_settings;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzconst struct master_service_ssl_settings *global_ssl_settings;
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarzstatic void login_access_lookup_next(struct login_access_lookup *lookup);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (!global_login_settings->verbose_proctitle)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz } else if (clients_get_count() > 1 || client == NULL) {
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz process_title_set(t_strdup_printf("[%u connections (%u TLS)]",
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz clients_get_count(), ssl_proxy_get_count()));
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz process_title_set(t_strdup_printf(client->tls ?
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz process_title_set(client->tls ? "[TLS]" : "");
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzstatic void auth_client_idle_timeout(struct auth_client *auth_client)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz auth_client_disconnect(auth_client, "idle disconnect");
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (clients == NULL && auth_client_to == NULL) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz auth_client_to = timeout_add(AUTH_CLIENT_IDLE_TIMEOUT_MSECS,
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarzstatic void login_die(void)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (!auth_client_is_connected(auth_client)) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* we don't have auth client, and we might never get one */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzclient_connected_finish(const struct master_service_connection *conn)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz const struct master_service_ssl_settings *ssl_set;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (net_getsockname(conn->fd, &local_ip, &local_port) < 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz pool = pool_alloconly_create("login client", 8*1024);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz set = login_settings_read(pool, &local_ip,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz &conn->remote_ip, NULL, &ssl_set, &other_sets);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz client = client_create(conn->fd, FALSE, pool,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz fd_ssl = ssl_proxy_alloc(conn->fd, &conn->remote_ip, pool,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz master_service_client_connection_destroyed(master_service);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz client = client_create(fd_ssl, TRUE, pool,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz client->real_remote_port = client->remote_port = conn->remote_port;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz client->real_local_port = client->local_port = local_port;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void login_access_lookup_free(struct login_access_lookup *lookup)
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz master_service_client_connection_destroyed(master_service);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz p_strsplit_free(default_pool, lookup->sockets);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void login_access_callback(bool success, void *context)
4ee5a85e75d520497bd43dbfcc6fc273f3e57ceaMichael Slusarz struct login_access_lookup *lookup = context;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz i_info("access(%s): Client refused (rip=%s)",
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void login_access_lookup_next(struct login_access_lookup *lookup)
f6fb60c7dcfc88895c8c45514c3fc424d3126336Michael Slusarz /* last one */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz lookup->access = access_lookup(*lookup->next_socket, lookup->conn.fd,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void client_input_error(struct login_access_lookup *lookup)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz ret = recv(lookup->conn.fd, &c, 1, MSG_PEEK);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz i_info("access(%s): Client disconnected during lookup (rip=%s)",
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* actual input. stop listening until lookup is done. */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void client_connected(struct master_service_connection *conn)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz global_login_settings->login_access_sockets;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz master_service_client_connection_accept(conn);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* log the connection's IP address in case we crash. it's of
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz course possible that another earlier client causes the
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz crash, but this is better than nothing. */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* make sure we're connected (or attempting to connect) to auth */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* no access checks */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz lookup = i_new(struct login_access_lookup, 1);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz lookup->io = io_add(conn->fd, IO_READ, client_input_error, lookup);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz lookup->sockets = p_strsplit_spaces(default_pool, access_sockets, " ");
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarzstatic void auth_connect_notify(struct auth_client *client ATTR_UNUSED,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* auth disconnected without having ever succeeded, so the
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz auth process is probably misconfigured. no point in
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz keeping the client connections hanging. */
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz clients_destroy_all_reason("Disconnected: Auth process broken");
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz /* we got disconnected from anvil. we can't reconnect to it since we're
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz chrooted, so just die after we've finished handling the current
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz connections. */
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz master_service_stop_new_connections(master_service);
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarzstatic void main_preinit(bool allow_core_dumps)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* Initialize SSL proxy so it can read certificate and private
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* set the number of fds we want to use. it may get increased or
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz decreased. leave a couple of extra fds for auth sockets and such.
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz worst case each connection can use:
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz - 1 for client
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz - 1 for login proxy
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz - 2 for client-side ssl proxy
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz - 2 for server-side ssl proxy (with login proxy)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz master_service_get_socket_count(master_service) +
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz master_service_get_client_limit(master_service)*6;
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz io_loop_set_max_fd_count(current_ioloop, max_fds);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz i_assert(strcmp(global_ssl_settings->ssl, "no") == 0 ||
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (global_login_settings->mail_max_userip_connections > 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz anvil = anvil_client_init("anvil", anvil_reconnect_callback, 0);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (anvil_client_connect(anvil, TRUE) < 0)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz initial_service_count = master_service_get_service_count(master_service);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz if (restrict_access_get_current_chroot() == NULL) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz access(login_rawlog_dir, W_OK | X_OK) < 0) {
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz i_error("access(%s, wx) failed: %m - disabling rawlog",
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarzstatic void main_init(const char *login_socket)
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz /* make sure we can't fork() */
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz master_service_set_avail_overflow_callback(master_service,
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz master_service_set_die_callback(master_service, login_die);
51ed197520dd9ea534fbc3bc1790ebe3cb5421e2Michael M Slusarz auth_client = auth_client_init(login_socket, (unsigned int)getpid(),
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
e7e9ca33af09b6ab77633bcafe27d751adf09c93Michael Slusarz master_auth = master_auth_init(master_service, login_binary->protocol);
da2423165d31474f5384833fdaa6dc4c0cee28f4Timo Sirainenstatic void main_deinit(void)
const char *login_socket;
return FATAL_DEFAULT;
main_deinit();