client-common.c revision bb8d0ec26bdd548624d7a7424071cca693b72f55
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "common.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "hostpid.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "llist.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "str.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "str-sanitize.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "var-expand.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "ssl-proxy.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "client-common.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include <stdlib.h>
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstruct client *clients = NULL;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenunsigned int clients_count = 0;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid client_link(struct client *client)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen DLLIST_PREPEND(&clients, client);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen clients_count++;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid client_unlink(struct client *client)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_assert(clients_count > 0);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen clients_count--;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen DLLIST_REMOVE(&clients, client);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainenunsigned int clients_get_count(void)
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen{
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen return clients_count;
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen}
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainen
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenstatic const struct var_expand_table *
7db7fbea5d8a07463b625f93d69166d56018dadfTimo Sirainenget_var_expand_table(struct client *client)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen static struct var_expand_table static_tab[] = {
b4a7dbfb4256abcd2f983d56bd032acd55f59591Timo Sirainen { 'u', NULL },
b4a7dbfb4256abcd2f983d56bd032acd55f59591Timo Sirainen { 'n', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'd', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 's', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'h', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'l', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'r', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'p', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'm', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'a', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'b', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 'c', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { '\0', NULL }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen };
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct var_expand_table *tab;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab = t_malloc(sizeof(static_tab));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (client->virtual_user != NULL) {
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen tab[0].value = client->virtual_user;
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen tab[1].value = t_strcut(client->virtual_user, '@');
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen tab[2].value = strchr(client->virtual_user, '@');
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen if (tab[2].value != NULL) tab[2].value++;
cb3ab2fd5668700a89b274a43595cfbfa1616e4bTimo Sirainen
4487c66123ca4830f8afbf4efcd7a260848d0e05Timo Sirainen for (i = 0; i < 3; i++)
4487c66123ca4830f8afbf4efcd7a260848d0e05Timo Sirainen tab[i].value = str_sanitize(tab[i].value, 80);
4487c66123ca4830f8afbf4efcd7a260848d0e05Timo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[3].value = login_protocol;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[4].value = getenv("HOME");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[5].value = net_ip2addr(&client->local_ip);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[6].value = net_ip2addr(&client->ip);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[7].value = my_pid;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[8].value = client->auth_mech_name == NULL ? NULL :
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_sanitize(client->auth_mech_name, MAX_MECH_NAME);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[9].value = dec2str(client->local_port);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[10].value = dec2str(client->remote_port);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (!client->tls) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[11].value = client->secured ? "secured" : NULL;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *ssl_state = ssl_proxy_is_handshaked(client->proxy) ?
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "TLS" : "TLS handshaking";
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *ssl_error = ssl_proxy_get_last_error(client->proxy);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[11].value = ssl_error == NULL ? ssl_state :
009217abb57a24a4076092e8e4e165545747839eStephan Bosch t_strdup_printf("%s: %s", ssl_state, ssl_error);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return tab;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic bool have_key(const struct var_expand_table *table, const char *str)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen char key;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen key = var_get_key(str);
a618726eb3eb09a3866fe93208baf923d593f4d3Timo Sirainen for (i = 0; table[i].key != '\0'; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (table[i].key == key) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return table[i].value != NULL &&
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen table[i].value[0] != '\0';
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen return FALSE;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void client_syslog_real(struct client *client, const char *msg)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
009217abb57a24a4076092e8e4e165545747839eStephan Bosch static struct var_expand_table static_tab[3] = {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { 's', NULL },
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen { '$', NULL },
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch { '\0', NULL }
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch };
67e0afe62b26d222614b8d817155bf5c74bd7fe0Stephan Bosch const struct var_expand_table *var_expand_table;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct var_expand_table *tab;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *p, *const *e;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen string_t *str;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen var_expand_table = get_var_expand_table(client);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab = t_malloc(sizeof(static_tab));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen memcpy(tab, static_tab, sizeof(static_tab));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str = t_str_new(256);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (e = log_format_elements; *e != NULL; e++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (p = *e; *p != '\0'; p++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (*p != '%' || p[1] == '\0')
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen continue;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen p++;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (have_key(var_expand_table, p)) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (str_len(str) > 0)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append(str, ", ");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen var_expand(str, *e, var_expand_table);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen break;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen tab[0].value = t_strdup(str_c(str));
tab[1].value = msg;
str_truncate(str, 0);
var_expand(str, log_format, tab);
i_info("%s", str_c(str));
}
void client_syslog(struct client *client, const char *msg)
{
T_BEGIN {
client_syslog_real(client, msg);
} T_END;
}