# --- SDE-COPYRIGHT-NOTE-BEGIN ---
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
#
# Filename: package/.../ucspi-ssl/ucspi-ssl-0.70.2-UCSPI-TLS.patch
# Copyright (C) 2011 The OpenSDE Project
#
# More information can be found in the files COPYING and README.
#
# This patch file is dual-licensed. It is available under the license the
# patched project is licensed under, as long as it is an OpenSource license
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
# of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
# --- SDE-COPYRIGHT-NOTE-END ---

From f9051950183f6bee0624c3d8fdef2e1cd70c5135 Mon Sep 17 00:00:00 2001
From: Christian Wiese <chris@opensde.org>
Date: Wed, 16 Nov 2011 17:39:24 +0100
Subject: [PATCH 1/2] added UCSPI-TLS support by appyling changes made by Scott Gifford

Note:

original tarball including UCSPI-TLS support:

http://www.suspectclass.com/sgifford/ucspi-tls/files/ucspi-ssl-0.70.2-sg.tar.gz

see: http://www.suspectclass.com/sgifford/ucspi-tls/
---
 src/CHANGES           |    5 +-
 src/Makefile          |   27 ++++--
 src/conf-ld           |    2 +-
 src/conf-ld~          |    3 +
 src/ssl.h             |    2 +-
 src/sslclient.c       |  200 ++++++++++++++++++++++++++++------------
 src/sslperl.c         |    1 +
 src/sslserver.c       |  244 ++++++++++++++++++++++++++++++++-----------------
 src/ucspissltest.c    |  206 +++++++++++++++++++++++++++++++++++++++++
 src/ucspitls.c        |  107 +++++++++++++++++++++
 src/ucspitls.h        |    1 +
 src/ucspitls_master.c |   44 +++++++++
 src/ucspitls_master.h |    1 +
 13 files changed, 687 insertions(+), 156 deletions(-)
 create mode 100644 src/conf-ld~
 create mode 100644 src/ucspissltest.c
 create mode 100644 src/ucspitls.c
 create mode 100644 src/ucspitls.h
 create mode 100644 src/ucspitls_master.c
 create mode 100644 src/ucspitls_master.h

diff --git ucspi-ssl-0.70.2/src/CHANGES ucspi-ssl-0.70.2-tls/src/CHANGES
index b9c54a0..1d88cb3 100644
--- ucspi-ssl-0.70.2/src/CHANGES
+++ ucspi-ssl-0.70.2-tls/src/CHANGES
@@ -89,4 +89,7 @@
 	Add () around args to barf in makeinclude.sh (Peter Conrad).
 	Version 0.70.2.
 
-
+20110901
+	Add support for UCSPI-TLS in server (Scott Gifford)
+	Add support for UCSPI-TLS in client (Scott Gifford, sponsored by Meixler Technologies, Inc.)
+	For details see: http://www.suspectclass.com/sgifford/ucspi-tls/
\ No newline at end of file
diff --git ucspi-ssl-0.70.2/src/Makefile ucspi-ssl-0.70.2-tls/src/Makefile
index a563ea3..2246751 100644
--- ucspi-ssl-0.70.2/src/Makefile
+++ ucspi-ssl-0.70.2-tls/src/Makefile
@@ -37,7 +37,8 @@ clean:
 	tai_pack.o taia_add.o taia_approx.o taia_frac.o taia_less.o taia_now.o \
 	taia_pack.o taia_sub.o taia_uint.o timeoutconn.o uint16_pack.o \
 	uint16_unpack.o uint32.h uint32_pack.o uint32_unpack.o uint64.h unix.a \
-	wait_nohang.o wait_pid.o
+	wait_nohang.o wait_pid.o tryssl.o \
+	ucspissltest ucspissltest.o ucspitls.o
 
 addcr: load addcr.o unix.a
 	./load addcr unix.a 
@@ -337,7 +338,7 @@ ip4_scan.o: compile ip4_scan.c scan.h ip4.h
 	./compile ip4_scan.c
 
 it: sysdeps sslclient sslserver https@ sslcat sslconnect sslprint \
-connect-io addcr delcr sslperl
+connect-io addcr delcr sslperl ucspissltest
 
 load: conf-ld print-ld.sh systype warn-auto.sh
 	rm -f load
@@ -537,9 +538,9 @@ sslcat: makeinclude makescrip warn-auto.sh sslcat.sh
 	chmod 755 sslcat
 
 sslclient: load sslclient.o remoteinfo.o timeoutconn.o ssl.a unix.a \
-auto_cafile.o auto_cadir.o auto_ciphers.o socket.lib ssl.lib
+auto_cafile.o auto_cadir.o auto_ciphers.o wait_nohang.o ucspitls_master.o socket.lib ssl.lib
 	./load sslclient remoteinfo.o timeoutconn.o ssl.a unix.a auto_cafile.o \
-	auto_cadir.o auto_ciphers.o  `cat socket.lib` `cat ssl.lib`
+	auto_cadir.o auto_ciphers.o wait_nohang.o ucspitls_master.o  `cat socket.lib` `cat ssl.lib`
 
 sslclient.o: compile sslclient.c ssl.h sig.h exit.h sgetopt.h uint16.h \
 fmt.h scan.h str.h ip4.h uint16.h socket.h fd.h stralloc.h buffer.h \
@@ -594,10 +595,10 @@ sslprint.o: compile sslprint.c buffer.h env.h
 
 sslserver: load sslserver.o auto_cafile.o auto_ccafile.o auto_cadir.o \
 auto_dhfile.o auto_certfile.o auto_keyfile.o auto_ciphers.o rules.o \
-remoteinfo.o timeoutconn.o cdb.a ssl.a unix.a socket.lib ssl.lib
+remoteinfo.o timeoutconn.o wait_nohang.o ucspitls_master.o ucspitls.o cdb.a ssl.a unix.a socket.lib ssl.lib
 	./load sslserver auto_cafile.o auto_ccafile.o auto_cadir.o auto_dhfile.o \
 	auto_certfile.o auto_keyfile.o auto_ciphers.o rules.o remoteinfo.o \
-	timeoutconn.o cdb.a ssl.a unix.a  `cat socket.lib` `cat ssl.lib`
+	timeoutconn.o wait_nohang.o ucspitls_master.o ucspitls.o cdb.a ssl.a unix.a  `cat socket.lib` `cat ssl.lib`
 
 sslserver.o: compile sslserver.c ssl.h uint16.h str.h byte.h fmt.h scan.h \
 ip4.h fd.h exit.h env.h prot.h open.h wait.h stralloc.h alloc.h buffer.h \
@@ -607,7 +608,7 @@ auto_ccafile.h auto_dhfile.h auto_certfile.h auto_keyfile.h \
 auto_ciphers.h stralloc.h gen_alloc.h buffer.h stralloc.h subgetopt.h \
 uint16.h stralloc.h uint16.h stralloc.h stralloc.h iopause.h taia.h \
 gen_alloc.h gen_alloc.h gen_alloc.h gen_alloc.h gen_alloc.h taia.h tai.h \
-tai.h uint64.h uint64.h
+tai.h uint64.h uint64.h ucspitls.h
 	./compile sslserver.c
 
 str_chr.o: compile str_chr.c str.h
@@ -762,3 +763,15 @@ wait_nohang.o: compile wait_nohang.c haswaitp.h
 
 wait_pid.o: compile wait_pid.c error.h haswaitp.h
 	./compile wait_pid.c
+
+ucspissltest.o: ucspissltest.c ucspitls.h
+	./compile ucspissltest.c
+
+ucspitls.o: ucspitls.c ucspitls.h
+	./compile ucspitls.c
+
+ucspitls_master.o: ucspitls_master.c ucspitls_master.h wait.h strerr.h
+	./compile ucspitls_master.c
+
+ucspissltest: load ucspissltest.o ucspitls.o sgetopt.o sgetopt.h subgetopt.h subgetopt.o buffer.o buffer_2.o
+	./load ucspissltest ucspitls.o unix.a
diff --git ucspi-ssl-0.70.2/src/conf-ld ucspi-ssl-0.70.2-tls/src/conf-ld
index 59a0de7..3d700b6 100644
--- ucspi-ssl-0.70.2/src/conf-ld
+++ ucspi-ssl-0.70.2-tls/src/conf-ld
@@ -1,3 +1,3 @@
-gcc -s
+gcc 
 
 This will be used to link .o files into an executable.
diff --git ucspi-ssl-0.70.2/src/conf-ld~ ucspi-ssl-0.70.2-tls/src/conf-ld~
new file mode 100644
index 0000000..1d0518a
--- /dev/null
+++ ucspi-ssl-0.70.2-tls/src/conf-ld~
@@ -0,0 +1,3 @@
+gcc
+
+This will be used to link .o files into an executable.
diff --git ucspi-ssl-0.70.2/src/ssl.h ucspi-ssl-0.70.2-tls/src/ssl.h
index 907a3aa..a92d106 100644
--- ucspi-ssl-0.70.2/src/ssl.h
+++ ucspi-ssl-0.70.2-tls/src/ssl.h
@@ -20,7 +20,7 @@ extern int ssl_verify(SSL *,const char *);
 extern int ssl_params(SSL_CTX *,const char *,int);
 extern int ssl_server_env(SSL *,stralloc *);
 extern int ssl_client_env(SSL *,stralloc *);
-extern void ssl_error_str();
+extern char *ssl_error_str(int);
 extern int ssl_error(int (*)(const char *));
 
 #define ssl_client() (ssl_context(SSLv23_client_method()))
diff --git ucspi-ssl-0.70.2/src/sslclient.c ucspi-ssl-0.70.2-tls/src/sslclient.c
index ed35bda..0feb3d2 100644
--- ucspi-ssl-0.70.2/src/sslclient.c
+++ ucspi-ssl-0.70.2-tls/src/sslclient.c
@@ -31,6 +31,7 @@
 #include "byte.h"
 #include "ndelay.h"
 #include "wait.h"
+#include "ucspitls_master.h"
 
 #define FATAL "sslclient: fatal: "
 #define CONNECT "sslclient: unable to connect to "
@@ -71,6 +72,7 @@ int flagremotehost = 1;
 int flag3 = 0;
 int flagsslenv = 0;
 int flagtcpenv = 0;
+int flagsslwait = 0;
 unsigned long itimeout = 26;
 unsigned long ctimeout[2] = { 2, 58 };
 unsigned int progtimeout = 3600;
@@ -130,6 +132,62 @@ int passwd_cb(char *buf,int size,int rwflag,void *userdata) {
   return password.len;
 }
 
+SSL *start_ssl(int s) {
+  int cloop;
+  SSL *ssl;
+
+  ctx = ssl_client();
+  ssl_errstr();
+  if (!ctx)
+    strerr_die2x(111,FATAL,"unable to create SSL context");
+
+  switch (ssl_certkey(ctx,certfile,keyfile,passwd_cb)) {
+    case -1: strerr_die2x(111,FATAL,"unable to load certificate");
+    case -2: strerr_die2x(111,FATAL,"unable to load key pair");
+    case -3: strerr_die2x(111,FATAL,"key does not match certificate");
+    default: break;
+  }
+
+  if (!ssl_ca(ctx,cafile,cadir,verifydepth))
+    strerr_die2x(111,FATAL,"unable to load CA list");
+
+  if (!ssl_ciphers(ctx,ciphers))
+    strerr_die2x(111,FATAL,"unable to set cipher list");
+
+  ssl = ssl_new(ctx,s);
+  if (!ssl) strerr_die2x(111,FATAL,"unable to create SSL instance");
+
+  for (cloop = 0;cloop < 2;++cloop) {
+    if (!ssl_timeoutconn(ssl,ctimeout[cloop])) goto SSLCONNECTED;
+    if (!cloop && ctimeout[1]) continue;
+    strerr_warn2(FATAL,"unable to SSL connect:",&strerr_sys);
+    ssl_error(error_warn);
+  }
+  return NULL; /* Failure */
+
+ SSLCONNECTED:
+  ndelay_off(s);
+
+  if (verbosity >= 2)
+    strerr_warn1("sslclient: ssl connect",0);
+
+  if (flagservercert)
+    switch(ssl_verify(ssl,flagname ? hostname : 0)) {
+      case -1:
+	strerr_die2x(111,FATAL,"unable to verify server certificate");
+      case -2:
+	strerr_die2x(111,FATAL,"no server certificate");
+      case -3:
+	strerr_die2x(111,FATAL,"server name does not match certificate");
+      default: break;
+    }
+
+  if (!flagdelay)
+    socket_tcpnodelay(s); /* if it fails, bummer */
+
+  return ssl;
+}
+
 int main(int argc,char * const *argv) {
   unsigned long u;
   int opt;
@@ -137,8 +195,12 @@ int main(int argc,char * const *argv) {
   int j;
   int s;
   int cloop;
-  SSL *ssl;
+  SSL *ssl = NULL;
   int wstat;
+  int sslctl[2];
+  char sslctl_cmd;
+  stralloc ssl_env = { 0 };
+  buffer ssl_env_buf;
 
   dns_random_init(seed);
 
@@ -146,7 +208,7 @@ int main(int argc,char * const *argv) {
   close(7);
   sig_ignore(sig_pipe);
  
-  while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:a:A:c:C:k:V:3eEsSnN0xXw:")) != opteof)
+  while ((opt = getopt(argc,argv,"dDvqQhHrRi:p:t:T:l:a:A:c:C:k:V:3eEsSnN0xXw:yY")) != opteof)
     switch(opt) {
       case 'd': flagdelay = 1; break;
       case 'D': flagdelay = 0; break;
@@ -181,6 +243,8 @@ int main(int argc,char * const *argv) {
       case 'n': flagname = 1; break;
       case 'x': flagservercert = 1; break;
       case 'X': flagservercert = 0; break;
+      case 'y': flagsslwait = 1; break;
+      case 'Y': flagsslwait = 0; break;
       default: usage();
     }
   argv += optind;
@@ -305,57 +369,24 @@ int main(int argc,char * const *argv) {
     }
   env("SSLREMOTEINFO",x);
   if (flagtcpenv) env("TCPREMOTEINFO",x);
-
-  ctx = ssl_client();
-  ssl_errstr();
-  if (!ctx)
-    strerr_die2x(111,FATAL,"unable to create SSL context");
-
-  switch (ssl_certkey(ctx,certfile,keyfile,passwd_cb)) {
-    case -1: strerr_die2x(111,FATAL,"unable to load certificate");
-    case -2: strerr_die2x(111,FATAL,"unable to load key pair");
-    case -3: strerr_die2x(111,FATAL,"key does not match certificate");
-    default: break;
-  }
-
-  if (!ssl_ca(ctx,cafile,cadir,verifydepth))
-    strerr_die2x(111,FATAL,"unable to load CA list");
-
-  if (!ssl_ciphers(ctx,ciphers))
-    strerr_die2x(111,FATAL,"unable to set cipher list");
-
-  ssl = ssl_new(ctx,s);
-  if (!ssl) strerr_die2x(111,FATAL,"unable to create SSL instance");
-
-  for (cloop = 0;cloop < 2;++cloop) {
-    if (!ssl_timeoutconn(ssl,ctimeout[cloop])) goto SSLCONNECTED;
-    if (!cloop && ctimeout[1]) continue;
-    strerr_warn2(FATAL,"unable to SSL connect:",&strerr_sys);
-    ssl_error(error_warn);
-  }
-
-  _exit(111);
-
-  SSLCONNECTED:
-
-  ndelay_off(s);
-
-  if (verbosity >= 2)
-    strerr_warn1("sslclient: ssl connect",0);
-
-  if (flagservercert)
-    switch(ssl_verify(ssl,flagname ? hostname : 0)) {
-      case -1:
-	strerr_die2x(111,FATAL,"unable to verify server certificate");
-      case -2:
-	strerr_die2x(111,FATAL,"no server certificate");
-      case -3:
-	strerr_die2x(111,FATAL,"server name does not match certificate");
-      default: break;
+  
+  if (flagsslwait) {
+    /* Create delayed SSL control socket */
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sslctl) == -1) strerr_die2sys(111,FATAL,"unable to create socketpair: ");
+
+    /* Copy the socket to file descriptors 6 and 7 right now, so we
+     * don't use them for something else later.
+     */
+    if (fd_copy(6,s) == -1)
+      strerr_die2sys(111,FATAL,"unable to set up descriptor 6: ");
+    if (fd_copy(7,s) == -1)
+      strerr_die2sys(111,FATAL,"unable to set up descriptor 7: ");
+  } else {
+    /* If we aren't delaying SSL, start it now, so we won't run the client if it fails */
+    if (!(ssl = start_ssl(s))) {
+      _exit(111);
     }
-
-  if (!flagdelay)
-    socket_tcpnodelay(s); /* if it fails, bummer */
+  }
 
   if (pipe(pi) == -1) strerr_die2sys(111,FATAL,"unable to create pipe: ");
   if (pipe(po) == -1) strerr_die2sys(111,FATAL,"unable to create pipe: ");
@@ -372,11 +403,47 @@ int main(int argc,char * const *argv) {
 
   switch(opt = fork()) {
     case -1:
+      /* Error */
       strerr_die2sys(111,FATAL,"unable to fork: ");
     case 0:
+      /* Child runs after switch */
       break;
     default:
+      /* Parent */
       close(pi[0]); close(po[1]);
+      if (flagsslwait) {
+	if (close(sslctl[1]) != 0) {
+	  strerr_die2sys(111, FATAL, "Error closing SSL control socket: ");
+	}
+
+	/* This will exit on a fatal error or if the client quits
+	 * without activating SSL
+	 */
+	sslctl_cmd = ucspitls_master_wait_for_activation(sslctl[0]);
+
+	/* If we got here, SSL has been requested. */
+	if (!(ssl = start_ssl(s))) {
+	  _exit(111);
+	}
+	
+	if (sslctl_cmd == 'Y') {
+	  if (!ssl_client_env(ssl, &ssl_env)) nomem();
+	  stralloc_0(&ssl_env); /* Add another NUL */
+	  buffer_init(&ssl_env_buf,buffer_unixwrite,sslctl[0],NULL,0);
+	  if (buffer_putflush(&ssl_env_buf, ssl_env.s, ssl_env.len) == -1) {
+	    strerr_die2sys(111, FATAL, "unable to write SSL environment: ");
+	  }
+	} else if (sslctl_cmd != 'y') {
+	  strerr_die2x(111,FATAL,"Unrecognized command on SSL socket");
+	}
+	if (close(sslctl[0]) != 0) {
+	  strerr_die2sys(111, FATAL, "Error closing SSL control socket: ");
+	}
+      }
+
+      if (verbosity >= 2)
+	strerr_warn1("sslclient: ssl_io starting",0);
+      
       if (ssl_io(ssl,pi[1],po[0],progtimeout)) {
 	strerr_warn2(FATAL,"unable to speak SSL:",&strerr_sys);
 	ssl_error(error_warn);
@@ -389,17 +456,28 @@ int main(int argc,char * const *argv) {
 	_exit(wait_exitcode(wstat));
       _exit(0);
   }
-  ssl_close(ssl); close(pi[1]); close(po[0]);
-
-  if (flagsslenv && !ssl_client_env(ssl,0)) nomem();
-
-  if (fd_move(6,pi[0]) == -1)
-    strerr_die2sys(111,FATAL,"unable to set up descriptor 6: ");
-  if (fd_move(7,po[1]) == -1)
-    strerr_die2sys(111,FATAL,"unable to set up descriptor 7: ");
+  
+  /* Child */
+  close(pi[1]); close(po[0]); close(sslctl[0]);
+
+  if (flagsslwait) {
+    strnum[fmt_ulong(strnum,sslctl[1])]=0;
+    env("SSLCTLFD",strnum);
+    strnum[fmt_ulong(strnum,pi[0])]=0;
+    env("SSLREADFD",strnum);
+    strnum[fmt_ulong(strnum,po[1])]=0;
+    env("SSLWRITEFD",strnum);
+  } else {
+    ssl_close(ssl); 
+    if (fd_move(6,pi[0]) == -1)
+      strerr_die2sys(111,FATAL,"unable to set up descriptor 6: ");
+    if (fd_move(7,po[1]) == -1)
+      strerr_die2sys(111,FATAL,"unable to set up descriptor 7: ");
+
+    if (flagsslenv && !ssl_client_env(ssl,0)) nomem();
+  }
   sig_uncatch(sig_pipe);
 
   pathexec(argv);
   strerr_die4sys(111,FATAL,"unable to run ",*argv,": ");
 }
-
diff --git ucspi-ssl-0.70.2/src/sslperl.c ucspi-ssl-0.70.2-tls/src/sslperl.c
index 8cf7811..e32a1cb 100644
--- ucspi-ssl-0.70.2/src/sslperl.c
+++ ucspi-ssl-0.70.2-tls/src/sslperl.c
@@ -13,6 +13,7 @@
 #endif
 
 extern const char *self;
+extern char **environ;
 
 /* ActiveState Perl requires this be called my_perl */
 static PerlInterpreter *my_perl = 0;
diff --git ucspi-ssl-0.70.2/src/sslserver.c ucspi-ssl-0.70.2-tls/src/sslserver.c
index b516e98..52f4494 100644
--- ucspi-ssl-0.70.2/src/sslserver.c
+++ ucspi-ssl-0.70.2-tls/src/sslserver.c
@@ -4,6 +4,8 @@
 #include <sys/param.h>
 #include <netdb.h>
 #include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <fcntl.h>
 #include <arpa/inet.h>
 #include "ssl.h"
 #include "uint16.h"
@@ -39,10 +41,12 @@
 #include "auto_certfile.h"
 #include "auto_keyfile.h"
 #include "auto_ciphers.h"
+#include "fmt.h"
+#include "ucspitls_master.h"
+#include "ucspitls.h"
 
 int verbosity = 1;
 int flagkillopts = 1;
-int flagafter = 0;
 int flagdelay = 0;
 const char *banner = "";
 int flagremoteinfo = 1;
@@ -51,6 +55,7 @@ int flagparanoid = 0;
 int flagclientcert = 0;
 int flagsslenv = 0;
 int flagtcpenv = 0;
+int flagsslwait = 0;
 unsigned long timeout = 26;
 unsigned long ssltimeout = 26;
 unsigned int progtimeout = 3600;
@@ -72,6 +77,9 @@ static stralloc remotehostsa;
 char *remotehost = 0;
 char *verifyhost = 0;
 
+unsigned long uid = 0;
+unsigned long gid = 0;
+
 char strnum[FMT_ULONG];
 char strnum2[FMT_ULONG];
 
@@ -106,10 +114,13 @@ stralloc envsa = {0};
 X509 *cert;
 char buf[SSL_NAME_LEN];
 
+#define FATAL "sslserver: fatal: "
+
 
 /* ---------------------------- child */
 
 #define DROP "sslserver: warning: dropping connection, "
+#define DROPSSL "sslserver: warning: SSL disabled due to server error, "
 
 int flagdeny = 0;
 int flagallownorules = 0;
@@ -180,9 +191,104 @@ void doit(int t) {
   int j;
   SSL *ssl;
   int wstat;
+  int sslctl[2];
+  char *s;
+  unsigned long tmp_long;
+  char sslctl_cmd;
+  stralloc ssl_env = { 0 };
+  buffer ssl_env_buf;
 
-  remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
+  if (pipe(pi) == -1) strerr_die2sys(111,DROP,"unable to create pipe: ");
+  if (pipe(po) == -1) strerr_die2sys(111,DROP,"unable to create pipe: ");
+  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sslctl) == -1) strerr_die2sys(111,DROP,"unable to create socketpair: ");
+  
+  switch(fork()) {
+    case -1:
+      strerr_die2sys(111,DROP,"unable to fork: ");
+    case 0:
+      /* Child */
+      break;
+    default:
+      /* Parent */
+      
+      close(pi[0]); close(po[1]); close(sslctl[1]);
+      
+      if ((s=env_get("SSL_CHROOT")))
+        if (chroot(s) == -1)
+          strerr_die2x(111,DROPSSL,"unable to chroot");
+      
+      if ((s=env_get("SSL_GID"))) {
+        scan_ulong(s,&tmp_long);
+        gid = tmp_long;
+      }
+      if (gid) if (prot_gid(gid) == -1) strerr_die2sys(111,DROPSSL,"unable to set gid: ");
 
+      if ((s=env_get("SSL_UID"))) {
+        scan_ulong(s,&tmp_long);
+        uid = tmp_long;
+      }
+      if (uid) if (prot_uid(uid) == -1)
+        strerr_die2sys(111,DROPSSL,"unable to set uid: ");
+
+      /* This will exit on a fatal error or if the client quits
+       * without activating SSL
+       */
+      sslctl_cmd = ucspitls_master_wait_for_activation(sslctl[0]);
+      
+      /* If we got here, SSL must have been activated */
+      ssl = ssl_new(ctx,t);
+      if (!ssl) strerr_die2x(111,DROP,"unable to create SSL instance");
+      if (ndelay_on(t) == -1)
+	strerr_die2sys(111,DROP,"unable to set socket options: ");
+      if (ssl_timeoutaccept(ssl,ssltimeout) == -1)
+	strerr_die3x(111,DROP,"unable to accept SSL: ",ssl_error_str(ssl_errno));
+      
+      if (verbosity >= 2) {
+        strnum[fmt_ulong(strnum,getpid())] = 0;
+        strerr_warn3("sslserver: ssl ",strnum," accept ",0);
+      }
+        
+      if (flagclientcert) {
+        switch(ssl_verify(ssl,verifyhost)) {
+          case -1:
+            strerr_die2x(111,DROP,"unable to verify client certificate");
+          case -2:
+            strerr_die2x(111,DROP,"no client certificate");
+          case -3:
+            strerr_die2x(111,DROP,"client name does not match certificate");
+          default: break;
+        }
+      }
+      
+      if (sslctl_cmd == 'Y') {
+        ssl_server_env(ssl, &ssl_env);
+        stralloc_0(&ssl_env); /* Add another NUL */
+	buffer_init(&ssl_env_buf,buffer_unixwrite,sslctl[0],NULL,0);
+	if (buffer_putflush(&ssl_env_buf, ssl_env.s, ssl_env.len) == -1) {
+	  strerr_die2sys(111, FATAL, "unable to write SSL environment: ");
+	}
+      } else if (sslctl_cmd != 'y') {
+	strerr_die2x(111,DROP,"Protocol error on SSL control descriptor: invalid command character read");
+      }
+
+      if (close(sslctl[0]) != 0) {
+	strerr_die2sys(111, DROP, "Error closing SSL control socket: ");
+      }
+      
+      if (ssl_io(ssl,pi[1],po[0],3600) != 0)
+        strerr_die3x(111,DROP,"unable to speak SSL: ",ssl_error_str(ssl_errno));
+      if (wait_nohang(&wstat) > 0)
+        _exit(wait_exitcode(wstat));
+      ssl_close(ssl);
+      _exit(0);
+  }
+
+  /* Child-only below this point */
+  if (close(sslctl[0]) != 0) { 
+    strerr_die2sys(111, DROP, "Error closing SSL control socket: ");
+  }
+  
+  remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
   if (verbosity >= 2) {
     strnum[fmt_ulong(strnum,getpid())] = 0;
     strerr_warn4("sslserver: pid ",strnum," from ",remoteipstr,0);
@@ -278,59 +384,11 @@ void doit(int t) {
 
   if (flagdeny) _exit(100);
 
-  if (pipe(pi) == -1) strerr_die2sys(111,DROP,"unable to create pipe: ");
-  if (pipe(po) == -1) strerr_die2sys(111,DROP,"unable to create pipe: ");
-
-  ssl = ssl_new(ctx,t);
-  if (!ssl) strerr_die2x(111,DROP,"unable to create SSL instance");
-  if (ndelay_on(t) == -1)
-    strerr_die2sys(111,DROP,"unable to set socket options: ");
-  if (ssl_timeoutaccept(ssl,ssltimeout) == -1) {
-    strerr_warn2(DROP,"unable to SSL accept:",&strerr_sys);
-    ssl_error(error_warn);
-    ssl_close(ssl);
-    _exit(111);
-  }
+  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: ");
 
-  if (verbosity >= 2) {
-    strnum[fmt_ulong(strnum,getpid())] = 0;
-    strerr_warn3("sslserver: ssl ",strnum," accept ",0);
-  }
-
-  if (flagclientcert) {
-    switch(ssl_verify(ssl,verifyhost)) {
-      case -1:
-	strerr_die2x(111,DROP,"unable to verify client certificate");
-      case -2:
-	strerr_die2x(111,DROP,"no client certificate");
-      case -3:
-	strerr_die2x(111,DROP,"client name does not match certificate");
-      default: break;
-    }
-  }
-
-  switch(j = fork()) {
-    case -1:
-      strerr_die2sys(111,DROP,"unable to fork: ");
-    case 0:
-      break;
-    default:
-      sig_ignore(sig_pipe);
-      sig_uncatch(sig_child);
-      sig_unblock(sig_child);
-      close(pi[0]); close(po[1]);
-      if (ssl_io(ssl,pi[1],po[0],progtimeout) != 0) {
-	strerr_warn2(DROP,"unable to speak SSL:",&strerr_sys);
-	ssl_error(error_warn);
-	ssl_close(ssl);
-	wait_pid(&wstat,j);
-	_exit(111);
-      }
-      ssl_close(ssl);
-      if (wait_pid(&wstat,j) > 0)
-	_exit(wait_exitcode(wstat));
-      _exit(0);
-  }
   close(pi[1]); close(po[0]);
 
   sig_uncatch(sig_child);
@@ -338,13 +396,32 @@ void doit(int t) {
   sig_uncatch(sig_term);
   sig_uncatch(sig_pipe);
 
-  if (flagsslenv && !ssl_server_env(ssl,0)) drop_nomem();
-  ssl_close(ssl);  
-
-  if (fd_move(0,pi[0]) == -1)
-    strerr_die2sys(111,DROP,"unable to set up descriptor 0: ");
-  if (fd_move(1,po[1]) == -1)
-    strerr_die2sys(111,DROP,"unable to set up descriptor 1: ");
+  if (fcntl(sslctl[1],F_SETFD,0) == -1)
+    strerr_die2sys(111,FATAL,"unable to clear close-on-exec flag");
+  strnum[fmt_ulong(strnum,sslctl[1])]=0;
+  setenv("SSLCTLFD",strnum,1);
+
+  if (fcntl(pi[0],F_SETFD,0) == -1)
+    strerr_die2sys(111,FATAL,"unable to clear close-on-exec flag");
+  strnum[fmt_ulong(strnum,pi[0])]=0;
+  setenv("SSLREADFD",strnum,1);
+
+  if (fcntl(po[1],F_SETFD,0) == -1)
+    strerr_die2sys(111,FATAL,"unable to clear close-on-exec flag");
+  strnum[fmt_ulong(strnum,po[1])]=0;
+  setenv("SSLWRITEFD",strnum,1);
+  
+  if (flagsslwait) {
+    if (fd_copy(0,t) == -1)
+      strerr_die2sys(111,DROP,"unable to set up descriptor 0: ");
+    if (fd_copy(1,t) == -1)
+      strerr_die2sys(111,DROP,"unable to set up descriptor 1: ");
+  } else {
+    if (fd_move(0,pi[0]) == -1)
+      strerr_die2sys(111,DROP,"unable to set up descriptor 0: ");
+    if (fd_move(1,po[1]) == -1)
+      strerr_die2sys(111,DROP,"unable to set up descriptor 1: ");
+  }
 
   if (flagkillopts)
     socket_ipoptionskill(t);
@@ -357,6 +434,12 @@ void doit(int t) {
       strerr_die2sys(111,DROP,"unable to print banner: ");
   }
 
+  if (!flagsslwait) {
+    strnum[fmt_ulong(strnum,flagsslenv)] = 0;
+    strerr_warn2("flagsslenv: ", strnum, 0);
+    ucspitls(flagsslenv,0,1);
+  }
+      
   pathexec(prog);
   strerr_die4sys(111,DROP,"unable to run ",*prog,": ");
 }
@@ -365,13 +448,11 @@ void doit(int t) {
 
 /* ---------------------------- parent */
 
-#define FATAL "sslserver: fatal: "
-
 void usage(void)
 {
   strerr_warn1("\
 sslserver: usage: sslserver \
-[ -13UXpPhHrRoOdDqQviIeEsS ] \
+[ -13UXpPhHrRoOdDqQviIeEsSnN ] \
 [ -c limit ] \
 [ -x rules.cdb ] \
 [ -B banner ] \
@@ -392,8 +473,6 @@ unsigned long numchildren = 0;
 int flag1 = 0;
 int flag3 = 0;
 unsigned long backlog = 20;
-unsigned long uid = 0;
-unsigned long gid = 0;
 
 void printstatus(void)
 {
@@ -449,7 +528,7 @@ int main(int argc,char * const *argv) {
   int s;
   int t;
  
-  while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:T:u:g:l:b:B:c:pPoO3IiEeSsaAw:")) != opteof)
+  while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:T:u:g:l:b:B:c:pPoO3IiEeSsaAw:nNyY")) != opteof)
     switch(opt) {
       case 'b': scan_ulong(optarg,&backlog); break;
       case 'c': scan_ulong(optarg,&limit); break;
@@ -485,8 +564,8 @@ int main(int argc,char * const *argv) {
       case 's': flagsslenv = 1; break;
       case 'E': flagtcpenv = 0; break;
       case 'e': flagtcpenv = 1; break;
-      case 'A': flagafter = 0; break;
-      case 'a': flagafter = 1; break;
+      case 'n': case 'y': flagsslwait = 1; break;
+      case 'N': case 'Y': flagsslwait = 0; break;
       default: usage();
     }
   argc -= optind;
@@ -566,13 +645,6 @@ int main(int argc,char * const *argv) {
     strerr_die2sys(111,FATAL,"unable to listen: ");
   ndelay_off(s);
 
-  if (!flagafter) {
-    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: ");
-  }
-
   localportstr[fmt_ulong(localportstr,localport)] = 0;
   if (flag1) {
     buffer_init(&b,buffer_unixwrite,1,bspace,sizeof bspace);
@@ -603,13 +675,6 @@ int main(int argc,char * const *argv) {
   if (!ssl_params(ctx,dhfile,rsalen))
     strerr_die2x(111,FATAL,"unable to set cipher parameters");
 
-  if (flagafter) {
-    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: ");
-  }
-
   if (!ssl_ciphers(ctx,ciphers))
     strerr_die2x(111,FATAL,"unable to set cipher list");
 
@@ -624,8 +689,9 @@ int main(int argc,char * const *argv) {
     strerr_warn6("sslserver: param ",strnum," ",dhfile," ",strnum2,0);
   }
 
-  close(0);
-  close(1);
+  close(0); open_read("/dev/null");
+  close(1); open_append("/dev/null");
+
   printstatus();
  
   for (;;) {
@@ -650,3 +716,11 @@ int main(int argc,char * const *argv) {
     close(t);
   }
 }
+
+/* taken from 0.68 */
+char *ssl_error_str(int e)
+{
+  SSL_load_error_strings();
+  return ERR_error_string(e,0);
+}
+
diff --git ucspi-ssl-0.70.2/src/ucspissltest.c ucspi-ssl-0.70.2-tls/src/ucspissltest.c
new file mode 100644
index 0000000..4acdba1
--- /dev/null
+++ ucspi-ssl-0.70.2-tls/src/ucspissltest.c
@@ -0,0 +1,206 @@
+#include <stdio.h>
+#include <sys/select.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include "ucspitls.h"
+#include "sgetopt.h"
+
+void usage(char *progname, int exit_status) {
+  printf("Usage: %s [-yYsScCvqQ]\n", progname);
+  printf(
+	 "\t-y: Delay SSL until SIGUSR1 is received\n"
+	 "\t-Y: Disable delayed SSL; plaintext mode, or SSL handled in sslclient/sslserver (default)\n"
+	 "\t-s: Send SSL environment\n"
+	 "\t-S: Don't send SSL environment (default)\n"
+	 "\t-c: Client mode, for use with sslclient\n"
+	 "\t-C: Server mode, for use with sslserver (default)\n"
+	 "\t-v: Verbose mode\n"
+	 "\t-q: Quiet mode\n"
+	 "\t-Q: Non-quiet, non-verbose output (default)\n"
+	 );
+  printf("Signals:\n"
+	 "\tSIGUSR1: Switch to SSL mode (if running with -y)\n"
+	 "\tSIGUSR2: Dump environment to stderr\n"
+	 );
+  printf("Examples:\n"
+	 "  Delayed TLS server with no environment (send SIGUSR1 to start TLS):\n"
+	 "\tenv DHFILE=./dh1024.pem CERTFILE=./localhost.cert KEYFILE=./localhost.key ./sslserver -3 3<localhost.pw -v -y $HOST $PORT ./ucspissltest -C -y\n"
+	 "  Initial TLS server with environment:\n"
+	 "\tenv DHFILE=./dh1024.pem CERTFILE=./localhost.cert KEYFILE=./localhost.key ./sslserver -3 3<localhost.pw -v -y $HOST $PORT ./ucspissltest -s -C\n"
+	 "  Delayed TLS client with environment (send SIGUSR1 to start TLS):\n"
+	 "\t./sslclient -s -X -y $HOST $PORT ./ucspissltest -c -s -y\n"
+	 "  Initial TLS client with no environment:\n"
+	 "\t./sslclient -X $HOST $PORT ./ucspissltest -c\n"
+	 );
+  
+  exit(exit_status);
+}
+
+#define BUFSIZE 8192
+
+static int fd_sets[2][2];
+static int num_sets;
+
+int start_ssl = 0;
+int dump_env = 0;
+
+/* Signal handler to set a flag to start SSL */
+void request_ssl(int sig) {
+  if (start_ssl == 0)
+    start_ssl = 1;
+}
+
+/* Signal handler to set a flag to dump environment */
+void request_dumpenv(int sig) {
+  dump_env = 1;
+}
+
+int flagsslwait = 0;
+int flagsslenv = 0;
+int verbosity = 1;
+int client = 0;
+
+/* Simple test program for tcpclient / sslclient */
+int main(int argc, char *argv[]) {
+  fd_set read_fds;
+  int selret, nr, max_read_fd, nw, total_written;
+  char buf[BUFSIZE];
+  int i;
+  int opt;
+  int readfd, writefd;
+
+  while ((opt = getopt(argc, argv, "yYsSvqQcCh")) != opteof) {
+    switch(opt) {
+      case 'y': flagsslwait = 1; break;
+      case 'Y': flagsslwait = 0; break;
+      case 's': flagsslenv = 1; break;
+      case 'S': flagsslenv = 0; break;
+      case 'v': verbosity = 2; break;
+      case 'q': verbosity = 0; break;
+      case 'Q': verbosity = 1; break;
+      case 'c': client = 1; break;
+      case 'C': client = 0; break;
+      case 'h': usage(argv[0],0); /* Exits */
+      default: usage(argv[0],1); /* Exits */
+    }
+  }
+
+  if (client) {
+    /*
+     * From sslclient, we have these file descriptors:
+     *   0: Standard input (terminal)
+     *   1: Standard output (terminal)
+     *   2: Standard error (terminal)
+     *   6: Remote read (network)
+     *   7: Remote write (network)
+     */
+    num_sets = 2;
+    fd_sets[0][0] = 0; fd_sets[0][1] = 7;
+    fd_sets[1][0] = 6; fd_sets[1][1] = 1;
+    readfd = 6; writefd = 7;
+  } else {
+    /* From sslserver, we have these file descriptors:
+     *   0: Remote read (network)
+     *   1: Remote write (network)
+     *   2: Standard error (terminal)
+     */
+    num_sets = 1;
+    fd_sets[0][0] = 0; fd_sets[0][1] = 1;
+    readfd = 0; writefd = 1;
+  }
+  if (verbosity > 0 ) {
+    fprintf(stderr,"%s started, pid %d\n", argv[0], getpid());
+    if (flagsslwait) {
+      fprintf(stderr,"Send USR1 to activate TLS\n");
+    }
+    fprintf(stderr,"Send USR2 to dump environment\n");
+  }
+
+  /* Initialize data structures for select */
+  FD_ZERO(&read_fds);
+  max_read_fd = -1;
+  for(i=0;i<num_sets;++i) {
+    if (max_read_fd < fd_sets[i][0]) {
+      max_read_fd = fd_sets[i][0];
+    }
+  }
+
+  if (flagsslwait) {
+    signal(SIGUSR1, request_ssl);
+  }
+  signal(SIGUSR2, request_dumpenv);
+  signal(SIGPIPE, SIG_IGN);
+
+  /* Simple event loop */
+  while (1) {
+    /* Check for flags set in signal handlers */
+    if (start_ssl == 1) {
+      /* Flag to activate SSL */
+      start_ssl = 2;
+      if (verbosity > 0) {
+	fprintf(stderr,"SSL requested, starting\n");
+      }
+      if (!ucspitls(flagsslenv,readfd,writefd)) {
+	fprintf(stderr,"SSL activation failed\n");
+	return 127;
+      }
+      if (verbosity > 0) {
+	fprintf(stderr,"SSL complete\n");
+      }
+    }
+    if (dump_env) {
+      dump_env = 0;
+      system("env >&2");
+    }
+
+    /* See what's readable with select().  Note this is not a
+     * super-efficient implementation, it really is designed for
+     * testing. */
+    for(i=0;i<num_sets;++i) {
+      FD_SET(fd_sets[i][0], &read_fds);
+    }
+    if ((selret = select(max_read_fd+1, &read_fds, NULL, NULL, NULL)) == -1) {
+      switch(errno) {
+        case EINTR:
+	  /* Retry */
+	  continue;
+      default:
+	fprintf(stderr,"select failed: %s\n",strerror(errno));
+	return 1;
+      }
+    }
+
+    /* Read from the readable FDs */
+    for(i=0;i<num_sets;++i) {
+      if (FD_ISSET(fd_sets[i][0], &read_fds)) {
+	nr = read(fd_sets[i][0], buf, BUFSIZE);
+	if (nr == 0) {
+	  /* EOF */
+	  if (verbosity > 0) {
+	    fprintf(stderr,"fd %d closed\n", fd_sets[i][0]);
+	  }
+	  return fd_sets[i][0];
+	} else if (nr < 0) {
+	  /* Error */
+	  fprintf(stderr,"read from fd %d failed: %s\n", fd_sets[i][0], strerror(errno));
+	  return fd_sets[i][0];
+	} else {
+	  /* Successfully read nr bytes */
+	  total_written = 0;
+	  while (total_written < nr) {
+	    nw = write(fd_sets[i][1], buf + total_written, nr - total_written);
+	    if (nw <= 0) {
+	      fprintf(stderr,"write to fd %d failed: %s\n", fd_sets[i][1], strerror(errno));
+	      return fd_sets[i][1];
+	    }
+	    total_written += nw;
+	  }
+	}
+      }
+    }
+  }
+  return 0;
+}
diff --git ucspi-ssl-0.70.2/src/ucspitls.c ucspi-ssl-0.70.2-tls/src/ucspitls.c
new file mode 100644
index 0000000..2ede81c
--- /dev/null
+++ ucspi-ssl-0.70.2-tls/src/ucspitls.c
@@ -0,0 +1,107 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <limits.h>
+
+#define BUFSIZE 16384
+
+/* This is written in a simple style, not using the ucspi-ssl string
+ * libraries, so it is easy to embed in other programs.
+ */
+
+/* Read a file descriptor from the environment, or return -1 on error
+*/
+static int fdenv(const char *envname) {
+  char *fdstr;
+  long fd;
+
+  if (!(fdstr=getenv(envname)))
+    return -1;
+  errno = 0;
+  fd = strtol(fdstr, NULL, 10);
+  if (errno != 0) return -1;
+  if (fd < 0 || fd > INT_MAX) return -1;
+
+  return fd;
+}
+
+/* Activate UCSPI-TLS */
+int ucspitls(int want_env, int readfd, int writefd)
+{
+  int fd;
+  char *addenv = malloc(BUFSIZE);
+  int curbufsize = BUFSIZE;
+  int readret;
+  int totalrb;
+  
+  /* Figure out our control FD */
+  if ( (fd = fdenv("SSLCTLFD")) < 0) {
+    return 0;
+  }
+
+  if (want_env) {
+    /* Request the environment on the SSL control FD */
+    
+    if (write((int)fd, "Y", 1) < 1)
+      return 0;
+  } else {
+    /* Activate SSL but don't request the environment */
+    if (write((int)fd, "y", 1) < 1)
+      return 0;
+  }
+
+    
+  /* Read what is sent over the file descriptor.  This should
+   * basically always happen in one read, so other situations are
+   * handled correctly but inefficiently.
+   */
+  totalrb = 0;
+  addenv[0] = '\0';
+  while ((readret = read(fd,addenv + totalrb,curbufsize - totalrb)) > 0) {
+    totalrb += readret;
+    if (totalrb == curbufsize) {
+      curbufsize += BUFSIZE;
+      addenv = realloc(addenv, curbufsize);
+    }
+    }
+  if (readret == -1) {
+    fprintf(stderr,"Error reading SSL environment: %s\n",strerror(errno));
+    return 0;
+  }
+  
+  if (want_env) {
+    /* Parse the variables we read, and add them to the environment */
+    char *nextenv = addenv;
+    while (*nextenv) {
+      char *val = strchr(nextenv,'=');
+      if (val && strncmp(nextenv,"SSL_",4) == 0) {
+	*val = '\0';
+	++val;
+	setenv(nextenv,val,1);
+      } else {
+	val = nextenv; // So we will start searching in the right place
+      }
+      nextenv = strchr(val, '\0') + 1;
+    }
+  }
+  
+  /* Now get the new file descriptors for reading and writing, and dup
+   * them to the client's read and write fd, respectively.  The client
+   * should be sure to discard any buffered data from before encyption
+   * was activated, to avoid any issues like CVE-2011-0411.
+   */
+  if ((fd = fdenv("SSLREADFD")) < 0)
+    return 0;
+  if (dup2((int)fd,readfd) == -1)
+    return 0;
+ 
+  if ((fd = fdenv("SSLWRITEFD")) < 0)
+    return 0;
+  if (dup2((int)fd,writefd) == -1)
+    return 0;
+ 
+  /* It worked! */
+  return 1;
+}
diff --git ucspi-ssl-0.70.2/src/ucspitls.h ucspi-ssl-0.70.2-tls/src/ucspitls.h
new file mode 100644
index 0000000..5a54500
--- /dev/null
+++ ucspi-ssl-0.70.2-tls/src/ucspitls.h
@@ -0,0 +1 @@
+int ucspitls(int want_env, int readfd, int writefd);
diff --git ucspi-ssl-0.70.2/src/ucspitls_master.c ucspi-ssl-0.70.2-tls/src/ucspitls_master.c
new file mode 100644
index 0000000..e6b4142
--- /dev/null
+++ ucspi-ssl-0.70.2-tls/src/ucspitls_master.c
@@ -0,0 +1,44 @@
+#include <unistd.h>
+#include <errno.h>
+#include "wait.h"
+#include "strerr.h"
+
+#define FATAL "Fatal error in SSL activation: "
+
+/* Returns UCSPI-TLS command character (y or Y) on success.
+ * On failure or child exit, exits directly and does not return.
+ */
+char ucspitls_master_wait_for_activation(int fd) {
+  char sslctl_read_ret;
+  char sslctl_cmd;
+  int wstat;
+
+  /* Read the TLS command socket.  This will block until/unless
+   * TLS is requested.
+   */  
+  while(1) {
+    sslctl_read_ret = read(fd,&sslctl_cmd,1);
+    if ( sslctl_read_ret == 1 ) {
+      /* SSL was requested */
+      break;
+    } else if (sslctl_read_ret == 0) {
+      /* EOF from client, it must have exited */
+      if (wait_nohang(&wstat) <= 0) {
+	strerr_die2sys(111, FATAL, "Error waiting for child socket: ");
+      }
+      _exit(wait_exitcode(wstat));
+    } else if (sslctl_read_ret < 0) {
+      /* Error.  Is it retryable? */
+      if (errno == EAGAIN || errno == EINTR) {
+	/* Do nothing, let the loop run again */
+      } else {
+	strerr_die2sys(111,FATAL,"Read error on SSL control descriptor");
+      }
+    } else {
+      /* Too many characters read, should not really happen */
+      strerr_die2x(111,FATAL,"Protocol error on SSL control descriptor: too many characters read");
+    }
+  }
+
+  return sslctl_cmd;
+}
diff --git ucspi-ssl-0.70.2/src/ucspitls_master.h ucspi-ssl-0.70.2-tls/src/ucspitls_master.h
new file mode 100644
index 0000000..acb84db
--- /dev/null
+++ ucspi-ssl-0.70.2-tls/src/ucspitls_master.h
@@ -0,0 +1 @@
+char ucspitls_master_wait_for_activation(int fd);
-- 
1.6.6.2


From 8f95e2c9d839a21e449f5de5975ef31010edadc7 Mon Sep 17 00:00:00 2001
From: Christian Wiese <chris@opensde.org>
Date: Wed, 16 Nov 2011 17:43:41 +0100
Subject: [PATCH 2/2] removed src/conf-ld~

---
 src/conf-ld~ |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)
 delete mode 100644 src/conf-ld~

diff --git ucspi-ssl-0.70.2/src/conf-ld~ ucspi-ssl-0.70.2-tls/src/conf-ld~
deleted file mode 100644
index 1d0518a..0000000
--- ucspi-ssl-0.70.2/src/conf-ld~
+++ /dev/null
@@ -1,3 +0,0 @@
-gcc
-
-This will be used to link .o files into an executable.
-- 
1.6.6.2