? src/client.h.patch
? src/options.c.patch
? src/client.c.patch
? src/prototypes.h.patch
? src/README
Index: src/client.c
===================================================================
RCS file: /home/iso/src/stunnel-4.00/src/client.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -c -r1.5 -r1.6
*** src/client.c	31 Oct 2002 17:43:01 -0000	1.5
--- src/client.c	31 Oct 2002 17:44:42 -0000	1.6
***************
*** 313,324 ****
--- 313,335 ----
      int check_SSL_pending;
      int ready;
      struct timeval tv;
+     int header_sent = 0;
  
      fdno=c->sock_rfd->fd;
      if(c->sock_wfd->fd>fdno) fdno=c->sock_wfd->fd;
      if(c->ssl_rfd->fd>fdno) fdno=c->ssl_rfd->fd;
      if(c->ssl_wfd->fd>fdno) fdno=c->ssl_wfd->fd;
      fdno+=1;
+     c->header_length = 0;
+ 
+     /* create X-Forwarded-For header if necessary */
+     if (c->opt->option.xforwardedfor) {
+         sprintf(c->header_buff, "X-Forwarded-For: %s\r\n", inet_ntoa(c->addr.sin_addr));
+ 
+         c->header_length = strlen(c->header_buff);
+ 
+         log(LOG_DEBUG, "X-Forwarded-For header is '%s' [%d]", c->header_buff, c->header_length);
+     }
  
      c->sock_ptr=c->ssl_ptr=0;
      sock_rd=sock_wr=ssl_rd=ssl_wr=1;
***************
*** 496,501 ****
--- 507,533 ----
  
              switch(SSL_get_error(c->ssl, num)) {
              case SSL_ERROR_NONE:
+                 /* insert X-Forwarded-For header if desired and not yet included */
+                 if (c->opt->option.xforwardedfor && ! header_sent) {
+                     char *eol = memchr(c->ssl_buff+c->ssl_ptr, '\n', num);
+ 
+                     if (eol) {
+                         log(LOG_DEBUG, "buffer is '%.*s' [%d]\n\n", num, c->ssl_buff+c->ssl_ptr, num);
+ 
+                         /* make room for X-Forwarded-For header */
+                         memmove(eol+1+c->header_length, eol+1, num-((eol-(c->ssl_buff+c->ssl_ptr))+1));
+ 
+                         /* insert X-Forwarded-For header */
+                         memcpy(eol + 1, c->header_buff, c->header_length);
+ 
+                         num += c->header_length;
+ 
+                         log(LOG_DEBUG, "re-written buffer is '%.*s' [%d]\n\n", num, c->ssl_buff+c->ssl_ptr, num);
+                     }
+ 
+                     header_sent = 1;
+                 }
+ 
                  c->ssl_ptr+=num;
                  break;
              case SSL_ERROR_WANT_WRITE:
Index: src/client.h
===================================================================
RCS file: /home/iso/src/stunnel-4.00/src/client.h,v
retrieving revision 1.3
retrieving revision 1.5
diff -c -r1.3 -r1.5
*** src/client.h	24 Oct 2002 21:46:29 -0000	1.3
--- src/client.h	29 Oct 2002 15:18:39 -0000	1.5
***************
*** 61,66 ****
--- 61,68 ----
      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;
Index: src/options.c
===================================================================
RCS file: /home/iso/src/stunnel-4.00/src/options.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -c -r1.3 -r1.4
*** src/options.c	24 Oct 2002 21:46:29 -0000	1.3
--- src/options.c	24 Oct 2002 21:58:10 -0000	1.4
***************
*** 831,836 ****
--- 831,859 ----
      }
  #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 */
***************
*** 955,960 ****
--- 978,994 ----
          exit(1);
      }
      fclose(fp);
+ 
+     /* validate that each section specifies a protocol or xforwardedfor but not both */
+     for (section = &local_options; section != NULL; section = section->next) {
+        /* X-Forwarded-For header only valid for HTTP and HTTPS */
+        if (section->option.xforwardedfor && (section->protocol != NULL)) {
+           log(LOG_ERR, "The X-Forwarded-For header (xforwardedfor) can only be used with the HTTP and HTTPS protocols");
+ 
+           section->option.xforwardedfor=0;
+        }
+     }
+ 
      if(!options.option.client)
          options.option.cert=1; /* Server always needs a certificate */
      if(!options.option.foreground)
Index: src/prototypes.h
===================================================================
RCS file: /home/iso/src/stunnel-4.00/src/prototypes.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -c -r1.3 -r1.4
*** src/prototypes.h	24 Oct 2002 21:46:29 -0000	1.3
--- src/prototypes.h	24 Oct 2002 21:58:10 -0000	1.4
***************
*** 163,168 ****
--- 163,169 ----
          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;
