Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7920:3644883cf44e HEAD
Support transferring original IPs and ports through IMAP proxies.
Clients from login_trusted_networks are allowed to override them. Dovecot's
IMAP proxy sends them via IMAP ID command. They're always sent if the remote
advertises ID in the banner's CAPABILITY.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 21 Jun 2008 10:10:06 +0300 |
parents | 423b8e3fedbb |
children | 9a7469e52f91 |
files | dovecot-example.conf src/imap-login/client.c src/imap-login/imap-proxy.c src/login-common/client-common.c src/login-common/client-common.h src/login-common/common.h src/login-common/main.c src/master/login-process.c src/master/master-settings-defs.c src/master/master-settings.c src/master/master-settings.h src/pop3-login/client.c |
diffstat | 12 files changed, 118 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Sat Jun 21 09:54:26 2008 +0300 +++ b/dovecot-example.conf Sat Jun 21 10:10:06 2008 +0300 @@ -174,6 +174,12 @@ # Greeting message for clients. #login_greeting = Dovecot ready. +# Space separated list of trusted network ranges. Connections from these +# IPs are allowed to override their IP addresses and ports (for logging and +# for authentication checks). disable_plaintext_auth is also ignored for +# these networks. Typically you'd specify your IMAP proxy servers here. +#login_trusted_networks = + # Space-separated list of elements we want to log. The elements which have # a non-empty variable value are joined together to form a comma-separated # string.
--- a/src/imap-login/client.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/imap-login/client.c Sat Jun 21 10:10:06 2008 +0300 @@ -200,12 +200,40 @@ return 1; } +static void +client_update_info(struct imap_client *client, const struct imap_arg *args) +{ + const char *key, *value; + + if (args->type != IMAP_ARG_LIST) + return; + args = IMAP_ARG_LIST_ARGS(args); + + while (args->type == IMAP_ARG_STRING && + args[1].type == IMAP_ARG_STRING) { + key = IMAP_ARG_STR_NONULL(&args[0]); + value = IMAP_ARG_STR_NONULL(&args[1]); + if (strcasecmp(key, "x-originating-ip") == 0) + (void)net_addr2ip(value, &client->common.ip); + else if (strcasecmp(key, "x-originating-port") == 0) + client->common.remote_port = atoi(value); + else if (strcasecmp(key, "x-local-ip") == 0) + (void)net_addr2ip(value, &client->common.local_ip); + else if (strcasecmp(key, "x-local-port") == 0) + client->common.local_port = atoi(value); + args += 2; + } +} + static int cmd_id(struct imap_client *client, const struct imap_arg *args) { const char *env, *value; if (!client->id_logged) { client->id_logged = TRUE; + if (client->common.trusted) + client_update_info(client, args); + env = getenv("IMAP_ID_LOG"); value = imap_id_args_get_log_reply(args, env); if (value != NULL) { @@ -478,12 +506,14 @@ client = i_new(struct imap_client, 1); client->created = ioloop_time; client->refcount = 1; - client->common.tls = ssl; - client->common.secured = ssl || net_ip_compare(ip, local_ip); client->common.local_ip = *local_ip; client->common.ip = *ip; client->common.fd = fd; + client->common.tls = ssl; + client->common.trusted = client_is_trusted(&client->common); + client->common.secured = ssl || client->common.trusted || + net_ip_compare(ip, local_ip); client_open_streams(client, fd); client->io = io_add(fd, IO_READ, client_input, client);
--- a/src/imap-login/imap-proxy.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/imap-login/imap-proxy.c Sat Jun 21 10:10:06 2008 +0300 @@ -11,6 +11,41 @@ #include "imap-quote.h" #include "imap-proxy.h" +static bool imap_banner_has_capability(const char *line, const char *capability) +{ + unsigned int capability_len = strlen(capability); + + if (strncmp(line, "[CAPABILITY ", 12) != 0) + return FALSE; + + line += 12; + while (strncmp(line, capability, capability_len) != 0 || + (line[capability_len] != ' ' && + line[capability_len] != '\0')) { + /* skip over the capability */ + while (*line != ' ') { + if (*line == '\0') + return FALSE; + line++; + } + line++; + } + return TRUE; +} + +static void proxy_write_id(struct imap_client *client, string_t *str) +{ + str_printfa(str, "I ID (" + "\"x-originating-ip\" \"%s\" " + "\"x-originating-port\" \"%u\" " + "\"x-local-ip\" \"%s\" " + "\"x-local-port\" \"%u\")\r\n", + net_ip2addr(&client->common.ip), + client->common.remote_port, + net_ip2addr(&client->common.local_ip), + client->common.local_port); +} + static int proxy_input_line(struct imap_client *client, struct ostream *output, const char *line) { @@ -29,8 +64,11 @@ return -1; } + str = t_str_new(128); + if (imap_banner_has_capability(line + 5, "ID")) + proxy_write_id(client, str); + /* send LOGIN command */ - str = t_str_new(128); str_append(str, "P LOGIN "); imap_quote_append_string(str, client->proxy_user, FALSE); str_append_c(str, ' ');
--- a/src/login-common/client-common.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/login-common/client-common.c Sat Jun 21 10:10:06 2008 +0300 @@ -151,3 +151,26 @@ client_syslog_real(client, msg); } T_END; } + +bool client_is_trusted(struct client *client) +{ + const char *const *net; + struct ip_addr net_ip; + unsigned int bits; + + if (trusted_networks == NULL) + return FALSE; + + net = t_strsplit_spaces(trusted_networks, ", "); + for (; *net != NULL; net++) { + if (net_parse_range(*net, &net_ip, &bits) < 0) { + i_error("login_trusted_networks: " + "Invalid network '%s'", *net); + break; + } + + if (net_is_in_network(&client->ip, &net_ip, bits)) + return TRUE; + } + return FALSE; +}
--- a/src/login-common/client-common.h Sat Jun 21 09:54:26 2008 +0300 +++ b/src/login-common/client-common.h Sat Jun 21 10:10:06 2008 +0300 @@ -27,6 +27,7 @@ char *virtual_user; unsigned int tls:1; unsigned int secured:1; + unsigned int trusted:1; unsigned int authenticating:1; unsigned int auth_tried_disabled_plaintext:1; /* ... */ @@ -42,6 +43,7 @@ unsigned int clients_get_count(void) ATTR_PURE; void client_syslog(struct client *client, const char *msg); +bool client_is_trusted(struct client *client); void clients_notify_auth_connected(void); void client_destroy_oldest(void);
--- a/src/login-common/common.h Sat Jun 21 09:54:26 2008 +0300 +++ b/src/login-common/common.h Sat Jun 21 10:10:06 2008 +0300 @@ -18,6 +18,7 @@ extern const char *greeting, *log_format; extern const char *const *log_format_elements; extern const char *capability_string; +extern const char *trusted_networks; extern unsigned int max_connections; extern unsigned int login_process_uid; extern struct auth_client *auth_client;
--- a/src/login-common/main.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/login-common/main.c Sat Jun 21 10:10:06 2008 +0300 @@ -23,6 +23,7 @@ bool verbose_proctitle, verbose_ssl, verbose_auth; const char *greeting, *log_format; const char *const *log_format_elements; +const char *trusted_networks; unsigned int max_connections; unsigned int login_process_uid; struct auth_client *auth_client; @@ -329,6 +330,8 @@ if (log_format == NULL) log_format = "%$: %s"; + trusted_networks = getenv("TRUSTED_NETWORKS"); + value = getenv("PROCESS_UID"); if (value == NULL) i_fatal("BUG: PROCESS_UID environment not given");
--- a/src/master/login-process.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/master/login-process.c Sat Jun 21 10:10:06 2008 +0300 @@ -582,6 +582,10 @@ set->imap_capability : set->imap_generated_capability, NULL)); } + if (*set->login_trusted_networks != '\0') { + env_put(t_strconcat("TRUSTED_NETWORKS=", + set->login_trusted_networks, NULL)); + } } static pid_t create_login_process(struct login_group *group)
--- a/src/master/master-settings-defs.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/master/master-settings-defs.c Sat Jun 21 10:10:06 2008 +0300 @@ -46,6 +46,7 @@ DEF_BOOL(login_process_per_connection), DEF_BOOL(login_chroot), DEF_BOOL(login_greeting_capability), + DEF_STR(login_trusted_networks), DEF_INT(login_process_size), DEF_INT(login_processes_count),
--- a/src/master/master-settings.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/master/master-settings.c Sat Jun 21 10:10:06 2008 +0300 @@ -208,6 +208,7 @@ MEMBER(login_process_per_connection) TRUE, MEMBER(login_chroot) TRUE, MEMBER(login_greeting_capability) FALSE, + MEMBER(login_trusted_networks) "", MEMBER(login_process_size) 64, MEMBER(login_processes_count) 3,
--- a/src/master/master-settings.h Sat Jun 21 09:54:26 2008 +0300 +++ b/src/master/master-settings.h Sat Jun 21 10:10:06 2008 +0300 @@ -60,6 +60,7 @@ bool login_process_per_connection; bool login_chroot; bool login_greeting_capability; + const char *login_trusted_networks; unsigned int login_process_size; unsigned int login_processes_count;
--- a/src/pop3-login/client.c Sat Jun 21 09:54:26 2008 +0300 +++ b/src/pop3-login/client.c Sat Jun 21 10:10:06 2008 +0300 @@ -317,12 +317,15 @@ client = i_new(struct pop3_client, 1); client->created = ioloop_time; client->refcount = 1; - client->common.tls = ssl; - client->common.secured = ssl || net_ip_compare(ip, local_ip); client->common.local_ip = *local_ip; client->common.ip = *ip; client->common.fd = fd; + client->common.tls = ssl; + client->common.trusted = client_is_trusted(&client->common); + client->common.secured = ssl || client->common.trusted || + net_ip_compare(ip, local_ip); + client_open_streams(client, fd); client_link(&client->common);