diff -ruNH stunnel-4.06_orig/src/client.c stunnel-4.06/src/client.c --- stunnel-4.06_orig/src/client.c 2004-12-26 00:42:08.000000000 +0100 +++ stunnel-4.06/src/client.c 2004-12-29 16:25:48.125017255 +0100 @@ -111,6 +111,7 @@ #endif c->remote_fd.fd=-1; c->ssl=NULL; + c->header_length = 0; cleanup(c, do_client(c)); #ifdef USE_FORK if(!c->opt->option.remote) /* 'exec' specified */ @@ -194,6 +195,13 @@ c->accepting_address); return -1; } + + /* create X-Forwarded-For header if necessary */ + if (c->opt->option.xforwardedfor) { + sprintf(c->header_buff, "X-Forwarded-For: %s\r\n", c->accepting_address); + c->header_length = strlen(c->header_buff); + s_log(LOG_DEBUG, "X-Forwarded-For header is '%s' [%d]", c->header_buff, c->header_length); + } s_log(LOG_NOTICE, "%s connected from %s", c->opt->servname, c->accepting_address); } @@ -361,6 +369,7 @@ /* 0=not closing SSL, 1=initiate SSL_shutdown, * 2=retry SSL_shutdown, 3=SSL_shutdown done */ int watchdog=0; /* a counter to detect an infinite loop */ + int header_sent = 0; c->sock_ptr=c->ssl_ptr=0; sock_rd=sock_wr=ssl_rd=ssl_wr=1; @@ -456,6 +465,26 @@ s_log(LOG_DEBUG, "No data written to the socket: retrying"); break; default: + + /* insert X-Forwarded-For header if desired and not yet included */ + if (c->opt->option.xforwardedfor && ! header_sent) { + char *eol = memchr(c->ssl_buff, '\n', num); + + if (eol) { + + /* make room for X-Forwarded-For header */ + memmove(eol+1+c->header_length, eol+1, (eol - c->ssl_buff) + 1); + + /* insert X-Forwarded-For header */ + memcpy(eol + 1, c->header_buff, c->header_length); + c->ssl_ptr = num += c->header_length+1; + s_log(LOG_DEBUG, "re-written buffer is '%.*s' [%d]\n\n", num, c->ssl_buff, num); + }else{ + s_log(LOG_DEBUG, "can't add X-Forwarded-For header\n"); + } + header_sent = 1; + } + memmove(c->ssl_buff, c->ssl_buff+num, c->ssl_ptr-num); if(c->ssl_ptr==BUFFSIZE) check_SSL_pending=1; diff -ruNH stunnel-4.06_orig/src/options.c stunnel-4.06/src/options.c --- stunnel-4.06_orig/src/options.c 2004-12-25 23:46:32.000000000 +0100 +++ stunnel-4.06/src/options.c 2004-12-29 13:20:23.000000000 +0100 @@ -978,6 +978,29 @@ } #endif + /* xforwardedfor */ + switch(cmd) { + case CMD_INIT: + section->option.xforwardedfor=0; + break; + case CMD_EXEC: + if(strcasecmp(opt, "xforwardedfor")) + break; + if(!strcasecmp(arg, "yes")) + section->option.xforwardedfor=1; + else if(!strcasecmp(arg, "no")) + section->option.xforwardedfor=0; + else + return "argument should be either 'yes' or 'no'"; + return NULL; /* OK */ + case CMD_DEFAULT: + break; + case CMD_HELP: + log_raw("%-15s = yes|no send X-Forwarded-For HTTP headers", + "xforwardedfor"); + break; + } + if(cmd==CMD_EXEC) return option_not_found; return NULL; /* OK */ diff -ruNH stunnel-4.06_orig/src/prototypes.h stunnel-4.06/src/prototypes.h --- stunnel-4.06_orig/src/prototypes.h 2004-12-25 22:24:09.000000000 +0100 +++ stunnel-4.06/src/prototypes.h 2004-12-29 11:12:36.000000000 +0100 @@ -195,6 +195,7 @@ unsigned int delayed_lookup:1; unsigned int accept:1; unsigned int remote:1; + unsigned int xforwardedfor:1; #ifndef USE_WIN32 unsigned int program:1; unsigned int pty:1; @@ -252,6 +253,8 @@ FD *sock_rfd, *sock_wfd; /* Read and write socket descriptors */ FD *ssl_rfd, *ssl_wfd; /* Read and write SSL descriptors */ int sock_bytes, ssl_bytes; /* Bytes written to socket and ssl */ + char header_buff[48]; /* Text of X-Forwarded-For header */ + int header_length; /* Length of X-Forwarded-For header */ } CLI; extern int max_clients;