client-common.c revision 46ec792dd4ccf6c34706c4774228301fafde6aa9
/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "hostpid.h"
#include "llist.h"
#include "istream.h"
#include "ostream.h"
#include "process-title.h"
#include "str.h"
#include "str-sanitize.h"
#include "safe-memset.h"
#include "var-expand.h"
#include "master-service.h"
#include "master-auth.h"
#include "auth-client.h"
#include "login-proxy.h"
#include "ssl-proxy.h"
#include "client-common.h"
#include <stdlib.h>
/* When max. number of simultaneous connections is reached, few of the
oldest connections are disconnected. Since we have to go through all of the
clients, it's faster if we disconnect multiple clients. */
#define CLIENT_DESTROY_OLDEST_COUNT 16
static unsigned int clients_count = 0;
{
"Disconnected for inactivity.");
}
{
}
const struct login_settings *set,
{
/* reached max. users count, kill few of the
oldest connections */
}
/* always use nonblocking I/O */
client->v = client_vfuncs;
else
return client;
}
{
return;
}
i_assert(clients_count > 0);
if (client->master_tag != 0) {
} else {
}
}
}
}
{
}
{
"Internal login failure. "
"Refer to server log for more information.");
}
{
}
{
return TRUE;
}
return FALSE;
}
void client_destroy_oldest(void)
{
unsigned int max_connections =
unsigned int i, destroy_count;
/* find the oldest clients and put them to destroy-buffer */
for (i = 0; i < destroy_count; i++) {
if (destroy_buf[i] == NULL ||
/* @UNSAFE */
sizeof(destroy_buf) -
(i+1) * sizeof(destroy_buf[0]));
destroy_buf[i] = client;
break;
}
}
}
/* then kill them */
for (i = 0; i < destroy_count; i++) {
if (destroy_buf[i] == NULL)
break;
"Disconnected: Connection queue full");
}
}
void clients_destroy_all(void)
{
}
}
{
int fd_ssl;
return;
if (fd_ssl == -1) {
"TLS initialization failed.");
"Disconnected: TLS initialization failed.");
return;
}
}
{
int ret;
return 1;
}
if (ret > 0) {
}
return 1;
}
{
"TLS is already active.");
return;
}
if (!ssl_initialized) {
"TLS support isn't enabled.");
return;
}
/* remove input handler, SSL proxy gives us a new fd. we also have to
remove it in case we have to wait for buffer to be flushed */
"Begin TLS negotiation now.");
/* uncork the old fd */
/* the buffer has to be flushed */
} else {
}
}
unsigned int clients_get_count(void)
{
return clients_count;
}
{
const char *addr;
return;
addr = "??";
}
static const struct var_expand_table *
{
static struct var_expand_table static_tab[] = {
};
struct var_expand_table *tab;
unsigned int i;
for (i = 0; i < 3; i++)
}
} else {
const char *ssl_state =
"TLS" : "TLS handshaking";
const char *ssl_error =
}
return tab;
}
{
char key;
unsigned int i;
}
}
return FALSE;
}
static const char *
{
};
const struct var_expand_table *var_expand_table;
struct var_expand_table *tab;
const char *p;
char *const *e;
for (p = *e; *p != '\0'; p++) {
if (*p != '%' || p[1] == '\0')
continue;
p++;
if (have_key(var_expand_table, p)) {
break;
}
}
}
str_truncate(str, 0);
}
{
T_BEGIN {
} T_END;
}
{
T_BEGIN {
} T_END;
}
{
const char *const *net;
unsigned int bits;
return FALSE;
i_error("login_trusted_networks: "
"Invalid network '%s'", *net);
break;
}
return TRUE;
}
return FALSE;
}
{
return "(client sent an invalid cert)";
return "(client didn't send a cert)";
}
if (client->auth_attempts == 0)
return "(no auth attempts)";
return "(tried to use disabled plaintext auth)";
return "(cert required, client didn't start TLS)";
return t_strdup_printf("(auth failed, %u attempts)",
}
const char *text)
{
}
{
/* either disconnection or buffer full. in either case we want
this connection destroyed. however destroying it here might
break things if client is still tried to be accessed without
being referenced.. */
}
}
{
}
{
case -2:
/* buffer full */
"Input buffer full, aborting");
return FALSE;
case -1:
/* disconnected */
return FALSE;
case 0:
/* nothing new read */
return TRUE;
default:
/* something was read */
return TRUE;
}
}
{
}