diff -u ../ucspi-tcp-0.88/conf-cc ./conf-cc
--- ../ucspi-tcp-0.88/conf-cc	Sat Mar 18 16:18:42 2000
+++ ./conf-cc	Thu Nov 20 16:49:54 2003
@@ -1,3 +1,3 @@
-gcc -O2
+gcc -O2 -I/opt/include
 
 This will be used to compile .c files.
diff -u ../ucspi-tcp-0.88/conf-home ./conf-home
--- ../ucspi-tcp-0.88/conf-home	Sat Mar 18 16:18:42 2000
+++ ./conf-home	Fri Nov 21 12:38:23 2003
@@ -1,4 +1,4 @@
-/usr/local
+/opt
 
 This is the ucspi-tcp home directory. Programs will be installed in
 .../bin.
diff -u ../ucspi-tcp-0.88/conf-ld ./conf-ld
--- ../ucspi-tcp-0.88/conf-ld	Sat Mar 18 16:18:42 2000
+++ ./conf-ld	Thu Nov 20 16:50:01 2003
@@ -1,3 +1,3 @@
-gcc -s
+gcc -s -L/opt/lib
 
 This will be used to link .o files into an executable.
--- ucspi-tcp-0.88/tcpserver.c.orig	2009-06-01 19:28:52.000000000 +0200
+++ ucspi-tcp-0.88/tcpserver.c	2009-06-01 19:36:13.000000000 +0200
@@ -1,6 +1,7 @@
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netdb.h>
+#include <openssl/ssl.h>
 #include "uint16.h"
 #include "str.h"
 #include "byte.h"
@@ -38,6 +39,19 @@
 int flagremotehost = 1;
 int flagparanoid = 0;
 unsigned long timeout = 26;
+#ifdef WITH_SSL
+int flagssl = 0;
+unsigned long jailuid = 0;
+struct stralloc certfile = {0};
+#define CERTFILE "./cert.pem"
+struct stralloc cafile = {0};
+struct stralloc jaildir = {0};
+#define JAILDIR ".jail"
+
+void translate(SSL*, int, int, unsigned int);
+#endif
+
+
 uint32 netif = 0;
 
 static stralloc tcpremoteinfo;
@@ -271,6 +285,7 @@
 
 void usage(void)
 {
+#ifndef WITH_SSL
   strerr_warn1("\
 tcpserver: usage: tcpserver \
 [ -461UXpPhHrRoOdDqQv ] \
@@ -284,6 +299,24 @@
 [ -t timeout ] \
 [ -I interface ] \
 host port program",0);
+#else
+  strerr_warn1("\
+tcpserver: usage: tcpserver \
+[ -1UXpPhHrRoOdDqQsSv ] \
+[ -c limit ] \
+[ -x rules.cdb ] \
+[ -B banner ] \
+[ -g gid ] \
+[ -u uid ] \
+[ -b backlog ] \
+[ -l localname ] \
+[ -t timeout ] \
+[ -n certfile ] \
+[ -a cafile ] \
+[ -j jailuid ] \
+[ -J jaildir ] \
+host port program",0);
+#endif
   _exit(100);
 }
 
@@ -334,7 +367,22 @@
   int s;
   int t;
 
+#ifdef WITH_SSL
+  BIO *sbio;
+  SSL *ssl;
+  SSL_CTX *ctx;
+  int pi2c[2], pi4c[2];
+
+  ctx = NULL;
+
+  if (!stralloc_copys(&certfile, CERTFILE) || !stralloc_0(&certfile) )
+    strerr_die2x(111,FATAL,"out of memory");
+  if (!stralloc_copys(&jaildir, JAILDIR) || !stralloc_0(&jaildir) )
+    strerr_die2x(111,FATAL,"out of memory");
+  while ((opt = getopt(argc,argv,"dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:n:a:j:J:pPoO")) != opteof)
+#else
   while ((opt = getopt(argc,argv,"46dDvqQhHrR1UXx:t:u:g:l:b:B:c:I:pPoO")) != opteof)
+#endif
     switch(opt) {
       case 'b': scan_ulong(optarg,&backlog); break;
       case 'c': scan_ulong(optarg,&limit); break;
@@ -364,6 +412,23 @@
       case '4': noipv6 = 1; break;
       case '6': forcev6 = 1; break;
       case 'l': localhost = optarg; break;
+#ifdef WITH_SSL
+      case 's': flagssl = 1; break;
+      case 'S': flagssl = 0; break;
+      case 'n': if (!stralloc_copys(&certfile, optarg) ||
+		    !stralloc_0(&certfile) )
+		  strerr_die2x(111,FATAL,"out of memory");
+		break;
+      case 'a': if (!stralloc_copys(&cafile, optarg) ||
+		    !stralloc_0(&cafile) )
+		  strerr_die2x(111,FATAL,"out of memory");
+		break;
+      case 'j': scan_ulong(optarg,&jailuid); break;
+      case 'J': if (!stralloc_copys(&jaildir, optarg) ||
+		    !stralloc_0(&jaildir) )
+		  strerr_die2x(111,FATAL,"out of memory");
+		break;
+#endif
       default: usage();
     }
   argc -= optind;
@@ -408,6 +473,24 @@
       noipv6=1;
   }
 
+#ifdef WITH_SSL
+  if (flagssl == 1) {
+    /* setup SSL context (load key and cert into ctx) */
+    SSL_library_init();
+    ctx=SSL_CTX_new(SSLv23_server_method());
+    if (!ctx) strerr_die2x(111,FATAL,"unable to create SSL context");
+
+    if(SSL_CTX_use_RSAPrivateKey_file(ctx, certfile.s, SSL_FILETYPE_PEM) != 1)
+      strerr_die2x(111,FATAL,"unable to load RSA private key");
+    if(SSL_CTX_use_certificate_file(ctx, certfile.s, SSL_FILETYPE_PEM) != 1)
+      strerr_die2x(111,FATAL,"unable to load certificate");
+              if ( cafile.s
+                      && 1 != SSL_CTX_load_verify_locations(ctx,cafile.s,0)
+              )
+      strerr_die2x(111,FATAL,"unable to load cafile");
+  }
+#endif
+
   s = socket_tcp6();
   if (s == -1)
     strerr_die2sys(111,FATAL,"unable to create socket: ");
@@ -419,10 +502,16 @@
     strerr_die2sys(111,FATAL,"unable to listen: ");
   ndelay_off(s);
 
+#ifdef WITH_SSL
+	if (!jailuid) { /* else delay to after chroot */
+#endif
   if (gid) if (prot_gid(gid) == -1)
     strerr_die2sys(111,FATAL,"unable to set gid: ");
   if (uid) if (prot_uid(uid) == -1)
     strerr_die2sys(111,FATAL,"unable to set uid: ");
+#ifdef WITH_SSL
+	} /* !jailuid */
+#endif
 
  
   localportstr[fmt_ulong(localportstr,localport)] = 0;
@@ -457,6 +546,55 @@
         sig_unblock(sig_child);
         sig_uncatch(sig_term);
         sig_uncatch(sig_pipe);
+#ifdef WITH_SSL
+	if (flagssl == 1) {
+	  if (pipe(pi2c) != 0)
+	    strerr_die2sys(111,DROP,"unable to create pipe: ");
+	  if (pipe(pi4c) != 0)
+	    strerr_die2sys(111,DROP,"unable to create pipe: ");
+	  switch(fork()) {
+	    case 0:
+	      close(0); close(1);
+	      close(pi2c[1]);
+	      close(pi4c[0]);
+	      if ((fd_move(0,pi2c[0]) == -1) || (fd_move(1,pi4c[1]) == -1))
+		strerr_die2sys(111,DROP,"unable to set up descriptors: ");
+	      /* signals are allready set in the parent */
+	      break; /* drop out to non-ssl case */
+	    case -1:
+	      strerr_die2sys(111,DROP,"unable to fork: ");
+	    default:
+				if (jailuid) { /* chroot */
+					if (chdir(jaildir.s))
+						strerr_die2sys(111,FATAL,"unable to chdir to jail: ");
+					if (chroot("."))
+						strerr_die2sys(111,FATAL,"unable to chroot to jail: ");
+					prot_gid(jailuid); /* just try ... not really important */
+					if (prot_uid(jailuid) == -1)
+						strerr_die2sys(111,FATAL,"unable to set jailuid: ");
+				} /* jailuid */
+	      ssl = SSL_new(ctx);
+	      if (!ssl)
+		strerr_die2x(111,DROP,"unable to set up SSL session");
+	      sbio = BIO_new_socket(0,BIO_NOCLOSE);
+	      if (!sbio)
+		strerr_die2x(111,DROP,"unable to set up BIO socket");
+	      SSL_set_bio(ssl,sbio,sbio);
+	      close(pi2c[0]);
+	      close(pi4c[1]);
+	      translate(ssl, pi2c[1], pi4c[0], 3600);
+	      _exit(0);
+	  }
+		/* we're working child */
+		if (jailuid) { /* delayed setuidgid */
+			if (gid) if (prot_gid(gid) == -1)
+				strerr_die2sys(111,FATAL,"unable to set gid: ");
+			if (uid) if (prot_uid(uid) == -1)
+				strerr_die2sys(111,FATAL,"unable to set uid: ");
+		} /* jailuid */
+	}
+
+#endif
         pathexec(argv);
 	strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
       case -1:
@@ -466,3 +604,102 @@
     close(t);
   }
 }
+
+#ifdef WITH_SSL
+static int allwrite(int fd, char *buf, int len)
+{
+  int w;
+
+  while (len) {
+    w = write(fd,buf,len);
+    if (w == -1) {
+      if (errno == error_intr) continue;
+      return -1; /* note that some data may have been written */
+    }
+    if (w == 0) ; /* luser's fault */
+    buf += w;
+    len -= w;
+  }
+  return 0;
+}
+
+static int allwritessl(SSL* ssl, char *buf, int len)
+{
+  int w;
+
+  while (len) {
+    w = SSL_write(ssl,buf,len);
+    if (w == -1) {
+      if (errno == error_intr) continue;
+      return -1; /* note that some data may have been written */
+    }
+    if (w == 0) ; /* luser's fault */
+    buf += w;
+    len -= w;
+  }
+  return 0;
+}
+
+char tbuf[2048];
+
+void translate(SSL* ssl, int clearout, int clearin, unsigned int iotimeout)
+{
+  struct taia now;
+  struct taia deadline;
+  iopause_fd iop[2];
+  int flagexitasap;
+  int iopl;
+  int sslout, sslin;
+  int n, r;
+
+  sslin = SSL_get_fd(ssl);
+  sslout = SSL_get_fd(ssl);
+  if (sslin == -1 || sslout == -1)
+    strerr_die2x(111,DROP,"unable to set up SSL connection");
+  
+  flagexitasap = 0;
+
+  if (SSL_accept(ssl)<=0)
+    strerr_die2x(111,DROP,"unable to accept SSL connection");
+
+  while (!flagexitasap) {
+    taia_now(&now);
+    taia_uint(&deadline,iotimeout);
+    taia_add(&deadline,&now,&deadline);
+
+    /* fill iopause struct */
+    iopl = 2;
+    iop[0].fd = sslin;
+    iop[0].events = IOPAUSE_READ;
+    iop[1].fd = clearin;
+    iop[1].events = IOPAUSE_READ;
+
+    /* do iopause read */
+    iopause(iop,iopl,&deadline,&now);
+    if (iop[0].revents) {
+      /* data on sslin */
+      n = SSL_read(ssl, tbuf, sizeof(tbuf));
+      if ( n < 0 )
+	strerr_die2sys(111,DROP,"unable to read form network: ");
+      if ( n == 0 )
+	flagexitasap = 1;
+      r = allwrite(clearout, tbuf, n);
+      if ( r < 0 )
+	strerr_die2sys(111,DROP,"unable to write to client: ");
+    }
+    if (iop[1].revents) {
+      /* data on clearin */
+      n = read(clearin, tbuf, sizeof(tbuf));
+      if ( n < 0 )
+	strerr_die2sys(111,DROP,"unable to read form client: ");
+      if ( n == 0 )
+	flagexitasap = 1;
+      r = allwritessl(ssl, tbuf, n);
+      if ( r < 0 )
+	strerr_die2sys(111,DROP,"unable to write to network: ");
+    }
+    if (!iop[0].revents && !iop[1].revents)
+      strerr_die2x(0, DROP,"timeout reached without input");
+  }
+}
+#endif
--- ucspi-tcp-0.88/Makefile.orig	2009-06-01 19:28:52.000000000 +0200
+++ ucspi-tcp-0.88/Makefile	2009-06-01 19:50:22.000000000 +0200
@@ -1,5 +1,13 @@
 # Don't edit Makefile! Use conf-* for configuration.
 
+DEFINES=-DWITH_SSL
+#add -DWITH_SSL to enable ssl support
+
+# LIBS for additional libraries and INCS for additional includes
+LIBS=-lssl -lcrypto
+#INCS=-I/usr/local/include
+OPENSSLBIN=openssl
+
 SHELL=/bin/sh
 
 default: it
@@ -153,6 +161,10 @@
 	> choose
 	chmod 755 choose
 
+clean: \
+TARGETS
+	rm -f `cat TARGETS`
+
 commands.o: \
 compile commands.c buffer.h stralloc.h gen_alloc.h str.h case.h \
 commands.h
@@ -755,7 +767,7 @@
 load tcpserver.o rules.o remoteinfo6.o timeoutconn6.o cdb.a dns.a \
 time.a unix.a byte.a socket.lib
 	./load tcpserver rules.o remoteinfo6.o timeoutconn6.o cdb.a \
-	dns.a time.a unix.a byte.a  `cat socket.lib`
+	dns.a time.a unix.a byte.a  $(LIBS) `cat socket.lib`
 
 tcpserver.o: \
 compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \
@@ -764,7 +776,7 @@
 socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h \
 stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \
 taia.h uint32.h
-	./compile tcpserver.c
+	./compile $(DEFINES) $(INCS) tcpserver.c
 
 time.a: \
 makelib iopause.o tai_pack.o taia_add.o taia_approx.o taia_frac.o \
@@ -861,6 +873,19 @@
 	> who@
 	chmod 755 who@
 
+cert:
+	${OPENSSLBIN} req -new -x509 -nodes \
+	-out cert.pem -days 366 \
+	-keyout cert.pem
+
+cert-req:
+	${OPENSSLBIN} req -new -nodes \
+	-out req.pem \
+	-keyout cert.pem
+	@echo
+	@echo "Send req.pem to your CA to obtain signed_req.pem, and do:"
+	@echo "cat signed_req.pem >> `head -1 conf-qmail`/control/cert.pem"
+
 socket_conn6.o: \
 compile socket_conn6.c socket.h uint16.h haveip6.h error.h ip6.h \
 uint32.h
