You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1249 lines
						
					
					
						
							38 KiB
						
					
					
				
			
		
		
	
	
							1249 lines
						
					
					
						
							38 KiB
						
					
					
				| # --- 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 <[email protected]> | |
| 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 <[email protected]> | |
| 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 | |
| 
 | |
| 
 |