(Solved) Re: [stunnel-users] Help Needed

Alexander Lazic al-stunnel at none.at
Fri Feb 25 22:26:27 CET 2005


Hi,

yes i answer my own Question :-(

On Don 17.02.2005 19:41, Alexander Lazic wrote:
>
>i have try to add the X-Forwarded-For Header, based on
>http://www.stunnel.org/patches/desc/xforwardedfor_jrd.html,
>into stunnel 4.07, but i don't come to a solution :-(

Now here is the working Solution.

al ;-)
-------------- next part --------------
diff -uwbBr stunnel-4.07/src/client.c stunnel-4.07_new/src/client.c
--- stunnel-4.07/src/client.c	2005-01-02 22:35:22.000000000 +0100
+++ stunnel-4.07_new/src/client.c	2005-02-25 20:24:18.873471920 +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,14 @@
                 c->accepting_address);
             return -1;
         }
+
+        /* create X-Forwarded-For header if necessary */
+        if (c->opt->option.xforwardedfor) {
+         snprintf(c->header_buff, XFORWARDEDFORBUFFER_LEN_WITH_IPV6,"X-Forwarded-For: %s\r\n", s_ntop_host_only(c->accepting_address, &c->peer_addr.addr[0]));
+         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);
     }
@@ -362,6 +371,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;
@@ -438,6 +448,29 @@
         check_SSL_pending = 0;
 
         if(sock_wr && sock_can_wr) {
+	  /* insert X-Forwarded-For header if desired and not yet included */
+	  if (c->opt->option.xforwardedfor && ! header_sent) {
+	    //s_log(LOG_DEBUG, "c->ssl_ptr:%p  c->ssl_buff+c->ssl_ptr '%p'\n\n", c->ssl_ptr,c->ssl_buff+c->ssl_ptr);
+		
+	    char *eol = memchr(c->ssl_buff, '\n', c->ssl_ptr);
+	    
+	    if (eol) {
+	      //s_log(LOG_DEBUG, "buffer is '%s' [%d]\n\n", c->ssl_buff, c->ssl_ptr);
+		  
+	      /* make room for X-Forwarded-For header */
+	      memmove(eol+1+c->header_length, eol+1, c->ssl_ptr-((eol-(c->ssl_buff))+1));
+	      
+	      /* insert X-Forwarded-For header */
+	      memcpy(eol + 1, c->header_buff, c->header_length);
+	      
+	      c->ssl_ptr += c->header_length;
+	      s_log(LOG_DEBUG, "re-written buffer is '%s' [%d]\n\n", c->ssl_buff, c->ssl_ptr);	      
+	    }else{
+	      s_log(LOG_DEBUG, "can't add X-Forwarded-For header\n");
+	    }
+	    header_sent = 1;
+	  }/* end of if (c->opt->option.xforwardedfor && ! header_sent) */
+	      
             switch(num=writesocket(c->sock_wfd->fd, c->ssl_buff, c->ssl_ptr)) {
             case -1: /* error */
                 switch(get_last_socket_error()) {
@@ -569,7 +602,11 @@
                 (check_SSL_pending && SSL_pending(c->ssl))
                 /* Write made space from full buffer */
                 )) {
+	  if (c->opt->option.xforwardedfor && ! header_sent) {
+            num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr-c->header_length);
+	  }else{
             num=SSL_read(c->ssl, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr);
+	  }
 
             switch(err=SSL_get_error(c->ssl, num)) {
             case SSL_ERROR_NONE:
@@ -677,7 +714,7 @@
 
 static void print_cipher(CLI *c) { /* print negotiated cipher */
 #if SSLEAY_VERSION_NUMBER <= 0x0800
-    s_log(LOG_INFO, "%s opened with SSLv%d, cipher %s",
+    s_log(LOG_NOTICE, "%s opened with SSLv%d, cipher %s",
         c->opt->servname, ssl->session->ssl_version, SSL_get_cipher(c->ssl));
 #else
     SSL_CIPHER *cipher;
@@ -689,7 +726,7 @@
     len=strlen(buf);
     if(len>0)
         buf[len-1]='\0';
-    s_log(LOG_INFO, "Negotiated ciphers: %s", buf);
+    s_log(LOG_NOTICE, "Negotiated ciphers: %s", buf);
 #endif
 }
 
diff -uwbBr stunnel-4.07/src/network.c stunnel-4.07_new/src/network.c
--- stunnel-4.07/src/network.c	2005-01-03 00:20:27.000000000 +0100
+++ stunnel-4.07_new/src/network.c	2005-01-21 12:25:41.000000000 +0100
@@ -501,6 +501,19 @@
     return text;
 }
 
+char *s_ntop_host_only(char *text, SOCKADDR_UNION *addr) {
+    char host[IPLEN-6], port[6];
+
+    if(getnameinfo(&addr->sa, addr_len(*addr),
+            host, IPLEN-6, port, 6, NI_NUMERICHOST|NI_NUMERICSERV)) {
+        sockerror("getnameinfo");
+        strcpy(text, "unresolvable IP");
+        return text;
+    }
+    strcpy(text, host);
+    return text;
+}
+
 /**************************************** My getaddrinfo() and getnameinfo() */
 /* implementations are limited to functionality needed by stunnel */
 
diff -uwbBr stunnel-4.07/src/options.c stunnel-4.07_new/src/options.c
--- stunnel-4.07/src/options.c	2004-12-31 09:53:40.000000000 +0100
+++ stunnel-4.07_new/src/options.c	2005-01-21 12:25:41.000000000 +0100
@@ -980,6 +980,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 -uwbBr stunnel-4.07/src/prototypes.h stunnel-4.07_new/src/prototypes.h
--- stunnel-4.07/src/prototypes.h	2005-01-02 23:43:23.000000000 +0100
+++ stunnel-4.07_new/src/prototypes.h	2005-02-25 20:24:02.104077232 +0100
@@ -198,6 +198,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;
@@ -239,6 +240,9 @@
     int is_socket; /* File descriptor is a socket */
 } FD;
 
+/* is the length from X-Forwarded-For: $IPV6-ADDR */
+#define XFORWARDEDFORBUFFER_LEN_WITH_IPV6 60
+
 typedef struct {
     LOCAL_OPTIONS *opt;
     char accepting_address[IPLEN], connecting_address[IPLEN]; /* text */
@@ -255,6 +259,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[XFORWARDEDFORBUFFER_LEN_WITH_IPV6]; /* Text of X-Forwarded-For header */
+    int header_length; /* Length of X-Forwarded-For header */
 } CLI;
 
 extern int max_clients;
@@ -311,6 +317,7 @@
 int name2addrlist(SOCKADDR_LIST *, char *, char *);
 int hostport2addrlist(SOCKADDR_LIST *, char *, char *);
 char *s_ntop(char *, SOCKADDR_UNION *);
+char *s_ntop_host_only(char *, SOCKADDR_UNION *);
 
 /**************************************** Prototypes for gui.c */
 


More information about the stunnel-users mailing list