--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: lighttpd: [mod_proxy] Please make it possible to forward environment variables
- From: Cyril Brulebois <kibi@debian.org>
- Date: Mon, 13 Aug 2012 22:56:07 +0200
- Message-id: <20120813205607.8927.93750.reportbug@kathleen>
Package: lighttpd
Version: 1.4.31-1
Severity: important
Tags: upstream patch
Forwarded: http://redmine.lighttpd.net/issues/2434
Hi folks,
unless I missed some docs, there's no way of forwarding environment
variables such as the SSL_* ones (which are set when one uses a client
certificate), through mod_proxy.
I've just submitted a patch upstream to add support for forwarding
environment variables (but not just those):
http://redmine.lighttpd.net/issues/2434
http://redmine.lighttpd.net/attachments/download/1379/0001-mod_proxy-Make-it-possible-to-forward-environment-va.patch
It looks to me like an important misssing feature in lighttpd, and might
be worth trying to get into wheezy (even if I won't be the one reviewing
the patch on the release team side, for obvious reasons).
Thanks for considering.
Mraw,
KiBi.
>From 88ba376bec3503daf06bb3129b0b89177169f6b9 Mon Sep 17 00:00:00 2001
From: Cyril Brulebois <kibi@debian.org>
Date: Mon, 13 Aug 2012 22:20:07 +0200
Subject: [PATCH] [mod_proxy] Make it possible to forward environment
variables.
Even if the original goal was to forward X509/SSL-related variables, it
was easy to generalize that to any environment variable. This adds a
proxy.forward-env-vars config string, which is a list of comma-separated
variables to be forwarded.
Signed-off-by: Cyril Brulebois <kibi@debian.org>
---
doc/config/conf.d/proxy.conf | 7 ++++++
src/mod_proxy.c | 51 ++++++++++++++++++++++++++++++++++++++++++
tests/proxy.conf | 2 ++
3 files changed, 60 insertions(+)
diff --git a/doc/config/conf.d/proxy.conf b/doc/config/conf.d/proxy.conf
index f0552c2..df1eb92 100644
--- a/doc/config/conf.d/proxy.conf
+++ b/doc/config/conf.d/proxy.conf
@@ -18,6 +18,13 @@ server.modules += ( "mod_proxy" )
## might be one of 'hash', 'round-robin' or 'fair' (default).
##
#proxy.balance = "fair"
+
+
+##
+## a comma-separated string with the variables to be forwarded through
+## X-... headers
+##
+#proxy.forward-env-vars = "SSL_CLIENT_S_DN_x500UniqueIdentifier,SSL_CLIENT_S_DN_emailAddress"
##
## Handle all jsp requests via 192.168.0.101
diff --git a/src/mod_proxy.c b/src/mod_proxy.c
index 06fe3db..1295b37 100644
--- a/src/mod_proxy.c
+++ b/src/mod_proxy.c
@@ -73,6 +73,7 @@ typedef struct {
buffer *parse_response;
buffer *balance_buf;
+ char **forward_env_vars;
plugin_config **config_storage;
@@ -149,6 +150,7 @@ INIT_FUNC(mod_proxy_init) {
p->parse_response = buffer_init();
p->balance_buf = buffer_init();
+ p->forward_env_vars = NULL;
return p;
}
@@ -162,6 +164,13 @@ FREE_FUNC(mod_proxy_free) {
buffer_free(p->parse_response);
buffer_free(p->balance_buf);
+ /* walk the array of environment variables to free them, if any */
+ char **forward_env_vars_ptr = p->forward_env_vars;
+ while (forward_env_vars_ptr && *forward_env_vars_ptr) {
+ free(*forward_env_vars_ptr++);
+ }
+ free(p->forward_env_vars);
+
if (p->config_storage) {
size_t i;
for (i = 0; i < srv->config_context->used; i++) {
@@ -191,6 +200,7 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
{ "proxy.server", NULL, T_CONFIG_LOCAL, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "proxy.debug", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
{ "proxy.balance", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
+ { "proxy.forward-env-vars", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 3 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -231,6 +241,36 @@ SETDEFAULTS_FUNC(mod_proxy_set_defaults) {
return HANDLER_ERROR;
}
+ if (NULL != (du = array_get_element(ca, "proxy.forward-env-vars"))) {
+ data_string *ds = (data_string *)du;
+ if (ds != NULL) {
+ char *ptr, *prev;
+ int parts = 1;
+ /* count the parts */
+ for (ptr = ds->value->ptr; *ptr; ptr++)
+ if (*ptr == ',')
+ parts++;
+ /* cheat a bit to ease with strchr() */
+ *ptr = ',';
+ /* do the real split work */
+ p->forward_env_vars = (char **)malloc((parts+1) * sizeof(char*));
+ prev = ds->value->ptr;
+ for (int j=0; j<parts; j++) {
+ ptr = strchr(prev+1, ',');
+ p->forward_env_vars[j] = (char *)malloc(ptr-prev+1);
+ strncpy(p->forward_env_vars[j], prev, ptr-prev+1);
+ p->forward_env_vars[j][ptr-prev] = '\0';
+ prev = ptr+1;
+ }
+ /* NULL-terminate the array to ease walking it */
+ p->forward_env_vars[parts] = NULL;
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "sb",
+ "proxy.forward-env-vars has to be a string");
+ return HANDLER_ERROR;
+ }
+ }
+
if (NULL != (du = array_get_element(ca, "proxy.server"))) {
size_t j;
data_array *da = (data_array *)du;
@@ -441,6 +481,7 @@ static void proxy_append_header(connection *con, const char *key, const char *va
static int proxy_create_env(server *srv, handler_ctx *hctx) {
size_t i;
+ char **forward_env_vars_ptr = hctx->plugin_data->forward_env_vars;
connection *con = hctx->remote_conn;
buffer *b;
@@ -456,6 +497,16 @@ static int proxy_create_env(server *srv, handler_ctx *hctx) {
buffer_append_string_buffer(b, con->request.uri);
buffer_append_string_len(b, CONST_STR_LEN(" HTTP/1.0\r\n"));
+ /* walk the array of environment variables to forward, if any */
+ while (forward_env_vars_ptr && *forward_env_vars_ptr) {
+ char forward_env_header[4096];
+ snprintf(forward_env_header, sizeof(forward_env_header), "X-%s", *forward_env_vars_ptr);
+ data_string *key_ds = (data_string *)array_get_element(hctx->remote_conn->environment, *forward_env_vars_ptr);
+ if (key_ds != NULL)
+ proxy_set_header(con, forward_env_header, key_ds->value->ptr);
+ forward_env_vars_ptr++;
+ }
+
proxy_append_header(con, "X-Forwarded-For", (char *)inet_ntop_cache_get_ip(srv, &(con->dst_addr)));
/* http_host is NOT is just a pointer to a buffer
* which is NULL if it is not set */
diff --git a/tests/proxy.conf b/tests/proxy.conf
index 2e959ac..fd8b148 100644
--- a/tests/proxy.conf
+++ b/tests/proxy.conf
@@ -76,6 +76,8 @@ proxy.server = ( "" => (
)
)
+proxy.forward-env-vars = "SSL_CLIENT_S_DN_x500UniqueIdentifier,SSL_CLIENT_S_DN_emailAddress"
+
cgi.assign = ( ".pl" => "/usr/bin/perl",
".cgi" => "/usr/bin/perl",
--
1.7.10.4
--- End Message ---