--- linux-ftpd-ssl-0.17.27+0.3.orig/debian/rules +++ linux-ftpd-ssl-0.17.27+0.3/debian/rules @@ -0,0 +1,72 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CONFIGUREARGS=--with-debug +else + CONFIGUREARGS= +endif + +CDEFS := -D_FILE_OFFSET_BITS=64 -g +LDDEFS := -Wl,-z,defs -Wl,--as-needed + +build: + dh_testdir + + if [ ! -f MCONFIG ]; then \ + USE_PAM=1 ./configure $(CONFIGUREARGS); \ + sed -e 's/^CFLAGS=\(.*\)$$/CFLAGS=$(CDEFS) \1/' \ + -e 's/^LDFLAGS=\(.*\)$$/LDFLAGS=$(LDDEFS) \1/' \ + MCONFIG > MCONFIG.new; \ + mv MCONFIG.new MCONFIG; \ + echo CFLAGS+=-DUSE_PAM >> MCONFIG; \ + echo LIBS+=-lpam >> MCONFIG; \ + fi + $(MAKE) + +clean: + dh_testdir + dh_testroot + + [ ! -f MCONFIG ] || $(MAKE) distclean + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + cp ftpd/ftpd debian/ftpd-ssl/usr/sbin/in.ftpd + cp ftpd/ftpd.8 debian/ftpd-ssl/usr/share/man/man8/in.ftpd.8 + cp ftpd/*.5 debian/*.5 debian/ftpd-ssl/usr/share/man/man5 + ln -sf in.ftpd.8 debian/ftpd-ssl/usr/share/man/man8/ftpd.8 + cp debian/ftpchroot debian/ftpusers debian/ftpd-ssl/etc + cp debian/pam.d/ftp debian/ftpd-ssl/etc/pam.d + cp debian/openssl.cnf debian/ftpd-ssl/etc/ftpd-ssl/ + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installchangelogs ChangeLog + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/postinst +++ linux-ftpd-ssl-0.17.27+0.3/debian/postinst @@ -0,0 +1,47 @@ +#!/bin/sh -e +# $Id: postinst,v 1.7 2003/06/21 02:31:44 herbert Exp $ + +if grep -q '[[:blank:]]/usr/sbin/in\.ftpd\>' /etc/inetd.conf; then + if ! grep -q '^ftp\>' /etc/inetd.conf; then + update-inetd --pattern '/usr/sbin/in\.ftpd' --enable ftp + fi +else + FTPENTRY="ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.ftpd" + if grep -q '^ftp\>' /etc/inetd.conf; then + update-inetd --group STANDARD --add "## $FTPENTRY" + else + update-inetd --group STANDARD --add "$FTPENTRY" + fi +fi + +PATH=$PATH:/usr/bin/ssl +if [ -f /etc/ssl/certs/ftpd.pem ] +then + echo "Moving ftpd.pem to /etc/ftpd-ssl" + mv /etc/ssl/certs/ftpd.pem /etc/ftpd-ssl + # remove old cert hash - don't care if it fails + rm -f `openssl x509 -noout -hash < /etc/ftpd-ssl/ftpd.pem`.0 || true +elif [ -f /etc/ftpd-ssl/ftpd.pem ] +then + echo "You already have /etc/ftpd-ssl/ftpd.pem" +else + cd /etc/ftpd-ssl + HSTNAME=`hostname -s` + DOMAINNAME=`hostname -d` + openssl req -config /etc/ftpd-ssl/openssl.cnf -new -x509 -nodes -out ftpd.pem -keyout ftpd.pem > /dev/null 2>&1 <<+ +. +. +. +$DOMAINNAME +$HSTNAME +ftpd +root@$HSTNAME.$DOMAINNAME ++ +# req -new -x509 -nodes -out ftpd.pem -keyout ftpd.pem +# ln -sf ftpd.pem `openssl x509 -noout -hash < ftpd.pem`.0 +# chmod 644 ftpd.pem +fi + +chmod 0600 /etc/ftpd-ssl/ftpd.pem + +#DEBHELPER# --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/dirs +++ linux-ftpd-ssl-0.17.27+0.3/debian/dirs @@ -0,0 +1,5 @@ +etc/pam.d +usr/share/man/man5 +usr/share/man/man8 +usr/sbin +etc/ftpd-ssl --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/ftpchroot +++ linux-ftpd-ssl-0.17.27+0.3/debian/ftpchroot @@ -0,0 +1 @@ +# /etc/ftpchroot: list of users who needs to be chrooted. See ftpchroot(5). --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/NEWS +++ linux-ftpd-ssl-0.17.27+0.3/debian/NEWS @@ -0,0 +1,19 @@ +linux-ftpd-ssl (0.17.27+0.3-2) unstable; urgency=low + + * SSL keys/certificates generated since 2006-09-17 with Debian's openssl + package are vulnerable due to a predictable random number generator. + For more details see: + + http://www.debian.org/security/2008/dsa-1571 + http://www.debian.org/security/key-rollover/ + http://wiki.debian.org/SSLkeys + + * To generate new keys using the default ftpd-ssl setup (as root): + + rm -f /etc/ftpd-ssl/ftpd.pem /etc/ssl/certs/ftpd.pem + dpkg-reconfigure ftpd-ssl + + * If you have set up any SSL infrastructure beyond this, it will + also need to be regenerated. + + -- Ian Beckwith Wed, 21 May 2008 18:48:51 +0100 --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/postrm +++ linux-ftpd-ssl-0.17.27+0.3/debian/postrm @@ -0,0 +1,16 @@ +#!/bin/sh -e +# $Id: postrm,v 1.1 1999/04/16 07:00:28 herbert Exp $ + +if [ "$1" = purge ]; then + if [ -x /usr/sbin/update-inetd ]; then + update-inetd --pattern '/usr/sbin/in\.ftpd' --remove "## ftp" + else + echo "Unable to disable FTP entry in /etc/inetd.conf, as update-inetd is not available." >&2 + fi + + cd /etc/ftpd-ssl + PATH=$PATH:/usr/bin/ssl + rm -f ftpd.pem +fi + +#DEBHELPER# --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/openssl.cnf +++ linux-ftpd-ssl-0.17.27+0.3/debian/openssl.cnf @@ -0,0 +1,313 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca' and 'req'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = ./demoCA # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = sha1 # which md to use. +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 1024 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString. +# utf8only: only UTF8Strings. +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings +# so use this option with caution! +string_mask = nombstr + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = AU +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = Some-State + +localityName = Locality Name (eg, city) + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Internet Widgits Pty Ltd + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +#organizationalUnitName_default = + +commonName = Common Name (eg, YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer:always + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always,issuer:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer:always + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/docs +++ linux-ftpd-ssl-0.17.27+0.3/debian/docs @@ -0,0 +1 @@ +README --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/ftpusers +++ linux-ftpd-ssl-0.17.27+0.3/debian/ftpusers @@ -0,0 +1,5 @@ +# /etc/ftpusers: list of users disallowed ftp access. See ftpusers(5). + +root +ftp +anonymous --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/README.SSL +++ linux-ftpd-ssl-0.17.27+0.3/debian/README.SSL @@ -0,0 +1,14 @@ +The SSL patches were downloaded from +ftp://ftp.uni-mainz.de/pub/software/security/ssl/SSL-MZapps/linux-ftpd-0.17+ssl-0.3.diff.gz + +The packages was build in the following way: + +apt-get source linux-ftpd +mv linux-ftpd-0.17 linux-ftpd-ssl-0.17.18+0.3 +cd linux-ftpd-ssl-0.17.18+0.3 +zcat ../linux-ftpd-0.17+ssl-0.3.diff.gz | patch -p1 +#don't fix problems with applied patches ! +cd .. +cp -a linux-ftpd-ssl-0.17.18+0.3 linux-ftpd-ssl-0.17.18+0.3.orig +cd linux-ftpd-ssl-0.17.18+0.3 +zcat ../linux-ftpd-ssl_0.17.12+0.3-2.diff.gz | patch -p1 --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/compat +++ linux-ftpd-ssl-0.17.27+0.3/debian/compat @@ -0,0 +1 @@ +5 --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/ftpchroot.5 +++ linux-ftpd-ssl-0.17.27+0.3/debian/ftpchroot.5 @@ -0,0 +1,28 @@ +.\" Copyright (c) 1999 Herbert Xu (herbert@gondor.apana.org.au), +.\" Copyright (c) 1994 Peter Tobias (tobias@server.et-inf.fho-emden.de), +.\" This file may be distributed under the GNU General Public License. +.TH FTPCHROOT 5 "1999 April 1st" "Linux" "Linux Programmer's Manual" +.SH NAME +ftpchroot \- file which lists users who need to be chrooted +.SH DESCRIPTION +\fB/etc/ftpchroot\fP is used by +.BR ftpd(8); +the file contains a list of users who need to be chrooted before the ftp +service is offered. Blank lines and lines beginning with "#" are ignored. +Remember that the whole line will be used for the username, so please +don't use the "#" character after a name to comment this entry. +.SH EXAMPLES +.B /etc/ftpchroot +may contain the following entries: +.sp +# +.br +# /etc/ftpusers +.br +# +.br +not_so_anonymous +.SH FILES +/etc/ftpchroot +.SH "SEE ALSO" +.BR ftp "(1), " ftpd "(8)" --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/changelog +++ linux-ftpd-ssl-0.17.27+0.3/debian/changelog @@ -0,0 +1,480 @@ +linux-ftpd-ssl (0.17.27+0.3-2ubuntu1) intrepid; urgency=low + + * Merge from Debian unstable, Remaining Ubuntu changes: (LP: #235190) + - debian/control: Add update-inetd to ftpd-ssl's dependencies + - debian/control: Add openbsd-inetd | inet-superserver dependencies + as ftpd-ssl needs an inet server to work + - Modify Maintainer value to match Debian-Maintainer-Field Spec + + -- Emanuele Gentili Tue, 27 May 2008 17:58:03 +0200 + +linux-ftpd-ssl (0.17.27+0.3-2) unstable; urgency=low + + * Create debian/NEWS with details of openssl problems + and key rollover. + * Explicitly depend/build-depend on fixed openssl. + * ftpd/ftpd.c: Set default ssl key/cert file to /etc/ftpd-ssl/ftpd.pem. + * postinst: + + On new installs don't bother with -z cert and -z key, as we + can now use the defaults. + + Revert to update-inetd logic from linux-ftpd. + * postrm: Only remove inetd entry on purge, and only if it is commented out. + * Add private copy of openssl.cnf from openssl 0.9.8g-10 (See #372105). + * debian/control: + + Added DM-Upload-Allowed: yes. + + -- Ian Beckwith Sun, 25 May 2008 19:24:55 +0100 + +linux-ftpd-ssl (0.17.27+0.3-1) unstable; urgency=low + + * New maintainer (Closes: #476132). + * Update to linux-ftpd 0.17-27. + * Fix all warnings in source. + * ftpd.8: Document SSL options, fix typo. + * debian/control: + + Standards-Version: 3.7.3 (no changes). + * debian/rules: + + Support DEB_BUILD_OPTIONS=noopt. + + Added -Wl,-z,defs -Wl,--as-needed to LDFLAGS. + + Fixed make distclean invocation. + + Removed unused install-stamp. + + Removed unnecessary debhelper calls. + * debian/postinst: worked round checkbashism false positive. + * debian/postrm: fixed wording of error message. + * debian/copyright: added copyright info for SSL patches. + * Bumped debhelper compat level to 5. + * Use linux-ftpd_0.17.orig.tar.gz as our orig.tar.gz. + + -- Ian Beckwith Wed, 23 Apr 2008 01:06:35 +0100 + +linux-ftpd (0.17-27) unstable; urgency=low + + * Ignore missing ../MCONFIG in clean target. (Closes: #436720) + + -- Alberto Gonzalez Iniesta Wed, 08 Aug 2007 20:49:22 +0200 + +linux-ftpd (0.17-26) unstable; urgency=low + + * Removed Depends on update-inetd, since it should be provided by + inetd-superserver. + + -- Alberto Gonzalez Iniesta Tue, 07 Aug 2007 18:02:11 +0200 + +linux-ftpd (0.17-25) unstable; urgency=low + + * Condition the call to update-inetd in postrm. (Closes: #416745) + * Moved netbase dependency to openbsd-inetd | inet-superserver. + * Added Depends on update-inetd + * Moved to debhelper compat 4. (Removed debian/conffiles) + * Bumped Standards-Version to 3.7.2.2. No change + + -- Alberto Gonzalez Iniesta Sat, 31 Mar 2007 19:43:37 +0200 + +linux-ftpd (0.17-24) unstable; urgency=low + + * pam.d/ftpd. Updated PAM configuration to used common-* files. + Thanks a lot Pierre Gaufillet for the patch (Closes: #308651) + + -- Alberto Gonzalez Iniesta Thu, 14 Dec 2006 12:14:53 +0100 + +linux-ftpd (0.17-23) unstable; urgency=high + + * Urgency set due to security fix. + * Corrected typo in patch used in previous upload that + made the server run some commands with EGID 'root'. + Thanks to Matt Power (for finding out) and + Stefan Cornelius from Gentoo (for warning me). + + -- Alberto Gonzalez Iniesta Sat, 25 Nov 2006 18:54:59 +0100 + +linux-ftpd (0.17-22) unstable; urgency=high + + * Fixing two security bugs: + - Fixed ftpd from doing chdir while running as root. + (Closes: #384454) Thanks a lot to Paul Szabo for finding out + and the patch. + - Check the return value from setuid calls to avoid running + code as root. Thanks Paul Szabo for the patch. + + -- Alberto Gonzalez Iniesta Fri, 15 Sep 2006 13:14:25 +0200 + +linux-ftpd (0.17-21) unstable; urgency=low + + * Patched ftpcmd.y to allow building on amd64 with gcc-4.0. + Thanks Andreas Jochens for the patch. (Closes: #300245) + + -- Alberto Gonzalez Iniesta Sun, 10 Jul 2005 08:48:19 +0200 + +linux-ftpd (0.17-20) unstable; urgency=low + + * New maintainer. + + -- Alberto Gonzalez Iniesta Sat, 12 Mar 2005 12:07:29 +0100 + +linux-ftpd (0.17-19) unstable; urgency=low + + * Add -n option to log numeric IPs rather than doing reverse lookup (for + improved log forensics in the event an attacker has control of their + reverse DNS.). Thanks Dean Gaudet. (Closes: #258369) + * Fix Build-Depends to avoid relying on virtual package 'libpam-dev' + exclussively. + * Convert changelog to UTF-8. + + -- Robert Millan Wed, 11 Aug 2004 22:08:44 +0200 + +linux-ftpd-ssl (0.17.18+0.3-9.1ubuntu1) hardy; urgency=low + + * Merge from Debian unstable (LP: #176175). Remaining Ubuntu changes: + - debian/control: Add update-inetd to ftpd-ssl's dependencies + - debian/control: Add openbsd-inetd | inet-superserver dependencies + as ftpd-ssl needs an inet server to work + - Modify Maintainer value to match Debian-Maintainer-Field Spec + * Bump Standards-Version to 3.7.3 + * Updated lintian warnings (distclean) + + -- Pedro Fragoso Thu, 13 Dec 2007 16:50:47 +0000 + +linux-ftpd-ssl (0.17.18+0.3-9.1) unstable; urgency=high + + * Non-maintainer upload by the testing-security team. + * Fix remote denial of service cause by passing an + uninitialized file stream to fopen().Initializing file + with NULL and checking for NULL before calling fclose() + fixes this (CVE-2007-6263; Closes: #454733). + + -- Nico Golde Mon, 10 Dec 2007 18:34:40 +0100 + +linux-ftpd-ssl (0.17.18+0.3-9ubuntu1) gutsy; urgency=low + + * Merge from Debian unstable. Remaining Ubuntu changes: + - debian/control: Add update-inetd to ftpd-ssl's dependencies + - debian/control: Add openbsd-inetd | inet-superserver dependencies + as ftpd-ssl needs an inet server to work + * Modify Maintainer value to match Debian-Maintainer-Field Spec + + -- Lionel Porcheron Fri, 04 May 2007 15:31:13 +0200 + +linux-ftpd-ssl (0.17.18+0.3-9) unstable; urgency=low + + * debian/postrm: invoke update-inetd if it is present. + (Closes: #416746) + + -- Cai Qian Mon, 3 Apr 2007 00:00:00 +0800 + +linux-ftpd-ssl (0.17.18+0.3-8) unstable; urgency=low + + * debian/control: dropped update-inetd,as netbase has already + provided it. + * debian/postrm: replaced update-inetd with sed. (Closes: #416746) + * debian/conffile: dropped it. + + -- Cai Qian Mon, 2 Apr 2007 16:00:00 +0800 + +linux-ftpd-ssl (0.17.18+0.3-7) unstable; urgency=low + + * debian/control: depends on update-inetd. (Closes: #351204, #416746) + + -- Cai Qian Fri, 30 Mar 2007 16:00:00 +0800 + +linux-ftpd-ssl (0.17.18+0.3-6ubuntu1) feisty; urgency=low + + * debian/control: Add update-inetd to ftpd-ssl's dependencies + (Closes Ubuntu: #76097). + * debian/control: Add openbsd-inetd | inet-superserver dependencies + as ftpd-ssl needs an inet server to work + + -- Lionel Porcheron Sun, 17 Dec 2006 10:30:13 +0100 + +linux-ftpd-ssl (0.17.18+0.3-6) unstable; urgency=low + + * Move the certificate file to /etc/ftpd-ssl. Patch from James Westby + . (Closes: #368420) + * Remove debian/conffile + + -- Cai Qian Sat, 01 July 2006 12:27:01 +0100 + +linux-ftpd-ssl (0.17.18+0.3-5) unstable; urgency=high + + * applied security patch for CVE-2005-3524. (Closes: #339074) + + -- Cai Qian Fri, 18 Nov 2005 17:27:01 +0000 + +linux-ftpd-ssl (0.17.18+0.3-4) unstable; urgency=low + + * applied gcc4/amd64 patch by Andreas Jochens (Closes: #300247) + + -- Cai Qian Wed, 28 Sep 2005 01:04:00 +0100 + +linux-ftpd-ssl (0.17.18+0.3-3) unstable; urgency=low + + * encoded changelog to UTF-8 + * followed debhelper V4 + + -- Cai Qian Mon, 15 Nov 2004 22:45:00 +0800 + +linux-ftpd-ssl (0.17.18+0.3-2) unstable; urgency=low + + * New maintainer (Closes: #250711) + * Change debian/rules to fix missing ftpd.8 + + -- Cai Qian Sun, 27 Sep 2004 01:45:00 +0800 + +linux-ftpd-ssl (0.17.18+0.3-1) unstable; urgency=low + + * Bring linux-ftpd in line with current netkit-telnet + * Build for sid/sarge + * Make ftp-ssl protocol compatible with + http://www.ietf.org/internet-drafts/draft-murray-auth-ftp-ssl-09.txt + or http://www.ietf.org/rfc/rfc2228.txt. This can break compatiblility + with older ftp-ssl (closes: #154138) + + -- Christoph Martin Thu, 27 May 2004 15:00:27 +0200 + +linux-ftpd (0.17-18) unstable; urgency=low + + * New maintainer. (Closes: #249709) + - control (Maintainer): Set myself. + + -- Robert Millan Wed, 19 May 2004 02:09:10 +0200 + +linux-ftpd (0.17-17) unstable; urgency=low + + * Documented the need for libnss_files.so.2 (closes: #241687). + + -- Herbert Xu Sat, 24 Apr 2004 17:48:37 +1000 + +linux-ftpd (0.17-16) unstable; urgency=low + + * Fixed ftpd entry existence test in postinst. + * Added missing -q for last grep in postinst. + * Removed debconf message about globbing attacks. + * Fixed type-punning warning in pam_doit. + * Removed stamp files for build and install. + * Fixed const cast warning in ftpcmd.y. + + -- Herbert Xu Sat, 21 Jun 2003 14:20:35 +1000 + +linux-ftpd (0.17-15) unstable; urgency=low + + * Removed description of bogus -p option (closes: #180652). + + -- Herbert Xu Thu, 6 Mar 2003 20:26:16 +1100 + +linux-ftpd (0.17-14) unstable; urgency=low + + * Added Spanish debconf translation (Carlos Valdivia Yagüe, closes: #143956). + * Call ls without -g (closes #156992). + + -- Herbert Xu Sun, 25 Aug 2002 10:09:07 +1000 + +linux-ftpd (0.17-13) unstable; urgency=low + + * Added Russian debconf translation (Ilgiz Kalmetev, closes: #135840). + + -- Herbert Xu Thu, 18 Apr 2002 19:18:28 +1000 + +linux-ftpd-ssl (0.17.12+0.3-2) unstable; urgency=low + + * moved from nonus to main + + -- Christoph Martin Sat, 23 Mar 2002 12:18:50 +0100 + +linux-ftpd-ssl (0.17.12+0.3-1) unstable; urgency=low + + * Fixed REST/STOR combination with OpenBSD patch (#132974). + * REST now accepts intmax_t (#126766). + * Built with support for large files (#122961). + * Added sample limits.conf entry against globbing (#121074). + * Added Brazilian debconf template (Andre Luis Lopes, #120835). + * Always specify the syslog facility explicitly (#121644). + + -- Christoph Martin Thu, 7 Mar 2002 09:57:26 +0100 + +linux-ftpd (0.17-12) unstable; urgency=low + + * Fixed REST/STOR combination with OpenBSD patch (closes: #132974). + + -- Herbert Xu Sat, 9 Feb 2002 14:50:45 +1100 + +linux-ftpd (0.17-11) unstable; urgency=low + + * REST now accepts intmax_t (closes: #126766). + + -- Herbert Xu Sun, 20 Jan 2002 19:03:22 +1100 + +linux-ftpd (0.17-10) unstable; urgency=low + + * Built with support for large files (closes: #122961). + + -- Herbert Xu Sun, 9 Dec 2001 17:45:53 +1100 + +linux-ftpd (0.17-9) unstable; urgency=low + + * Added sample limits.conf entry against globbing (closes: #121074). + * Added Brazilian debconf template (Andre Luis Lopes, closes: #120835). + * Always specify the syslog facility explicitly (closes: #121644). + + -- Herbert Xu Sat, 1 Dec 2001 18:28:51 +1100 + +linux-ftpd-ssl (0.17.8+0.3-1) unstable; urgency=low + + * bring in line with linux-ftpd + * Debconf (see 113611) + * pam_limits used + + -- Christoph Martin Wed, 21 Nov 2001 16:05:54 +0100 + +linux-ftpd (0.17-8) unstable; urgency=low + + * Added German debconf template (Sebastian Feltel, closes: #113611). + + -- Herbert Xu Sat, 13 Oct 2001 08:13:55 +1000 + +linux-ftpd (0.17-7) unstable; urgency=low + + * Added debconf about globbing attacks. + + -- Herbert Xu Thu, 23 Aug 2001 19:49:01 +1000 + +linux-ftpd (0.17-6) unstable; urgency=low + + * Register sessions with PAM. + * Use pam_limits by default. + * Documented the procedure to counter globbing attacks. + + -- Herbert Xu Sat, 9 Jun 2001 13:25:27 +1000 + +linux-ftpd-ssl (0.17.5+0.3-1) unstable; urgency=low + + * Remove Provides ftpd (closes: #93532) + * Bring in line with linux-ftpd (see 96640 and 93217) + * new upstream patch (0.3) brings working -z secure (closes: #92873) + which can now force ftpd to only accept secure connections + * add SSL options to manpage (closes: #92602) + + -- Christoph Martin Sun, 13 May 2001 13:44:58 +0200 + +linux-ftpd (0.17-5) unstable; urgency=low + + * Removed duplicate authentication error message (closes: #96640). + + -- Herbert Xu Mon, 7 May 2001 22:08:29 +1000 + +linux-ftpd (0.17-4) unstable; urgency=low + + * The value of unique is now passed to dataconn (closes: #93217). + + -- Herbert Xu Sun, 22 Apr 2001 09:33:26 +1000 + +linux-ftpd-ssl (0.17.4+0.2-1) unstable; urgency=low + + * bring linux-ftpd updates to -ssl + * builddepends on libssl-dev + + -- Christoph Martin Sat, 10 Mar 2001 17:48:45 +0100 + +linux-ftpd (0.17-3) unstable; urgency=low + + * Fixed anonymous authentication bug when PAM is disabled (Liviu Daia, + Abraham vd Merwe, Rainer Weikusat, closes: #88837). + * Fixed patterns used to check for existing ftp services (closes: #85579). + + -- Herbert Xu Fri, 9 Mar 2001 22:30:37 +1100 + +linux-ftpd-ssl (0.17.2+0.2-1) unstable; urgency=low + + * initial linux-ftpd-ssl version + + -- Christoph Martin Sun, 18 Feb 2001 14:27:54 +0100 + +linux-ftpd (0.17-2) unstable; urgency=high + + * Applied bug fix from OpenBSD (closes: #78973). + + -- Herbert Xu Thu, 7 Dec 2000 19:47:47 +1100 + +linux-ftpd (0.17-1) unstable; urgency=low + + * New upstream release (identical to 0.16-2). + + -- Herbert Xu Sat, 12 Aug 2000 13:29:38 +1000 + +linux-ftpd (0.16-2) unstable; urgency=high + + * Fixed a security hole discovered by OpenBSD, thanks to Thomas Roessler for + notifying me (closes: #66832). + * Added build-time dependency on debhelper. + + -- Herbert Xu Fri, 7 Jul 2000 10:15:38 +1000 + +linux-ftpd (0.16-1) unstable; urgency=low + + * New upstream release. + * Added Source-Depends on bison (closes: #61160). + * Removed checks on the remote address of the data connection which violated + RFC 959 (closes: #59251). + + -- Herbert Xu Mon, 24 Apr 2000 20:46:00 +1000 + +linux-ftpd (0.11-9) frozen unstable; urgency=low + + * Added Bource-Depends on libpam0g-dev (closes: #49917). + + -- Herbert Xu Sat, 18 Mar 2000 12:50:14 +1100 + +linux-ftpd (0.11-8) unstable; urgency=low + + * Added entry for ~ftp/lib in in.ftpd(8) (closes: #49035). + + -- Herbert Xu Sat, 6 Nov 1999 12:21:37 +1100 + +linux-ftpd (0.11-7) unstable; urgency=low + + * Added missing dependencies on netbase and libpam-modules (closes: #48411). + + -- Herbert Xu Wed, 27 Oct 1999 09:25:59 +1000 + +linux-ftpd (0.11-6) unstable; urgency=low + + * Anonymous users other than ftp should work now (closes: #48252). + + -- Herbert Xu Mon, 25 Oct 1999 16:38:16 +1000 + +linux-ftpd (0.11-5) unstable; urgency=low + + * Installed files according to the FHS. + * Applied PAM patch from Olaf Kirch. + * Renamed PAM file to ftp. + + -- Herbert Xu Thu, 7 Oct 1999 22:19:58 +1000 + +linux-ftpd (0.11-4) unstable; urgency=low + + * Rewritten PAM code to remove hack for ftp prompt. + * Provide/conflict with ftp-server (fixes #42412). + + -- Herbert Xu Fri, 10 Sep 1999 10:32:04 +1000 + +linux-ftpd (0.11-3) unstable; urgency=low + + * Fixed incorrect usage of update-inetd in postinst (fixes #40771). + + -- Herbert Xu Mon, 5 Jul 1999 17:46:41 +1000 + +linux-ftpd (0.11-2) unstable; urgency=low + + * Don't use absoluet paths in PAM configuration file (fixes #38985). + + -- Herbert Xu Sat, 19 Jun 1999 12:10:03 +1000 + +linux-ftpd (0.11-1) unstable; urgency=low + + * Split from netstd. + * Added support for PAM. + * Pad with zeros instead of spaces in setproctitle. + * Add a note about ftp-bugs in README (fixes #29733). + * Made response to STOU commands conform to RFC 1123 (fixes #32490). + + -- Herbert Xu Thu, 1 Apr 1999 13:45:20 +1000 + + --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/pam.d/ftp +++ linux-ftpd-ssl-0.17.27+0.3/debian/pam.d/ftp @@ -0,0 +1,13 @@ +# Standard behaviour for ftpd(8). +auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed + +# This line is required by ftpd(8). +auth sufficient pam_ftp.so + +# Uncomment this to achieve what used to be ftpd -A. +#auth required pam_listfile.so item=user sense=allow file=/etc/ftpchroot onerr=fail + +# Standard blurb. +@include common-auth +@include common-account +@include common-session --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/prerm +++ linux-ftpd-ssl-0.17.27+0.3/debian/prerm @@ -0,0 +1,6 @@ +#!/bin/sh -e +# $Id: prerm,v 1.1 1999/04/16 07:00:29 herbert Exp $ + +update-inetd --pattern '/usr/sbin/in\.ftpd' --disable ftp + +#DEBHELPER# --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/copyright +++ linux-ftpd-ssl-0.17.27+0.3/debian/copyright @@ -0,0 +1,40 @@ +This package was split from netstd by Herbert Xu herbert@debian.org on +Thu, 1 Apr 1999 16:42:48 +1000. + +netstd was created by Peter Tobias tobias@et-inf.fho-emden.de on +Wed, 20 Jul 1994 17:23:21 +0200. + +It was downloaded from ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/. + +Copyright: + +/************************************************************************ + Copyright 1988, 1991 by Carnegie Mellon University + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of Carnegie Mellon University not be used +in advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. +************************************************************************/ + +/* + * The modifications to support SSLeay were done by Tim Hudson + * tjh@cryptsoft.com + * + * You can do whatever you like with these patches except pretend that + * you wrote them. + * + */ --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/preinst +++ linux-ftpd-ssl-0.17.27+0.3/debian/preinst @@ -0,0 +1,12 @@ +#!/bin/sh -e +# $Id: preinst,v 1.1 1999/10/07 12:48:39 herbert Exp $ + +# Rename old PAM conffile. +if [ -n "$2" ] && dpkg --compare-versions "$2" lt 0.11-5; then + cd /etc/pam.d + if [ -f ftpd -a ! -f ftp ]; then + cp -p ftpd ftp + fi +fi + +#DEBHELPER# --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/control +++ linux-ftpd-ssl-0.17.27+0.3/debian/control @@ -0,0 +1,28 @@ +Source: linux-ftpd-ssl +Section: net +Priority: extra +Maintainer: Ubuntu MOTU Developers +XSBC-Original-Maintainer: Ian Beckwith +Build-Depends: bison, debhelper (>= 5), libpam-dev, libssl-dev +Standards-Version: 3.7.3 +DM-Upload-Allowed: yes + +Package: ftpd-ssl +Architecture: any +Depends: openbsd-inetd | inet-superserver, libpam-modules, openssl (>= 0.9.2b), libssl0.9.8, ${shlibs:Depends}, ${misc:Depends} + netbase, update-inetd +Provides: ftp-server +Conflicts: ftp-server, ftpd +Replaces: ftpd +Description: FTP server with SSL encryption support + This is the netkit ftp server with encryption support. + . + ftpd-ssl replaces normal ftpd using SSL authentication and encryption. + It interoperates with normal ftp. + It checks if the other side is also talking SSL, if not it falls back + to normal ftp protocol. + . + Advantages over normal ftp(d): Your passwords and the data you send + will not go in cleartext over the line. Nobody can get it with + tcpdump or similar tools. + --- linux-ftpd-ssl-0.17.27+0.3.orig/debian/README.Debian +++ linux-ftpd-ssl-0.17.27+0.3/debian/README.Debian @@ -0,0 +1,37 @@ +ftpd for Debian +--------------- + +ftpd now supports PAM. It is recommended that you leave the pam_ftp entry +alone in the pam configuration file since ftpd uses it to figure out prompts +and determining anonymity. + +The best way to disable anonymous ftp is to place ftp and anonymous in +/etc/ftpusers. Removing the user ftp from the system also works. + +The -A option no longer has any effect since authentication is done by PAM. +To recover its functionality, just uncomment the ftpchroot line in the pam +configuration file. + +If you wish to receive reports from users of your ftp server, you should setup +an alias for ftp-bugs@name.of.your.ftp.server. + +Globbing Attacks +---------------- + +Globbing attacks aimed at exhausting memory/CPU resources (e.g., +ls ../*/../*/../*/../*/../*/../*/../*/../*/../*/../*/../*/../*/../*) can be +countered by setting the appropriate resource limits in +/etc/security/limits.conf. To do so, you need to make sure that /etc/pam.d/ftp +contains the line + +session required pam_limits.so + +Which is the case by default. The limits which are most important on Linux are +"as" and "cpu". For example, to limit the memory usage to 10MB, you should put + +ftp hard as 10240 + +in /etc/security/limits.conf. + +Herbert +$Id: README.Debian,v 1.4 2002/10/06 22:23:49 herbert Exp $ --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/ftpcmd.y +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/ftpcmd.y @@ -1,3 +1,15 @@ +/* + * The modifications to support SSLeay we done by Tim Hudson + * tjh@mincom.oz.au + * + * You can do whatever you like with these patches except pretend that + * you wrote them. + * + * Email ssl-users-request@mincom.oz.au to get instructions on how to + * join the mailing list that discusses SSLeay and also these patches. + * + */ + /* * Copyright (c) 1985, 1988, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -55,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +105,20 @@ extern int portcheck; extern struct sockaddr_in his_addr; +#ifdef USE_SSL +/*#include "ssl_port.h"*/ +typedef struct ssl_st SSL; +int SSL_write(SSL *ssl,const char *buf,int num); +extern int do_ssl_start(void); +extern int ssl_getc(SSL *ssl_con); +extern int ssl_secure_flag; +extern int ssl_active_flag; +extern SSL *ssl_con; +#define FFLUSH(X) (ssl_active_flag && (((X)==cin)||((X)==cout)) ? 1 : fflush((X)) ) +#define GETC(X) (ssl_active_flag && (((X)==cin)||((X)==cout)) ? ssl_getc(ssl_con) : getc((X)) ) +extern FILE *cin, *cout; +#endif /* USE_SSL */ + off_t restart_point; static int cmd_type; @@ -100,7 +127,14 @@ char cbuf[512]; char *fromname; -struct tab; +struct tab { + const char *name; + short token; + short state; + short implemented; /* 1 if command is implemented */ + const char *help; +}; + static int yylex __P((void)); static void sizecmd __P((char *)); static void help __P((struct tab *, char *)); @@ -111,8 +145,9 @@ %} %union { - int i; - char *s; + intmax_t i; + char *s; + const char *cs; } %token @@ -129,7 +164,7 @@ STAT HELP NOOP MKD RMD PWD CDUP STOU SMNT SYST SIZE MDTM - UMASK IDLE CHMOD + UMASK IDLE CHMOD AUTH LEXERR @@ -138,7 +173,7 @@ %type check_login octal_number byte_size %type struct_code mode_code type_code form_code -%type pathstring pathname password username +%type pathstring pathname password username auth_type %type host_port %start cmd_list @@ -156,13 +191,43 @@ ; cmd - : USER SP username CRLF + : AUTH SP auth_type CRLF + { + if (!strncmp((char *) $3,"SSL",3)) { +#ifdef USE_SSL + reply(234, "AUTH SSL OK."); + + /* now do all the hard work :-) */ + do_ssl_start(); + +#else /* !USE_SSL */ + reply(504,"AUTH type not supported."); +#endif /* USE_SSL */ + } else { + reply(504,"AUTH type not supported."); + } + if ($3 != NULL) + free((char *)$3); + } + | USER SP username CRLF { +#ifdef USE_SSL + if (ssl_secure_flag && !ssl_active_flag) { + reply(504,"SSL is mandatory."); + break; + } +#endif /* USE_SSL */ user($3); free($3); } | PASS SP password CRLF { +#ifdef USE_SSL + if (ssl_secure_flag && !ssl_active_flag) { + reply(504,"SSL is mandatory."); + break; + } +#endif /* USE_SSL */ pass($3); memset($3, 0, strlen($3)); free($3); @@ -312,12 +377,12 @@ | LIST check_login CRLF { if ($2) - retrieve("/bin/ls -lgA", ""); + retrieve("/bin/ls -lA", ""); } | LIST check_login SP pathname CRLF { if ($2 && $4 != NULL) - retrieve("/bin/ls -lgA %s", $4); + retrieve("/bin/ls -lA %s", $4); if ($4 != NULL) free($4); } @@ -595,9 +660,9 @@ { if ($2) { fromname = (char *) 0; - restart_point = $4; /* XXX $4 is only "int" */ - reply(350, "Restarting at %qd. %s", - (quad_t) restart_point, + restart_point = $4; + reply(350, "Restarting at %jd. %s", + (intmax_t) restart_point, "Send STORE or RETRIEVE to initiate transfer."); } } @@ -607,6 +672,10 @@ : STRING ; +auth_type + : STRING + ; + password : /* empty */ { @@ -832,15 +901,8 @@ #define SITECMD 7 /* SITE command */ #define NSTR 8 /* Number followed by a string */ -struct tab { - const char *name; - short token; - short state; - short implemented; /* 1 if command is implemented */ - const char *help; -}; - struct tab cmdtab[] = { /* In order defined in RFC 765 */ + { "AUTH", AUTH, STR1, 1, " auth_type" }, { "USER", USER, STR1, 1, " username" }, { "PASS", PASS, ZSTR1, 1, " password" }, { "ACCT", ACCT, STR1, 0, "(specify account)" }, @@ -923,6 +985,7 @@ { int c; register char *cs; + char buf[16]; cs = s; /* tmpline may contain saved command from urgent mode interruption */ @@ -931,30 +994,41 @@ if (tmpline[c] == '\n') { *cs++ = '\0'; if (debug) - syslog(LOG_DEBUG, "command: %s", s); + syslog(LOG_FTP | LOG_DEBUG, "command: %s", s); tmpline[0] = '\0'; return(s); } if (c == 0) tmpline[0] = '\0'; } - while ((c = getc(iop)) != EOF) { + while ((c = GETC(iop)) != EOF) { c &= 0377; if (c == IAC) { - if ((c = getc(iop)) != EOF) { + if ((c = GETC(iop)) != EOF) { c &= 0377; switch (c) { case WILL: case WONT: - c = getc(iop); - printf("%c%c%c", IAC, DONT, 0377&c); - (void) fflush(stdout); + c = GETC(iop); + sprintf(buf,"%c%c%c", IAC, DONT, 0377&c); +#ifdef USE_SSL + if (ssl_active_flag) + SSL_write(ssl_con,buf,strlen(buf)); + else +#endif /* USE_SSL */ + fwrite(buf,strlen(buf),1,stdout); + (void) FFLUSH(stdout); continue; case DO: case DONT: - c = getc(iop); - printf("%c%c%c", IAC, WONT, 0377&c); - (void) fflush(stdout); + c = GETC(iop); + sprintf(buf,"%c%c%c", IAC, WONT, 0377&c); +#ifdef USE_SSL + if (ssl_active_flag) + SSL_write(ssl_con,buf,strlen(buf)); + else +#endif /* USE_SSL */ + (void) FFLUSH(stdout); continue; case IAC: break; @@ -973,7 +1047,7 @@ if (debug) { if (!guest && strncasecmp("pass ", s, 5) == 0) { /* Don't syslog passwords */ - syslog(LOG_DEBUG, "command: %.5s ???", s); + syslog(LOG_FTP | LOG_DEBUG, "command: %.5s ???", s); } else { register char *cp; register int len; @@ -985,7 +1059,7 @@ --cp; --len; } - syslog(LOG_DEBUG, "command: %.*s", len, s); + syslog(LOG_FTP | LOG_DEBUG, "command: %.*s", len, s); } } return (s); @@ -998,7 +1072,7 @@ reply(421, "Timeout (%d seconds): closing control connection.", timeout); if (logging) - syslog(LOG_INFO, "User %s timed out after %d seconds", + syslog(LOG_FTP | LOG_INFO, "User %s timed out after %d seconds", (pw ? pw -> pw_name : "unknown"), timeout); dologout(1); } @@ -1052,7 +1126,7 @@ /* NOTREACHED */ } state = p->state; - yylval.s = (char *)p->name; /* XXX */ + yylval.cs = p->name; return (p->token); } break; @@ -1078,7 +1152,7 @@ /* NOTREACHED */ } state = p->state; - yylval.s = (char *) p->name; /* XXX */ + yylval.cs = p->name; return (p->token); } state = CMD; @@ -1143,7 +1217,7 @@ ; c = cbuf[cpos]; cbuf[cpos] = '\0'; - yylval.i = atoi(cp); + yylval.i = strtoimax(cp, 0, 10); cbuf[cpos] = c; state = STR1; return (NUMBER); @@ -1158,7 +1232,7 @@ ; c = cbuf[cpos]; cbuf[cpos] = '\0'; - yylval.i = atoi(cp); + yylval.i = strtoimax(cp, 0, 10); cbuf[cpos] = c; return (NUMBER); } @@ -1314,7 +1388,7 @@ if (stat(filename, &stbuf) < 0 || !S_ISREG(stbuf.st_mode)) reply(550, "%s: not a plain file.", filename); else - reply(213, "%qu", (quad_t) stbuf.st_size); + reply(213, "%ju", (uintmax_t) stbuf.st_size); break; } case TYPE_A: { FILE *fin; @@ -1340,7 +1414,7 @@ } (void) fclose(fin); - reply(213, "%qd", (quad_t) count); + reply(213, "%jd", (intmax_t) count); break; } default: reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/logwtmp.c +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/logwtmp.c @@ -41,7 +41,6 @@ "$Id: logwtmp.c,v 1.5 1999/07/16 00:34:29 dholland Exp $"; #include -#include #include #include @@ -49,6 +48,7 @@ #include #include #include +#include #include "extern.h" static int fd = -1; --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/Makefile +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/Makefile @@ -1,7 +1,7 @@ include ../MCONFIG -CFLAGS+=-I../support -LIBS+=-L../support -lsupport +CFLAGS+=-I../support -DUSE_SSL -g +LIBS+=-L../support -lsupport -lssl -lcrypto OBJS=ftpd.o ftpcmd.o logutmp.o logwtmp.o popen.o --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/sslapp.c +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/sslapp.c @@ -0,0 +1,186 @@ +/* sslapp.c - ssl application code */ + +/* + * The modifications to support SSLeay were done by Tim Hudson + * tjh@cryptsoft.com + * + * You can do whatever you like with these patches except pretend that + * you wrote them. + * + * Email ssl-users-request@lists.cryptsoft.com to get instructions on how to + * join the mailing list that discusses SSLeay and also these patches. + * + */ + +#ifdef USE_SSL + +#include "sslapp.h" + +SSL_CTX *ssl_ctx; +SSL *ssl_con; +int ssl_debug_flag=0; +int ssl_only_flag=0; +int ssl_active_flag=0; +int ssl_verify_flag=SSL_VERIFY_NONE; +int ssl_secure_flag=0; +int ssl_certsok_flag=0; +int ssl_cert_required=0; +int ssl_verbose_flag=0; +int ssl_disabled_flag=0; +char *ssl_cert_file=NULL; +char *ssl_key_file=NULL; +char *ssl_cipher_list=NULL; +char *ssl_log_file=NULL; + +/* fwd decl */ +static void +client_info_callback(const SSL *s, int where, int ret); + +int +do_ssleay_init(int server) +{ + char *p; + + /* make sure we have somewhere we can log errors to */ + if (bio_err==NULL) { + if ((bio_err=BIO_new(BIO_s_file()))!=NULL) { + if (ssl_log_file==NULL) + BIO_set_fp(bio_err,stderr,BIO_NOCLOSE); + else { + if (BIO_write_filename(bio_err,ssl_log_file)<=0) { + /* not a lot we can do */ + } + } + } + } + + /* rather simple things these days ... the old SSL_LOG and SSL_ERR + * vars are long gone now SSLeay8 has rolled around and we have + * a clean interface for doing things + */ + if (ssl_debug_flag) + BIO_printf(bio_err,"SSL_DEBUG_FLAG on\r\n"); + + + /* init things so we will get meaningful error messages + * rather than numbers + */ + SSL_load_error_strings(); + + SSLeay_add_ssl_algorithms(); + ssl_ctx=(SSL_CTX *)SSL_CTX_new(SSLv23_method()); + + /* we may require a temp 512 bit RSA key because of the + * wonderful way export things work ... if so we generate + * one now! + */ + if (server) { + if (SSL_CTX_need_tmp_RSA(ssl_ctx)) { + RSA *rsa; + + if (ssl_debug_flag) + BIO_printf(bio_err,"Generating temp (512 bit) RSA key ...\r\n"); + rsa=RSA_generate_key(512,RSA_F4,NULL,NULL); + if (ssl_debug_flag) + BIO_printf(bio_err,"Generation of temp (512 bit) RSA key done\r\n"); + + if (!SSL_CTX_set_tmp_rsa(ssl_ctx,rsa)) { + BIO_printf(bio_err,"Failed to assign generated temp RSA key!\r\n"); + } + RSA_free(rsa); + if (ssl_debug_flag) + BIO_printf(bio_err,"Assigned temp (512 bit) RSA key\r\n"); + } + } + + /* also switch on all the interoperability and bug + * workarounds so that we will communicate with people + * that cannot read poorly written specs :-) + */ + SSL_CTX_set_options(ssl_ctx,SSL_OP_ALL); + + /* the user can set whatever ciphers they want to use */ + if (ssl_cipher_list==NULL) { + p=getenv("SSL_CIPHER"); + if (p!=NULL) + SSL_CTX_set_cipher_list(ssl_ctx,p); + } else + SSL_CTX_set_cipher_list(ssl_ctx,ssl_cipher_list); + + /* for verbose we use the 0.6.x info callback that I got + * eric to finally add into the code :-) --tjh + */ + if (ssl_verbose_flag) { + SSL_CTX_set_info_callback(ssl_ctx,client_info_callback); + } + + /* Add in any certificates if you want to here ... */ + if (ssl_cert_file) { + if (!SSL_CTX_use_certificate_file(ssl_ctx, ssl_cert_file, + X509_FILETYPE_PEM)) { + BIO_printf(bio_err,"Error loading %s: ",ssl_cert_file); + ERR_print_errors(bio_err); + BIO_printf(bio_err,"\r\n"); + return(0); + } else { + if (!ssl_key_file) + ssl_key_file = ssl_cert_file; + if (!SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, ssl_key_file, + X509_FILETYPE_PEM)) { + BIO_printf(bio_err,"Error loading %s: ",ssl_key_file); + ERR_print_errors(bio_err); + BIO_printf(bio_err,"\r\n"); + return(0); + } + } + } + + /* make sure we will find certificates in the standard + * location ... otherwise we don't look anywhere for + * these things which is going to make client certificate + * exchange rather useless :-) + */ + SSL_CTX_set_default_verify_paths(ssl_ctx); + + /* now create a connection */ + ssl_con=(SSL *)SSL_new(ssl_ctx); + SSL_set_verify(ssl_con,ssl_verify_flag,NULL); + +#if 0 + SSL_set_verify(ssl_con,ssl_verify_flag,client_verify_callback); +#endif + + return(1); +} + + +static void +client_info_callback(const SSL *s, int where, int ret) +{ + if (where==SSL_CB_CONNECT_LOOP) { + BIO_printf(bio_err,"SSL_connect:%s %s\r\n", + SSL_state_string(s),SSL_state_string_long(s)); + } else if (where==SSL_CB_CONNECT_EXIT) { + if (ret == 0) { + BIO_printf(bio_err,"SSL_connect:failed in %s %s\r\n", + SSL_state_string(s),SSL_state_string_long(s)); + } else if (ret < 0) { + BIO_printf(bio_err,"SSL_connect:error in %s %s\r\n", + SSL_state_string(s),SSL_state_string_long(s)); + } + } +} + + +#else /* !USE_SSL */ + +/* something here to stop warnings if we build without SSL support */ +static int dummy_func() +{ + int i; + + i++; +} + +#endif /* USE_SSL */ + --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/popen.c +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/popen.c @@ -169,8 +169,13 @@ * XXX: this doesn't seem right... and shouldn't * we initgroups, or at least setgroups(0,0)? */ - setgid(getegid()); - setuid(i); + +/* + * PSz 25 Aug 06 Must check the return status of these setgid/setuid calls, + * see http://www.bress.net/blog/archives/34-setuid-madness.html + */ + if ( setgid(getegid()) != 0 ) _exit(1); + if ( setuid(i) != 0 ) _exit(1); #ifndef __linux__ /* --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/sslapp.h +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/sslapp.h @@ -0,0 +1,63 @@ +/* sslapp.h - ssl application code */ + +/* + * The modifications to support SSLeay were done by Tim Hudson + * tjh@cryptsoft.com + * + * You can do whatever you like with these patches except pretend that + * you wrote them. + * + * Email ssl-users-request@mincom.oz.au to get instructions on how to + * join the mailing list that discusses SSLeay and also these patches. + * + */ + +#ifdef USE_SSL + +#include + +#include + +#define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n) +#define ONELINE_NAME(X) X509_NAME_oneline(X,NULL,0) + +#define OLDPROTO NOPROTO +#define NOPROTO +#include +#undef NOPROTO +#define NOPROTO OLDPROTO +#undef OLDPROTO +#include + +#include +#include +#include + +extern BIO *bio_err; +extern SSL *ssl_con; +extern SSL_CTX *ssl_ctx; +extern int ssl_debug_flag; +extern int ssl_only_flag; +extern int ssl_active_flag; +extern int ssl_verify_flag; +extern int ssl_secure_flag; +extern int ssl_verbose_flag; +extern int ssl_disabled_flag; +extern int ssl_cert_required; +extern int ssl_certsok_flag; + +extern char *ssl_log_file; +extern char *ssl_cert_file; +extern char *ssl_key_file; +extern char *ssl_cipher_list; + +/* we hide all the initialisation code in a separate file now */ +extern int do_ssleay_init(int server); + +/*extern int display_connect_details(); +extern int server_verify_callback(); +extern int client_verify_callback();*/ + +#endif /* USE_SSL */ + + --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/ssl_port.h +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/ssl_port.h @@ -0,0 +1,86 @@ +/* ssl_port.h - standard porting things + * + * The modifications to support SSLeay were done by Tim Hudson + * tjh@mincom.oz.au + * + * You can do whatever you like with these patches except pretend that + * you wrote them. + * + * Email ssl-users-request@mincom.oz.au to get instructions on how to + * join the mailing list that discusses SSLeay and also these patches. + * + */ + +#ifndef HEADER_SSL_PORT_H +#define HEADER_SSL_PORT_H + +#ifdef USE_SSL + +#include + +#define OLDPROTO NOPROTO +#undef NOPROTO +#define NOPROTO +#include +#undef NOPROTO +#define NOPROTO OLDPROTO + +#include +#include +#include + +extern SSL *ssl_con; +extern SSL_CTX *ssl_ctx; +extern int ssl_debug_flag; +extern int ssl_only_flag; +extern int ssl_active_flag; +extern int ssl_verify_flag; +extern int ssl_secure_flag; +extern int ssl_enabled; + +extern int ssl_encrypt_data; +extern SSL *ssl_data_con; +extern int ssl_data_active_flag; + +extern char *my_ssl_cert_file; +extern char *my_ssl_key_file; +extern int ssl_certsok_flag; + +extern int set_ssl_trace(SSL *s); + +extern FILE *cin, *cout; + +#define is_ssl_fd(X,Y) ( (SSL_get_fd((X))==0) || \ + (SSL_get_fd((X))==1) || \ + (SSL_get_fd((X))==pdata) || \ + (SSL_get_fd((X))==(Y)) \ + ) + +#define is_ssl_fp(X,Y) ( ( (SSL_get_fd((X))==0) && (fileno((Y))==0) ) || \ + ( (SSL_get_fd((X))==1) && (fileno((Y))==1) ) || \ + ( (SSL_get_fd((X))==pdata) && \ + (fileno((Y))==pdata) ) || \ + (SSL_get_fd((X))==fileno(Y)) \ + ) + +/* these macros make things much easier to handle ... */ + +#define FFLUSH(X) (ssl_active_flag && (((X)==cin)||((X)==cout)) ? 1 : fflush((X)) ) + +#define GETC(X) (ssl_active_flag && (((X)==cin)||((X)==cout)) ? ssl_getc(ssl_con) : getc((X)) ) + +#define DATAGETC(X) (ssl_data_active_flag && ((fileno(X)==data)||(fileno(X)==pdata)) ? ssl_getc(ssl_data_con) : getc((X)) ) +#define DATAPUTC(X,Y) (ssl_data_active_flag && ((fileno(Y)==data)||(fileno(Y)==pdata)) ? ssl_putc(ssl_data_con,(X)) : putc((X),(Y)) ) +#define DATAFLUSH(X) (ssl_data_active_flag && ((fileno(X)==data)||(fileno(X)==pdata)) ? ssl_putc_flush(ssl_data_con) : fflush((X)) ) + +#else + +#define GETC(X) getc((X)) +#define DATAGETC(X) getc((X)) +#define DATAPUTC(X,Y) putc((X),(Y)) +#define DATAFLUSH(X) fflush((X)) +#define FFLUSH(X) fflush((X)) + +#endif /* USE_SSL */ + +#endif /* HEADER_SSL_PORT_H */ --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/ftpd.8 +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/ftpd.8 @@ -46,10 +46,18 @@ Internet File Transfer Protocol server .Sh SYNOPSIS .Nm ftpd -.Op Fl AdDhlMPSU +.Op Fl AdDhlMnPSU .Op Fl T Ar maxtimeout .Op Fl t Ar timeout .Op Fl u Ar mask +.Op Fl z Ar debug +.Op Fl z Ar certsok +.Op Fl z Ar certrequired +.Op Fl z Ar secure +.Op Fl z Ar verify=flags +.Op Fl z Ar cert=certfile +.Op Fl z Ar key=keyfile +.Op Fl z Ar ciper=list .Sh DESCRIPTION .Nm Ftpd is the @@ -67,7 +75,9 @@ .It Fl A Permit only anonymous ftp connections or accounts listed in .Pa /etc/ftpchroot. -Other connection attempts are refused. +Other connection attempts are refused. This option is nolonger effective if +PAM is enabled. Please refer to the README file for instructions to doing +this with PAM. .It Fl d Debugging information is written to the syslog using LOG_FTP. .It Fl D @@ -103,12 +113,8 @@ the IP number the client connected to, and located inside .Pa ~ftp is used instead. -.It Fl p -Disable passive mode ftp connections. This is useful if you are behind -a firewall that refuses connections to arbitrary high numbered ports. -Many ftp clients try passive mode first and do not always react gracefully -to a server that refuses connections to the port it asked the client to -connect to. +.It Fl n +Use numeric IP addresses in logs instead of doing hostname lookup. .It Fl P Permit illegal port numbers or addresses for PORT command initiated connects. By default @@ -146,6 +152,53 @@ .It Fl u Change the default umask from 027 to .Ar mask . +.It Fl z Ar SSL-parameter +This option is only valid if +.Nm ftpd +has been built with SSL (Secure Socket Layer) support. +.Bl -tag -width Fl +.It Ic debug +Enable SSL related debugging. +.It Ic ssl +Negotiate SSL at first, then use ftp protocol. In this mode ftpd +only accepts connections from SSL enhanced ftp with option +.Ic -z ssl . +(Not yet implemented) +.It Ic nossl, !ssl +switch off SSL negotiation +.It Ic certsok +Look username up in /etc/ssl.users. The format of this file is lines +of this form: +.Ar user1,user2:/C=US/..... +where user1 and user2 are usernames. If client certificate is valid, +authenticate without password. +.It Ic certrequired +client certificate is mandatory +.It Ic secure +Don't switch back to unencrypted mode (no SSL) if SSL is not available. +.It Ic verify=int +.\" TODO +Set the SSL verify flags (SSL_VERIFY_* in +.Ar ssl/ssl.h +). +.\" TODO +.It Ic cert=cert_file +.\" TODO +Use the certificate(s) in +.Ar cert_file . +.It Ic key=key_file +.\" TODO +Use the key(s) in +.Ar key_file . +.It Ic cipher=ciph_list +.\" TODO +Set the preferred ciphers to +.Ar ciph_list . +.\" TODO: possible values; comma-separated list? +(See +.Ar ssl/ssl.h +). +.El .El .Pp The file @@ -356,6 +409,29 @@ .Pa motd , if present, will be printed after a successful login. These files should be mode 444. +.It Pa ~ftp/lib +Make this directory owned by +.Dq root +and unwritable by anyone (mode 511). +The libraries +.Xr ld-linux.so.2 +and +.Xr libc.so.6 +(or whatever your +.Xr ls +command is linked to) +must be present. +In order to read +.Xr passwd 5 +and +.Xr group 5 , +the library +.Xr libnss_files.so.2 +is also needed. +Note that if you're using a 2.2.* or later Linux kernel, +.Xr ld-linux.so.2 +must be executable as well as readable (555). All other files should be mode +444. .It Pa ~ftp/pub Make this directory mode 555 and owned by .Dq root . --- linux-ftpd-ssl-0.17.27+0.3.orig/ftpd/ftpd.c +++ linux-ftpd-ssl-0.17.27+0.3/ftpd/ftpd.c @@ -1,3 +1,15 @@ +/* + * The modifications to support SSLeay were done by Tim Hudson + * tjh@cryptsoft.com + * + * You can do whatever you like with these patches except pretend that + * you wrote them. + * + * Email ssl-users-request@lists.cryptsoft.com to get instructions on how to + * join the mailing list that discusses SSLeay and also these patches. + * + */ + /* * Copyright (c) 1985, 1988, 1990, 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -80,6 +92,7 @@ #include #include #include +#include #include #include #include @@ -95,8 +108,6 @@ #else #include /* for initgroups() */ /* #include * for L_SET et al. * <--- not used? */ -/*typedef int64_t quad_t;*/ -typedef unsigned int useconds_t; #endif #include "../version.h" @@ -126,12 +137,82 @@ #include "pathnames.h" #include "extern.h" +#ifdef USE_SSL + +#include "sslapp.c" + +BIO *bio_err; +SSL *ssl_data_con; +int ssl_auto_login=0; + +#if 0 +#include "rsa.h" /* extra ... */ +/* +#include "asn1.h" +*/ +#include +#include +#include +/* +#include "ssl_err.h" +*/ + +SSL *ssl_con; +SSL_CTX *ssl_ctx; +int ssl_debug_flag=0; +int ssl_only_flag=0; +int ssl_active_flag=0; +int ssl_secure_flag=0; +int ssl_verify_flag=SSL_VERIFY_NONE; +int ssl_certsok_flag=0; +#endif + +static char *auth_ssl_name=NULL; +FILE *cin, *cout; + +int ssl_data_active_flag=0; + +/* for the moment this is a compile time option only --tjh */ +int ssl_encrypt_data=1; + +#define DEFAULT_SSL_FILE "/etc/ftpd-ssl/ftpd.pem" +char ssl_file_path[1024]; /* don't look at that nasty value to the left */ + +X509 *ssl_public_cert; +RSA *ssl_private_key; + +static char *my_ssl_key_file=NULL; +static char *my_ssl_cert_file=NULL; + +#include "ssl_port.h" + +int +do_ssl_start(void); +int +ssl_getc(SSL *ssl_con); +static int +ssl_putc(SSL *ssl_con,int oneint); +static int +ssl_putc_flush(SSL *ssl_con); + +#endif /* USE_SSL */ + #ifdef __STDC__ #include #else #include #endif +#ifdef USE_PAM +#include +#include +#include +/* backward compatibility hack for libpam < 0.58 */ +#ifndef PAM_ESTABLISH_CRED +#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH +#endif +#endif + static char versionpre[] = "Version 6.4/OpenBSD/Linux"; static char version[sizeof(versionpre)+sizeof(pkg)]; @@ -156,7 +237,8 @@ #endif int debug = 0; int timeout = 900; /* timeout after 15 minutes of inactivity */ -int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */ +int maxtimeout = 7200; /* don't allow idle time to be set beyond 2 hours */ +int numeric_hosts = 0; /* log numeric IP rather than doing lookup */ int logging; int high_data_ports = 0; int anon_only = 0; @@ -218,29 +300,37 @@ char proctitle[BUFSIZ]; /* initial part of title */ #endif /* HASSETPROCTITLE */ +#ifdef USE_PAM +static pam_handle_t *pamh; +static char *PAM_username; +static char *PAM_password; +static char *PAM_message; +static int PAM_accepted; +#endif + #define LOGCMD(cmd, file) \ if (logging > 1) \ - syslog(LOG_INFO,"%s %s%s", cmd, \ + syslog(LOG_FTP | LOG_INFO,"%s %s%s", cmd, \ *(file) == '/' ? "" : curdir(), file); #define LOGCMD2(cmd, file1, file2) \ if (logging > 1) \ - syslog(LOG_INFO,"%s %s%s %s%s", cmd, \ + syslog(LOG_FTP | LOG_INFO,"%s %s%s %s%s", cmd, \ *(file1) == '/' ? "" : curdir(), file1, \ *(file2) == '/' ? "" : curdir(), file2); #define LOGBYTES(cmd, file, cnt) \ if (logging > 1) { \ if (cnt == (off_t)-1) \ - syslog(LOG_INFO,"%s %s%s", cmd, \ + syslog(LOG_FTP | LOG_INFO,"%s %s%s", cmd, \ *(file) == '/' ? "" : curdir(), file); \ else \ - syslog(LOG_INFO, "%s %s%s = %qd bytes", cmd, \ - *(file) == '/' ? "" : curdir(), file, (quad_t)(cnt)); \ + syslog(LOG_FTP | LOG_INFO, "%s %s%s = %jd bytes", cmd, \ + *(file) == '/' ? "" : curdir(), file, (intmax_t)(cnt)); \ } static void ack __P((const char *)); static void myoob __P((int)); static int checkuser __P((const char *, const char *)); -static FILE *dataconn __P((const char *, off_t, const char *)); +static FILE *dataconn __P((const char *, off_t, const char *, int)); static void dolog __P((struct sockaddr_in *)); static const char *curdir __P((void)); static void end_login __P((void)); @@ -255,6 +345,7 @@ sgetpwnam __P((const char *)); static char *sgetsave __P((char *)); static void reapchild __P((int)); +static void authentication_setup(const char *); #if defined(TCPWRAPPERS) static int check_host __P((struct sockaddr_in *)); @@ -294,7 +385,7 @@ socklen_t addrlen; char *cp, line[LINE_MAX]; FILE *fd; - const char *argstr = "AdDhlMSt:T:u:UvP"; + const char *argstr = "AdDhlMnSt:T:u:UvPz:"; struct hostent *hp; #ifdef __linux__ @@ -354,6 +445,10 @@ multihome = 1; break; + case 'n': + numeric_hosts = 1; + break; + case 'S': stats = 1; break; @@ -390,12 +485,196 @@ debug = 1; break; +#ifdef USE_SSL + case 'z': + if (strcmp(optarg, "debug") == 0 ) { + ssl_debug_flag=1; + } + if (strcmp(optarg, "verbose") == 0 ) { + ssl_verbose_flag=1; + } + if (strcmp(optarg, "ssl") == 0 ) { + ssl_only_flag=1; + } + if (strcmp(optarg, "secure") == 0 ) { + ssl_secure_flag=1; + } + if (strcmp(optarg, "certsok") == 0) { + ssl_certsok_flag=1; + } + if (strncmp(optarg, "verify=", strlen("verify=")) == 0 ) { + ssl_verify_flag=atoi(optarg+strlen("verify=")); + + } + if (strncmp(optarg, "cert=", strlen("cert=")) == 0 ) { + my_ssl_cert_file=optarg+strlen("cert="); + } + if (strncmp(optarg, "key=", strlen("key=")) == 0 ) { + my_ssl_key_file=optarg+strlen("key="); + } + /* we have swallowed an extra arg */ + /*argc--; + argv++;*/ + break; +#endif /* USE_SSL */ + default: warnx("unknown flag -%c ignored", optopt); break; } } +#ifdef USE_SSL + /* make sure we have access to the required certificate + * and key files now ... before we perhaps chroot and + * do the other "muck" for anon-ftp style setup ... though + * why we want to run SSL for anon I don't know + */ + + { +#if 0 + int i; + FILE *fp; + char *filename; +#endif + + /* keep the macros that are common between the client + * and the server happy + */ + cin=stdin; + cout=stderr; + + if (my_ssl_cert_file==NULL) { + strcpy(ssl_file_path,DEFAULT_SSL_FILE); + ssl_cert_file=ssl_file_path; + } else { + ssl_cert_file=my_ssl_cert_file; + } + + if (!do_ssleay_init(1)) { + fprintf(stderr,"ftpd: SSLeay initialisation failed\n"); + fflush(stderr); + sleep(1); + exit(1); + } + +#if 0 + /* if we are not running in debug then any error + * stuff from SSL debug *must* not go down + * the socket (which 0,1,2 are all pointing to by + * default) + */ + if (ssl_debug_flag) { + if (standalone) { + SSL_ERR=stderr; + SSL_LOG=stderr; + } else { + (void)freopen("ftpd.err","w",stderr); + SSL_ERR=stderr; + SSL_LOG=NULL; + SSL_debug("ftpd.log"); + if (SSL_LOG==NULL) { + SSL_LOG=fopen("ftpd.log","w"); + if (SSL_LOG==NULL) + SSL_LOG=stderr; + } + } + } else { + /* disable all the debug and trace */ + SSL_LOG=SSL_ERR=NULL; /**/ + } + + if (ssl_debug_flag) { + if (SSL_LOG!=NULL) { + fprintf(SSL_LOG,"SSL_LOG started\n"); + fflush(SSL_LOG); + } + if (SSL_ERR!=NULL) { + fprintf(SSL_ERR,"SSL_ERR started\n"); + fflush(SSL_ERR); + } + } + + SSL_load_error_strings(); + + ssl_ctx=SSL_CTX_new(); + + /* I really should syslog any of the following + * errors but I haven't bothered at this stage + * as that can wait + */ +/* + if (!X509_set_default_verify_paths(ssl_ctx->cert)) +*/ + if (!SSL_set_default_verify_paths(ssl_ctx)) { + fprintf(stderr,"ftpd: cannot set default path via X509_set_default_verify_paths\n"); + fflush(stderr); + sleep(1); + exit(1); + } + +#if 0 + sprintf(ssl_file_path,"%s/%s",X509_get_default_cert_dir(), + "ftpd.cert"); +#endif + + strcpy(ssl_file_path,DEFAULT_SSL_FILE); + + filename=my_ssl_cert_file==NULL?ssl_file_path:my_ssl_cert_file; + fp=fopen(filename,"r"); + if (fp==NULL) { + fprintf(stderr,"ftpd: cannot open public cert file \"%s\"\n",filename); + fflush(stderr); + exit(1); + } + + ssl_public_cert=X509_new(); + if (PEM_read_X509(fp,&ssl_public_cert,NULL)==NULL) { + fprintf(stderr,"ftpd: error reading public cert - %s\n", + ERR_error_string(ERR_get_error(),NULL)); + fflush(stderr); + exit(1); + } + fclose(fp); + + if (ssl_debug_flag) { + fprintf(SSL_LOG,"ftpd: got public cert\n"); + fflush(SSL_LOG); + } + +#if 0 + sprintf(ssl_file_path,"%s/private/%s",X509_get_default_cert_area(), + "ftpd.key"); +#endif + + strcpy(ssl_file_path,DEFAULT_SSL_FILE); + + filename=my_ssl_key_file==NULL?ssl_file_path:my_ssl_key_file; + fp=fopen(filename,"r"); + if (fp==NULL) { + fprintf(stderr,"ftpd: cannot open private key file \"%s\"\n",filename); + fflush(stderr); + exit(1); + } + + ssl_private_key=RSA_new(); + if (PEM_read_RSAPrivateKey(fp,&ssl_private_key,NULL)==0) { + fprintf(stderr,"ftpd: error reading private key - %s\n", + ERR_error_string(ERR_get_error(),NULL)); + fflush(stderr); + exit(1); + } + fclose(fp); + + if (ssl_debug_flag) { + fprintf(SSL_LOG,"ftpd: got private key\n"); + fflush(SSL_LOG); + } +#endif + + } +#endif /* USE_SSL */ + (void) freopen(_PATH_DEVNULL, "w", stderr); /* @@ -415,7 +694,7 @@ * Detach from parent. */ if (daemon(1, 1) < 0) { - syslog(LOG_ERR, "failed to become a daemon"); + syslog(LOG_FTP | LOG_ERR, "failed to become a daemon"); exit(1); } (void) signal(SIGCHLD, reapchild); @@ -424,7 +703,8 @@ */ sv = getservbyname("ftp", "tcp"); if (sv == NULL) { - syslog(LOG_ERR, "getservbyname for ftp failed"); + syslog(LOG_FTP | LOG_ERR, + "getservbyname for ftp failed"); exit(1); } /* @@ -433,22 +713,22 @@ */ ctl_sock = socket(AF_INET, SOCK_STREAM, 0); if (ctl_sock < 0) { - syslog(LOG_ERR, "control socket: %m"); + syslog(LOG_FTP | LOG_ERR, "control socket: %m"); exit(1); } if (setsockopt(ctl_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) - syslog(LOG_ERR, "control setsockopt: %m");; + syslog(LOG_FTP | LOG_ERR, "control setsockopt: %m");; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = sv->s_port; if (bind(ctl_sock, (struct sockaddr *)&server_addr, sizeof(server_addr))) { - syslog(LOG_ERR, "control bind: %m"); + syslog(LOG_FTP | LOG_ERR, "control bind: %m"); exit(1); } if (listen(ctl_sock, 32) < 0) { - syslog(LOG_ERR, "control listen: %m"); + syslog(LOG_FTP | LOG_ERR, "control listen: %m"); exit(1); } /* @@ -478,7 +758,8 @@ addrlen = sizeof(his_addr); if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) { - syslog(LOG_ERR, "getpeername (%s): %m", argv[0]); + syslog(LOG_FTP | LOG_ERR, "getpeername (%s): %m", + argv[0]); exit(1); } } @@ -490,29 +771,29 @@ (void) signal(SIGPIPE, lostconn); (void) signal(SIGCHLD, SIG_IGN); if (signal(SIGURG, myoob) == SIG_ERR) - syslog(LOG_ERR, "signal: %m"); + syslog(LOG_FTP | LOG_ERR, "signal: %m"); addrlen = sizeof(ctrl_addr); if (getsockname(0, (struct sockaddr *)&ctrl_addr, &addrlen) < 0) { - syslog(LOG_ERR, "getsockname (%s): %m", argv[0]); + syslog(LOG_FTP | LOG_ERR, "getsockname (%s): %m", argv[0]); exit(1); } #ifdef IP_TOS tos = IPTOS_LOWDELAY; if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); + syslog(LOG_FTP | LOG_WARNING, "setsockopt (IP_TOS): %m"); #endif data_source.sin_port = htons(ntohs(ctrl_addr.sin_port) - 1); /* Try to handle urgent data inline */ #ifdef SO_OOBINLINE if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)) < 0) - syslog(LOG_ERR, "setsockopt: %m"); + syslog(LOG_FTP | LOG_ERR, "setsockopt: %m"); #endif #ifdef F_SETOWN if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) - syslog(LOG_ERR, "fcntl F_SETOWN: %m"); + syslog(LOG_FTP | LOG_ERR, "fcntl F_SETOWN: %m"); #endif dolog(&his_addr); /* @@ -583,13 +864,13 @@ (void)signo; if (debug) - syslog(LOG_DEBUG, "lost connection"); + syslog(LOG_FTP | LOG_DEBUG, "lost connection"); dologout(-1); } static void sigquit(int signo) { - syslog(LOG_ERR, "got signal %s", strsignal(signo)); + syslog(LOG_FTP | LOG_ERR, "got signal %s", strsignal(signo)); dologout(-1); } @@ -648,6 +929,9 @@ static int askpasswd; /* had user command, ask for passwd */ static char curname[16]; /* current USER name */ +int +good_ssl_user(char *name); + /* * USER command. * Sets global passwd pointer pw if named account exists and is acceptable; @@ -658,10 +942,15 @@ * requesting login privileges. Disallow anyone who does not have a standard * shell as returned by getusershell(). Disallow anyone mentioned in the file * _PATH_FTPUSERS to allow people such as root and uucp to be avoided. + * + * pw maybe unset if we're using PAM and the login turns out to be anonymous. + * -- herbert */ void user(char *name) { +#ifndef USE_PAM const char *cp, *shell; +#endif if (logged_in) { if (guest) { @@ -674,6 +963,9 @@ end_login(); } +#ifdef USE_PAM + authentication_setup(name); +#else guest = 0; if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { if (checkuser(_PATH_FTPUSERS, "ftp") || @@ -687,7 +979,7 @@ } else reply(530, "User %s unknown.", name); if (!askpasswd && logging) - syslog(LOG_NOTICE, + syslog(LOG_FTP | LOG_NOTICE, "ANONYMOUS FTP LOGIN REFUSED FROM %s", remotehost); return; } @@ -707,17 +999,19 @@ if (cp == NULL || checkuser(_PATH_FTPUSERS, name)) { reply(530, "User %s access denied.", name); if (logging) - syslog(LOG_NOTICE, + syslog(LOG_FTP | LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s", remotehost, name); pw = (struct passwd *) NULL; return; } } - if (logging) { - strncpy(curname, name, sizeof(curname)-1); - curname[sizeof(curname)-1] = '\0'; - } +#ifdef USE_SSL + if (pw && good_ssl_user(name)) { + reply(331, "Send dummy password to login."); + ssl_auto_login = 1; + } else +#endif #ifdef SKEY if (!skey_haskey(name)) { char *myskey, *skey_keyinfo __P((char *name)); @@ -728,6 +1022,11 @@ } else #endif reply(331, "Password required for %s.", name); +#endif + if (logging) { + strncpy(curname, name, sizeof(curname)-1); + curname[sizeof(curname)-1] = '\0'; + } askpasswd = 1; /* @@ -774,9 +1073,19 @@ sigprocmask (SIG_BLOCK, &allsigs, NULL); (void) seteuid((uid_t)0); if (logged_in) { +#ifdef USE_PAM + int error; + error = pam_close_session(pamh, 0); + pam_end(pamh, error); + pamh = 0; +#endif ftpdlogwtmp(ttyline, "", ""); if (doutmp) logout(utmp.ut_line); +#if defined(KERBEROS) + if (!notickets && krbtkfile_env) + unlink(krbtkfile_env); +#endif } pw = NULL; logged_in = 0; @@ -784,9 +1093,214 @@ dochroot = 0; } +#ifdef USE_PAM +/* + * PAM authentication, now using the PAM's async feature. + */ +static int PAM_conv (int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + struct pam_response *repl = NULL; + int retval, count = 0, replies = 0; + int size = sizeof(struct pam_response); + +#define GET_MEM \ + if (!(repl = realloc(repl, size))) \ + return PAM_CONV_ERR; \ + size += sizeof(struct pam_response) +#define COPY_STRING(s) (s) ? strdup(s) : NULL + + (void) appdata_ptr; + retval = PAM_SUCCESS; + for (count = 0; count < num_msg; count++) { + int savemsg = 0; + + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + GET_MEM; + repl[replies].resp_retcode = PAM_SUCCESS; + repl[replies].resp = COPY_STRING(PAM_username); + replies++; + break; + case PAM_PROMPT_ECHO_OFF: + GET_MEM; + if (PAM_password == 0) { + savemsg = 1; + retval = PAM_CONV_AGAIN; + } else { + repl[replies].resp_retcode = PAM_SUCCESS; + repl[replies].resp = COPY_STRING(PAM_password); + replies++; + } + break; + case PAM_TEXT_INFO: + savemsg = 1; + break; + case PAM_ERROR_MSG: + default: + /* Must be an error of some sort... */ + retval = PAM_CONV_ERR; + } + + if (savemsg) { + char *sp; + + if (PAM_message) { + /* XXX: make sure we split newlines correctly */ + lreply(331, "%s", PAM_message); + free(PAM_message); + } + PAM_message = COPY_STRING(msg[count]->msg); + + /* Remove trailing `: ' */ + sp = PAM_message + strlen(PAM_message); + while (sp > PAM_message && strchr(" \t\n:", *--sp)) + *sp = '\0'; + } + + /* In case of error, drop responses and return */ + if (retval) { + _pam_drop_reply(repl, replies); + return retval; + } + } + if (repl) + *resp = repl; + return PAM_SUCCESS; +} + +static struct pam_conv PAM_conversation = { + &PAM_conv, + NULL +}; + +static int pam_doit(void) +{ + int error; + + error = pam_authenticate(pamh, 0); + if (error == PAM_CONV_AGAIN || error == PAM_INCOMPLETE) { + /* Avoid overly terse passwd messages */ + if (PAM_message && !strcasecmp(PAM_message, "password")) { + free(PAM_message); + PAM_message = 0; + } + if (PAM_message == 0) { + reply(331, "Password required for %s.", PAM_username); + } else { + reply(331, "%s", PAM_message); + free(PAM_message); + PAM_message = 0; + } + return 1; + } + if (error == PAM_SUCCESS) { + const void *vp; + + /* Alright, we got it */ + error = pam_acct_mgmt(pamh, 0); + if (error == PAM_SUCCESS) + error = pam_open_session(pamh, 0); + if (error == PAM_SUCCESS) + error = pam_setcred(pamh, PAM_ESTABLISH_CRED); + if (error == PAM_SUCCESS) + error = pam_get_item(pamh, PAM_USER, &vp); + if (error == PAM_SUCCESS) { + const char *user = vp; + + if (strcmp(user, "ftp") == 0) { + guest = 1; + } + pw = sgetpwnam(user); + } + if (error == PAM_SUCCESS && pw) + PAM_accepted = 1; + } + + return (error == PAM_SUCCESS); +} + + +static void authentication_setup(const char *username) +{ + int error; + + if (pamh != 0) { + pam_end(pamh, PAM_ABORT); + pamh = 0; + } + + if (PAM_username) + free(PAM_username); + PAM_username = strdup(username); + PAM_password = 0; + PAM_message = 0; + PAM_accepted = 0; + + error = pam_start("ftp", PAM_username, &PAM_conversation, &pamh); + if (error == PAM_SUCCESS) + error = pam_set_item(pamh, PAM_RHOST, remotehost); + if (error != PAM_SUCCESS) { + reply(550, "Authentication failure"); + pam_end(pamh, error); + pamh = 0; + } + + if (pamh && !pam_doit()) + reply(550, "Authentication failure"); +} + +static int authenticate(char *passwd) +{ + if (PAM_accepted) + return 1; + + if (pamh == 0) + return 0; + + PAM_password = passwd; + pam_doit(); + PAM_password = 0; + return PAM_accepted; +} + +#else /* !USE_PAM */ +static int authenticate(char *passwd) +{ + if (pw == NULL) { + useconds_t us; + + /* Sleep between 1 and 3 seconds to emulate a crypt. */ +#ifndef __linux__ + us = arc4random() % 3000000; +#else + us = random() % 3000000; +#endif + usleep(us); + return 0; + } + +#if defined(KERBEROS) + if (klogin(pw, "", hostname, passwd) == 0) + return 1; +#endif +#ifdef SKEY + if (skey_haskey(pw->pw_name) == 0 && + (skey_passcheck(pw->pw_name, passwd) != -1)) + return 1; +#endif + /* the strcmp does not catch null passwords! */ + if (pw == NULL || *pw->pw_passwd == '\0' || + strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd)) + return 0; /* failure */ + + return 1; +} +#endif /* !USE_PAM */ + + void pass(char *passwd) { - int rval; FILE *fd; static char homedir[MAXPATHLEN]; char rootdir[MAXPATHLEN]; @@ -797,84 +1311,62 @@ return; } askpasswd = 0; - if (!guest) { /* "ftp" is only account allowed no password */ - if (pw == NULL) { - useconds_t us; - - /* Sleep between 1 and 3 seconds to emulate a crypt. */ -#ifndef __linux__ - us = arc4random() % 3000000; -#else - us = random() % 3000000; -#endif - usleep(us); - rval = 1; /* failure below */ - goto skip; - } -#if defined(KERBEROS) - rval = klogin(pw, "", hostname, passwd); - if (rval == 0) - goto skip; +#ifndef USE_PAM + if (!guest +#ifdef USE_SSL + && !ssl_auto_login #endif -#ifdef SKEY - if (skey_haskey(pw->pw_name) == 0 && - (skey_passcheck(pw->pw_name, passwd) != -1)) { - rval = 0; - goto skip; - } + ) { /* "ftp" is only account allowed no password */ #endif - /* the strcmp does not catch null passwords! */ - if (strcmp(crypt(passwd, pw->pw_passwd), pw->pw_passwd) || - *pw->pw_passwd == '\0') { - rval = 1; /* failure */ - goto skip; - } - rval = 0; - -skip: /* - * If rval == 1, the user failed the authentication check - * above. If rval == 0, either Kerberos or local authentication - * succeeded. + * Try to authenticate the user */ - if (rval) { + if (!authenticate(passwd)) { reply(530, "Login incorrect."); if (logging) - syslog(LOG_NOTICE, + syslog(LOG_FTP | LOG_NOTICE, "FTP LOGIN FAILED FROM %s, %s", remotehost, curname); pw = NULL; if (login_attempts++ >= 5) { - syslog(LOG_NOTICE, + syslog(LOG_FTP | LOG_NOTICE, "repeated login failures from %s", remotehost); exit(0); } return; } +#ifdef USE_PAM + if (guest +#ifdef USE_SSL + || ssl_auto_login +#endif + ) { +#else } else { +#endif /* Save anonymous' password. */ guestpw = strdup(passwd); if (guestpw == (char *)NULL) fatal("Out of memory"); } login_attempts = 0; /* this time successful */ -#ifdef USE_SHADOW +#if defined(USE_SHADOW) && !defined(USE_PAM) switch (isexpired(spw)) { case 0: /* success */ break; case 1: - syslog(LOG_NOTICE, "expired password from %s, %s", + syslog(LOG_FTP | LOG_NOTICE, "expired password from %s, %s", remotehost, pw->pw_name); reply(530, "Please change your password and try again."); return; case 2: - syslog(LOG_NOTICE, "inactive login from %s, %s", + syslog(LOG_FTP | LOG_NOTICE, "inactive login from %s, %s", remotehost, pw->pw_name); reply(530, "Login inactive -- contact administrator."); return; case 3: - syslog(LOG_NOTICE, "expired login from %s, %s", + syslog(LOG_FTP | LOG_NOTICE, "expired login from %s, %s", remotehost, pw->pw_name); reply(530, "Account expired -- contact administrator."); return; @@ -940,6 +1432,13 @@ } strcpy(pw->pw_dir, "/"); setenv("HOME", "/", 1); + } + /* PSz 25 Aug 06 chdir for real users done after setting UID */ + if (seteuid((uid_t)pw->pw_uid) < 0) { + reply(550, "Can't set uid."); + goto bad; + } + if (guest || dochroot) { /* do nothing, handled above */ } else if (chdir(pw->pw_dir) < 0) { if (chdir("/") < 0) { reply(530, "User %s: can't change directory to %s.", @@ -948,10 +1447,7 @@ } else lreply(230, "No directory! Logging in with home=/"); } - if (seteuid((uid_t)pw->pw_uid) < 0) { - reply(550, "Can't set uid."); - goto bad; - } + sigfillset(&allsigs); sigprocmask(SIG_UNBLOCK,&allsigs,NULL); @@ -991,7 +1487,8 @@ setproctitle("%s", proctitle); #endif /* HASSETPROCTITLE */ if (logging) - syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", + syslog(LOG_FTP | LOG_INFO, + "ANONYMOUS FTP LOGIN FROM %s, %s", remotehost, passwd); } else { reply(230, "User %s logged in.", pw->pw_name); @@ -1001,7 +1498,7 @@ setproctitle("%s", proctitle); #endif /* HASSETPROCTITLE */ if (logging) - syslog(LOG_INFO, "FTP LOGIN FROM %s as %s", + syslog(LOG_FTP | LOG_INFO, "FTP LOGIN FROM %s as %s", remotehost, pw->pw_name); } (void) umask(defumask); @@ -1064,7 +1561,7 @@ goto done; } } - dout = dataconn(name, st.st_size, "w"); + dout = dataconn(name, st.st_size, "w", 0); if (dout == NULL) goto done; time(&start); @@ -1072,6 +1569,15 @@ (restart_point == 0 && cmd == 0 && S_ISREG(st.st_mode))); if ((cmd == 0) && stats) logxfer(name, st.st_size, start); + +#ifdef USE_SSL + if (ssl_data_active_flag && (ssl_data_con!=NULL)) { + SSL_free(ssl_data_con); + ssl_data_active_flag=0; + ssl_data_con=NULL; + } +#endif /* USE_SSL */ + (void) fclose(dout); data = -1; pdata = -1; @@ -1088,6 +1594,9 @@ struct stat st; int fd; + if (restart_point && *mode != 'a') + mode = "r+"; + if (unique && stat(name, &st) == 0) { char *nam; @@ -1097,8 +1606,6 @@ return; } name = nam; - if (restart_point) - mode = "r+"; fout = fdopen(fd, mode); } else fout = fopen(name, mode); @@ -1139,7 +1646,7 @@ goto done; } } - din = dataconn(name, (off_t)-1, "r"); + din = dataconn(name, (off_t)-1, "r", unique); if (din == NULL) goto done; if (receive_data(din, fout) == 0) { @@ -1187,14 +1694,15 @@ goto bad; sleep(tries); } - (void) seteuid((uid_t)pw->pw_uid); +/* PSz 25 Aug 06 Check return status */ + if (seteuid((uid_t)pw->pw_uid) != 0) _exit(1); sigfillset(&allsigs); sigprocmask (SIG_UNBLOCK, &allsigs, NULL); #ifdef IP_TOS on = IPTOS_THROUGHPUT; if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); + syslog(LOG_FTP | LOG_WARNING, "setsockopt (IP_TOS): %m"); #endif #ifdef TCP_NOPUSH /* @@ -1205,13 +1713,13 @@ */ on = 1; if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, (char *)&on, sizeof on) < 0) - syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m"); + syslog(LOG_FTP | LOG_WARNING, "setsockopt (TCP_NOPUSH): %m"); #endif #if 0 /* Respect the user's settings */ #ifdef SO_SNDBUF on = 65536; if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&on, sizeof on) < 0) - syslog(LOG_WARNING, "setsockopt (SO_SNDBUF): %m"); + syslog(LOG_FTP | LOG_WARNING, "setsockopt (SO_SNDBUF): %m"); #endif #endif @@ -1219,7 +1727,8 @@ bad: /* Return the real value of errno (close may change it) */ t = errno; - (void) seteuid((uid_t)pw->pw_uid); +/* PSz 25 Aug 06 Check return status */ + if (seteuid((uid_t)pw->pw_uid) != 0) _exit(1); sigfillset (&allsigs); sigprocmask (SIG_UNBLOCK, &allsigs, NULL); (void) close(s); @@ -1227,17 +1736,17 @@ return (NULL); } -static FILE * dataconn(const char *name, off_t size, const char *mode) +static FILE * dataconn(const char *name, off_t size, const char *mode, int stou) { char sizebuf[32]; - FILE *file; + FILE *file = NULL; int retry = 0, tos; file_size = size; byte_count = 0; if (size != (off_t) -1) { - (void) snprintf(sizebuf, sizeof(sizebuf), " (%lld bytes)", - (quad_t) size); + (void) snprintf(sizebuf, sizeof(sizebuf), " (%jd bytes)", + (intmax_t) size); } else sizebuf[0] = '\0'; if (pdata >= 0) { @@ -1262,6 +1771,7 @@ pdata = -1; return (NULL); } +#ifdef BREAKRFC if (from.sin_addr.s_addr != his_addr.sin_addr.s_addr) { perror_reply(435, "Can't build data connection"); (void) close(pdata); @@ -1269,6 +1779,7 @@ pdata = -1; return (NULL); } +#endif (void) close(pdata); pdata = s; #ifdef IP_TOS @@ -1276,13 +1787,90 @@ (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)); #endif - reply(150, "Opening %s mode data connection for '%s'%s.", - type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); +#ifdef USE_SSL + /* time to negotiate SSL on the data connection ... + * do this via SSL_accept (as we are still the server + * even though things are started around the other way) + * + * note: we really *must* make sure the session stuff + * is copied correctly as we cannot afford a full + * SSL negotiation for each data socket! + */ + /* TODO XXXX fill in the blanks :-) + */ + ssl_data_active_flag=0; + if (ssl_active_flag && ssl_encrypt_data) { + /* do SSL */ + + reply(150, "Opening %s mode SSL data connection for %s%s.", + type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); + + if (ssl_data_con!=NULL) { + SSL_free(ssl_data_con); + ssl_data_con=NULL; + } + ssl_data_con=(SSL *)SSL_new(ssl_ctx); + + /* copy session details ... */ + SSL_copy_session_id(ssl_data_con,ssl_con); + + /* for 0.5.2 - want to change the timeout value etc ... */ + + SSL_set_fd(ssl_data_con,pdata); + SSL_set_verify(ssl_data_con,ssl_verify_flag,NULL); + + /* if is "safe" to read ahead */ + /* SSL_set_read_ahead(ssl_data_con,1); */ + + if (ssl_debug_flag) + BIO_printf(bio_err,"===>START SSL_accept on DATA\n"); + + if (SSL_accept(ssl_data_con)<=0) { + static char errbuf[1024]; + + sprintf(errbuf,"ftpd: SSL_accept DATA error %s\n", + ERR_error_string(ERR_get_error(),NULL)); + perror_reply(425, errbuf); + /* abort time methinks ... */ + if(file != NULL){ + fclose(file); + file = NULL; + } + return NULL; + } else { + if (ssl_debug_flag) { + BIO_printf(bio_err,"[SSL DATA Cipher %s]\n", + SSL_get_cipher(ssl_con)); + } + ssl_data_active_flag=1; + } + + if (ssl_debug_flag) + BIO_printf(bio_err,"===>DONE SSL_accept on DATA\n"); + + } else { +#endif /* USE_SSL */ + if (stou) { + reply(150, "FILE: %s", name); + } else { + reply(150, + "Opening %s mode data connection for '%s'%s.", + type == TYPE_A ? "ASCII" : "BINARY", name, + sizebuf); + } +#ifdef USE_SSL + } +#endif /* USE_SSL */ return (fdopen(pdata, mode)); } if (data >= 0) { - reply(125, "Using existing data connection for '%s'%s.", - name, sizebuf); + if (stou) { + reply(125, "FILE: %s", name); + } else { + reply(125, + "Using existing data connection for '%s'%s.", + name, sizebuf); + } usedefault = 1; return (fdopen(data, mode)); } @@ -1309,12 +1897,14 @@ data = -1; return NULL; } +#ifdef BREAKRFC if (data_dest.sin_addr.s_addr != his_addr.sin_addr.s_addr) { perror_reply(435, "Can't build data connection"); (void) fclose(file); data = -1; return NULL; } +#endif while (connect(data, (struct sockaddr *)&data_dest, sizeof(data_dest)) < 0) { if (errno == EADDRINUSE && retry < swaitmax) { @@ -1327,8 +1917,76 @@ data = -1; return (NULL); } - reply(150, "Opening %s mode data connection for '%s'%s.", - type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); +#ifdef USE_SSL + /* time to negotiate SSL on the data connection ... + * do this via SSL_accept (as we are still the server + * even though things are started around the other way) + * + * note: we really *must* make sure the session stuff + * is copied correctly as we cannot afford a full + * SSL negotiation for each data socket! + */ + /* TODO XXXX fill in the blanks :-) + */ + ssl_data_active_flag=0; + if (ssl_active_flag && ssl_encrypt_data) { + /* do SSL */ + + reply(150, "Opening %s mode SSL data connection for %s%s.", + type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); + + if (ssl_data_con!=NULL) { + SSL_free(ssl_data_con); + ssl_data_con=NULL; + } + ssl_data_con=(SSL *)SSL_new(ssl_ctx); + + /* copy session details ... */ + SSL_copy_session_id(ssl_data_con,ssl_con); + + /* for 0.5.2 - want to change the timeout value etc ... */ + + SSL_set_fd(ssl_data_con,data); + SSL_set_verify(ssl_data_con,ssl_verify_flag,NULL); + + /* if is "safe" to read ahead */ + /* SSL_set_read_ahead(ssl_data_con,1); */ + + if (ssl_debug_flag) + BIO_printf(bio_err,"===>START SSL_accept on DATA\n"); + + if (SSL_accept(ssl_data_con)<=0) { + static char errbuf[1024]; + + sprintf(errbuf,"ftpd: SSL_accept DATA error %s\n", + ERR_error_string(ERR_get_error(),NULL)); + perror_reply(425, errbuf); + /* abort time methinks ... */ + fclose(file); + return NULL; + } else { + if (ssl_debug_flag) + BIO_printf(bio_err,"[SSL DATA Cipher %s]\n", + SSL_get_cipher(ssl_con)); + ssl_data_active_flag=1; + } + + if (ssl_debug_flag) + BIO_printf(bio_err,"===>DONE SSL_accept on DATA\n"); + + } else { +#endif /* USE_SSL */ + if (stou) { + reply(150, "FILE: %s", name); + } else { + reply(150, + "Opening %s mode data connection for '%s'%s.", + type == TYPE_A ? "ASCII" : "BINARY", name, + sizebuf); + } +#ifdef USE_SSL + } +#endif /* USE_SSL */ return (file); } @@ -1357,11 +2015,11 @@ if (c == '\n') { if (ferror(outstr)) goto data_err; - (void) putc('\r', outstr); + (void) DATAPUTC('\r', outstr); } - (void) putc(c, outstr); + (void) DATAPUTC(c, outstr); } - fflush(outstr); + DATAFLUSH(outstr); transflag = 0; if (ferror(instr)) goto file_err; @@ -1379,11 +2037,15 @@ netfd = fileno(outstr); filefd = fileno(instr); - if (isreg && filesize < (off_t)16 * 1024 * 1024) { + if ( +#ifdef USE_SSL + !ssl_data_active_flag && +#endif /* USE_SSL */ + isreg && filesize < (off_t)16 * 1024 * 1024) { buf = mmap(0, filesize, PROT_READ, MAP_SHARED, filefd, (off_t)0); if (buf==MAP_FAILED || buf==NULL) { - syslog(LOG_WARNING, "mmap(%lu): %m", + syslog(LOG_FTP | LOG_WARNING, "mmap(%lu): %m", (unsigned long)filesize); goto oldway; } @@ -1420,6 +2082,13 @@ /* failure is harmless */ } #endif +#ifdef USE_SSL + if (ssl_data_active_flag) { + while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 && + SSL_write(ssl_data_con, buf, cnt) == cnt) + byte_count += cnt; + } else +#endif /* USE_SSL */ while ((cnt = read(filefd, buf, size)) > 0 && write(netfd, buf, cnt) == cnt) byte_count += cnt; @@ -1478,6 +2147,16 @@ case TYPE_L: signal (SIGALRM, lostconn); +#ifdef USE_SSL + if (ssl_data_active_flag) { + while ((cnt = SSL_read(ssl_data_con,buf,sizeof buf)) > 0) { + if (write(fileno(outstr), buf, cnt) != cnt) + goto file_err; + byte_count += cnt; + } + } else +#endif /* !USE_SSL */ + { do { (void) alarm ((unsigned) timeout); cnt = read(fileno(instr), buf, sizeof(buf)); @@ -1489,6 +2168,7 @@ byte_count += cnt; } } while (cnt > 0); + } if (cnt < 0) goto data_err; transflag = 0; @@ -1500,14 +2180,14 @@ return (-1); case TYPE_A: - while ((c = getc(instr)) != EOF) { + while ((c = DATAGETC(instr)) != EOF) { byte_count++; if (c == '\n') bare_lfs++; while (c == '\r') { if (ferror(outstr)) goto data_err; - if ((c = getc(instr)) != '\n') { + if ((c = DATAGETC(instr)) != '\n') { (void) putc ('\r', outstr); if (c == '\0' || c == EOF) goto contin2; @@ -1552,7 +2232,7 @@ int c; char line[LINE_MAX]; - (void)snprintf(line, sizeof(line), "/bin/ls -lgA %s", filename); + (void)snprintf(line, sizeof(line), "/bin/ls -lA %s", filename); fin = ftpd_popen(line, "r"); lreply(211, "status of %s:", filename); while ((c = getc(fin)) != EOF) { @@ -1644,20 +2324,43 @@ reply(int n, char *fmt, va_dcl va_alist) #endif { +#ifdef USE_SSL + char outputbuf[2048]; /* allow for a 2k command string */ +#endif /* USE_SSL */ va_list ap; #ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif +#ifdef USE_SSL + /* assemble the output into a buffer, checking for length */ + sprintf(outputbuf,"%d ",n); + vsnprintf(outputbuf+strlen(outputbuf),2048-(strlen(outputbuf) + 3),fmt,ap); + strcat(outputbuf,"\r\n"); + + if (ssl_debug_flag) + BIO_printf(bio_err,"\n<--- %s",outputbuf); + + if (ssl_active_flag) { + SSL_write(ssl_con,outputbuf,strlen(outputbuf)); + } else { + fprintf(stdout,"%s",outputbuf); + fflush(stdout); + } + if (debug) + syslog(LOG_DEBUG, "<--- %s ", outputbuf); +#else /* !USE_SSL */ (void)printf("%d ", n); (void)vprintf(fmt, ap); (void)printf("\r\n"); (void)fflush(stdout); if (debug) { - syslog(LOG_DEBUG, "<--- %d ", n); - vsyslog(LOG_DEBUG, fmt, ap); + syslog(LOG_FTP | LOG_DEBUG, "<--- %d ", n); + vsyslog(LOG_FTP | LOG_DEBUG, fmt, ap); } +#endif /* USE_SSL */ + va_end(ap); } void @@ -1670,20 +2373,44 @@ va_dcl #endif { +#ifdef USE_SSL + char outputbuf[2048]; /* allow for a 2k command string */ +#endif /* USE_SSL */ va_list ap; #ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); #endif + +#ifdef USE_SSL + /* assemble the output into a buffer */ + sprintf(outputbuf,"%d- ",n); + vsprintf(outputbuf+strlen(outputbuf),fmt,ap); + strcat(outputbuf,"\r\n"); + + if (ssl_debug_flag) + BIO_printf(bio_err,"\n<--- %s",outputbuf); + + if (ssl_active_flag) { + SSL_write(ssl_con,outputbuf,strlen(outputbuf)); + } else { + fprintf(stdout,"%s",outputbuf); + fflush(stdout); + } + if (debug) + syslog(LOG_DEBUG, "<--- %s ", outputbuf); +#else /* !USE_SSL */ (void)printf("%d- ", n); (void)vprintf(fmt, ap); (void)printf("\r\n"); (void)fflush(stdout); if (debug) { - syslog(LOG_DEBUG, "<--- %d- ", n); - vsyslog(LOG_DEBUG, fmt, ap); + syslog(LOG_FTP | LOG_DEBUG, "<--- %d- ", n); + vsyslog(LOG_FTP | LOG_DEBUG, fmt, ap); } +#endif /* USE_SSL */ + va_end(ap); } static void ack(const char *s) @@ -1758,15 +2485,21 @@ void replydirname(const char *name, const char *message) { + char *p, *ep; char npath[MAXPATHLEN]; - int i; - for (i = 0; *name != '\0' && i < (int)sizeof(npath) - 1; i++, name++) { - npath[i] = *name; - if (*name == '"') - npath[++i] = '"'; + p = npath; + ep = &npath[sizeof(npath) - 1]; + while (*name) { + if (*name == '"' && ep - p >= 2) { + *p++ = *name++; + *p++ = '"'; + } else if (ep - p >= 1) + *p++ = *name++; + else + break; } - npath[i] = '\0'; + *p = '\0'; reply(257, "\"%s\" %s", npath, message); } @@ -1823,10 +2556,11 @@ static void dolog(struct sockaddr_in *sn) { - struct hostent *hp = gethostbyaddr((char *)&sn->sin_addr, - sizeof(struct in_addr), AF_INET); + struct hostent *hp; - if (hp) + if (!numeric_hosts && + (hp = gethostbyaddr((char *)&sn->sin_addr, + sizeof(struct in_addr), AF_INET))) (void) strncpy(remotehost, hp->h_name, sizeof(remotehost)-1); else (void) strncpy(remotehost, inet_ntoa(sn->sin_addr), @@ -1838,7 +2572,7 @@ #endif /* HASSETPROCTITLE */ if (logging) - syslog(LOG_INFO, "connection from %s", remotehost); + syslog(LOG_FTP | LOG_INFO, "connection from %s", remotehost); } /* @@ -1847,22 +2581,8 @@ */ void dologout(int status) { - sigset_t allsigs; - transflag = 0; - - if (logged_in) { - sigfillset(&allsigs); - sigprocmask(SIG_BLOCK, &allsigs, NULL); - (void) seteuid((uid_t)0); - ftpdlogwtmp(ttyline, "", ""); - if (doutmp) - logout(utmp.ut_line); -#if defined(KERBEROS) - if (!notickets && krbtkfile_env) - unlink(krbtkfile_env); -#endif - } + end_login(); /* beware of flushing buffers after a SIGPIPE */ _exit(status); } @@ -1891,11 +2611,11 @@ } if (strcmp(cp, "STAT\r\n") == 0) { if (file_size != (off_t) -1) - reply(213, "Status: %qd of %qd bytes transferred", - (quad_t) byte_count, (quad_t) file_size); + reply(213, "Status: %jd of %jd bytes transferred", + (intmax_t) byte_count, (intmax_t) file_size); else - reply(213, "Status: %qd bytes transferred", - (quad_t)byte_count); + reply(213, "Status: %jd bytes transferred", + (intmax_t)byte_count); } errno = save_errno; } @@ -2046,6 +2766,7 @@ volatile int simple = 0; volatile int freeglob = 0; glob_t gl; + char buf[1024]; /* XXX: should the { go away if __linux__? */ if (strpbrk(whichf, "~{[*?") != NULL) { @@ -2101,13 +2822,19 @@ if (S_ISREG(st.st_mode)) { if (dout == NULL) { - dout = dataconn("file list", (off_t)-1, "w"); + dout = dataconn("file list", (off_t)-1, "w", 0); if (dout == NULL) goto out; transflag++; } - fprintf(dout, "%s%s\n", dirname, + sprintf(buf,"%s%s\n", dirname, type == TYPE_A ? "\r" : ""); +#ifdef USE_SSL + if (ssl_active_flag) + SSL_write(ssl_data_con,buf,strlen(buf)); + else +#endif /* USE_SSL */ + fwrite(buf,strlen(buf),1,dout); byte_count += strlen(dirname) + 1; continue; } else if (!S_ISDIR(st.st_mode)) @@ -2143,17 +2870,23 @@ S_ISREG(st.st_mode))) { if (dout == NULL) { dout = dataconn("file list", (off_t)-1, - "w"); + "w", 0); if (dout == NULL) goto out; transflag++; } if (nbuf[0] == '.' && nbuf[1] == '/') - fprintf(dout, "%s%s\n", &nbuf[2], + sprintf(buf, "%s%s\n", &nbuf[2], type == TYPE_A ? "\r" : ""); else - fprintf(dout, "%s%s\n", nbuf, + sprintf(buf, "%s%s\n", nbuf, type == TYPE_A ? "\r" : ""); +#ifdef USE_SSL + if (ssl_active_flag) + SSL_write(ssl_data_con,buf,strlen(buf)); + else +#endif /* USE_SSL */ + fwrite(buf,strlen(buf),1,dout); byte_count += strlen(nbuf) + 1; } } @@ -2169,6 +2902,13 @@ transflag = 0; if (dout != NULL) +#ifdef USE_SSL + if (ssl_data_active_flag && (ssl_data_con!=NULL)) { + SSL_free(ssl_data_con); + ssl_data_active_flag=0; + ssl_data_con=NULL; + } +#endif /* USE_SSL */ (void) fclose(dout); data = -1; pdata = -1; @@ -2238,13 +2978,15 @@ if (hp) { if (!hosts_ctl("ftpd", hp->h_name, addr, STRING_UNKNOWN)) { - syslog(LOG_NOTICE, "tcpwrappers rejected: %s [%s]", + syslog(LOG_FTP | LOG_NOTICE, + "tcpwrappers rejected: %s [%s]", hp->h_name, addr); return (0); } } else { if (!hosts_ctl("ftpd", STRING_UNKNOWN, addr, STRING_UNKNOWN)) { - syslog(LOG_NOTICE, "tcpwrappers rejected: [%s]", addr); + syslog(LOG_FTP | LOG_NOTICE, + "tcpwrappers rejected: [%s]", addr); return (0); } } @@ -2252,3 +2994,223 @@ } #endif /* TCPWRAPPERS */ +#ifdef USE_SSL + +static +int +verify_callback(int ok, + X509_STORE_CTX *ctx); + +int +do_ssl_start(void) +{ + static char errstr[1024]; + + if (ssl_debug_flag) + BIO_printf(bio_err,"do_ssl_start triggered\n"); + + /* do the SSL stuff now ... before we play with pty's */ + ssl_con=(SSL *)SSL_new(ssl_ctx); + + /* we are working with stdin (inetd based) by default */ + SSL_set_fd(ssl_con,0); + +#if 0 + if (SSL_use_RSAPrivateKey(ssl_con,ssl_private_key)==0) { + sprintf(errstr,"ftpd: SSL_use_RSAPrivateKey %s",ERR_error_string(ERR_get_error(),NULL)); + perror_reply(421, errstr); + dologout(1); + } + + if (SSL_use_certificate(ssl_con,ssl_public_cert)==0) { + sprintf(errstr,"ftpd: SSL_use_certificate %s",ERR_error_string(ERR_get_error(),NULL)); + perror_reply(421, errstr); + dologout(1); + } +#endif + + SSL_set_verify(ssl_con,ssl_verify_flag, + ssl_certsok_flag ? verify_callback : NULL); + + if (SSL_accept(ssl_con)<=0) { + sprintf(errstr,"ftpd: SSL_accept %s",ERR_error_string(ERR_get_error(),NULL)); + + perror_reply(421, errstr); + dologout(1); + + SSL_free(ssl_con); + ssl_con=NULL; + + /* we will probably want to know this sort of stuff ... + * at least for the moment I'd like to keep track of + * who is using SSL - later I will probably make this + * just a debug option and only log after the user has + * actually connected --tjh + */ + if (logging) + syslog(LOG_NOTICE, "SSL FAILED WITH %s", remotehost); + + } else { + ssl_active_flag=1; + + if (logging) { + if (auth_ssl_name) + syslog(LOG_NOTICE, "SSL SUCCEEDED WITH %s as %s", remotehost, + auth_ssl_name); + else + syslog(LOG_NOTICE, "SSL SUCCEEDED WITH %s", remotehost); + } + } + + /* ssl_fprintf calls require that this be null to test + * for being an ssl stream + */ + if (!ssl_active_flag) { + if (ssl_con!=NULL) + SSL_free(ssl_con); + ssl_con=NULL; + } + + return 0; + +} + +/* we really shouldn't have code like this! --tjh */ +int +ssl_getc(SSL *ssl_con) +{ + char onebyte; + + if (SSL_read(ssl_con,&onebyte,1)!=1) + return -1; + else { + if (ssl_debug_flag) + BIO_printf(bio_err,"ssl_getc: SSL_read %d (%c) ",onebyte & 0xff,isprint(onebyte)?onebyte:'.'); + return onebyte & 0xff; + } +} + + +/* got back to this an implemented some rather "simple" buffering */ +static char putc_buf[BUFSIZ]; +static int putc_buf_pos=0; + +static int +ssl_putc_flush(SSL *ssl_con) +{ + if (putc_buf_pos>0) { + if (SSL_write(ssl_con,putc_buf,putc_buf_pos)!=putc_buf_pos) { + if (ssl_debug_flag) + BIO_printf(bio_err,"ssl_putc_flush: WRITE FAILED\n"); + putc_buf_pos=0; + return -1; + } + } + putc_buf_pos=0; + return 0; +} + +static int +ssl_putc(SSL *ssl_con,int oneint) +{ + char onebyte; + + onebyte = oneint & 0xff; + + /* make sure there is space */ + if (putc_buf_pos>=BUFSIZ) + if (ssl_putc_flush(ssl_con)!=0) + return EOF; + putc_buf[putc_buf_pos++]=onebyte; + + return onebyte; +} + +static +int +verify_callback(int ok, + X509_STORE_CTX *ctx) +{ + int depth,error; + X509 *xs; + + depth=ctx->error_depth; + error=ctx->error; + xs=X509_STORE_CTX_get_current_cert(ctx); + + /* + * If the verification fails, then don't remember the name. However, + * if we don't require a certificate, then return success which will + * still allow us to set up an encrypted session. + * + */ + if (!ok) { + /* If we can't verify the issuer, then don't accept the name. */ + if (depth != 0 && auth_ssl_name) { + free(auth_ssl_name); + auth_ssl_name = 0; + } + ok=ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT ? 0 : 1; + goto done; + } + if (depth == 0) + auth_ssl_name = + (char *)ONELINE_NAME(X509_get_subject_name(xs)); +done: ; + + if (ssl_debug_flag) + BIO_printf(bio_err,"verify_callback: returning %d\n",ok); + + return ok; +} + +/* return true if this auth_ssl_name is authorized to use name. */ +int +good_ssl_user(char *name) +{ + FILE *user_fp; + char buf[2048]; + + if (!auth_ssl_name) + return 0; + if (!ssl_certsok_flag) + return 0; /* can't happen */ + user_fp = fopen("/etc/ssl.users", "r"); + if (!user_fp) + return 0; + while (fgets(buf, sizeof buf, user_fp)) { + char *cp; + char *n; + + /* allow for comments in the file ... always nice + * to be able to add a little novel in files and + * also disable easily --tjh + */ + if (buf[0]=='#') + continue; + + if ((cp = strchr(buf, '\n'))) + *cp = '\0'; + cp = strchr(buf, ':'); + if (!cp) + continue; + *cp++ = '\0'; + if (strcasecmp(cp, auth_ssl_name) == 0) { + n = buf; + while (n) { + cp = strchr(n, ','); + if (cp) + *cp++ = '\0'; + if (!strcmp(name, n)) { + fclose(user_fp); + return 1; + } + n = cp; + } + } + } + fclose(user_fp); + return 0; +} + +#endif /* USE_SSL */ --- linux-ftpd-ssl-0.17.27+0.3.orig/support/Makefile +++ linux-ftpd-ssl-0.17.27+0.3/support/Makefile @@ -1,6 +1,6 @@ include ../MCONFIG -OBJS=daemon.o setproctitle.o isexpired.o vis.o +OBJS=setproctitle.o isexpired.o vis.o all: libsupport.a @@ -16,4 +16,3 @@ rm -f *.o libsupport.a setproctitle.o: setproctitle.h -daemon.o: daemon.h --- linux-ftpd-ssl-0.17.27+0.3.orig/support/setproctitle.c +++ linux-ftpd-ssl-0.17.27+0.3/support/setproctitle.c @@ -139,7 +139,7 @@ (void) strcpy(Argv[0], buf); p = &Argv[0][i]; while (p < LastArgv) - *p++ = ' '; + *p++ = '\0'; Argv[1] = NULL; }