diff -cr stunnel-3.8/FAQ stunnel-3.8p1/FAQ *** stunnel-3.8/FAQ Mon Feb 21 00:58:06 2000 --- stunnel-3.8p1/FAQ Sun Jun 11 23:20:13 2000 *************** *** 1,6 **** stunnel Universal SSL tunnel ! See another FAQ at http://www.onsight.com/faq/stunnel/ Q: Is there a mailing list for stunnel? A: Sure. You can subscribe the list in two simple steps: --- 1,6 ---- stunnel Universal SSL tunnel ! See another FAQ at http://www.stunnel.org/ Q: Is there a mailing list for stunnel? A: Sure. You can subscribe the list in two simple steps: diff -cr stunnel-3.8/HISTORY stunnel-3.8p1/HISTORY *** stunnel-3.8/HISTORY Thu Feb 24 03:39:36 2000 --- stunnel-3.8p1/HISTORY Sun Jun 11 23:19:19 2000 *************** *** 1,5 **** --- 1,13 ---- stunnel Universal SSL tunnel + Version 3.8p1, 2000.06.11 bri@stunnel.org: + * Added rigerous PRNG seeding + * PID changes (and related security-fix) + * Man page fixes + * Client SSL Session-IDs now used + * -N flag to specify tcpwrapper service name + + Version 3.8, 2000.02.24: * Checking for threads in c_r library for FreeBSD. * Some compatibility fixes for Ultrix. diff -cr stunnel-3.8/Makefile.in stunnel-3.8p1/Makefile.in *** stunnel-3.8/Makefile.in Tue Feb 22 04:08:16 2000 --- stunnel-3.8p1/Makefile.in Sun Jun 11 23:12:07 2000 *************** *** 7,13 **** sbindir=@sbindir@ libdir=@libdir@ man8dir=@mandir@/man8 ! piddir=@localstatedir@/stunnel ssldir=@ssldir@ certdir=$(ssldir)/certs @SET_MAKE@ --- 7,13 ---- sbindir=@sbindir@ libdir=@libdir@ man8dir=@mandir@/man8 ! piddir=@localstatedir@/stunnel/ ssldir=@ssldir@ certdir=$(ssldir)/certs @SET_MAKE@ *************** *** 15,21 **** RANDOM_OPT=@RANDOM_OPT@ CC=@CC@ INSTALL=@INSTALL@ ! CFLAGS=@CFLAGS@ @DEFS@ -Dcertdir=\"$(certdir)\" -Dlibdir=\"$(libdir)\" -Dpiddir=\"$(piddir)\" LIBS=@LIBS@ OBJS=stunnel.o ssl.o protocol.o sthreads.o pty.o log.o DESTFILES=$(sbindir)/stunnel $(libdir)/stunnel.so $(man8dir)/stunnel.8 $(certdir)/stunnel.pem --- 15,21 ---- RANDOM_OPT=@RANDOM_OPT@ CC=@CC@ INSTALL=@INSTALL@ ! CFLAGS=@CFLAGS@ @DEFS@ -Dcertdir=\"$(certdir)\" -Dlibdir=\"$(libdir)\" -DPIDDIR=\"$(piddir)\" LIBS=@LIBS@ OBJS=stunnel.o ssl.o protocol.o sthreads.o pty.o log.o DESTFILES=$(sbindir)/stunnel $(libdir)/stunnel.so $(man8dir)/stunnel.8 $(certdir)/stunnel.pem diff -cr stunnel-3.8/common.h stunnel-3.8p1/common.h *** stunnel-3.8/common.h Thu Feb 24 03:35:00 2000 --- stunnel-3.8p1/common.h Sun Jun 11 23:12:07 2000 *************** *** 126,131 **** --- 126,136 ---- /* Length of strings (including the terminating '\0' character) */ #define STRLEN 1024 + /* How many bytes of random input to read from files for PRNG */ + /* OpenSSL likes at least 128 bits, so 64 bytes seems plenty. */ + #define RANDOM_BYTES 64 + #define RANDOM_BYTES_STRING "64" + /* Safe copy for strings declarated as char[STRLEN] */ #define safecopy(dst, src) \ (dst[STRLEN-1]='\0', strncpy((dst), (src), STRLEN-1)) *************** *** 135,140 **** --- 140,146 ---- typedef struct { char certfile[STRLEN]; /* name of the certificate */ char clientdir[STRLEN]; + char cacert[STRLEN]; char pidfile[STRLEN]; unsigned long dpid; int clients; *************** *** 153,158 **** --- 159,169 ---- char *protocol; char *setuid_user; char *setgid_group; + char *egd_sock; /* entropy gathering daemon socket */ + char *rand_file; /* file with random data */ + int rand_write; /* overwrite rand_file with new rand data when PRNG seeded */ + int random_bytes; /* how many random bytes to read */ + char *pid_dir; } server_options; /* Prototypes for stunnel.c */ diff -cr stunnel-3.8/configure stunnel-3.8p1/configure *** stunnel-3.8/configure Thu Feb 24 03:28:45 2000 --- stunnel-3.8p1/configure Sun Jun 11 23:12:07 2000 *************** *** 12,17 **** --- 12,19 ---- ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help + --with-egd-socket=FILE Entropy Gathering Daemon socket pathname" + ac_help="$ac_help --with-random=FILE read randomness from FILE (default=/dev/urandom)" ac_help="$ac_help --with-ssl=DIR location of installed SSL libraries/include files" *************** *** 552,558 **** fi echo $ac_n "checking host system type""... $ac_c" 1>&6 ! echo "configure:556: checking host system type" >&5 host_alias=$host case "$host_alias" in --- 554,560 ---- fi echo $ac_n "checking host system type""... $ac_c" 1>&6 ! echo "configure:558: checking host system type" >&5 host_alias=$host case "$host_alias" in *************** *** 575,581 **** # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ! echo "configure:579: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 577,583 ---- # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ! echo "configure:581: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 605,611 **** # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ! echo "configure:609: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 607,613 ---- # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ! echo "configure:611: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 656,662 **** # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ! echo "configure:660: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 658,664 ---- # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 ! echo "configure:662: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 688,694 **** fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 ! echo "configure:692: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. --- 690,696 ---- fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 ! echo "configure:694: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. *************** *** 699,710 **** cat > conftest.$ac_ext << EOF ! #line 703 "configure" #include "confdefs.h" main(){return(0);} EOF ! if { (eval echo configure:708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then --- 701,712 ---- cat > conftest.$ac_ext << EOF ! #line 705 "configure" #include "confdefs.h" main(){return(0);} EOF ! if { (eval echo configure:710: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then *************** *** 730,741 **** { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 ! echo "configure:734: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 ! echo "configure:739: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 732,743 ---- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 ! echo "configure:736: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 ! echo "configure:741: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 744,750 **** yes; #endif EOF ! if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:748: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no --- 746,752 ---- yes; #endif EOF ! if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:750: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no *************** *** 763,769 **** ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 ! echo "configure:767: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 765,771 ---- ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 ! echo "configure:769: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 807,813 **** # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 ! echo "configure:811: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 809,815 ---- # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 ! echo "configure:813: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 860,866 **** test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 ! echo "configure:864: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 862,868 ---- test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 ! echo "configure:866: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 894,909 **** EOF # Check whether --with-random or --without-random was given. if test "${with_random+set}" = set; then withval="$with_random" ! RANDOM_OPT="-rand $withval" else ac_safe=`echo ""/dev/urandom"" | sed 'y%./+-%__p_%'` echo $ac_n "checking for "/dev/urandom"""... $ac_c" 1>&6 ! echo "configure:907: checking for "/dev/urandom"" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 896,925 ---- EOF + # Check whether --with-egd-socket or --without-egd-socket was given. + if test "${with_egd_socket+set}" = set; then + withval="$with_egd_socket" + EGD_SOCKET="$withval" + + fi + + if test -n "$EGD_SOCKET" ; then + cat >> confdefs.h <&6 ! echo "configure:923: checking for "/dev/urandom"" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 933,938 **** --- 949,960 ---- fi + if test -n "$RANDOM_FILE" ; then + cat >> confdefs.h <&6 ! echo "configure:957: checking for SSL directory" >&5 # Check whether --with-ssl or --without-ssl was given. if test "${with_ssl+set}" = set; then withval="$with_ssl" --- 975,981 ---- } echo $ac_n "checking for SSL directory""... $ac_c" 1>&6 ! echo "configure:979: checking for SSL directory" >&5 # Check whether --with-ssl or --without-ssl was given. if test "${with_ssl+set}" = set; then withval="$with_ssl" *************** *** 993,999 **** echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 ! echo "configure:997: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 1015,1021 ---- echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 ! echo "configure:1019: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 1001,1007 **** ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else --- 1034,1040 ---- gethostbyname() ; return 0; } EOF ! if { (eval echo configure:1038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else *************** *** 1040,1046 **** fi echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 ! echo "configure:1044: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 1062,1068 ---- fi echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 ! echo "configure:1066: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 1048,1054 **** ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else --- 1081,1087 ---- socket() ; return 0; } EOF ! if { (eval echo configure:1085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else *************** *** 1087,1093 **** fi echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 ! echo "configure:1091: checking for pthread_create in -lpthread" >&5 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 1109,1115 ---- fi echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6 ! echo "configure:1113: checking for pthread_create in -lpthread" >&5 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 1095,1101 **** ac_save_LIBS="$LIBS" LIBS="-lpthread $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else --- 1128,1134 ---- pthread_create() ; return 0; } EOF ! if { (eval echo configure:1132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else *************** *** 1134,1140 **** fi echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6 ! echo "configure:1138: checking for pthread_create in -lc_r" >&5 ac_lib_var=`echo c_r'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 1156,1162 ---- fi echo $ac_n "checking for pthread_create in -lc_r""... $ac_c" 1>&6 ! echo "configure:1160: checking for pthread_create in -lc_r" >&5 ac_lib_var=`echo c_r'_'pthread_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 1142,1148 **** ac_save_LIBS="$LIBS" LIBS="-lc_r $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else --- 1175,1181 ---- pthread_create() ; return 0; } EOF ! if { (eval echo configure:1179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else *************** *** 1181,1187 **** fi echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 ! echo "configure:1185: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 1203,1209 ---- fi echo $ac_n "checking for openpty in -lutil""... $ac_c" 1>&6 ! echo "configure:1207: checking for openpty in -lutil" >&5 ac_lib_var=`echo util'_'openpty | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 1189,1195 **** ac_save_LIBS="$LIBS" LIBS="-lutil $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else --- 1222,1228 ---- openpty() ; return 0; } EOF ! if { (eval echo configure:1226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else *************** *** 1229,1246 **** echo $ac_n "checking for hosts_access in -lwrap""... $ac_c" 1>&6 ! echo "configure:1233: checking for hosts_access in -lwrap" >&5 saved_LIBS="$LIBS" LIBS="-lwrap $saved_LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF #define HAVE_LIBWRAP 1 --- 1251,1268 ---- echo $ac_n "checking for hosts_access in -lwrap""... $ac_c" 1>&6 ! echo "configure:1255: checking for hosts_access in -lwrap" >&5 saved_LIBS="$LIBS" LIBS="-lwrap $saved_LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6; cat >> confdefs.h <<\EOF #define HAVE_LIBWRAP 1 *************** *** 1258,1275 **** LIBS="$LIBS -L$ssldir/lib -lssl -lcrypto" echo $ac_n "checking for RSAref library""... $ac_c" 1>&6 ! echo "configure:1262: checking for RSAref library" >&5 saved_LIBS="$LIBS" LIBS="$saved_LIBS -lRSAglue -lrsaref" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6; else --- 1280,1297 ---- LIBS="$LIBS -L$ssldir/lib -lssl -lcrypto" echo $ac_n "checking for RSAref library""... $ac_c" 1>&6 ! echo "configure:1284: checking for RSAref library" >&5 saved_LIBS="$LIBS" LIBS="$saved_LIBS -lRSAglue -lrsaref" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6; else *************** *** 1283,1289 **** ac_safe=`echo ""/dev/ptmx"" | sed 'y%./+-%__p_%'` echo $ac_n "checking for "/dev/ptmx"""... $ac_c" 1>&6 ! echo "configure:1287: checking for "/dev/ptmx"" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 1305,1311 ---- ac_safe=`echo ""/dev/ptmx"" | sed 'y%./+-%__p_%'` echo $ac_n "checking for "/dev/ptmx"""... $ac_c" 1>&6 ! echo "configure:1309: checking for "/dev/ptmx"" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 1311,1317 **** ac_safe=`echo ""/dev/ptc"" | sed 'y%./+-%__p_%'` echo $ac_n "checking for "/dev/ptc"""... $ac_c" 1>&6 ! echo "configure:1315: checking for "/dev/ptc"" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else --- 1333,1339 ---- ac_safe=`echo ""/dev/ptc"" | sed 'y%./+-%__p_%'` echo $ac_n "checking for "/dev/ptc"""... $ac_c" 1>&6 ! echo "configure:1337: checking for "/dev/ptc"" >&5 if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 1341,1347 **** # AC_HEADER_STDC # AC_HEADER_SYS_WAIT echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 ! echo "configure:1345: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= --- 1363,1369 ---- # AC_HEADER_STDC # AC_HEADER_SYS_WAIT echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 ! echo "configure:1367: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= *************** *** 1356,1368 **** # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1366: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : --- 1378,1390 ---- # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1388: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : *************** *** 1373,1385 **** rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : --- 1395,1407 ---- rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : *************** *** 1390,1402 **** rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1400: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : --- 1412,1424 ---- rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1422: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : *************** *** 1424,1440 **** do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 ! echo "configure:1428: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1438: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* --- 1446,1462 ---- do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 ! echo "configure:1450: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1460: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* *************** *** 1471,1482 **** for ac_func in getopt snprintf vsnprintf openpty _getpty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 ! echo "configure:1475: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 ! echo "configure:1497: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else --- 1521,1527 ---- ; return 0; } EOF ! if { (eval echo configure:1525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff -cr stunnel-3.8/configure.in stunnel-3.8p1/configure.in *** stunnel-3.8/configure.in Tue Feb 22 05:19:04 2000 --- stunnel-3.8p1/configure.in Sun Jun 11 23:12:07 2000 *************** *** 12,21 **** AC_SUBST(VERSION) AC_DEFINE_UNQUOTED(VERSION, "$VERSION") dnl Check for user-specified random device AC_ARG_WITH(random, [ --with-random=FILE read randomness from FILE (default=/dev/urandom)], ! [ RANDOM_OPT="-rand $withval" ], [ dnl Check for random device AC_CHECK_FILE("/dev/urandom", --- 12,29 ---- AC_SUBST(VERSION) AC_DEFINE_UNQUOTED(VERSION, "$VERSION") + AC_ARG_WITH(egd-socket, + [ --with-egd-socket=FILE Entropy Gathering Daemon socket pathname], + [ EGD_SOCKET="$withval" ] + ) + if test -n "$EGD_SOCKET" ; then + AC_DEFINE_UNQUOTED(EGD_SOCKET, "$EGD_SOCKET") + fi + dnl Check for user-specified random device AC_ARG_WITH(random, [ --with-random=FILE read randomness from FILE (default=/dev/urandom)], ! [ RANDOM_OPT="-rand $withval"; RANDOM_FILE="$withval" ], [ dnl Check for random device AC_CHECK_FILE("/dev/urandom", *************** *** 26,31 **** --- 34,42 ---- ) ] ) + if test -n "$RANDOM_FILE" ; then + AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE") + fi checkssldir() { : if test -d "$1/certs"; then diff -cr stunnel-3.8/ssl.c stunnel-3.8p1/ssl.c *** stunnel-3.8/ssl.c Fri Feb 18 07:26:48 2000 --- stunnel-3.8p1/ssl.c Sun Jun 11 23:12:07 2000 *************** *** 52,57 **** --- 52,58 ---- #include #include #include + #include #else #include #include *************** *** 119,124 **** --- 120,128 ---- void context_init(); void context_free(); void client(int); + int prng_seeded(int); + int add_rand_file(char *); + void initialize_prng(); static int transfer(SSL *, int); #ifndef NO_RSA static RSA *tmp_rsa_cb(SSL *, int, int); *************** *** 147,152 **** --- 151,284 ---- /* const allowed here */ #endif + + /* shortcut to determine if sufficient entropy for PRNG is present */ + int prng_seeded( int bytes ) { + + #if SSLEAY_VERSION_NUMBER >= 0x0090581fL + if ( RAND_status() ) { + log(LOG_DEBUG, "RAND_status claims sufficient entropy for the PRNG"); + return(1); + } + #else + if ( bytes >= options.random_bytes ) { + log(LOG_INFO, "Sufficient entropy in PRNG assumed (>= %d)", options.random_bytes); + return(1); + } + #endif + + return(0); /* assume we don't have enough */ + } + + int add_rand_file( char *filename ) { + int readbytes; + int writebytes; + struct stat sb; + + if ( stat(filename, &sb) !=0 ) { return(0); } + + if ( (readbytes = RAND_load_file(filename, options.random_bytes )) ) { + log(LOG_DEBUG, "Snagged %d random bytes from %s", readbytes, filename); + } else { + log(LOG_INFO, "Unable to retrieve any random data from %s", filename); + } + + /* Write new random data for future seeding if it's a regular file */ + if ( options.rand_write && (sb.st_mode & S_IFREG) ) { + writebytes = RAND_write_file(filename); + if ( -1 == writebytes ) { + log(LOG_WARNING, "Failed to write strong random data to %s. May " + "be a permissions or seeding problem", filename); + } else { + log(LOG_DEBUG, "Wrote %d new random bytes to %s", writebytes, filename); + } + } + return(readbytes); + } + + + + void initialize_prng( void ) { + int totbytes=0; + char filename[STRLEN]; + #if SSLEAY_VERSION_NUMBER >= 0x0090581fL + int bytes=0; + #endif + + /* If they specify a rand file on the command line we + assume that they really do want it, so try it first */ + if ( options.rand_file ) { + totbytes += add_rand_file(options.rand_file); + if ( prng_seeded(totbytes) ) { goto SEEDED; } + } + /* Yes. goto. Deal with it. */ + + /* try the $RANDFILE or $HOME/.rnd files */ + if ( RAND_file_name(filename, STRLEN) ) { + filename[STRLEN-1]='\0'; + totbytes += add_rand_file(filename); + if ( prng_seeded(totbytes) ) { goto SEEDED; } + } + + #ifdef RANDOM_FILE + totbytes += add_rand_file( RANDOM_FILE ); + if ( prng_seeded(totbytes) ) { goto SEEDED; } + #endif + + #ifdef USE_WIN32 + RAND_screen(); + if ( prng_seeded(totbytes) ) { + log(LOG_DEBUG, "Seeded PRNG with RAND_screen"); + goto SEEDED; + } else { + log(LOG_DEBUG, "RAND_screen failed to sufficiently seed PRNG"); + } + #else + + #if SSLEAY_VERSION_NUMBER >= 0x0090581fL + if ( options.egd_sock ) { + if ( (bytes=RAND_egd(options.egd_sock)) == -1 ) { + log(LOG_WARNING, "EGD Socket %s failed", options.egd_sock); + bytes=0; + } else { + totbytes += bytes; + log(LOG_DEBUG, "Snagged %d random bytes from EGD Socket %s", + bytes, options.egd_sock); + goto SEEDED; /* openssl always gets what it needs or fails, + so no need to check if seeded sufficiently */ + } + } + #ifdef EGD_SOCKET + if ( (bytes=RAND_egd( EGD_SOCKET )) == -1 ) { + log(LOG_WARNING, "EGD Socket %s failed", EGD_SOCKET); + } else { + totbytes += bytes; + log(LOG_DEBUG, "Snagged %d random bytes from EGD Socket %s", + bytes, EGD_SOCKET); + goto SEEDED; /* ditto */ + } + #endif /* EGD_SOCKET */ + + #endif /* OpenSSL-0.9.5a */ + #endif /* USE_WIN32 */ + + + /* Try the good-old default /dev/urandom, if available */ + totbytes += add_rand_file( "/dev/urandom" ); + if ( prng_seeded(totbytes) ) { goto SEEDED; } + + /* Random file specified during configure */ + + log(LOG_INFO, "PRNG seeded with %d bytes total", totbytes); + log(LOG_WARNING, "PRNG may not have been seeded with enough random bytes"); + return; + + SEEDED: + log(LOG_INFO, "PRNG seeded successfully"); + return; + + } + void context_init() /* init SSL */ { #ifndef NO_DH *************** *** 154,159 **** --- 286,293 ---- BIO *bio=NULL; #endif /* NO_DH */ + initialize_prng(); + SSLeay_add_ssl_algorithms(); SSL_load_error_strings(); if(options.option&OPT_CLIENT) { *************** *** 202,207 **** --- 336,342 ---- DH_free(dh); #endif /* NO_DH */ } + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); SSL_CTX_set_timeout(ctx, options.session_timeout); if(options.option&OPT_CERT) { *************** *** 228,240 **** } if(options.verify_level!=SSL_VERIFY_NONE) { if ((!SSL_CTX_set_default_verify_paths(ctx)) ! || (!SSL_CTX_load_verify_locations(ctx, CLIENT_CA, options.clientdir))){ sslerror("X509_load_verify_locations"); exit(1); } SSL_CTX_set_verify(ctx, options.verify_level, verify_callback); ! SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CLIENT_CA)); if (options.verify_use_only_my) log(LOG_NOTICE, "Peer certificate location %s", options.clientdir); } --- 363,375 ---- } if(options.verify_level!=SSL_VERIFY_NONE) { if ((!SSL_CTX_set_default_verify_paths(ctx)) ! || (!SSL_CTX_load_verify_locations(ctx, options.cacert, options.clientdir))){ sslerror("X509_load_verify_locations"); exit(1); } SSL_CTX_set_verify(ctx, options.verify_level, verify_callback); ! SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(options.cacert)); if (options.verify_use_only_my) log(LOG_NOTICE, "Peer certificate location %s", options.clientdir); } *************** *** 322,327 **** --- 457,466 ---- SSL_set_session_id_context(ssl, sid_ctx, strlen(sid_ctx)); #endif if(options.option&OPT_CLIENT) { + /* Attempt to use the most recent id in the session cache */ + if ( ctx->session_cache_head ) + if ( ! SSL_set_session(ssl, ctx->session_cache_head) ) + log(LOG_WARNING, "Cannot set SSL session id to most recent used"); SSL_set_fd(ssl, remote); SSL_set_connect_state(ssl); if(SSL_connect(ssl)<=0) { diff -cr stunnel-3.8/stunnel.8.in stunnel-3.8p1/stunnel.8.in *** stunnel-3.8/stunnel.8.in Tue Feb 15 09:13:15 2000 --- stunnel-3.8p1/stunnel.8.in Sun Jun 11 23:12:07 2000 *************** *** 1,16 **** ! .TH STUNNEL 8 "10 June 1999" .SH NAME stunnel \- universal SSL tunnel .SH SYNOPSIS .B stunnel ! [-T] [-p pemfile] [-v level] [-a directory] ! [-t timeout] [-u username] [-n protocol] ! [-d [ip:]port [-f]] [ -l program | -r [ip:]port | -L program [-- args] ] .PP - .B stunnel - {-c} [-p pemfile] [-v level] [-a directory] - [-t timeout] [-u username] [-n protocol] - -r [ip:]port [ -d [ip:]port [-f] | -l program | -L program [-- args] ] .SH DESCRIPTION The \fBstunnel\fR program is designed to work as \fISSL\fR encryption wrapper between remote clients and local (\fIinetd\fR-startable) or remote --- 1,28 ---- ! .TH STUNNEL 8 "11 June 2000" .SH NAME stunnel \- universal SSL tunnel .SH SYNOPSIS .B stunnel ! [-c | -T] ! [-D level] ! [-C cipherlist] ! [-p pemfile] ! [-v level] ! [-A certfile] ! [-a directory] ! [-t timeout] ! [-u ident_username] ! [-s setuid_user] ! [-g setgid_group] ! [-n protocol] ! [-P { dir/ | filename | none } ] ! [-B bytes] ! [-R randfile] ! [-W] ! [-E socket] ! [-d [host:]port [-f] ] ! [ -r [host:]port | { -l | -L } program [-- progname args] ] .PP .SH DESCRIPTION The \fBstunnel\fR program is designed to work as \fISSL\fR encryption wrapper between remote clients and local (\fIinetd\fR-startable) or remote *************** *** 27,32 **** --- 39,64 ---- This product includes cryptographic software written by Eric Young (eay@cryptsoft.com) .SH OPTIONS + .B -h + Print stunnel help menu + .PP + .B -V + Print stunnel version and compile options + .PP + .B -D level + Debugging level + .RS + Level is a number between 0 (no logging at all) and 7 (show + lots of debugging info) + .RE + .PP + .B -C cipherlist + Select permitted SSL ciphers + .RS + A colon delimited list of the ciphers to allow in the SSL connection. + For example DES-CBC3-SHA:IDEA-CBC-MD5 + .RE + .PP .B -c client mode (remote service uses SSL) .RS *************** *** 34,40 **** .RE .PP .B -T ! transparent proxy mode (on hosts that support it) .PP .B -p pemfile certificate (*.pem) file name --- 66,77 ---- .RE .PP .B -T ! transparent proxy mode ! .RS ! Available only in server mode, re-write address to appear ! as if connection is originating from actual SSL client machine. ! Only available on some OS versions. ! .RE .PP .B -p pemfile certificate (*.pem) file name *************** *** 46,55 **** .B -v level verify peer certificate .RS ! level 1 - verify peer certificate if present level 2 - verify peer certificate ! level 3 - verify peer with locally installed certificate default: no verify .RE .PP .B -a directory --- 83,96 ---- .B -v level verify peer certificate .RS ! .nf ! level 1 - verify peer certificate ! if present level 2 - verify peer certificate ! level 3 - verify peer with locally ! installed certificate default: no verify + .fi .RE .PP .B -a directory *************** *** 58,70 **** default: @ssldir@/certs/trusted .RE .PP .B -t timeout session cache timeout .RS default: 300 s. .RE .PP ! .B -u user Use IDENT (RFC 1413) username checking .PP .B -n proto --- 99,122 ---- default: @ssldir@/certs/trusted .RE .PP + .B -A certfile + Certificate Authority file + .RS + .br + default: + .br + @ssldir@/cert.pem and/or + .br + @ssldir@/localCA/cacert.pem + .RE + .PP .B -t timeout session cache timeout .RS default: 300 s. .RE .PP ! .B -u ident_username Use IDENT (RFC 1413) username checking .PP .B -n proto *************** *** 73,98 **** currenty supported: smtp .RE .PP ! .B -d [ip:]port ! daemon mode (ip defaults to INADDR_ANY) .RS default: inetd mode .RE .PP .B -f ! foreground mode (don't fork, log to stderr) .RS default: background in daemon mode .RE .PP ! .B -l program [-- args] .RS ! execute local inetd-type program .RE .PP ! .B -L program [-- args] .RS ! open local pty and execute program .RE .PP .B -s username --- 125,182 ---- currenty supported: smtp .RE .PP ! .PP ! .B -E socket ! .RS ! Entropy Gathering Daemon socket to use to feed OpenSSL random number ! generator. (Available only if compiled with OpenSSL 0.9.5a or higher) ! .RE ! .PP ! .B -R filename ! .RS ! File containing random input. The SSL library ! will use data from this file first to seed the ! random number generator. ! .RE ! .PP ! .B -W ! Do not overwrite the random seed files with new random data. ! .RE ! .PP ! .B -B bytes .RS + Number of bytes of data read from random seed files. With SSL versions + less than 0.9.5a, also determines how many bytes of data are considered + sufficient to seed the PRNG. More recent OpenSSL versions have a builtin + function to determine when sufficient randomness is available. + .RE + .PP + .B -d [host:]port + daemon mode + .RS + Listen for connections on [host:]port. + If no host specified, defaults to all IP addresses for the local host. + .br default: inetd mode .RE .PP .B -f ! foreground mode .RS + Stay in foreground (don't fork) and log to stderr + instead of via syslog. + .br default: background in daemon mode .RE .PP ! .B -l program [-- programname [arg1 arg2 arg3...] ] .RS ! execute local inetd-type program. .RE .PP ! .B -L program [-- programname [arg1 arg2 arg3...] ] .RS ! open local pty and execute program. .RE .PP .B -s username *************** *** 105,114 **** setgid() to groupname in daemon mode. Clears all other groups. .RE .PP ! .B -r [ip:]port connect to remote service .RS ! (ip defaults to INADDR_LOOPBACK) .RE .SH EXAMPLES --- 189,209 ---- setgid() to groupname in daemon mode. Clears all other groups. .RE .PP ! .B -P { dir/ | file | none } ! Pid file location ! .RS ! If the argument is a pathname ending in a slash, then a pid file ! named "\fIstunnel.\fRservicename\fI.pid\fR" will be created in ! the specified directory. If the argument is a filename (no ! trailing slash), then that filename will be used for the pid. ! If ! the argument is 'none', then no pid file will be created. ! .RE ! .PP ! .B -r [host:]port connect to remote service .RS ! If no host specified, defaults to localhost. .RE .SH EXAMPLES *************** *** 160,165 **** --- 255,301 ---- [empty line] .fi .sp + .SH RANDOMNESS + \fIstunnel\fR needs to seed the PRNG (pseudo random number generator) in + order for SSL to use good randomness. The following sources are loaded + in order until sufficient random data has been gathered: + .sp + .RS + .nf + The file specified with the \fI-R\fR flag. + The file specified by the RANDFILE environment variable, if set. + The file .rnd in your home directory, iff RANDFILE not set. + The file specified with '--with-random' at compile time. + The contents of the screen if running on Windows. + The egd socket specified with the \fI-E\fR flag. + The egd socket specified with '--with-egd-sock' at compile time. + The /dev/urandom device. + .fi + .sp + .RE + With recent (>=OpenSSL 0.9.5a) version of SSL it will stop loading + random data automatically when sufficient entropy has been gathered. + With previous versions it will continue to gather from all the above + sources since no SSL function exists to tell when enough data is available. + .PP + Note that on Windows machines that do not have console user interaction + (mouse movements, creating windows, etc) the screen contents are not + variable enough to be sufficient, and you should provide a random file + for use with the \fI-R\fR flag. + .PP + Note that the file specified with the \fI-R\fR flag should contain + random data -- that means it should contain different information + each time \fIstunnel\fR is run. This is handled automatically + unless the \fI-W\fR flag is used. If you wish to update this file + manually, the \fIopenssl rand\fR command in recent versions of OpenSSL, + would be useful. + .PP + One important note -- if /dev/urandom is available, OpenSSL has a habit of + seeding the PRNG with it even when checking the random state, so on + systems with /dev/urandom you're likely to use it even though it's listed + at the very bottom of the list above. This isn't stunnel's behaviour, it's + OpenSSLs. + .PP .SH LIMITATIONS \fIstunnel\fR cannot be used for the FTP daemon because of the nature of the FTP protocol which utilizes multiple ports for data transfers. diff -cr stunnel-3.8/stunnel.c stunnel-3.8p1/stunnel.c *** stunnel-3.8/stunnel.c Thu Feb 24 03:32:27 2000 --- stunnel-3.8p1/stunnel.c Sun Jun 11 23:12:07 2000 *************** *** 36,41 **** --- 36,48 ---- /* Must be included before sys/stat.h for Ultrix */ #include /* u_short, u_long */ + /* Needed so we know which version of OpenSSL we're using */ + #ifdef HAVE_OPENSSL + #include + #else + #include + #endif + /* General headers */ #include #include /* errno */ *************** *** 49,54 **** --- 56,62 ---- #define Win32_Winsock #include + static struct WSAData wsa_state; #else /* defined USE_WIN32 */ *************** *** 148,153 **** --- 156,162 ---- options.foreground=1; safecopy(options.certfile, DEFAULT_CERT); safecopy(options.clientdir, CA_DIR); + safecopy(options.cacert, CLIENT_CA); get_options(argc, argv); if(!(options.option&OPT_FOREGROUND)) { options.foreground=0; *************** *** 205,210 **** --- 214,220 ---- extern int optind, opterr, optopt; char *tmpstr; static char *default_args[2]; + char *servname_selected=NULL; options.option=0; options.verify_level=0x00; /* SSL_VERIFY_NONE */ *************** *** 216,224 **** options.protocol=NULL; options.setuid_user=NULL; options.setgid_group=NULL; opterr=0; ! while ((c = getopt(argc, argv, "a:cp:v:d:fTl:L:r:s:g:t:u:n:hC:D:V")) != EOF) switch (c) { case 'a': safecopy(options.clientdir, optarg); break; --- 226,242 ---- options.protocol=NULL; options.setuid_user=NULL; options.setgid_group=NULL; + options.pid_dir=PIDDIR; + options.egd_sock=NULL; + options.rand_file=NULL; + options.rand_write=1; + options.random_bytes=RANDOM_BYTES; opterr=0; ! while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:hC:D:E:R:WB:VP:")) != EOF) switch (c) { + case 'A': + safecopy(options.cacert,optarg); + break; case 'a': safecopy(options.clientdir, optarg); break; *************** *** 264,269 **** --- 282,304 ---- case 'T': options.option|=OPT_TRANSPARENT; break; + case 'R': + options.rand_file=optarg; + break; + case 'W': + options.rand_write=0; + break; + case 'B': + options.random_bytes=atoi(optarg); + break; + case 'E': + #if SSLEAY_VERSION_NUMBER >= 0x0090581fL + options.egd_sock=optarg; + #else + log(LOG_ERR, "-E is only supported when compiled with OpenSSL 0.9.5a or later"); + /* exit(1) ??? */ + #endif + break; case 'L': options.option |= OPT_PTY; case 'l': *************** *** 308,313 **** --- 343,351 ---- case 'n': options.protocol=optarg; break; + case 'N': + servname_selected=optarg; + break; case 'C': options.cipher_list=optarg; break; *************** *** 321,326 **** --- 359,367 ---- case 'V': fprintf(stderr, "\n" STUNNEL_INFO "\n\n"); exit(0); + case 'P': + options.pid_dir=optarg; + break; case '?': log(LOG_ERR, "Illegal option: '%c'", optopt); case 'h': *************** *** 364,370 **** options.execargs = argv + optind; safecopy(options.servname, options.execargs[0]); } ! log(LOG_DEBUG, "Service name to be used: %s", options.servname); } static void daemon_loop() --- 405,414 ---- options.execargs = argv + optind; safecopy(options.servname, options.execargs[0]); } ! if ( servname_selected ) { ! safecopy(options.servname, servname_selected); ! } ! log(LOG_NOTICE, "Using '%s' as tcpwrapper service name", options.servname); } static void daemon_loop() *************** *** 432,461 **** static void create_pid() { ! FILE *pf; ! int oldumask; options.dpid=(unsigned long)getpid(); ! #ifdef HAVE_SNPRINTF ! snprintf(options.pidfile, STRLEN, #else ! sprintf(options.pidfile, #endif ! "%s/stunnel.%s.pid", piddir, options.servname); ! oldumask=umask(022); ! pf=fopen(options.pidfile, "w"); ! umask(oldumask); ! if(!pf) { ! ioerror(options.pidfile); ! return; /* not critical */ } ! fprintf(pf, "%lu", options.dpid); ! fclose(pf); atexit(delete_pid); } static void delete_pid() { if((unsigned long)getpid()!=options.dpid) return; /* Current process is not main deamon process */ if(unlink(options.pidfile)<0) --- 476,530 ---- static void create_pid() { ! int pf; ! char pid[STRLEN]; + if ( strcmp(options.pid_dir, "none") == 0 ) { + log(LOG_DEBUG, "No pid file being created."); + options.pidfile[0]='\0'; + return; + } + if ( ! strchr(options.pid_dir, '/') ) { + log(LOG_ERR, "Argument to -P (%s) must be full path name.", + options.pid_dir); + /* Why? Because we don't want to confuse by + allowing '.', which would be '/' after + daemonizing) */ + exit(1); + } options.dpid=(unsigned long)getpid(); ! ! /* determine if they specified a pid dir or pid file, ! and set our options.pidfile appropriately */ ! if ( options.pid_dir[ strlen(options.pid_dir)-1 ] == '/' ) { ! #ifdef HAVE_SNPRINTF ! snprintf(options.pidfile, STRLEN, ! "%sstunnel.%s.pid", options.pid_dir, options.servname); #else ! safecopy(options.pidfile, options.pid_dir); ! safeconcat(options.pidfile, "stunnel."); ! safeconcat(options.pidfile, options.servname); ! safeconcat(options.pidfile, ".pid"); #endif ! } else { ! safecopy(options.pidfile, options.pid_dir); } ! ! if (-1==(pf=open(options.pidfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0644))) { ! log(LOG_ERR, "Cannot create pid file %s", options.pidfile); ! ioerror("Create"); ! exit(1); ! } ! sprintf(pid, "%lu", options.dpid); ! write( pf, pid, strlen(pid) ); ! close(pf); ! log(LOG_DEBUG, "Created pid file %s", options.pidfile); atexit(delete_pid); } static void delete_pid() { + log(LOG_DEBUG, "removing pid file %s", options.pidfile); if((unsigned long)getpid()!=options.dpid) return; /* Current process is not main deamon process */ if(unlink(options.pidfile)<0) *************** *** 522,527 **** --- 591,602 ---- options.setuid_user); exit(1); } + #ifndef USE_WIN32 + /* gotta chown that pid file, or we can't remove it. */ + if ( options.pidfile[0] && chown( options.pidfile, pw->pw_uid, -1) ) { + log(LOG_ERR, "Failed to chown pidfile %s", options.pidfile); + } + #endif if(setuid(pw->pw_uid)) { sockerror("setuid"); exit(1); *************** *** 873,897 **** static void print_help() { fprintf(stderr, ! "\nstunnel [-T] [-p pemfile] [-v level] [-a directory]" ! "\n\t[-t timeout] [-u username] [-n protocol]" ! #ifndef USE_WIN32 ! "\n\t[-d [ip:]port [-f]]" ! "\n\t[ -l program | -r [ip:]port | -L program [-- args] ]" #else ! "\n\t-d [ip:]port -r [ip:]port" #endif ! "\nstunnel {-c} [-p pemfile] [-v level] [-a directory]" ! "\n\t[-t timeout] [-u username] [-n protocol]" #ifndef USE_WIN32 ! "\n\t-r [ip:]port" ! "\n\t[ -d [ip:]port [-f] | -l program | -L program [-- args] ]" #else ! "\n\t-r [ip:]port -d [ip:]port" #endif ! "\n\n -c\t\tclient mode (remote service uses SSL)" "\n\t\tdefault: server mode" ! "\n -T\t\ttransparent proxy mode (on hosts that support it)" "\n -p pemfile\tcertificate (*.pem) file name" "\n\t\tdefault: " DEFAULT_CERT " for server mode," "\n\t\t\t none for client mode" --- 948,1004 ---- static void print_help() { fprintf(stderr, ! /* Server execution */ ! "\nstunnel\t" ! "[-h] " ! "[-c | -T] " ! "[-D level] " ! "[-C cipherlist] " ! "[-p pemfile] " ! "\n\t" ! "[-v level] " ! "[-A certfile] " ! "[-a directory] " ! "[-t timeout] " ! "\n\t" ! "[-u ident_username] " ! "[-s setuid_user] " ! "[-g setgid_group] " ! "[-n protocol]" ! "\n\t" ! "[-P { dir/ | filename | none } ] " ! "[-R randfile] " ! "[-R randfile] " ! #if SSLEAY_VERSION_NUMBER >= 0x0090581fL ! "[-E egdsock] " #else ! "[-B bytes] " #endif ! #ifndef USE_WIN32 ! "\n\t[-d [host:]port [-f] ] " ! "\n\t[-r [host:]port | { -l | -L } program [-- args] ] " #else ! "\n\t-d [host:]port -r [host:]port" #endif ! ! ! /* Argument notes */ ! ! "\n\n" ! "\n -d [host:]port\tdaemon mode (host defaults to INADDR_ANY)" ! "\n\t\t\tdefault: inetd mode" ! "\n -r [host:]port\tconnect to remote service (host defaults to INADDR_LOOPBACK)" ! #ifndef USE_WIN32 ! "\n -l program\t\texecute local inetd-type program" ! "\n -L program\t\topen local pty and execute program" ! #endif ! "\n" ! "\n -c\t\tclient mode (remote service uses SSL)" "\n\t\tdefault: server mode" ! "\n -f\t\tforeground mode (don't fork, log to stderr)" ! "\n\t\tdefault: background in daemon mode" ! "\n -T\t\ttransparent proxy mode on hosts that support it." "\n -p pemfile\tcertificate (*.pem) file name" "\n\t\tdefault: " DEFAULT_CERT " for server mode," "\n\t\t\t none for client mode" *************** *** 902,927 **** "\n\t\tdefault: no verify" "\n -a directory\tclient certificate directory for -v 3 option" "\n\t\tdefault: " CA_DIR "\n -t timeout\tsession cache timeout" "\n\t\tdefault: 300 s." "\n -u user\tUse IDENT (RFC 1413) username checking" "\n -n proto\tNegotiate SSL with specified protocol" "\n\t\tcurrenty supported: smtp" ! "\n -d [ip:]port\tdaemon mode (ip defaults to INADDR_ANY)" #ifndef USE_WIN32 - "\n\t\tdefault: inetd mode" - "\n -f\t\tforeground mode (don't fork, log to stderr)" - "\n\t\tdefault: background in daemon mode" - "\n -l program\texecute local inetd-type program" - "\n -L program\topen local pty and execute program" "\n -s username\tsetuid() to username in daemon mode" "\n -g groupname\tsetgid() to groupname in daemon mode" #endif - "\n -r [ip:]port\tconnect to remote service" - " (ip defaults to INADDR_LOOPBACK)" - "\n -h\t\tprint this help screen" "\n -C list\tset permitted SSL ciphers" "\n -D level\tdebug level (0-7) default: 5" "\n -V\t\tprint stunnel version\n"); exit(1); } --- 1009,1046 ---- "\n\t\tdefault: no verify" "\n -a directory\tclient certificate directory for -v 3 option" "\n\t\tdefault: " CA_DIR + "\n -A certfile\tCA certificate for -v2 and -v3 options" + "\n\t\tdefault: " CLIENT_CA "\n -t timeout\tsession cache timeout" "\n\t\tdefault: 300 s." "\n -u user\tUse IDENT (RFC 1413) username checking" "\n -n proto\tNegotiate SSL with specified protocol" "\n\t\tcurrenty supported: smtp" ! "\n -N name\tService name to use for tcp wrapper checking" #ifndef USE_WIN32 "\n -s username\tsetuid() to username in daemon mode" "\n -g groupname\tsetgid() to groupname in daemon mode" + "\n -P arg\tSpecify pid file. { dir/ | filename | none }" #endif "\n -C list\tset permitted SSL ciphers" + #if SSLEAY_VERSION_NUMBER >= 0x0090581fL + "\n -E socket\tpath to Entropy Gathering Daemon socket" + "\n -B bytes\thow many bytes to read from random seed files" + #ifdef EGD_SOCKET + "\n\t\t" EGD_SOCKET " is used when this option is not specified." + #endif + #else + "\n -B bytes\thow many bytes of random data are considered 'sufficient' for PRNG" + "\n\t\tand maximum number of bytes to read from random seed files." + #endif + "\n\t\tdefault: " RANDOM_BYTES_STRING + "\n -R file\tpath to file with random seed data" + #ifdef RANDOM_FILE + "\n\t\t" RANDOM_FILE " is used when this option is not specified." + #endif + "\n -W\t\tDo not overwrite random seed datafiles with new random data" "\n -D level\tdebug level (0-7) default: 5" + "\n -h\t\tprint this help screen" "\n -V\t\tprint stunnel version\n"); exit(1); } diff -cr stunnel-3.8/stunnel.html stunnel-3.8p1/stunnel.html *** stunnel-3.8/stunnel.html Tue Feb 15 09:13:15 2000 --- stunnel-3.8p1/stunnel.html Sun Jun 11 23:12:07 2000 *************** *** 6,19 **** stunnel - universal SSL tunnel

SYNOPSIS

stunnel ! [-T] [-p pemfile] [-v level] [-a directory] ! [-t timeout] [-u username] [-n protocol] ! [-d [ip:]port [-f]] [ -l program | -r [ip:]port | -L program [-- args] ]

- stunnel - {-c} [-p pemfile] [-v level] [-a directory] - [-t timeout] [-u username] [-n protocol] - -r [ip:]port [ -d [ip:]port [-f] | -l program | -L program [-- args] ]

DESCRIPTION

The stunnel program is designed to work as SSL encryption wrapper between remote clients and local (inetd-startable) or remote --- 6,31 ---- stunnel - universal SSL tunnel

SYNOPSIS

stunnel ! [-c | -T] ! [-D level] ! [-C cipherlist] ! [-p pemfile] ! [-v level] ! [-A certfile] ! [-a directory] ! [-t timeout] ! [-u ident_username] ! [-s setuid_user] ! [-g setgid_group] ! [-n protocol] ! [-P { dir/ | filename | none } ] ! [-B bytes] ! [-R randfile] ! [-W] ! [-E socket] ! [-d [host:]port [-f] ] ! [ -r [host:]port | { -l | -L } program [-- progname args] ]

DESCRIPTION

The stunnel program is designed to work as SSL encryption wrapper between remote clients and local (inetd-startable) or remote *************** *** 30,35 **** --- 42,67 ---- This product includes cryptographic software written by Eric Young (eay@cryptsoft.com)

OPTIONS

+ -h + Print stunnel help menu +

+ -V + Print stunnel version and compile options +

+ -D level + Debugging level +

+ Level is a number between 0 (no logging at all) and 7 (show + lots of debugging info) +
+

+ -C cipherlist + Select permitted SSL ciphers +

+ A colon delimited list of the ciphers to allow in the SSL connection. + For example DES-CBC3-SHA:IDEA-CBC-MD5 +
+

-c client mode (remote service uses SSL)

*************** *** 37,43 ****

-T ! transparent proxy mode (on hosts that support it)

-p pemfile certificate (*.pem) file name --- 69,80 ----

-T ! transparent proxy mode !

! Available only in server mode, re-write address to appear ! as if connection is originating from actual SSL client machine. ! Only available on some OS versions. !

-p pemfile certificate (*.pem) file name *************** *** 49,58 **** -v level verify peer certificate

! level 1 - verify peer certificate if present level 2 - verify peer certificate ! level 3 - verify peer with locally installed certificate ! default: no verify

-a directory --- 86,97 ---- -v level verify peer certificate

!
level 1 - verify peer certificate
!           if present
  level 2 - verify peer certificate
! level 3 - verify peer with locally
!           installed certificate
! default: no verify

-a directory *************** *** 61,73 **** default: /usr/local/ssl/certs/trusted

-t timeout session cache timeout

default: 300 s.

! -u user Use IDENT (RFC 1413) username checking

-n proto --- 100,123 ---- default: /usr/local/ssl/certs/trusted

+ -A certfile + Certificate Authority file +

+

+ default: +

+ /usr/local/ssl/cert.pem and/or +

+ /usr/local/ssl/localCA/cacert.pem +

+

-t timeout session cache timeout

default: 300 s.

! -u ident_username Use IDENT (RFC 1413) username checking

-n proto *************** *** 76,101 **** currenty supported: smtp

! -d [ip:]port ! daemon mode (ip defaults to INADDR_ANY)

default: inetd mode

-f ! foreground mode (don't fork, log to stderr)

default: background in daemon mode

! -l program [-- args]

! execute local inetd-type program

! -L program [-- args]

! open local pty and execute program

-s username --- 126,183 ---- currenty supported: smtp

!

! -E socket !

! Entropy Gathering Daemon socket to use to feed OpenSSL random number ! generator. (Available only if compiled with OpenSSL 0.9.5a or higher) !
!

! -R filename !

! File containing random input. The SSL library ! will use data from this file first to seed the ! random number generator. !
!

! -W ! Do not overwrite the random seed files with new random data. ! !

! -B bytes

+ Number of bytes of data read from random seed files. With SSL versions + less than 0.9.5a, also determines how many bytes of data are considered + sufficient to seed the PRNG. More recent OpenSSL versions have a builtin + function to determine when sufficient randomness is available. +
+

+ -d [host:]port + daemon mode +

+ Listen for connections on [host:]port. + If no host specified, defaults to all IP addresses for the local host. +

default: inetd mode

-f ! foreground mode

+ Stay in foreground (don't fork) and log to stderr + instead of via syslog. +

default: background in daemon mode

! -l program [-- programname [arg1 arg2 arg3...] ]

! execute local inetd-type program.

! -L program [-- programname [arg1 arg2 arg3...] ]

! open local pty and execute program.

-s username *************** *** 106,116 **** -g groupname

setgid() to groupname in daemon mode. Clears all other groups.

! -r [ip:]port connect to remote service

! (ip defaults to INADDR_LOOPBACK)

EXAMPLES

--- 188,210 ---- -g groupname
setgid() to groupname in daemon mode. Clears all other groups. +
+

+ -P { dir/ | file | none } + Pid file location +

+ If the argument is a pathname ending in a slash, then a pid file + named "stunnel.servicename.pid" will be created in + the specified directory. If the argument is a filename (no + trailing slash), then that filename will be used for the pid. + If + the argument is 'none', then no pid file will be created. +

! -r [host:]port connect to remote service

! If no host specified, defaults to localhost.

EXAMPLES

*************** *** 156,161 **** --- 250,294 ---- -----END CERTIFICATE----- [empty line] +

RANDOMNESS

+ stunnel needs to seed the PRNG (pseudo random number generator) in + order for SSL to use good randomness. The following sources are loaded + in order until sufficient random data has been gathered: + +
+
The file specified with the -R flag.
+ The file specified by the RANDFILE environment variable, if set.
+ The file .rnd in your home directory, iff RANDFILE not set.
+ The file specified with '--with-random' at compile time.
+ The contents of the screen if running on Windows.
+ The egd socket specified with the -E flag.
+ The egd socket specified with '--with-egd-sock' at compile time.
+ The /dev/urandom device.
+ +
+ With recent (>=OpenSSL 0.9.5a) version of SSL it will stop loading + random data automatically when sufficient entropy has been gathered. + With previous versions it will continue to gather from all the above + sources since no SSL function exists to tell when enough data is available. +

+ Note that on Windows machines that do not have console user interaction + (mouse movements, creating windows, etc) the screen contents are not + variable enough to be sufficient, and you should provide a random file + for use with the -R flag. +

+ Note that the file specified with the -R flag should contain + random data -- that means it should contain different information + each time stunnel is run. This is handled automatically + unless the -W flag is used. If you wish to update this file + manually, the openssl rand command in recent versions of OpenSSL, + would be useful. +

+ One important note -- if /dev/urandom is available, OpenSSL has a habit of + seeding the PRNG with it even when checking the random state, so on + systems with /dev/urandom you're likely to use it even though it's listed + at the very bottom of the list above. This isn't stunnel's behaviour, it's + OpenSSLs. +

LIMITATIONS

stunnel cannot be used for the FTP daemon because of the nature of the FTP protocol which utilizes multiple ports for data transfers.