Ejemplo n.º 1
0
static void client_start_tls(struct client *client)
{
	int fd_ssl;

	client_ref(client);
	if (!client_unref(&client) || client->destroyed)
		return;

	fd_ssl = ssl_proxy_alloc(client->fd, &client->ip, client->pool,
				 client->set, client->ssl_set,
				 &client->ssl_proxy);
	if (fd_ssl == -1) {
		client_notify_disconnect(client,
			CLIENT_DISCONNECT_INTERNAL_ERROR,
			"TLS initialization failed.");
		client_destroy(client,
			"Disconnected: TLS initialization failed.");
		return;
	}
	ssl_proxy_set_client(client->ssl_proxy, client);
	ssl_proxy_start(client->ssl_proxy);

	client->starttls = TRUE;
	client->tls = TRUE;
	client->secured = TRUE;
	login_refresh_proctitle();

	client->fd = fd_ssl;
	client->io = io_add(client->fd, IO_READ, client_input, client);
	i_stream_unref(&client->input);
	o_stream_unref(&client->output);
	client_open_streams(client);

	client->v.starttls(client);
}
Ejemplo n.º 2
0
bool client_unref(struct client **_client)
{
	struct client *client = *_client;

	i_assert(client->refcount > 0);
	if (--client->refcount > 0)
		return TRUE;

	*_client = NULL;

	i_assert(client->destroyed);
	i_assert(client->ssl_proxy == NULL);
	i_assert(client->login_proxy == NULL);

	if (client->input != NULL)
		i_stream_unref(&client->input);
	if (client->output != NULL)
		o_stream_unref(&client->output);

	i_free(client->proxy_user);
	i_free(client->proxy_master_user);
	i_free(client->virtual_user);
	i_free(client->auth_mech_name);
	pool_unref(&client->pool);

	i_assert(clients_count > 0);
	clients_count--;

	master_service_client_connection_destroyed(master_service);
	login_refresh_proctitle();
	return FALSE;
}
Ejemplo n.º 3
0
struct client *
client_create(int fd, bool ssl, pool_t pool,
	      const struct login_settings *set,
	      const struct master_service_ssl_settings *ssl_set,
	      void **other_sets,
	      const struct ip_addr *local_ip, const struct ip_addr *remote_ip)
{
	struct client *client;

	i_assert(fd != -1);

	client = login_binary->client_vfuncs->alloc(pool);
	client->v = *login_binary->client_vfuncs;
	if (client->v.auth_send_challenge == NULL)
		client->v.auth_send_challenge = client_auth_send_challenge;
	if (client->v.auth_parse_response == NULL)
		client->v.auth_parse_response = client_auth_parse_response;

	client->created = ioloop_time;
	client->refcount = 1;

	client->pool = pool;
	client->set = set;
	client->ssl_set = ssl_set;
	client->real_local_ip = client->local_ip = *local_ip;
	client->real_remote_ip = client->ip = *remote_ip;
	client->fd = fd;
	client->tls = ssl;
	client->trusted = client_is_trusted(client);
	client->secured = ssl || client->trusted ||
		net_ip_compare(remote_ip, local_ip);
	client->proxy_ttl = LOGIN_PROXY_TTL;

	if (last_client == NULL)
		last_client = client;
	DLLIST_PREPEND(&clients, client);
	clients_count++;

	client->to_disconnect =
		timeout_add(CLIENT_LOGIN_TIMEOUT_MSECS,
			    client_idle_disconnect_timeout, client);
	client_open_streams(client);

	client->v.create(client, other_sets);

	if (auth_client_is_connected(auth_client))
		client_notify_auth_ready(client);
	else
		client_set_auth_waiting(client);

	login_refresh_proctitle();
	return client;
}
Ejemplo n.º 4
0
void client_destroy(struct client *client, const char *reason)
{
	if (client->destroyed)
		return;
	client->destroyed = TRUE;

	if (!client->login_success && reason != NULL) {
		reason = t_strconcat(reason, " ",
			client_get_extra_disconnect_reason(client), NULL);
	}
	if (reason != NULL)
		client_log(client, reason);

	if (last_client == client)
		last_client = client->prev;
	DLLIST_REMOVE(&clients, client);

	if (client->input != NULL)
		i_stream_close(client->input);
	if (client->output != NULL)
		o_stream_close(client->output);

	if (client->master_tag != 0) {
		i_assert(client->auth_request == NULL);
		i_assert(client->authenticating);
		i_assert(client->refcount > 1);
		client->authenticating = FALSE;
		master_auth_request_abort(master_auth, client->master_tag);
		client->refcount--;
	} else if (client->auth_request != NULL) {
		i_assert(client->authenticating);
		sasl_server_auth_abort(client);
	} else {
		i_assert(!client->authenticating);
	}

	if (client->io != NULL)
		io_remove(&client->io);
	if (client->to_disconnect != NULL)
		timeout_remove(&client->to_disconnect);
	if (client->to_auth_waiting != NULL)
		timeout_remove(&client->to_auth_waiting);
	if (client->auth_response != NULL)
		str_free(&client->auth_response);

	if (client->fd != -1) {
		net_disconnect(client->fd);
		client->fd = -1;
	}

	if (client->proxy_password != NULL) {
		safe_memset(client->proxy_password, 0,
			    strlen(client->proxy_password));
		i_free_and_null(client->proxy_password);
	}

	if (client->proxy_sasl_client != NULL)
		dsasl_client_free(&client->proxy_sasl_client);
	if (client->login_proxy != NULL)
		login_proxy_free(&client->login_proxy);
	if (client->v.destroy != NULL)
		client->v.destroy(client);
	if (client_unref(&client) && initial_service_count == 1) {
		/* as soon as this connection is done with proxying
		   (or whatever), the process will die. there's no need for
		   authentication anymore, so close the connection.
		   do this only with initial service_count=1, in case there
		   are other clients with pending authentications */
		auth_client_disconnect(auth_client, "unnecessary connection");
	}
	login_client_destroyed();
	login_refresh_proctitle();
}