diff -Nur ucspi-tcp-0.88.orig/fixcrio.1 ucspi-tcp-0.88/fixcrio.1
--- ucspi-tcp-0.88.orig/fixcrio.1	1970-01-01 01:00:00.000000000 +0100
+++ ucspi-tcp-0.88/fixcrio.1	2006-03-12 18:20:34.000000000 +0100
@@ -0,0 +1,15 @@
+.TH fixcrio 1
+.SH NAME
+fixcrio \- make sure that there is a CR before each LF
+.SH SYNOPSIS
+.B fixcrio
+.I program
+[
+.I arg ...
+]
+.SH DESCRIPTION
+.B fixcrio
+inserts CR at the end of each line of input where a CR is not already present.
+It does not insert CR at the end of a partial final line.
+.SH "SEE ALSO"
+addcr(1)
diff -Nur ucspi-tcp-0.88.orig/Makefile ucspi-tcp-0.88/Makefile
--- ucspi-tcp-0.88.orig/Makefile	2006-03-12 18:20:02.000000000 +0100
+++ ucspi-tcp-0.88/Makefile	2006-03-12 18:27:18.000000000 +0100
@@ -1,13 +1,25 @@
 # 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=-lcrypto -lssl
+#INCS=-I/usr/local/include
+OPENSSLBIN=openssl
+
 SHELL=/bin/sh
 
-default: it
+default: it man
 
 addcr: \
 load addcr.o unix.a byte.a
 	./load addcr unix.a byte.a 
 
+addcr.0: \
+addcr.1
+	nroff -man addcr.1 > addcr.0
+
 addcr.o: \
 compile addcr.c buffer.h exit.h
 	./compile addcr.c
@@ -24,6 +36,10 @@
 load argv0.o unix.a byte.a
 	./load argv0 unix.a byte.a 
 
+argv0.0: \
+argv0.1
+	nroff -man argv0.1 > argv0.0
+
 argv0.o: \
 compile argv0.c pathexec.h strerr.h
 	./compile argv0.c
@@ -153,6 +169,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
@@ -172,10 +192,18 @@
 	> date@
 	chmod 755 date@
 
+date@.0: \
+date@.1
+	nroff -man date@.1 > date@.0
+
 delcr: \
 load delcr.o unix.a byte.a
 	./load delcr unix.a byte.a 
 
+delcr.0: \
+delcr.1
+	nroff -man delcr.1 > delcr.0
+
 delcr.o: \
 compile delcr.c buffer.h exit.h
 	./compile delcr.c
@@ -296,10 +324,18 @@
 	> finger@
 	chmod 755 finger@
 
+finger@.0: \
+finger@.1
+	nroff -man finger@.1 > finger@.0
+
 fixcrio: \
 load fixcrio.o time.a unix.a byte.a
 	./load fixcrio time.a unix.a byte.a 
 
+fixcrio.0: \
+fixcrio.1
+	nroff -man fixcrio.1 > fixcrio.0
+
 fixcrio.o: \
 compile fixcrio.c sig.h buffer.h strerr.h byte.h readwrite.h exit.h \
 iopause.h taia.h tai.h uint64.h pathexec.h
@@ -350,6 +386,10 @@
 	> http@
 	chmod 755 http@
 
+http@.0: \
+http@.1
+	nroff -man http@.1 > http@.0
+
 install: \
 load install.o hier.o auto_home.o unix.a byte.a
 	./load install hier.o auto_home.o unix.a byte.a 
@@ -413,6 +453,11 @@
 	) > makelib
 	chmod 755 makelib
 
+man: \
+tcpclient.0 tcpserver.0 tcprules.0 tcprulescheck.0 tcp-environ.0 \
+who@.0 date@.0 finger@.0 http@.0 tcpcat.0 mconnect.0 fixcrio.0 addcr.0 \
+delcr.0 argv0.0 recordio.0
+
 mconnect: \
 warn-auto.sh mconnect.sh conf-home
 	cat warn-auto.sh mconnect.sh \
@@ -429,6 +474,10 @@
 readwrite.h exit.h
 	./compile mconnect-io.c
 
+mconnect.0: \
+mconnect.1
+	nroff -man mconnect.1 > mconnect.0
+
 ndelay_off.o: \
 compile ndelay_off.c ndelay.h
 	./compile ndelay_off.c
@@ -499,6 +548,10 @@
 exit.h fmt.h iopause.h taia.h tai.h uint64.h pathexec.h
 	./compile recordio.c
 
+recordio.0: \
+recordio.1
+	nroff -man recordio.1 > recordio.0
+
 remoteinfo.o: \
 compile remoteinfo.c fmt.h buffer.h socket.h uint16.h error.h \
 iopause.h taia.h tai.h uint64.h timeoutconn.h uint16.h remoteinfo.h \
@@ -712,6 +765,10 @@
 compile taia_uint.c taia.h tai.h uint64.h
 	./compile taia_uint.c
 
+tcp-environ.0: \
+tcp-environ.5
+	nroff -man tcp-environ.5 > tcp-environ.0
+
 tcpcat: \
 warn-auto.sh tcpcat.sh conf-home
 	cat warn-auto.sh tcpcat.sh \
@@ -719,12 +776,20 @@
 	> tcpcat
 	chmod 755 tcpcat
 
+tcpcat.0: \
+tcpcat.1
+	nroff -man tcpcat.1 > tcpcat.0
+ 
 tcpclient: \
 load tcpclient.o remoteinfo6.o dns.a time.a unix.a \
 byte.a socket.lib byte.h timeoutconn6.o
 	./load tcpclient remoteinfo6.o timeoutconn6.o dns.a time.a \
 	unix.a byte.a  `cat socket.lib`
 
+tcpclient.0: \
+tcpclient.1
+	nroff -man tcpclient.1 > tcpclient.0
+
 tcpclient.o: \
 compile tcpclient.c sig.h exit.h sgetopt.h subgetopt.h uint16.h fmt.h \
 scan.h str.h ip4.h uint16.h socket.h uint16.h fd.h stralloc.h \
@@ -737,6 +802,10 @@
 load tcprules.o cdb.a unix.a byte.a
 	./load tcprules cdb.a unix.a byte.a 
 
+tcprules.0: \
+tcprules.1
+	nroff -man tcprules.1 > tcprules.0
+
 tcprules.o: \
 compile tcprules.c strerr.h stralloc.h gen_alloc.h getln.h buffer.h \
 stralloc.h buffer.h exit.h fmt.h byte.h cdb_make.h buffer.h uint32.h
@@ -746,6 +815,10 @@
 load tcprulescheck.o rules.o cdb.a unix.a byte.a
 	./load tcprulescheck rules.o cdb.a unix.a byte.a 
 
+tcprulescheck.0: \
+tcprulescheck.1
+	nroff -man tcprulescheck.1 > tcprulescheck.0
+
 tcprulescheck.o: \
 compile tcprulescheck.c byte.h buffer.h strerr.h env.h rules.h \
 stralloc.h gen_alloc.h
@@ -755,7 +828,11 @@
 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.0: \
+tcpserver.1
+	nroff -man tcpserver.1 > tcpserver.0
 
 tcpserver.o: \
 compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \
@@ -764,7 +841,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 \
@@ -965,5 +1042,19 @@
 compile socket_v6loopback.c
 	./compile socket_v6loopback.c
 
-clean:
-	rm -f `cat TARGETS`
+who@.0: \
+who@.1
+	nroff -man who@.1 > who@.0
+
+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"
diff -Nur ucspi-tcp-0.88.orig/tcprules.c ucspi-tcp-0.88/tcprules.c
--- ucspi-tcp-0.88.orig/tcprules.c	2006-03-12 18:20:02.000000000 +0100
+++ ucspi-tcp-0.88/tcprules.c	2006-03-12 18:20:34.000000000 +0100
@@ -94,6 +94,7 @@
   int len;
   int fd;
   int i;
+  int e;
   char ch;
 
   fn = argv[1];
@@ -154,8 +155,16 @@
     while (len)
       switch(*x) {
         case ',':
+	  e = byte_chr(x + 1,len - 1,',');
           i = byte_chr(x,len,'=');
-          if (i == len) die_bad();
+          if (i > e) {
+	    if (e < 2 || x[1] != '!') die_bad();
+	    if (!stralloc_catb(&data,"-",1)) nomem();
+	    if (!stralloc_catb(&data,x + 2,e - 1)) nomem();
+	    if (!stralloc_0(&data)) nomem();
+	    x += e + 1; len -= e + 1;
+	    break;
+	  }
           if (!stralloc_catb(&data,"+",1)) nomem();
           if (!stralloc_catb(&data,x + 1,i)) nomem();
           x += i + 1; len -= i + 1;
diff -Nur ucspi-tcp-0.88.orig/tcprulescheck.c ucspi-tcp-0.88/tcprulescheck.c
--- ucspi-tcp-0.88.orig/tcprulescheck.c	2006-03-12 18:20:02.000000000 +0100
+++ ucspi-tcp-0.88/tcprulescheck.c	2006-03-12 18:20:34.000000000 +0100
@@ -22,6 +22,11 @@
 	buffer_puts(buffer_1,data + 1);
 	buffer_puts(buffer_1,"\n");
 	break;
+      case '-':
+	buffer_puts(buffer_1,"unset environment variable ");
+	buffer_puts(buffer_1,data + 1);
+	buffer_puts(buffer_1,"\n");
+	break;
     }
     ++next0;
     data += next0; datalen -= next0;
diff -Nur ucspi-tcp-0.88.orig/tcpserver.c ucspi-tcp-0.88/tcpserver.c
--- ucspi-tcp-0.88.orig/tcpserver.c	2006-03-12 18:20:02.000000000 +0100
+++ ucspi-tcp-0.88/tcpserver.c	2006-03-12 18:35:37.000000000 +0100
@@ -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"
@@ -40,6 +41,14 @@
 unsigned long timeout = 26;
 uint32 netif = 0;
 
+#ifdef WITH_SSL
+int flagssl = 0;
+struct stralloc certfile = {0};
+#define CERTFILE "./cert.pem"
+
+void translate(SSL*, int, int, unsigned int);
+#endif
+
 static stralloc tcpremoteinfo;
 
 uint16 localport;
@@ -130,6 +139,9 @@
 	  env(data + 1,data + 1 + split + 1);
 	}
 	break;
+      case '-':
+	env(data + 1, (char *)0);
+	break;
     }
     ++next0;
     data += next0; datalen -= next0;
@@ -271,10 +283,28 @@
 
 void usage(void)
 {
+#ifndef WITH_SSL
   strerr_warn1("\
 tcpserver: usage: tcpserver \
 [ -461UXpPhHrRoOdDqQv ] \
 [ -c limit ] \
+[ -C [address[/len]:]limit ] \
+[ -e name=var ] \
+[ -x rules.cdb ] \
+[ -B banner ] \
+[ -g gid ] \
+[ -u uid ] \
+[ -b backlog ] \
+[ -l localname ] \
+[ -t timeout ] \
+host port program",0);
+#else
+  strerr_warn1("\
+tcpserver: usage: tcpserver \
+[ -461UXpPhHrRoOdDqQsSv ] \
+[ -c limit ] \
+[ -C [address[/len]:]limit ] \
+[ -e name=var ] \
 [ -x rules.cdb ] \
 [ -B banner ] \
 [ -g gid ] \
@@ -283,7 +313,9 @@
 [ -l localname ] \
 [ -t timeout ] \
 [ -I interface ] \
+[ -n certfile ] \
 host port program",0);
+#endif
   _exit(100);
 }
 
@@ -308,12 +340,106 @@
   _exit(0);
 }
 
+struct conn {
+  int pid;
+  char remoteip[4];
+} *conns;
+
+struct ip_limelt {
+  char ip[4];
+  char mask[4];
+  unsigned long limit;
+  unsigned long count;
+};
+
+#include "gen_alloc.h"
+#include "gen_allocdefs.h"
+GEN_ALLOC_typedef(ip_limit,struct ip_limelt,l,len,a)
+GEN_ALLOC_readyplus(ip_limit, struct ip_limelt,l,len,a,i,n,x,10,
+  ip_limit_rp)
+
+ip_limit ipl = {0};
+unsigned long limit_ip = 0;
+
+void
+ip_limit_add(char *str)
+{
+  unsigned int n, len;
+  unsigned long ul = 0;
+  struct ip_limelt lim;
+
+  byte_zero(&lim, sizeof(lim));
+  n = str_chr(str, ':');
+  if (str[n] == ':') {
+    str[n] = 0;
+    scan_ulong(str + n + 1, &ul);
+    lim.limit = ul;
+    /* parse ip */
+    ul = 32;
+    n = str_chr(str, '/');
+    if (str[n] == '/')
+      scan_ulong(str + n + 1, &ul);
+    if (ul > 32)
+      strerr_die2x(111,FATAL,"ip prefix len > 32");
+    if (ip4_scan(str, lim.ip) == 0)
+      strerr_die2x(111,FATAL,"bad ip address");
+    for (n = 0; n < 4; n++)
+      if (ul > 8) {
+	lim.mask[n] = 0xff;
+	ul -= 8;
+      } else {
+	lim.mask[n] = 0xff << (8 - ul);
+	ul = 0;
+      }
+    if (!ip_limit_rp(&ipl,1))
+      strerr_die2x(111,FATAL,"out of memory");
+    ipl.l[ipl.len++] = lim;
+  } else {
+    scan_ulong(str, &ul);
+    limit_ip = ul;
+  }
+}
+
+int
+ip_limit_check(char ip[4], int d)
+{
+  unsigned long c;
+  unsigned int l;
+  int i;
+
+  for (l = 0; l < ipl.len; l++)
+    if ((ip[0] & ipl.l[l].mask[0]) == (ipl.l[l].ip[0] & ipl.l[l].mask[0]) &&
+        (ip[1] & ipl.l[l].mask[1]) == (ipl.l[l].ip[1] & ipl.l[l].mask[1]) &&
+        (ip[2] & ipl.l[l].mask[2]) == (ipl.l[l].ip[2] & ipl.l[l].mask[2]) &&
+        (ip[3] & ipl.l[l].mask[3]) == (ipl.l[l].ip[3] & ipl.l[l].mask[3])) {
+      if (ipl.l[l].count + d > ipl.l[l].limit)
+	return 1;
+      ipl.l[l].count += d;
+      return 0;
+    }
+
+  /* global per ip limit */
+  for (l = 0, c= 0; l < limit; l++)
+    if (!byte_diff(conns[l].remoteip, sizeof(ip), ip))
+      c++;
+  if (limit_ip != 0 && c + d > limit_ip)
+    return 1;
+
+  return 0;
+}
+
 void sigchld()
 {
   int wstat;
   int pid;
- 
+  unsigned int i;
+
   while ((pid = wait_nohang(&wstat)) > 0) {
+    for (i = 0; i < limit; i++)
+      if (conns[i].pid == pid) {
+	ip_limit_check(conns[i].remoteip, -1);
+	byte_zero(&conns[i], sizeof(struct conn));
+      }
     if (verbosity >= 2) {
       strnum[fmt_ulong(strnum,pid)] = 0;
       strnum2[fmt_ulong(strnum2,wstat)] = 0;
@@ -330,14 +456,32 @@
   int opt;
   struct servent *se;
   char *x;
+  char *iplimenv;
+  int flagiplim;
   unsigned long u;
   int s;
   int t;
 
+  unsigned int i;
+  int pid;
+#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");
+  while ((opt = getopt(argc,argv,"46dDvqQhHrRsS1UXx:t:u:g:l:b:B:c:I:C:e:n: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;
+      case 'C': ip_limit_add(optarg); break;
       case 'X': flagallownorules = 1; break;
       case 'x': fnrules = optarg; break;
       case 'B': banner = optarg; break;
@@ -364,6 +508,18 @@
       case '4': noipv6 = 1; break;
       case '6': forcev6 = 1; break;
       case 'l': localhost = optarg; break;
+      case 'e': iplimenv = optarg;
+		if (iplimenv[str_chr(iplimenv, '=')] != '=')
+		  strerr_die2x(100,FATAL, "no '=' in ip limit env-var");
+		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;
+#endif
       default: usage();
     }
   argc -= optind;
@@ -371,6 +527,15 @@
 
   if (!verbosity)
     buffer_2->fd = -1;
+
+  if (limit == 0)
+    strerr_die2x(100,FATAL,"limit may not be set to 0");
+  if (limit > 65000)
+    strerr_die2x(100,FATAL,"limit way to high");
+  conns = (struct conn *)alloc(limit * sizeof(struct conn));
+  if (!conns)
+    strerr_die2x(111,FATAL,"out of memory");
+  byte_zero(conns, limit * sizeof(struct conn));
  
   hostname = *argv++;
   if (!hostname) usage();
@@ -412,6 +577,25 @@
       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");
+
+    /* set prefered ciphers */
+    if (env_get("SSL_CIPHER"))
+      if (SSL_CTX_set_cipher_list(ctx, env_get("SSL_CIPHER")) == 0)
+	strerr_die2x(111,FATAL,"unable to set cipher list");
+
+    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_chain_file(ctx, certfile.s) != 1)
+      strerr_die2x(111,FATAL,"unable to load certificate");
+  }
+#endif
+
   s = socket_tcp6();
   if (s == -1)
     strerr_die2sys(111,FATAL,"unable to create socket: ");
@@ -450,9 +634,31 @@
 
     if (t == -1) continue;
     ++numchildren; printstatus();
+
+    /* per ip handling */
+    flagiplim = 0;
+    if (ip_limit_check(remoteip, 1)) {
+      remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
+      if (iplimenv) {
+        strerr_warn4(DROP,"too many conections from ",remoteipstr,
+	    " only flagged",0);
+	flagiplim = 1;
+      } else {
+        strerr_warn3(DROP,"too many conections from ",remoteipstr,0);
+        --numchildren; printstatus();
+        close(t);
+        continue;
+      }
+    }
  
-    switch(fork()) {
+    switch(pid = fork()) {
       case 0:
+	if (flagiplim) {
+          int split;
+      	  split = str_chr(iplimenv,'=');
+	  iplimenv[split] = 0;
+	  env(iplimenv,iplimenv + split + 1);
+	}
         close(s);
         doit(t);
         if ((fd_move(0,t) == -1) || (fd_copy(1,0) == -1))
@@ -461,12 +667,159 @@
         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 */
+	      pathexec(argv);
+	      strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
+	    case -1:
+	      strerr_die2sys(111,DROP,"unable to fork: ");
+	    default:
+	      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);
+	  }
+	}
+#endif
         pathexec(argv);
 	strerr_die4sys(111,DROP,"unable to run ",*argv,": ");
       case -1:
         strerr_warn2(DROP,"unable to fork: ",&strerr_sys);
         --numchildren; printstatus();
+	break;
+      default:
+	for (i = 0; i < limit; i++)
+	  if (conns[i].pid == 0) {
+	    conns[i].pid = pid;
+	    byte_copy(conns[i].remoteip, sizeof(remoteip), remoteip);
+	    break;
+	  }
     }
     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) {
+      do {
+        /* 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 the data payload was longer than sizeof(tbuf) then SSL will have
+	 * bytes processed and pending. We need to pick them up and write them
+	 * to clearout.
+	 */
+      } while (SSL_pending(ssl));
+    }
+    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
