Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 01 Feb 2011 16:17:52 -0800
From:      Jason Helfman <jhelfman@experts-exchange.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/154455: [patch] security/stunnel: add aloha sendproxy support for stunnel
Message-ID:  <1296605872.814282.11894.nullmailer@experts-exchange.com>
Resent-Message-ID: <201102020030.p120UAeb026696@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         154455
>Category:       ports
>Synopsis:       [patch] security/stunnel: add aloha sendproxy support for stunnel
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb 02 00:30:10 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Jason Helfman
>Release:        FreeBSD 8.1-RELEASE i386
>Organization:
Experts Exchange, LLC.
>Environment:
System: FreeBSD eggman.experts-exchange.com 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010 root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386


	
>Description:
This patch adds aloha sendproxy support for stunnel 

This patch adds the ability to inform stunnel about the incoming connection 
(protocol, source, destination, ...)

Patch integrated from:
http://www.mail-archive.com/haproxy@formilux.org/msg04049.html

This has been tested and works as designed.
Results attached for enabled proxy, and disabled proxy.

>How-To-Repeat:
General stunnel configuration:
foreground = yes
; certificate/key is needed in server mode and optional in client mode
cert = /usr/local/etc/stunnel/stunnel.pem
                        
; protocol version (all, SSLv2, SSLv3, TLSv1)
; sslVersion = SSLv3
sslVersion = all
                        
; security enhancements for UNIX systems - comment them out on Win32
; for chroot a copy of some devices and files is needed within the jail
;chroot = /var/tmp/stunnel
setuid = stunnel
setgid = nogroup
; PID is created inside the chroot jail
pid = /tmp/stunnel.pid
                        
; performance tunings
socket = a:SO_LINGER=1:30
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
; debugging stuff (may useful for troubleshooting)
debug = 7
output = /var/log/stunnel.log
                        
; SSL client mode
;client = yes


Start ./server. Once started, an openssl s_client connect needs to be made.
openssl s_client -connect server:1000
<type "test" once connected and hit RETURN>

stunnel.conf additional contents for sendproxy disabled

[test]
accept = 1000
connect = 999
sendproxy = no

$ sudo ./server
test

(no output)

stunnel.conf additional contents for sendproxy enabled

[test]
accept = 1000
connect = 999
sendproxy = yes

$ sudo ./server
PROXY TCP4 192.168.103.69 192.168.11.223 35578 1000

(note additional details)

$ cat server.c

/* compile : gcc -o server server.c */
/*
modified from simple socket server example given by
http://www.pcs.cnu.edu/~dgame/sockets/sockets.html
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>

#define PORT        999
#define DIRSIZE     8192

int main()
{
         char     dir[DIRSIZE];  /* used for incomming dir name, and
                     outgoing data */
     int      sd, sd_current, cc, fromlen, tolen;
     int      addrlen;
     struct   sockaddr_in sin;
     struct   sockaddr_in pin;

     /* get an internet domain socket */
     if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
         perror("socket");
         return 1;
     }

     /* complete the socket structure */
     memset(&sin, 0, sizeof(sin));
     sin.sin_family = AF_INET;
     sin.sin_addr.s_addr = INADDR_ANY;
     sin.sin_port = htons(PORT);

     /* bind the socket to the port number */
     if (bind(sd, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
         perror("bind");
         return 1;
     }

     /* show that we are willing to listen */
     if (listen(sd, 5) == -1) {
         perror("listen");
         return 1;
     }
     /* wait for a client to talk to us */
         addrlen = sizeof(pin);
     if ((sd_current = accept(sd, (struct sockaddr *) &pin, &addrlen)) 
== -1) {
         perror("accept");
         return 1;
     }
/* if you want to see the ip address and port of the client, uncomment the
     next two lines */

     /* get a message from the client */
     if (recv(sd_current, dir, sizeof(dir), 0) == -1) {
         perror("recv");
         return 1;
     }

    puts(dir);

    /* close up both sockets */
     close(sd_current); close(sd);

    return 0;
}

>Fix:

Index: security/stunnel/Makefile
===================================================================
RCS file: /home/jhelfman/ncvs/ports/security/stunnel/Makefile,v
retrieving revision 1.101
diff -u -r1.101 Makefile
--- security/stunnel/Makefile	4 Jan 2011 16:37:24 -0000	1.101
+++ security/stunnel/Makefile	1 Feb 2011 23:32:21 -0000
@@ -42,7 +42,8 @@
 		UCONTEXT	"use the ucontext(3) threading model"	off \
 		IPV6	"enable IPv6 support" off \
 		LIBWRAP	"use TCP wrappers" on \
-		SSL_PORT	"use OpenSSL from the Ports Collection" on
+		SSL_PORT	"use OpenSSL from the Ports Collection" on \
+		SENDPROXY	"use Aloha Sendproxy patch" off
 
 .include <bsd.port.options.mk>
 
@@ -99,6 +100,13 @@
 		${WRKSRC}/tools/Makefile.in
 .endif
 
+.if defined(WITH_SENDPROXY)
+	@${ECHO} "Applying special patches for Aloha Sendproxy."
+	@cd ${WRKSRC} && ${PATCH} --quiet < ${FILESDIR}/aloha-sendproxy-src::client.c		
+	@cd ${WRKSRC} && ${PATCH} --quiet < ${FILESDIR}/aloha-sendproxy-src::prototypes.h
+	@cd ${WRKSRC} && ${PATCH} --quiet < ${FILESDIR}/aloha-sendproxy-src::options.c
+.endif
+
 post-install:
 	@${SETENV} PKG_PREFIX=${PREFIX} ${SH} \
 		${PKGINSTALL} ${PKGNAME} POST-INSTALL
Index: security/stunnel/files/aloha-sendproxy-src::client.c
===================================================================
RCS file: security/stunnel/files/aloha-sendproxy-src::client.c
diff -N security/stunnel/files/aloha-sendproxy-src::client.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ security/stunnel/files/aloha-sendproxy-src::client.c	1 Feb 2011 23:34:40 -0000
@@ -0,0 +1,85 @@
+--- ./src/client.c.orig	2011-01-04 14:24:52.000000000 -0800
++++ ./src/client.c	2011-01-04 14:25:35.000000000 -0800
+@@ -86,6 +86,8 @@
+     c->opt=opt;
+     c->local_rfd.fd=rfd;
+     c->local_wfd.fd=wfd;
++    if (c->opt->option.sendproxy)
++        c->sendproxy = 1;
+     return c;
+ }
+ 
+@@ -564,6 +566,73 @@
+             }
+         }
+ 
++	if (c->sendproxy && !c->ssl_ptr) {
++		int cfd;
++		struct sockaddr_storage local_addr;
++		struct sockaddr_storage peer_addr;
++		u_char family = AF_UNSPEC;
++
++		cfd = SSL_get_fd(c->ssl);
++		if (cfd != -1) {
++			size_t namelen;
++
++			namelen = sizeof(local_addr);
++			if (!getsockname(cfd, (struct sockaddr *)&local_addr, &namelen)) {
++				namelen = sizeof(peer_addr);
++				if (!getpeername(cfd, (struct sockaddr *)&peer_addr, &namelen))
++					family = peer_addr.ss_family;
++			}
++		}
++
++		if (family == AF_INET) {
++
++			if (BUFFSIZE >= 11) {
++				memcpy(c->ssl_buff, "PROXY TCP4 ", 11);
++				c->ssl_ptr += 11;
++			}
++
++			if (inet_ntop(peer_addr.ss_family, &((struct sockaddr_in*)&peer_addr)->sin_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
++				c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
++			}
++			if (c->ssl_ptr != BUFFSIZE) {
++				c->ssl_buff[c->ssl_ptr] = ' ';
++				c->ssl_ptr++;
++			}
++			if (inet_ntop(local_addr.ss_family, &((struct sockaddr_in*)&local_addr)->sin_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
++				c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
++			}
++			c->ssl_ptr += snprintf(c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr, " %u %u\r\n", ntohs(((struct sockaddr_in*)&peer_addr)->sin_port), ntohs(((struct sockaddr_in*)&local_addr)->sin_port));
++		}
++#if defined(USE_IPv6) && !defined(USE_WIN32)			
++		else if (family == AF_INET6) {
++
++			if (BUFFSIZE >= 11) {
++                                memcpy(c->ssl_buff, "PROXY TCP6 ", 11);
++                                c->ssl_ptr += 11;
++                        }
++
++                        if (inet_ntop(peer_addr.ss_family, &((struct sockaddr_in6*)&peer_addr)->sin6_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
++                                c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
++                        }
++                        if (c->ssl_ptr != BUFFSIZE) {
++                                c->ssl_buff[c->ssl_ptr] = ' ';
++                                c->ssl_ptr++;
++                        }
++                        if (inet_ntop(local_addr.ss_family, &((struct sockaddr_in6*)&local_addr)->sin6_addr, c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr)) {
++                                c->ssl_ptr += strlen(c->ssl_buff+c->ssl_ptr);
++                        }
++                        c->ssl_ptr += snprintf(c->ssl_buff+c->ssl_ptr, BUFFSIZE-c->ssl_ptr, " %u %u\r\n", ntohs(((struct sockaddr_in6*)&peer_addr)->sin6_port), ntohs(((struct sockaddr_in6*)&local_addr)->sin6_port));
++		}
++#endif
++		else {
++			if (BUFFSIZE >= 15) {
++                                memcpy(c->ssl_buff, "PROXY UNKNOWN\r\n ", 15);
++                                c->ssl_ptr += 15;
++                        }
++		}
++		c->sendproxy = 0;
++	}
++
+         /****************************** update *_wants_* based on new *_ptr */
+         /* this update is also required for SSL_pending() to be used */
+         read_wants_read=
Index: security/stunnel/files/aloha-sendproxy-src::options.c
===================================================================
RCS file: security/stunnel/files/aloha-sendproxy-src::options.c
diff -N security/stunnel/files/aloha-sendproxy-src::options.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ security/stunnel/files/aloha-sendproxy-src::options.c	1 Feb 2011 23:34:40 -0000
@@ -0,0 +1,32 @@
+--- ./src/options.c.orig	2010-09-14 08:09:36.000000000 -0700
++++ ./src/options.c	2011-01-04 14:25:35.000000000 -0800
+@@ -818,6 +818,29 @@
+     }
+ #endif
+ 
++    /* sendproxy */
++    switch(cmd) {
++    case CMD_INIT:
++        section->option.sendproxy=0;
++        break;
++    case CMD_EXEC:
++        if(strcasecmp(opt, "sendproxy"))
++            break;
++        if(!strcasecmp(arg, "yes"))
++            section->option.sendproxy=1;
++        else if(!strcasecmp(arg, "no"))
++            section->option.sendproxy=0;
++        else
++            return "argument should be either 'yes' or 'no'";
++        return NULL; /* OK */
++    case CMD_DEFAULT:
++        break;
++    case CMD_HELP:
++        s_log(LOG_NOTICE, "%-15s = yes|no append proxy prefix",
++            "sendproxy");
++        break;
++    }
++
+     /* exec */
+     switch(cmd) {
+     case CMD_INIT:
Index: security/stunnel/files/aloha-sendproxy-src::prototypes.h
===================================================================
RCS file: security/stunnel/files/aloha-sendproxy-src::prototypes.h
diff -N security/stunnel/files/aloha-sendproxy-src::prototypes.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ security/stunnel/files/aloha-sendproxy-src::prototypes.h	1 Feb 2011 23:34:40 -0000
@@ -0,0 +1,18 @@
+--- ./src/prototypes.h.orig	2010-09-14 08:09:50.000000000 -0700
++++ ./src/prototypes.h	2011-01-04 14:25:35.000000000 -0800
+@@ -176,6 +176,7 @@
+         unsigned int retry:1; /* loop remote+program */
+         unsigned int sessiond:1;
+         unsigned int program:1;
++        unsigned int sendproxy:1;
+ #ifndef USE_WIN32
+         unsigned int pty:1;
+         unsigned int transparent:1;
+@@ -341,6 +342,7 @@
+ 
+     char sock_buff[BUFFSIZE]; /* socket read buffer */
+     char ssl_buff[BUFFSIZE]; /* SSL read buffer */
++    int sendproxy;
+     int sock_ptr, ssl_ptr; /* index of first unused byte in buffer */
+     FD *sock_rfd, *sock_wfd; /* read and write socket descriptors */
+     FD *ssl_rfd, *ssl_wfd; /* read and write SSL descriptors */
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1296605872.814282.11894.nullmailer>