Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 3323 Details for
Bug 6898
proftpd-1.2.6_rc1-r1.ebuild (Update)
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
TLS/SSL Patch
proftpd-1.2.6rc1-tls-20020711.patch (text/plain), 145.30 KB, created by
Stian B. Barmen
on 2002-08-22 17:48:00 UTC
(
hide
)
Description:
TLS/SSL Patch
Filename:
MIME Type:
Creator:
Stian B. Barmen
Created:
2002-08-22 17:48:00 UTC
Size:
145.30 KB
patch
obsolete
>diff -urN proftpd-1.2.6rc1.orig/Make.rules.in proftpd-1.2.6rc1-tls/Make.rules.in >--- proftpd-1.2.6rc1.orig/Make.rules.in Tue Jun 11 18:18:05 2002 >+++ proftpd-1.2.6rc1-tls/Make.rules.in Wed Jul 3 10:54:31 2002 >@@ -58,10 +58,10 @@ > #CFLAGS=-g -pedantic -DUSESHADOW -DDEBUG_NOFORK > > OBJS=main.o timers.o sets.o pool.o dirtree.o support.o inet.o log.o \ >- io.o ident.o data.o modules.o auth.o fs.o >+ io.o ident.o data.o modules.o auth.o fs.o @TLS_OBJS@ > BUILD_OBJS=src/main.o src/timers.o src/sets.o src/pool.o src/dirtree.o \ > src/support.o src/inet.o src/log.o src/io.o src/ident.o \ >- src/data.o src/modules.o src/auth.o src/fs.o >+ src/data.o src/modules.o src/auth.o src/fs.o @TLS_BUILD_OBJS@ > > LIB_OBJS=getopt.o getopt1.o pr_fnmatch.o strsep.o vsnprintf.o glibc-glob.o \ > glibc-mkstemp.o pwgrent.o >diff -urN proftpd-1.2.6rc1.orig/README.TLS proftpd-1.2.6rc1-tls/README.TLS >--- proftpd-1.2.6rc1.orig/README.TLS Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/README.TLS Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,147 @@ >+TLS patch for proftpd-1.2.5 together with OpenSSL >= 0.9.4, based on the >+"draft-murray-auth-ftp-ssl-09.txt" IETF draft. >+Copyright (c) 2000 Peter 'Luna' Runestig <peter@runestig.com> >+The verify_crl() function by Ralf S. Engelschall <rse@engelschall.com> >+This product includes software developed by the OpenSSL Project >+for use in the OpenSSL Toolkit. (http://www.openssl.org/) >+This product includes cryptographic software written by >+Eric Young (eay@cryptsoft.com) >+ >+Patching: >+ $ tar xzf proftpd-1.2.5.tar.gz >+ $ cd proftpd-1.2.5 >+ $ patch -p1 < ../proftpd-tls.current.patch >+ >+ Or just use the prepatched tarball. >+ >+Configuring: >+ $ ./configure [--with-openssl-dir=DIR] >+ >+Building: >+ $ make >+ >+Installation: >+ $ make install >+ >+By default, proftpd looks for a single configuration file at >+/usr/local/etc/proftpd.conf. Copy sample-configurations/basic.conf to >+/usr/local/etc/proftpd.conf and modify to suit your needs. More advanced >+configuration examples are also included. >+ >+The proftpd server tries to use these TLS related files by default: >+ftpd-rsa.pem RSA certificate, may include private key >+ftpd-rsa-key.pem RSA private key >+ftpd-dsa.pem DSA certificate, may include private key >+ftpd-dsa-key.pem DSA private key >+ftpd-crl.pem Certificate Revokation List >+ftpd-dhparam.pem DH Parameters (a set of DH params is compiled in) >+ >+These files is searched for in the following directorys (in this order): >+* Current working directory of the process. >+* Specified by the `X509_get_default_cert_dir_env()` environment variable >+ (usually $SSL_CERT_DIR). >+* `X509_get_default_cert_dir()`, usually (openssl-dir)/certs. >+* `X509_get_default_private_dir()`, usually (openssl-dir/private. >+ >+Default CRL directory for the proftpd server is (openssl-dir)/crl. >+ >+If you don't have any "proper" certificate files (signed by some CA), you might >+create a self-signed one using the ``openssl'' command: >+$ openssl req -new -x509 -days 365 -nodes -out ftpd-rsa.pem -keyout ftpd-rsa-key.pem >+This creates a cert which is valid 365 days, you might want to adjust that. >+ >+X509 client authentication >+-------------------------- >+Support for user authentication is possible through the custom function >+int x509_to_user(X509 *peer_cert, char *userid, int len) in the file >+src/x509_to_user.c, and by a .tlslogin file in the user's home directory. >+ >+o tls_userid_from_client_cert() is called and returns a user id or NULL. >+ tls_userid_from_client_cert() calls the site specific function >+ x509_to_user(). >+ >+o If the user name, set by the USER command, equals the user id mapped from the >+ client cert, the user is logged right in. >+ >+o If "USER" differ from the user id mapped from the client cert the function >+ tls_is_user_valid() is called to check "USER"'s ~/.tlslogin file. >+ That file, if it exist, contains one or more X509 certificates in PEM for- >+ mat. If the client cert is present in the file, the user is logged right in. >+ >+o If tls_userid_from_client_cert() can't map a user id from the client cert, >+ tls_is_user_valid() is called to check "USER"'s ~/.tlslogin file. If the >+ client cert is present in the file, the user is logged right in. >+ >+Hash symlinks for certs: ln -s cert.pem `openssl x509 -hash -noout -in cert.pem`.0 >+Hash symlinks for CRLs: ln -s crl.pem `openssl crl -hash -noout -in crl.pem`.r0 >+ >+Default cipher list is "ALL:!EXP". >+ >+How to put together a 'cipher list string': >+ Key Exchange Algorithms: >+ "kRSA" RSA key exchange >+ "kDHr" Diffie-Hellman key exchange (key from RSA cert) >+ "kDHd" Diffie-Hellman key exchange (key from DSA cert) >+ "kEDH' Ephemeral Diffie-Hellman key exchange (temporary key) >+ >+ Authentication Algorithm: >+ "aNULL" No authentication >+ "aRSA" RSA authentication >+ "aDSS" DSS authentication >+ "aDH" Diffie-Hellman authentication >+ >+ Cipher Encoding Algorithm: >+ "eNULL" No encodiing >+ "DES" DES encoding >+ "3DES" Triple DES encoding >+ "RC4" RC4 encoding >+ "RC2" RC2 encoding >+ "IDEA" IDEA encoding >+ >+ MAC Digest Algorithm: >+ "MD5" MD5 hash function >+ "SHA1" SHA1 hash function >+ "SHA" SHA hash function (should not be used) >+ >+ Aliases: >+ "ALL" all ciphers >+ "SSLv2" all SSL version 2.0 ciphers (should not be used) >+ "SSLv3" all SSL version 3.0 ciphers >+ "EXP" all export ciphers (40-bit) >+ "EXPORT56" all export ciphers (56-bit) >+ "LOW" all low strength ciphers (no export) >+ "MEDIUM" all ciphers with 128-bit encryption >+ "HIGH" all ciphers using greater than 128-bit encryption >+ "RSA" all ciphers using RSA key exchange >+ "DH" all ciphers using Diffie-Hellman key exchange >+ "EDH" all ciphers using Ephemeral Diffie-Hellman key exchange >+ "ADH" all ciphers using Anonymous Diffie-Hellman key exchange >+ "DSS" all ciphers using DSS authentication >+ "NULL" all ciphers using no encryption >+ >+Each item in the list may include a prefix modifier: >+ >+ "+" move cipher(s) to the current location in the list >+ "-" remove cipher(s) from the list (may be added again by >+ a subsequent list entry) >+ "!" kill cipher from the list (it may not be added again >+ by a subsequent list entry) >+ >+If no modifier is specified the entry is added to the list at the current >+position. "+" may also be used to combine tags to specify entries such as >+"RSA+RC4" describes all ciphers that use both RSA and RC4. >+ >+For example, all available ciphers not including ADH key exchange: >+ >+ ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP >+ >+All algorithms including ADH and export but excluding patented algorithms: >+ >+ HIGH:MEDIUM:LOW:EXPORT56:EXP:ADH:!kRSA:!aRSA:!RC4:!RC2:!IDEA >+ >+The OpenSSL command >+ >+ openssl ciphers -v <list of ciphers> >+ >+may be used to list all of the ciphers and the order described by a specific >+<list of ciphers>. >diff -urN proftpd-1.2.6rc1.orig/acconfig.h proftpd-1.2.6rc1-tls/acconfig.h >--- proftpd-1.2.6rc1.orig/acconfig.h Sat Mar 17 21:34:31 2001 >+++ proftpd-1.2.6rc1-tls/acconfig.h Mon Jun 10 11:56:48 2002 >@@ -18,6 +18,12 @@ > /* Define if you have BSD sendfile() semantics */ > #undef HAVE_BSD_SENDFILE > >+/* Define to build with SSL/TLS support */ >+#undef TLS >+ >+/* Define this symbol if support for OpenSSL zlib compression is enabled. */ >+#undef ZLIB >+ > /* Define if you have Linux sendfile() semantics */ > #undef HAVE_LINUX_SENDFILE > >diff -urN proftpd-1.2.6rc1.orig/config.h.in proftpd-1.2.6rc1-tls/config.h.in >--- proftpd-1.2.6rc1.orig/config.h.in Fri Jun 28 00:36:25 2002 >+++ proftpd-1.2.6rc1-tls/config.h.in Wed Jul 3 10:54:31 2002 >@@ -19,6 +19,12 @@ > /* Define if you have BSD sendfile() semantics */ > #undef HAVE_BSD_SENDFILE > >+/* Define to build with SSL/TLS support */ >+#undef TLS >+ >+/* Define this symbol if support for OpenSSL zlib compression is enabled. */ >+#undef ZLIB >+ > /* Define if you have Linux sendfile() semantics */ > #undef HAVE_LINUX_SENDFILE > >@@ -423,7 +429,7 @@ > /* Define if you have the <utmpx.h> header file. */ > #undef HAVE_UTMPX_H > >-/* Define if you have the "vmsdir.h" header file. */ >+/* Define if you have the <vmsdir.h> header file. */ > #undef HAVE_VMSDIR_H > > /* Define if you have the bind library (-lbind). */ >diff -urN proftpd-1.2.6rc1.orig/configure proftpd-1.2.6rc1-tls/configure >--- proftpd-1.2.6rc1.orig/configure Fri Jun 28 00:39:29 2002 >+++ proftpd-1.2.6rc1-tls/configure Wed Jul 3 11:18:14 2002 >@@ -838,6 +838,8 @@ > > --enable-shadow force compilation of shadowed password support > >+ --disable-tls disable TLS security >+ --enable-tls_zlib enable use of OpenSSL zlib compression (EXPERIMENTAL) > > Optional Packages: > --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] >@@ -854,6 +856,7 @@ > LIST is a ':' separated list of modules to add > e.g. --with-modules=mod_pam:mod_readme > >+ --with-openssl-dir=DIR specify location of the OpenSSL directory > > Some influential environment variables: > CC C compiler command >@@ -3495,6 +3498,32 @@ > fi > > >+# Check whether --with-openssl-dir or --without-openssl-dir was given. >+if test "${with_openssl_dir+set}" = set; then >+ withval="$with_openssl_dir" >+ OPENSSLDIR=$withval >+fi; >+if test -n "$OPENSSLDIR"; then >+ LIBS="$LIBS -L$OPENSSLDIR/lib" >+ CPPFLAGS="$CPPFLAGS -I$OPENSSLDIR/include" >+fi >+ >+# Check whether --enable-tls or --disable-tls was given. >+if test "${enable_tls+set}" = set; then >+ enableval="$enable_tls" >+ >+else >+ enable_tls=yes >+fi; >+# Check whether --enable-tls_zlib or --disable-tls_zlib was given. >+if test "${enable_tls_zlib+set}" = set; then >+ enableval="$enable_tls_zlib" >+ >+else >+ enable_tls_zlib=no >+fi; >+ >+ > echo "$as_me:$LINENO: checking for set_auth_parameters in -lsecurity" >&5 > echo $ECHO_N "checking for set_auth_parameters in -lsecurity... $ECHO_C" >&6 > if test "${ac_cv_lib_security_set_auth_parameters+set}" = set; then >@@ -10449,6 +10478,216 @@ > esac > fi > >+if test "$enable_tls" = yes; then >+ # look for OpenSSL libraries >+ echo "$as_me:$LINENO: checking for X509_STORE_load_locations in -lcrypto" >&5 >+echo $ECHO_N "checking for X509_STORE_load_locations in -lcrypto... $ECHO_C" >&6 >+if test "${ac_cv_lib_crypto_X509_STORE_load_locations+set}" = set; then >+ echo $ECHO_N "(cached) $ECHO_C" >&6 >+else >+ ac_check_lib_save_LIBS=$LIBS >+LIBS="-lcrypto $LIBS" >+cat >conftest.$ac_ext <<_ACEOF >+#line $LINENO "configure" >+#include "confdefs.h" >+ >+/* Override any gcc2 internal prototype to avoid an error. */ >+#ifdef __cplusplus >+extern "C" >+#endif >+/* We use char because int might match the return type of a gcc2 >+ builtin and then its argument prototype would still apply. */ >+char X509_STORE_load_locations (); >+#ifdef F77_DUMMY_MAIN >+# ifdef __cplusplus >+ extern "C" >+# endif >+ int F77_DUMMY_MAIN() { return 1; } >+#endif >+int >+main () >+{ >+X509_STORE_load_locations (); >+ ; >+ return 0; >+} >+_ACEOF >+rm -f conftest.$ac_objext conftest$ac_exeext >+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 >+ (eval $ac_link) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); } && >+ { ac_try='test -s conftest$ac_exeext' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; }; then >+ ac_cv_lib_crypto_X509_STORE_load_locations=yes >+else >+ echo "$as_me: failed program was:" >&5 >+cat conftest.$ac_ext >&5 >+ac_cv_lib_crypto_X509_STORE_load_locations=no >+fi >+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext >+LIBS=$ac_check_lib_save_LIBS >+fi >+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_X509_STORE_load_locations" >&5 >+echo "${ECHO_T}$ac_cv_lib_crypto_X509_STORE_load_locations" >&6 >+if test $ac_cv_lib_crypto_X509_STORE_load_locations = yes; then >+ LIBTLS=-lcrypto >+else >+ { { echo "$as_me:$LINENO: error: Could not find OpenSSL library needed for SSL/TLS support. Try again using --with-openssl-dir=DIR" >&5 >+echo "$as_me: error: Could not find OpenSSL library needed for SSL/TLS support. Try again using --with-openssl-dir=DIR" >&2;} >+ { (exit 1); exit 1; }; } >+fi >+ >+ echo "$as_me:$LINENO: checking for SSL_accept in -lssl" >&5 >+echo $ECHO_N "checking for SSL_accept in -lssl... $ECHO_C" >&6 >+if test "${ac_cv_lib_ssl_SSL_accept+set}" = set; then >+ echo $ECHO_N "(cached) $ECHO_C" >&6 >+else >+ ac_check_lib_save_LIBS=$LIBS >+LIBS="-lssl -lcrypto $LIBS" >+cat >conftest.$ac_ext <<_ACEOF >+#line $LINENO "configure" >+#include "confdefs.h" >+ >+/* Override any gcc2 internal prototype to avoid an error. */ >+#ifdef __cplusplus >+extern "C" >+#endif >+/* We use char because int might match the return type of a gcc2 >+ builtin and then its argument prototype would still apply. */ >+char SSL_accept (); >+#ifdef F77_DUMMY_MAIN >+# ifdef __cplusplus >+ extern "C" >+# endif >+ int F77_DUMMY_MAIN() { return 1; } >+#endif >+int >+main () >+{ >+SSL_accept (); >+ ; >+ return 0; >+} >+_ACEOF >+rm -f conftest.$ac_objext conftest$ac_exeext >+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 >+ (eval $ac_link) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); } && >+ { ac_try='test -s conftest$ac_exeext' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; }; then >+ ac_cv_lib_ssl_SSL_accept=yes >+else >+ echo "$as_me: failed program was:" >&5 >+cat conftest.$ac_ext >&5 >+ac_cv_lib_ssl_SSL_accept=no >+fi >+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext >+LIBS=$ac_check_lib_save_LIBS >+fi >+echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_accept" >&5 >+echo "${ECHO_T}$ac_cv_lib_ssl_SSL_accept" >&6 >+if test $ac_cv_lib_ssl_SSL_accept = yes; then >+ LIBTLS="-lssl $LIBTLS" >+else >+ { { echo "$as_me:$LINENO: error: Could not find OpenSSL library needed for SSL/TLS support. Try again using --with-openssl-dir=DIR" >&5 >+echo "$as_me: error: Could not find OpenSSL library needed for SSL/TLS support. Try again using --with-openssl-dir=DIR" >&2;} >+ { (exit 1); exit 1; }; } >+fi >+ >+ ac_core_modules="$ac_core_modules mod_tls.o" >+ ac_build_core_modules="$ac_build_core_modules modules/mod_tls.o" >+ TLS_OBJS="tlsutil.o x509_to_user.o" >+ TLS_BUILD_OBJS="src/tlsutil.o src/x509_to_user.o" >+ >+ >+ cat >>confdefs.h <<\_ACEOF >+#define TLS 1 >+_ACEOF >+ >+ if test "$enable_tls_zlib" = yes; then >+ echo "$as_me:$LINENO: checking for compress in -lz" >&5 >+echo $ECHO_N "checking for compress in -lz... $ECHO_C" >&6 >+if test "${ac_cv_lib_z_compress+set}" = set; then >+ echo $ECHO_N "(cached) $ECHO_C" >&6 >+else >+ ac_check_lib_save_LIBS=$LIBS >+LIBS="-lz $LIBS" >+cat >conftest.$ac_ext <<_ACEOF >+#line $LINENO "configure" >+#include "confdefs.h" >+ >+/* Override any gcc2 internal prototype to avoid an error. */ >+#ifdef __cplusplus >+extern "C" >+#endif >+/* We use char because int might match the return type of a gcc2 >+ builtin and then its argument prototype would still apply. */ >+char compress (); >+#ifdef F77_DUMMY_MAIN >+# ifdef __cplusplus >+ extern "C" >+# endif >+ int F77_DUMMY_MAIN() { return 1; } >+#endif >+int >+main () >+{ >+compress (); >+ ; >+ return 0; >+} >+_ACEOF >+rm -f conftest.$ac_objext conftest$ac_exeext >+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 >+ (eval $ac_link) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); } && >+ { ac_try='test -s conftest$ac_exeext' >+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 >+ (eval $ac_try) 2>&5 >+ ac_status=$? >+ echo "$as_me:$LINENO: \$? = $ac_status" >&5 >+ (exit $ac_status); }; }; then >+ ac_cv_lib_z_compress=yes >+else >+ echo "$as_me: failed program was:" >&5 >+cat conftest.$ac_ext >&5 >+ac_cv_lib_z_compress=no >+fi >+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext >+LIBS=$ac_check_lib_save_LIBS >+fi >+echo "$as_me:$LINENO: result: $ac_cv_lib_z_compress" >&5 >+echo "${ECHO_T}$ac_cv_lib_z_compress" >&6 >+if test $ac_cv_lib_z_compress = yes; then >+ LIBS="$LIBS -lz" >+else >+ { { echo "$as_me:$LINENO: error: Could not find ZLIB library needed." >&5 >+echo "$as_me: error: Could not find ZLIB library needed." >&2;} >+ { (exit 1); exit 1; }; } >+fi >+ >+ cat >>confdefs.h <<\_ACEOF >+#define ZLIB 1 >+_ACEOF >+ >+ fi >+ LIBS="$LIBS $LIBTLS" >+fi >+ > > for ac_func in setproctitle > do >@@ -11740,10 +11979,13 @@ > s,@INSTALL_DATA@,$INSTALL_DATA,;t t > s,@RANLIB@,$RANLIB,;t t > s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t >+s,@OPENSSLDIR@,$OPENSSLDIR,;t t > s,@CPP@,$CPP,;t t > s,@install_user@,$install_user,;t t > s,@install_group@,$install_group,;t t > s,@ALLOCA@,$ALLOCA,;t t >+s,@TLS_OBJS@,$TLS_OBJS,;t t >+s,@TLS_BUILD_OBJS@,$TLS_BUILD_OBJS,;t t > s,@MODULES@,$MODULES,;t t > s,@BUILD_MODULES@,$BUILD_MODULES,;t t > s,@ADDL_DIRS@,$ADDL_DIRS,;t t >diff -urN proftpd-1.2.6rc1.orig/configure.in proftpd-1.2.6rc1-tls/configure.in >--- proftpd-1.2.6rc1.orig/configure.in Fri Jun 28 00:36:25 2002 >+++ proftpd-1.2.6rc1-tls/configure.in Wed Jul 3 10:54:31 2002 >@@ -239,6 +239,20 @@ > AC_DEFINE(HAVE__PW_STAYOPEN) > fi > >+dnl TLS options >+AC_ARG_WITH(openssl-dir, >+ [ --with-openssl-dir=DIR specify location of the OpenSSL directory], >+ OPENSSLDIR=$withval) >+if test -n "$OPENSSLDIR"; then >+ LIBS="$LIBS -L$OPENSSLDIR/lib" >+ CPPFLAGS="$CPPFLAGS -I$OPENSSLDIR/include" >+fi >+AC_SUBST(OPENSSLDIR) >+AC_ARG_ENABLE(tls, [ --disable-tls disable TLS security], >+ , enable_tls=yes) >+AC_ARG_ENABLE(tls_zlib, [ --enable-tls_zlib enable use of OpenSSL zlib compression (EXPERIMENTAL)], >+ , enable_tls_zlib=no) >+ > AC_CHECK_LIB(security, set_auth_parameters) > AC_CHECK_HEADERS(sys/security.h) > AC_CHECK_HEADERS(krb.h) >@@ -536,6 +550,28 @@ > esac > fi > >+dnl TLS options >+if test "$enable_tls" = yes; then >+ # look for OpenSSL libraries >+ AC_CHECK_LIB(crypto, X509_STORE_load_locations, LIBTLS=-lcrypto, >+ AC_MSG_ERROR(Could not find OpenSSL library needed for SSL/TLS support. Try again using --with-openssl-dir=DIR)) >+ AC_CHECK_LIB(ssl, SSL_accept, LIBTLS="-lssl $LIBTLS", >+ AC_MSG_ERROR(Could not find OpenSSL library needed for SSL/TLS support. Try again using --with-openssl-dir=DIR), -lcrypto) >+ ac_core_modules="$ac_core_modules mod_tls.o" >+ ac_build_core_modules="$ac_build_core_modules modules/mod_tls.o" >+ TLS_OBJS="tlsutil.o x509_to_user.o" >+ TLS_BUILD_OBJS="src/tlsutil.o src/x509_to_user.o" >+ AC_SUBST(TLS_OBJS) >+ AC_SUBST(TLS_BUILD_OBJS) >+ AC_DEFINE(TLS) >+ if test "$enable_tls_zlib" = yes; then >+ AC_CHECK_LIB(z, compress, LIBS="$LIBS -lz", >+ AC_MSG_ERROR(Could not find ZLIB library needed.)) >+ AC_DEFINE(ZLIB) >+ fi >+ LIBS="$LIBS $LIBTLS" >+fi >+ > dnl Check for various argv[] replacing functions on various OSs > AC_CHECK_FUNCS(setproctitle) > AC_CHECK_HEADERS(libutil.h) >diff -urN proftpd-1.2.6rc1.orig/contrib/dist/rpm/proftpd.spec.in proftpd-1.2.6rc1-tls/contrib/dist/rpm/proftpd.spec.in >--- proftpd-1.2.6rc1.orig/contrib/dist/rpm/proftpd.spec.in Sun May 19 16:38:42 2002 >+++ proftpd-1.2.6rc1-tls/contrib/dist/rpm/proftpd.spec.in Thu Jul 11 21:03:37 2002 >@@ -1,21 +1,45 @@ > # $Id: proftpd.spec.in,v 1.14 2002/05/19 14:38:42 jwm Exp $ > # >+%define tls 1 >+%if %{tls} >+%define TLSVERSION 20020711 >+%define TLSVERSIONRELEASE 1 >+%endif >+%if %{tls} >+Summary: ProFTPD -- Professional FTP Server (TLS enabled). >+%else > Summary: ProFTPD -- Professional FTP Server. >+%endif > Name: proftpd > Version: @VERSION@ >+%if %{tls} >+Release: 1.tls.%{TLSVERSION}.%{TLSVERSIONRELEASE} >+%else > Release: 1 >+%endif > Copyright: GPL > Group: System Environment/Daemons >-Packager: Daniel Roesen <droesen@entire-systems.com> >+Packager: Daniel Roesen <droesen@entire-systems.com> and Dr. Peter Bieringer <pbieringer@aerasec.de> (TLS) > Vendor: The ProFTPD Group > URL: http://www.proftpd.org/ > Source: ftp://ftp.proftpd.org/distrib/%{name}-%{version}.tar.gz >+%if %{tls} >+Patch0: ftp://ftp.runestig.com/pub/%{name}-%{version}-tls.%{TLSVERSION}.patch.gz >+%endif > Prefix: /usr >+%if %{tls} >+BuildRoot: %{_builddir}/%{name}-%{version}-%{TLSVERSION}-root >+Requires: pam >= 0.72, openssl >+%else > BuildRoot: %{_builddir}/%{name}-%{version}-root > Requires: pam >= 0.72 >+%endif > Provides: ftpserver > Prereq: fileutils > Obsoletes: proftpd-core >+%if %{tls} >+BuildPreReq: openssl-devel >+%endif > > %description > ProFTPD is an enhanced FTP server with a focus toward simplicity, security, >@@ -26,6 +50,9 @@ > > There are two other packages you can use to setup for inetd or standalone > operation. >+%if %{tls} >+This package is TLS enabled, used TLS patch version is: %{TLSVERSION} >+%endif > > %package standalone > Summary: ProFTPD -- Setup for standalone operation. >@@ -39,7 +66,7 @@ > %package inetd > Summary: ProFTPD -- Setup for inetd operation. > Group: System Environment/Daemons >-Requires: proftpd >+Requires: proftpd-tls > Obsoletes: proftpd-standalone > > %description inetd >@@ -47,6 +74,9 @@ > > %prep > %setup -q >+%if %{tls} >+%patch0 -p1 >+%endif > CFLAGS="$RPM_OPT_FLAGS" ./configure \ > --prefix=%{prefix} \ > --sysconfdir=/etc \ >@@ -178,6 +208,9 @@ > - Added use of %defattr to allow build of RPMs by non-root users > For details see http://bugs.proftpd.org/show_bug.cgi?id=1580 > >+* Mon May 07 2001 Dr. Peter Bieringer <pbieringer@aerasec.de> >+- Make "tls" usage switchable >+ > * Mon Mar 05 2001 Daniel Roesen <droesen@entire-systems.com> > - PAM >= 0.72 is now a requirement. Versions before are broken and > Red Hat provides a PAM update for all RH 6.x releases. See: >diff -urN proftpd-1.2.6rc1.orig/doc/rfc/draft-murray-auth-ftp-ssl-09.txt proftpd-1.2.6rc1-tls/doc/rfc/draft-murray-auth-ftp-ssl-09.txt >--- proftpd-1.2.6rc1.orig/doc/rfc/draft-murray-auth-ftp-ssl-09.txt Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/doc/rfc/draft-murray-auth-ftp-ssl-09.txt Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,1679 @@ >+ >+ >+ >+ >+ >+ >+ Paul Ford-Hutchinson >+<draft-murray-auth-ftp-ssl-09.txt> IBM UK Ltd >+ Martin Carpenter >+ Verisign Inc >+ Tim Hudson >+INTERNET-DRAFT (draft) RSA Australia Ltd >+ Eric Murray >+ Wave Systems Inc >+ Volker Wiegand >+ SuSE Linux >+ >+ 2nd April, 2002 >+This document expires on 2nd October, 2002 >+ >+ >+ Securing FTP with TLS >+ >+ >+Status of this Memo >+ >+ This document is an Internet-Draft and is in full conformance with >+ all provisions of Section 10 of RFC2026. >+ >+ Internet-Drafts are working documents of the Internet Engineering >+ Task Force (IETF), its areas, and its working groups. Note that >+ other groups may also distribute working documents as Internet- >+ Drafts. >+ >+ Internet-Drafts are draft documents valid for a maximum of six months >+ and may be updated, replaced, or obsoleted by other documents at any >+ time. It is inappropriate to use Internet-Drafts as reference >+ material or to cite them other than as "work in progress." >+ >+ The list of current Internet-Drafts can be accessed at >+ http://www.ietf.org/1id-abstracts.txt >+ >+ The list of Internet-Draft Shadow Directories can be accessed at >+ http://www.ietf.org/shadow.html >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 1] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+Index >+ 1. .......... Abstract >+ 2. .......... Introduction >+ 3. .......... Audience >+ 4. .......... Session negotiation on the control port >+ 5. .......... Response to FEAT command >+ 6. .......... Data Connection Behaviour >+ 7. .......... Mechanisms for the AUTH Command >+ 8. .......... Data Connection Security >+ 9. .......... A discussion of negotiation behaviour >+ 10. ......... Who negotiates what, where and how >+ 11. ......... Timing Diagrams >+ 12. ......... Discussion of the REIN command >+ 13. ......... Discussion of the STAT and ABOR commands >+ 14. ......... Security Considerations >+ 15. ......... IANA Considerations >+ 16. ......... Other Parameters >+ 17. ......... Network Management >+ 18. ......... Internationalization >+ 19. ......... Scalability & Limits >+ 20. ......... Applicability >+ 21. ......... Acknowledgements >+ 22. ......... References >+ 23. ......... Authors' Contact Addresses >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 2] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+1. Abstract >+ >+ This document describes a mechanism that can be used by FTP clients >+ and servers to implement security and authentication using the TLS >+ protocol defined by [RFC-2246] and the extensions to the FTP protocol >+ defined by [RFC-2228]. It describes the subset of the extensions >+ that are required and the parameters to be used; discusses some of >+ the policy issues that clients and servers will need to take; >+ considers some of the implications of those policies and discusses >+ some expected behaviours of implementations to allow interoperation. >+ This document is intended to provide TLS support for FTP in a similar >+ way to that provided for SMTP in [RFC-2487] and HTTP in [RFC-2817]. >+ >+ TLS is not the only mechanism for securing file transfer, however it >+ does offer some of the following positive attributes:- >+ >+ - Flexible security levels. TLS can support confidentiality, >+ integrity, authentication or some combination of all of these. >+ This allows clients and servers to dynamically, during a session, >+ decide on the level of security required for a particular data >+ transfer, >+ >+ - It is possible to use TLS identities to authenticate client >+ users and not just client hosts. >+ >+ - Formalised public key management. By use of well established >+ client identity mechnisms (supported by TLS) during the >+ authentication phase, certificate management may be built into a >+ central function. Whilst this may not be desirable for all uses >+ of secured file transfer, it offers advantages in certain >+ structured environments. >+ >+ - Co-existence and interoperation with authentication mechanisms >+ that are already in place for the HTTPS protocol. This allows web >+ browsers to incorporate secure file transfer using the same >+ infrastructure that has been set up to allow secure web browsing. >+ >+ The TLS protocol is a development of the Netscape Communication >+ Corporation's SSL protocol and this document can be used to allow the >+ FTP protocol to be used with either SSL or TLS. The actual protocol >+ used will be decided by the negotiation of the protected session by >+ the TLS/SSL layer. This document will only refer to the TLS >+ protocol, however, it is understood that the Client and Server MAY >+ actually be using SSL if they are so configured. >+ >+ Note that this specification is in accordance with the FTP RFC >+ [RFC-959] and relies on the TLS protocol [RFC-2246] and the FTP >+ security extensions [RFC-2228]. >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 3] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+2. Introduction >+ >+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", >+ "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and >+ "OPTIONAL" that appear in this document are to be interpreted as >+ described in [RFC-2119]. >+ >+ This document is an attempt to describe how three other documents >+ should combined to provide a useful, interoperable, secure file >+ transfer protocol. Those documents are:- >+ >+ >+ RFC 959 [RFC-959] >+ >+ The description of the Internet File Transfer Protocol >+ >+ RFC 2246 [RFC-2246] >+ >+ The description of the Transport Layer Security protocol >+ (developed from the Netscape Secure Sockets Layer (SSL) >+ protocol version 3.0). >+ >+ RFC 2228 [RFC-2228] >+ >+ Extensions to the FTP protocol to allow negotiation of security >+ mechanisms to allow authentication, confidentiality and message >+ integrity. >+ >+ The File Transfer Protocol (FTP) currently defined in [RFC-959] and >+ in place on the Internet is an excellent mechanism for exchanging >+ files. The security extensions to FTP in [RFC-2228] offer a >+ comprehensive set of commands and responses that can be used to add >+ authentication, integrity and confidentiality to the FTP protocol. >+ The TLS protocol is a popular (due to its wholesale adoption in the >+ HTTP environment) mechanism for generally securing a socket >+ connection. >+ There are many ways in which these three protocols can be combined >+ which would ensure that interoperation is impossible. This document >+ describes one method by which FTP can operate securely in such a way >+ as to provide both flexibility and interoperation. This necessitates >+ a brief description of the actual negotiation mechanism ; a much more >+ detailed description of the policies and practices that would be >+ required and a discussion of the expected behaviours of clients and >+ servers to allow either party to impose their security requirements >+ on the FTP session. >+ >+ >+3. Audience >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 4] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ This document is aimed at developers who wish to implement TLS as a >+ security mechanism to secure FTP clients and/or servers. >+ >+ >+4. Session negotiation on the control port >+ >+ The server listens on the normal FTP control port {FTP-PORT} and the >+ session initiation is not secured at all. Once the client wishes to >+ secure the session, the AUTH command is sent and the server MAY then >+ allow TLS negotiation to take place. >+ >+ 4.1 Client wants a secured session >+ >+ If a client wishes to attempt to secure a session then it SHOULD, >+ in accordance with [RFC-2228] send the AUTH command with the >+ parameter requesting TLS {TLS-PARM}. >+ >+ >+ The client then needs to behave according to its policies depending >+ on the response received from the server and also the result of the >+ TLS negotiation. i.e. A client which receives an AUTH rejection >+ MAY choose to continue with the session unprotected if it so >+ desires. >+ >+ 4.2 Server wants a secured session >+ >+ The FTP protocol does not allow a server to directly dictate client >+ behaviour, however the same effect can be achieved by refusing to >+ accept certain FTP commands until the session is secured to an >+ acceptable level to the server. >+ >+ The server response to an 'AUTH TLS' command which it will honour, is >+ '234'. >+ >+ Note. The '334' response as defined in [RFC-2228] implies that an >+ ADAT exchange will folow. This document does not use the ADAT >+ command and so the '334' reply is incorrect. >+ >+ Note. The FTP protocol insists that a USER command be used to >+ identify the entity attempting to use the ftp server. Although the >+ TLS negotiation may be providing authentication information the USER >+ command must still be isssued by the client. However, it will be a >+ server implementation issue to decide which credentials to accept and >+ what consistency checks to make between any client cert used and the >+ parameter on the USER command. >+ >+5. Response to the FEAT command >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 5] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ The FEAT command (introduced in [RFC-2389]) allows servers with >+ additional features to advertise these to a client by responding to >+ the FEAT command. If a server supports the FEAT command then it MUST >+ advertise supported AUTH, PBSZ and PROT commands in the reply as >+ described in section 3.2 of [RFC-2389]. Additionally, the AUTH >+ command should have a reply that identifies 'TLS' as one of the >+ possible parameters to AUTH. It is not necessary to identify the >+ 'TLS-C' synonym separately. >+ >+ Example reply (in same style is [RFC-2389]) >+ C> FEAT >+ S> 211-Extensions supported >+ S> AUTH TLS >+ S> PBSZ >+ S> PROT >+ S> 211 END >+ >+ >+6. Data Connection Behaviour >+ >+ The Data Connection in the FTP model can be used in one of three >+ ways. (Note: these descriptions are not necessarily placed in exact >+ chronological order, but do describe the steps required. - See >+ diagrams later for clarification) >+ >+ i) Classic FTP client/server data exchange >+ >+ - The client obtains a port; sends the port number to the >+ server; the server connects to the client. The client issues a >+ send or receive request to the server on the control connection >+ and the data transfer commences on the data connection. >+ >+ ii) Firewall-Friendly client/server data exchange (as discussed >+ in [RFC-1579]) using the PASV command to reverse the direction >+ of the data connection. >+ >+ - The client requests that the server open a port; the server >+ obtains a port and returns the address and port number to the >+ client; the client connects to the server on this port. The >+ client issues a send or receive request on the control >+ connection and the data transfer commences on the data >+ connection. >+ >+ iii) Client initiated server/server data exchange (proxy or >+ PASV connections) >+ >+ - The client requests that server A opens a port; server A >+ obtains a port and returns it to the client; the client sends >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 6] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ this port number to server B. Server B connects to server A. >+ The client sends a send or receive request to server A and the >+ complement to server B and the data transfer commences. In >+ this model server A is the proxy or PASV host and is a client >+ for the Data Connection to server B. >+ >+ For i) and ii) the FTP client MUST be the TLS client and the FTP >+ server MUST be the TLS server. >+ >+ That is to say, it does not matter which side initiates the >+ connection with a connect() call or which side reacts to the >+ connection via the accept() call; the FTP client as defined in >+ [RFC-959] is always the TLS client as defined in [RFC-2246]. >+ >+ In scenario iii) there is a problem in that neither server A nor >+ server B is the TLS client given the fact that an FTP server must act >+ as a TLS server for Firewall-Friendly FTP [RFC-1579]. Thus this is >+ explicitly excluded in the security extensions document [RFC-2228], >+ and in this document. >+ >+ >+ >+7. Mechanisms for the AUTH Command >+ >+ The AUTH command takes a single parameter to define the security >+ mechanism to be negotiated. As the SSL/TLS protocols self-negotiate >+ their levels there is no need to distinguish SSL vs TLS in the >+ application layer. The proposed mechanism name for negotiating TLS >+ will be the character string identified in {TLS-PARM}. This will >+ allow the client and server to negotiate TLS on the control >+ connection without altering the protection of the data channel. To >+ protect the data channel as well, the PBSZ:PROT command sequence MUST >+ be used. >+ >+ Note: The data connection state MAY be modified by the client issuing >+ the PROT command with the new desired level of data channel >+ protection and the server replying in the affirmative. This data >+ channel protection negotiation can happen at any point in the session >+ (even straight after a PORT or PASV command) and as often as is >+ required. >+ >+ See also Section 15, "IANA Considerations". >+ >+ >+8. Data Connection Security >+ >+ The Data Connection security level is determined by the PROT command >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 7] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ The PROT command, as specified in [RFC-2228] allows client/server >+ negotiation of the security level of the data connection. Once a >+ PROT command has been issued by the client and accepted by the >+ server returning the '200' reply, the security of subsequent data >+ connections MUST be at that level until another PROT command is >+ issued and accepted; the session ends; a REIN command is issued; >+ or the security of the session (via an AUTH command) is re- >+ negotiated. >+ >+ Data Connection Security Negotiation (the PROT command) >+ >+ Note: In line with [RFC-2228], there is no facility for securing >+ the Data connection with an insecure Control connection. >+ Specifically, the PROT command MUST be preceded by a PBSZ command >+ and a PBSZ command MUST be preceded by a successful security data >+ exchange (the TLS negotiation in this case) >+ >+ The command defined in [RFC-2228] to negotiate data connection >+ security is the PROT command. As defined there are four values >+ that the PROT command parameter can take. >+ >+ 'C' - Clear - neither Integrity nor Privacy >+ >+ 'S' - Safe - Integrity without Privacy >+ >+ 'E' - Confidential - Privacy without Integrity >+ >+ 'P' - Private - Integrity and Privacy >+ >+ As TLS negotiation encompasses (and exceeds) the Safe / >+ Confidential / Private distinction, only Private (use TLS) and >+ Clear (don't use TLS) are used. >+ >+ For TLS, the data connection can have one of two security levels. >+ >+ 1)Clear (requested by 'PROT C') >+ >+ 2)Private (requested by 'PROT P') >+ >+ With 'Clear' protection level, the data connection is made without >+ TLS at all. Thus the connection is unauthenticated and has no >+ confidentiality or integrity. This might be the desired behaviour >+ for servers sending file lists, pre-encrypted data or non- >+ sensitive data (e.g. for anonymous FTP servers). >+ >+ If the data connection security level is 'Private' then a TLS >+ negotiation must take place on the data connection, to the >+ satisfaction of the Client and Server prior to any data being >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 8] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ transmitted over the connection. The TLS layers of the Client and >+ Server will be responsible for negotiating the exact TLS Cipher >+ Suites that will be used (and thus the eventual security of the >+ connection). >+ >+ >+ In addition, the PBSZ (protection buffer size) command, as >+ detailed in [RFC-2228], is compulsory prior to any PROT command. >+ This document also defines a data channel encapsulation mechanism >+ for protected data buffers. For FTP-TLS, which appears to the FTP >+ application as a streaming protection mechanism, this is not >+ required. Thus the PBSZ command must still be issued, but must >+ have a parameter of '0' to indicate that no buffering is taking >+ place and the data connection should not be encapsulated. >+ Note that PBSZ 0 is not in the grammar of [RFC-2228], section >+ 8.1, where it is stated: >+ PBSZ <sp> <decimal-integer> <CRLF> <decimal-integer> ::= any >+ decimal integer from 1 to (2^32)-1 >+ However it should be noted that using a value of '0' to mean a >+ streaming protocol is a reasonable use of '0' for that parameter >+ and is not ambiguous. >+ >+ Initial Data Connection Security >+ >+ The initial state of the data connection MUST be 'Clear' (this is >+ the behaviour as indicated by [RFC-2228].) >+ >+ >+9. A Discussion of Negotiation Behaviour >+ >+ 9.1. The server's view of the control connection >+ >+ A server MAY have a policy statement somewhere that might: >+ >+ - Deny any command before TLS is negotiated (this might cause >+ problems if a SITE or some such command is required prior to >+ login) >+ - Deny certain commands before TLS is negotiated (such as USER, >+ PASS or ACCT) >+ - Deny insecure USER commands for certain users (e.g. not >+ ftp/anonymous) >+ - Deny secure USER commands for certain users (e.g. >+ ftp/anonymous) >+ - Define the level(s) of TLS to be allowed >+ - Define the CipherSuites allowed to be used (perhaps on a per >+ host/domain/... basis) >+ - Allow TLS authentication as a substitute for local >+ authentication. >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 9] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ - Define data connection policies (see next section) >+ >+ It is possible that the TLS negotiation may not be completed >+ satisfactorily for the server, in which case it can be one of >+ these states. >+ >+ The TLS negotiation failed completely >+ >+ In this case, the control connection should still be up in >+ unprotected mode and the server SHOULD issue an unprotected >+ '421' reply to end the session. >+ >+ The TLS negotiation completed successfully, but the server >+ decides that the session parameters are not acceptable (e.g. >+ Distinguished Name in the client certificate is not >+ permitted to use the server) >+ >+ In this case, the control connection should still be up in a >+ protected state, so the server MAY either continue to refuse to >+ service commands or issue a protected '421' reply and close the >+ connection. >+ >+ The TLS negotiation failed during the TLS handshake >+ >+ In this case, the control connection is in an unknown state and >+ the server SHOULD simply drop the control connection. >+ >+ Server code will be responsible for implementing the required >+ policies and ensuring that the client is prevented from >+ circumventing the chosen security by refusing to service those >+ commands that are against policy. >+ >+ 9.2. The server's view of the data connection >+ >+ The server can take one of four basic views of the data connection >+ >+ 1 - Don't allow encryption at all (in which case the PROT >+ command should not allow any value other than 'C' - if it is >+ allowed at all) >+ 2 - Allow the client to choose protection or not >+ 3 - Insist on data protection (in which case the PROT command >+ must be issued prior to the first attempted data transfer) >+ 4 - Decide on one of the above three for each and every data >+ connection >+ >+ The server SHOULD only check the status of the data protection >+ level (for options 3 and 4 above) on the actual command that will >+ initiate the data transfer (and not on the PORT or PASV). The >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 10] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ following commands, defined in [RFC-959] cause data connections to >+ be opened and thus may be rejected (before any 1xx) message due to >+ an incorrect PROT setting. >+ >+ >+ STOR >+ RETR >+ NLST >+ LIST >+ STOU >+ APPE >+ >+ >+ The reply to indicate that the PROT setting is incorrect is >+ '521 data connection cannot be opened with this PROT setting' >+ If the protection level indicates that TLS is required, then it >+ should be negotiated once the data connection is made. Thus, the >+ '150' reply only states that the command can be used given the >+ current PROT level. Should the server not like the TLS >+ negotiation then it will close the data port immediately and >+ follow the '150' command with a '522' reply indicating that the >+ TLS negotiation failed or was unacceptable. (Note: this means >+ that the application can pass a standard list of CipherSuites to >+ the TLS layer for negotiation and review the one negotiated for >+ applicability in each instance). >+ >+ It is quite reasonable for the server to insist that the data >+ connection uses a TLS cached session. This might be a cache of a >+ previous data connection or of the control connection. If this is >+ the reason for the the refusal to allow the data transfer then the >+ '522' reply should indicate this. >+ Note: this has an important impact on client design, but allows >+ servers to minimise the cycles used during TLS negotiation by >+ refusing to perform a full negotiation with a previously >+ authenticated client. >+ >+ It should be noted that the TLS authentication of the server will >+ be authentication of the server host itself and not a user on the >+ server host. >+ >+ 9.3. The client's view of the control connection >+ >+ In most cases it is likely that the client will be using TLS >+ because the server would refuse to interact insecurely. To allow >+ for this, clients SHOULD be able to be flexible enough to manage >+ the securing of a session at the appropriate time and still allow >+ the user/server policies to dictate exactly when in the session >+ the security is negotiated. >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 11] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ In the case where it is the client that is insisting on the >+ securing of the session, it will need to ensure that the >+ negotiations are all completed satisfactorily and will need to be >+ able to inform the user sensibly should the server not support, or >+ be prepared to use, the required security levels. >+ >+ Clients SHOULD be coded in such a manner as to allow the timing of >+ the AUTH, PBSZ and PROT commands to be flexible and dictated by >+ the server. It is quite reasonable for a server to refuse certain >+ commands prior to these commands, similarly it is quite possible >+ that a SITE or quoted command might be needed by a server prior to >+ the AUTH. A client MUST allow a user to override the timing of >+ these commands to suit a specific server. >+ For example, a client SHOULD NOT insist on sending the AUTH as the >+ first command in a session, nor should it insist on issuing a >+ PBSZ, PROT pair directly after the AUTH. This may well be the >+ default behaviour, but must be overridable by a user. >+ >+ Note: The TLS negotiation may not be completed satisfactorily for >+ the client, in which case it will be in one of these states: >+ >+ The TLS negotiation failed completely >+ >+ In this case, the control connection should still be up in >+ unprotected mode and the client should issue an unprotected >+ QUIT command to end the session. >+ >+ The TLS negotiation completed successfully, but the client >+ decides that the session parameters are not acceptable (e.g. >+ Distinguished Name in certificate is not the actual server >+ expected) >+ >+ In this case, the control connection should still be up in a >+ protected state, so the client should issue a protected QUIT >+ command to end the session. >+ >+ The TLS negotiation failed during the TLS handshake >+ >+ In this case, the control connection is in an unknown state >+ and the client should simply drop the control connection. >+ >+ 9.4. The client's view of the data connection >+ >+ Client security policies >+ >+ Clients do not typically have 'policies' as such, instead they >+ rely on the user defining their actions and, to a certain extent, >+ are reactive to the server policy. Thus a client will need to >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 12] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ have commands that will allow the user to switch the protection >+ level of the data connection dynamically, however, there may be a >+ general 'policy' that attempts all LIST and NLST commands on a >+ Clear connection first (and automatically switches to Private if >+ it fails). In this case there would need to be a user command >+ available to ensure that a given data transfer was not attempted >+ on an insecure data connection. >+ >+ Clients also need to understand that the level of the PROT setting >+ is only checked for a particular data transfer after that transfer >+ has been requested. Thus a refusal by the server to accept a >+ particular data transfer should not be read by the client as a >+ refusal to accept that data protection level in toto, as not only >+ may other data transfers be acceptable at that protection level, >+ but it is entirely possible that the same transfer may be accepted >+ at the same protection level at a later point in the session. >+ >+ It should be noted that the TLS authentication of the client >+ should be authentication of a user on the client host and not the >+ client host itself. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 13] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+10. Who negotiates what, where and how >+ >+ 10.1. Do we protect at all ? >+ >+ Client issues 'AUTH TLS', server accepts or rejects. >+ If server needs AUTH, then it refuses to accept certain commands >+ until it gets a successfully protected session. >+ >+ 10.2. What level of protection do we use on the Control connection ? >+ >+ Decided entirely by the TLS CipherSuite negotiation. >+ >+ 10.3. Do we protect data connections in general ? >+ >+ Client issues PROT command, server accepts or rejects. >+ >+ >+ 10.4. Is protection required for a particular data transfer ? >+ >+ A client would already have issued a PROT command if it required >+ the connection to be protected. >+ If a server needs to have the connection protected then it will >+ reply to the STOR/RETR/NLST/... command with a '522' indicating >+ that the current state of the data connection protection level is >+ not sufficient for that data transfer at that time. >+ >+ 10.5. What level of protection is required for a particular data >+ transfer ? >+ >+ Decided entirely by the TLS CipherSuite negotiation. >+ >+ Thus it can be seen that, for flexibility, it is desirable for the >+ FTP application to be able to interact with the TLS layer upon which >+ it sits to define and discover the exact TLS CipherSuites that are to >+ be/have been negotiated and make decisions accordingly. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 14] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+11. Timing Diagrams >+ >+ 11.1. Establishing a protected session >+ >+ Client Server >+ control data data control >+==================================================================== >+ >+ socket() >+ bind() >+ socket() >+ connect() ----------------------------------------------> accept() >+ <---------------------------------------------- 220 >+ AUTH TLS ----------------------------------------------> >+ <---------------------------------------------- 234 >+ TLSneg() <----------------------------------------------> TLSneg() >+ PBSZ 0 ----------------------------------------------> >+ <---------------------------------------------- 200 >+ PROT P ----------------------------------------------> >+ <---------------------------------------------- 200 >+ USER fred ----------------------------------------------> >+ <---------------------------------------------- 331 >+ PASS pass ----------------------------------------------> >+ <---------------------------------------------- 230 >+ >+Note 1: the order of the PBSZ/PROT pair and the USER/PASS pair (with >+respect to each other) is not important (i.e. the USER/PASS can happen >+prior to the PBSZ/PROT - or indeed the server can refuse to allow a >+PBSZ/PROT pair until the USER/PASS pair has happened). >+ >+Note 2: the PASS command might not be required at all (if the USER >+parameter and any client identity presented provide sufficient >+authentication). The server would indicate this by issuing a '232' >+reply to the USER command instead of the '331' which requests a PASS >+from the client. >+ >+Note 3: the AUTH command might not be the first command after the >+receipt of the 220 welcome message. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 15] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ 11.2. A standard data transfer without protection. >+ >+ Client Server >+ control data data control >+==================================================================== >+ >+ socket() >+ bind() >+ PORT w,x,y,z,a,b -----------------------------------------> >+ <----------------------------------------------------- 200 >+ STOR file ------------------------------------------------> >+ socket() >+ bind() >+ <----------------------------------------------------- 150 >+ accept() <----------- connect() >+ write() -----------> read() >+ close() -----------> close() >+ <----------------------------------------------------- 226 >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 16] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ 11.3. A firewall-friendly data transfer without protection >+ >+ Client Server >+ control data data control >+==================================================================== >+ >+ PASV --------------------------------------------------------> >+ socket() >+ bind() >+ <------------------------------------------ 227 (w,x,y,z,a,b) >+ socket() >+ STOR file ---------------------------------------------------> >+ connect() ----------> accept() >+ <-------------------------------------------------------- 150 >+ write() ----------> read() >+ close() ----------> close() >+ <-------------------------------------------------------- 226 >+ >+ >+ Note: Implementors should be aware that then connect()/accept() >+ function is performed prior to the receipt of the reply from the >+ STOR command. This contrasts with situation when (non-firewall- >+ friendly) PORT is used prior to the STOR, and the accept()/connect() >+ is performed after the reply from the aforementioned STOR has been >+ dealt with. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 17] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ 11.4. A standard data transfer with protection >+ >+ Client Server >+ control data data control >+==================================================================== >+ >+ socket() >+ bind() >+ PORT w,x,y,z,a,b --------------------------------------------> >+ <-------------------------------------------------------- 200 >+ STOR file ---------------------------------------------------> >+ socket() >+ bind() >+ <-------------------------------------------------------- 150 >+ accept() <---------- connect() >+ TLSneg() <----------> TLSneg() >+ TLSwrite() ----------> TLSread() >+ TLSshutdown() -------> TLSshutdown() >+ close() ----------> close() >+ <-------------------------------------------------------- 226 >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 18] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ 11.5. A firewall-friendly data transfer with protection >+ >+ Client Server >+ control data data control >+==================================================================== >+ >+ PASV --------------------------------------------------------> >+ socket() >+ bind() >+ <------------------------------------------ 227 (w,x,y,z,a,b) >+ socket() >+ STOR file ---------------------------------------------------> >+ connect() ----------> accept() >+ <-------------------------------------------------------- 150 >+ TLSneg() <---------> TLSneg() >+ TLSwrite() ---------> TLSread() >+ TLSshutdown() -------> TLSshutdown() >+ close() ---------> close() >+ <-------------------------------------------------------- 226 >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 19] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+12. Discussion of the REIN command >+ >+ The REIN command, defined in [RFC-959], allows the user to reset the >+ state of the FTP session. From [RFC-959]: >+ REINITIALIZE (REIN) >+ This command terminates a USER, flushing all I/O and account >+ information, except to allow any transfer in progress to be >+ completed. All parameters are reset to the default settings >+ and the control connection is left open. This is identical to >+ the state in which a user finds himself immediately after the >+ control connection is opened. A USER command may be expected >+ to follow. >+ When this command is processed by the server, the TLS session(s) >+ MUST be cleared and the control and data connections revert to >+ unprotected, clear communications. It MAY be acceptable to use >+ cached TLS sessions for subsequent connections, however a server MUST >+ not mandate this. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 20] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+13. Discussion of the STAT and ABOR commands >+ >+ The ABOR and STAT commands and the use of TCP Urgent Pointers >+ >+ [RFC-959] describes the use of Telnet commands (IP and DM) and the >+ TCP Urgent pointer to indicate the transmission of commands on the >+ control channel during the execution of a data transfer. FTP uses >+ the Telnet Interrupt Process and Data Mark commands in conjunction >+ with Urgent data to preface two commands: ABOR (Abort Transfer) >+ and STAT (Status request). >+ >+ The Urgent Pointer was used because in a Unix implementation the >+ receipt of a TCP packet marked as Urgent would result in the the >+ execution of the SIGURG interrupt handler. This reliance on >+ interrupt handlers was necessary on systems which did not >+ implement select() or did not support multiple threads. TLS does >+ not support the notion of Urgent data. >+ >+ When TLS is implemented as a security method in FTP the server >+ SHOULD NOT rely on the use of SIGURG to process input on the >+ control channel during data transfers. The client MUST send all >+ data including Telnet commands across the TLS session. The TLS >+ session will be corrupted if any data is sent on a socket while >+ TLS is active. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 21] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+14. Security Considerations >+ >+ This entire document deals with security considerations related to >+ the File Transfer Protocol. >+ >+ 14.1. Verification of Authentication tokens >+ >+ 14.1.1. Server Certificates >+ >+ Although it is entirely an implementation decision, it is >+ recommended that certificates used for server authentication of >+ the TLS session contain the server identification information >+ in a similar manner to those used for http servers. (see >+ [RFC-2818]) >+ >+ Similarly, it is recommended that the certificate used for >+ server authentication of Data connections is the same >+ certificate as that used for the corresponding Control >+ connection. >+ >+ 14.1.2. Client Certificates >+ >+ - Deciding which client certificates to allow and defining >+ which fields define what authentication information is entirely >+ a server implementation issue. >+ >+ - It is also server implementation issue to decide if the >+ authentication token presented for the data connection must >+ match the one used for the corresponding control connection. >+ >+ 14.2. Addressing FTP Security Considerations [RFC-2577] >+ >+ 14.2.1. Bounce Attack >+ >+ A bounce attack should be harder in a secured FTP environment >+ because: >+ >+ - The FTP server that is being used to initiate a false >+ connection will always be a 'server' in the TLS context. >+ Therefore, only services that act as 'clients' in the TLS >+ context could be vulnerable. This would be a counter- >+ intuitive way to implement TLS on a service. >+ >+ - The FTP server would detect that the authentication >+ credentials for the data connection are not the same as >+ those for the control connection, thus the server policies >+ COULD be set to drop the data connection. >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 22] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ - Genuine users are less likely to initiate such attacks >+ when the authentication is strong and malicious users are >+ less likely to gain access to the FTP server if the >+ authentication is not easily subverted (password guessing, >+ network tracing, etc...) >+ >+ 14.2.2. Restricting Access >+ >+ This document presents a strong mechanism for solving the issue >+ raised in this section. >+ >+ 14.2.3. Protecting Passwords >+ >+ The twin solutions of strong authentication and data >+ confidentiality ensure that this is not an issue when TLS is >+ used to protect the control session. >+ >+ 14.2.4. Privacy >+ >+ The TLS protocol ensures data confidentiality by encryption. >+ Privacy (e.g. access to download logs, user profile >+ information, etc...) is outside the scope of this document (and >+ [RFC-2577] presumably) >+ >+ 14.2.5. Protecting Usernames >+ >+ This is not an issue when TLS is used as the primary >+ authentication mechanism. >+ >+ 14.2.6. Port Stealing >+ >+ This proposal will do little for the Denial of Service element >+ of this section, however, strong authentication on the data >+ connection will prevent unauthorised connections retrieving or >+ submitting files. >+ >+ 14.2.7. Software-Base Security Problems >+ >+ Nothing in this proposal will affect the discussion in this >+ section. >+ >+ >+15. IANA Considerations >+ >+ {FTP-PORT} - The port assigned to the FTP control connection is 21. >+ >+16. Other Parameters >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 23] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ {TLS-PARM} - The parameter for the AUTH command to indicate that TLS >+ is required. To request the TLS protocol in accordance with this >+ document, the client MUST use 'TLS' >+ >+ To maintain backward compatability with older versions of this >+ document, the server SHOULD accept 'TLS-C' as a synonym for 'TLS' >+ >+ Note - [RFC-2228] states that these parameters are case- >+ insensitive. >+ >+ >+17. Network Management >+ >+ NONE >+ >+ >+18. Internationalization >+ >+ NONE >+ >+ >+19. Scalability & Limits >+ >+ There are no issues other than those concerned with the ability of >+ the server to refuse to have a complete TLS negotiation for each and >+ every data connection, which will allow servers to retain throughput >+ whilst using cycles only when necessary. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 24] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+20. Applicability >+ >+ This mechanism is generally applicable as a mechanism for securing >+ the FTP protocol. It is unlikely that anonymous FTP clients or >+ servers will require such security (although some might like the >+ authentication features without the confidentiality). >+ >+ >+21. Acknowledgements >+ >+ o Netscape Communications Corporation for the original SSL protocol. >+ >+ o Eric Young for the SSLeay libraries. >+ >+ o University of California, Berkley for the original implementations >+ of FTP and ftpd on which the initial implementation of these >+ extensions were layered. >+ >+ o IETF CAT working group. >+ >+ o IETF TLS working group. >+ >+ o IETF FTPEXT working group. >+ >+ o Jeff Altman for the ABOR and STAT discussion. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 25] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+22. References >+ >+ [RFC-959] J. Postel, "File Transfer Protocol" >+ RFC 959, October 1985. >+ >+ [RFC-1579] S. Bellovin, "Firewall-Friendly FTP" >+ RFC 1579, February 1994. >+ >+ [RFC-2119] S. Bradner, "Key words for use in RFCs to Indicate >+ Requirement Levels" >+ RFC 2119, March 1997. >+ >+ [RFC-2222] J. Myers, "Simple Authentication and Security Layer" >+ RFC 2222, October 1997. >+ >+ [RFC-2228] M. Horowitz, S. Lunt, "FTP Security Extensions" >+ RFC 2228, October 1997. >+ >+ [RFC-2246] T. Dierks, C. Allen, "The TLS Protocol Version 1.0" >+ RFC 2246, January 1999. >+ >+ [RFC-2389] P Hethmon, R.Elz, "Feature Negotiation Mechanism for the >+ File Transfer Protocol" >+ RFC 2389, August 1998. >+ >+ [RFC-2487] P Hoffman, "SMTP Service Extension for Secure SMTP over >+ TLS" >+ RFC 2487, January 1999. >+ >+ [RFC-2577] M Allman, S Ostermann, "FTP Security Considerations" >+ RFC 2577, May 1999. >+ >+ [RFC-2817] R. Khare, S. Lawrence, "Upgrading to TLS Within HTTP/1.1" >+ RFC 2817, May 2000. >+ >+ [RFC-2818] E. Rescorla, "HTTP Over TLS" >+ RFC 2818, May 2000. >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 26] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+23. Authors' Contact Addresses >+ >+The FTP-TLS draft information site is at http://www.ford- >+hutchinson.com/~fh-1-pfh/ftps-ext.html >+ >+ >+Please send comments to Paul Ford-Hutchinson at the address below >+ >+ Tim Hudson Paul Ford-Hutchinson >+ RSA Data Security IBM UK Ltd >+ Australia Pty Ltd PO Box 31 >+ Birmingham Road >+ Warwick >+ United Kingdom >+ tel - +61 7 3227 4444 +44 1926 462005 >+ fax - +61 7 3227 4400 +44 1926 496482 >+email - tjh@rsasecurity.com.au paulfordh@uk.ibm.com >+ >+ Martin Carpenter Eric Murray >+ Verisign Ltd Wave Systems Inc. >+email - mcarpenter@verisign.com ericm@lne.com >+ >+ Volker Wiegand >+ SuSE Linux >+email - wiegand@suse.de >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 27] >+ >+ >+ >+ >+ >+Internet-Draft Secure FTP using TLS 2nd April, 2002 >+ >+ >+ The IETF takes no position regarding the validity or scope of any >+ intellectual property or other rights that might be claimed to >+ pertain to the implementation or use of the technology described in >+ this document or the extent to which any license under such rights >+ might or might not be available; neither does it represent that it >+ has made any effort to identify any such rights. Information on the >+ IETF's procedures with respect to rights in standards-track and >+ standards-related documentation can be found in BCP-11. Copies of >+ claims of rights made available for publication and any assurances of >+ licenses to be made available, or the result of an attempt made to >+ obtain a general license or permission for the use of such >+ proprietary rights by implementors or users of this specification can >+ be obtained from the IETF Secretariat. >+ >+ The IETF invites any interested party to bring to its attention any >+ copyrights, patents or patent applications, or other proprietary >+ rights which may cover technology that may be required to practice >+ this standard. Please address the information to the IETF Executive >+ Director. >+ >+Copyright (C) The Internet Society (2002). All Rights Reserved. >+ >+ This document and translations of it may be copied and furnished to >+ others, and derivative works that comment on or otherwise explain it >+ or assist in its implementation may be prepared, copied, published >+ and distributed, in whole or in part, without restriction of any >+ kind, provided that the above copyright notice and this paragraph are >+ included on all such copies and derivative works. However, this >+ document itself may not be modified in any way, such as by removing >+ the copyright notice or references to the Internet Society or other >+ Internet organizations, except as needed for the purpose of >+ developing Internet standards in which case the procedures for >+ copyrights defined in the Internet Standards process must be >+ followed, or as required to translate it into languages other than >+ English. >+ >+ The limited permissions granted above are perpetual and will not be >+ revoked by the Internet Society or its successors or assigns. >+ >+ This document and the information contained herein is provided on an >+ "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING >+ TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING >+ BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION >+ HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF >+ MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. >+ >+This document expires on 2nd October, 2002 >+ >+ >+ >+ >+Ford-Hutchinson, Carpenter, Hudson, Murray & Wiegand FORMFEED[Page 28] >+ >diff -urN proftpd-1.2.6rc1.orig/include/conf.h proftpd-1.2.6rc1-tls/include/conf.h >--- proftpd-1.2.6rc1.orig/include/conf.h Tue Jun 25 19:35:14 2002 >+++ proftpd-1.2.6rc1-tls/include/conf.h Wed Jul 3 10:54:31 2002 >@@ -33,6 +33,10 @@ > > #include "version.h" > #include "config.h" >+#if defined(TLS) && defined(HAVE_SENDFILE) >+/* using sendfile() together with TLS breaks things! */ >+#undef HAVE_SENDFILE >+#endif > > #include "default_paths.h" > >diff -urN proftpd-1.2.6rc1.orig/include/ftp.h proftpd-1.2.6rc1-tls/include/ftp.h >--- proftpd-1.2.6rc1.orig/include/ftp.h Fri May 10 18:52:39 2002 >+++ proftpd-1.2.6rc1-tls/include/ftp.h Mon Jun 10 11:56:48 2002 >@@ -102,6 +102,7 @@ > #define R_226 "226" /* Closing data connection. File transfer/abort successful */ > #define R_227 "227" /* Entering passive mode (h1,h2,h3,h4,p1,p2) */ > #define R_230 "230" /* User logged in, proceed */ >+#define R_232 "232" /* User logged in, authorized by security data exchange */ > #define R_250 "250" /* Requested file action okay, completed. */ > #define R_257 "257" /* "PATHNAME" created. */ > #define R_331 "331" /* User name okay, need password. */ >@@ -110,6 +111,7 @@ > #define R_421 "421" /* Service not available, closing control connection (service is about to be shutdown) */ > #define R_425 "425" /* Can't open data connection */ > #define R_426 "426" /* Connection closed; transfer aborted */ >+#define R_431 "431" /* Can't accept specified protection level, maybe some resource unavailable */ > #define R_450 "450" /* Requested file action not taken (file unavailable; busy) */ > #define R_451 "451" /* Requested action aborted; local error in processing */ > #define R_452 "452" /* Requested action not taken; insufficient storage space */ >@@ -120,6 +122,8 @@ > #define R_504 "504" /* Command not implemented for that parameter */ > #define R_530 "530" /* Not logged in */ > #define R_532 "532" /* Need account for storing files */ >+#define R_534 "534" /* Request denied for policy reasons */ >+#define R_536 "536" /* Current security mechanism doesn't support the specified protection level */ > #define R_550 "550" /* Requested action not taken. No access, etc */ > #define R_551 "551" /* Requested action not taken, page type unknown */ > #define R_552 "552" /* Requested file action aborted, exceeding storage allocation */ >diff -urN proftpd-1.2.6rc1.orig/include/io.h proftpd-1.2.6rc1-tls/include/io.h >--- proftpd-1.2.6rc1.orig/include/io.h Tue Jul 2 19:01:47 2002 >+++ proftpd-1.2.6rc1-tls/include/io.h Wed Jul 3 10:54:31 2002 >@@ -32,6 +32,10 @@ > #ifndef __IO_H > #define __IO_H > >+#ifdef TLS >+#include <openssl/ssl.h> >+#endif >+ > #define IO_READ 0 > #define IO_WRITE 1 > >@@ -81,6 +85,9 @@ > IOBUF *buf; > IOREQ *req; /* Request buffer */ > int bufsize; /* Default size of request buffer */ >+#ifdef TLS >+ SSL *tls_session; /* OpenSSL SSL pointer */ >+#endif > }; > > struct IO_Buffer { >diff -urN proftpd-1.2.6rc1.orig/include/tls_dh.h proftpd-1.2.6rc1-tls/include/tls_dh.h >--- proftpd-1.2.6rc1.orig/include/tls_dh.h Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/include/tls_dh.h Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,187 @@ >+static unsigned char dh512_p[]={ >+ 0xC0,0xC5,0x23,0x8D,0x3A,0xB3,0xA3,0x63,0x57,0xC0,0xD3,0xFE, >+ 0xD4,0xC2,0x8F,0x17,0x0E,0x7A,0xDB,0x8E,0x3B,0xB6,0xA5,0xC2, >+ 0x60,0x7D,0xE7,0x03,0xCC,0xA3,0x10,0xCC,0x82,0x39,0x3C,0x68, >+ 0xA0,0x82,0x9C,0x7A,0x4A,0x96,0x8C,0xB0,0x1A,0xB4,0xB8,0xA0, >+ 0x9E,0x64,0x9D,0x40,0x77,0x8A,0x9C,0x97,0x96,0x69,0x3D,0xCA, >+ 0xA8,0x25,0xAE,0xAB, >+ }; >+static unsigned char dh512_g[]={ >+ 0x02, >+ }; >+ >+DH *get_dh512() >+ { >+ DH *dh; >+ >+ if ((dh=DH_new()) == NULL) return(NULL); >+ dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); >+ dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); >+ if ((dh->p == NULL) || (dh->g == NULL)) >+ return(NULL); >+ return(dh); >+ } >+/* >+-----BEGIN DH PARAMETERS----- >+MEYCQQDAxSONOrOjY1fA0/7Uwo8XDnrbjju2pcJgfecDzKMQzII5PGiggpx6SpaM >+sBq0uKCeZJ1Ad4qcl5ZpPcqoJa6rAgEC >+-----END DH PARAMETERS----- >+*/ >+static unsigned char dh768_p[]={ >+ 0xB3,0x95,0x74,0xCE,0x0B,0xFD,0xAB,0xC3,0x53,0x9B,0x0B,0xFD, >+ 0x6E,0xB2,0x64,0x64,0x02,0xDD,0xFF,0x2E,0x77,0xEB,0x0D,0x6C, >+ 0xCE,0x04,0x2C,0x8E,0x5A,0xA7,0x96,0x45,0x54,0xA6,0x2F,0xBC, >+ 0xF9,0x77,0x1C,0x50,0x66,0x8E,0x48,0xA8,0x34,0xF0,0x81,0xDD, >+ 0x5B,0x5A,0xD4,0xA6,0x13,0x89,0x60,0x46,0x05,0x65,0x57,0x2C, >+ 0x1E,0x94,0x57,0x3C,0x3E,0x38,0xA6,0xFE,0x7B,0x03,0x7D,0x16, >+ 0x46,0xF6,0xB3,0x21,0x3C,0x44,0xF1,0xF1,0x90,0xCE,0x40,0x93, >+ 0x4B,0xE6,0xD6,0x0E,0x20,0x85,0xDA,0x9B,0x3F,0x5C,0x1F,0xDB, >+ }; >+static unsigned char dh768_g[]={ >+ 0x02, >+ }; >+ >+DH *get_dh768() >+ { >+ DH *dh; >+ >+ if ((dh=DH_new()) == NULL) return(NULL); >+ dh->p=BN_bin2bn(dh768_p,sizeof(dh768_p),NULL); >+ dh->g=BN_bin2bn(dh768_g,sizeof(dh768_g),NULL); >+ if ((dh->p == NULL) || (dh->g == NULL)) >+ return(NULL); >+ return(dh); >+ } >+/* >+-----BEGIN DH PARAMETERS----- >+MGYCYQCzlXTOC/2rw1ObC/1usmRkAt3/LnfrDWzOBCyOWqeWRVSmL7z5dxxQZo5I >+qDTwgd1bWtSmE4lgRgVlVywelFc8Pjim/nsDfRZG9rMhPETx8ZDOQJNL5tYOIIXa >+mz9cH9sCAQI= >+-----END DH PARAMETERS----- >+*/ >+static unsigned char dh1024_p[]={ >+ 0xC1,0xD8,0x9C,0x90,0xB1,0x58,0x7C,0xE1,0x56,0x70,0xD7,0x61, >+ 0x6C,0x00,0xE6,0xE7,0x99,0x04,0x9F,0x86,0xD9,0xB4,0x11,0x09, >+ 0x23,0x18,0xAA,0x19,0xCA,0x49,0x7C,0xA8,0x9D,0xF7,0x43,0x3A, >+ 0xAF,0xC3,0x1F,0x0E,0xAE,0xBB,0xF2,0xEA,0x5B,0x62,0xA1,0x5F, >+ 0x7C,0x26,0xA8,0xB4,0x5D,0x2A,0x25,0xAB,0x88,0x70,0x27,0x06, >+ 0xD0,0xF5,0x01,0xD9,0x6A,0x1F,0x48,0x2D,0x9C,0xEC,0xFE,0xA8, >+ 0x45,0x97,0x1D,0xC0,0x8A,0xFF,0xE5,0xE1,0x79,0xDF,0x85,0x31, >+ 0xFC,0x58,0x91,0x35,0xE8,0xC7,0xDA,0x55,0x7B,0xAA,0xDD,0xC2, >+ 0x0A,0x94,0x34,0xF7,0xB4,0x4A,0x91,0x3B,0x1E,0x16,0x89,0x2A, >+ 0x04,0x47,0x5D,0xE9,0x42,0x47,0x5E,0x30,0x61,0xE8,0x42,0xC1, >+ 0x23,0xC7,0x97,0x78,0x63,0x36,0x9D,0x3B, >+ }; >+static unsigned char dh1024_g[]={ >+ 0x02, >+ }; >+ >+DH *get_dh1024() >+ { >+ DH *dh; >+ >+ if ((dh=DH_new()) == NULL) return(NULL); >+ dh->p=BN_bin2bn(dh1024_p,sizeof(dh1024_p),NULL); >+ dh->g=BN_bin2bn(dh1024_g,sizeof(dh1024_g),NULL); >+ if ((dh->p == NULL) || (dh->g == NULL)) >+ return(NULL); >+ return(dh); >+ } >+/* >+-----BEGIN DH PARAMETERS----- >+MIGHAoGBAMHYnJCxWHzhVnDXYWwA5ueZBJ+G2bQRCSMYqhnKSXyonfdDOq/DHw6u >+u/LqW2KhX3wmqLRdKiWriHAnBtD1AdlqH0gtnOz+qEWXHcCK/+Xhed+FMfxYkTXo >+x9pVe6rdwgqUNPe0SpE7HhaJKgRHXelCR14wYehCwSPHl3hjNp07AgEC >+-----END DH PARAMETERS----- >+*/ >+static unsigned char dh1536_p[]={ >+ 0xDA,0x68,0x25,0x7F,0x9D,0xB5,0x3F,0x42,0x05,0xBC,0x79,0x65, >+ 0x6F,0x19,0x6A,0x6F,0x70,0x11,0x91,0xF2,0x08,0x48,0x2B,0xE2, >+ 0x0C,0x15,0xD9,0x31,0xE7,0x3A,0x50,0x32,0x9F,0xFB,0xD6,0x56, >+ 0xFA,0xB4,0xA9,0x5F,0x22,0x17,0x52,0x72,0x2C,0xE3,0x5D,0xA1, >+ 0xA8,0xEF,0x16,0x42,0x35,0xC6,0xD9,0x64,0xC1,0xB3,0xB3,0x4C, >+ 0x09,0x90,0xF4,0x49,0xEF,0xDE,0x64,0x99,0xFF,0x3C,0x37,0x0A, >+ 0x91,0xA4,0x9E,0x38,0x27,0xF2,0x96,0x13,0x1E,0x15,0xA2,0x52, >+ 0xF1,0x54,0x0C,0xED,0x5C,0x38,0xC4,0xEC,0xFF,0xE2,0xFA,0x0A, >+ 0x41,0xBB,0x48,0x5D,0xD3,0x54,0xA1,0xEB,0xBD,0x1F,0x68,0xED, >+ 0x2A,0x49,0x7F,0x68,0x52,0xB3,0xA0,0x77,0x3E,0x19,0xFB,0x44, >+ 0xCD,0x4B,0x21,0x3E,0x3B,0xBA,0xF6,0xA2,0x36,0x37,0xE5,0xFA, >+ 0x95,0xB0,0x7D,0x7B,0x58,0x96,0xC4,0xC9,0xC0,0xCF,0xD9,0x3F, >+ 0xA3,0x42,0x0B,0xD7,0xBE,0x1A,0xA8,0xB5,0x57,0x58,0xF4,0x04, >+ 0x97,0x54,0xB0,0x59,0x23,0x5F,0x98,0x09,0x90,0xC0,0x49,0x85, >+ 0x40,0x23,0x2D,0x21,0x3E,0xB0,0x07,0x06,0x07,0x32,0xFB,0xB9, >+ 0x91,0x40,0x92,0x09,0xED,0x07,0x80,0x05,0x14,0x5B,0xC1,0x9B, >+ }; >+static unsigned char dh1536_g[]={ >+ 0x02, >+ }; >+ >+DH *get_dh1536() >+ { >+ DH *dh; >+ >+ if ((dh=DH_new()) == NULL) return(NULL); >+ dh->p=BN_bin2bn(dh1536_p,sizeof(dh1536_p),NULL); >+ dh->g=BN_bin2bn(dh1536_g,sizeof(dh1536_g),NULL); >+ if ((dh->p == NULL) || (dh->g == NULL)) >+ return(NULL); >+ return(dh); >+ } >+/* >+-----BEGIN DH PARAMETERS----- >+MIHHAoHBANpoJX+dtT9CBbx5ZW8Zam9wEZHyCEgr4gwV2THnOlAyn/vWVvq0qV8i >+F1JyLONdoajvFkI1xtlkwbOzTAmQ9Env3mSZ/zw3CpGknjgn8pYTHhWiUvFUDO1c >+OMTs/+L6CkG7SF3TVKHrvR9o7SpJf2hSs6B3Phn7RM1LIT47uvaiNjfl+pWwfXtY >+lsTJwM/ZP6NCC9e+Gqi1V1j0BJdUsFkjX5gJkMBJhUAjLSE+sAcGBzL7uZFAkgnt >+B4AFFFvBmwIBAg== >+-----END DH PARAMETERS----- >+*/ >+static unsigned char dh2048_p[]={ >+ 0xD0,0xE6,0xFF,0x1F,0x39,0xE0,0xCC,0x85,0xAC,0xA4,0xE6,0xDD, >+ 0x06,0xE5,0x2D,0xBF,0xEA,0x64,0x2E,0xC7,0x99,0x8A,0x0F,0xCB, >+ 0x3C,0x9D,0xEE,0xAC,0x61,0xFF,0x69,0x31,0x71,0xFE,0x2F,0x7B, >+ 0x65,0x95,0xA0,0xA4,0x59,0xB8,0xE3,0x66,0x5B,0x3F,0xD8,0x42, >+ 0x99,0x4F,0x09,0x44,0xC5,0x8D,0x8B,0x5D,0x16,0xAA,0x05,0x6E, >+ 0x8B,0x11,0x59,0x1F,0xD7,0x11,0x84,0x87,0x4D,0xBE,0xBB,0xBA, >+ 0x9A,0xF0,0xC3,0xE2,0x0E,0xB8,0x0F,0xFD,0x08,0xB1,0x48,0x98, >+ 0xDE,0x89,0xDA,0x00,0x15,0x04,0xA4,0x51,0xBE,0x5B,0x60,0x0A, >+ 0x0E,0x20,0xAC,0xC5,0x83,0x5D,0xC4,0x0F,0xA3,0x8E,0x11,0x66, >+ 0x2C,0xD3,0x61,0x5F,0x16,0x83,0xAA,0xCF,0x52,0x9C,0x7D,0x75, >+ 0xEA,0xCA,0x67,0xA3,0xAB,0x58,0x9F,0x67,0x17,0xA0,0x54,0x3A, >+ 0x2B,0xCA,0xB5,0x03,0x7E,0x50,0xBD,0x99,0x1E,0xEF,0xB2,0x8F, >+ 0xB4,0xFB,0xD2,0x2D,0x6A,0xA9,0xA2,0xC0,0xD4,0xD2,0x68,0x6C, >+ 0x21,0x71,0x78,0x75,0x82,0x4C,0xD8,0xE8,0x2C,0x0B,0xC9,0x3F, >+ 0xF6,0xF0,0x64,0xD9,0x6E,0x76,0xCB,0xBB,0x99,0xFB,0xBC,0x15, >+ 0x54,0x7B,0x7F,0x97,0x36,0x8F,0x0B,0x1C,0xFF,0xDD,0x28,0x99, >+ 0xE5,0x3A,0xAD,0xCD,0x84,0xAB,0xA1,0xEF,0xB2,0x21,0xEA,0xD6, >+ 0x49,0x22,0x6A,0x30,0x6A,0x63,0x2E,0x52,0x79,0xCF,0xBC,0xC2, >+ 0xB6,0x2E,0xA5,0x5D,0xB3,0xDA,0xC2,0xDD,0x02,0xEA,0x26,0x2F, >+ 0x3B,0x0A,0x12,0xBB,0xA2,0xEF,0x2B,0xFA,0xCC,0x25,0x63,0x1B, >+ 0xC3,0x00,0x18,0x8F,0x36,0xB7,0x30,0x5A,0x55,0x1A,0xE0,0x12, >+ 0xA1,0xD2,0x9C,0x93, >+ }; >+static unsigned char dh2048_g[]={ >+ 0x02, >+ }; >+ >+DH *get_dh2048() >+ { >+ DH *dh; >+ >+ if ((dh=DH_new()) == NULL) return(NULL); >+ dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL); >+ dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL); >+ if ((dh->p == NULL) || (dh->g == NULL)) >+ return(NULL); >+ return(dh); >+ } >+/* >+-----BEGIN DH PARAMETERS----- >+MIIBCAKCAQEA0Ob/HzngzIWspObdBuUtv+pkLseZig/LPJ3urGH/aTFx/i97ZZWg >+pFm442ZbP9hCmU8JRMWNi10WqgVuixFZH9cRhIdNvru6mvDD4g64D/0IsUiY3ona >+ABUEpFG+W2AKDiCsxYNdxA+jjhFmLNNhXxaDqs9SnH116spno6tYn2cXoFQ6K8q1 >+A35QvZke77KPtPvSLWqposDU0mhsIXF4dYJM2OgsC8k/9vBk2W52y7uZ+7wVVHt/ >+lzaPCxz/3SiZ5TqtzYSroe+yIerWSSJqMGpjLlJ5z7zCti6lXbPawt0C6iYvOwoS >+u6LvK/rMJWMbwwAYjza3MFpVGuASodKckwIBAg== >+-----END DH PARAMETERS----- >+*/ >diff -urN proftpd-1.2.6rc1.orig/include/tlsutil.h proftpd-1.2.6rc1-tls/include/tlsutil.h >--- proftpd-1.2.6rc1.orig/include/tlsutil.h Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/include/tlsutil.h Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,65 @@ >+/* >+ * Copyright (c) 1999 - 2002 Peter 'Luna' Runestig <peter@runestig.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without modifi- >+ * cation, are permitted provided that the following conditions are met: >+ * >+ * o Redistributions of source code must retain the above copyright notice, >+ * this list of conditions and the following disclaimer. >+ * >+ * o Redistributions in binary form must reproduce the above copyright no- >+ * tice, this list of conditions and the following disclaimer in the do- >+ * cumentation and/or other materials provided with the distribution. >+ * >+ * o The names of the contributors may not be used to endorse or promote >+ * products derived from this software without specific prior written >+ * permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI- >+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- >+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- >+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- >+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef _TLSUTIL_H_ >+#define _TLSUTIL_H_ >+ >+extern int tls_on_data; >+extern int tls_on_ctrl; >+extern int tls_implicit; >+extern int tls_no_verify; >+extern int tls_dont_request_cert; >+extern int tls_required; >+extern int tls_init_error; >+extern char *tls_rsa_key_file; >+extern char *tls_rsa_cert_file; >+extern char *tls_dsa_key_file; >+extern char *tls_dsa_cert_file; >+extern char *tls_crl_file; >+extern char *tls_dhparam_file; >+extern char *tls_cipher_list; >+ >+int tls_init(void); >+int tls_accept(conn_t *conn, int data_connection); >+void tls_cleanup(void); >+void tls_close_session(SSL *ssl); >+int tls_recv(int s, void *buf, size_t len, int flags); >+int tls_send(int s, const void *msg, size_t len, int flags); >+ssize_t tls_read(SSL *ssl, void *buf, size_t count); >+ssize_t tls_write(SSL *ssl, const void *buf, size_t count); >+int tls_pending(SSL *ssl); >+void tls_optarg(char *optarg); >+char *tls_userid_from_client_cert(); >+int tls_is_user_valid(char *user); >+void tls_set_file_defaults(void); >+int tls_setup_session_cache(void); >+ >+ >+#endif >diff -urN proftpd-1.2.6rc1.orig/modules/mod_auth.c proftpd-1.2.6rc1-tls/modules/mod_auth.c >--- proftpd-1.2.6rc1.orig/modules/mod_auth.c Thu Jun 27 09:31:54 2002 >+++ proftpd-1.2.6rc1-tls/modules/mod_auth.c Wed Jul 3 11:04:48 2002 >@@ -67,6 +67,12 @@ > return 0; > } > >+#ifdef TLS >+static int tls_logged_in = 0; >+MODRET cmd_pass(cmd_rec *cmd); >+#include "tlsutil.h" >+#endif >+ > /* check_auth is hooked into the main server's auth_hook function, > * so that we can deny all commands until authentication is complete. > */ >@@ -173,6 +179,11 @@ > char *cpw = NULL; > config_rec *c; > >+#ifdef TLS >+ if (tls_logged_in) >+ return 0; >+#endif >+ > if (conf) { > c = find_config(conf,CONF_PARAM,"UserPassword",FALSE); > >@@ -1015,6 +1026,12 @@ > if(c && c->subset) > resolve_anonymous_dirs(c->subset); > >+#if TLS >+ if (tls_logged_in) >+ log_auth(LOG_NOTICE, "USER %s: TLS/X509 authentication login successful.", >+ origuser); >+ else >+#endif /* TLS */ > log_auth(LOG_NOTICE, "%s %s: Login successful.", > (c != NULL) ? "ANON" : "USER", > origuser); >@@ -1573,6 +1590,9 @@ > config_rec *c; > char *user, *origuser; > int failnopwprompt = 0, aclp, i; >+#ifdef TLS >+ char *tls_user = NULL; >+#endif > > if(logged_in) > return ERROR_MSG(cmd,R_503,"You are already logged in!"); >@@ -1580,6 +1600,12 @@ > if(cmd->argc < 2) > return ERROR_MSG(cmd,R_500,"'USER': command requires a parameter."); > >+#ifdef TLS >+ if (tls_required && !tls_on_ctrl) >+ return ERROR_MSG(cmd, R_534, >+ "Server policy denies USER command on insecure connection."); >+#endif >+ > user = cmd->arg; > > remove_config(cmd->server->conf, C_USER, FALSE); >@@ -1652,6 +1678,15 @@ > if(c && user && get_param_int(c->subset, "AnonRequirePassword", FALSE) != 1) > nopass++; > >+#ifdef TLS >+ tls_user = tls_userid_from_client_cert(); >+ if ((tls_user && !strcmp(user, tls_user)) || tls_is_user_valid(user)) { >+ /* user is X509-authenticated */ >+ tls_logged_in = 1; >+ return cmd_pass(cmd); >+ } >+#endif >+ > if(nopass) > add_response(R_331, "Anonymous login ok, send your complete email " > "address as your password."); >@@ -1680,7 +1715,8 @@ > char *display = NULL; > char *user, *grantmsg; > int res = 0; >- >+ char *reply_code = R_230; >+ > if(logged_in) > return ERROR_MSG(cmd, R_503, "You are already logged in!"); > >@@ -1695,6 +1731,10 @@ > > _auth_check_count(cmd, user); > >+#ifdef TLS >+ if (tls_logged_in) >+ reply_code = R_232; >+#endif > if((res = _setup_environment(cmd->tmp_pool,user,cmd->arg)) == 1) { > add_config_param_set(&cmd->server->conf,"authenticated",1,(void*)1); > set_auth_check(NULL); >@@ -1713,21 +1753,21 @@ > "DisplayLogin", FALSE); > > if(display) >- core_display_file(R_230, display, NULL); >+ core_display_file(reply_code, display, NULL); > > if ((grantmsg = (char *)get_param_ptr((session.anon_config ? > session.anon_config->subset : cmd->server->conf), > "AccessGrantMsg",FALSE)) != NULL) { > grantmsg = sreplace(cmd->tmp_pool, grantmsg, "%u", user, NULL); > >- add_response(R_230, "%s", grantmsg); >+ add_response(reply_code, "%s", grantmsg); > > } else { > > if (session.flags & SF_ANON) > add_response(R_230, "Anonymous access granted, restrictions apply."); > else >- add_response(R_230, "User %s logged in.", user); >+ add_response(reply_code, "User %s logged in.", user); > } > > logged_in = 1; >diff -urN proftpd-1.2.6rc1.orig/modules/mod_tls.c proftpd-1.2.6rc1-tls/modules/mod_tls.c >--- proftpd-1.2.6rc1.orig/modules/mod_tls.c Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/modules/mod_tls.c Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,483 @@ >+/* >+ * ProFTPD - FTP server daemon >+ * Copyright (c) 1997, 1998 Public Flood Software >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it 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. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, write to the Free Software >+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. >+ */ >+/* >+ * AUTH/TLS module for ProFTPD, based on the mod_sample.c file. >+ * >+ * Copyright (c) 2000 - 2002 Peter 'Luna' Runestig <peter@runestig.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without modifi- >+ * cation, are permitted provided that the following conditions are met: >+ * >+ * o Redistributions of source code must retain the above copyright notice, >+ * this list of conditions and the following disclaimer. >+ * >+ * o Redistributions in binary form must reproduce the above copyright no- >+ * tice, this list of conditions and the following disclaimer in the do- >+ * cumentation and/or other materials provided with the distribution. >+ * >+ * o The names of the contributors may not be used to endorse or promote >+ * products derived from this software without specific prior written >+ * permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI- >+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- >+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- >+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- >+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "conf.h" >+#include <privs.h> >+#include "tlsutil.h" >+ >+extern session_t session; >+ >+#define CHECK_TLS_INIT_ERROR() if (tls_init_error) { \ >+ char errmsg[256]; \ >+ snprintf(errmsg, sizeof(errmsg), \ >+ "Local error code %d was returned from tls_init()", \ >+ tls_init_error); \ >+ return ERROR_MSG(cmd, R_431, errmsg); } >+ >+/* This sample configuration directive handler will get called >+ * whenever the "FooBarDirective" directive is encountered in the >+ * configuration file. >+ */ >+ >+MODRET set_rsacertfile(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ /* The CHECK_ARGS macro checks the number of arguments passed to the >+ * directive against what we want. Note that this is *one* less than >+ * cmd->argc, because cmd->argc includes cmd->argv[0] (the directive >+ * itself). If CHECK_ARGS fails, a generic error is sent to the user >+ */ >+ CHECK_ARGS(cmd, 1); >+ >+ /* The CHECK_CONF macro makes sure that this directive is not being >+ * "used" in the wrong context (i.e. if the directive is only available >+ * or applicable inside certain contexts). In this case, we are allowing >+ * the directive inside of <Anonymous> and <Limit>, but nowhere else. >+ * If this macro fails a generic error is logged and the handler aborts. >+ */ >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ /* add_config_param adds a configuration paramater to our current >+ * configuration context. >+ */ >+ c = add_config_param_str("TlsRsaCertFile", 1, cmd->argv[1]); >+ >+ /* By adding the CF_MERGEDOWN flag to the parameter we just created >+ * we are telling proftpd that this parameter should be copied and >+ * "merged" into all "lower" contexts until it either hits a >+ * parameter w/ the same name or bottoms out. >+ * >+ * Example _without_ CF_MERGEDOWN: >+ * >+ * <VirtualHost> >+ * |----------\ >+ * <Anonymous> >+ * | - FooBarDirective <------- Config places it here >+ * |-----------\ >+ * <Directory> <------- Doesn't apply here >+ * |-------------\ >+ * <Limit> <--- Or here..... >+ * >+ * Now, if we specify CF_MERGDOWN, the tree ends up looking like: >+ * >+ * <VirtualHost> >+ * |----------\ >+ * <Anonymous> >+ * | - FooBarDirective <------- Config places it here >+ * |-----------\ >+ * <Directory> <------- Now, it DOES apply here >+ * | - FooBarDirective >+ * |-------------\ >+ * <Limit> <-------- And here ... >+ * | - FooBarDirective >+ * >+ */ >+ c->flags |= CF_MERGEDOWN; >+ >+ /* Tell proftpd that we handled the request w/ no problems. >+ */ >+ return HANDLED(cmd); >+} >+ >+MODRET set_rsakeyfile(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ c = add_config_param_str("TlsRsaKeyFile", 1, cmd->argv[1]); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_dsacertfile(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ c = add_config_param_str("TlsDsaCertFile", 1, cmd->argv[1]); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_dsakeyfile(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ c = add_config_param_str("TlsDsaKeyFile", 1, cmd->argv[1]); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_crlfile(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ c = add_config_param_str("TlsCrlFile", 1, cmd->argv[1]); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_dhparamfile(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ c = add_config_param_str("TlsDhParamFile", 1, cmd->argv[1]); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_cipherlist(cmd_rec *cmd) >+{ >+ config_rec *c; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ c = add_config_param_str("TlsCipherList", 1, cmd->argv[1]); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_no_verify(cmd_rec *cmd) >+{ >+ config_rec *c; >+ int b; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ if ((b = get_boolean(cmd, 1)) == -1) >+ CONF_ERROR(cmd, "expected boolean argument."); >+ c = add_config_param("TlsCertsOk", 1, (void *) b); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_dont_request_cert(cmd_rec *cmd) >+{ >+ config_rec *c; >+ int b; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ if ((b = get_boolean(cmd, 1)) == -1) >+ CONF_ERROR(cmd, "expected boolean argument."); >+ c = add_config_param("TlsDontRequestCert", 1, (void *) b); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_required(cmd_rec *cmd) >+{ >+ config_rec *c; >+ int b; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ if ((b = get_boolean(cmd, 1)) == -1) >+ CONF_ERROR(cmd, "expected boolean argument."); >+ c = add_config_param("TlsRequired", 1, (void *) b); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET set_implicit(cmd_rec *cmd) >+{ >+ config_rec *c; >+ int b; >+ >+ CHECK_ARGS(cmd, 1); >+ CHECK_CONF(cmd, CONF_ROOT | CONF_VIRTUAL | CONF_GLOBAL); >+ >+ if ((b = get_boolean(cmd, 1)) == -1) >+ CONF_ERROR(cmd, "expected boolean argument."); >+ c = add_config_param("TlsImplicit", 1, (void *) b); >+ c->flags |= CF_MERGEDOWN; >+ return HANDLED(cmd); >+} >+ >+MODRET cmd_auth(cmd_rec *cmd) >+{ >+ char *cp; >+ >+ if (tls_implicit) >+ return ERROR_MSG(cmd, R_504, "The AUTH command is not supported on an implicit TLS connection"); >+ if (cmd->argc < 2) >+ return ERROR_MSG(cmd, R_504, "The AUTH command needs at least one argument"); >+ >+ /* convert to upper case */ >+ cp = cmd->argv[1]; >+ while (*cp) { >+ *cp = toupper(*cp); >+ cp++; >+ } >+ >+ if (!strcmp(cmd->argv[1], "TLS") || !strcmp(cmd->argv[1], "TLS-C")) { >+ CHECK_TLS_INIT_ERROR(); >+ send_response("234", "AUTH TLS successful"); >+ if (tls_accept(session.c, FALSE)) { >+ /* exit if we fail */ >+ send_response_async(R_421, >+ "Failed TLS negotiation on control channel, disconnected"); >+ main_exit((void*) LOG_ERR, >+ "Failed TLS negotiation on control channel, disconnected.", >+ (void*) 0, NULL); >+ } >+ } >+ else if (!strcmp(cmd->argv[1], "SSL") || !strcmp(cmd->argv[1], "TLS-P")) { >+ CHECK_TLS_INIT_ERROR(); >+ send_response("234", "AUTH SSL successful"); >+ if (tls_accept(session.c, FALSE)) { >+ /* exit if we fail */ >+ send_response_async(R_421, >+ "Failed TLS negotiation on control channel, disconnected"); >+ main_exit((void*) LOG_ERR, >+ "Failed TLS negotiation on control channel, disconnected.", >+ (void*) 0, NULL); >+ } >+ tls_on_data = 1; >+ } >+ else { >+ char errmsg[255]; >+ snprintf(errmsg, sizeof(errmsg), "AUTH %s unsupported", cmd->argv[1]); >+ return ERROR_MSG(cmd, R_504, errmsg); >+ } >+ >+ return HANDLED(cmd); >+} >+ >+static int pbsz_ok = 0; >+ >+MODRET cmd_pbsz(cmd_rec *cmd) >+{ >+ if (cmd->argc < 2) >+ return ERROR_MSG(cmd, R_501, "PBSZ command needs at least one argument"); >+ if (!tls_on_ctrl) >+ return ERROR_MSG(cmd, R_503, "You can't issue PBSZ on an insecure control connection"); >+ >+ /* we expect "PBSZ 0" */ >+ CHECK_TLS_INIT_ERROR(); >+ if (!strcmp(cmd->argv[1], "0")) >+ send_response("200", "PBSZ 0 successful"); >+ else >+ send_response("200", "PBSZ=0 successful"); >+ pbsz_ok = 1; >+ >+ return HANDLED(cmd); >+} >+ >+MODRET cmd_prot(cmd_rec *cmd) >+{ >+ if (cmd->argc < 2) >+ return ERROR_MSG(cmd, R_504, "PROT command needs at least one argument"); >+ if (!pbsz_ok) >+ return ERROR_MSG(cmd, R_503, "You must issue the PBSZ command prior to PROT"); >+ >+ /* only PROT C or PROT P is valid in respect to SSL/TLS */ >+ if (!strcmp(cmd->argv[1], "C")) { >+ CHECK_TLS_INIT_ERROR(); >+ send_response("200", "Protection set to Clear"); >+ tls_on_data = 0; >+ } >+ else if (!strcmp(cmd->argv[1], "P")) { >+ CHECK_TLS_INIT_ERROR(); >+ send_response("200", "Protection set to Private"); >+ tls_on_data = 1; >+ } >+ else if (!strcmp(cmd->argv[1], "S") || !strcmp(cmd->argv[1], "E")) { >+ char errmsg[255]; >+ snprintf(errmsg, sizeof(errmsg), "PROT %s unsupported", cmd->argv[1]); >+ return ERROR_MSG(cmd, R_536, errmsg); >+ } >+ else { >+ char errmsg[255]; >+ snprintf(errmsg, sizeof(errmsg), "PROT %s unsupported", cmd->argv[1]); >+ return ERROR_MSG(cmd, R_504, errmsg); >+ } >+ >+ return HANDLED(cmd); >+} >+ >+/* There are three tables which act as the "glue" between proftpd and >+ * a module. None of the tables are _required_ (however having none would >+ * make the module fairly useless). >+ */ >+ >+/* The first table is the "configuration directive" table. It specifies >+ * handler routines in the module which will be used during configuration >+ * file parsing. >+ */ >+ >+static conftable mod_tls_config[] = { >+ { "TlsRsaCertFile", set_rsacertfile, NULL }, >+ { "TlsRsaKeyFile", set_rsakeyfile, NULL }, >+ { "TlsDsaCertFile", set_dsacertfile, NULL }, >+ { "TlsDsaKeyFile", set_dsakeyfile, NULL }, >+ { "TlsCrlFile", set_crlfile, NULL }, >+ { "TlsDhParamFile", set_dhparamfile, NULL }, >+ { "TlsCipherList", set_cipherlist, NULL }, >+ { "TlsCertsOk", set_no_verify, NULL }, >+ { "TlsDontRequestCert", set_dont_request_cert, NULL }, >+ { "TlsRequired", set_required, NULL }, >+ { "TlsImplicit", set_implicit, NULL }, >+ { NULL , NULL, NULL} >+}; >+ >+/* Each module can supply up to two initialization routines (via >+ * the module structure at the bottom of this file). The first >+ * init function is called immediately after the module is loaded, >+ * while the second is called after proftpd is connected to a client, >+ * and the main proftpd server (if not in inetd mode) has forked off. >+ * The second init function's purpose is to let the module perform >+ * any necessary work once a client is connected and proftpd is ready >+ * to service the new client. In inetd mode, the "child init" function >+ * will be called immediately after proftpd is loaded, because proftpd >+ * is _always_ in "child mode" when run from inetd. Note that both >+ * of these initialization routines are optional. If you don't need >+ * them (or only need one), simply set the function pointer to NULL >+ * in the module structure. >+ */ >+ >+static int mod_tls_init() >+{ >+ return 0; >+} >+ >+#define PROCESS_PARAM_STR(x, y) { \ >+ char *str = (char *) get_param_ptr(CURRENT_CONF, x, FALSE); \ >+ if (str) { \ >+ if (y) \ >+ free(y); \ >+ y = strdup(str); \ >+ } \ >+} >+ >+#define PROCESS_PARAM_INT(x, y) { \ >+ long i = get_param_int(CURRENT_CONF, x, FALSE); \ >+ if (i != -1) \ >+ y = i; \ >+} >+ >+static int mod_tls_child_init() >+{ >+ PROCESS_PARAM_STR("TlsRsaCertFile", tls_rsa_cert_file); >+ PROCESS_PARAM_STR("TlsRsaKeyFile", tls_rsa_key_file); >+ PROCESS_PARAM_STR("TlsDsaCertFile", tls_dsa_cert_file); >+ PROCESS_PARAM_STR("TlsDsaKeyFile", tls_dsa_key_file); >+ PROCESS_PARAM_STR("TlsCrlFile", tls_crl_file); >+ PROCESS_PARAM_STR("TlsDhParamFile", tls_dhparam_file); >+ PROCESS_PARAM_STR("TlsCipherList", tls_cipher_list); >+ PROCESS_PARAM_INT("TlsCertsOk", tls_no_verify); >+ PROCESS_PARAM_INT("TlsDontRequestCert", tls_dont_request_cert); >+ PROCESS_PARAM_INT("TlsRequired", tls_required); >+ PROCESS_PARAM_INT("TlsImplicit", tls_implicit); >+ >+ return tls_init_error = tls_init(); >+} >+ >+/* command table ... >+ * first : command "type" (see the doc/API for more info) >+ * >+ * second : command "name", or the actual null-terminated ascii text >+ * sent by a client (in uppercase) for this command. see >+ * include/ftp.h for macros which define all rfced FTP protocol >+ * commands. Can also be the special macro C_ANY, which receives >+ * ALL commands. >+ * >+ * third : command "group" (used for access control via Limit directives), >+ * this can be either G_DIRS (for commands related to directory >+ * listing), G_READ (for commands related to reading files), >+ * G_WRITE (for commands related to file writing), or the >+ * special G_NONE for those commands against which the >+ * special <Limit READ|WRITE|DIRS> will not be applied. >+ * >+ * fourth : function pointer to your handler >+ * >+ * fifth : TRUE if the command cannot be used before authentication >+ * (via USER/PASS), otherwise FALSE. >+ * >+ * sixth : TRUE if the command can be sent during a file transfer >+ * (note: as of 1.1.5, this is obsolete) >+ * >+ */ >+ >+cmdtable mod_tls_commands[] = { >+ { CMD, "AUTH", G_NONE, cmd_auth, FALSE, FALSE }, >+ { CMD, "PBSZ", G_NONE, cmd_pbsz, FALSE, FALSE }, >+ { CMD, "PROT", G_NONE, cmd_prot, FALSE, FALSE }, >+ { 0, NULL } >+}; >+ >+module tls_module = { >+ NULL,NULL, /* Always NULL */ >+ 0x20, /* API Version 2.0 */ >+ "tls", >+ mod_tls_config, /* Configuration handler table */ >+ mod_tls_commands, /* Command handler table */ >+ NULL, /* No authentication handler table */ >+ mod_tls_init, /* Initialization function */ >+ mod_tls_child_init /* Post-fork "child mode" init */ >+}; >diff -urN proftpd-1.2.6rc1.orig/sample-configurations/basic.conf proftpd-1.2.6rc1-tls/sample-configurations/basic.conf >--- proftpd-1.2.6rc1.orig/sample-configurations/basic.conf Sun Oct 18 04:24:41 1998 >+++ proftpd-1.2.6rc1-tls/sample-configurations/basic.conf Wed Jul 3 14:49:19 2002 >@@ -3,10 +3,37 @@ > # and a single anonymous login. It assumes that you have a user/group > # "nobody" and "ftp" for normal operation and anon. > >-ServerName "ProFTPD Default Installation" >+ServerName "ProFTPD-TLS Default Installation" >+# ServerType is either "standalone" or "inetd" > ServerType standalone > DefaultServer on > >+# If you want .message files to work with browsers, you probably >+# want to uncomment the next line >+#MultilineRFC2228 on >+ >+# These are the TLS related options, default values >+#TlsRsaCertFile ftpd-rsa.pem >+#TlsRsaKeyFile ftpd-rsa-key.pem >+#TlsDsaCertFile ftpd-dsa.pem >+#TlsDsaKeyFile ftpd-dsa-key.pem >+#TlsCrlFile ftpd-crl.pem >+#TlsDhParamFile ftpd-dhparam.pem >+#TlsCipherList ALL:!ADH >+#TlsRequired off >+# don't verify any peer certificates >+#TlsCertsOk off >+# Some ftp clients (e.g. SmartFTP) uses a broken SSL/TLS implementation that >+# aborts the SSL/TLS handshake, if the server sends a "CertificateRequest" and >+# the client don't have any certificate. This behaviour violates both the SSLv3 >+# and TLSv1 spec (it's actually old SSLv2 behaviour). To be able to use those >+# clients without client certs, you must set the following option to "on". >+#TlsDontRequestCert off >+# Set the following to "on" if you want to use implicit SSL/TLS. It's not the >+# recommended way do to SSL/TLS ftp, but some user's want it anyway. Remember >+# to make proftpd listen to the proper ``ftps'' port also. >+#TlsImplicit off >+ > # Port 21 is the standard FTP port. > Port 21 > # Umask 022 is a good standard umask to prevent new dirs and files >diff -urN proftpd-1.2.6rc1.orig/src/data.c proftpd-1.2.6rc1-tls/src/data.c >--- proftpd-1.2.6rc1.orig/src/data.c Tue Jul 2 19:01:47 2002 >+++ proftpd-1.2.6rc1-tls/src/data.c Wed Jul 3 10:54:31 2002 >@@ -41,6 +41,11 @@ > #include <sys/uio.h> > #endif /* HAVE_SYS_UIO_H */ > >+#ifdef TLS >+#include <openssl/ssl.h> >+#include "tlsutil.h" >+#endif >+ > /* local macro */ > > #define MODE_STRING (session.flags & (SF_ASCII|SF_ASCII_OVERRIDE) ? \ >@@ -199,6 +204,18 @@ > */ > send_response(R_150, "FILE: %s", reason); > } >+#ifdef TLS >+ /* start TLS handshake if appropriate */ >+ if (tls_on_data) >+ if (tls_accept(c, TRUE)) { >+ /* exit if we fail */ >+ send_response_async(R_421, >+ "Failed TLS negotiation on data channel, disconnected"); >+ main_exit((void*) LOG_ERR, >+ "Failed TLS negotiation on data channel, disconnected.", (void*) 0, >+ NULL); >+ } >+#endif > > return 0; > } >@@ -289,6 +306,18 @@ > send_response(R_150, "FILE: %s", reason); > } > >+#ifdef TLS >+ /* start TLS handshake if appropriate */ >+ if (tls_on_data) >+ if (tls_accept(c, TRUE)) { >+ /* exit if we fail */ >+ send_response_async(R_421, >+ "Failed TLS negotiation on data channel, disconnected"); >+ main_exit((void*) LOG_ERR, >+ "Failed TLS negotiation on data channel, disconnected.", (void*) 0, >+ NULL); >+ } >+#endif > inet_close(session.pool,session.d); > inet_setnonblock(session.pool,session.d); > session.d = c; >diff -urN proftpd-1.2.6rc1.orig/src/io.c proftpd-1.2.6rc1-tls/src/io.c >--- proftpd-1.2.6rc1.orig/src/io.c Tue Jul 2 19:01:47 2002 >+++ proftpd-1.2.6rc1-tls/src/io.c Wed Jul 3 11:10:46 2002 >@@ -27,6 +27,11 @@ > > #include <signal.h> > >+#ifdef TLS >+#include <openssl/ssl.h> >+#include "tlsutil.h" >+#endif >+ > #ifndef IAC > #define IAC 255 > #endif >@@ -102,6 +107,9 @@ > > f->fd = fd; > f->mode = mode; >+#ifdef TLS >+ f->tls_session = NULL; >+#endif > > return f; > } >@@ -116,6 +124,11 @@ > > res = close(f->fd); > f->fd = -1; >+#ifdef TLS >+ /* only close the READ IOFILE since they come in pairs with the same SSL */ >+ if (f->mode == IO_READ) >+ tls_close_session(f->tls_session); >+#endif > > destroy_pool(f->pool); > return res; >@@ -248,6 +261,12 @@ > tv.tv_sec = ((f->flags & IO_INTR) ? f->restart_secs : 60); > tv.tv_usec = 0; > >+#ifdef TLS >+ /* check if there some data "hidden" left in the OpenSSL system */ >+ if (tls_pending(f->tls_session)) >+ res = 1; >+ else >+#endif > res = select(f->fd + 1,rfds,wfds,NULL,&tv); > switch(res) { > case -1: >@@ -305,6 +324,11 @@ > do { > run_schedule(); > handle_signals(); >+#ifdef TLS >+ if (f->tls_session) >+ written = tls_write(f->tls_session,buf,size); >+ else >+#endif > written = write(f->fd,buf,size); > } while(written == -1 && errno == EINTR); > break; >@@ -361,6 +385,11 @@ > while(size) { > do { > handle_signals(); >+#ifdef TLS >+ if (f->tls_session) >+ written = tls_write(f->tls_session,buf,size); >+ else >+#endif > written = write(f->fd, buf, size); > } while (written == -1 && errno == EINTR); > >@@ -414,6 +443,11 @@ > do { > run_schedule(); > handle_signals(); >+#ifdef TLS >+ if (f->tls_session) >+ bread = tls_read(f->tls_session,buf,size); >+ else >+#endif > bread = read(f->fd, buf, size); > } while(bread == -1 && errno == EINTR); > break; >diff -urN proftpd-1.2.6rc1.orig/src/main.c proftpd-1.2.6rc1-tls/src/main.c >--- proftpd-1.2.6rc1.orig/src/main.c Fri Jun 28 20:43:17 2002 >+++ proftpd-1.2.6rc1-tls/src/main.c Wed Jul 3 11:46:08 2002 >@@ -71,6 +71,11 @@ > > #include "privs.h" > >+#ifdef TLS >+#include <openssl/ssl.h> >+#include "tlsutil.h" >+#endif >+ > /* From mod_core.c > */ > extern int core_display_file(const char *numeric, const char *fn, const char *fs); >@@ -647,6 +652,12 @@ > void end_login(int exitcode) > { > end_login_noexit(); >+#ifdef TLS >+ if (session.c) >+ tls_close_session(session.c->inf->tls_session); >+ if (is_master) >+ tls_cleanup(); >+#endif > _exit(exitcode); > } > >@@ -1593,6 +1604,21 @@ > inet_ntoa(*session.c->remote_ipaddr), > session.c->remote_port); > >+#ifdef TLS >+ /* start TLS handshake if we use implicit TLS */ >+ if (tls_implicit) { >+ if (tls_accept(conn, FALSE)) { >+ /* exit if we fail */ >+ send_response_async(R_421, >+ "Failed TLS negotiation on control channel, disconnected"); >+ main_exit((void*) LOG_ERR, >+ "Failed TLS negotiation on control channel, disconnected.", >+ (void*) 0, NULL); >+ } else >+ tls_on_data = 1; >+ } >+#endif >+ > /* xfer_set_data_port(conn->local_ipaddr,conn->local_port-1); */ > cmd_loop(serv,conn); > } >diff -urN proftpd-1.2.6rc1.orig/src/tlsutil.c proftpd-1.2.6rc1-tls/src/tlsutil.c >--- proftpd-1.2.6rc1.orig/src/tlsutil.c Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/src/tlsutil.c Thu Jul 11 19:53:59 2002 >@@ -0,0 +1,889 @@ >+/* >+ * Copyright (c) 1999 - 2002 Peter 'Luna' Runestig <peter@runestig.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without modifi- >+ * cation, are permitted provided that the following conditions are met: >+ * >+ * o Redistributions of source code must retain the above copyright notice, >+ * this list of conditions and the following disclaimer. >+ * >+ * o Redistributions in binary form must reproduce the above copyright no- >+ * tice, this list of conditions and the following disclaimer in the do- >+ * cumentation and/or other materials provided with the distribution. >+ * >+ * o The names of the contributors may not be used to endorse or promote >+ * products derived from this software without specific prior written >+ * permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI- >+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- >+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- >+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- >+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef lint >+static char copyright[] = >+"@(#) Copyright (c) Peter 'Luna' Runestig 1999 - 2002 <peter@runestig.com>.\n"; >+#endif /* not lint */ >+ >+/* ProFTPD special includes */ >+#include "conf.h" >+#include <privs.h> >+ >+#include <string.h> >+#include <errno.h> >+#include <sys/time.h> >+#include <sys/types.h> >+#include <sys/socket.h> >+#include <sys/poll.h> >+#include <openssl/ssl.h> >+#include <openssl/x509v3.h> >+#include <openssl/err.h> >+#include <openssl/rand.h> >+#include "tls_dh.h" >+#include "io.h" >+#include "inet.h" >+ >+#if OPENSSL_VERSION_NUMBER < 0x00905100 >+/* ASN1_BIT_STRING_cmp was renamed in 0.9.5 */ >+#define M_ASN1_BIT_STRING_cmp ASN1_BIT_STRING_cmp >+#endif >+ >+#define DEFRSACERTFILE "ftpd-rsa.pem" >+#define DEFRSAKEYFILE "ftpd-rsa-key.pem" >+#define DEFDSACERTFILE "ftpd-dsa.pem" >+#define DEFDSAKEYFILE "ftpd-dsa-key.pem" >+#define DEFCRLFILE "ftpd-crl.pem" >+#define DEFDHPARAMFILE "ftpd-dhparam.pem" >+#define DEFAULTCIPHERLIST "ALL:!ADH" >+ >+/* define if you want to check for OpenSSL-related memory leaks */ >+/*#define DEBUG_OPENSSL_MEM*/ >+ >+int x509_to_user(X509 *peer_cert, char *userid, int len); >+static char *file_fullpath(char *fn); >+ >+int tls_on_ctrl = 0; >+int tls_on_data = 0; >+int tls_implicit = 0; >+int tls_init_error = 0; >+int tls_no_verify = 0; >+int tls_dont_request_cert = 0; >+int tls_required = 0; >+char *tls_rsa_key_file = NULL; >+char *tls_rsa_cert_file = NULL; >+char *tls_dsa_key_file = NULL; >+char *tls_dsa_cert_file = NULL; >+char *tls_crl_file = NULL; >+char *tls_crl_dir = NULL; >+char *tls_dhparam_file = NULL; >+char *tls_rand_file = NULL; >+char *tls_cipher_list = NULL; >+static SSL *first_ssl = NULL; >+static SSL_CTX *ssl_ctx = NULL; >+static X509_STORE *crl_store = NULL; >+static DH *tmp_dh = NULL; >+static RSA *tmp_rsa = NULL; >+ >+/* we need this so we don't mix static and malloc'ed strings */ >+void tls_set_file_defaults(void) >+{ >+ if (!tls_rsa_key_file) >+ tls_rsa_key_file = strdup(DEFRSAKEYFILE); >+ if (!tls_rsa_cert_file) >+ tls_rsa_cert_file = strdup(DEFRSACERTFILE); >+ if (!tls_dsa_key_file) >+ tls_dsa_key_file = strdup(DEFDSAKEYFILE); >+ if (!tls_dsa_cert_file) >+ tls_dsa_cert_file = strdup(DEFDSACERTFILE); >+ if (!tls_crl_file) >+ tls_crl_file = strdup(DEFCRLFILE); >+ if (!tls_crl_dir && (tls_crl_dir = malloc(strlen(X509_get_default_cert_area()) + 5))) >+ sprintf(tls_crl_dir, "%s/crl", X509_get_default_cert_area()); >+ if (!tls_dhparam_file) >+ tls_dhparam_file = strdup(DEFDHPARAMFILE); >+ if (!tls_cipher_list) >+ tls_cipher_list = strdup(DEFAULTCIPHERLIST); >+} >+ >+/* if we are using OpenSSL 0.9.6 or newer, we want to use X509_NAME_print_ex() >+ * instead of X509_NAME_oneline(). >+ */ >+static char *x509_name_oneline(X509_NAME *n, char *buf, int len) >+{ >+#if OPENSSL_VERSION_NUMBER < 0x000906000 >+ return X509_NAME_oneline(n, buf, len); >+#else >+ BIO *mem = BIO_new(BIO_s_mem()); >+ char *data = NULL; >+ int data_len = 0, ok; >+ >+ ok = X509_NAME_print_ex(mem, n, 0, XN_FLAG_ONELINE); >+ if (ok) >+ data_len = BIO_get_mem_data(mem, &data); >+ if (data) { >+ /* the 'data' returned is not '\0' terminated */ >+ if (buf) { >+ memcpy(buf, data, data_len < len ? data_len : len); >+ buf[data_len < len ? data_len : len - 1] = 0; >+ BIO_free(mem); >+ return buf; >+ } else { >+ char *b = malloc(data_len + 1); >+ if (b) { >+ memcpy(b, data, data_len); >+ b[data_len] = 0; >+ } >+ BIO_free(mem); >+ return b; >+ } >+ } else { >+ BIO_free(mem); >+ return NULL; >+ } >+#endif /* OPENSSL_VERSION_NUMBER >= 0x000906000 */ >+} >+ >+char *tls_get_subject_name() >+{ >+ static char name[256]; >+ X509 *cert; >+ >+ if ((cert = SSL_get_peer_certificate(first_ssl))) { >+ x509_name_oneline(X509_get_subject_name(cert), name, sizeof(name)); >+ X509_free(cert); >+ return name; >+ } else >+ return NULL; >+} >+ >+static DH *tmp_dh_cb(SSL *ssl, int is_export, int keylength) >+{ >+ FILE *fp; >+ >+ if (!tmp_dh) { >+ /* first try any 'tls_dhparam_file', else use built-in dh params */ >+ if (tls_dhparam_file && (fp = fopen(tls_dhparam_file, "r"))) { >+ tmp_dh = PEM_read_DHparams(fp, NULL, NULL, NULL); >+ fclose(fp); >+ if (tmp_dh) >+ return tmp_dh; >+ } >+ switch (keylength) { >+ case 512: return tmp_dh = get_dh512(); >+ case 768: return tmp_dh = get_dh768(); >+ case 1024: return tmp_dh = get_dh1024(); >+ case 1536: return tmp_dh = get_dh1536(); >+ case 2048: return tmp_dh = get_dh2048(); >+ default: return tmp_dh = get_dh1024(); >+ } >+ } >+ else >+ return tmp_dh; >+} >+ >+static RSA *tmp_rsa_cb(SSL *ssl, int is_export, int keylength) >+{ >+ if (!tmp_rsa) >+ tmp_rsa = RSA_generate_key(keylength, RSA_F4, NULL, NULL); >+ return tmp_rsa; >+} >+ >+/* check_file() expands 'file' to an existing full path or NULL if not found */ >+static void check_file(char **file) >+{ >+ char *p; >+ >+ if (*file) { >+ p = file_fullpath(*file); >+ if (p == *file) /* same pointer returned from file_fullpath() */ >+ return; >+ free(*file); >+ if (p) { >+ *file = malloc(strlen(p) + 1); >+ strcpy(*file, p); >+ } >+ else >+ *file = NULL; >+ } >+} >+ >+/* this one is (very much!) based on work by Ralf S. Engelschall <rse@engelschall.com>. >+ * comments by Ralf. >+ */ >+static int verify_crl(int ok, X509_STORE_CTX *ctx) >+{ >+ X509_OBJECT obj; >+ X509_NAME *subject; >+ X509_NAME *issuer; >+ X509 *xs; >+ X509_CRL *crl; >+ X509_REVOKED *revoked; >+ X509_STORE_CTX store_ctx; >+ long serial; >+ int i, n, rc; >+ char *cp; >+ >+ /* >+ * Unless a revocation store for CRLs was created we >+ * cannot do any CRL-based verification, of course. >+ */ >+ if (!crl_store) >+ return ok; >+ >+ /* >+ * Determine certificate ingredients in advance >+ */ >+ xs = X509_STORE_CTX_get_current_cert(ctx); >+ subject = X509_get_subject_name(xs); >+ issuer = X509_get_issuer_name(xs); >+ >+ /* >+ * OpenSSL provides the general mechanism to deal with CRLs but does not >+ * use them automatically when verifying certificates, so we do it >+ * explicitly here. We will check the CRL for the currently checked >+ * certificate, if there is such a CRL in the store. >+ * >+ * We come through this procedure for each certificate in the certificate >+ * chain, starting with the root-CA's certificate. At each step we've to >+ * both verify the signature on the CRL (to make sure it's a valid CRL) >+ * and it's revocation list (to make sure the current certificate isn't >+ * revoked). But because to check the signature on the CRL we need the >+ * public key of the issuing CA certificate (which was already processed >+ * one round before), we've a little problem. But we can both solve it and >+ * at the same time optimize the processing by using the following >+ * verification scheme (idea and code snippets borrowed from the GLOBUS >+ * project): >+ * >+ * 1. We'll check the signature of a CRL in each step when we find a CRL >+ * through the _subject_ name of the current certificate. This CRL >+ * itself will be needed the first time in the next round, of course. >+ * But we do the signature processing one round before this where the >+ * public key of the CA is available. >+ * >+ * 2. We'll check the revocation list of a CRL in each step when >+ * we find a CRL through the _issuer_ name of the current certificate. >+ * This CRLs signature was then already verified one round before. >+ * >+ * This verification scheme allows a CA to revoke its own certificate as >+ * well, of course. >+ */ >+ >+ /* >+ * Try to retrieve a CRL corresponding to the _subject_ of >+ * the current certificate in order to verify it's integrity. >+ */ >+ memset((char *)&obj, 0, sizeof(obj)); >+ X509_STORE_CTX_init(&store_ctx, crl_store, NULL, NULL); >+ rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, subject, &obj); >+ X509_STORE_CTX_cleanup(&store_ctx); >+ crl = obj.data.crl; >+ if (rc > 0 && crl != NULL) { >+ /* >+ * Verify the signature on this CRL >+ */ >+ if (X509_CRL_verify(crl, X509_get_pubkey(xs)) <= 0) { >+ log_pri(LOG_ERR, "Invalid signature on CRL!"); >+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); >+ X509_OBJECT_free_contents(&obj); >+ return 0; >+ } >+ >+ /* >+ * Check date of CRL to make sure it's not expired >+ */ >+ i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); >+ if (i == 0) { >+ log_pri(LOG_ERR, "Found CRL has invalid nextUpdate field."); >+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); >+ X509_OBJECT_free_contents(&obj); >+ return 0; >+ } >+ if (i < 0) { >+ log_pri(LOG_ERR, "Found CRL is expired - revoking all certificates until you get updated CRL."); >+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); >+ X509_OBJECT_free_contents(&obj); >+ return 0; >+ } >+ X509_OBJECT_free_contents(&obj); >+ } >+ >+ /* >+ * Try to retrieve a CRL corresponding to the _issuer_ of >+ * the current certificate in order to check for revocation. >+ */ >+ memset((char *)&obj, 0, sizeof(obj)); >+ X509_STORE_CTX_init(&store_ctx, crl_store, NULL, NULL); >+ rc = X509_STORE_get_by_subject(&store_ctx, X509_LU_CRL, issuer, &obj); >+ X509_STORE_CTX_cleanup(&store_ctx); >+ crl = obj.data.crl; >+ if (rc > 0 && crl != NULL) { >+ /* >+ * Check if the current certificate is revoked by this CRL >+ */ >+ n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); >+ for (i = 0; i < n; i++) { >+ revoked = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); >+ if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(xs)) == 0) { >+ >+ serial = ASN1_INTEGER_get(revoked->serialNumber); >+ cp = x509_name_oneline(issuer, NULL, 0); >+ log_pri(LOG_ERR, "Certificate with serial %ld (0x%lX) revoked per CRL from issuer %s", >+ serial, serial, cp ? cp : "(ERROR)"); >+ if (cp) free(cp); >+ >+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); >+ X509_OBJECT_free_contents(&obj); >+ return 0; >+ } >+ } >+ X509_OBJECT_free_contents(&obj); >+ } >+ return ok; >+} >+ >+static int verify_callback(int ok, X509_STORE_CTX *ctx) >+{ >+ /* TODO: Make up my mind on what to accept or not.*/ >+ /* we can configure the server to skip the peer's cert verification */ >+ if (tls_no_verify) >+ return 1; >+ >+ ok = verify_crl(ok, ctx); >+ if (!ok) { >+ switch (ctx->error) { >+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: >+ log_pri(LOG_ERR, "Error: Client's certificate is self signed."); >+ ok = 0; >+ break; >+ case X509_V_ERR_CERT_HAS_EXPIRED: >+ log_pri(LOG_ERR, "Error: Client's certificate has expired."); >+ ok = 0; >+ break; >+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: >+ log_pri(LOG_ERR, "Error: Client's certificate issuer's certificate isn't available locally."); >+ ok = 0; >+ break; >+ case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: >+ log_pri(LOG_ERR, "Error: Unable to verify leaf signature."); >+ ok = 0; >+ break; >+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: >+ /* XXX this is strange. we get this error for certain clients (ie Jeff's kftp) when >+ * all is ok. I think it's because the client is actually sending the whole CA >+ * cert. this must be figured out, but we let it pass for now. if the CA cert isn't >+ * available locally, we will fail anyway. >+ */ >+ log_pri(LOG_NOTICE, "Warning: Self signed certificate in chain."); >+ ok = 1; >+ break; >+ case X509_V_ERR_CERT_REVOKED: >+ log_pri(LOG_ERR, "Error: Certificate revoked."); >+ ok = 0; >+ break; >+ default: >+ log_pri(LOG_ERR, >+ "Error %d while verifying the client's certificate.", ctx->error); >+ ok = 0; >+ break; >+ } >+ } >+ return ok; >+} >+ >+static int seed_PRNG(void) >+{ >+ char stackdata[1024]; >+ static char rand_file[300]; >+ FILE *fh; >+ >+#if OPENSSL_VERSION_NUMBER >= 0x00905100 >+ if (RAND_status()) >+ return 0; /* PRNG already good seeded */ >+#endif >+ /* if the device '/dev/urandom' is present, OpenSSL uses it by default. >+ * check if it's present, else we have to make random data ourselfs. >+ */ >+ if ((fh = fopen("/dev/urandom", "r"))) { >+ fclose(fh); >+ return 0; >+ } >+ /* the ftpd's rand file is (openssl-dir)/.rnd */ >+ sprintf(rand_file, "%s/.rnd", X509_get_default_cert_area()); >+ tls_rand_file = rand_file; >+ if (!RAND_load_file(rand_file, 1024)) { >+ /* no .rnd file found, create new seed */ >+ unsigned int c; >+ c = time(NULL); >+ RAND_seed(&c, sizeof(c)); >+ c = getpid(); >+ RAND_seed(&c, sizeof(c)); >+ RAND_seed(stackdata, sizeof(stackdata)); >+ } >+#if OPENSSL_VERSION_NUMBER >= 0x00905100 >+ if (!RAND_status()) >+ return 2; /* PRNG still badly seeded */ >+#endif >+ return 0; >+} >+ >+int tls_init(void) >+{ >+ int err; >+ >+#ifdef DEBUG_OPENSSL_MEM >+ CRYPTO_malloc_debug_init(); >+ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); >+#endif /* DEBUG_OPENSSL_MEM */ >+ SSL_load_error_strings(); >+ SSL_library_init(); >+#ifdef ZLIB >+ { >+ COMP_METHOD *cm = COMP_zlib(); >+ if (cm != NULL && cm->type != NID_undef) { >+ SSL_COMP_add_compression_method(0xe0, cm); /* Eric Young's ZLIB ID */ >+ } >+ } >+#endif /* ZLIB */ >+ ssl_ctx = SSL_CTX_new(SSLv23_method()); >+ if (!ssl_ctx) { >+ log_pri(LOG_ERR, "SSL_CTX_new() %s", >+ (char *)ERR_error_string(ERR_get_error(), NULL)); >+ return 1; >+ } >+ SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); >+ if (!tls_dont_request_cert) >+ SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback); >+ SSL_CTX_set_default_verify_paths(ssl_ctx); >+ /* set up session caching */ >+ SSL_CTX_set_session_cache_mode(ssl_ctx, SSL_SESS_CACHE_SERVER); >+ SSL_CTX_set_session_id_context(ssl_ctx, "1", 1); >+ >+ /* let's find out which files are available */ >+ tls_set_file_defaults(); >+#ifdef PRIVS_ROOT >+ PRIVS_ROOT /* ProFTPD must regain root privs here to read the key file(s) */ >+#endif >+ check_file(&tls_rsa_cert_file); >+ check_file(&tls_rsa_key_file); >+ check_file(&tls_dsa_cert_file); >+ check_file(&tls_dsa_key_file); >+ check_file(&tls_crl_file); >+ check_file(&tls_dhparam_file); >+ if (!tls_rsa_cert_file && !tls_dsa_cert_file) { >+ log_pri(LOG_ERR, "No certificate files found!"); >+ return 2; >+ } >+ if (!tls_rsa_key_file) >+ tls_rsa_key_file = tls_rsa_cert_file; >+ if (!tls_dsa_key_file) >+ tls_dsa_key_file = tls_dsa_cert_file; >+ >+ if (tls_rsa_cert_file) { >+ err = SSL_CTX_use_certificate_file(ssl_ctx, tls_rsa_cert_file, X509_FILETYPE_PEM); >+ if (err <= 0) { >+ log_pri(LOG_ERR, "SSL_CTX_use_certificate_file(%s) %s", tls_rsa_cert_file, >+ (char *)ERR_error_string(ERR_get_error(), NULL)); >+ return 3; >+ } >+ SSL_CTX_set_tmp_rsa_callback(ssl_ctx, tmp_rsa_cb); >+ } >+ if (tls_rsa_key_file) { >+ err = SSL_CTX_use_PrivateKey_file(ssl_ctx, tls_rsa_key_file, X509_FILETYPE_PEM); >+ if (err <= 0) { >+ log_pri(LOG_ERR, "SSL_CTX_use_PrivateKey_file(%s) %s", tls_rsa_key_file, >+ (char *)ERR_error_string(ERR_get_error(), NULL)); >+ return 4; >+ } >+ } >+ if (tls_dsa_cert_file) { >+ err = SSL_CTX_use_certificate_file(ssl_ctx, tls_dsa_cert_file, X509_FILETYPE_PEM); >+ if (err <= 0) { >+ log_pri(LOG_ERR, "SSL_CTX_use_certificate_file(%s) %s", tls_dsa_cert_file, >+ (char *)ERR_error_string(ERR_get_error(), NULL)); >+ return 5; >+ } >+ } >+ if (tls_dsa_key_file) { >+ err = SSL_CTX_use_PrivateKey_file(ssl_ctx, tls_dsa_key_file, X509_FILETYPE_PEM); >+ if (err <= 0) { >+ log_pri(LOG_ERR, "SSL_CTX_use_PrivateKey_file(%s) %s", tls_dsa_key_file, >+ (char *)ERR_error_string(ERR_get_error(), NULL)); >+ return 6; >+ } >+ } >+#ifdef PRIVS_RELINQUISH >+ PRIVS_RELINQUISH /* ProFTPD dropping root privs again */ >+#endif >+ >+ SSL_CTX_set_tmp_dh_callback(ssl_ctx, tmp_dh_cb); >+ >+ /* set up the CRL */ >+ if ((tls_crl_file || tls_crl_dir) && (crl_store = X509_STORE_new())) >+ X509_STORE_load_locations(crl_store, tls_crl_file, tls_crl_dir); >+ >+ if (tls_cipher_list) >+ SSL_CTX_set_cipher_list(ssl_ctx, tls_cipher_list); >+ else >+ log_pri(LOG_NOTICE, "NULL tls_cipher_list!"); >+ if (seed_PRNG()) >+ log_pri(LOG_NOTICE, "Wasn't able to properly seed the PRNG!"); >+ return 0; >+} >+ >+char *tls_userid_from_client_cert() >+{ >+ static char cn[256]; >+ static char *r = cn; >+ static int again = 0; >+ int err; >+ X509 *client_cert; >+ >+ if (!tls_on_ctrl || !first_ssl) >+ return NULL; >+ if (again) >+ return r; >+ again = 1; >+ if ((client_cert = SSL_get_peer_certificate(first_ssl))) { >+ /* call the custom function */ >+ err = x509_to_user(client_cert, cn, sizeof(cn)); >+ X509_free(client_cert); >+ if (err) >+ return r = NULL; >+ else >+ return r; >+ } >+ else >+ return r = NULL; >+} >+ >+int tls_is_user_valid(char *user) >+/* check if clients cert is in "user"'s ~/.tlslogin file */ >+{ >+ char buf[512]; >+ int r = 0; >+ FILE *fp = NULL; >+ X509 *client_cert = NULL, *file_cert; >+ struct passwd *pwd; >+ >+ if (!tls_on_ctrl || !first_ssl || !user) >+ return 0; >+#ifdef PRIVS_ROOT >+ PRIVS_ROOT /* ProFTPD must regain root privs here to read the .tlslogin file */ >+#endif >+ if (!(pwd = getpwnam(user))) >+ goto cleanup; >+ snprintf(buf, sizeof(buf), "%s/.tlslogin", pwd->pw_dir); >+ if (!(fp = fopen(buf, "r"))) >+ goto cleanup; >+ if (!(client_cert = SSL_get_peer_certificate(first_ssl))) >+ goto cleanup; >+ while ((file_cert = PEM_read_X509(fp, NULL, NULL, NULL))) { >+ if (!M_ASN1_BIT_STRING_cmp(client_cert->signature, file_cert->signature)) >+ r = 1; >+ X509_free(file_cert); >+ if (r) break; >+ } >+ cleanup: >+ if (client_cert) >+ X509_free(client_cert); >+ if (fp) >+ fclose(fp); >+#ifdef PRIVS_RELINQUISH >+ PRIVS_RELINQUISH /* ProFTPD dropping root privs again */ >+#endif >+ return r; >+} >+ >+void tls_close_session(SSL *ssl) >+{ >+ if (!ssl) >+ return; >+ SSL_shutdown(ssl); >+ SSL_free(ssl); >+} >+ >+int tls_accept(conn_t *conn, int data_connection) >+{ >+ int err; >+ SSL *ssl; >+ static int logged_data_connection = 0; >+ >+ if (!ssl_ctx) { >+ log_pri(LOG_ERR, "tls_accept() called when ssl_ctx == NULL!"); >+ return 1; >+ } >+ ssl = SSL_new(ssl_ctx); >+ if (!ssl) { >+ log_pri(LOG_ERR, "SSL_new() %s", (char *)ERR_error_string(ERR_get_error(), NULL)); >+ return 2; >+ } >+ >+ if (!first_ssl) >+ first_ssl = ssl; >+ SSL_set_fd(ssl, conn->rfd); /* it works with either rfd or wfd (I hope ;-) */ >+ >+ retry: >+ err = SSL_accept(ssl); >+ if (err < 1) { >+ int ssl_err = SSL_get_error(ssl, err); >+ if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) >+ goto retry; >+ log_pri(LOG_ERR, "SSL_accept(): (%d) %s", ssl_err, >+ (char *)ERR_error_string(ERR_get_error(), NULL)); >+ tls_close_session(ssl); >+ return 3; >+ } >+ conn->inf->tls_session = conn->outf->tls_session = ssl; >+ tls_on_ctrl = 1; >+ >+ if (data_connection) { >+ /* only log first TLS data connection, otherwise there might be lots of logging */ >+ if (!logged_data_connection) { >+ log_pri(LOG_NOTICE, "TLS data connection using cipher %s (%d bits)", >+ SSL_get_cipher(ssl), SSL_get_cipher_bits(ssl, NULL)); >+ logged_data_connection = 1; >+ } >+ } else { >+ char *subject = tls_get_subject_name(); >+ log_pri(LOG_NOTICE, "TLS connection using cipher %s (%d bits)", >+ SSL_get_cipher(ssl), SSL_get_cipher_bits(ssl, NULL)); >+ if (subject) >+ log_pri(LOG_NOTICE, "Client: %s", subject); >+ } >+ return 0; >+} >+ >+void tls_cleanup(void) >+{ >+ if (crl_store) { >+ X509_STORE_free(crl_store); >+ crl_store = NULL; >+ } >+ if (ssl_ctx) { >+ SSL_CTX_free(ssl_ctx); >+ ssl_ctx = NULL; >+ } >+ if (tmp_dh) { >+ DH_free(tmp_dh); >+ tmp_dh = NULL; >+ } >+ if (tmp_rsa) { >+ RSA_free(tmp_rsa); >+ tmp_rsa = NULL; >+ } >+ ERR_free_strings(); >+ ERR_remove_state(0); >+ EVP_cleanup(); /* release the stuff allocated by SSL_library_init() */ >+ if (tls_rsa_key_file) { >+ if (tls_rsa_key_file != tls_rsa_cert_file) >+ free(tls_rsa_key_file); >+ tls_rsa_key_file = NULL; >+ } >+ if (tls_rsa_cert_file) { >+ free(tls_rsa_cert_file); >+ tls_rsa_cert_file = NULL; >+ } >+ if (tls_dsa_key_file) { >+ if (tls_dsa_key_file != tls_dsa_cert_file) >+ free(tls_dsa_key_file); >+ tls_dsa_key_file = NULL; >+ } >+ if (tls_dsa_cert_file) { >+ free(tls_dsa_cert_file); >+ tls_dsa_cert_file = NULL; >+ } >+ if (tls_dhparam_file) { >+ free(tls_dhparam_file); >+ tls_dhparam_file = NULL; >+ } >+ if (tls_crl_file) { >+ free(tls_crl_file); >+ tls_crl_file = NULL; >+ } >+ if (tls_crl_dir) { >+ free(tls_crl_dir); >+ tls_crl_dir = NULL; >+ } >+ if (tls_cipher_list) { >+ free(tls_cipher_list); >+ tls_cipher_list = NULL; >+ } >+ if (tls_rand_file) >+ /* tls_rand_file is not malloc()'ed */ >+ RAND_write_file(tls_rand_file); >+#ifdef DEBUG_OPENSSL_MEM >+ { >+ char fname[] = "/tmp/proftpd_memleak_XXXXXX"; >+ int fd; >+ if ((fd = mkstemp(fname)) != -1) { >+ FILE *f = fdopen(fd, "w"); >+ if (f) { >+ CRYPTO_mem_leaks_fp(f); >+ fclose(f); >+ } >+ } >+ } >+#endif /* DEBUG_OPENSSL_MEM */ >+} >+ >+static void handle_ssl_error(int error, int line) >+{ >+ switch (error) { >+ case SSL_ERROR_NONE: >+ return; >+ case SSL_ERROR_SSL: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_SSL on line %d!", line); >+ break; >+ case SSL_ERROR_WANT_READ: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_WANT_READ on line %d!", line); >+ break; >+ case SSL_ERROR_WANT_WRITE: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_WANT_WRITE on line %d!", line); >+ break; >+ case SSL_ERROR_WANT_X509_LOOKUP: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_WANT_X509_LOOKUP on line %d!", line); >+ break; >+ case SSL_ERROR_SYSCALL: >+ /* ProFTPD is sloppy in checking the return value/errno status from >+ * read()/write(), so we must double-check here so we don't generate >+ * unnecessary fuzz... >+ */ >+ if (errno == ECONNRESET) /* peer hung up */ >+ return; >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_SYSCALL on line %d!", line); >+ break; >+ case SSL_ERROR_ZERO_RETURN: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_ZERO_RETURN on line %d!", line); >+ break; >+ case SSL_ERROR_WANT_CONNECT: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR_WANT_CONNECT on line %d!", line); >+ break; >+ default: >+ log_pri(LOG_ERR, "Panic: SSL_ERROR %d on line %d!", error, line); >+ break; >+ } >+ /* if we reply something here, we might just trigger another handle_ssl_error() >+ * call and loop endlessly... >+ */ >+ main_exit((void*) LOG_ERR, >+ "Unexpected OpenSSL error, disconnected.", (void*) 0, NULL); >+ /* NOTREACHED */ >+} >+ >+static int select_read(int rfd) >+/* timeout = 20 seconds */ >+{ >+ fd_set rfds; >+ struct timeval tv; >+ >+ FD_ZERO(&rfds); >+ FD_SET(rfd, &rfds); >+ tv.tv_sec = 20; >+ tv.tv_usec = 0; >+ return select(rfd + 1, &rfds, NULL, NULL, &tv); >+} >+ >+ssize_t tls_read(SSL *ssl, void *buf, size_t count) >+{ >+ ssize_t c; >+ >+ retry: >+ c = SSL_read(ssl, buf, count); >+ if (c < 0) { >+ int err = SSL_get_error(ssl, c); >+ /* read(2) returns only the generic error number -1 */ >+ c = -1; >+ switch (err) { >+ case SSL_ERROR_WANT_READ: >+ /* OpenSSL needs more data from the wire to finish the current block, >+ * so we wait a little while for it. */ >+ err = select_read(SSL_get_fd(ssl)); >+ if (err > 0) >+ goto retry; >+ else if (err == 0) >+ /* still missing data after timeout. simulate an EINTR and return. */ >+ errno = EINTR; >+ /* if err < 0, i.e. some error from the select(), everything is already >+ * in place; errno is properly set and this function returns -1. */ >+ break; >+ default: >+ handle_ssl_error(err, __LINE__); >+ break; >+ } >+ } >+ return c; >+} >+ >+ssize_t tls_write(SSL *ssl, const void *buf, size_t count) >+{ >+ ssize_t c; >+ >+ c = SSL_write(ssl, buf, count); >+ if (c < 0) { >+ int err = SSL_get_error(ssl, c); >+ /* write(2) returns only the generic error number -1 */ >+ c = -1; >+ switch (err) { >+ case SSL_ERROR_WANT_WRITE: >+ /* simulate an EINTR in case OpenSSL wants to write more */ >+ errno = EINTR; >+ break; >+ default: >+ handle_ssl_error(err, __LINE__); >+ break; >+ } >+ } >+ return c; >+} >+ >+int tls_pending(SSL *ssl) >+{ >+ if (ssl) >+ return SSL_pending(ssl); >+ else >+ return 0; >+} >+ >+char *file_fullpath(char *fn) >+{ >+ static char fp[256]; >+ FILE *file; >+ char *dir; >+ >+ /* check if it is a full path already */ >+ if (strchr(fn, '/')) { >+ if ((file = fopen(fn, "r"))) { >+ fclose(file); >+ return fn; >+ } >+ else >+ return NULL; >+ } >+ /* check if it is in current dir */ >+ if ((file = fopen(fn, "r"))) { >+ fclose(file); >+ return fn; >+ } >+ if (!(dir = getenv(X509_get_default_cert_dir_env()))) /* $SSL_CERT_DIR */ >+ dir = (char *)X509_get_default_cert_dir(); >+ snprintf(fp, sizeof(fp), "%s/%s", dir, fn); >+ if ((file = fopen(fp, "r"))) { >+ fclose(file); >+ return fp; >+ } >+ dir = (char *)X509_get_default_private_dir(); >+ snprintf(fp, sizeof(fp), "%s/%s", dir, fn); >+ if ((file = fopen(fp, "r"))) { >+ fclose(file); >+ return fp; >+ } >+ return NULL; >+} >diff -urN proftpd-1.2.6rc1.orig/src/x509_to_user.c proftpd-1.2.6rc1-tls/src/x509_to_user.c >--- proftpd-1.2.6rc1.orig/src/x509_to_user.c Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/src/x509_to_user.c Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,43 @@ >+/* >+ * Copyright (c) 1999, 2000 Peter 'Luna' Runestig <peter@runestig.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without modifi- >+ * cation, are permitted provided that the following conditions are met: >+ * >+ * o Redistributions of source code must retain the above copyright notice, >+ * this list of conditions and the following disclaimer. >+ * >+ * o Redistributions in binary form must reproduce the above copyright no- >+ * tice, this list of conditions and the following disclaimer in the do- >+ * cumentation and/or other materials provided with the distribution. >+ * >+ * o The names of the contributors may not be used to endorse or promote >+ * products derived from this software without specific prior written >+ * permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI- >+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- >+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- >+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- >+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include <openssl/ssl.h> >+ >+/* x509_to_user() returns 0 if valid userid in 'userid', else 1 */ >+int x509_to_user(X509 *peer_cert, char *userid, int len) >+{ >+ >+ if (!(peer_cert && userid)) >+ return 1; >+ >+ /* TODO: insert cert => userid translation code here */ >+ >+ return 1; >+} >diff -urN proftpd-1.2.6rc1.orig/src/x509_to_user.c.samp1 proftpd-1.2.6rc1-tls/src/x509_to_user.c.samp1 >--- proftpd-1.2.6rc1.orig/src/x509_to_user.c.samp1 Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/src/x509_to_user.c.samp1 Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,49 @@ >+/* >+ * Copyright (c) 1999, 2000 Peter 'Luna' Runestig <peter@runestig.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without modifi- >+ * cation, are permitted provided that the following conditions are met: >+ * >+ * o Redistributions of source code must retain the above copyright notice, >+ * this list of conditions and the following disclaimer. >+ * >+ * o Redistributions in binary form must reproduce the above copyright no- >+ * tice, this list of conditions and the following disclaimer in the do- >+ * cumentation and/or other materials provided with the distribution. >+ * >+ * o The names of the contributors may not be used to endorse or promote >+ * products derived from this software without specific prior written >+ * permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI- >+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- >+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- >+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- >+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include <openssl/ssl.h> >+ >+/* sample that returns a userid in cert's subj UID */ >+/* x509_to_user() returns 0 if valid userid in 'userid', else 1 */ >+int x509_to_user(X509 *peer_cert, char *userid, int len) >+{ >+ int err; >+ >+ if (!(peer_cert && userid)) >+ return 1; >+ >+ /* userid is in cert subject /UID */ >+ err = X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), >+ NID_uniqueIdentifier, userid, len); >+ if (err > 0) >+ return 0; >+ else >+ return 1; >+} >diff -urN proftpd-1.2.6rc1.orig/src/x509_to_user.c.samp2 proftpd-1.2.6rc1-tls/src/x509_to_user.c.samp2 >--- proftpd-1.2.6rc1.orig/src/x509_to_user.c.samp2 Thu Jan 1 01:00:00 1970 >+++ proftpd-1.2.6rc1-tls/src/x509_to_user.c.samp2 Mon Jun 10 11:56:48 2002 >@@ -0,0 +1,104 @@ >+/* >+ * Copyright (c) 1999, 2000 Peter 'Luna' Runestig <peter@runestig.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without modifi- >+ * cation, are permitted provided that the following conditions are met: >+ * >+ * o Redistributions of source code must retain the above copyright notice, >+ * this list of conditions and the following disclaimer. >+ * >+ * o Redistributions in binary form must reproduce the above copyright no- >+ * tice, this list of conditions and the following disclaimer in the do- >+ * cumentation and/or other materials provided with the distribution. >+ * >+ * o The names of the contributors may not be used to endorse or promote >+ * products derived from this software without specific prior written >+ * permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS >+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED >+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI- >+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN- >+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV- >+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI- >+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF >+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include <stdio.h> >+#include <unistd.h> >+#include <sys/time.h> >+#include <openssl/ssl.h> >+ >+/* sample that uses SafeGossip's "Certificate Mapping Server" */ >+ >+char *trim(char *s) >+{ >+ while (isspace(*s)) >+ memmove(s, s + 1, strlen(s + 1) + 1); >+ while (isspace(s[strlen(s) - 1])) >+ s[strlen(s) - 1] = 0; >+ return s; >+} >+ >+/* x509_to_user() returns 0 if valid userid in 'userid', else 1 */ >+int x509_to_user(X509 *peer_cert, char *userid, int len) >+{ >+ int pin[2], pout[2], err; >+ FILE *pfp; >+ pid_t pid; >+ fd_set rfds; >+ struct timeval tv; >+ >+ if (!(peer_cert && userid)) >+ return 1; >+ >+ /* '/usr/sbin/authcert' reads a cert from stdin and writes the userid to stdout. */ >+ if (pipe(pin)) >+ return 1; >+ if (pipe(pout)) >+ return 1; >+ pid = fork(); >+ if (pid == -1) >+ return 1; >+ else if (pid == 0) { >+ /* child */ >+ dup2(pin[0], 0); >+ close(pin[0]); close(pin[1]); >+ dup2(pout[1], 1); >+ execl("/usr/sbin/authcert", "authcert", NULL); >+ /* normally not reached */ >+ exit(2); >+ } >+ >+ /* write PEM-formatted cert to subprocess' stdin */ >+ if (!(pfp = fdopen(pin[1], "w"))) >+ return 1; >+ PEM_write_X509(pfp, peer_cert); >+ fclose(pfp); >+ close(pin[0]); >+ >+ /* wait for userid from pout[0] */ >+ FD_ZERO(&rfds); >+ FD_SET(pout[0], &rfds); >+ tv.tv_sec = 20; >+ tv.tv_usec = 0; >+ err = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); >+ >+ if (err < 1) { >+ close(pout[0]); close(pout[1]); >+ return 1; >+ } >+ err = read(pout[0], userid, len - 1); >+ close(pout[0]); close(pout[1]); >+ if (err) { >+ userid[err] = 0; >+ trim(userid); >+ return 0; >+ } >+ else >+ return 1; >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 6898
:
3322
| 3323