client-common.c revision 506e41a4efbc7f4bba93cd295ca4dba18ed3cf09
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2002-2010 Dovecot authors, see the included COPYING file */
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainenstruct client *clients = NULL, *last_client = NULL;
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainenstatic unsigned int clients_count = 0;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenstatic void client_idle_disconnect_timeout(struct client *client)
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_BYE,
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen "Disconnected for inactivity.");
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen client_destroy(client, "Disconnected: Inactivity");
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenstatic void client_open_streams(struct client *client)
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen i_stream_create_fd(client->fd, LOGIN_MAX_INBUF_SIZE, FALSE);
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen o_stream_create_fd(client->fd, LOGIN_MAX_OUTBUF_SIZE, FALSE);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen const struct login_settings *set, void **other_sets,
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainen const struct ip_addr *local_ip, const struct ip_addr *remote_ip)
b346610430690398b8c840006004a2df4aa8ce92Timo Sirainen client->v.auth_send_challenge = client_auth_send_challenge;
b346610430690398b8c840006004a2df4aa8ce92Timo Sirainen client->v.auth_parse_response = client_auth_parse_response;
7212243efb0d8fa1cd8b2e37b7498323540b9e97Timo Sirainenvoid client_destroy(struct client *client, const char *reason)
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen if (!client->login_success && reason != NULL) {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen client_get_extra_disconnect_reason(client), NULL);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen master_auth_request_abort(master_auth, client->master_tag);
3b426f49d36187895debdda67fff09f97941881cTimo Sirainen master_service_get_service_count(master_service) == 1) {
3b426f49d36187895debdda67fff09f97941881cTimo Sirainen /* as soon as this connection is done with proxying
3b426f49d36187895debdda67fff09f97941881cTimo Sirainen (or whatever), the process will die. there's no need for
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen authentication anymore, so close the connection. */
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenvoid client_destroy_success(struct client *client, const char *reason)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid client_destroy_internal_failure(struct client *client)
61ddcdc28f50d9cb9994fcc4ad63f9dff0e80628Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_AUTH_FAIL_TEMP,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Internal login failure. "
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen "Refer to server log for more information.");
439942f89a77180719644e7af3752a8329259eb9Timo Sirainen client_destroy(client, "Internal login failure");
9404a7b90dcb80d31bd37ee2493f03751acdb1bdTimo Sirainen master_service_client_connection_destroyed(master_service);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen /* we have no clients */
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen /* destroy the last client that hasn't successfully authenticated yet.
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen this is usually the last client, but don't kill it if it's just
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen waiting for master to finish its job. */
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen for (client = last_client; client != NULL; client = client->prev) {
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen client_destroy(client, "Disconnected: Connection queue full");
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen for (client = clients; client != NULL; client = next) {
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen client_destroy(client, "Disconnected: Shutting down");
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainenstatic void client_start_tls(struct client *client)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen if (!client_unref(&client) || client->destroyed)
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainen fd_ssl = ssl_proxy_alloc(client->fd, &client->ip,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen client_send_line(client, CLIENT_CMD_REPLY_BYE,
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen "TLS initialization failed.");
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen "Disconnected: TLS initialization failed.");
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen ssl_proxy_set_client(client->ssl_proxy, client);
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen client->io = io_add(client->fd, IO_READ, client_input, client);
439942f89a77180719644e7af3752a8329259eb9Timo Sirainenstatic int client_output_starttls(struct client *client)
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen if ((ret = o_stream_flush(client->output)) < 0) {
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen o_stream_unset_flush_callback(client->output);
if (!ssl_initialized) {
unsigned int clients_get_count(void)
return clients_count;
static const struct var_expand_table *
const char *ssl_state =
const char *ssl_error =
return tab;
char key;
return FALSE;
T_BEGIN {
} T_END;
T_BEGIN {
} T_END;
const char *const *net;
unsigned int bits;
return FALSE;
return TRUE;
return FALSE;
const char *text)
return FALSE;
return FALSE;
return TRUE;
return TRUE;