changeset 21773:606a4b7ccb21

imap-login: Allow x-forward- to specify forward fields from trusted networks
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 20 Feb 2017 20:37:09 +0200
parents 5379a8dd5937
children 9666b37cb252
files src/imap-login/imap-login-client.c src/imap-login/imap-proxy.c src/login-common/client-common-auth.c
diffstat 3 files changed, 33 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/imap-login/imap-login-client.c	Mon Feb 20 20:36:58 2017 +0200
+++ b/src/imap-login/imap-login-client.c	Mon Feb 20 20:37:09 2017 +0200
@@ -186,6 +186,17 @@
 			client->common.session_id =
 				p_strdup(client->common.pool, value);
 		}
+	} else if (strncasecmp(key, "x-forward-", 10) == 0) {
+		/* handle extra field */
+		if (client->common.forward_fields == NULL)
+			client->common.forward_fields = str_new(client->common.preproxy_pool, 32);
+		else
+			str_append_c(client->common.forward_fields, '\t');
+		/* prefixing is done by auth process */
+		str_append_tabescaped(client->common.forward_fields,
+				      key+10);
+		str_append_c(client->common.forward_fields, '=');
+		str_append_tabescaped(client->common.forward_fields, value);
 	} else {
 		return FALSE;
 	}
@@ -195,7 +206,8 @@
 static bool client_id_reserved_word(const char *key)
 {
 	i_assert(key != NULL);
-	return str_array_icase_find(imap_login_reserved_id_keys, key);
+	return (strncasecmp(key, "x-forward-", 10) == 0 ||
+		str_array_icase_find(imap_login_reserved_id_keys, key));
 }
 
 static void cmd_id_handle_keyvalue(struct imap_client *client,
--- a/src/imap-login/imap-proxy.c	Mon Feb 20 20:36:58 2017 +0200
+++ b/src/imap-login/imap-proxy.c	Mon Feb 20 20:37:09 2017 +0200
@@ -40,13 +40,30 @@
 		    "\"x-originating-port\" \"%u\" "
 		    "\"x-connected-ip\" \"%s\" "
 		    "\"x-connected-port\" \"%u\" "
-		    "\"x-proxy-ttl\" \"%u\")\r\n",
+		    "\"x-proxy-ttl\" \"%u\"",
 		    client_get_session_id(&client->common),
 		    net_ip2addr(&client->common.ip),
 		    client->common.remote_port,
 		    net_ip2addr(&client->common.local_ip),
 		    client->common.local_port,
 		    client->common.proxy_ttl - 1);
+
+	/* append any forward_ variables to request */
+	for(const char *const *ptr = client->common.auth_passdb_args; *ptr != NULL; ptr++) {
+		if (strncasecmp(*ptr, "forward_", 8) == 0) {
+			str_append_c(str, ' ');
+			const char *key = t_strconcat("x-forward-",
+						      t_strcut((*ptr)+8, '='),
+						      NULL);
+			const char *val = i_strchr_to_next(*ptr, '=');
+			str_append_c(str, ' ');
+			imap_append_string(str, key);
+			str_append_c(str, ' ');
+			imap_append_nstring(str, val);
+		}
+	}
+
+	str_append(str, ")\r\n");
 }
 
 static void proxy_free_password(struct client *client)
--- a/src/login-common/client-common-auth.c	Mon Feb 20 20:36:58 2017 +0200
+++ b/src/login-common/client-common-auth.c	Mon Feb 20 20:37:09 2017 +0200
@@ -177,6 +177,8 @@
 				alt_username_set(&alt_usernames, client->pool,
 						 key, value);
 			}
+		} else if (strncmp(key, "forward_", 8) == 0) {
+			/* these are passed to upstream */
 		} else if (client->set->auth_debug)
 			i_debug("Ignoring unknown passdb extra field: %s", key);
 	}