debian/0000755000000000000000000000000011564463603007176 5ustar debian/changelog0000644000000000000000000004054111564463603011054 0ustar netkit-ftp-ssl (0.17.23+0.2-1build1) oneiric; urgency=low * Rebuild for OpenSSL 1.0.0. -- Colin Watson Tue, 17 May 2011 13:18:02 +0100 netkit-ftp-ssl (0.17.23+0.2-1) unstable; urgency=low * Update to netkit-ftp 0.17.23. * CFLAGS: add -g -fno-strict-aliasing. * Standards-Version: 3.9.0. * debian/copyright: explicitly embed BSD license. -- Ian Beckwith Sun, 04 Jul 2010 01:45:37 +0100 netkit-ftp (0.17-23) unstable; urgency=low [Mats Erik Andersson] * Rework error recovery. (Closes: #582598) + 040_ipv6_ftp_c.diff: Updated file. + Avoid double free errors by freeing immediately at an intermediary error. + Conditional use of IP_TOS for GNU/kfreebsd. * debian/copyright: Explicit licensing for the IPv6 coding. * debian/rules: Added compiler flag '-fno-strict-aliasing'. -- Mats Erik Andersson Tue, 25 May 2010 23:50:59 +0200 netkit-ftp-ssl (0.17.22+0.2-1) unstable; urgency=low * Update to netkit-ftp 0.17-22. * Refresh all patches. -- Ian Beckwith Sun, 16 May 2010 22:56:14 +0100 netkit-ftp (0.17-22) unstable; urgency=low * Changes by Mats Erik Andersson. - Updated 040_ipv6_ftp_c.diff to fix double free error (Closes: #579532) * Added Mats to the Uploaders field. -- Alberto Gonzalez Iniesta Tue, 11 May 2010 12:01:39 +0200 netkit-ftp-ssl (0.17.21+0.2-1) unstable; urgency=low * Update to netkit-ftp 0.17-21 + IPv6 support! (Closes: #336106) Thanks to Mats Erik Andersson . * Convert to format 3.0 (quilt). * Extract source changes to patches in debian/patch/, annotate patches in DEP3 format. SSL patches start at 500, patches below that are imported unchanged from the debian netkit-ftp package. * 520_check_ssl_new.diff: also check return valueof SSL_new() when setting up a data connection. * debian/rules: + Use -fno-strict-aliasing to avoid warnings from type-punning sockaddr_storage. + Remove unnecessary extra '-g' from CFLAGS. * debian/watch: check for new debian package of netkit-ftp. * Standards-Version: 3.8.4 (no changes). -- Ian Beckwith Fri, 09 Apr 2010 02:41:25 +0100 netkit-ftp (0.17-21) unstable; urgency=low * Updated 040_ipv6_ftp_c.diff with Mats' latest patch -- Alberto Gonzalez Iniesta Tue, 30 Mar 2010 16:45:04 +0200 netkit-ftp (0.17-20) unstable; urgency=low * Changes by Mats Erik Andersson. Thanks for the HUGE patch! - Migrate to format "3.0 (quilt)". - debian/control: Adding ${misc:Depends} due to Debhelper. - debian/substvars: Deleted file. - debian/watch: New file. - Extract in-situ patches. Deposited in debian/patches/: + 010_patches_in_sarge.diff + 020_optional_stripping.diff + 025_long_cmd_overflow.diff + 030_argv_handling.diff - [lintian] New patch 035_lintian_pedantic.diff. - New patch for IPv6-capability: 040_ipv6_ftp_c.diff (Closes: #228752) - [lintian] maintainer-script-without-set-e: debian/{postinst,prerm} * Bumped Standards-Version to 3.8.4.0. -- Alberto Gonzalez Iniesta Tue, 30 Mar 2010 16:19:20 +0200 netkit-ftp-ssl (0.17.19+0.2-1) unstable; urgency=low * Update to netkit-ftp 0.17-19. * ftp/cmds.c: fix typo. * debian/control: remove DM-Upload-Allowed flag. -- Ian Beckwith Wed, 23 Sep 2009 01:48:43 +0100 netkit-ftp (0.17-19) unstable; urgency=low * Patched main.c to fix memory management on command line arguments. Thanks a lot to Mark Calderbank for the patch. (Closes: #508378, #505533, #510009) * debian/control: replaced libreadline5-dev with libreadline-dev * Moved to debhelper compat 7 * Bumped Standards-Version to 3.8.3. -- Alberto Gonzalez Iniesta Mon, 14 Sep 2009 13:35:40 +0200 netkit-ftp-ssl (0.17.18+0.2-3) unstable; urgency=low * Use editline instead of readline (Closes: #531822) Licensing problems forbid us from linking to readline and openssl in the same binary. * Explicitly Build-Depend on libncurses5-dev, was previously pulled in indirectly by libreadline5-dev. * Standards-Version: 3.8.1 (no changes). * Change maintainer email address. -- Ian Beckwith Sat, 06 Jun 2009 16:10:42 +0100 netkit-ftp-ssl (0.17.18+0.2-2) unstable; urgency=low * Incorporate Ubuntu patch (LP: #184626) to fix segfault when no parameter is given to -z. Thanks to Alexander Gitter (Closes: #506137). * Added stub watch file. * Standards-Version: 3.8.0 (no changes). * control: removed superfluous Section: field. * prerm, postinst: use set -e instead of /bin/sh -e -- Ian Beckwith Wed, 25 Feb 2009 23:00:16 +0000 netkit-ftp-ssl (0.17.18+0.2-1) unstable; urgency=low * New maintainer (Closes: #476131). * Update to netkit-ftp 0.17.18. * Initialize SSL even when -n is used (Closes: #450723). Also enforce -z secure in USER command. * Fix nostrip and noopt DEB_BUILD_OPTIONS (Closes: #437616). * Fix all warnings in source. * Remove dpatch - not worth it for one change out of many. * Remove ncurses Build-Dep and drop it from LIBTERMCAP setting, as we don't actually use it. * ftp.1: Document SSL options, fix typos & hyphen quoting. * ftp -h: Document SSL options. * Add DM-Upload-Allowed: yes. * Update debian/copyright. * Bump debhelper compat level to 5. * Remove unused debhelper calls. * Use netkit-ftp_0.17.orig.tar.gz as our orig.tar.gz. -- Ian Beckwith Fri, 25 Apr 2008 00:22:46 +0100 netkit-ftp (0.17-18) unstable; urgency=low * Clean patch applied in previous version. Thanks Steve for helping again with this. -- Alberto Gonzalez Iniesta Wed, 26 Mar 2008 18:31:12 +0100 netkit-ftp (0.17-17) unstable; urgency=low * Applied patch by Steve Kemp to fix buffer overflow in ftp commands. (Closes: #391207, #407924) Thanks a lot Steve for looking into this. * Removed stripping from Makefile. Added it as an option in debian/rules. (Closes: #437615) * Bumped Standards-Version to 3.7.3. Did some cleaning. -- Alberto Gonzalez Iniesta Fri, 21 Mar 2008 18:14:02 +0100 netkit-ftp (0.17-16) unstable; urgency=low * Build with libreadline5-dev again. Don't know how libreadline4-dev managed to get back to debian/control. (Closes: #340302) -- Alberto Gonzalez Iniesta Tue, 22 Nov 2005 19:57:36 +0100 netkit-ftp (0.17-15) unstable; urgency=low * debian/control: Added Depends: on netbase (Closes: #340082) -- Alberto Gonzalez Iniesta Mon, 21 Nov 2005 10:18:15 +0100 netkit-ftp (0.17-14) unstable; urgency=low * Rebuild with libreadline5-dev (Closes: #326364, #336572) * Removed /usr/share/doc/ftp/README since it didn't contain useful information. (Closes:#323231) * Bumped Standards-Version to 3.6.2.0, no change. * Moved to debhelper compatibility 4. Created debian/compat. -- Alberto Gonzalez Iniesta Mon, 14 Nov 2005 16:25:56 +0100 netkit-ftp (0.17-13) unstable; urgency=low * New maintainer. * debian/control. Build-Depends: Added libreadline4-dev as alternative to libreadline-dev * debian/control. Removed full stop from package description to make lintian happy. * debian/control. Bumped Standards-Version to 3.6.1.0, no change. -- Alberto Gonzalez Iniesta Sat, 12 Mar 2005 12:15:12 +0100 netkit-ftp-ssl (0.17.12+0.2-6) unstable; urgency=low * Apply ftp-tls patch by Andreas Oberritter to support TLS authenticaton and (optional) data connection encryption -- Cai Qian Tue, 11 Oct 2005 19:35:00 +0100 netkit-ftp-ssl (0.17.12+0.2-5) unstable; urgency=low * Build-Depends against libreadline5-dev (Closes: #326363) * Fixed typo in manpage (Closes: #298063) * Fixed needless conflicts (Closes: #309388) -- Cai Qian Tue, 27 Sep 2005 22:07:00 +0100 netkit-ftp-ssl (0.17.12+0.2-4) unstable; urgency=low * Build-Depends against libreadline4-dev (Closes: #279415) * followed debhelper v4 -- Cai Qian Wed, 15 Nov 2004 10:30:00 +0800 netkit-ftp-ssl (0.17.12+0.2-3) unstable; urgency=low * ftp-ssl should not conflict with lftp (Closes: #161710) * Adjust wrong Maintainer field (Closes: #277717) -- Cai Qian Fri, 22 Oct 2004 13:30:00 +0800 netkit-ftp-ssl (0.17.12+0.2-2) unstable; urgency=low * New maintainer (Closes: #250712) * Add lftp to Conflicts in control file (Closes: #161710) -- Cai Qian Sun, 26 Sep 2004 22:00:00 +0800 netkit-ftp-ssl (0.17.12+0.2-1) unstable; urgency=low * Bring netkit-ftp-ssl in line with current netkit-ftp * patch to make ftp-ssl compatible with other ftp/ssl implementations. (Closes: #168762) * add patch for GNU/HURD (Closes: #218336) * fix manpage (Closes: #250587) * build for sid/sarge (Closes: #189599) -- Christoph Martin Thu, 27 May 2004 16:10:10 +0200 netkit-ftp (0.17-12) unstable; urgency=low * New maintainer. (Closes: #249706) - control (Maintainer): Set myself. -- Robert Millan Wed, 19 May 2004 02:09:50 +0200 netkit-ftp (0.17-11) unstable; urgency=low * Added netrc(5) reference to ftp(1). * Added port to SYNOPSIS in ftp(1) (closes: #191497). -- Herbert Xu Sun, 29 Jun 2003 15:37:35 +1000 netkit-ftp (0.17-10) unstable; urgency=low * Fixed LFS problem with ptransfer bytes count (closes: #143469). -- Herbert Xu Fri, 19 Apr 2002 19:27:58 +1000 netkit-ftp-ssl (0.17.9+0.2-4) unstable; urgency=low * change section to net and priority to extra -- Christoph Martin Sun, 29 Sep 2002 18:04:50 +0200 netkit-ftp-ssl (0.17.9+0.2-3) unstable; urgency=low * fix broken passive mode while SSL is enabled (thanks to Stefan Esser ) -- Christoph Martin Sun, 29 Sep 2002 14:46:03 +0200 netkit-ftp-ssl (0.17.9+0.2-2) unstable; urgency=low * moved from nonus to main -- Christoph Martin Sat, 23 Mar 2002 12:10:37 +0100 netkit-ftp-ssl (0.17.9+0.2-1) unstable; urgency=low * Fixed more LFS issues (Hiroyuki YAMAMO, #126521). * Built with support for large files. -- Christoph Martin Thu, 7 Mar 2002 08:44:50 +0100 netkit-ftp (0.17-9) unstable; urgency=low * Fixed more LFS issues (Hiroyuki YAMAMO, #126521). -- Herbert Xu Fri, 28 Dec 2001 20:05:07 +1100 netkit-ftp (0.17-8) unstable; urgency=low * Built with support for large files. -- Herbert Xu Tue, 11 Dec 2001 19:02:28 +1100 netkit-ftp-ssl (0.17.7+0.2-1) unstable; urgency=low * bring in line with netkit-ftp * corrected error in netrc(5) manpage (99527) * No longer provides ftp-client. * Check for NULL pointers in abort_remote(). * hopefully better changelog now (closes: #91347) -- Christoph Martin Wed, 21 Nov 2001 16:36:45 +0100 netkit-ftp (0.17-7) unstable; urgency=low * Moved second entry in NAME of netrc(5) to SYNOPSIS (closes: #99527). -- Herbert Xu Thu, 14 Jun 2001 19:12:49 +1000 netkit-ftp (0.17-6) unstable; urgency=low * No longer provides ftp-client. * Check for NULL pointers in abort_remote(). -- Herbert Xu Wed, 30 May 2001 19:22:30 +1000 netkit-ftp-ssl (0.17.5+0.2-1) unstable; urgency=low * new upstream ssl-patch (0.2) brings working -z secure option * build with readline support (closes: #97213) * include SSL options into manpage -- Christoph Martin Sun, 13 May 2001 17:30:22 +0200 netkit-ftp-ssl (0.17.5+0.1-1) unstable; urgency=low * bring netkit-ftp updates to -ssl * provides,conflicts,replaces ftp (closes: #86656, #86657, #87453, #86783) * builddepend on libssl-dev -- Christoph Martin Sat, 10 Mar 2001 17:33:56 +0100 netkit-ftp (0.17-5) unstable; urgency=low * Provide ftp-client (closes: #86782). * Check cin and cout at the top of getreply() (closes: #87845). -- Herbert Xu Wed, 28 Feb 2001 20:37:58 +1100 netkit-ftp-ssl (0.17.4+0.1-1) unstable; urgency=low * initial netkit-ftp-ssl release -- Christoph Martin Sun, 18 Feb 2001 13:44:34 +0100 netkit-ftp (0.17-4) unstable; urgency=low * Added a missing terminating NUL in quote1(). -- Herbert Xu Mon, 9 Oct 2000 18:59:21 +1100 netkit-ftp (0.17-3) unstable; urgency=low * Added build-time dependency on debhelper (closes: #69103). * Replace control characters by ? on stdout if it is a tty. Also configurable via qc (closes: #69712). -- Herbert Xu Sat, 26 Aug 2000 12:41:30 +1000 netkit-ftp (0.17-2) unstable; urgency=low * Empty lines no longer cause ftp to exit. * Protect obstack_free(3) with INTOFF/INTON. -- Herbert Xu Sat, 12 Aug 2000 11:20:55 +1000 netkit-ftp (0.17-1) unstable; urgency=low * New upstream release. * Use glob(3). * Use obstacks. -- Herbert Xu Thu, 10 Aug 2000 20:39:09 +1000 netkit-ftp (0.16-8) unstable; urgency=low * Fixed an incorrect call to command() in quote1() (closes: #66901). -- Herbert Xu Sat, 8 Jul 2000 12:14:59 +1000 netkit-ftp (0.16-7) unstable; urgency=low * The pipeprotect() problem also affected globulize(). So instead of having them always return malloced memory, the result is now checked to see if it is malloced or not. This fixes a core dump observed by Jeff Lessem (closes: #63656). * Added code to protect globulize() in ls(). * Removed duplicate globulize() calls in ls(). -- Herbert Xu Sun, 14 May 2000 10:28:34 +1000 netkit-ftp (0.16-6) unstable; urgency=low * pipeprotect() now always returns malloced memory. This fixes a core dump reported by Mike Baker. -- Herbert Xu Mon, 1 May 2000 15:20:30 +1000 netkit-ftp (0.16-5) unstable; urgency=low * An attempt to fix some SIGINT races, a lot more needs to be done as the current code is a piece of crap. Unfortunately the same holds for the current ftp code in the various BSD variants so we can't steal from them (closes: #62494). * SIGPIPE is now ignored as errors are now handled in the code (closes: #56222). -- Herbert Xu Mon, 24 Apr 2000 13:03:03 +1000 netkit-ftp (0.16-4) unstable; urgency=low * Added dynamic allocation for macro expansion (closes: #62307). -- Herbert Xu Fri, 14 Apr 2000 15:01:36 +1000 netkit-ftp (0.16-3) unstable; urgency=low * Fixed a coredump due to uninitialised parameters (closes: #61036). -- Herbert Xu Thu, 30 Mar 2000 14:24:22 +1000 netkit-ftp (0.16-2) unstable; urgency=low * Recompiled against libreadline4 (closes: #61139). -- Herbert Xu Tue, 28 Mar 2000 19:04:02 +1000 netkit-ftp (0.16-1) unstable; urgency=low * New upstream release. * Merged changes from the NMU (closes: #59682, #44778, #46132, #55652, #57906). * Added support for arbitrarily long command lines (closes: #21672). * ftp(1) is now installed as netkit-ftp and update-alternatives is now used (closes: #55610). -- Herbert Xu Thu, 23 Mar 2000 21:07:33 +1100 netkit-ftp (0.10-3.1) frozen unstable; urgency=low * Non-maintainer upload (Herbert Xu is still away, it seems). * Recompiled against libreadline4 and libncurses5, more properly closes: #44778, #46132, #55652, #57906. [ftp is Priority: standard] * Updated for Policy 3.x. Lintian clean. * Changed some bits and pieces in the build system. -- Josip Rodin Sun, 13 Feb 2000 01:20:28 +0100 netkit-ftp (0.10-3) unstable; urgency=low * Initialise transfer types upon login (fixes #20721). -- Herbert Xu Sun, 27 Jun 1999 13:38:08 +1000 netkit-ftp (0.10-2) unstable; urgency=low * Fixed buffer overrun with long lines (reported by +VipVop ). -- Herbert Xu Sun, 20 Jun 1999 12:36:31 +1000 netkit-ftp (0.10-1) unstable; urgency=low * Initial Release. * Fixed a Y2K problem with patch from Jeff Smith (fixes #39150). -- Herbert Xu Fri, 18 Jun 1999 22:39:23 +1000 debian/rules0000755000000000000000000000345511413755027010262 0ustar #!/usr/bin/make -f # $Id: rules,v 1.9 2001/12/11 09:03:39 herbert Exp $ # Adapted for netkit-ftp. Copyright 1999 by Herbert Xu. # Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 DEFS := -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CONFIGUREARGS=--with-debug else CONFIGUREARGS= endif build: build-stamp build-stamp: dh_testdir if [ ! -f MCONFIG ]; then \ ./configure $(CONFIGUREARGS) --with-editline ; \ sed -e 's/^CFLAGS=\(.*\)$$/CFLAGS= -g $(DEFS) -fno-strict-aliasing \1/' \ -e 's/^\(LIBTERMCAP=\).*/\1/' \ MCONFIG > MCONFIG.new; \ mv MCONFIG.new MCONFIG; \ fi $(MAKE) touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp install-stamp [ ! -f MCONFIG ] || $(MAKE) distclean dh_clean install: install-stamp install-stamp: build-stamp dh_testdir dh_testroot dh_prep dh_installdirs $(MAKE) INSTALLROOT=`pwd`/debian/ftp-ssl MANDIR=/usr/share/man install mv debian/ftp-ssl/usr/bin/ftp debian/ftp-ssl/usr/bin/ftp-ssl ln -sf ftp-ssl debian/ftp-ssl/usr/bin/pftp mv debian/ftp-ssl/usr/share/man/man1/ftp.1 \ debian/ftp-ssl/usr/share/man/man1/ftp-ssl.1 ln -sf ftp-ssl.1 debian/ftp-ssl/usr/share/man/man1/pftp.1 touch install-stamp # 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_installman dh_installchangelogs ChangeLog dh_link 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 debian/watch0000644000000000000000000000035411413755027010226 0ustar version=3 # check for new debian package of our upstream, netkit-ftp # the other possible upstreams are long dead opts="uversionmangle=s/(.*)-(.*)/$1.$2+0.2/" http://www.uk.debian.org/debian/pool/main/n/netkit-ftp/netkit-ftp_(.*).dsc debian/compat0000644000000000000000000000000211413755027010371 0ustar 7 debian/README.Debian0000644000000000000000000000212711413755027011236 0ustar The TLS patch was downloaded from ttp://www.saftware.de/patches/ftp_tls.diff. Netkit-ftp-ssl is now supporting TLS authentication and (optional) data connection encryption according to http://www.ietf.org/internet-drafts/draft-murray-auth-ftp-ssl-16.txt . The default is to fall back to insecure authentication if AUTH TLS is not supported by the server to match the current behaviour of the AUTH SSL code. If you specify "-z secure", then encryption of both the control and the data connection are required. -- Cai Qian Tue, 11 Oct 2005 19:35:00 +0100 The SSL patches were downloaded from ftp://ftp.uni-mainz.de/pub/software/security/ssl/SSL-MZapps/netkit-ftp-0.17+ssl-0.2.diff.gz The packages was build in the following way: apt-get source netkit-ftp mv netkit-ftp-0.17 netkit-ftp-ssl-0.17.12+0.2 cd netkit-ftp-ssl-0.17.12+0.2 zcat ../netkit-ftp-0.17+ssl-0.2.diff.gz | patch -p1 #don't fix problems with applied patches ! cd .. cp -a netkit-ftp-ssl-0.17.12+0.2 netkit-ftp-ssl-0.17.12+0.2.orig cd netkit-ftp-ssl-0.17.12+0.2 zcat ../netkit-ftp-ssl_0.17.9+0.2-4.diff.gz | patch -p1 debian/source/0000755000000000000000000000000011413755027010473 5ustar debian/source/format0000644000000000000000000000001411413755027011701 0ustar 3.0 (quilt) debian/prerm0000644000000000000000000000030011413755027010234 0ustar #!/bin/sh # $Id: prerm,v 1.2 2001/02/24 13:03:29 herbert Exp $ set -e if [ "$1" = remove ] || [ "$1" = deconfigure ]; then update-alternatives --remove ftp /usr/bin/ftp-ssl fi #DEBHELPER# debian/control0000644000000000000000000000167111413755027010603 0ustar Source: netkit-ftp-ssl Section: net Priority: extra Maintainer: Ian Beckwith Standards-Version: 3.9.0 Build-Depends: debhelper (>= 7), libeditline-dev, libncurses5-dev, libssl-dev Package: ftp-ssl Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, netbase Conflicts: ftp (>= 0.10) Replaces: ftp (>= 0.10) Provides: ftp Description: The FTP client with SSL or TLS encryption support ftp is the user interface to the ARPANET standard File Transfer Protocol. The program allows a user to transfer files to and from a remote network site. . ftp-ssl replaces normal ftp using SSL or TLS authentication and encryption. It interoperates with normal ftpd. It checks if the other side is also talking SSL or TLS, 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. debian/patches/0000755000000000000000000000000011413755027010622 5ustar debian/patches/590_fix_ssl_without_autologin.diff0000644000000000000000000000434411413755027017371 0ustar Description: Fix SSL without autologin (-n) Initialize SSL even when -n is used. Also enforce -z secure when logging in with USER command. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=450723 Author: Ian Beckwith Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/cmds.c =================================================================== --- netkit-ftp-ssl.orig/ftp/cmds.c 2010-07-04 00:06:04.000000000 +0100 +++ netkit-ftp-ssl/ftp/cmds.c 2010-07-04 00:06:04.000000000 +0100 @@ -271,6 +271,10 @@ (void) strcpy(bytename, "8"), bytesize = 8; if (autologin) (void) dologin(argv[1]); +#ifdef USE_SSL + else + (void) ssl_init(); +#endif /* USE_SSL */ dosyst(); } } Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-04 00:06:04.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-04 00:06:04.000000000 +0100 @@ -2109,12 +2109,11 @@ fflush(stdout); } -static int -auth_user(char *u,char *p) -{ - int n; - #ifdef USE_SSL +int +ssl_init(void) +{ + int n; int use_tls = 0; if (ssl_enabled) { n = command("AUTH SSL"); @@ -2185,22 +2184,27 @@ fprintf(stderr, "Data connection security level refused.\n"); return ERROR; } - - n = command("USER %s",u); - if (n == CONTINUE) { - if(p == NULL) - p = getpass("Password:"); - n = command("PASS %s",p); - } - return (n); } } + return CONTINUE; +} #endif /* USE_SSL */ + +static int +auth_user(char *u,char *p) +{ + int n; + +#ifdef USE_SSL + if (ssl_init() == ERROR) + return ERROR; +#endif /* USE_SSL */ + n = command("USER %s",u); if (n == CONTINUE) { - if(p == NULL) + if(p == NULL) p = getpass("Password:"); - n = command("PASS %s",p); + n = command("PASS %s",p); } return(n); } Index: netkit-ftp-ssl/ftp/sslapp.h =================================================================== --- netkit-ftp-ssl.orig/ftp/sslapp.h 2010-07-04 00:06:04.000000000 +0100 +++ netkit-ftp-ssl/ftp/sslapp.h 2010-07-04 00:06:04.000000000 +0100 @@ -59,6 +59,7 @@ extern int server_verify_callback(); extern int client_verify_callback();*/ +extern int ssl_init(void); #endif /* USE_SSL */ debian/patches/570_fix_warnings.diff0000644000000000000000000001047511413755027014554 0ustar Description: fix various warnings some trivial, some (like the sprintf fix) are actual bugs Author: Ian Beckwith Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-04 00:03:20.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-04 00:03:20.000000000 +0100 @@ -124,8 +124,14 @@ # define FTP_CONNECT_TIMEOUT 10 #endif +#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _UNUSED_PARAMETER_ __attribute__ ((__unused__)) +#else +# define _UNUSED_PARAMETER_ +#endif + static void -trivial_alarm(int sig) +trivial_alarm(int sig _UNUSED_PARAMETER_) { /* Only used to generate an EINTR error. */ return; @@ -504,7 +510,9 @@ intrnewline--; INTON; return(r); +#ifndef USE_SSL outerr: +#endif /* !USE_SSL */ lostpeer(0); INTON; if (verbose) { @@ -547,7 +555,7 @@ case WONT: if ((c = GETC(cin)) == EOF) goto goteof; - snprintf(buf, + sprintf(buf, "%c%c%c", IAC, DONT, c); #ifdef USE_SSL if (ssl_active_flag) Index: netkit-ftp-ssl/ftp/main.c =================================================================== --- netkit-ftp-ssl.orig/ftp/main.c 2010-07-04 00:03:20.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.c 2010-07-04 00:03:20.000000000 +0100 @@ -134,11 +134,14 @@ static long bio_dump_cb(BIO *bio, int cmd, - char *argp, + const char *argp, int argi, - long argl, - long ret) - { + long argl +#ifdef __GNUC__ + __attribute__ ((unused)) +#endif /* __GNUC__ */ + , long ret) +{ BIO *out; /* @@ -149,20 +152,20 @@ if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) { - BIO_printf(out,"read from %08X (%d bytes => %ld (%X))\n", + BIO_printf(out,"read from %p (%d bytes => %ld (%lX))\n", bio,argi,ret,ret); BIO_dump(out,argp,(int)ret); BIO_flush(out); } else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) { - BIO_printf(out,"write to %08X (%d bytes => %ld (%X))\n", + BIO_printf(out,"write to %p (%d bytes => %ld (%lX))\n", bio,argi,ret,ret); BIO_dump(out,argp,(int)ret); BIO_flush(out); } return( (cmd & BIO_CB_RETURN) ? ret : 1); - } +} int set_ssl_trace(SSL *con) @@ -170,7 +173,10 @@ if (con!=NULL) { if (ssl_debug_flag) { BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); +#if 0 + /* not needed, we access bio_err directly */ BIO_set_callback_arg(SSL_get_rbio(con),bio_err); +#endif } } return 0; @@ -203,8 +209,7 @@ struct passwd *pw = NULL; char homedir[MAXPATHLEN]; sigjmp_buf jmploc; - char *optarg; - + tick = 0; sp = getservbyname("ftp", "tcp"); Index: netkit-ftp-ssl/ftp/ssl_port.h =================================================================== --- netkit-ftp-ssl.orig/ftp/ssl_port.h 2010-07-04 00:03:20.000000000 +0100 +++ netkit-ftp-ssl/ftp/ssl_port.h 2010-07-04 00:03:20.000000000 +0100 @@ -19,6 +19,7 @@ #include #define OLDPROTO NOPROTO +#undef NOPROTO #define NOPROTO #include #undef NOPROTO Index: netkit-ftp-ssl/ftp/sslapp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/sslapp.c 2010-07-04 00:03:20.000000000 +0100 +++ netkit-ftp-ssl/ftp/sslapp.c 2010-07-04 00:03:20.000000000 +0100 @@ -34,7 +34,7 @@ /* fwd decl */ static void -client_info_callback(SSL *s, int where, int ret); +client_info_callback(const SSL *s, int where, int ret); int do_ssleay_init(int server) @@ -155,7 +155,7 @@ static void -client_info_callback(SSL *s, int where, int ret) +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", Index: netkit-ftp-ssl/ftp/sslapp.h =================================================================== --- netkit-ftp-ssl.orig/ftp/sslapp.h 2010-07-04 00:03:20.000000000 +0100 +++ netkit-ftp-ssl/ftp/sslapp.h 2010-07-04 00:03:20.000000000 +0100 @@ -22,6 +22,7 @@ #define ONELINE_NAME(X) X509_NAME_oneline(X,NULL,0) #define OLDPROTO NOPROTO +#undef NOPROTO #define NOPROTO #include #undef NOPROTO debian/patches/550_doc_fixes.diff0000644000000000000000000000516511413755027014017 0ustar Description: Man page improvements Document SSL options in synopsis, and fix groff errors. For groff error report (only), see #250587. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=250587 Author: Ian Beckwith , Christoph Martin Forwarded: no Last-Update: 2010-04-06 Index: netkit-ftp-ssl/ftp/ftp.1 =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.1 2010-05-16 22:19:16.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.1 2010-05-16 22:19:16.000000000 +0100 @@ -43,9 +43,29 @@ .Sh SYNOPSIS .Nm ftp .Op Fl pinegvd +.Op Fl z Ar debug +.Op Fl z Ar authdebug +.Op Fl z Ar nossl +.Op Fl z Ar certrequired +.Op Fl z Ar secure +.Op Fl z Ar verbose +.Op Fl z Ar verify=flags +.Op Fl z Ar cert=cert_file +.Op Fl z Ar key=key_file +.Op Fl z Ar cipher=list .Op Ar host Op Ar port .Nm pftp .Op Fl inegvd +.Op Fl z Ar debug +.Op Fl z Ar authdebug +.Op Fl z Ar nossl +.Op Fl z Ar certrequired +.Op Fl z Ar secure +.Op Fl z Ar verbose +.Op Fl z Ar verify=flags +.Op Fl z Ar cert=cert_file +.Op Fl z Ar key=key_file +.Op Fl z Ar cipher=list .Op Ar host Op Ar port .Sh DESCRIPTION .Nm Ftp @@ -99,42 +119,42 @@ Enables debugging. .It Fl z Ar option Set SSL (Secure Socket Layer) parameters. The default is to negotiate -via ftp protocoll if SSL is availlable at server side and then to +via ftp protocol if SSL is available on the server side and then to switch it on. In this mode you can connect to both conventional and SSL enhanced ftpd's. .Pp The SSL parameters are: .Bl -tag -width Fl -.It Ic Ar debug +.It Ic debug Send SSL related debugging information to stderr. -.It Ic Ar authdebug +.It Ic authdebug Enable authentication debugging. -.It Ic Ar ssl +.It Ic ssl Negotiate SSL at first, then use ftp protocol. ftp protocol negotiation goes encrypted. (Not yet implemented) -.It Ic Ar nossl, Ar !ssl +.It Ic nossl, !ssl switch of SSL negotiation -.It Ic Ar certrequired +.It Ic certrequired client certificate is mandatory -.It Ic Ar secure +.It Ic secure Don't switch back to unencrypted mode (no SSL) if SSL is not available. -.It Ic Ar verbose +.It Ic verbose Be verbose about certificates etc. -.It Ic Ar verify=int +.It Ic verify= Ns Ar int .\" TODO Set the SSL verify flags (SSL_VERIFY_* in .Ar ssl/ssl.h ). .\" TODO -.It Ic Ar cert=cert_file +.It Ic cert= Ns Ar cert_file .\" TODO Use the certificate(s) in .Ar cert_file . -.It Ic Ar key=key_file +.It Ic key= Ns Ar key_file .\" TODO Use the key(s) in .Ar key_file . -.It Ic Ar cipher=ciph_list +.It Ic cipher= Ns Ar ciph_list .\" TODO Set the preferred ciphers to .Ar ciph_list . debian/patches/035_lintian_pedantic.diff0000644000000000000000000000311311413755027015346 0ustar Description: Pedantic complaits by lintian. Spelling in ftp/ftp.1 and ftp/cmds.c. . Incorrect use of hyphenation in ftp/ftp.1. Author: Mats Erik Andersson Forwarded: no Last-Update: 2010-02-27 --- netkit-ftp-0.17/ftp/ftp.1.debian +++ netkit-ftp-0.17/ftp/ftp.1 @@ -343,7 +343,7 @@ seconds. If .Ar seconds -is ommitted, the current inactivity timer is printed. +is omitted, the current inactivity timer is printed. .It Ic lcd Op Ar directory Change the working directory on the local machine. If @@ -854,7 +854,7 @@ .Ar newmask . If .Ar newmask -is ommitted, the current umask is printed. +is omitted, the current umask is printed. .It Xo .Ic user Ar user-name .Op Ar password @@ -957,7 +957,7 @@ (stdin). If the shell command includes spaces, the argument must be quoted; e.g. -\*(Lq" ls -lt"\*(Rq. +\*(Lq" ls \-lt"\*(Rq. A particularly useful example of this mechanism is: \*(Lqdir more\*(Rq. .It @@ -1010,9 +1010,9 @@ .Ic type may be one of \*(Lqascii\*(Rq, \*(Lqimage\*(Rq (binary), \*(Lqebcdic\*(Rq, and \*(Lqlocal byte size\*(Rq (for -.Tn PDP Ns -10's +.Tn PDP Ns \-10's and -.Tn PDP Ns -20's +.Tn PDP Ns \-20's mostly). .Nm Ftp supports the ascii and image types of file transfer, --- netkit-ftp-0.17/ftp/cmds.c.debian +++ netkit-ftp-0.17/ftp/cmds.c @@ -2511,7 +2511,7 @@ if (overbose && !strncmp(reply_string, "215 TOPS20", 10)) printf( -"Remember to set tenex mode when transfering binary files from this machine.\n"); +"Remember to set tenex mode when transferring binary files from this machine.\n"); } verbose = overbose; #else debian/patches/620_enforce_ssl_in_user_cmd.diff0000644000000000000000000000344511413755027016722 0ustar Description: Enforce -z secure when logging in with USER command Author: Ian Beckwith Forwarded: no Last-Update: 2010-04-06 Index: netkit-ftp-ssl/ftp/cmds.c =================================================================== --- netkit-ftp-ssl.orig/ftp/cmds.c 2010-07-04 00:52:02.000000000 +0100 +++ netkit-ftp-ssl/ftp/cmds.c 2010-07-04 00:52:02.000000000 +0100 @@ -1607,6 +1607,12 @@ code = -1; return; } +#ifdef USE_SSL + if (ssl_secure_flag && !ssl_available) { + fprintf(stdout, "SSL not available - login failed.\n"); + return; + } +#endif /* USE_SSL */ n = command("USER %s", argv[1]); if (n == CONTINUE) { if (argc < 3 ) Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-04 00:52:02.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-04 00:52:02.000000000 +0100 @@ -91,6 +91,7 @@ static int ptflag = 0; static int ptabflg = 0; #ifdef USE_SSL +int ssl_available=1; static int pdata = -1; static int auth_user(char *u,char *p); @@ -2125,8 +2126,10 @@ /* spit the dummy as we will only talk ssl * when running in "secure" mode */ - if (ssl_secure_flag) + if (ssl_secure_flag) { + ssl_available=0; return ERROR; + } } else if (n == CONTINUE || n == COMPLETE ) { /* do SSL */ ssl_con=(SSL *)SSL_new(ssl_ctx); Index: netkit-ftp-ssl/ftp/sslapp.h =================================================================== --- netkit-ftp-ssl.orig/ftp/sslapp.h 2010-07-04 00:52:02.000000000 +0100 +++ netkit-ftp-ssl/ftp/sslapp.h 2010-07-04 00:52:02.000000000 +0100 @@ -59,7 +59,9 @@ extern int server_verify_callback(); extern int client_verify_callback();*/ +extern int ssl_available; extern int ssl_init(void); + #endif /* USE_SSL */ debian/patches/040_ipv6_ftp_c.diff0000644000000000000000000003342111413755027014101 0ustar Description: Impose IPv6-capacities on ftp.c. Super structure 'struct sockaddr_storage' is replacing 'struct sockaddr_in' . For peer address strings, a first try aims at IPv4. That failing, next try is for IPv6, and ultimatively a host lookup follows as last resort. . Use a SIGALRM mechanism to decrease the default TCP handshake timeout to a value better suited for interactive use. The macro can be set externally to change the suggested FTP_CONNECT_TIMEOUT=10 . Use a command EPSV with explicit request for IPv6 address family as soon as parsing concluded that the control socket is using IPv6. . Make IP_TOS conditioned on AF_INET for non-Linux, i.e., GNU/kfreebsd, GNU/Hurd. Author: Mats Erik Andersson Forwarded: no Last-Update: 2010-05-25 --- netkit-ftp-0.17.debian/ftp/ftp.c +++ netkit-ftp-0.17/ftp/ftp.c @@ -71,9 +71,11 @@ int data = -1; off_t restart_point = 0; -static struct sockaddr_in hisctladdr; -static struct sockaddr_in data_addr; -static struct sockaddr_in myctladdr; +static char ipstring[INET6_ADDRSTRLEN]; /* Scribble area for resolver. */ + +static struct sockaddr_storage hisctladdr; +static struct sockaddr_storage data_addr; +static struct sockaddr_storage myctladdr; static int ptflag = 0; static int ptabflg = 0; @@ -95,40 +97,56 @@ static FILE *dataconn(const char *); static void printbytes(off_t); +#if ! defined(FTP_CONNECT_TIMEOUT) || FTP_CONNECT_TIMEOUT < 1 +# define FTP_CONNECT_TIMEOUT 10 +#endif + +static void +trivial_alarm(int sig) +{ + /* Only used to generate an EINTR error. */ + return; +} + char * hookup(char *host, int port) { - register struct hostent *hp = 0; + struct addrinfo hints, *ai = NULL, *aiptr = NULL; + struct sigaction sigact, oldsigact; + int status; volatile int s = -1; - int tos; + int tos, af_in_use; socklen_t len; static char hostnamebuf[256]; sigjmp_buf jmploc; sigjmp_buf *volatile oldtoplevel; int dupfd; + struct sockaddr_in *hisctl_sa4 = (struct sockaddr_in *) &hisctladdr; + struct sockaddr_in6 *hisctl_sa6 = (struct sockaddr_in6 *) &hisctladdr; memset(&hisctladdr, 0, sizeof(hisctladdr)); - if (inet_aton(host, &hisctladdr.sin_addr)) { - hisctladdr.sin_family = AF_INET; - strncpy(hostnamebuf, host, sizeof(hostnamebuf)); - hostnamebuf[sizeof(hostnamebuf)-1]=0; - } - else { - hp = gethostbyname(host); - if (hp == NULL) { - fprintf(stderr, "ftp: %s: ", host); - herror((char *)NULL); - code = -1; - return((char *) 0); - } - hisctladdr.sin_family = hp->h_addrtype; - if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) { - hp->h_length = sizeof(hisctladdr.sin_addr); - } - memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length); - (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf)); - hostnamebuf[sizeof(hostnamebuf)-1] = 0; + + sigact.sa_handler = trivial_alarm; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ( (status = getaddrinfo(host, NULL, &hints, &ai)) ) { + fprintf(stderr, "ftp: %s: %s", host, + gai_strerror(status)); + code = -1; + return((char *) 0); } + + aiptr = ai; + memcpy(&hisctladdr, aiptr->ai_addr, aiptr->ai_addrlen); + (void) strncpy(hostnamebuf, aiptr->ai_canonname, + sizeof(hostnamebuf)); + hostnamebuf[sizeof(hostnamebuf)-1] = 0; hostname = hostnamebuf; oldtoplevel = toplevel; @@ -141,53 +159,132 @@ toplevel = &jmploc; INTOFF; - s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + s = socket(hisctladdr.ss_family, SOCK_STREAM, 0); + af_in_use = hisctladdr.ss_family; INTON; if (s < 0) { perror("ftp: socket"); + freeaddrinfo(ai); code = -1; goto out; } - hisctladdr.sin_port = port; - while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) { - if (hp && hp->h_addr_list[1]) { + switch (hisctladdr.ss_family) { + case AF_INET: + hisctl_sa4->sin_port = port; + break; + case AF_INET6: + hisctl_sa6->sin6_port = port; + } + + sigaction(SIGALRM, &sigact, &oldsigact); + alarm(FTP_CONNECT_TIMEOUT); + + while (connect(s, (struct sockaddr *)&hisctladdr, + (hisctladdr.ss_family == AF_INET) + ? sizeof(struct sockaddr_in) + : sizeof(struct sockaddr_in6)) + < 0) + { + alarm(0); + sigaction(SIGALRM, &oldsigact, NULL); + if (errno == EINTR) + errno = ETIMEDOUT; + + if (aiptr && aiptr->ai_next) + { int oerrno = errno; + struct in_addr *ctladdr4 = &hisctl_sa4->sin_addr; + struct in6_addr *ctladdr6 = &hisctl_sa6->sin6_addr; - fprintf(stderr, "ftp: connect to address %s: ", - inet_ntoa(hisctladdr.sin_addr)); + switch (aiptr->ai_family) { + case AF_INET: + fprintf(stderr, "ftp: connect to address %s: ", + inet_ntop(aiptr->ai_family, + ctladdr4, + ipstring, + sizeof(ipstring))); + break; + case AF_INET6: + fprintf(stderr, "ftp: connect to address %s: ", + inet_ntop(aiptr->ai_family, + ctladdr6, + ipstring, + sizeof(ipstring))); + } errno = oerrno; perror((char *) 0); - hp->h_addr_list++; - memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], - hp->h_length); - fprintf(stdout, "Trying %s...\n", - inet_ntoa(hisctladdr.sin_addr)); + + aiptr = aiptr->ai_next; + memcpy(&hisctladdr, aiptr->ai_addr, + aiptr->ai_addrlen); + switch (hisctladdr.ss_family) { + case AF_INET: + hisctl_sa4->sin_port = port; + break; + case AF_INET6: + hisctl_sa6->sin6_port = port; + } + + switch (aiptr->ai_family) { + case AF_INET: + fprintf(stdout, "Trying %s...\n", + inet_ntop(aiptr->ai_family, + ctladdr4, + ipstring, + sizeof(ipstring))); + break; + case AF_INET6: + fprintf(stdout, "Trying %s...\n", + inet_ntop(aiptr->ai_family, + ctladdr6, + ipstring, + sizeof(ipstring))); + } INTOFF; (void) close(s); - s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + s = socket(aiptr->ai_family, SOCK_STREAM, 0); + af_in_use = aiptr->ai_family; INTON; if (s < 0) { perror("ftp: socket"); + freeaddrinfo(ai); code = -1; goto out; } + /* Try next server candidate. */ continue; } + /* No answer to any call. */ perror("ftp: connect"); + freeaddrinfo(ai); code = -1; goto bad; } + alarm(0); + sigaction(SIGALRM, &oldsigact, NULL); + len = sizeof (myctladdr); if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { perror("ftp: getsockname"); + if (ai) + freeaddrinfo(ai); code = -1; goto bad; } + if (ai) + freeaddrinfo(ai); #ifdef IP_TOS tos = IPTOS_LOWDELAY; +# if defined(__GLIBC__) && !defined(__linux__) + if ( (af_in_use == AF_INET) && + (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(tos)) < 0) ) + perror("ftp: setsockopt TOS (ignored)"); +# else /* __linux__ */ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) perror("ftp: setsockopt TOS (ignored)"); -#endif +# endif /* GNU/kfreebsd */ +#endif /* IP_TOS */ INTOFF; if (cin) fclose(cin); @@ -458,7 +555,7 @@ } if (dig < 4 && isdigit(c)) code = code * 10 + (c - '0'); - if (!pflag && code == 227) + if (!pflag && (code == 227 || code == 229)) pflag = 1; if (dig > 4 && pflag == 1 && isdigit(c)) pflag = 2; @@ -1198,18 +1295,21 @@ static int initconn(void) { - register char *p, *a; + register char *p = NULL, *a = NULL; int result, tmpno = 0; socklen_t len; int on = 1; int tos; u_long a1,a2,a3,a4,p1,p2; + unsigned short int port; + struct sockaddr_in *data_addr_sa4 = (struct sockaddr_in *) &data_addr; + struct sockaddr_in6 *data_addr_sa6 = (struct sockaddr_in6 *) &data_addr; if (passivemode) { INTOFF; if (data >= 0) close(data); - data = socket(AF_INET, SOCK_STREAM, 0); + data = socket(hisctladdr.ss_family, SOCK_STREAM, 0); INTON; if (data < 0) { perror("ftp: socket"); @@ -1219,32 +1319,67 @@ setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0) perror("ftp: setsockopt (ignored)"); - if (command("PASV") != COMPLETE) { - printf("Passive mode refused.\n"); - return(1); - } - - /* - * What we've got at this point is a string of comma separated - * one-byte unsigned integer values, separated by commas. - * The first four are the an IP address. The fifth is the MSB - * of the port number, the sixth is the LSB. From that we'll - * prepare a sockaddr_in. - */ - - if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld", - &a1,&a2,&a3,&a4,&p1,&p2) - != 6) - { - printf("Passive mode address scan failure. Shouldn't happen!\n"); - return(1); + switch (hisctladdr.ss_family) { + case AF_INET: + if (command("PASV") != COMPLETE) { + printf("Passive mode refused.\n"); + return(1); + } + break; + case AF_INET6: + if (command("EPSV 2") != COMPLETE) { + printf("Passive mode refused.\n"); + return(1); + } } - data_addr.sin_family = AF_INET; - data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) | - (a3 << 8) | a4); - data_addr.sin_port = htons((p1 << 8) | p2); - + if (hisctladdr.ss_family == AF_INET) { + /* + * IPv4 + * + * What we've got at this point is a string of + * comma separated one-byte unsigned integer + * values, separated by commas. The first four + * are the an IP address. The fifth is the MSB + * of the port number, the sixth is the LSB. + * From that we will prepare a sockaddr_in. + */ + + if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld", + &a1,&a2,&a3,&a4,&p1,&p2) + != 6) + { + printf("Passive mode address scan failure." + "Shouldn't happen!\n"); + return(1); + } + + data_addr.ss_family = AF_INET; + data_addr_sa4->sin_addr.s_addr = + htonl((a1 << 24) | (a2 << 16) | + (a3 << 8) | a4); + data_addr_sa4->sin_port = htons((p1 << 8) | p2); + } /* Old IPv4 command PASV */ + else { + /* EPSV for IPv6 + * + * Expected: pasv =~ "%u|" + * + * This is a shortcut based on the old code + * for getreply(), only altered to accept + * return code "229" for ESPV, in addition + * to "227" which goes with PASV. + */ + if (sscanf(pasv, "%hu", &port) != 1) { + printf("Extended passive mode address " + "scan failure. Unfortunate!\n"); + return(1); + } + data_addr = hisctladdr; + data_addr.ss_family = AF_INET6; + data_addr_sa6->sin6_port = htons(port); + } /* EPSV for IPv6 */ + if (connect(data, (struct sockaddr *) &data_addr, sizeof(data_addr))<0) { perror("ftp: connect"); @@ -1252,20 +1387,34 @@ } #ifdef IP_TOS tos = IPTOS_THROUGHPUT; +# if defined(__GLIBC__) && !defined(__linux__) + if ( (hisctladdr.ss_family == AF_INET) && + (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(tos)) < 0) ) + perror("ftp: setsockopt TOS (ignored)"); +# else /* __linux__ */ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos)) < 0) perror("ftp: setsockopt TOS (ignored)"); -#endif +# endif /* GNU/kfreebsd */ +#endif /* IP_TOS */ return(0); } noport: data_addr = myctladdr; if (sendport) - data_addr.sin_port = 0; /* let system pick one */ + /* let the system pick a port */ + switch (data_addr.ss_family) { + case AF_INET: + data_addr_sa4->sin_port = 0; + break; + case AF_INET6: + data_addr_sa6->sin6_port = 0; + } INTOFF; if (data != -1) (void) close(data); - data = socket(AF_INET, SOCK_STREAM, 0); + data = socket(data_addr.ss_family, SOCK_STREAM, 0); INTON; if (data < 0) { perror("ftp: socket"); @@ -1293,13 +1442,23 @@ if (listen(data, 1) < 0) perror("ftp: listen"); if (sendport) { - a = (char *)&data_addr.sin_addr; - p = (char *)&data_addr.sin_port; #define UC(b) (((int)b)&0xff) - result = - command("PORT %d,%d,%d,%d,%d,%d", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(p[0]), UC(p[1])); + switch (data_addr.ss_family) { + case AF_INET: + a = (char *)&data_addr_sa4->sin_addr; + p = (char *)&data_addr_sa4->sin_port; + result = command("PORT %d,%d,%d,%d,%d,%d", + UC(a[0]), UC(a[1]), UC(a[2]), + UC(a[3]), UC(p[0]), UC(p[1])); + break; + case AF_INET6: + result = command("EPRT |2|%s|%d|", + inet_ntop(data_addr.ss_family, + &data_addr_sa6->sin6_addr, + ipstring, + sizeof(ipstring)), + ntohs(data_addr_sa6->sin6_port)); + } if (result == ERROR && sendport == -1) { sendport = 0; tmpno = 1; @@ -1311,9 +1470,16 @@ sendport = 1; #ifdef IP_TOS on = IPTOS_THROUGHPUT; +# if defined(__GLIBC__) && !defined(__linux__) + if ( (data_addr.ss_family == AF_INET) && + (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(tos)) < 0) ) + perror("ftp: setsockopt TOS (ignored)"); +# else /* __linux__ */ if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) perror("ftp: setsockopt TOS (ignored)"); -#endif +# endif /* GNU/kfreebsd */ +#endif /* IP_TOS */ return (0); bad: INTOFF; @@ -1327,7 +1493,7 @@ static FILE * dataconn(const char *lmode) { - struct sockaddr_in from; + struct sockaddr_storage from; int s, tos; socklen_t fromlen = sizeof(from); @@ -1344,9 +1510,16 @@ data = s; #ifdef IP_TOS tos = IPTOS_THROUGHPUT; +# if defined(__GLIBC__) && !defined(__linux__) + if ( (from.ss_family == AF_INET) && + (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(tos)) < 0) ) + perror("ftp: setsockopt TOS (ignored)"); +# else /* __linux__ */ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) perror("ftp: setsockopt TOS (ignored)"); -#endif +# endif /* GNU/kfreebsd */ +#endif /* IP_TOS */ return (fdopen(data, lmode)); } @@ -1398,8 +1571,8 @@ static struct comvars { int connect; char name[MAXHOSTNAMELEN]; - struct sockaddr_in mctl; - struct sockaddr_in hctl; + struct sockaddr_storage mctl; + struct sockaddr_storage hctl; FILE *in; FILE *out; int tpe; debian/patches/510_fix_ssl_auth_response.diff0000644000000000000000000000133511413755027016451 0ustar Description: Fix AUTH SSL response handling Accept COMPLETE (234) as well as CONTINUE (334) See Debian bug #168762 for full details. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=168762 Forwarded: no Author: James Manning Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-03 23:54:41.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-03 23:54:41.000000000 +0100 @@ -2110,7 +2110,7 @@ */ if (ssl_secure_flag) return ERROR; - } else if (n == CONTINUE ) { + } else if (n == CONTINUE || n == COMPLETE ) { /* do SSL */ ssl_con=(SSL *)SSL_new(ssl_ctx); debian/patches/600_fix_passive_mode.diff0000644000000000000000000000346211413755027015372 0ustar Description: Fix passive mode when SSL is enabled Origin/Author unknown. From netkit-telnet-ssl 0.17.9+0.2-3: * fix broken passive mode while SSL is enabled (thanks to Stefan Esser ) Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-04 00:08:21.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-04 00:49:39.000000000 +0100 @@ -1630,29 +1630,28 @@ socklen_t fromlen = sizeof(from); int ret; - if (passivemode) - return (fdopen(data, lmode)); - - s = accept(data, (struct sockaddr *) &from, &fromlen); - if (s < 0) { - perror("ftp: accept"); - (void) close(data), data = -1; - return (NULL); - } - (void) close(data); - data = s; + if (!passivemode) { + s = accept(data, (struct sockaddr *) &from, &fromlen); + if (s < 0) { + perror("ftp: accept"); + (void) close(data), data = -1; + return (NULL); + } + (void) close(data); + data = s; #ifdef IP_TOS - tos = IPTOS_THROUGHPUT; + tos = IPTOS_THROUGHPUT; # if defined(__GLIBC__) && !defined(__linux__) - if ( (from.ss_family == AF_INET) && - (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, - sizeof(tos)) < 0) ) - perror("ftp: setsockopt TOS (ignored)"); + if ( (from.ss_family == AF_INET) && + (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, + sizeof(tos)) < 0) ) + perror("ftp: setsockopt TOS (ignored)"); # else /* __linux__ */ - if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); + if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) + perror("ftp: setsockopt TOS (ignored)"); # endif /* GNU/kfreebsd */ #endif /* IP_TOS */ + } #ifdef USE_SSL ssl_data_active_flag=0; debian/patches/010_patches_in_sarge.diff0000644000000000000000000017632111413755027015344 0ustar Description: Source patches applied to release Sarge. Multiple patches. X-Comment: Recovered from package netkit-ftp_0.17-12.diff.gx Author: Herbert Xu Forwarded: no Last-Update: 2003+06-29 --- netkit-ftp-0.17.orig/ftp/Makefile +++ netkit-ftp-0.17/ftp/Makefile @@ -8,7 +8,7 @@ LIBS += -lreadline $(LIBTERMCAP) endif -ftp: cmds.o cmdtab.o domacro.o ftp.o glob.o main.o ruserpass.o +ftp: cmds.o cmdtab.o domacro.o ftp.o main.o ruserpass.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ domacro.o ftp.o glob.o main.o ruserpass.o: ftp_var.h pathnames.h --- netkit-ftp-0.17.orig/ftp/cmds.c +++ netkit-ftp-0.17/ftp/cmds.c @@ -50,6 +50,7 @@ #include #include +#include #include #include #include @@ -58,6 +59,7 @@ #include #include #include +#include #ifdef __USE_READLINE__ #include #include @@ -66,9 +68,7 @@ #include "ftp_var.h" #include "pathnames.h" #include "cmds.h" -#include "glob.h" - -void intr(int); +#include "main.h" extern FILE *cout; extern int data; @@ -77,17 +77,16 @@ extern char reply_string[]; static char *mname; -static sigjmp_buf jabort; -static sigjmp_buf abortprox; static char *remglob(char *argv[], int doswitch); -static int checkglob(int fd, const char *pattern); +static int checkglob(FILE *fp, const char *pattern); static char *dotrans(char *name); static char *domap(char *name); static char *globulize(char *str); static int confirm(const char *cmd, const char *file); static int getit(int argc, char *argv[], int restartit, const char *modestr); static void quote1(const char *initial, int argc, char **argv); +static void dosyst(void); /* @@ -101,13 +100,9 @@ return name; } - /* We're going to leak this memory. XXX. */ - nu = malloc(strlen(name)+3); - if (nu==NULL) { - perror("malloc"); - code = -1; - return NULL; - } + INTOFF; + nu = obstack_alloc(&mainobstack, strlen(name)+3); + INTON; strcpy(nu, "."); if (*name != '/') strcat(nu, "/"); strcat(nu, name); @@ -163,18 +158,38 @@ unsigned len = strlen(line); int ret; + size_t lynesize; + ssize_t lynelen; + char *lyne; + + /* We need obstack_unfinish() badly! */ + INTOFF; + lyne = obstack_copy(&mainobstack, line, len); + obstack_free(&lineobstack, line); + obstack_grow(&lineobstack, lyne, len); + obstack_1grow(&lineobstack, ' '); + INTON; + obstack_free(&mainobstack, lyne); - if (len >= sizeof(line) - 3) { - printf("sorry, arguments too long\n"); - intr(0); - } printf("(%s) ", prompt); - line[len++] = ' '; - if (fgets(&line[len], sizeof(line) - len, stdin) == NULL) + lyne = NULL; + lynesize = 0; + INTOFF; + if ((lynelen = getline(&lyne, &lynesize, stdin)) == -1) { + if (lyne) + free(lyne); + suppressint = 0; intr(0); - len += strlen(&line[len]); - if (len > 0 && line[len - 1] == '\n') - line[len - 1] = '\0'; + } + if (lynelen > 0) { + obstack_grow0(&lineobstack, lyne, lyne[lynelen - 1] == '\n' ? + lynelen - 1 : lynelen); + } else { + obstack_1grow(&lineobstack, '\0'); + } + free(lyne); + INTON; + line = obstack_finish(&lineobstack); margv = makeargv(&margc, NULL); ret = margc > *pargc; *pargc = margc; @@ -218,8 +233,6 @@ } host = hookup(argv[1], port); if (host) { - int overbose; - connected = 1; /* * Set up defaults for FTP. @@ -232,62 +245,7 @@ (void) strcpy(bytename, "8"), bytesize = 8; if (autologin) (void) dologin(argv[1]); - -#if defined(__unix__) && CHAR_BIT == 8 -/* - * this ifdef is to keep someone form "porting" this to an incompatible - * system and not checking this out. This way they have to think about it. - */ - overbose = verbose; - if (debug == 0) - verbose = -1; - if (command("SYST") == COMPLETE && overbose) { - register char *cp, c = 0; - cp = index(reply_string+4, ' '); - if (cp == NULL) - cp = index(reply_string+4, '\r'); - if (cp) { - if (cp[-1] == '.') - cp--; - c = *cp; - *cp = '\0'; - } - - printf("Remote system type is %s.\n", - reply_string+4); - if (cp) - *cp = c; - } - if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { - if (proxy) - unix_proxy = 1; - else - unix_server = 1; - /* - * Set type to 0 (not specified by user), - * meaning binary by default, but don't bother - * telling server. We can use binary - * for text files unless changed by the user. - */ - type = 0; - (void) strcpy(typename, "binary"); - if (overbose) - printf("Using %s mode to transfer files.\n", - typename); - } else { - if (proxy) - unix_proxy = 0; - else - unix_server = 0; - if (overbose && - !strncmp(reply_string, "215 TOPS20", 10)) - printf( -"Remember to set tenex mode when transfering binary files from this machine.\n"); - } - verbose = overbose; -#else -#warning "Unix auto-mode code skipped" -#endif /* unix */ + dosyst(); } } @@ -513,9 +471,13 @@ mput(int argc, char *argv[]) { register int i; - void (*oldintr)(int); int ointer; char *tp; + glob_t pglob; + volatile int glob_called = 0; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; + int globerr; if (argc < 2 && !another(&argc, &argv, "local-files")) { printf("usage: %s local-files\n", argv[0]); @@ -524,8 +486,16 @@ } mname = argv[0]; mflag = 1; - oldintr = signal(SIGINT, mabort); - (void) sigsetjmp(jabort, 1); + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + if (glob_called) { + globfree(&pglob); + glob_called = 0; + } + mabort(SIGINT); + } else { + toplevel = &jmploc; + } if (proxy) { char *cp, *tp2, tmpbuf[PATH_MAX]; @@ -571,12 +541,10 @@ } } } - (void) signal(SIGINT, oldintr); - mflag = 0; - return; + goto out; } for (i = 1; i < argc; i++) { - register char **cpp, **gargs; + char **cpp; if (!doglob) { if (mflag && confirm(argv[0], argv[i])) { @@ -595,16 +563,23 @@ } continue; } - gargs = ftpglob(argv[i]); - if (globerr != NULL) { - printf("%s\n", globerr); - if (gargs) { - blkfree(gargs); - free((char *)gargs); - } + INTOFF; + globerr = glob(argv[i], GLOB_BRACE | GLOB_ERR | GLOB_NOCHECK | + GLOB_NOESCAPE | GLOB_TILDE, 0, &pglob); + switch (globerr) { + case GLOB_NOSPACE: + errno = ENOMEM; + goto err; + case GLOB_ABORTED: + globfree(&pglob); +err: + INTON; + puts(strerror(errno)); continue; } - for (cpp = gargs; cpp && *cpp != NULL; cpp++) { + glob_called = 1; + INTON; + for (cpp = pglob.gl_pathv; *cpp; cpp++) { if (mflag && confirm(argv[0], *cpp)) { tp = (ntflag) ? dotrans(*cpp) : *cpp; tp = (mapflag) ? domap(tp) : tp; @@ -620,12 +595,13 @@ } } } - if (gargs != NULL) { - blkfree(gargs); - free((char *)gargs); - } + INTOFF; + globfree(&pglob); + glob_called = 0; + INTON; } - (void) signal(SIGINT, oldintr); +out: + toplevel = oldtoplevel; mflag = 0; } @@ -657,10 +633,6 @@ * local names. */ argv[2] = pipeprotect(argv[1]); - if (!argv[2]) { - code = -1; - return 0; - } loc++; } if (argc < 2 && !another(&argc, &argv, "remote-file")) @@ -785,12 +757,11 @@ interactive = 1; if (confirm("Continue with", mname)) { interactive = ointer; - siglongjmp(jabort,0); + return; } interactive = ointer; } mflag = 0; - siglongjmp(jabort,0); } /* @@ -799,9 +770,10 @@ void mget(int argc, char **argv) { - void (*oldintr)(int); int ointer; char *cp, *tp, *tp2, tmpbuf[PATH_MAX]; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; if (argc < 2 && !another(&argc, &argv, "remote-files")) { printf("usage: %s remote-files\n", argv[0]); @@ -810,8 +782,12 @@ } mname = argv[0]; mflag = 1; - oldintr = signal(SIGINT,mabort); - (void) sigsetjmp(jabort, 1); + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + mabort(SIGINT); + } else { + toplevel = &jmploc; + } while ((cp = remglob(argv,proxy)) != NULL) { if (*cp == '\0') { mflag = 0; @@ -847,14 +823,8 @@ /* Prepend ./ to "-" or "!*" or leading "/" */ tp = pipeprotect(tp); - if (tp == NULL) { - /* hmm... how best to handle this? */ - mflag = 0; - } - else { - recvrequest("RETR", tp, cp, "w", - tp != cp || !interactive); - } + recvrequest("RETR", tp, cp, "w", + tp != cp || !interactive); if (!mflag && fromatty) { ointer = interactive; interactive = 1; @@ -865,14 +835,13 @@ } } } - (void) signal(SIGINT,oldintr); + toplevel = oldtoplevel; mflag = 0; } char * remglob(char *argv[], int doswitch) { - char temp[16]; static char buf[PATH_MAX]; static FILE *ftemp = NULL; static char **args; @@ -885,8 +854,10 @@ } else { if (ftemp) { + INTOFF; (void) fclose(ftemp); ftemp = NULL; + INTON; } } return(NULL); @@ -899,34 +870,88 @@ return (cp); } if (ftemp == NULL) { - int oldumask, fd; + char temp[16] = ""; +#if !defined(__GLIBC__) || !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)) + int oldumask; +#endif + volatile int fd = -1; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; + (void) strcpy(temp, _PATH_TMP); + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 0)) { + if (fd >= 0) { + unlink(temp); + close(fd); + } + toplevel = oldtoplevel; + siglongjmp(*toplevel, 1); + } + toplevel = &jmploc; + /* libc 5.2.18 creates with mode 0666, which is dumb */ + INTOFF; +#if !defined(__GLIBC__) || !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)) oldumask = umask(077); +#endif fd = mkstemp(temp); +#if !defined(__GLIBC__) || !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)) umask(oldumask); +#endif + INTON; if (fd<0) { + toplevel = oldtoplevel; printf("Error creating temporary file, oops\n"); return NULL; } - + oldverbose = verbose, verbose = 0; oldhash = hash, hash = 0; if (doswitch) { pswitch(!proxy); } while (*++argv != NULL) { - int dupfd = dup(fd); + int dupfd; recvrequest ("NLST", temp, *argv, "a", 0); - if (!checkglob(dupfd, *argv)) { - badglob = 1; + + INTOFF; + if ((dupfd = dup(fd)) < 0) { + INTON; + perror("remglob: dup"); +duperr: + INTOFF; + unlink(temp); + close(fd); + fd = -1; + INTON; + toplevel = oldtoplevel; + return NULL; + } + if ((ftemp = fdopen(dupfd, "r")) == NULL) { + int olderrno = errno; + close(dupfd); + INTON; + errno = olderrno; + perror("remglob: fdopen"); + goto duperr; + } + INTON; + + badglob = !checkglob(ftemp, *argv); + + INTOFF; + fclose(ftemp); + ftemp = NULL; + INTON; + + if (badglob) { break; } } - unlink(temp); if (doswitch) { pswitch(!proxy); @@ -934,18 +959,27 @@ verbose = oldverbose; hash = oldhash; if (badglob) { printf("Refusing to handle insecure file list\n"); - close(fd); - return NULL; + goto duperr; } + + INTOFF; + unlink(temp); ftemp = fdopen(fd, "r"); + fd = -1; + INTON; + toplevel = oldtoplevel; + if (ftemp == NULL) { printf("fdopen failed, oops\n"); return NULL; } + rewind(ftemp); } if (fgets(buf, sizeof (buf), ftemp) == NULL) { + INTOFF; (void) fclose(ftemp), ftemp = NULL; + INTON; return (NULL); } if ((cp = index(buf, '\n')) != NULL) @@ -993,12 +1027,11 @@ * --okir */ static int -checkglob(int fd, const char *pattern) +checkglob(FILE *fp, const char *pattern) { const char *sp; char buffer[MAXPATHLEN], dotdot[MAXPATHLEN]; int okay = 1, nrslash, initial, nr; - FILE *fp; /* Find slashes in glob pattern, and verify whether component * matches `..' @@ -1014,7 +1047,6 @@ dotdot[nrslash++] = isdotdotglob(sp); } - fp = fdopen(fd, "r"); while (okay && fgets(buffer, sizeof(buffer), fp) != NULL) { char *sp; @@ -1043,7 +1075,6 @@ printf("Filename provided by server " "doesn't match pattern `%s': %s\n", pattern, buffer); - fclose(fp); return okay; } @@ -1083,6 +1114,7 @@ printf("Store unique: %s; Receive unique: %s\n", onoff(sunique), onoff(runique)); printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag)); + printf("Quote control characters: %s\n", onoff(qcflag)); if (ntflag) { printf("Ntrans: (in) %s (out) %s\n", ntin,ntout); } @@ -1316,9 +1348,10 @@ void mdelete(int argc, char *argv[]) { - void (*oldintr)(int); int ointer; char *cp; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; if (argc < 2 && !another(&argc, &argv, "remote-files")) { printf("usage: %s remote-files\n", argv[0]); @@ -1327,8 +1360,12 @@ } mname = argv[0]; mflag = 1; - oldintr = signal(SIGINT, mabort); - (void) sigsetjmp(jabort, 1); + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + mabort(SIGINT); + } else { + toplevel = &jmploc; + } while ((cp = remglob(argv,0)) != NULL) { if (*cp == '\0') { mflag = 0; @@ -1346,7 +1383,7 @@ } } } - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; mflag = 0; } @@ -1390,16 +1427,15 @@ code = -1; return; } + cmd = argv[0][0] == 'n' ? "NLST" : "LIST"; - if (strcmp(argv[2], "-") && (argv[2] = globulize(argv[2]))==NULL) { - code = -1; - return; - } - if (strcmp(argv[2], "-") && *argv[2] != '|') - if ((argv[2] = globulize(argv[2]))==NULL || + if (strcmp(argv[2], "-") && *argv[2] != '|') { + argv[2] = globulize(argv[2]); + if (argv[2] == NULL || !confirm("output to local-file:", argv[2])) { code = -1; return; + } } recvrequest(cmd, argv[2], argv[1], "w", 0); } @@ -1411,11 +1447,12 @@ void mls(int argc, char *argv[]) { - void (*oldintr)(int); int ointer, i; const char *volatile cmd; char *volatile dest; const char *modestr; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; if (argc < 2 && !another(&argc, &argv, "remote-files")) goto usage; @@ -1425,23 +1462,30 @@ code = -1; return; } + dest = argv[argc - 1]; argv[argc - 1] = NULL; - if (strcmp(dest, "-") && *dest != '|') - if ((dest = globulize(dest))==NULL || - !confirm("output to local-file:", dest)) { + + if (strcmp(dest, "-") && *dest != '|') { + dest = globulize(dest); + if (dest == NULL || !confirm("output to local-file:", dest)) { code = -1; return; + } } cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; mname = argv[0]; mflag = 1; - oldintr = signal(SIGINT, mabort); /* * This just plain seems wrong. */ - (void) sigsetjmp(jabort, 1); + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + mabort(SIGINT); + } else { + toplevel = &jmploc; + } for (i = 1; mflag && i < argc-1; ++i) { modestr = (i == 1) ? "w" : "a"; @@ -1455,7 +1499,7 @@ interactive = ointer; } } - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; mflag = 0; } @@ -1555,6 +1599,7 @@ if (!aflag && argc == 4) { (void) command("ACCT %s", argv[3]); } + dosyst(); } /* @@ -1651,19 +1696,28 @@ static void quote1(const char *initial, int argc, char **argv) { - register int i, len; - char buf[BUFSIZ]; /* must be >= sizeof(line) */ + register int i; + char *buf; - (void) strcpy(buf, initial); + INTOFF; + obstack_grow(&mainobstack, initial, strlen(initial)); if (argc > 1) { - len = strlen(buf); - len += strlen(strcpy(&buf[len], argv[1])); + obstack_grow(&mainobstack, argv[1], strlen(argv[1])); for (i = 2; i < argc; i++) { - buf[len++] = ' '; - len += strlen(strcpy(&buf[len], argv[i])); + obstack_1grow(&mainobstack, ' '); + obstack_grow(&mainobstack, argv[i], strlen(argv[i])); } } - if (command("%s", buf) == PRELIM) { + INTON; + + obstack_1grow(&mainobstack, '\0'); + buf = obstack_finish(&mainobstack); + i = command("%s", buf); + INTOFF; + obstack_free(&mainobstack, buf); + INTON; + + if (i == PRELIM) { while (getreply(0) == PRELIM); } } @@ -1742,11 +1796,18 @@ return; (void) command("QUIT"); if (cout) { + INTOFF; (void) fclose(cout); + cout = NULL; + INTON; + } + if (data >= 0) { + INTOFF; + close(data); + data = -1; + INTON; } - cout = NULL; connected = 0; - data = -1; if (!proxy) { macnum = 0; } @@ -1764,10 +1825,16 @@ if (fromatty && !rl_inhibit) { char *lineread; snprintf(lyne, BUFSIZ, "%s %s? ", cmd, file); + /* XXX readline memory leak */ lineread = readline(lyne); - if (!lineread) return 0; - strcpy(lyne, lineread); + if (!lineread) { + return 0; + } + INTOFF; + lyne[0] = lineread[0]; free(lineread); + INTON; + lyne[1] = 0; } else { #endif @@ -1800,28 +1867,28 @@ char * globulize(char *cpp) { - char **globbed; - char *rv = cpp; + char *rv; + glob_t pglob; if (!doglob) return cpp; - globbed = ftpglob(cpp); - if (globerr != NULL) { - printf("%s: %s\n", cpp, globerr); - if (globbed) { - blkfree(globbed); - free(globbed); - } + INTOFF; + switch(glob(cpp, GLOB_BRACE | GLOB_ERR | GLOB_NOCHECK | + GLOB_NOESCAPE | GLOB_TILDE, 0, &pglob)) { + case GLOB_NOSPACE: + errno = ENOMEM; + goto err; + case GLOB_ABORTED: + globfree(&pglob); +err: + INTON; + puts(strerror(errno)); return NULL; } - if (globbed) { - rv = globbed[0]; - /* don't waste too much memory */ - if (globbed[0]) { - blkfree(globbed+1); - } - free(globbed); - } + rv = pglob.gl_pathv[0]; + rv = obstack_copy0(&mainobstack, rv, strlen(rv)); + globfree(&pglob); + INTON; return rv; } @@ -1862,14 +1929,14 @@ proxflag = 0; } pswitch(0); - siglongjmp(abortprox,1); } void doproxy(int argc, char *argv[]) { register struct cmd *c; - void (*oldintr)(int); + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; if (argc < 2 && !another(&argc, &argv, "command")) { printf("usage: %s command\n", argv[0]); @@ -1895,17 +1962,20 @@ code = -1; return; } - if (sigsetjmp(abortprox, 1)) { + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + proxabort(SIGINT); + toplevel = oldtoplevel; code = -1; return; } - oldintr = signal(SIGINT, proxabort); + toplevel = &jmploc; pswitch(1); if (c->c_conn && !connected) { printf("Not connected\n"); (void) fflush(stdout); pswitch(0); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } @@ -1921,7 +1991,7 @@ proxflag = 0; } pswitch(0); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; } void @@ -1941,6 +2011,14 @@ } void +setqc(void) +{ + qcflag = !qcflag; + printf("Quote control characters %s.\n", onoff(qcflag)); + code = qcflag; +} + +void setntrans(int argc, char *argv[]) { if (argc == 1) { @@ -2225,8 +2303,8 @@ if (argc != 2) printf("restart: offset not specified\n"); else { - restart_point = atol(argv[1]); - printf("restarting at %ld. %s\n", restart_point, + restart_point = atoll(argv[1]); + printf("restarting at %jd. %s\n", (intmax_t) restart_point, "execute get, put or append to initiate transfer"); } } @@ -2374,3 +2452,69 @@ argv[2], argv[1]); } } + +/* + * initialise file types etc + */ +static void +dosyst() +{ +#if defined(__unix__) && CHAR_BIT == 8 +/* + * this ifdef is to keep someone form "porting" this to an incompatible + * system and not checking this out. This way they have to think about it. + */ + + int overbose; + + overbose = verbose; + if (debug == 0) + verbose = -1; + if (command("SYST") == COMPLETE && overbose) { + register char *cp, c = 0; + cp = index(reply_string+4, ' '); + if (cp == NULL) + cp = index(reply_string+4, '\r'); + if (cp) { + if (cp[-1] == '.') + cp--; + c = *cp; + *cp = '\0'; + } + + printf("Remote system type is %s.\n", + reply_string+4); + if (cp) + *cp = c; + } + if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) { + if (proxy) + unix_proxy = 1; + else + unix_server = 1; + /* + * Set type to 0 (not specified by user), + * meaning binary by default, but don't bother + * telling server. We can use binary + * for text files unless changed by the user. + */ + type = 0; + (void) strcpy(typename, "binary"); + if (overbose) + printf("Using %s mode to transfer files.\n", + typename); + } else { + if (proxy) + unix_proxy = 0; + else + unix_server = 0; + if (overbose && + !strncmp(reply_string, "215 TOPS20", 10)) + printf( +"Remember to set tenex mode when transfering binary files from this machine.\n"); + } + verbose = overbose; +#else +#warning "Unix auto-mode code skipped" +#endif /* unix */ +} --- netkit-ftp-0.17.orig/ftp/cmds.h +++ netkit-ftp-0.17/ftp/cmds.h @@ -42,6 +42,7 @@ void makedir(int argc, char *argv[]); void removedir(int argc, char *argv[]); void setcr(void); +void setqc(void); void account(int argc, char *argv[]); void doproxy(int argc, char *argv[]); void reset(void); --- netkit-ftp-0.17.orig/ftp/cmdtab.c +++ netkit-ftp-0.17/ftp/cmdtab.c @@ -56,6 +56,7 @@ const char chmodhelp[] = "change file permissions of remote file"; const char connecthelp[] = "connect to remote ftp"; const char crhelp[] = "toggle carriage return stripping on ascii gets"; +const char qchelp[] = "print ? in place of control characters on stdout"; const char deletehelp[] = "delete remote file"; const char debughelp[] = "toggle/set debugging mode"; const char dirhelp[] = "list contents of remote directory"; @@ -160,6 +161,7 @@ { "prompt", prompthelp, 0, 0, 0, NULL, setprompt, NULL }, { "passive", passivehelp, 0, 0, 0, NULL, setpassive, NULL }, { "proxy", proxyhelp, 0, 0, 1, doproxy, NULL, NULL }, + { "qc", qchelp, 0, 0, 0, NULL, setqc, NULL }, { "sendport", porthelp, 0, 0, 0, NULL, setport, NULL }, { "put", sendhelp, 1, 1, 1, put, NULL, NULL }, { "pwd", pwdhelp, 0, 1, 1, NULL, pwd, NULL }, --- netkit-ftp-0.17.orig/ftp/domacro.c +++ netkit-ftp-0.17/ftp/domacro.c @@ -40,9 +40,21 @@ #include #include #include +#include #include #include "ftp_var.h" +#include "main.h" + +static char *append(char *p, const char *s) { + size_t slen = strlen(s); + + INTOFF; + obstack_blank(&lineobstack, slen); + INTON; + memcpy(p, s, slen); + return p + slen; +} void domacro(int argc, char *argv[]) @@ -53,8 +65,9 @@ register int i, j; register char *cp1, *cp2; int count = 2, loopflg = 0; - char line2[200]; + char *line2; struct cmd *c; + size_t len; if (argc < 2 && !another(&argc, &argv, "macro name")) { printf("Usage: %s macro_name.\n", argv[0]); @@ -71,14 +84,18 @@ code = -1; return; } - (void) strcpy(line2, line); + line2 = line; TOP: cp1 = macros[i].mac_start; while (cp1 != macros[i].mac_end) { while (isspace(*cp1)) { cp1++; } - cp2 = line; + len = strlen(cp1) + 1; + INTOFF; + obstack_blank(&lineobstack, len); + INTON; + cp2 = obstack_base(&lineobstack); while (*cp1 != '\0') { switch(*cp1) { case '\\': @@ -92,8 +109,7 @@ } cp1--; if (argc - 2 >= j) { - (void) strcpy(cp2, argv[j+1]); - cp2 += strlen(argv[j+1]); + cp2 = append(cp2, argv[j+1]); } break; } @@ -101,8 +117,7 @@ loopflg = 1; cp1++; if (count < argc) { - (void) strcpy(cp2, argv[count]); - cp2 += strlen(argv[count]); + cp2 = append(cp2, argv[count]); } break; } @@ -116,6 +131,7 @@ } } *cp2 = '\0'; + line = obstack_finish(&lineobstack); margv = makeargv(&margc, &marg); c = getcmd(margv[0]); if (c == (struct cmd *)-1) { @@ -141,11 +157,19 @@ if (bell && c->c_bell) { (void) putchar('\007'); } - (void) strcpy(line, line2); + INTOFF; + obstack_free(&lineobstack, line); + INTON; + line = line2; margv = makeargv(&margc, &marg); argc = margc; argv = margv; } + if (line != line2) { + INTOFF; + obstack_free(&lineobstack, line); + INTON; + } if (cp1 != macros[i].mac_end) { cp1++; } @@ -153,4 +177,5 @@ if (loopflg && ++count < argc) { goto TOP; } + line = line2; } --- netkit-ftp-0.17.orig/ftp/ftp.1 +++ netkit-ftp-0.17/ftp/ftp.1 @@ -43,10 +43,10 @@ .Sh SYNOPSIS .Nm ftp .Op Fl pinegvd -.Op Ar host +.Op Ar host Op Ar port .Nm pftp .Op Fl inegvd -.Op Ar host +.Op Ar host Op Ar port .Sh DESCRIPTION .Nm Ftp is the user interface to the @@ -99,7 +99,7 @@ Enables debugging. .El .Pp -The client host with which +The client host and an optional port number with which .Nm ftp is to communicate may be specified on the command line. If this is done, @@ -218,6 +218,13 @@ distinguished from a record delimiter only when .Ic \&cr is off. +.It Ic qc +Toggle the printing of control characters in the output of +.Tn ASCII +type commands. When this is turned on, control characters +are replaced with a question mark if the output file is the +standard output. This is the default when the standard +output is a tty. .It Ic delete Ar remote-file Delete the file .Ar remote-file @@ -698,6 +705,9 @@ .Ar remote-file and the transfer is continued from the apparent point of failure. +If +.Ar local-file +does not exist ftp won't fetch the file. This command is useful when transferring very large files over networks that are prone to dropping connections. @@ -1030,6 +1040,7 @@ .El .Sh SEE ALSO .Xr ftpd 8 , +.Xr netrc 5 , RFC 959 .Sh HISTORY The --- netkit-ftp-0.17.orig/ftp/ftp.c +++ netkit-ftp-0.17/ftp/ftp.c @@ -50,6 +50,7 @@ #include #include +#include #include #include #include @@ -59,9 +60,11 @@ #include #include #include +#include #include "ftp_var.h" #include "cmds.h" +#include "main.h" #include "../version.h" @@ -72,11 +75,7 @@ static struct sockaddr_in data_addr; static struct sockaddr_in myctladdr; static int ptflag = 0; -static sigjmp_buf recvabort; -static sigjmp_buf sendabort; -static sigjmp_buf ptabort; static int ptabflg = 0; -static int abrtflag = 0; void lostpeer(int); extern int connected; @@ -84,7 +83,7 @@ static char *gunique(char *); static void proxtrans(const char *cmd, char *local, char *remote); static int initconn(void); -static void ptransfer(const char *direction, long bytes, +static void ptransfer(const char *direction, off_t bytes, const struct timeval *t0, const struct timeval *t1); static void tvsub(struct timeval *tdiff, @@ -94,14 +93,19 @@ FILE *cin, *cout; static FILE *dataconn(const char *); +static void printbytes(off_t); char * hookup(char *host, int port) { register struct hostent *hp = 0; - int s, tos; + volatile int s = -1; + int tos; socklen_t len; static char hostnamebuf[256]; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; + int dupfd; memset(&hisctladdr, 0, sizeof(hisctladdr)); if (inet_aton(host, &hisctladdr.sin_addr)) { @@ -126,11 +130,23 @@ hostnamebuf[sizeof(hostnamebuf)-1] = 0; } hostname = hostnamebuf; + + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 0)) { + if (s >= 0) + close(s); + toplevel = oldtoplevel; + siglongjmp(*toplevel, 1); + } + toplevel = &jmploc; + + INTOFF; s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + INTON; if (s < 0) { perror("ftp: socket"); code = -1; - return (0); + goto out; } hisctladdr.sin_port = port; while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) { @@ -146,12 +162,14 @@ hp->h_length); fprintf(stdout, "Trying %s...\n", inet_ntoa(hisctladdr.sin_addr)); + INTOFF; (void) close(s); s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); + INTON; if (s < 0) { perror("ftp: socket"); code = -1; - return (0); + goto out; } continue; } @@ -170,26 +188,49 @@ if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) perror("ftp: setsockopt TOS (ignored)"); #endif + INTOFF; + if (cin) + fclose(cin); + if (cout) + fclose(cout); cin = fdopen(s, "r"); - cout = fdopen(s, "w"); + if (cin == NULL) + close(s); + dupfd = dup(s); + cout = fdopen(dup(s), "w"); + if (cout == NULL && dupfd >= 0) + close(dupfd); + s = -1; + toplevel = oldtoplevel; + INTON; if (cin == NULL || cout == NULL) { fprintf(stderr, "ftp: fdopen failed.\n"); - if (cin) + if (cin) { + INTOFF; (void) fclose(cin); - if (cout) + cin = NULL; + INTON; + } + if (cout) { + INTOFF; (void) fclose(cout); + cout = NULL; + INTON; + } code = -1; - goto bad; + goto out; } if (verbose) printf("Connected to %s.\n", hostname); if (getreply(0) > 2) { /* read startup message from server */ - if (cin) - (void) fclose(cin); - if (cout) - (void) fclose(cout); + INTOFF; + fclose(cin); + fclose(cout); + cin = NULL; + cout = NULL; + INTON; code = -1; - goto bad; + goto out; } #ifdef SO_OOBINLINE { @@ -204,7 +245,12 @@ return (hostname); bad: + INTOFF; (void) close(s); + s = -1; + INTON; +out: + toplevel = oldtoplevel; return ((char *)0); } @@ -216,10 +262,13 @@ int n, aflag = 0; luser = pass = zacct = 0; + INTOFF; if (xruserpass(host, &luser, &pass, &zacct) < 0) { + INTON; code = -1; return(0); } + INTON; while (luser == NULL) { char *myname = getlogin(); @@ -233,11 +282,13 @@ printf("Name (%s:%s): ", host, myname); else printf("Name (%s): ", host); - if (fgets(tmp, sizeof(tmp) - 1, stdin)==NULL) { + if (fgets(tmp, sizeof(tmp), stdin)==NULL) { fprintf(stderr, "\nLogin failed.\n"); return 0; } - tmp[strlen(tmp) - 1] = '\0'; + n = strlen(tmp); + if (tmp[n - 1] == '\n') + tmp[n - 1] = 0; if (*tmp == '\0') luser = myname; else @@ -269,42 +320,35 @@ if (!strcmp("init", macros[n].mac_name)) { int margc; char **margv; - strcpy(line, "$init"); + char *oldline = line; + INTOFF; + line = obstack_copy(&lineobstack, "$init", 6); + INTON; margv = makeargv(&margc, NULL); domacro(margc, margv); + INTOFF; + obstack_free(&lineobstack, line); + INTON; + line = oldline; break; } } return (1); } - -static void -cmdabort(int ignore) -{ - (void)ignore; - - printf("\n"); - fflush(stdout); - abrtflag++; - if (ptflag) siglongjmp(ptabort,1); -} - int command(const char *fmt, ...) { va_list ap; int r; - void (*oldintr)(int); - abrtflag = 0; if (debug) { printf("---> "); va_start(ap, fmt); if (strncmp("PASS ", fmt, 5) == 0) printf("PASS XXXX"); else - vfprintf(stdout, fmt, ap); + vprintf(fmt, ap); va_end(ap); printf("\n"); (void) fflush(stdout); @@ -314,18 +358,28 @@ code = -1; return (0); } - oldintr = signal(SIGINT, cmdabort); + INTOFF; + intrnewline++; va_start(ap, fmt); vfprintf(cout, fmt, ap); va_end(ap); - fprintf(cout, "\r\n"); - (void) fflush(cout); + fputs("\r\n", cout); + if (fflush(cout) == EOF) + goto outerr; cpend = 1; r = getreply(!strcmp(fmt, "QUIT")); - if (abrtflag && oldintr != SIG_IGN) - (*oldintr)(SIGINT); - (void) signal(SIGINT, oldintr); + intrnewline--; + INTON; return(r); +outerr: + lostpeer(0); + INTON; + if (verbose) { + printf("421 Service not available, remote server has closed connection\n"); + fflush(stdout); + } + code = 421; + return 4; } char reply_string[BUFSIZ]; /* last line of previous reply */ @@ -339,12 +393,16 @@ register int dig; register char *cp; int originalcode = 0, continuation = 0; - void (*oldintr)(int); int pflag = 0; size_t px = 0; size_t psize = sizeof(pasv); - oldintr = signal(SIGINT, cmdabort); + if (!cin || !cout) { + cpend = 0; + return 4; + } + INTOFF; + intrnewline++; for (;;) { dig = n = code = 0; cp = reply_string; @@ -353,15 +411,19 @@ switch (c = getc(cin)) { case WILL: case WONT: - c = getc(cin); + if ((c = getc(cin)) == EOF) + goto goteof; fprintf(cout, "%c%c%c", IAC, DONT, c); - (void) fflush(cout); + if (fflush(cout) == EOF) + goto goteof; break; case DO: case DONT: - c = getc(cin); + if ((c = getc(cin)) == EOF) + goto goteof; fprintf(cout, "%c%c%c", IAC, WONT, c); - (void) fflush(cout); + if (fflush(cout) == EOF) + goto goteof; break; default: break; @@ -371,11 +433,15 @@ dig++; if (c == EOF) { if (expecteof) { - (void) signal(SIGINT,oldintr); + intrnewline--; + INTON; code = 221; return (0); } +goteof: lostpeer(0); + intrnewline--; + INTON; if (verbose) { printf("421 Service not available, remote server has closed connection\n"); (void) fflush(stdout); @@ -427,11 +493,13 @@ *cp = '\0'; if (n != '1') cpend = 0; - (void) signal(SIGINT,oldintr); - if (code == 421 || originalcode == 421) + intrnewline--; + INTON; + if (code == 421 || originalcode == 421) { + INTOFF; lostpeer(0); - if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN) - (*oldintr)(SIGINT); + INTON; + } return (n - '0'); } } @@ -452,10 +520,8 @@ (void)ignore; mflag = 0; - abrtflag = 0; printf("\nsend aborted\nwaiting for remote to finish abort\n"); (void) fflush(stdout); - siglongjmp(sendabort, 1); } #define HASHBYTES 1024 @@ -466,13 +532,13 @@ struct stat st; struct timeval start, stop; register int c, d; - FILE *volatile fin, *volatile dout = 0; + FILE *volatile fin = 0, *volatile dout = 0; int (*volatile closefunc)(FILE *); - void (*volatile oldintr)(int); - void (*volatile oldintp)(int); - volatile long bytes = 0, hashbytes = HASHBYTES; + volatile off_t bytes = 0, hashbytes = HASHBYTES; char buf[BUFSIZ], *bufp; const char *volatile lmode; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; if (verbose && printnames) { if (local && *local != '-') @@ -487,84 +553,104 @@ if (curtype != type) changetype(type, 0); closefunc = NULL; - oldintr = NULL; - oldintp = NULL; lmode = "w"; - if (sigsetjmp(sendabort, 1)) { + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + abortsend(SIGINT); while (cpend) { (void) getreply(0); } if (data >= 0) { + INTOFF; (void) close(data); data = -1; + INTON; } - if (oldintr) - (void) signal(SIGINT,oldintr); - if (oldintp) - (void) signal(SIGPIPE,oldintp); + if (fin != NULL && closefunc != NULL) + (*closefunc)(fin); + toplevel = oldtoplevel; code = -1; return; } - oldintr = signal(SIGINT, abortsend); + toplevel = &jmploc; if (strcmp(local, "-") == 0) fin = stdin; else if (*local == '|') { - oldintp = signal(SIGPIPE,SIG_IGN); + closefunc = pclose; + INTOFF; fin = popen(local + 1, "r"); + INTON; if (fin == NULL) { perror(local + 1); - (void) signal(SIGINT, oldintr); - (void) signal(SIGPIPE, oldintp); + toplevel = oldtoplevel; code = -1; return; } - closefunc = pclose; } else { + closefunc = fclose; + INTOFF; fin = fopen(local, "r"); + INTON; if (fin == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } - closefunc = fclose; if (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) { fprintf(stdout, "%s: not a plain file.\n", local); - (void) signal(SIGINT, oldintr); + INTOFF; fclose(fin); + fin = NULL; + INTON; + toplevel = oldtoplevel; code = -1; return; } } if (initconn()) { - (void) signal(SIGINT, oldintr); - if (oldintp) - (void) signal(SIGPIPE, oldintp); code = -1; - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + toplevel = oldtoplevel; return; } - if (sigsetjmp(sendabort, 1)) + if (sigsetjmp(jmploc, 1)) { + abortsend(SIGINT); goto abort; + } if (restart_point && (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) { - if (fseek(fin, (long) restart_point, 0) < 0) { + if (fseek(fin, restart_point, 0) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); restart_point = 0; - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + toplevel = oldtoplevel; return; } - if (command("REST %ld", (long) restart_point) + if (command("REST %jd", (intmax_t) restart_point) != CONTINUE) { restart_point = 0; - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + toplevel = oldtoplevel; return; } restart_point = 0; @@ -572,27 +658,32 @@ } if (remote) { if (command("%s %s", cmd, remote) != PRELIM) { - (void) signal(SIGINT, oldintr); - if (oldintp) - (void) signal(SIGPIPE, oldintp); - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + toplevel = oldtoplevel; return; } } else if (command("%s", cmd) != PRELIM) { - (void) signal(SIGINT, oldintr); - if (oldintp) - (void) signal(SIGPIPE, oldintp); - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + toplevel = oldtoplevel; return; } + INTOFF; dout = dataconn(lmode); + INTON; if (dout == NULL) goto abort; (void) gettimeofday(&start, (struct timezone *)0); - oldintp = signal(SIGPIPE, SIG_IGN); switch (curtype) { case TYPE_I: @@ -601,8 +692,10 @@ while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { bytes += c; for (bufp = buf; c > 0; c -= d, bufp += d) - if ((d = write(fileno(dout), bufp, c)) <= 0) + if ((d = write(fileno(dout), bufp, c)) <= 0) { + perror("netout"); break; + } if (hash) { while (bytes >= hashbytes) { (void) putchar('#'); @@ -611,11 +704,12 @@ (void) fflush(stdout); } if (tick && (bytes >= hashbytes)) { - printf("\rBytes transferred: %ld", bytes); - (void) fflush(stdout); + printbytes(bytes); while (bytes >= hashbytes) hashbytes += TICKBYTES; } + if (d <= 0) + break; } if (hash && (bytes > 0)) { if (bytes < HASHBYTES) @@ -624,17 +718,13 @@ (void) fflush(stdout); } if (tick) { - (void) printf("\rBytes transferred: %ld\n", bytes); - (void) fflush(stdout); + printbytes(bytes); } if (c < 0) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - if (d < 0) { - if (errno != EPIPE) - perror("netout"); + if (d <= 0) bytes = -1; - } break; case TYPE_A: @@ -646,18 +736,20 @@ hashbytes += HASHBYTES; } if (tick && (bytes >= hashbytes)) { - (void) printf("\rBytes transferred: %ld", - bytes); - (void) fflush(stdout); + printbytes(bytes); while (bytes >= hashbytes) hashbytes += TICKBYTES; } - if (ferror(dout)) + if (putc('\r', dout) == EOF) { + perror("netout"); break; - (void) putc('\r', dout); + } bytes++; } - (void) putc(c, dout); + if (putc(c, dout) == EOF) { + perror("netout"); + break; + } bytes++; /* if (c == '\r') { */ /* (void) putc('\0', dout); (* this violates rfc */ @@ -671,53 +763,63 @@ (void) fflush(stdout); } if (tick) { - (void) printf("\rBytes transferred: %ld\n", bytes); - (void) fflush(stdout); + printbytes(bytes); } if (ferror(fin)) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - if (ferror(dout)) { - if (errno != EPIPE) - perror("netout"); + if (ferror(dout)) bytes = -1; - } break; } (void) gettimeofday(&stop, (struct timezone *)0); - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + INTOFF; (void) fclose(dout); + dout = NULL; /* closes data as well, so discard it */ data = -1; + INTON; (void) getreply(0); - (void) signal(SIGINT, oldintr); - if (oldintp) - (void) signal(SIGPIPE, oldintp); + toplevel = oldtoplevel; if (bytes > 0) ptransfer("sent", bytes, &start, &stop); return; abort: (void) gettimeofday(&stop, (struct timezone *)0); - (void) signal(SIGINT, oldintr); - if (oldintp) - (void) signal(SIGPIPE, oldintp); if (!cpend) { code = -1; + toplevel = oldtoplevel; return; } if (dout) { + INTOFF; + if (data == fileno(dout)) + data = -1; (void) fclose(dout); + dout = NULL; + INTON; } if (data >= 0) { - /* if it just got closed with dout, again won't hurt */ + INTOFF; (void) close(data); data = -1; + INTON; } (void) getreply(0); code = -1; - if (closefunc != NULL && fin != NULL) + if (closefunc != NULL && fin != NULL) { + INTOFF; (*closefunc)(fin); + fin = NULL; + INTON; + } + toplevel = oldtoplevel; if (bytes > 0) ptransfer("sent", bytes, &start, &stop); } @@ -728,10 +830,8 @@ (void)ignore; mflag = 0; - abrtflag = 0; printf("\nreceive aborted\nwaiting for remote to finish abort\n"); (void) fflush(stdout); - siglongjmp(recvabort, 1); } void @@ -739,17 +839,18 @@ char *volatile local, char *remote, const char *lmode, int printnames) { - FILE *volatile fout, *volatile din = 0; + FILE *volatile fout = 0, *volatile din = 0; int (*volatile closefunc)(FILE *); - void (*volatile oldintp)(int); - void (*volatile oldintr)(int); volatile int is_retr, tcrflag, bare_lfs = 0; - static unsigned bufsize; - static char *buf; - volatile long bytes = 0, hashbytes = HASHBYTES; + int tqcflag = 0; + unsigned bufsize; + char *buf; + volatile off_t bytes = 0, hashbytes = HASHBYTES; register int c, d; struct timeval start, stop; struct stat st; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; is_retr = strcmp(cmd, "RETR") == 0; if (is_retr && verbose && printnames) { @@ -763,23 +864,24 @@ return; } closefunc = NULL; - oldintr = NULL; - oldintp = NULL; tcrflag = !crflag && is_retr; - if (sigsetjmp(recvabort, 1)) { + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + abortrecv(SIGINT); while (cpend) { (void) getreply(0); } if (data >= 0) { + INTOFF; (void) close(data); data = -1; + INTON; } - if (oldintr) - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } - oldintr = signal(SIGINT, abortrecv); + toplevel = &jmploc; if (strcmp(local, "-") && *local != '|') { if (access(local, W_OK) < 0) { char *dir = rindex(local, '/'); @@ -787,7 +889,7 @@ if (errno != ENOENT && errno != EACCES) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } @@ -799,7 +901,7 @@ if (d < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } @@ -807,24 +909,20 @@ chmod(local, 0600) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - /* - * Believe it or not, this was actually - * repeated in the original source. - */ - (void) signal(SIGINT, oldintr); - /*(void) signal(SIGINT, oldintr);*/ + toplevel = oldtoplevel; code = -1; return; } if (runique && errno == EACCES && (local = gunique(local)) == NULL) { - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } } - else if (runique && (local = gunique(local)) == NULL) { - (void) signal(SIGINT, oldintr); + else if (runique && (strcmp(cmd,"NLST") != 0) && + (local = gunique(local)) == NULL) { + toplevel = oldtoplevel; code = -1; return; } @@ -837,74 +935,84 @@ changetype(type, 0); } if (initconn()) { - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; code = -1; return; } - if (sigsetjmp(recvabort, 1)) + if (sigsetjmp(jmploc, 1)) { + abortrecv(SIGINT); goto abort; + } if (is_retr && restart_point && - command("REST %ld", (long) restart_point) != CONTINUE) + command("REST %jd", (intmax_t) restart_point) != CONTINUE) { + toplevel = oldtoplevel; return; + } if (remote) { if (command("%s %s", cmd, remote) != PRELIM) { - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; return; } } else { if (command("%s", cmd) != PRELIM) { - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; return; } } + INTOFF; din = dataconn("r"); + INTON; if (din == NULL) goto abort; - if (strcmp(local, "-") == 0) + if (strcmp(local, "-") == 0) { fout = stdout; + tqcflag = qcflag; + } else if (*local == '|') { - oldintp = signal(SIGPIPE, SIG_IGN); + closefunc = pclose; + INTOFF; fout = popen(local + 1, "w"); + INTON; if (fout == NULL) { perror(local+1); goto abort; } - closefunc = pclose; } else { + closefunc = fclose; + INTOFF; fout = fopen(local, lmode); + INTON; if (fout == NULL) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); goto abort; } - closefunc = fclose; } if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0) - st.st_blksize = BUFSIZ; - if (st.st_blksize > bufsize) { - if (buf) - (void) free(buf); - buf = malloc((unsigned)st.st_blksize); - if (buf == NULL) { - perror("malloc"); - bufsize = 0; - goto abort; - } + bufsize = BUFSIZ; + else bufsize = st.st_blksize; - } + INTOFF; + buf = obstack_alloc(&mainobstack, bufsize); + INTON; (void) gettimeofday(&start, (struct timezone *)0); switch (curtype) { case TYPE_I: case TYPE_L: if (restart_point && - lseek(fileno(fout), (long) restart_point, L_SET) < 0) { + lseek(fileno(fout), restart_point, L_SET) < 0) { fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fout); + fout = NULL; + INTON; + } + toplevel = oldtoplevel; return; } errno = d = 0; @@ -920,9 +1028,7 @@ (void) fflush(stdout); } if (tick && (bytes >= hashbytes) && is_retr) { - (void) printf("\rBytes transferred: %ld", - bytes); - (void) fflush(stdout); + printbytes(bytes); while (bytes >= hashbytes) hashbytes += TICKBYTES; } @@ -934,12 +1040,10 @@ (void) fflush(stdout); } if (tick && is_retr) { - (void) printf("\rBytes transferred: %ld\n", bytes); - (void) fflush(stdout); + printbytes(bytes); } if (c < 0) { - if (errno != EPIPE) - perror("netin"); + perror("netin"); bytes = -1; } if (d < c) { @@ -968,8 +1072,13 @@ done: fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fout); + fout = NULL; + INTON; + } + toplevel = oldtoplevel; return; } } @@ -984,9 +1093,7 @@ hashbytes += HASHBYTES; } if (tick && (bytes >= hashbytes) && is_retr) { - printf("\rBytes transferred: %ld", - bytes); - fflush(stdout); + printbytes(bytes); while (bytes >= hashbytes) hashbytes += TICKBYTES; } @@ -1003,6 +1110,8 @@ goto contin2; } } + if (tqcflag && !isprint(c) && !isspace(c)) + c = '?'; (void) putc(c, fout); bytes++; contin2: ; @@ -1015,16 +1124,14 @@ (void) fflush(stdout); } if (tick && is_retr) { - (void) printf("\rBytes transferred: %ld\n", bytes); - (void) fflush(stdout); + printbytes(bytes); } if (bare_lfs) { printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs); printf("File may not have transferred correctly.\n"); } if (ferror(din)) { - if (errno != EPIPE) - perror("netin"); + perror("netin"); bytes = -1; } if (ferror(fout)) @@ -1032,15 +1139,19 @@ strerror(errno)); break; } - if (closefunc != NULL) + if (closefunc != NULL) { + INTOFF; (*closefunc)(fout); - (void) signal(SIGINT, oldintr); - if (oldintp) - (void) signal(SIGPIPE, oldintp); - (void) gettimeofday(&stop, (struct timezone *)0); + fout = NULL; + INTON; + } + INTOFF; (void) fclose(din); /* closes data as well, so discard it */ data = -1; + INTON; + toplevel = oldtoplevel; + (void) gettimeofday(&stop, (struct timezone *)0); (void) getreply(0); if (bytes > 0 && is_retr) ptransfer("received", bytes, &start, &stop); @@ -1050,30 +1161,34 @@ /* abort using RFC959 recommended IP,SYNC sequence */ (void) gettimeofday(&stop, (struct timezone *)0); - if (oldintp) - (void) signal(SIGPIPE, oldintp); - (void) signal(SIGINT, SIG_IGN); + INTOFF; if (!cpend) { code = -1; - (void) signal(SIGINT, oldintr); + INTON; + toplevel = oldtoplevel; return; } abort_remote(din); code = -1; - if (closefunc != NULL && fout != NULL) + if (closefunc != NULL && fout != NULL) { (*closefunc)(fout); + fout = NULL; + } if (din) { + if (data == fileno(din)) + data = -1; (void) fclose(din); + din = NULL; } if (data >= 0) { - /* if it just got closed with din, again won't hurt */ (void) close(data); data = -1; } if (bytes > 0) ptransfer("received", bytes, &start, &stop); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; + INTON; } /* @@ -1091,7 +1206,11 @@ u_long a1,a2,a3,a4,p1,p2; if (passivemode) { + INTOFF; + if (data >= 0) + close(data); data = socket(AF_INET, SOCK_STREAM, 0); + INTON; if (data < 0) { perror("ftp: socket"); return(1); @@ -1143,9 +1262,11 @@ data_addr = myctladdr; if (sendport) data_addr.sin_port = 0; /* let system pick one */ + INTOFF; if (data != -1) (void) close(data); data = socket(AF_INET, SOCK_STREAM, 0); + INTON; if (data < 0) { perror("ftp: socket"); if (tmpno) @@ -1195,7 +1316,9 @@ #endif return (0); bad: + INTOFF; (void) close(data), data = -1; + INTON; if (tmpno) sendport = 1; return (1); @@ -1228,7 +1351,7 @@ } static void -ptransfer(const char *direction, long bytes, +ptransfer(const char *direction, off_t bytes, const struct timeval *t0, const struct timeval *t1) { @@ -1240,8 +1363,8 @@ s = td.tv_sec + (td.tv_usec / 1000000.); #define nz(x) ((x) == 0 ? 1 : (x)) bs = bytes / nz(s); - printf("%ld bytes %s in %.3g secs (%.2g Kbytes/sec)\n", - bytes, direction, s, bs / 1024.0); + printf("%jd bytes %s in %.2f secs (%.1f kB/s)\n", + (intmax_t) bytes, direction, s, bs / 1024.0); } } @@ -1269,18 +1392,9 @@ tdiff->tv_sec--, tdiff->tv_usec += 1000000; } -static -void -psabort(int ignore) -{ - (void)ignore; - abrtflag++; -} - void pswitch(int flag) { - void (*oldintr)(int); static struct comvars { int connect; char name[MAXHOSTNAMELEN]; @@ -1303,11 +1417,10 @@ } proxstruct, tmpstruct; struct comvars *ip, *op; - abrtflag = 0; - oldintr = signal(SIGINT, psabort); if (flag) { if (proxy) return; + INTOFF; ip = &tmpstruct; op = &proxstruct; proxy++; @@ -1315,6 +1428,7 @@ else { if (!proxy) return; + INTOFF; ip = &proxstruct; op = &tmpstruct; proxy = 0; @@ -1323,7 +1437,7 @@ connected = op->connect; if (hostname) { (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1); - ip->name[strlen(ip->name)] = '\0'; + ip->name[sizeof(ip->name) - 1] = '\0'; } else { ip->name[0] = 0; @@ -1351,25 +1465,21 @@ mcase = op->mcse; ip->ntflg = ntflag; ntflag = op->ntflg; - (void) strncpy(ip->nti, ntin, 16); - (ip->nti)[strlen(ip->nti)] = '\0'; + (void) strncpy(ip->nti, ntin, sizeof(ip->nti) - 1); + (ip->nti)[sizeof(ip->nti) - 1] = '\0'; (void) strcpy(ntin, op->nti); - (void) strncpy(ip->nto, ntout, 16); - (ip->nto)[strlen(ip->nto)] = '\0'; + (void) strncpy(ip->nto, ntout, sizeof(ip->nto) - 1); + (ip->nto)[sizeof(ip->nto) - 1] = '\0'; (void) strcpy(ntout, op->nto); ip->mapflg = mapflag; mapflag = op->mapflg; - (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1); - (ip->mi)[strlen(ip->mi)] = '\0'; + (void) strncpy(ip->mi, mapin, sizeof(ip->mi) - 1); + (ip->mi)[sizeof(ip->mi) - 1] = '\0'; (void) strcpy(mapin, op->mi); - (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1); - (ip->mo)[strlen(ip->mo)] = '\0'; + (void) strncpy(ip->mo, mapout, sizeof(ip->mo) - 1); + (ip->mo)[sizeof(ip->mo) - 1] = '\0'; (void) strcpy(mapout, op->mo); - (void) signal(SIGINT, oldintr); - if (abrtflag) { - abrtflag = 0; - (*oldintr)(SIGINT); - } + INTON; } static @@ -1381,17 +1491,16 @@ fflush(stdout); ptabflg++; mflag = 0; - abrtflag = 0; - siglongjmp(ptabort, 1); } static void proxtrans(const char *cmd, char *local, char *remote) { - void (*volatile oldintr)(int); volatile int secndflag = 0, prox_type, nfnd; const char *volatile cmd2; fd_set mask; + sigjmp_buf jmploc; + sigjmp_buf *volatile oldtoplevel; if (strcmp(cmd, "RETR")) cmd2 = "RETR"; @@ -1422,11 +1531,14 @@ pswitch(1); return; } - if (sigsetjmp(ptabort, 1)) + oldtoplevel = toplevel; + if (sigsetjmp(jmploc, 1)) { + abortpt(SIGINT); goto abort; - oldintr = signal(SIGINT, abortpt); + } + toplevel = &jmploc; if (command("%s %s", cmd, remote) != PRELIM) { - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; pswitch(1); return; } @@ -1439,13 +1551,13 @@ (void) getreply(0); pswitch(0); (void) getreply(0); - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; pswitch(1); ptflag = 0; printf("local: %s remote: %s\n", local, remote); return; abort: - (void) signal(SIGINT, SIG_IGN); + INTOFF; ptflag = 0; if (strcmp(cmd, "RETR") && !proxy) pswitch(1); @@ -1460,7 +1572,8 @@ pswitch(1); if (ptabflg) code = -1; - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; + INTON; return; } if (cpend) @@ -1474,7 +1587,8 @@ pswitch(1); if (ptabflg) code = -1; - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; + INTON; return; } } @@ -1500,7 +1614,8 @@ pswitch(1); if (ptabflg) code = -1; - (void) signal(SIGINT, oldintr); + toplevel = oldtoplevel; + INTON; } void @@ -1515,7 +1630,9 @@ if ((nfnd = empty(&mask, fileno(cin), 0)) < 0) { perror("reset"); code = -1; + INTOFF; lostpeer(0); + INTON; } else if (nfnd) { (void) getreply(0); @@ -1572,26 +1689,30 @@ abort_remote(FILE *din) { char buf[BUFSIZ]; - int nfnd, hifd; + int nfnd, hifd = -1; fd_set mask; /* * send IAC in urgent mode instead of DM because 4.3BSD places oob mark * after urgent byte rather than before as is protocol now */ - snprintf(buf, sizeof(buf), "%c%c%c", IAC, IP, IAC); - if (send(fileno(cout), buf, 3, MSG_OOB) != 3) - perror("abort"); - fprintf(cout,"%cABOR\r\n", DM); - (void) fflush(cout); + if (cout) { + snprintf(buf, sizeof(buf), "%c%c%c", IAC, IP, IAC); + if (send(fileno(cout), buf, 3, MSG_OOB) != 3) + perror("abort"); + fprintf(cout,"%cABOR\r\n", DM); + (void) fflush(cout); + } FD_ZERO(&mask); - FD_SET(fileno(cin), &mask); - hifd = fileno(cin); + if (cin) { + FD_SET(fileno(cin), &mask); + hifd = fileno(cin); + } if (din) { FD_SET(fileno(din), &mask); if (hifd < fileno(din)) hifd = fileno(din); } - if ((nfnd = empty(&mask, hifd, 10)) <= 0) { + if (hifd >= 0 && (nfnd = empty(&mask, hifd, 10)) <= 0) { if (nfnd < 0) { perror("abort"); } @@ -1609,3 +1730,10 @@ } (void) getreply(0); } + +static void +printbytes(off_t bytes) +{ + printf("\rBytes transferred: %jd", (intmax_t) bytes); + fflush(stdout); +} --- netkit-ftp-0.17.orig/ftp/ftp_var.h +++ netkit-ftp-0.17/ftp/ftp_var.h @@ -76,6 +76,7 @@ Extern int mapflag; /* use mapin mapout templates on file names */ Extern int code; /* return/reply code for ftp command */ Extern int crflag; /* if 1, strip car. rets. on ascii gets */ +Extern int qcflag; /* if 1, print ? instead of control chars */ Extern char pasv[64]; /* passive port for proxy data connection */ Extern int passivemode; /* passive mode enabled */ Extern char *altarg; /* argv[1] with no shell-like preprocessing */ @@ -102,11 +103,11 @@ /*Extern struct servent *sp;*/ /* service spec for tcp/ftp */ Extern int ftp_port; /* htons'd port number for ftp service */ -Extern sigjmp_buf toplevel; /* non-local goto stuff for cmd scanner */ +Extern sigjmp_buf *toplevel; /* non-local goto stuff for cmd scanner */ -Extern char line[200]; /* input line buffer */ +Extern char *line; /* input line buffer */ Extern char *stringbase; /* current scan point in line buffer */ -Extern char argbuf[200]; /* argument storage buffer */ +Extern char *argbuf; /* argument storage buffer */ Extern char *argbase; /* current storage point in arg buffer */ Extern int cpend; /* flag: if != 0, then pending server reply */ Extern int mflag; /* flag: if != 0, then active multi command */ --- netkit-ftp-0.17.orig/ftp/main.c +++ netkit-ftp-0.17/ftp/main.c @@ -60,6 +60,7 @@ #include #include #include +#include #ifdef __USE_READLINE__ #include #include @@ -67,9 +68,21 @@ #define Extern #include "ftp_var.h" +#include "main.h" + +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free + int traceflag = 0; const char *home = "/"; +int suppressint; +volatile int intpending; +int intrnewline; +struct obstack mainobstack; +struct obstack lineobstack; + +extern FILE *cin; extern FILE *cout; extern int data; extern struct cmd cmdtab[]; @@ -79,8 +92,10 @@ void lostpeer(int); void help(int argc, char *argv[]); +static void inthandler(int); static void cmdscanner(int top); static char *slurpstring(void); +static void resetstack(struct obstack *); static void @@ -106,6 +121,7 @@ int top; struct passwd *pw = NULL; char homedir[MAXPATHLEN]; + sigjmp_buf jmploc; tick = 0; @@ -125,13 +141,6 @@ if (strcmp(cp, "pftp") == 0) passivemode = 1; -#ifdef __USE_READLINE__ - /* - * Set terminal type so libreadline can parse .inputrc correctly - */ - rl_terminal_name = getenv("TERM"); -#endif - argc--, argv++; while (argc > 0 && **argv == '-') { for (cp = *argv + 1; *cp; cp++) @@ -182,12 +191,23 @@ argc--, argv++; } fromatty = isatty(fileno(stdin)); + +#ifdef __USE_READLINE__ + /* + * Set terminal type so libreadline can parse .inputrc correctly + */ + if (fromatty && !rl_inhibit) { + rl_terminal_name = getenv("TERM"); + } +#endif + if (fromatty) verbose++; cpend = 0; /* no pending replies */ proxy = 0; /* proxy not active */ crflag = 1; /* strip c.r. on ascii gets */ sendport = -1; /* not using ports */ + qcflag = isatty(fileno(stdout)); /* * Set up the home directory in case we're globbing. */ @@ -202,17 +222,33 @@ homedir[sizeof(homedir)-1] = 0; home = homedir; } + /* + * We need this since we want to return from unsafe library calls ASAP + * when a SIGINT happens. + */ + siginterrupt(SIGINT, 1); + toplevel = &jmploc; + obstack_init(&mainobstack); + obstack_init(&lineobstack); if (argc > 0) { - if (sigsetjmp(toplevel, 1)) + if (sigsetjmp(jmploc, 1)) exit(0); - (void) signal(SIGINT, intr); - (void) signal(SIGPIPE, lostpeer); + (void) signal(SIGINT, inthandler); + (void) signal(SIGPIPE, SIG_IGN); setpeer(argc + 1, argv - 1); + resetstack(&mainobstack); + resetstack(&lineobstack); } - top = sigsetjmp(toplevel, 1) == 0; + top = sigsetjmp(jmploc, 1) == 0; if (top) { - (void) signal(SIGINT, intr); - (void) signal(SIGPIPE, lostpeer); + (void) signal(SIGINT, inthandler); + (void) signal(SIGPIPE, SIG_IGN); + } else { + INTOFF; + resetstack(&mainobstack); + resetstack(&lineobstack); + INTON; + pswitch(0); } for (;;) { cmdscanner(top); @@ -224,9 +260,28 @@ intr(int ignore) { (void)ignore; - siglongjmp(toplevel, 1); + + intpending = 0; + siglongjmp(*toplevel, 1); +} + +static void +inthandler(int sig) +{ + if (intrnewline) { + putchar('\n'); + fflush(stdout); + } + if (suppressint) { + intpending++; + return; + } + intr(sig); } +/* + * Must be called with interrupts off. + */ void lostpeer(int ignore) { @@ -238,6 +293,10 @@ fclose(cout); cout = NULL; } + if (cin != NULL) { + fclose(cin); + cin = NULL; + } if (data >= 0) { shutdown(data, 1+1); close(data); @@ -252,6 +311,10 @@ fclose(cout); cout = NULL; } + if (cin != NULL) { + fclose(cin); + cin = NULL; + } connected = 0; } proxflag = 0; @@ -276,24 +339,40 @@ } */ -static char *get_input_line(char *buf, int buflen) +static char *get_input_line(void) { + char *lineread; + size_t size; + ssize_t len; + #ifdef __USE_READLINE__ if (fromatty && !rl_inhibit) { - char *lineread = readline("ftp> "); - if (!lineread) return NULL; - strncpy(buf, lineread, buflen); - buf[buflen-1] = 0; + lineread = readline("ftp> "); + INTOFF; + if (!lineread) goto err; if (lineread[0]) add_history(lineread); - free(lineread); - return buf; + len = strlen(lineread); + goto out; } #endif if (fromatty) { printf("ftp> "); fflush(stdout); } - return fgets(buf, buflen, stdin); + size = 0; + lineread = 0; + INTOFF; + len = getline(&lineread, &size, stdin); + if (len == -1 || !lineread) { +err: + INTON; + return NULL; + } +out: + line = obstack_copy(&lineobstack, lineread, len + 1); + free (lineread); + INTON; + return line; } @@ -308,11 +387,19 @@ char **margv; register struct cmd *c; register int l; + int first = 1; if (!top) (void) putchar('\n'); for (;;) { - if (!get_input_line(line, sizeof(line))) { + if (!first) { + INTOFF; + obstack_free(&lineobstack, line); + resetstack(&mainobstack); + INTON; + } + first = 0; + if (!get_input_line()) { quit(); } l = strlen(line); @@ -323,12 +410,6 @@ break; line[l] = '\0'; } - else if (l == sizeof(line) - 2) { - printf("sorry, input line too long\n"); - while ((l = getchar()) != '\n' && l != EOF) - /* void */; - break; - } /* else it was a line without a newline */ margv = makeargv(&margc, &marg); if (margc == 0) { continue; @@ -354,8 +435,10 @@ if (c->c_handler_v != help) break; } - (void) signal(SIGINT, intr); - (void) signal(SIGPIPE, lostpeer); + INTOFF; + obstack_free(&lineobstack, line); + resetstack(&mainobstack); + INTON; } struct cmd * @@ -399,6 +482,9 @@ int rargc = 0; char **argp; + INTOFF; + argbuf = obstack_alloc(&mainobstack, strlen(line) + 1); + INTON; argp = rargv; stringbase = line; /* scan from first of buffer */ argbase = argbuf; /* store from first of buffer */ @@ -602,3 +688,10 @@ c->c_name, c->c_help); } } + +static void +resetstack(struct obstack *stack) +{ + obstack_free(stack, 0); + obstack_init(stack); +} --- netkit-ftp-0.17.orig/ftp/netrc.5 +++ netkit-ftp-0.17/ftp/netrc.5 @@ -37,8 +37,10 @@ .Dt NETRC 5 .Os "Linux NetKit (0.17)" .Sh NAME -.Nm netrc, .netrc +.Nm netrc .Nd user configuration for ftp +.Sh SYNOPSIS +.Nm ~/.netrc .Sh DESCRIPTION This file contains configuration and autologin information for the File Transfer Protocol client --- netkit-ftp-0.17.orig/ftp/ruserpass.c +++ netkit-ftp-0.17/ftp/ruserpass.c @@ -46,6 +46,7 @@ #include #include #include "ftp_var.h" +#include "main.h" static FILE *cfile; static int token(void); @@ -136,8 +137,7 @@ case LOGIN: if (token()) { if (*aname == 0) { - *aname = malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*aname, tokval); + *aname = obstack_copy(&mainobstack, tokval, strlen(tokval) + 1); } else { if (strcmp(*aname, tokval)) goto next; @@ -157,8 +157,7 @@ goto bad; } if (token() && *apass == 0) { - *apass = malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*apass, tokval); + *apass = obstack_copy(&mainobstack, tokval, strlen(tokval) + 1); } break; case ACCOUNT: @@ -169,8 +168,7 @@ goto bad; } if (token() && *aacct == 0) { - *aacct = malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*aacct, tokval); + *aacct = obstack_copy(&mainobstack, tokval, strlen(tokval) + 1); } break; case MACDEF: --- netkit-ftp-0.17.orig/ftp/main.h +++ netkit-ftp-0.17/ftp/main.h @@ -0,0 +1,20 @@ +#include +#include + +extern int suppressint; +extern volatile int intpending; +extern int intrnewline; +extern struct obstack mainobstack; +extern struct obstack lineobstack; + +#ifdef __GNUC__ +void intr(int) __attribute__ ((noreturn)); +#else +void intr(int); +#endif + +#define INTOFF suppressint++; +#define INTON do { if (--suppressint == 0 && intpending) intr(SIGINT); } \ + while(0) +#define CHECKINT do { if (suppressint == 1 && intpending) { \ + suppressint = 0; intr(SIGINT); }} while(0) debian/patches/560_hurd.diff0000644000000000000000000000263311413755027013014 0ustar Description: Definitions needed by Hurd port There is no PATH_MAX, MAXPATHLEN or MAXHOSTNAMELEN in GNU/Hurd, so this package does not compile from source. . The "right" fix for this would be to modify the program so that no PATH_MAX is assumed (doing dynamic allocation of the required space), but for now this patch should be enough: Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=218336 Author: Santiago Vila Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/ftp_var.h =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp_var.h 2010-05-16 22:19:45.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp_var.h 2010-05-16 22:19:45.000000000 +0100 @@ -50,6 +50,10 @@ #define Extern extern #endif +#ifndef MAXPATHLEN +#define MAXPATHLEN 4096 +#endif + /* * Options and other state info. Index: netkit-ftp-ssl/ftp/main.h =================================================================== --- netkit-ftp-ssl.orig/ftp/main.h 2010-05-16 22:19:45.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.h 2010-05-16 22:19:45.000000000 +0100 @@ -18,3 +18,16 @@ while(0) #define CHECKINT do { if (suppressint == 1 && intpending) { \ suppressint = 0; intr(SIGINT); }} while(0) + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#ifndef MAXPATHLEN +#define MAXPATHLEN 4096 +#endif + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + debian/patches/020_optional_stripping.diff0000644000000000000000000000130511413755027015760 0ustar Description: Hard coded stripping behaviour. Remove explicit stripping from makefile target. X-Closes: #437615 X-Comment: debdiff netkit-ftp_0.17-{12,16}.dsc Author: Alberto Gonzalez Iniesta Forwarded: no Last-Update: 2008-03-21 diff -u netkit-ftp-0.17/ftp/Makefile netkit-ftp-0.17/ftp/Makefile --- netkit-ftp-0.17/ftp/Makefile +++ netkit-ftp-0.17/ftp/Makefile @@ -16,7 +16,7 @@ cmds.o glob.o: glob.h install: ftp - install -s -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR) + install $(INSTALL_OPTS) -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR) ln -sf ftp $(INSTALLROOT)$(BINDIR)/pftp install -m$(MANMODE) ftp.1 $(INSTALLROOT)$(MANDIR)/man1 ln -sf ftp.1 $(INSTALLROOT)$(MANDIR)/man1/pftp.1 debian/patches/500_ssl.diff0000644000000000000000000007345111413755027012653 0ustar Description: Base SSL patch The original ssl patch, lightly modified to apply to debian's netkit-ftp 0.17 Origin: ftp://ftp.uni-mainz.de/pub/software/security/ssl/SSL-MZapps/netkit-ftp-0.17+ssl-0.2.diff.gz Forwarded: not-needed Author: Tim Hudson Last-Update: 2010-04-06 Index: netkit-ftp-ssl/ftp/Makefile =================================================================== --- netkit-ftp-ssl.orig/ftp/Makefile 2010-07-03 23:47:48.000000000 +0100 +++ netkit-ftp-ssl/ftp/Makefile 2010-07-03 23:49:52.000000000 +0100 @@ -8,6 +8,9 @@ LIBS += -lreadline $(LIBTERMCAP) endif +CFLAGS += -DUSE_SSL -g +LIBS += -lssl -lcrypto + ftp: cmds.o cmdtab.o domacro.o ftp.o main.o ruserpass.o $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ Index: netkit-ftp-ssl/ftp/cmds.c =================================================================== --- netkit-ftp-ssl.orig/ftp/cmds.c 2010-07-03 23:47:48.000000000 +0100 +++ netkit-ftp-ssl/ftp/cmds.c 2010-07-03 23:49:52.000000000 +0100 @@ -222,6 +222,32 @@ } port = ftp_port; if (argc > 2) { +#ifdef USE_SSL + /* not really an SSL enhancement but something that + * should have always been here --tjh + */ + if (!isdigit(argv[2][0])) { + struct servent *destsp; + + destsp = getservbyname(argv[2], "tcp"); + + /* if lookup fails for ssl-ftp we fallback to + * the default (unofficial) port number + */ + if ((strcmp(argv[2],"ssl-ftp")==0) && (destsp==NULL)) + port = 150; + else { + if (destsp == NULL ) { + printf("%s: bad port name-- %s\n",argv[1],argv[2]); + printf ("usage: %s host-name [port]\n",argv[0]); + code = -1; + return; + } else { + port = ntohs(destsp->s_port); + } + } + } else +#endif /* USE_SSL */ port = atoi(argv[2]); if (port < 1) { printf("%s: bad port number-- %s\n", argv[1], argv[2]); Index: netkit-ftp-ssl/ftp/ftp.1 =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.1 2010-07-03 23:47:48.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.1 2010-07-03 23:49:52.000000000 +0100 @@ -97,6 +97,52 @@ as report on data transfer statistics. .It Fl d Enables debugging. +.It Fl z Ar option +Set SSL (Secure Socket Layer) parameters. The default is to negotiate +via ftp protocoll if SSL is availlable at server side and then to +switch it on. In this mode you can connect to both conventional and +SSL enhanced ftpd's. +.Pp +The SSL parameters are: +.Bl -tag -width Fl +.It Ic Ar debug +Send SSL related debugging information to stderr. +.It Ic Ar authdebug +Enable authentication debugging. +.It Ic Ar ssl +Negotiate SSL at first, then use ftp protocol. ftp protocol +negotiation goes encrypted. (Not yet implemented) +.It Ic Ar nossl, Ar !ssl +switch of SSL negotiation +.It Ic Ar certrequired +client certificate is mandatory +.It Ic Ar secure +Don't switch back to unencrypted mode (no SSL) if SSL is not available. +.It Ic Ar verbose +Be verbose about certificates etc. +.It Ic Ar verify=int +.\" TODO +Set the SSL verify flags (SSL_VERIFY_* in +.Ar ssl/ssl.h +). +.\" TODO +.It Ic Ar cert=cert_file +.\" TODO +Use the certificate(s) in +.Ar cert_file . +.It Ic Ar key=key_file +.\" TODO +Use the key(s) in +.Ar key_file . +.It Ic Ar 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 client host and an optional port number with which Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-03 23:47:48.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-03 23:50:41.000000000 +0100 @@ -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, 1989 Regents of the University of California. * All rights reserved. @@ -78,6 +90,17 @@ static struct sockaddr_storage myctladdr; static int ptflag = 0; static int ptabflg = 0; +#ifdef USE_SSL +static int pdata = -1; +static int +auth_user(char *u,char *p); +static int +ssl_getc(SSL *ssl_con); +static int +ssl_putc_flush(SSL *ssl_con); +static int +ssl_putc(SSL *ssl_con, int oneint); +#endif void lostpeer(int); extern int connected; @@ -391,14 +414,7 @@ else luser = tmp; } - n = command("USER %s", luser); - if (n == CONTINUE) { - if (pass == NULL) { - /* fflush(stdout); */ - pass = getpass("Password:"); - } - n = command("PASS %s", pass); - } + n = auth_user(luser,pass); if (n == CONTINUE) { aflag++; /* fflush(stdout); */ @@ -438,6 +454,9 @@ { va_list ap; int r; +#ifdef USE_SSL + char outputbuf[2048]; /* allow for a 2k command string */ +#endif /* USE_SSL */ if (debug) { printf("---> "); @@ -458,11 +477,28 @@ INTOFF; intrnewline++; va_start(ap, fmt); +#ifdef USE_SSL + /* assemble the output into a buffer */ + vsprintf(outputbuf,fmt,ap); + strcat(outputbuf,"\r\n"); + if (ssl_active_flag) { + SSL_write(ssl_con,outputbuf,strlen(outputbuf)); + } else { + fprintf(cout,"%s",outputbuf); + fflush(cout); + } +#else /* !USE_SSL */ vfprintf(cout, fmt, ap); +#endif /* USE_SSL */ va_end(ap); + +#ifndef USE_SSL + /* we don't need this as we concatenated it above */ fputs("\r\n", cout); if (fflush(cout) == EOF) goto outerr; +#endif /* !USE_SSL */ + cpend = 1; r = getreply(!strcmp(fmt, "QUIT")); intrnewline--; @@ -493,6 +529,7 @@ int pflag = 0; size_t px = 0; size_t psize = sizeof(pasv); + char buf[16]; if (!cin || !cout) { cpend = 0; @@ -503,24 +540,38 @@ for (;;) { dig = n = code = 0; cp = reply_string; - while ((c = getc(cin)) != '\n') { + while ((c = GETC(cin)) != '\n') { if (c == IAC) { /* handle telnet commands */ - switch (c = getc(cin)) { + switch (c = GETC(cin)) { case WILL: case WONT: - if ((c = getc(cin)) == EOF) + if ((c = GETC(cin)) == EOF) goto goteof; - fprintf(cout, "%c%c%c", IAC, DONT, c); + snprintf(buf, + "%c%c%c", IAC, DONT, c); +#ifdef USE_SSL + if (ssl_active_flag) + SSL_write(ssl_con,buf,3); + else +#endif /* !USE_SSL */ + fwrite(buf,3,1,cout); + (void) FFLUSH(cout); + if (fflush(cout) == EOF) goto goteof; break; case DO: case DONT: - if ((c = getc(cin)) == EOF) - goto goteof; - fprintf(cout, "%c%c%c", IAC, WONT, c); - if (fflush(cout) == EOF) + if ((c = GETC(cin)) == EOF) goto goteof; + sprintf(buf, "%c%c%c", IAC, WONT, c); +#ifdef USE_SSL + if (ssl_active_flag) + SSL_write(ssl_con,buf,3); + else +#endif /* !USE_SSL */ + fwrite(buf,3,1,cout); + (void) FFLUSH(cout); break; default: break; @@ -788,11 +839,20 @@ errno = d = 0; while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) { bytes += c; +#ifdef USE_SSL + if (ssl_data_active_flag) { + for (bufp = buf; c > 0; c -= d, bufp += d) + if ((d = SSL_write(ssl_data_con, bufp, c)) <= 0) + break; + } else +#endif /* !USE_SSL */ + { for (bufp = buf; c > 0; c -= d, bufp += d) if ((d = write(fileno(dout), bufp, c)) <= 0) { perror("netout"); break; } + } if (hash) { while (bytes >= hashbytes) { (void) putchar('#'); @@ -837,10 +897,7 @@ while (bytes >= hashbytes) hashbytes += TICKBYTES; } - if (putc('\r', dout) == EOF) { - perror("netout"); - break; - } + (void) DATAPUTC('\r', dout); bytes++; } if (putc(c, dout) == EOF) { @@ -853,6 +910,7 @@ /* bytes++; */ /* } */ } + DATAFLUSH(dout); if (hash) { if (bytes < hashbytes) (void) putchar('#'); @@ -878,6 +936,15 @@ } INTOFF; (void) fclose(dout); + +#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 */ + dout = NULL; /* closes data as well, so discard it */ data = -1; @@ -908,6 +975,15 @@ data = -1; INTON; } + +#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) getreply(0); code = -1; if (closefunc != NULL && fin != NULL) { @@ -1113,6 +1189,33 @@ return; } errno = d = 0; +#ifdef USE_SSL + if (ssl_data_active_flag) { + while ((c = SSL_read(ssl_data_con, buf, bufsize)) > 0) { + if ((d = write(fileno(fout), buf, c)) != c) + break; + bytes += c; + if (hash) { + while (bytes >= hashbytes) { + (void) putchar('#'); + hashbytes += HASHBYTES; + } + (void) fflush(stdout); + } + } + if ( c < -1 ) { + static char errbuf[1024]; + + sprintf(errbuf,"ftp: SSL_read DATA error %s\n", + ERR_error_string(ERR_get_error(),NULL)); + + /* tell the user ... who else */ + fprintf(stderr,"%s", errbuf); + fflush(stderr); + } + } else +#endif /* !USE_SSL */ + { while ((c = read(fileno(din), buf, bufsize)) > 0) { if ((d = write(fileno(fout), buf, c)) != c) break; @@ -1130,6 +1233,7 @@ hashbytes += TICKBYTES; } } + } if (hash && bytes > 0) { if (bytes < HASHBYTES) (void) putchar('#'); @@ -1179,7 +1283,7 @@ return; } } - while ((c = getc(din)) != EOF) { + while ((c = DATAGETC(din)) != EOF) { if (c == '\n') bare_lfs++; while (c == '\r') { @@ -1195,7 +1299,7 @@ hashbytes += TICKBYTES; } bytes++; - if ((c = getc(din)) != '\n' || tcrflag) { + if ((c = DATAGETC(din)) != '\n' || tcrflag) { if (ferror(fout)) goto break2; (void) putc('\r', fout); @@ -1244,6 +1348,15 @@ } INTOFF; (void) fclose(din); + +#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 */ + /* closes data as well, so discard it */ data = -1; INTON; @@ -1282,6 +1395,15 @@ (void) close(data); data = -1; } + +#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 */ + if (bytes > 0) ptransfer("received", bytes, &start, &stop); toplevel = oldtoplevel; @@ -1496,6 +1618,7 @@ struct sockaddr_storage from; int s, tos; socklen_t fromlen = sizeof(from); + int ret; if (passivemode) return (fdopen(data, lmode)); @@ -1520,6 +1643,67 @@ perror("ftp: setsockopt TOS (ignored)"); # endif /* GNU/kfreebsd */ #endif /* IP_TOS */ + +#ifdef USE_SSL + ssl_data_active_flag=0; + if (ssl_active_flag && ssl_encrypt_data) { + /* do SSL */ + if (ssl_data_con!=NULL) { + SSL_free(ssl_data_con); + ssl_data_con=NULL; + } + ssl_data_con=(SSL *)SSL_new(ssl_ctx); + + SSL_set_fd(ssl_data_con,data); + set_ssl_trace(ssl_data_con); + + SSL_set_verify(ssl_data_con,ssl_verify_flag,NULL); + + /* this is the "magic" call that makes + * this quick assuming Eric has this going + * okay! ;-) + */ + SSL_copy_session_id(ssl_data_con,ssl_con); + + /* we are doing I/O and not using select so + * it is "safe" to read ahead + */ + /* SSL_set_read_ahead(ssl_data_con,1); */ + + if (debug) { + fprintf(stderr,"===>START SSL connect on DATA\n"); + fflush(stderr); + } + + if ((ret=SSL_connect(ssl_data_con))<=0) { + static char errbuf[1024]; + + sprintf(errbuf,"ftp: SSL_connect DATA error %d - %s\n", + ret,ERR_error_string(ERR_get_error(),NULL)); + + /* tell the user ... who else */ + fprintf(stderr,"%s", errbuf); + fflush(stderr); + + /* abort time methinks ... */ + close(data); + 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 (debug) { + fprintf(stderr,"===>DONE SSL connect on DATA %d\n",data); + fflush(stderr); + } + + } +#endif /* USE_SSL */ + return (fdopen(data, lmode)); } @@ -1910,3 +2094,142 @@ printf("\rBytes transferred: %jd", (intmax_t) bytes); fflush(stdout); } + +static int +auth_user(char *u,char *p) +{ + int n; + +#ifdef USE_SSL + if (ssl_enabled) { + n = command("AUTH SSL"); + if (n == ERROR) { /* do normal USER/PASS */ + printf("SSL not available\n"); + /* spit the dummy as we will only talk ssl + * when running in "secure" mode + */ + if (ssl_secure_flag) + return ERROR; + } else if (n == CONTINUE ) { + /* do SSL */ + ssl_con=(SSL *)SSL_new(ssl_ctx); + + SSL_set_fd(ssl_con,fileno(cout)); + set_ssl_trace(ssl_con); + + SSL_set_verify(ssl_con,ssl_verify_flag,NULL); + + /* Add in any certificates if you want to here ... */ + if (my_ssl_cert_file) { + if (!SSL_use_certificate_file(ssl_con, my_ssl_cert_file, + X509_FILETYPE_PEM)) { + fprintf(stderr,"%s: ",my_ssl_cert_file); + ERR_print_errors_fp(stderr); + exit(1); + } else { + if (!my_ssl_key_file) + my_ssl_key_file = my_ssl_cert_file; + if (!SSL_use_RSAPrivateKey_file(ssl_con, my_ssl_key_file, + X509_FILETYPE_PEM)) { + fprintf(stderr,"%s: ", my_ssl_key_file); + ERR_print_errors_fp(stderr); + exit(1); + } + } + } + + if (SSL_connect(ssl_con)<=0) { + static char errbuf[1024]; + + sprintf(errbuf,"ftp: SSL_connect error %s\n", + ERR_error_string(ERR_get_error(),NULL)); + perror(errbuf); + /* abort time methinks ... */ + exit(1); + } else { + fprintf(stderr,"[SSL Cipher %s]\n",SSL_get_cipher(ssl_con)); + fflush(stderr); + ssl_active_flag=1; + } + + n = command("USER %s",u); + if (n == CONTINUE) { + if(p == NULL) + p = getpass("Password:"); + n = command("PASS %s",p); + } + return (n); + } + } +#endif /* USE_SSL */ + n = command("USER %s",u); + if (n == CONTINUE) { + if(p == NULL) + p = getpass("Password:"); + n = command("PASS %s",p); + } + return(n); +} + +#ifdef USE_SSL + +/* we really shouldn't have code like this! --tjh */ +static int +ssl_getc(SSL *ssl_con) +{ + char onebyte; + int ret; + + if ((ret=SSL_read(ssl_con,&onebyte,1))!=1) { + /* we want to know this stuff! */ + if (ssl_debug_flag || (ret!=0)) { + fprintf(stderr,"ssl_getc: SSL_read failed %d = %d\n",ret,errno); + fflush(stderr); + } + 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; +} + +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; +} + +#endif /* USE_SSL */ Index: netkit-ftp-ssl/ftp/ftp_var.h =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp_var.h 2010-07-03 23:47:48.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp_var.h 2010-07-03 23:49:52.000000000 +0100 @@ -159,3 +159,6 @@ void setpeer(int argc, char *argv[]); void quit(void); void changetype(int newtype, int show); + +#include "sslapp.h" +#include "ssl_port.h" Index: netkit-ftp-ssl/ftp/main.c =================================================================== --- netkit-ftp-ssl.orig/ftp/main.c 2010-07-03 23:47:48.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.c 2010-07-03 23:49:52.000000000 +0100 @@ -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, 1989 Regents of the University of California. * All rights reserved. @@ -97,6 +109,75 @@ static char *slurpstring(void); static void resetstack(struct obstack *); +#ifdef USE_SSL + +/* icky way of doing things ... */ +#include "sslapp.c" + +/* +#include "ssl_err.h" +*/ + +SSL *ssl_con; +SSL *ssl_data_con; +int ssl_data_active_flag=0; + +/* for the moment this is a compile time option only --tjh */ +int ssl_encrypt_data=1; +int ssl_enabled=1; + +char *my_ssl_key_file=NULL; +char *my_ssl_cert_file=NULL; + +BIO *bio_err=NULL; + +static long +bio_dump_cb(BIO *bio, + int cmd, + char *argp, + int argi, + long argl, + long ret) + { + BIO *out; + +/* + out=(BIO *)BIO_get_callback_arg(bio); +*/ + out=bio_err; + if (out == NULL) return(ret); + + if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) + { + BIO_printf(out,"read from %08X (%d bytes => %ld (%X))\n", + bio,argi,ret,ret); + BIO_dump(out,argp,(int)ret); + BIO_flush(out); + } + else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) + { + BIO_printf(out,"write to %08X (%d bytes => %ld (%X))\n", + bio,argi,ret,ret); + BIO_dump(out,argp,(int)ret); + BIO_flush(out); + } + return( (cmd & BIO_CB_RETURN) ? ret : 1); + } + +int +set_ssl_trace(SSL *con) +{ + if (con!=NULL) { + if (ssl_debug_flag) { + BIO_set_callback(SSL_get_rbio(con),bio_dump_cb); + BIO_set_callback_arg(SSL_get_rbio(con),bio_err); + } + } + return 0; +} + +#endif /* USE_SSL */ + static void usage(void) @@ -122,6 +203,7 @@ struct passwd *pw = NULL; char homedir[MAXPATHLEN]; sigjmp_buf jmploc; + char *optarg; tick = 0; @@ -143,6 +225,7 @@ argc--, argv++; while (argc > 0 && **argv == '-') { + optarg=*(argv+1); for (cp = *argv + 1; *cp; cp++) switch (*cp) { @@ -183,6 +266,44 @@ usage(); exit(0); +#ifdef USE_SSL + case 'z': + if (strcmp(optarg, "debug") == 0 ) { + ssl_debug_flag=1; + } + if (strcmp(optarg, "ssl") == 0 ) { + ssl_only_flag=1; + } + /* disable *all* ssl stuff */ + if ( (strcmp(optarg, "!ssl") == 0 ) || + (strcmp(optarg, "nossl") == 0 ) ) { + ssl_enabled=0; + } + if (strcmp(optarg, "secure") == 0 ) { + ssl_secure_flag=1; + } + if (strcmp(optarg, "certsok") == 0 ) { + ssl_certsok_flag=1; + } + if (strcmp(optarg, "verbose") == 0 ) { + ssl_verbose_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: fprintf(stdout, "ftp: %c: unknown option\n", *cp); @@ -222,6 +343,18 @@ homedir[sizeof(homedir)-1] = 0; home = homedir; } + +#ifdef USE_SSL + if (ssl_enabled) { + if (!do_ssleay_init(0)) { + fprintf(stderr,"ftp: SSLeay initialisation failed\n"); + fflush(stderr); + ERR_print_errors_fp(stderr); + exit(1); + } + } +#endif /* USE_SSL */ + /* * We need this since we want to return from unsafe library calls ASAP * when a SIGINT happens. Index: netkit-ftp-ssl/ftp/sslapp.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ netkit-ftp-ssl/ftp/sslapp.c 2010-07-03 23:49:52.000000000 +0100 @@ -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(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(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 */ + Index: netkit-ftp-ssl/ftp/sslapp.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ netkit-ftp-ssl/ftp/sslapp.h 2010-07-03 23:49:52.000000000 +0100 @@ -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 */ + + Index: netkit-ftp-ssl/ftp/ssl_port.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ netkit-ftp-ssl/ftp/ssl_port.h 2010-07-03 23:49:52.000000000 +0100 @@ -0,0 +1,85 @@ +/* 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 +#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 */ debian/patches/640_use_editline.diff0000644000000000000000000001250411413755027014520 0ustar Description: Use editline instead of readline netkit-ftp-ssl links against openssl, which is incompatible with the GPL. Unfortunately readline is GPLed, so link to editline (BSD licensed) instead. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=531822 Author: Ian Beckwith Forwarded: no Last-Update: 2010-04-06 Index: netkit-ftp-ssl/configure =================================================================== --- netkit-ftp-ssl.orig/configure 2010-05-16 22:24:26.000000000 +0100 +++ netkit-ftp-ssl/configure 2010-05-16 22:24:32.000000000 +0100 @@ -3,6 +3,8 @@ # This file was generated by confgen version 2. # Do not edit. # +# Which is all very well, except I can't find a copy of confgen +# hence manually edited to add editline support - ianb@erislabs.net PREFIX='/usr' #EXECPREFIX='$PREFIX' @@ -17,7 +19,8 @@ Usage: configure [options] --help Show this message --with-debug Enable debugging - --without-readline Disable readline support + --with-editline Use editline instead of readline + --without-readline Disable readline support --prefix=path Prefix for location of files [/usr] --exec-prefix=path Location for arch-depedent files [prefix] --installroot=root Top of filesystem tree to install in [/] @@ -39,6 +42,7 @@ --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;; --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;; --without-readline|--disable-readline) WITHOUT_READLINE=1;; + --with-editline) WITHOUT_READLINE=1; WITH_EDITLINE=1;; *) echo "Unrecognized option: $1"; exit 1;; esac shift @@ -266,8 +270,29 @@ ################################################## +echo -n 'Checking for libeditline... ' +if [ x$WITH_EDITLINE = x ]; then + echo disabled +else +cat <__conftest.c +#include +#include +int main() { readline("foo"); return 0; } + +EOF +if ( + $CC $CFLAGS __conftest.c -leditline $LIBTERMCAP -o __conftest || exit 1 + ) >/dev/null 2>&1; then + echo 'yes' + USE_EDITLINE=1 + else + echo 'no' + fi +fi +rm -f __conftest* + echo -n 'Checking for libreadline... ' -if [ x$WITHOUT_READLINE != x ]; then +if [ x$WITHOUT_READLINE != x ] || [ x$WITH_EDITLINEx = x ] ; then echo disabled else cat <__conftest.c @@ -439,5 +464,6 @@ echo "LIBTERMCAP=$LIBTERMCAP" echo "USE_GLIBC=$USE_GLIBC" echo "USE_READLINE=$USE_READLINE" + echo "USE_EDITLINE=$USE_EDITLINE" ) > MCONFIG Index: netkit-ftp-ssl/ftp/Makefile =================================================================== --- netkit-ftp-ssl.orig/ftp/Makefile 2010-05-16 22:24:32.000000000 +0100 +++ netkit-ftp-ssl/ftp/Makefile 2010-05-16 22:24:32.000000000 +0100 @@ -8,6 +8,11 @@ LIBS += -lreadline $(LIBTERMCAP) endif +ifeq ($(USE_EDITLINE),1) +CFLAGS += -D__USE_EDITLINE__ +LIBS += -leditline $(LIBTERMCAP) +endif + CFLAGS += -DUSE_SSL -g LIBS += -lssl -lcrypto Index: netkit-ftp-ssl/ftp/cmds.c =================================================================== --- netkit-ftp-ssl.orig/ftp/cmds.c 2010-05-16 22:24:32.000000000 +0100 +++ netkit-ftp-ssl/ftp/cmds.c 2010-05-16 22:24:32.000000000 +0100 @@ -65,6 +65,10 @@ #include #endif +#ifdef __USE_EDITLINE__ +#include +#endif + #include "ftp_var.h" #include "pathnames.h" #include "cmds.h" @@ -1857,7 +1861,7 @@ if (!interactive) return (1); -#ifdef __USE_READLINE__ +#ifdef __USE_LINE_EDITOR__ if (fromatty && !rl_inhibit) { char *lineread; snprintf(lyne, BUFSIZ, "%s %s? ", cmd, file); @@ -1879,7 +1883,7 @@ if (fgets(lyne, sizeof(lyne), stdin) == NULL) { return 0; } -#ifdef __USE_READLINE__ +#ifdef __USE_LINE_EDITOR__ } #endif return (*lyne != 'n' && *lyne != 'N'); Index: netkit-ftp-ssl/ftp/main.c =================================================================== --- netkit-ftp-ssl.orig/ftp/main.c 2010-05-16 22:24:32.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.c 2010-05-16 22:24:32.000000000 +0100 @@ -78,6 +78,10 @@ #include #endif +#ifdef __USE_EDITLINE__ +#include +#endif + #define Extern #include "ftp_var.h" #include "main.h" @@ -196,7 +200,7 @@ printf(" -p enable passive mode (default for pftp)\n"); printf(" -i turn off prompting during mget\n"); printf(" -n inhibit auto-login\n"); - printf(" -e disable readline support, if present\n"); + printf(" -e disable readline/editline support, if present\n"); printf(" -g disable filename globbing\n"); printf(" -v verbose mode\n"); printf(" -t enable packet tracing [nonfunctional]\n"); @@ -504,7 +508,7 @@ size_t size; ssize_t len; -#ifdef __USE_READLINE__ +#ifdef __USE_LINE_EDITOR__ if (fromatty && !rl_inhibit) { lineread = readline("ftp> "); INTOFF; Index: netkit-ftp-ssl/ftp/main.h =================================================================== --- netkit-ftp-ssl.orig/ftp/main.h 2010-05-16 22:24:32.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.h 2010-05-16 22:24:32.000000000 +0100 @@ -31,3 +31,11 @@ #define MAXHOSTNAMELEN 64 #endif +#ifdef __USE_READLINE__ +#define __USE_LINE_EDITOR__ +#endif + +#ifdef __USE_EDITLINE__ +#define __USE_LINE_EDITOR__ +#endif + debian/patches/520_check_ssl_new.diff0000644000000000000000000000161711413755027014656 0ustar Description: Check return code of ssl_NEW() Origin unknown, comes from netkit-ftp-ssl 0.17.12+0.2-6 or earlier Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-03 23:58:22.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-03 23:58:22.000000000 +0100 @@ -1653,6 +1653,10 @@ ssl_data_con=NULL; } ssl_data_con=(SSL *)SSL_new(ssl_ctx); + if (!ssl_data_con) { + ERR_print_errors_fp(stderr); + exit(1); + } SSL_set_fd(ssl_data_con,data); set_ssl_trace(ssl_data_con); @@ -2113,6 +2117,10 @@ } else if (n == CONTINUE || n == COMPLETE ) { /* do SSL */ ssl_con=(SSL *)SSL_new(ssl_ctx); + if (!ssl_con) { + ERR_print_errors_fp(stderr); + exit(1); + } SSL_set_fd(ssl_con,fileno(cout)); set_ssl_trace(ssl_con); debian/patches/610_usage.diff0000644000000000000000000000455111413755027013153 0ustar Description: Include SSL options in ftp -h output Author: Ian Beckwith Forwarded: no Last-Update: 2010-04-06 Index: netkit-ftp-ssl/ftp/main.c =================================================================== --- netkit-ftp-ssl.orig/ftp/main.c 2010-05-16 22:22:54.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.c 2010-05-16 22:22:54.000000000 +0100 @@ -188,15 +188,31 @@ void usage(void) { - printf("\n\tUsage: { ftp | pftp } [-pinegvtd] [hostname]\n"); - printf("\t -p: enable passive mode (default for pftp)\n"); - printf("\t -i: turn off prompting during mget\n"); - printf("\t -n: inhibit auto-login\n"); - printf("\t -e: disable readline support, if present\n"); - printf("\t -g: disable filename globbing\n"); - printf("\t -v: verbose mode\n"); - printf("\t -t: enable packet tracing [nonfunctional]\n"); - printf("\t -d: enable debugging\n"); +#ifdef USE_SSL + printf("\nUsage: { ftp-ssl | pftp } [-pinegvtd] [-z sslopt] [hostname]\n"); +#else /* !USE_SSL */ + printf("\nUsage: { ftp | pftp } [-pinegvtd] [hostname]\n"); +#endif /* !USE_SSL */ + printf(" -p enable passive mode (default for pftp)\n"); + printf(" -i turn off prompting during mget\n"); + printf(" -n inhibit auto-login\n"); + printf(" -e disable readline support, if present\n"); + printf(" -g disable filename globbing\n"); + printf(" -v verbose mode\n"); + printf(" -t enable packet tracing [nonfunctional]\n"); + printf(" -d enable debugging\n"); +#ifdef USE_SSL + printf(" -z debug enable SSL debugging\n"); + printf(" -z authdebug enable authentication debugging\n"); + printf(" -z nossl switch off SSL negotiation\n"); + printf(" -z certrequired client certificate is mandatory\n"); + printf(" -z secure don't allow non-SSL connections\n"); + printf(" -z verbose be verbose about certificates, etc.\n"); + printf(" -z verify=flags set the SSL verify flags\n"); + printf(" -z cert=cert_file use the certificate(s) in cert_file\n"); + printf(" -z key=key_file use the key(s) in key_file\n"); + printf(" -z cipher=cipher_list set preferred ciphers to cipher_list\n"); +#endif /* USE_SSL */ printf("\n"); } debian/patches/580_ssl_fflush.diff0000644000000000000000000000334111413755027014221 0ustar Description: use SSL-specific macros to wrap fflush and putc Origin unknown, first appeared in netkit-ftp-ssl 0.17.12+0.2 somewhere between -1 and -6 Author unknown, probably Christoph Martin Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-04 00:04:28.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-04 00:04:28.000000000 +0100 @@ -556,16 +556,14 @@ if ((c = GETC(cin)) == EOF) goto goteof; sprintf(buf, - "%c%c%c", IAC, DONT, c); + "%c%c%c", IAC, DONT, c); #ifdef USE_SSL if (ssl_active_flag) SSL_write(ssl_con,buf,3); else #endif /* !USE_SSL */ fwrite(buf,3,1,cout); - (void) FFLUSH(cout); - - if (fflush(cout) == EOF) + if (FFLUSH(cout) == EOF) goto goteof; break; case DO: @@ -579,7 +577,8 @@ else #endif /* !USE_SSL */ fwrite(buf,3,1,cout); - (void) FFLUSH(cout); + if (FFLUSH(cout) == EOF) + goto goteof; break; default: break; @@ -905,10 +904,13 @@ while (bytes >= hashbytes) hashbytes += TICKBYTES; } - (void) DATAPUTC('\r', dout); + if (DATAPUTC('\r', dout) == EOF) { + perror("netout"); + break; + } bytes++; } - if (putc(c, dout) == EOF) { + if (DATAPUTC(c, dout) == EOF) { perror("netout"); break; } @@ -944,6 +946,7 @@ } INTOFF; (void) fclose(dout); + dout = NULL; #ifdef USE_SSL if (ssl_data_active_flag && (ssl_data_con!=NULL)) { @@ -953,7 +956,6 @@ } #endif /* USE_SSL */ - dout = NULL; /* closes data as well, so discard it */ data = -1; INTON; debian/patches/030_argv_handling.diff0000644000000000000000000000604511413755027014646 0ustar Description: Multiple flaws in ftp/main.c. There are several flaws in the current code of the makeargv function in ftp/main.c. It certainly errs, but not on the side of caution. . 1. The 'count' variable is supposed to count the number of arguments on the command line. In fact it counts the number of arguments less one, so malloc is often called with an argument of zero. . 2. The argument to malloc is completely wrong. Space needs to be reserved for a certain number of pointers; the length of the command line string is irrelevant. . 3. The slurpstring parsing function accepts both space and tab as delimiters. The 'count' variable is calculated assuming spaces only. . 4. It appears to me that the memory allocated for rargv is never freed, leading to a memory leak. I may be wrong about this, and I do not know the code well enough to suggest where the free should take place if it does not happen already. My patch does not address this. . Attempting to count parameters in advance is not the best solution in my opinion. It is duplicating part of the effort of slurpstring. My preference would have been to allocate memory for 20 pointers, as in the original code, then realloc() for a larger size if more than 20 parameters are returned from slurpstring. X-Closes: Closes #508378, #505533, #510009 X-Comment: debdiff netkit-ftp_0.17-{18,19}.dsc Description collected from #508378 Author: Mark Calderbank Forwarded: no Last-Update: 2009-09-14 diff -u netkit-ftp-0.17/ftp/main.c netkit-ftp-0.17/ftp/main.c --- netkit-ftp-0.17/ftp/main.c +++ netkit-ftp-0.17/ftp/main.c @@ -479,23 +479,15 @@ makeargv(int *pargc, char **parg) { static char **rargv = NULL; + static int arglimit = 0; int rargc = 0; - int i = 0, count = 0; char **argp; - - /* Allocate enough space: err on the side of caution */ - while ( line[i] != '\0' ) { - if ( line[i] == ' ' ) - count += 1 ; - i+= 1; - } - - /* allocate memory for $count-sized array of chars */ - rargv = (char **) malloc( count * strlen(line)); - if (rargv == NULL) - fatal("Out of memory"); - + if (arglimit == 0) { + arglimit = 10; + rargv = malloc(arglimit * sizeof(char*)); + if (rargv == NULL) fatal ("Out of memory"); + } INTOFF; argbuf = obstack_alloc(&mainobstack, strlen(line) + 1); INTON; @@ -503,9 +495,15 @@ stringbase = line; /* scan from first of buffer */ argbase = argbuf; /* store from first of buffer */ slrflag = 0; - while ((*argp++ = slurpstring())!=NULL) + while ((*argp++ = slurpstring())!=NULL) { rargc++; - + if (rargc == arglimit) { + rargv = realloc(rargv, (arglimit+10) * sizeof(char*)); + if (rargv == NULL) fatal ("Out of memory"); + argp = rargv + arglimit; + arglimit += 10; + } + } *pargc = rargc; if (parg) *parg = altarg; return rargv; debian/patches/540_tls.diff0000644000000000000000000000313711413755027012652 0ustar Description: support TLS authentication and (optional) data connection encryption Netkit-ftp-ssl now supports TLS authentication and (optional) data connection encryption according to http://www.ietf.org/internet-drafts/draft-murray-auth-ftp-ssl-16.txt . . The default is to fall back to insecure authentication if AUTH TLS is not supported by the server to match the current behaviour of the AUTH SSL code. . If you specify "-z secure", then encryption of both the control and the data connection are required. Author: Andreas Oberritter Origin: http://www.saftware.de/patches/ftp_tls.diff Forwarded: no Last-Update: 2010-04-06 Index: netkit-ftp-ssl/ftp/ftp.c =================================================================== --- netkit-ftp-ssl.orig/ftp/ftp.c 2010-07-04 00:00:58.000000000 +0100 +++ netkit-ftp-ssl/ftp/ftp.c 2010-07-04 00:00:58.000000000 +0100 @@ -2105,8 +2105,13 @@ int n; #ifdef USE_SSL + int use_tls = 0; if (ssl_enabled) { n = command("AUTH SSL"); + if (n == ERROR) { + use_tls = 1; + n = command("AUTH TLS"); + } if (n == ERROR) { /* do normal USER/PASS */ printf("SSL not available\n"); /* spit the dummy as we will only talk ssl @@ -2160,6 +2165,17 @@ ssl_active_flag=1; } + if (use_tls) { + (void) command("PBSZ 0"); + if (command("PROT P") != COMPLETE) + ssl_encrypt_data = 0; + } + + if (!ssl_encrypt_data && ssl_secure_flag) { + fprintf(stderr, "Data connection security level refused.\n"); + return ERROR; + } + n = command("USER %s",u); if (n == CONTINUE) { if(p == NULL) debian/patches/series0000644000000000000000000000075511413755027012046 0ustar 010_patches_in_sarge.diff 020_optional_stripping.diff 025_long_cmd_overflow.diff 030_argv_handling.diff 035_lintian_pedantic.diff 040_ipv6_ftp_c.diff 500_ssl.diff 510_fix_ssl_auth_response.diff 520_check_ssl_new.diff 530_move_interrupt_handler.diff 540_tls.diff 550_doc_fixes.diff 560_hurd.diff 570_fix_warnings.diff 580_ssl_fflush.diff 590_fix_ssl_without_autologin.diff 600_fix_passive_mode.diff 610_usage.diff 620_enforce_ssl_in_user_cmd.diff 630_fix_-z_segfault.diff 640_use_editline.diff debian/patches/025_long_cmd_overflow.diff0000644000000000000000000000212611413755027015550 0ustar Description: Buffer overflow caused by long commands. Allocate a sufficient amount of memory to handle many arguments. X-Closes: #391207, #407924 X-Comment: debdiff netkit-ftp_0.17-{16,18}.dsc Description interpreted from #407924 Author: Steve Kemp Forwarded: no Last-Update: 2008-03-26 diff -u netkit-ftp-0.17/ftp/main.c netkit-ftp-0.17/ftp/main.c --- netkit-ftp-0.17/ftp/main.c +++ netkit-ftp-0.17/ftp/main.c @@ -478,10 +478,24 @@ char ** makeargv(int *pargc, char **parg) { - static char *rargv[20]; + static char **rargv = NULL; int rargc = 0; + int i = 0, count = 0; char **argp; + + /* Allocate enough space: err on the side of caution */ + while ( line[i] != '\0' ) { + if ( line[i] == ' ' ) + count += 1 ; + i+= 1; + } + + /* allocate memory for $count-sized array of chars */ + rargv = (char **) malloc( count * strlen(line)); + if (rargv == NULL) + fatal("Out of memory"); + INTOFF; argbuf = obstack_alloc(&mainobstack, strlen(line) + 1); INTON; debian/patches/530_move_interrupt_handler.diff0000644000000000000000000000207511413755027016626 0ustar Description: Install interrupt handler before initializing SSL Origin unknown, comes from netkit-ftp-ssl 0.17.12+0.2-6 or earlier Forwarded: no Last-Update: 2010-04-07 Index: netkit-ftp-ssl/ftp/main.c =================================================================== --- netkit-ftp-ssl.orig/ftp/main.c 2010-05-16 22:15:20.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.c 2010-05-16 22:15:20.000000000 +0100 @@ -343,6 +343,14 @@ homedir[sizeof(homedir)-1] = 0; home = homedir; } + /* + * We need this since we want to return from unsafe library calls ASAP + * when a SIGINT happens. + */ + siginterrupt(SIGINT, 1); + toplevel = &jmploc; + obstack_init(&mainobstack); + obstack_init(&lineobstack); #ifdef USE_SSL if (ssl_enabled) { @@ -355,14 +363,6 @@ } #endif /* USE_SSL */ - /* - * We need this since we want to return from unsafe library calls ASAP - * when a SIGINT happens. - */ - siginterrupt(SIGINT, 1); - toplevel = &jmploc; - obstack_init(&mainobstack); - obstack_init(&lineobstack); if (argc > 0) { if (sigsetjmp(jmploc, 1)) exit(0); debian/patches/630_fix_-z_segfault.diff0000644000000000000000000000143611413755027015136 0ustar Description: Fix segfault when -z is given with no following args Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=506137 Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/netkit-ftp-ssl/+bug/184626 Author: Alexander Gitter Forwarded: no Last-Update: 2010-04-06 Index: netkit-ftp-ssl/ftp/main.c =================================================================== --- netkit-ftp-ssl.orig/ftp/main.c 2010-05-16 22:24:05.000000000 +0100 +++ netkit-ftp-ssl/ftp/main.c 2010-05-16 22:24:05.000000000 +0100 @@ -289,6 +289,11 @@ #ifdef USE_SSL case 'z': + if (argc < 2) { + fprintf(stdout, + "ftp: please specify a SSL parameter\n"); + exit(1); + } if (strcmp(optarg, "debug") == 0 ) { ssl_debug_flag=1; } debian/dirs0000644000000000000000000000005611413755027010060 0ustar usr/bin usr/share/man/man1 usr/share/man/man5 debian/copyright0000644000000000000000000000473611413755027011140 0ustar This package was split from netstd by Herbert Xu on Fri, 18 Jun 1999 21:41:52 +1000. netstd was created by Peter Tobias on Wed, 20 Jul 1994 17:23:21 +0200. It was downloaded from ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/. Copyright: /* * Copyright (c) 1985, 1989, 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * 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. * */ Files: debian/patches/040_ipv6_ftp_c.diff Copyright: 2010, Mats Erik Andersson License: BSD X-Comment: The license of the original software is used verbatim for the IPv6-patch. debian/postinst0000644000000000000000000000040011413755027010773 0ustar #!/bin/sh # $Id: postinst,v 1.1 2000/03/23 10:27:08 herbert Exp $ set -e update-alternatives --install /usr/bin/ftp ftp /usr/bin/ftp-ssl 100 \ --slave /usr/share/man/man1/ftp.1.gz ftp.1.gz \ /usr/share/man/man1/ftp-ssl.1.gz #DEBHELPER# debian/docs0000644000000000000000000000000511413755027010041 0ustar BUGS