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 <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 |
|
|
|
|