diff options
Diffstat (limited to 'crypto/kerberosIV/appl/ftp')
27 files changed, 1450 insertions, 435 deletions
diff --git a/crypto/kerberosIV/appl/ftp/ChangeLog b/crypto/kerberosIV/appl/ftp/ChangeLog index 422f4a5..e2e1bb5 100644 --- a/crypto/kerberosIV/appl/ftp/ChangeLog +++ b/crypto/kerberosIV/appl/ftp/ChangeLog @@ -1,8 +1,188 @@ +1999-11-30 Assar Westerlund <assar@sics.se> + + * ftpd/ftpd.c (getdatasock): make sure to keep the port-number of + the outgoing connections. It has to be `ftp-data' or some people + might get upset. + + * ftpd/ftpd.c (args): set correct variable when `-l' so that + logging actually works + +1999-11-29 Assar Westerlund <assar@sics.se> + + * ftp/security.c (sec_login): check return value from realloc + (sec_end): set app_data to NULL + +1999-11-25 Assar Westerlund <assar@sics.se> + + * ftp/krb4.c (krb4_auth): obtain the `local' address when doing + NAT. also turn on passive mode. From <thn@stacken.kth.se> + +1999-11-20 Assar Westerlund <assar@sics.se> + + * ftpd/ls.c (make_fileinfo): cast to allow for non-const + prototypes of readlink + +1999-11-12 Assar Westerlund <assar@sics.se> + + * ftpd/ftpd.c (args): use arg_counter for `l' + +1999-11-04 Assar Westerlund <assar@sics.se> + + * ftpd/ls.c (S_ISSOCK, S_ISLNK): fallback definitions for systems + that don't have them (such as ultrix) + +1999-10-29 Assar Westerlund <assar@sics.se> + + * ftpd/ls.c (make_fileinfo): cast uid's and gid's to unsigned in + printf, we don't know what types they might be. + (lstat_file): conditionalize the kafs part on KRB4 + + * ftpd/ftpd_locl.h: <sys/ioccom.h> is needed for kafs.h + +1999-10-28 Assar Westerlund <assar@sics.se> + + * ftpd/ls.c (lstat_file): don't set st_mode, it should already be + correct + + * ftpd/ls.c: don't use warnx to print errors + + * ftpd/ls.c (builtin_ls): fix typo, 'd' shouldn't imply 'f' + + * ftpd/ls.c (lstat_file): new function for avoiding stating AFS + mount points. From Love <lha@s3.kth.se> + (list_files): use `lstat_file' + + * ftpd/ftpd.c: some const-poisoning + + * ftpd/ftpd.c (args): add `-B' as an alias for `--builtin-ls' to + allow for stupid inetds that only support two arguments. From + Love <lha@s3.kth.se> + +1999-10-26 Assar Westerlund <assar@sics.se> + + * ftpd/ftpcmd.y (help): it's unnecessary to interpret help strings + as printf commands + + * ftpd/ftpd.c (show_issue): don't interpret contents of + /etc/issue* as printf commands. From Brian A May + <bmay@dgs.monash.edu.au> + +1999-10-21 Johan Danielsson <joda@pdc.kth.se> + + * ftpd/kauth.c (kauth): complain if protection level isn't + `private' + + * ftp/krb4.c (krb4_decode): syslog failure reason + + * ftp/kauth.c (kauth): set private level earlier + + * ftp/security.c: get_command_prot; (sec_prot): partially match + `command' and `data' + +1999-10-18 Johan Danielsson <joda@pdc.kth.se> + + * ftpd/ftpd.c: change `-l' flag to use arg_collect (this makes + `-ll' work again) + + * ftpd/ftpd.c (list_file): pass filename to ls + +1999-10-04 Johan Danielsson <joda@pdc.kth.se> + + * ftpd/ftpcmd.y: FEAT + +1999-10-03 Assar Westerlund <assar@sics.se> + + * ftpd/ls.c: fall-back definitions for constans and casts for + printfs + +1999-10-03 Johan Danielsson <joda@pdc.kth.se> + + * ftpd/ftpd.c (main): make this use getarg; add `list_file' + + * ftpd/ftpcmd.y (LIST): call list_file + + * ftpd/ls.c: add simple built-in ls + + * ftp/security.c: add `sec_vfprintf2' and `sec_fprintf2' that + prints to the data stream + + * ftp/kauth.c (kauth): make sure we're using private protection + level + + * ftp/security.c (set_command_prot): set command protection level + + * ftp/security.c: make it possible to set the command protection + level with `prot' + +1999-09-30 Assar Westerlund <assar@sics.se> + + * ftpd/ftpd_locl.h: add prototype for fclose to make sunos happy + +1999-08-19 Johan Danielsson <joda@pdc.kth.se> + + * ftpd/ftpd.c (do_login): show issue-file + (send_data): change handling of zero-byte files + 1999-08-18 Assar Westerlund <assar@sics.se> * ftp/cmds.c (getit): be more suspicious when parsing the result of MDTM. Do the comparison of timestamps correctly. +1999-08-13 Assar Westerlund <assar@sics.se> + + * ftpd/ftpd.c (send_data): avoid calling mmap with `len == 0'. + Some mmap:s rather dislike that (Solaris) and some munmap (Linux) + get grumpy later. + + * ftp/ftp.c (copy_stream): avoid calling mmap with `len == 0'. + Some mmap:s rather dislike that (Solaris) and some munmap (Linux) + get grumpy later. + +1999-08-03 Assar Westerlund <assar@sics.se> + + * ftp/ftp.c (active_mode): hide failure of EPRT by setting verbose + + * ftp/gssapi.c (gss_auth): initialize application_data in bindings + +1999-08-02 Assar Westerlund <assar@sics.se> + + * ftpd/ftpcmd.y: save file names when doing commands that might + get aborted (and longjmp:ed out of) to avoid overwriting them also + remove extra closing brace + +1999-08-01 Johan Danielsson <joda@pdc.kth.se> + + * ftpd/ftpcmd.y: change `site find' to `site locate' (to match + what it does, and other implementations) keep find as an alias + +1999-07-28 Assar Westerlund <assar@sics.se> + + * common/socket.c: moved to roken + + * common/socket.c: new file with generic socket functions + + * ftpd/ftpd.c: make it more AF-neutral and v6-capable + + * ftpd/ftpcmd.y: add EPRT and EPSV + + * ftpd/extern.h: update prototypes and variables + + * ftp/krb4.c: update to new types of addresses + + * ftp/gssapi.c: add support for both AF_INET and AF_INET6 + addresses + + * ftp/ftp.c: make it more AF-neutral and v6-capable + + * ftp/extern.h (hookup): change prototype + + * common/common.h: add prototypes for functions in socket.c + + * common/Makefile.am (libcommon_a_SOURCES): add socket.c + + * ftp/gssapi.c (gss_auth): check return value from + `gss_import_name' and print error messages if it fails + 1999-06-15 Assar Westerlund <assar@sics.se> * ftp/krb4.c (krb4_auth): type correctness diff --git a/crypto/kerberosIV/appl/ftp/common/Makefile.am b/crypto/kerberosIV/appl/ftp/common/Makefile.am index 2ab5801..4fab07b 100644 --- a/crypto/kerberosIV/appl/ftp/common/Makefile.am +++ b/crypto/kerberosIV/appl/ftp/common/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.7 1999/03/20 13:58:14 joda Exp $ +# $Id: Makefile.am,v 1.9 1999/07/28 21:15:06 assar Exp $ include $(top_srcdir)/Makefile.am.common diff --git a/crypto/kerberosIV/appl/ftp/common/buffer.c b/crypto/kerberosIV/appl/ftp/common/buffer.c index 97e2815..0385d49 100644 --- a/crypto/kerberosIV/appl/ftp/common/buffer.c +++ b/crypto/kerberosIV/appl/ftp/common/buffer.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -41,7 +36,7 @@ #include <err.h> #include "roken.h" -RCSID("$Id: buffer.c,v 1.2 1997/12/14 23:51:45 assar Exp $"); +RCSID("$Id: buffer.c,v 1.3 1999/12/02 16:58:29 joda Exp $"); /* * Allocate a buffer enough to handle st->st_blksize, if diff --git a/crypto/kerberosIV/appl/ftp/common/common.h b/crypto/kerberosIV/appl/ftp/common/common.h index 4ec3149..5949b25 100644 --- a/crypto/kerberosIV/appl/ftp/common/common.h +++ b/crypto/kerberosIV/appl/ftp/common/common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: common.h,v 1.9 1997/05/18 19:59:58 assar Exp $ */ +/* $Id: common.h,v 1.12 1999/12/02 16:58:29 joda Exp $ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -56,6 +51,9 @@ void set_buffer_size(int, int); #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif void *alloc_buffer (void *oldbuf, size_t *sz, struct stat *st); diff --git a/crypto/kerberosIV/appl/ftp/common/sockbuf.c b/crypto/kerberosIV/appl/ftp/common/sockbuf.c index ab8c293..460cc6f 100644 --- a/crypto/kerberosIV/appl/ftp/common/sockbuf.c +++ b/crypto/kerberosIV/appl/ftp/common/sockbuf.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -44,7 +39,7 @@ #include <sys/socket.h> #endif -RCSID("$Id: sockbuf.c,v 1.2 1997/05/11 10:01:48 assar Exp $"); +RCSID("$Id: sockbuf.c,v 1.3 1999/12/02 16:58:29 joda Exp $"); void set_buffer_size(int fd, int read) diff --git a/crypto/kerberosIV/appl/ftp/ftp/cmds.c b/crypto/kerberosIV/appl/ftp/ftp/cmds.c index 1571fc8..7698313 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/cmds.c +++ b/crypto/kerberosIV/appl/ftp/ftp/cmds.c @@ -36,7 +36,7 @@ */ #include "ftp_locl.h" -RCSID("$Id: cmds.c,v 1.34.2.1 1999/08/18 18:19:44 assar Exp $"); +RCSID("$Id: cmds.c,v 1.36 1999/09/16 20:37:28 assar Exp $"); typedef void (*sighand)(int); @@ -119,16 +119,16 @@ setpeer(int argc, char **argv) /* * Set up defaults for FTP. */ - strcpy_truncate(typename, "ascii", sizeof(typename)); + strlcpy(typename, "ascii", sizeof(typename)); type = TYPE_A; curtype = TYPE_A; - strcpy_truncate(formname, "non-print", sizeof(formname)); + strlcpy(formname, "non-print", sizeof(formname)); form = FORM_N; - strcpy_truncate(modename, "stream", sizeof(modename)); + strlcpy(modename, "stream", sizeof(modename)); mode = MODE_S; - strcpy_truncate(structname, "file", sizeof(structname)); + strlcpy(structname, "file", sizeof(structname)); stru = STRU_F; - strcpy_truncate(bytename, "8", sizeof(bytename)); + strlcpy(bytename, "8", sizeof(bytename)); bytesize = 8; if (autologin) login(argv[1]); @@ -170,7 +170,7 @@ setpeer(int argc, char **argv) * for text files unless changed by the user. */ type = 0; - strcpy_truncate(typename, "binary", sizeof(typename)); + strlcpy(typename, "binary", sizeof(typename)); if (overbose) printf("Using %s mode to transfer files.\n", typename); @@ -243,7 +243,7 @@ settype(int argc, char **argv) else comret = command("TYPE %s", p->t_mode); if (comret == COMPLETE) { - strcpy_truncate(typename, p->t_name, sizeof(typename)); + strlcpy(typename, p->t_name, sizeof(typename)); curtype = type = p->t_type; } } @@ -784,7 +784,7 @@ remglob(char **argv, int doswitch) } if (ftemp == NULL) { int fd; - strcpy_truncate(temp, _PATH_TMP_XXX, sizeof(temp)); + strlcpy(temp, _PATH_TMP_XXX, sizeof(temp)); fd = mkstemp(temp); if(fd < 0){ warn("unable to create temporary file %s", temp); @@ -1419,11 +1419,11 @@ quote1(char *initial, int argc, char **argv) int i; char buf[BUFSIZ]; /* must be >= sizeof(line) */ - strcpy_truncate(buf, initial, sizeof(buf)); + strlcpy(buf, initial, sizeof(buf)); for(i = 1; i < argc; i++) { if(i > 1) - strcat_truncate(buf, " ", sizeof(buf)); - strcat_truncate(buf, argv[i], sizeof(buf)); + strlcat(buf, " ", sizeof(buf)); + strlcat(buf, argv[i], sizeof(buf)); } if (command("%s", buf) == PRELIM) { while (getreply(0) == PRELIM) @@ -1575,11 +1575,11 @@ account(int argc, char **argv) if (argc > 1) { ++argv; --argc; - strcpy_truncate (acct, *argv, sizeof(acct)); + strlcpy (acct, *argv, sizeof(acct)); while (argc > 1) { --argc; ++argv; - strcat_truncate(acct, *argv, sizeof(acct)); + strlcat(acct, *argv, sizeof(acct)); } } else { @@ -1691,12 +1691,12 @@ setntrans(int argc, char **argv) } ntflag++; code = ntflag; - strcpy_truncate (ntin, argv[1], 17); + strlcpy (ntin, argv[1], 17); if (argc == 2) { ntout[0] = '\0'; return; } - strcpy_truncate (ntout, argv[2], 17); + strlcpy (ntout, argv[2], 17); } char * @@ -1753,10 +1753,10 @@ setnmap(int argc, char **argv) cp = strchr(altarg, ' '); } *cp = '\0'; - strcpy_truncate(mapin, altarg, MaxPathLen); + strlcpy(mapin, altarg, MaxPathLen); while (*++cp == ' ') continue; - strcpy_truncate(mapout, cp, MaxPathLen); + strlcpy(mapout, cp, MaxPathLen); } char * @@ -2008,7 +2008,7 @@ macdef(int argc, char **argv) if (interactive) { printf("Enter macro line by line, terminating it with a null line\n"); } - strcpy_truncate(macros[macnum].mac_name, + strlcpy(macros[macnum].mac_name, argv[1], sizeof(macros[macnum].mac_name)); if (macnum == 0) { diff --git a/crypto/kerberosIV/appl/ftp/ftp/domacro.c b/crypto/kerberosIV/appl/ftp/ftp/domacro.c index 432e3e5..d91660d 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/domacro.c +++ b/crypto/kerberosIV/appl/ftp/ftp/domacro.c @@ -32,7 +32,7 @@ */ #include "ftp_locl.h" -RCSID("$Id: domacro.c,v 1.6 1998/06/09 19:24:21 joda Exp $"); +RCSID("$Id: domacro.c,v 1.7 1999/09/16 20:37:29 assar Exp $"); void domacro(int argc, char **argv) @@ -56,7 +56,7 @@ domacro(int argc, char **argv) code = -1; return; } - strcpy_truncate(line2, line, sizeof(line2)); + strlcpy(line2, line, sizeof(line2)); TOP: cp1 = macros[i].mac_start; while (cp1 != macros[i].mac_end) { diff --git a/crypto/kerberosIV/appl/ftp/ftp/extern.h b/crypto/kerberosIV/appl/ftp/ftp/extern.h index 5efe918..d488ecd 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/extern.h +++ b/crypto/kerberosIV/appl/ftp/ftp/extern.h @@ -33,7 +33,7 @@ * @(#)extern.h 8.3 (Berkeley) 10/9/94 */ -/* $Id: extern.h,v 1.16 1999/05/21 09:21:51 assar Exp $ */ +/* $Id: extern.h,v 1.18 1999/10/28 20:49:10 assar Exp $ */ #include <setjmp.h> #include <stdlib.h> @@ -62,7 +62,7 @@ void cmdabort (int); void cmdscanner (int); int command (char *fmt, ...); int confirm (char *, char *); -FILE *dataconn (char *); +FILE *dataconn (const char *); void delete (int, char **); void disconnect (int, char **); void do_chmod (int, char **); @@ -80,7 +80,7 @@ int getreply (int); int globulize (char **); char *gunique (char *); void help (int, char **); -char *hookup (char *, int); +char *hookup (const char *, int); void ftp_idle (int, char **); int initconn (void); void intr (int); diff --git a/crypto/kerberosIV/appl/ftp/ftp/ftp.c b/crypto/kerberosIV/appl/ftp/ftp/ftp.c index 3021a19..833fb08 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/ftp.c +++ b/crypto/kerberosIV/appl/ftp/ftp/ftp.c @@ -32,16 +32,19 @@ */ #include "ftp_locl.h" -RCSID ("$Id: ftp.c,v 1.55 1999/06/02 20:12:22 joda Exp $"); - -struct sockaddr_in hisctladdr; -struct sockaddr_in data_addr; +RCSID ("$Id: ftp.c,v 1.60 1999/10/28 19:32:17 assar Exp $"); + +struct sockaddr_storage hisctladdr_ss; +struct sockaddr *hisctladdr = (struct sockaddr *)&hisctladdr_ss; +struct sockaddr_storage data_addr_ss; +struct sockaddr *data_addr = (struct sockaddr *)&data_addr_ss; +struct sockaddr_storage myctladdr_ss; +struct sockaddr *myctladdr = (struct sockaddr *)&myctladdr_ss; int data = -1; int abrtflag = 0; jmp_buf ptabort; int ptabflg; int ptflag = 0; -struct sockaddr_in myctladdr; off_t restart_point = 0; @@ -50,77 +53,76 @@ FILE *cin, *cout; typedef void (*sighand) (int); char * -hookup (char *host, int port) +hookup (const char *host, int port) { - struct hostent *hp = 0; + struct hostent *hp = NULL; int s, len; static char hostnamebuf[MaxHostNameLen]; + int error; + int af; + char **h; + int ret; + +#ifdef HAVE_IPV6 + if (hp == NULL) + hp = getipnodebyname (host, AF_INET6, 0, &error); +#endif + if (hp == NULL) + hp = getipnodebyname (host, AF_INET, 0, &error); - memset (&hisctladdr, 0, sizeof (hisctladdr)); - if (inet_aton (host, &hisctladdr.sin_addr)) { - hisctladdr.sin_family = AF_INET; - strcpy_truncate (hostnamebuf, host, sizeof (hostnamebuf)); - } else { - hp = gethostbyname (host); - if (hp == NULL) { - warnx("%s: %s", host, hstrerror(h_errno)); - code = -1; - return NULL; - } - hisctladdr.sin_family = hp->h_addrtype; - memmove(&hisctladdr.sin_addr, - hp->h_addr_list[0], - sizeof(hisctladdr.sin_addr)); - strcpy_truncate (hostnamebuf, hp->h_name, sizeof (hostnamebuf)); - } - hostname = hostnamebuf; - s = socket (hisctladdr.sin_family, SOCK_STREAM, 0); - if (s < 0) { - warn ("socket"); + if (hp == NULL) { + warnx ("%s: %s", host, hstrerror(error)); code = -1; - return (0); + return NULL; } - hisctladdr.sin_port = port; - while (connect (s, (struct sockaddr *) & hisctladdr, sizeof (hisctladdr)) < 0) { - if (hp && hp->h_addr_list[1]) { - int oerrno = errno; - char *ia; - - ia = inet_ntoa (hisctladdr.sin_addr); - errno = oerrno; - warn ("connect to address %s", ia); - hp->h_addr_list++; - memmove (&hisctladdr.sin_addr, - hp->h_addr_list[0], - sizeof (hisctladdr.sin_addr)); - fprintf (stdout, "Trying %s...\n", - inet_ntoa (hisctladdr.sin_addr)); + strlcpy (hostnamebuf, hp->h_name, sizeof(hostnamebuf)); + hostname = hostnamebuf; + af = hisctladdr->sa_family = hp->h_addrtype; + + for (h = hp->h_addr_list; + *h != NULL; + ++h) { + + s = socket (af, SOCK_STREAM, 0); + if (s < 0) { + warn ("socket"); + code = -1; + freehostent (hp); + return (0); + } + + socket_set_address_and_port (hisctladdr, *h, port); + + ret = connect (s, hisctladdr, socket_sockaddr_size(hisctladdr)); + if (ret < 0) { + char addr[256]; + + if (inet_ntop (af, socket_get_address(hisctladdr), + addr, sizeof(addr)) == NULL) + strlcpy (addr, "unknown address", + sizeof(addr)); + warn ("connect %s", addr); close (s); - s = socket (hisctladdr.sin_family, SOCK_STREAM, 0); - if (s < 0) { - warn ("socket"); - code = -1; - return (0); - } continue; } - warn ("connect"); - code = -1; - goto bad; + break; } - len = sizeof (myctladdr); - if (getsockname (s, (struct sockaddr *) & myctladdr, &len) < 0) { - warn ("getsockname"); + freehostent (hp); + if (ret < 0) { code = -1; - goto bad; + close (s); + return NULL; } -#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) - { - int tos = IPTOS_LOWDELAY; - if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - warn("setsockopt TOS (ignored)"); + len = sizeof(myctladdr_ss); + if (getsockname (s, myctladdr, &len) < 0) { + warn ("getsockname"); + code = -1; + close (s); + return NULL; } +#ifdef IPTOS_LOWDELAY + socket_set_tos (s, IPTOS_LOWDELAY); #endif cin = fdopen (s, "r"); cout = fdopen (s, "w"); @@ -198,7 +200,7 @@ login (char *host) else user = tmp; } - strcpy_truncate(username, user, sizeof(username)); + strlcpy(username, user, sizeof(username)); n = command("USER %s", user); if (n == CONTINUE) { if(sec_complete) @@ -238,7 +240,7 @@ login (char *host) return (1); for (n = 0; n < macnum; ++n) { if (!strcmp("init", macros[n].mac_name)) { - strcpy_truncate (line, "$init", sizeof (line)); + strlcpy (line, "$init", sizeof (line)); makeargv(); domacro(margc, margv); break; @@ -375,7 +377,7 @@ getreply (int expecteof) osa.sa_handler != SIG_IGN) osa.sa_handler (SIGINT); #endif - if (code == 227) { + if (code == 227 || code == 229) { char *p, *q; pasv[0] = 0; @@ -565,6 +567,11 @@ copy_stream (FILE * from, FILE * to) #endif if (fstat (fileno (from), &st) == 0 && S_ISREG (st.st_mode)) { + /* + * mmap zero bytes has potential of loosing, don't do it. + */ + if (st.st_size == 0) + return 0; chunk = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fileno (from), 0); if (chunk != (void *) MAP_FAILED) { int res; @@ -1120,154 +1127,249 @@ abort: signal (SIGINT, oldintr); } -/* - * Need to start a listen on the data channel before we send the command, - * otherwise the server's connect may fail. - */ -int -initconn (void) +static int +parse_epsv (const char *str) +{ + char sep; + char *end; + int port; + + if (*str == '\0') + return -1; + sep = *str++; + if (sep != *str++) + return -1; + if (sep != *str++) + return -1; + port = strtol (str, &end, 0); + if (str == end) + return -1; + if (end[0] != sep || end[1] != '\0') + return -1; + return htons(port); +} + +static int +parse_pasv (struct sockaddr_in *sin, const char *str) { - int result, len, tmpno = 0; - int on = 1; int a0, a1, a2, a3, p0, p1; - if (passivemode) { - data = socket (AF_INET, SOCK_STREAM, 0); - if (data < 0) { - perror ("ftp: socket"); - return (1); - } -#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT) - if ((options & SO_DEBUG) && - setsockopt (data, SOL_SOCKET, SO_DEBUG, (char *) &on, - sizeof (on)) < 0) - perror ("ftp: setsockopt (ignored)"); -#endif + /* + * What we've got at this point is a string of comma separated + * one-byte unsigned integer values. 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 (str, "%d,%d,%d,%d,%d,%d", + &a0, &a1, &a2, &a3, &p0, &p1) != 6) { + printf ("Passive mode address scan failure. " + "Shouldn't happen!\n"); + return -1; + } + if (a0 < 0 || a0 > 255 || + a1 < 0 || a1 > 255 || + a2 < 0 || a2 > 255 || + a3 < 0 || a3 > 255 || + p0 < 0 || p0 > 255 || + p1 < 0 || p1 > 255) { + printf ("Can't parse passive mode string.\n"); + return -1; + } + memset (sin, 0, sizeof(*sin)); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl ((a0 << 24) | (a1 << 16) | + (a2 << 8) | a3); + sin->sin_port = htons ((p0 << 8) | p1); + return 0; +} + +static int +passive_mode (void) +{ + int port; + + data = socket (myctladdr->sa_family, SOCK_STREAM, 0); + if (data < 0) { + warn ("socket"); + return (1); + } + if (options & SO_DEBUG) + socket_set_debug (data); + if (command ("EPSV") != COMPLETE) { if (command ("PASV") != COMPLETE) { printf ("Passive mode refused.\n"); goto bad; } + } - /* - * What we've got at this point is a string of comma separated - * one-byte unsigned integer values. 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. - */ + /* + * Parse the reply to EPSV or PASV + */ - if (sscanf (pasv, "%d,%d,%d,%d,%d,%d", - &a0, &a1, &a2, &a3, &p0, &p1) != 6) { - printf ("Passive mode address scan failure. " - "Shouldn't happen!\n"); - goto bad; - } - if (a0 < 0 || a0 > 255 || - a1 < 0 || a1 > 255 || - a2 < 0 || a2 > 255 || - a3 < 0 || a3 > 255 || - p0 < 0 || p0 > 255 || - p1 < 0 || p1 > 255) { - printf ("Can't parse passive mode string.\n"); - goto bad; - } - memset(&data_addr, 0, sizeof(data_addr)); - data_addr.sin_family = AF_INET; - data_addr.sin_addr.s_addr = htonl ((a0 << 24) | (a1 << 16) | - (a2 << 8) | a3); - data_addr.sin_port = htons ((p0 << 8) | p1); - - if (connect (data, (struct sockaddr *) & data_addr, - sizeof (data_addr)) < 0) { - perror ("ftp: connect"); + port = parse_epsv (pasv); + if (port > 0) { + data_addr->sa_family = myctladdr->sa_family; + socket_set_address_and_port (data_addr, + socket_get_address (hisctladdr), + port); + } else { + if (parse_pasv ((struct sockaddr_in *)data_addr, pasv) < 0) goto bad; - } -#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) - on = IPTOS_THROUGHPUT; - if (setsockopt (data, IPPROTO_IP, IP_TOS, (char *) &on, - sizeof (int)) < 0) - perror ("ftp: setsockopt TOS (ignored)"); -#endif - return (0); } + + if (connect (data, data_addr, socket_sockaddr_size (data_addr)) < 0) { + warn ("connect"); + goto bad; + } +#ifdef IPTOS_THROUGHPUT + socket_set_tos (data, IPTOS_THROUGHPUT); +#endif + return (0); +bad: + close (data); + data = -1; + sendport = 1; + return (1); +} + + +static int +active_mode (void) +{ + int tmpno = 0; + int len; + int result; + noport: - data_addr = myctladdr; - if (sendport) - data_addr.sin_port = 0; /* let system pick one */ + data_addr->sa_family = myctladdr->sa_family; + socket_set_address_and_port (data_addr, socket_get_address (myctladdr), + sendport ? 0 : socket_get_port (myctladdr)); + if (data != -1) close (data); - data = socket (AF_INET, SOCK_STREAM, 0); + data = socket (data_addr->sa_family, SOCK_STREAM, 0); if (data < 0) { warn ("socket"); if (tmpno) sendport = 1; return (1); } -#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT) if (!sendport) - if (setsockopt (data, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof (on)) < 0) { - warn ("setsockopt (reuse address)"); - goto bad; - } -#endif - if (bind (data, (struct sockaddr *) & data_addr, sizeof (data_addr)) < 0) { + socket_set_reuseaddr (data, 1); + if (bind (data, data_addr, socket_sockaddr_size (data_addr)) < 0) { warn ("bind"); goto bad; } -#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT) - if (options & SO_DEBUG && - setsockopt (data, SOL_SOCKET, SO_DEBUG, (char *) &on, sizeof (on)) < 0) - warn ("setsockopt (ignored)"); -#endif - len = sizeof (data_addr); - if (getsockname (data, (struct sockaddr *) & data_addr, &len) < 0) { + if (options & SO_DEBUG) + socket_set_debug (data); + len = sizeof (data_addr_ss); + if (getsockname (data, data_addr, &len) < 0) { warn ("getsockname"); goto bad; } if (listen (data, 1) < 0) warn ("listen"); if (sendport) { - unsigned int a = ntohl(data_addr.sin_addr.s_addr); - unsigned int p = ntohs(data_addr.sin_port); - - result = command("PORT %d,%d,%d,%d,%d,%d", - (a >> 24) & 0xff, - (a >> 16) & 0xff, - (a >> 8) & 0xff, - a & 0xff, - (p >> 8) & 0xff, - p & 0xff); - if (result == ERROR && sendport == -1) { - sendport = 0; - tmpno = 1; - goto noport; + char *cmd; + char addr_str[256]; + int inet_af; + int overbose; + + if (inet_ntop (data_addr->sa_family, socket_get_address (data_addr), + addr_str, sizeof(addr_str)) == NULL) + errx (1, "inet_ntop failed"); + switch (data_addr->sa_family) { + case AF_INET : + inet_af = 1; + break; +#ifdef HAVE_IPV6 + case AF_INET6 : + inet_af = 2; + break; +#endif + default : + errx (1, "bad address family %d", data_addr->sa_family); + } + + asprintf (&cmd, "EPRT |%d|%s|%d|", + inet_af, addr_str, ntohs(socket_get_port (data_addr))); + + overbose = verbose; + if (debug == 0) + verbose = -1; + + result = command (cmd); + + verbose = overbose; + + if (result == ERROR) { + struct sockaddr_in *sin = (struct sockaddr_in *)data_addr; + + unsigned int a = ntohl(sin->sin_addr.s_addr); + unsigned int p = ntohs(sin->sin_port); + + if (data_addr->sa_family != AF_INET) { + warnx ("remote server doesn't support EPRT"); + goto bad; + } + + result = command("PORT %d,%d,%d,%d,%d,%d", + (a >> 24) & 0xff, + (a >> 16) & 0xff, + (a >> 8) & 0xff, + a & 0xff, + (p >> 8) & 0xff, + p & 0xff); + if (result == ERROR && sendport == -1) { + sendport = 0; + tmpno = 1; + goto noport; + } + return (result != COMPLETE); } - return (result != COMPLETE); + return result != COMPLETE; } if (tmpno) sendport = 1; -#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) - on = IPTOS_THROUGHPUT; - if (setsockopt (data, IPPROTO_IP, IP_TOS, (char *) &on, sizeof (int)) < 0) - warn ("setsockopt TOS (ignored)"); + + +#ifdef IPTOS_THROUGHPUT + socket_set_tos (data, IPTOS_THROUGHPUT); #endif return (0); bad: - close (data), data = -1; + close (data); + data = -1; if (tmpno) sendport = 1; return (1); } +/* + * Need to start a listen on the data channel before we send the command, + * otherwise the server's connect may fail. + */ +int +initconn (void) +{ + if (passivemode) + return passive_mode (); + else + return active_mode (); +} + FILE * -dataconn (char *lmode) +dataconn (const char *lmode) { - struct sockaddr_in from; - int s, fromlen = sizeof (from), tos; + struct sockaddr_storage from_ss; + struct sockaddr *from = (struct sockaddr *)&from_ss; + int s, fromlen = sizeof (from_ss); if (passivemode) return (fdopen (data, lmode)); - s = accept (data, (struct sockaddr *) & from, &fromlen); + s = accept (data, from, &fromlen); if (s < 0) { warn ("accept"); close (data), data = -1; @@ -1275,10 +1377,8 @@ dataconn (char *lmode) } close (data); data = s; -#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT) - tos = IPTOS_THROUGHPUT; - if (setsockopt (s, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof (int)) < 0) - warn ("setsockopt TOS (ignored)"); +#ifdef IPTOS_THROUGHPUT + socket_set_tos (s, IPTOS_THROUGHPUT); #endif return (fdopen (data, lmode)); } @@ -1334,8 +1434,8 @@ pswitch (int flag) 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; @@ -1371,14 +1471,14 @@ pswitch (int flag) ip->connect = connected; connected = op->connect; if (hostname) { - strcpy_truncate (ip->name, hostname, sizeof (ip->name)); + strlcpy (ip->name, hostname, sizeof (ip->name)); } else ip->name[0] = 0; hostname = op->name; - ip->hctl = hisctladdr; - hisctladdr = op->hctl; - ip->mctl = myctladdr; - myctladdr = op->mctl; + ip->hctl = hisctladdr_ss; + hisctladdr_ss = op->hctl; + ip->mctl = myctladdr_ss; + myctladdr_ss = op->mctl; ip->in = cin; cin = op->in; ip->out = cout; @@ -1397,16 +1497,16 @@ pswitch (int flag) mcase = op->mcse; ip->ntflg = ntflag; ntflag = op->ntflg; - strcpy_truncate (ip->nti, ntin, sizeof (ip->nti)); - strcpy_truncate (ntin, op->nti, 17); - strcpy_truncate (ip->nto, ntout, sizeof (ip->nto)); - strcpy_truncate (ntout, op->nto, 17); + strlcpy (ip->nti, ntin, sizeof (ip->nti)); + strlcpy (ntin, op->nti, 17); + strlcpy (ip->nto, ntout, sizeof (ip->nto)); + strlcpy (ntout, op->nto, 17); ip->mapflg = mapflag; mapflag = op->mapflg; - strcpy_truncate (ip->mi, mapin, MaxPathLen); - strcpy_truncate (mapin, op->mi, MaxPathLen); - strcpy_truncate (ip->mo, mapout, MaxPathLen); - strcpy_truncate (mapout, op->mo, MaxPathLen); + strlcpy (ip->mi, mapin, MaxPathLen); + strlcpy (mapin, op->mi, MaxPathLen); + strlcpy (ip->mo, mapout, MaxPathLen); + strlcpy (mapout, op->mo, MaxPathLen); signal(SIGINT, oldintr); if (abrtflag) { abrtflag = 0; @@ -1580,7 +1680,7 @@ gunique (char *local) warn ("local: %s", local); return NULL; } - strcpy_truncate (new, local, sizeof(new)); + strlcpy (new, local, sizeof(new)); cp = new + strlen(new); *cp++ = '.'; while (!d) { diff --git a/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h b/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h index 5ae44b1..49c2b2f 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h +++ b/crypto/kerberosIV/appl/ftp/ftp/ftp_locl.h @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: ftp_locl.h,v 1.33 1998/06/13 00:06:40 assar Exp $ */ +/* $Id: ftp_locl.h,v 1.34 1999/12/02 16:58:29 joda Exp $ */ #ifndef __FTP_LOCL_H__ #define __FTP_LOCL_H__ diff --git a/crypto/kerberosIV/appl/ftp/ftp/gssapi.c b/crypto/kerberosIV/appl/ftp/ftp/gssapi.c index bc001a4..d06b5d6 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/gssapi.c +++ b/crypto/kerberosIV/appl/ftp/ftp/gssapi.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -43,7 +38,7 @@ #endif #include <gssapi.h> -RCSID("$Id: gssapi.c,v 1.7 1999/04/10 15:08:39 assar Exp $"); +RCSID("$Id: gssapi.c,v 1.13 1999/12/02 16:58:29 joda Exp $"); struct gss_data { gss_ctx_id_t context_hdl; @@ -117,6 +112,36 @@ gss_encode(void *app_data, void *from, int length, int level, void **to) return output.length; } +static void +sockaddr_to_gss_address (const struct sockaddr *sa, + OM_uint32 *addr_type, + gss_buffer_desc *gss_addr) +{ + switch (sa->sa_family) { +#ifdef HAVE_IPV6 + case AF_INET6 : { + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; + + gss_addr->length = 16; + gss_addr->value = &sin6->sin6_addr; + *addr_type = GSS_C_AF_INET6; + break; + } +#endif + case AF_INET : { + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + + gss_addr->length = 4; + gss_addr->value = &sin->sin_addr; + *addr_type = GSS_C_AF_INET; + break; + } + default : + errx (1, "unknown address family %d", sa->sa_family); + + } +} + /* end common stuff */ #ifdef FTP_SERVER @@ -131,12 +156,13 @@ gss_adat(void *app_data, void *buf, size_t len) struct gss_data *d = app_data; gss_channel_bindings_t bindings = malloc(sizeof(*bindings)); - bindings->initiator_addrtype = GSS_C_AF_INET; - bindings->initiator_address.length = 4; - bindings->initiator_address.value = &his_addr.sin_addr; - bindings->acceptor_addrtype = GSS_C_AF_INET; - bindings->acceptor_address.length = 4; - bindings->acceptor_address.value = &ctrl_addr.sin_addr; + sockaddr_to_gss_address (his_addr, + &bindings->initiator_addrtype, + &bindings->initiator_address); + sockaddr_to_gss_address (ctrl_addr, + &bindings->acceptor_addrtype, + &bindings->acceptor_address); + bindings->application_data.length = 0; bindings->application_data.value = NULL; @@ -216,7 +242,7 @@ struct sec_server_mech gss_server_mech = { #else /* FTP_SERVER */ -extern struct sockaddr_in hisctladdr, myctladdr; +extern struct sockaddr *hisctladdr, *myctladdr; static int gss_auth(void *app_data, char *host) @@ -237,6 +263,23 @@ gss_auth(void *app_data, char *host) &name, GSS_C_NT_HOSTBASED_SERVICE, &target_name); + if (GSS_ERROR(maj_stat)) { + OM_uint32 new_stat; + OM_uint32 msg_ctx = 0; + gss_buffer_desc status_string; + + gss_display_status(&new_stat, + min_stat, + GSS_C_MECH_CODE, + GSS_C_NO_OID, + &msg_ctx, + &status_string); + printf("Error importing name %s: %s\n", + (char *)name.value, + (char *)status_string.value); + gss_release_buffer(&new_stat, &status_string); + return AUTH_ERROR; + } free(name.value); @@ -244,12 +287,14 @@ gss_auth(void *app_data, char *host) input.value = NULL; bindings = malloc(sizeof(*bindings)); - bindings->initiator_addrtype = GSS_C_AF_INET; - bindings->initiator_address.length = 4; - bindings->initiator_address.value = &myctladdr.sin_addr; - bindings->acceptor_addrtype = GSS_C_AF_INET; - bindings->acceptor_address.length = 4; - bindings->acceptor_address.value = &hisctladdr.sin_addr; + + sockaddr_to_gss_address (myctladdr, + &bindings->initiator_addrtype, + &bindings->initiator_address); + sockaddr_to_gss_address (hisctladdr, + &bindings->acceptor_addrtype, + &bindings->acceptor_address); + bindings->application_data.length = 0; bindings->application_data.value = NULL; @@ -268,8 +313,8 @@ gss_auth(void *app_data, char *host) NULL, NULL); if (GSS_ERROR(maj_stat)) { - int new_stat; - int msg_ctx = 0; + OM_uint32 new_stat; + OM_uint32 msg_ctx = 0; gss_buffer_desc status_string; gss_display_status(&new_stat, diff --git a/crypto/kerberosIV/appl/ftp/ftp/kauth.c b/crypto/kerberosIV/appl/ftp/ftp/kauth.c index 434dfb8..613593a 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/kauth.c +++ b/crypto/kerberosIV/appl/ftp/ftp/kauth.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995-1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +33,7 @@ #include "ftp_locl.h" #include <krb.h> -RCSID("$Id: kauth.c,v 1.17 1998/03/26 02:55:38 joda Exp $"); +RCSID("$Id: kauth.c,v 1.20 1999/12/02 16:58:29 joda Exp $"); void kauth(int argc, char **argv) @@ -54,6 +49,8 @@ kauth(int argc, char **argv) char passwd[100]; int tmp; + int save; + if(argc > 2){ printf("usage: %s [principal]\n", argv[0]); code = -1; @@ -67,9 +64,11 @@ kauth(int argc, char **argv) overbose = verbose; verbose = 0; + save = set_command_prot(prot_private); ret = command("SITE KAUTH %s", name); if(ret != CONTINUE){ verbose = overbose; + set_command_prot(save); code = -1; return; } @@ -77,6 +76,7 @@ kauth(int argc, char **argv) p = strstr(reply_string, "T="); if(!p){ printf("Bad reply from server.\n"); + set_command_prot(save); code = -1; return; } @@ -84,6 +84,7 @@ kauth(int argc, char **argv) tmp = base64_decode(p, &tkt.dat); if(tmp < 0){ printf("Failed to decode base64 in reply.\n"); + set_command_prot(save); code = -1; return; } @@ -94,6 +95,7 @@ kauth(int argc, char **argv) if(!p){ printf("Bad reply from server.\n"); verbose = overbose; + set_command_prot(save); code = -1; return; } @@ -124,12 +126,14 @@ kauth(int argc, char **argv) memset(passwd, 0, sizeof(passwd)); if(base64_encode(tktcopy.dat, tktcopy.length, &p) < 0) { printf("Out of memory base64-encoding.\n"); + set_command_prot(save); code = -1; return; } memset (tktcopy.dat, 0, tktcopy.length); ret = command("SITE KAUTH %s %s", name, p); free(p); + set_command_prot(save); if(ret != COMPLETE){ code = -1; return; diff --git a/crypto/kerberosIV/appl/ftp/ftp/krb4.c b/crypto/kerberosIV/appl/ftp/ftp/krb4.c index 5b9b9b8..aa30c1b 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/krb4.c +++ b/crypto/kerberosIV/appl/ftp/ftp/krb4.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -43,7 +38,7 @@ #endif #include <krb.h> -RCSID("$Id: krb4.c,v 1.30 1999/06/15 03:50:28 assar Exp $"); +RCSID("$Id: krb4.c,v 1.36.2.1 1999/12/06 17:29:45 assar Exp $"); #ifdef FTP_SERVER #define LOCAL_ADDR ctrl_addr @@ -52,7 +47,8 @@ RCSID("$Id: krb4.c,v 1.30 1999/06/15 03:50:28 assar Exp $"); #define LOCAL_ADDR myctladdr #define REMOTE_ADDR hisctladdr #endif -extern struct sockaddr_in LOCAL_ADDR, REMOTE_ADDR; + +extern struct sockaddr *LOCAL_ADDR, *REMOTE_ADDR; struct krb4_data { des_cblock key; @@ -78,11 +74,15 @@ krb4_decode(void *app_data, void *buf, int len, int level) struct krb4_data *d = app_data; if(level == prot_safe) - e = krb_rd_safe(buf, len, &d->key, &REMOTE_ADDR, &LOCAL_ADDR, &m); + e = krb_rd_safe(buf, len, &d->key, + (struct sockaddr_in *)REMOTE_ADDR, + (struct sockaddr_in *)LOCAL_ADDR, &m); else e = krb_rd_priv(buf, len, d->schedule, &d->key, - &REMOTE_ADDR, &LOCAL_ADDR, &m); + (struct sockaddr_in *)REMOTE_ADDR, + (struct sockaddr_in *)LOCAL_ADDR, &m); if(e){ + syslog(LOG_ERR, "krb4_decode: %s", krb_get_err_text(e)); return -1; } memmove(buf, m.app_data, m.app_length); @@ -102,10 +102,12 @@ krb4_encode(void *app_data, void *from, int length, int level, void **to) *to = malloc(length + 31); if(level == prot_safe) return krb_mk_safe(from, *to, length, &d->key, - &LOCAL_ADDR, &REMOTE_ADDR); + (struct sockaddr_in *)LOCAL_ADDR, + (struct sockaddr_in *)REMOTE_ADDR); else if(level == prot_private) return krb_mk_priv(from, *to, length, d->schedule, &d->key, - &LOCAL_ADDR, &REMOTE_ADDR); + (struct sockaddr_in *)LOCAL_ADDR, + (struct sockaddr_in *)REMOTE_ADDR); else return -1; } @@ -124,17 +126,18 @@ krb4_adat(void *app_data, void *buf, size_t len) int tmp_len; struct krb4_data *d = app_data; char inst[INST_SZ]; + struct sockaddr_in *his_addr_sin = (struct sockaddr_in *)his_addr; memcpy(tkt.dat, buf, len); tkt.length = len; k_getsockinst(0, inst, sizeof(inst)); kerror = krb_rd_req(&tkt, "ftp", inst, - his_addr.sin_addr.s_addr, &auth_dat, ""); + his_addr_sin->sin_addr.s_addr, &auth_dat, ""); if(kerror == RD_AP_UNDEC){ k_getsockinst(0, inst, sizeof(inst)); kerror = krb_rd_req(&tkt, "rcmd", inst, - his_addr.sin_addr.s_addr, &auth_dat, ""); + his_addr_sin->sin_addr.s_addr, &auth_dat, ""); } if(kerror){ @@ -145,15 +148,17 @@ krb4_adat(void *app_data, void *buf, size_t len) memcpy(d->key, auth_dat.session, sizeof(d->key)); des_set_key(&d->key, d->schedule); - strcpy_truncate(d->name, auth_dat.pname, sizeof(d->name)); - strcpy_truncate(d->instance, auth_dat.pinst, sizeof(d->instance)); - strcpy_truncate(d->realm, auth_dat.prealm, sizeof(d->instance)); + strlcpy(d->name, auth_dat.pname, sizeof(d->name)); + strlcpy(d->instance, auth_dat.pinst, sizeof(d->instance)); + strlcpy(d->realm, auth_dat.prealm, sizeof(d->instance)); cs = auth_dat.checksum + 1; { unsigned char tmp[4]; KRB_PUT_INT(cs, tmp, 4, sizeof(tmp)); - tmp_len = krb_mk_safe(tmp, msg, 4, &d->key, &LOCAL_ADDR, &REMOTE_ADDR); + tmp_len = krb_mk_safe(tmp, msg, 4, &d->key, + (struct sockaddr_in *)LOCAL_ADDR, + (struct sockaddr_in *)REMOTE_ADDR); } if(tmp_len < 0){ reply(535, "Error creating reply: %s.", strerror(errno)); @@ -204,15 +209,15 @@ mk_auth(struct krb4_data *d, KTEXT adat, CREDENTIALS cred; char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ]; - strcpy_truncate(sname, service, sizeof(sname)); - strcpy_truncate(inst, krb_get_phost(host), sizeof(inst)); - strcpy_truncate(realm, krb_realmofhost(host), sizeof(realm)); + strlcpy(sname, service, sizeof(sname)); + strlcpy(inst, krb_get_phost(host), sizeof(inst)); + strlcpy(realm, krb_realmofhost(host), sizeof(realm)); ret = krb_mk_req(adat, sname, inst, realm, checksum); if(ret) return ret; - strcpy_truncate(sname, service, sizeof(sname)); - strcpy_truncate(inst, krb_get_phost(host), sizeof(inst)); - strcpy_truncate(realm, krb_realmofhost(host), sizeof(realm)); + strlcpy(sname, service, sizeof(sname)); + strlcpy(inst, krb_get_phost(host), sizeof(inst)); + strlcpy(realm, krb_realmofhost(host), sizeof(realm)); ret = krb_get_cred(sname, inst, realm, &cred); memmove(&d->key, &cred.session, sizeof(des_cblock)); des_key_sched(&d->key, d->schedule); @@ -231,6 +236,8 @@ krb4_auth(void *app_data, char *host) int checksum; u_int32_t cs; struct krb4_data *d = app_data; + struct sockaddr_in *localaddr = (struct sockaddr_in *)LOCAL_ADDR; + struct sockaddr_in *remoteaddr = (struct sockaddr_in *)REMOTE_ADDR; checksum = getpid(); ret = mk_auth(d, &adat, "ftp", host, checksum); @@ -241,7 +248,38 @@ krb4_auth(void *app_data, char *host) return AUTH_CONTINUE; } - if(base64_encode(adat.dat, adat.length, &p) < 0) { +#ifdef HAVE_KRB_GET_OUR_IP_FOR_REALM + if (krb_get_config_bool("nat_in_use")) { + struct in_addr natAddr; + + if (krb_get_our_ip_for_realm(krb_realmofhost(host), + &natAddr) != KSUCCESS + && krb_get_our_ip_for_realm(NULL, &natAddr) != KSUCCESS) + printf("Can't get address for realm %s\n", + krb_realmofhost(host)); + else { + if (natAddr.s_addr != localaddr->sin_addr.s_addr) { + printf("Using NAT IP address (%s) for kerberos 4\n", + inet_ntoa(natAddr)); + localaddr->sin_addr = natAddr; + + /* + * This not the best place to do this, but it + * is here we know that (probably) NAT is in + * use! + */ + + passivemode = 1; + printf("Setting: Passive mode on.\n"); + } + } + } +#endif + + printf("Local address is %s\n", inet_ntoa(localaddr->sin_addr)); + printf("Remote address is %s\n", inet_ntoa(remoteaddr->sin_addr)); + + if(base64_encode(adat.dat, adat.length, &p) < 0) { printf("Out of memory base64-encoding.\n"); return AUTH_CONTINUE; } @@ -266,7 +304,8 @@ krb4_auth(void *app_data, char *host) } adat.length = len; ret = krb_rd_safe(adat.dat, adat.length, &d->key, - &hisctladdr, &myctladdr, &msg_data); + (struct sockaddr_in *)hisctladdr, + (struct sockaddr_in *)myctladdr, &msg_data); if(ret){ printf("Error reading reply from server: %s.\n", krb_get_err_text(ret)); diff --git a/crypto/kerberosIV/appl/ftp/ftp/main.c b/crypto/kerberosIV/appl/ftp/ftp/main.c index 5b0fe36..dfe9e88 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/main.c +++ b/crypto/kerberosIV/appl/ftp/ftp/main.c @@ -36,7 +36,7 @@ */ #include "ftp_locl.h" -RCSID("$Id: main.c,v 1.25 1999/05/08 02:22:09 assar Exp $"); +RCSID("$Id: main.c,v 1.27 1999/11/13 06:18:02 assar Exp $"); int main(int argc, char **argv) @@ -56,7 +56,7 @@ main(int argc, char **argv) autologin = 1; passivemode = 0; /* passive mode not active */ - while ((ch = getopt(argc, argv, "dginptv")) != EOF) { + while ((ch = getopt(argc, argv, "dginptv")) != -1) { switch (ch) { case 'd': options |= SO_DEBUG; @@ -107,7 +107,7 @@ main(int argc, char **argv) */ pw = k_getpwuid(getuid()); if (pw != NULL) { - strcpy_truncate(homedir, pw->pw_dir, sizeof(homedir)); + strlcpy(homedir, pw->pw_dir, sizeof(homedir)); home = homedir; } if (argc > 0) { @@ -246,7 +246,7 @@ cmdscanner(int top) p = readline("ftp> "); if(p == NULL) quit(0, 0); - strcpy_truncate(line, p, sizeof(line)); + strlcpy(line, p, sizeof(line)); add_history(p); free(p); } else{ diff --git a/crypto/kerberosIV/appl/ftp/ftp/ruserpass.c b/crypto/kerberosIV/appl/ftp/ftp/ruserpass.c index 043e6fb..c687a59 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/ruserpass.c +++ b/crypto/kerberosIV/appl/ftp/ftp/ruserpass.c @@ -32,7 +32,7 @@ */ #include "ftp_locl.h" -RCSID("$Id: ruserpass.c,v 1.15 1999/03/11 13:54:58 joda Exp $"); +RCSID("$Id: ruserpass.c,v 1.16 1999/09/16 20:37:31 assar Exp $"); static int token (void); static FILE *cfile; @@ -77,7 +77,7 @@ guess_domain (char *hostname, size_t sz) char **aliases; if (gethostname (hostname, sz) < 0) { - strcpy_truncate (hostname, "", sz); + strlcpy (hostname, "", sz); return ""; } dot = strchr (hostname, '.'); @@ -90,13 +90,13 @@ guess_domain (char *hostname, size_t sz) dot = strchr (he->h_name, '.'); if (dot != NULL) { - strcpy_truncate (hostname, he->h_name, sz); + strlcpy (hostname, he->h_name, sz); return dot + 1; } for (aliases = he->h_aliases; (a = *aliases) != NULL; ++aliases) { dot = strchr (a, '.'); if (dot != NULL) { - strcpy_truncate (hostname, a, sz); + strlcpy (hostname, a, sz); return dot + 1; } } diff --git a/crypto/kerberosIV/appl/ftp/ftp/security.c b/crypto/kerberosIV/appl/ftp/ftp/security.c index 96d598f..ca7eb00 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/security.c +++ b/crypto/kerberosIV/appl/ftp/ftp/security.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -42,7 +37,7 @@ #include "ftp_locl.h" #endif -RCSID("$Id: security.c,v 1.8 1999/04/07 14:16:48 joda Exp $"); +RCSID("$Id: security.c,v 1.15 1999/12/02 16:58:30 joda Exp $"); static enum protection_level command_prot; static enum protection_level data_prot; @@ -127,7 +122,7 @@ sec_getc(FILE *F) { if(sec_complete && data_prot) { char c; - if(sec_read(fileno(F), &c, 1) == 0) + if(sec_read(fileno(F), &c, 1) <= 0) return EOF; return c; } else @@ -141,7 +136,9 @@ block_read(int fd, void *buf, size_t len) int b; while(len) { b = read(fd, p, len); - if(b <= 0) + if (b == 0) + return 0; + else if (b < 0) return -1; len -= b; p += b; @@ -168,12 +165,19 @@ static int sec_get_data(int fd, struct buffer *buf, int level) { int len; - - if(block_read(fd, &len, sizeof(len)) < 0) + int b; + + b = block_read(fd, &len, sizeof(len)); + if (b == 0) + return 0; + else if (b < 0) return -1; len = ntohl(len); buf->data = realloc(buf->data, len); - if(block_read(fd, buf->data, len) < 0) + b = block_read(fd, buf->data, len); + if (b == 0) + return 0; + else if (b < 0) return -1; buf->size = (*mech->decode)(app_data, buf->data, len, data_prot); buf->index = 0; @@ -292,6 +296,32 @@ sec_write(int fd, char *data, int length) } int +sec_vfprintf2(FILE *f, const char *fmt, va_list ap) +{ + char *buf; + int ret; + if(data_prot == prot_clear) + return vfprintf(f, fmt, ap); + else { + vasprintf(&buf, fmt, ap); + ret = buffer_write(&out_buffer, buf, strlen(buf)); + free(buf); + return ret; + } +} + +int +sec_fprintf2(FILE *f, const char *fmt, ...) +{ + int ret; + va_list ap; + va_start(ap, fmt); + ret = sec_vfprintf2(f, fmt, ap); + va_end(ap); + return ret; +} + +int sec_putc(int c, FILE *F) { char ch = c; @@ -547,6 +577,12 @@ secure_command(void) return ftp_command != NULL; } +enum protection_level +get_command_prot(void) +{ + return command_prot; +} + #else /* FTP_SERVER */ void @@ -603,30 +639,30 @@ sec_prot_internal(int level) return 0; } +enum protection_level +set_command_prot(enum protection_level level) +{ + enum protection_level old = command_prot; + command_prot = level; + return old; +} + void sec_prot(int argc, char **argv) { int level = -1; - if(argc != 2){ - printf("usage: %s (clear | safe | confidential | private)\n", - argv[0]); - code = -1; - return; - } - if(!sec_complete){ + if(argc < 2 || argc > 3) + goto usage; + if(!sec_complete) { printf("No security data exchange has taken place.\n"); code = -1; return; } - level = name_to_level(argv[1]); + level = name_to_level(argv[argc - 1]); - if(level == -1){ - printf("usage: %s (clear | safe | confidential | private)\n", - argv[0]); - code = -1; - return; - } + if(level == -1) + goto usage; if((*mech->check_prot)(app_data, level)) { printf("%s does not implement %s protection.\n", @@ -635,11 +671,21 @@ sec_prot(int argc, char **argv) return; } - if(sec_prot_internal(level) < 0){ - code = -1; - return; - } + if(argc == 2 || strncasecmp(argv[1], "data", strlen(argv[1])) == 0) { + if(sec_prot_internal(level) < 0){ + code = -1; + return; + } + } else if(strncasecmp(argv[1], "command", strlen(argv[1])) == 0) + set_command_prot(level); + else + goto usage; code = 0; + return; + usage: + printf("usage: %s [command|data] [clear|safe|confidential|private]\n", + argv[0]); + code = -1; } static enum protection_level request_data_prot; @@ -673,7 +719,15 @@ sec_login(char *host) are usually not very user friendly) */ for(m = mechs; *m && (*m)->name; m++) { - app_data = realloc(app_data, (*m)->size); + void *tmp; + + tmp = realloc(app_data, (*m)->size); + if (tmp == NULL) { + warnx ("realloc %u failed", (*m)->size); + return -1; + } + app_data = tmp; + if((*m)->init && (*(*m)->init)(app_data) != 0) { printf("Skipping %s...\n", (*m)->name); continue; @@ -721,6 +775,7 @@ sec_end(void) (*mech->end)(app_data); memset(app_data, 0, mech->size); free(app_data); + app_data = NULL; } sec_complete = 0; data_prot = (enum protection_level)0; diff --git a/crypto/kerberosIV/appl/ftp/ftp/security.h b/crypto/kerberosIV/appl/ftp/ftp/security.h index adac689..6fe0694 100644 --- a/crypto/kerberosIV/appl/ftp/ftp/security.h +++ b/crypto/kerberosIV/appl/ftp/ftp/security.h @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: security.h,v 1.3 1999/04/07 14:15:20 joda Exp $ */ +/* $Id: security.h,v 1.7 1999/12/02 16:58:30 joda Exp $ */ #ifndef __security_h__ #define __security_h__ @@ -105,6 +100,8 @@ int sec_putc (int, FILE *); int sec_read (int, void *, int); int sec_read_msg (char *, int); int sec_vfprintf (FILE *, const char *, va_list); +int sec_fprintf2(FILE *f, const char *fmt, ...); +int sec_vfprintf2(FILE *, const char *, va_list); int sec_write (int, char *, int); #ifdef FTP_SERVER @@ -118,6 +115,7 @@ void delete_ftp_command (void); void new_ftp_command (char *); int sec_userok (char *); int secure_command (void); +enum protection_level get_command_prot(void); #else void sec_end (void); int sec_login (char *); @@ -125,6 +123,9 @@ void sec_prot (int, char **); int sec_request_prot (char *); void sec_set_protection_level (void); void sec_status (void); + +enum protection_level set_command_prot(enum protection_level); + #endif #endif /* __security_h__ */ diff --git a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am index 187fca3..282cb3a 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am +++ b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.19 1999/04/25 13:24:55 assar Exp $ +# $Id: Makefile.am,v 1.20 1999/10/03 16:38:53 joda Exp $ include $(top_srcdir)/Makefile.am.common @@ -21,6 +21,7 @@ ftpd_SOURCES = \ ftpd.c \ ftpd_locl.h \ logwtmp.c \ + ls.c \ pathnames.h \ popen.c \ security.c \ diff --git a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in index 3b555a6..bc5c12e 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in +++ b/crypto/kerberosIV/appl/ftp/ftpd/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.40 1999/03/10 19:01:11 joda Exp $ +# $Id: Makefile.in,v 1.41 1999/10/03 16:39:27 joda Exp $ # srcdir = @srcdir@ @@ -47,8 +47,8 @@ LIBROKEN= -L$(LIBTOP)/roken -lroken PROGS = ftpd$(EXECSUFFIX) -ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c popen.c security.c krb4.c kauth.c -ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o security.o krb4.o kauth.o +ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c ls.c popen.c security.c krb4.c kauth.c +ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o ls.o popen.o security.o krb4.o kauth.o SOURCES = $(ftpd_SOURCES) OBJECTS = $(ftpd_OBJS) diff --git a/crypto/kerberosIV/appl/ftp/ftpd/extern.h b/crypto/kerberosIV/appl/ftp/ftpd/extern.h index e96809e..2e1e0d0 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/extern.h +++ b/crypto/kerberosIV/appl/ftp/ftpd/extern.h @@ -67,6 +67,8 @@ char **copyblk(char **); void cwd(char *); void do_delete(char *); void dologout(int); +void eprt(char *); +void epsv(char *); void fatal(char *); int filename_check(char *); int ftpd_pclose(FILE *); @@ -86,8 +88,8 @@ __attribute__ ((format (printf, 1, 2))) #endif ; void pass(char *); -void passive(void); -void perror_reply(int, char *); +void pasv(void); +void perror_reply(int, const char *); void pwd(void); void removedir(char *); void renamecmd(char *, char *); @@ -97,7 +99,7 @@ void reply(int, const char *, ...) __attribute__ ((format (printf, 2, 3))) #endif ; -void retrieve(char *, char *); +void retrieve(const char *, char *); void send_file_list(char *); void setproctitle(const char *, ...) #ifdef __GNUC__ @@ -111,6 +113,8 @@ void upper(char *); void user(char *); void yyerror(char *); +void list_file(char*); + void kauth(char *, char*); void klist(void); void cond_kdestroy(void); @@ -121,15 +125,17 @@ void afsunlog(void); int find(char *); +void builtin_ls(FILE*, const char*); + int do_login(int code, char *passwd); int klogin(char *name, char *password); const char *ftp_rooted(const char *path); -extern struct sockaddr_in ctrl_addr, his_addr; +extern struct sockaddr *ctrl_addr, *his_addr; extern char hostname[]; -extern struct sockaddr_in data_dest; +extern struct sockaddr *data_dest; extern int logged_in; extern struct passwd *pw; extern int guest; diff --git a/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y b/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y index be36ea2..07ff9a5 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y +++ b/crypto/kerberosIV/appl/ftp/ftpd/ftpcmd.y @@ -43,7 +43,7 @@ %{ #include "ftpd_locl.h" -RCSID("$Id: ftpcmd.y,v 1.48 1999/05/08 02:22:43 assar Exp $"); +RCSID("$Id: ftpcmd.y,v 1.56 1999/10/26 11:56:23 assar Exp $"); off_t restart_point; @@ -98,6 +98,7 @@ static int yylex (void); ABOR DELE CWD LIST NLST SITE sTAT HELP NOOP MKD RMD PWD CDUP STOU SMNT SYST SIZE MDTM + EPRT EPSV UMASK IDLE CHMOD @@ -105,7 +106,9 @@ static int yylex (void); CONF ENC KAUTH KLIST KDESTROY KRBTKFILE AFSLOG - FIND URL + LOCATE URL + + FEAT OPTS LEXERR @@ -151,9 +154,23 @@ cmd } reply(200, "PORT command successful."); } + | EPRT SP STRING CRLF + { + eprt ($3); + free ($3); + } | PASV CRLF { - passive(); + pasv (); + } + | EPSV CRLF + { + epsv (NULL); + } + | EPSV SP STRING CRLF + { + epsv ($3); + free ($3); } | TYPE SP type_code CRLF { @@ -224,24 +241,30 @@ cmd } | RETR SP pathname CRLF check_login { - if ($5 && $3 != NULL) - retrieve(0, $3); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + retrieve(0, name); + if (name != NULL) + free(name); } | STOR SP pathname CRLF check_login { - if ($5 && $3 != NULL) - do_store($3, "w", 0); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + do_store(name, "w", 0); + if (name != NULL) + free(name); } | APPE SP pathname CRLF check_login { - if ($5 && $3 != NULL) - do_store($3, "a", 0); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + do_store(name, "a", 0); + if (name != NULL) + free(name); } | NLST CRLF check_login { @@ -250,33 +273,23 @@ cmd } | NLST SP STRING CRLF check_login { - if ($5 && $3 != NULL) - send_file_list($3); - if ($3 != NULL) - free($3); + char *name = $3; + + if ($5 && name != NULL) + send_file_list(name); + if (name != NULL) + free(name); } | LIST CRLF check_login { -#ifdef HAVE_LS_A - char *cmd = "/bin/ls -lA"; -#else - char *cmd = "/bin/ls -la"; -#endif - if ($3) - retrieve(cmd, ""); - + if($3) + list_file("."); } | LIST SP pathname CRLF check_login { -#ifdef HAVE_LS_A - char *cmd = "/bin/ls -lA %s"; -#else - char *cmd = "/bin/ls -la %s"; -#endif - if ($5 && $3 != NULL) - retrieve(cmd, $3); - if ($3 != NULL) - free($3); + if($5) + list_file($3); + free($3); } | sTAT SP pathname CRLF check_login { @@ -388,6 +401,20 @@ cmd if ($3) cwd(".."); } + | FEAT CRLF + { + lreply(211, "Supported features:"); + lreply(0, " MDTM"); + lreply(0, " REST STREAM"); + lreply(0, " SIZE"); + reply(211, "End"); + } + | OPTS SP STRING CRLF + { + free ($3); + reply(501, "Bad options"); + } + | SITE SP HELP CRLF { help(sitetab, (char *) 0); @@ -522,16 +549,15 @@ cmd #ifdef KRB4 if(guest) reply(500, "Can't be done as guest."); - else if($7){ + else if($7) afslog($5); - } if($5) free($5); #else reply(500, "Command not implemented."); #endif } - | SITE SP FIND SP STRING CRLF check_login + | SITE SP LOCATE SP STRING CRLF check_login { if($7 && $5 != NULL) find($5); @@ -696,9 +722,11 @@ host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER { - data_dest.sin_family = AF_INET; - data_dest.sin_port = htons($9 * 256 + $11); - data_dest.sin_addr.s_addr = + struct sockaddr_in *sin = (struct sockaddr_in *)data_dest; + + sin->sin_family = AF_INET; + sin->sin_port = htons($9 * 256 + $11); + sin->sin_addr.s_addr = htonl(($1 << 24) | ($3 << 16) | ($5 << 8) | $7); } ; @@ -901,7 +929,9 @@ struct tab cmdtab[] = { /* In order defined in RFC 765 */ { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, + { "EPRT", EPRT, STR1, 1, "<sp> string" }, { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, + { "EPSV", EPSV, OSTR, 1, "[<sp> foo]" }, { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, { "STRU", STRU, ARGS, 1, "(specify file structure)" }, { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, @@ -952,6 +982,10 @@ struct tab cmdtab[] = { /* In order defined in RFC 765 */ { "CONF", CONF, STR1, 1, "<sp> confidentiality command" }, { "ENC", ENC, STR1, 1, "<sp> privacy command" }, + /* RFC2389 */ + { "FEAT", FEAT, ARGS, 1, "" }, + { "OPTS", OPTS, ARGS, 1, "<sp> command [<sp> options]" }, + { NULL, 0, 0, 0, 0 } }; @@ -967,7 +1001,8 @@ struct tab sitetab[] = { { "KRBTKFILE", KRBTKFILE, STR1, 1, "<sp> ticket-file" }, { "AFSLOG", AFSLOG, OSTR, 1, "[<sp> cell]" }, - { "FIND", FIND, STR1, 1, "<sp> globexpr" }, + { "LOCATE", LOCATE, STR1, 1, "<sp> globexpr" }, + { "FIND", LOCATE, STR1, 1, "<sp> globexpr" }, { "URL", URL, ARGS, 1, "?" }, @@ -996,7 +1031,7 @@ ftpd_getline(char *s, int n) cs = s; /* tmpline may contain saved command from urgent mode interruption */ if(ftp_command){ - strcpy_truncate(s, ftp_command, n); + strlcpy(s, ftp_command, n); if (debug) syslog(LOG_DEBUG, "command: %s", s); #ifdef XXX @@ -1162,7 +1197,10 @@ yylex(void) dostr1: if (cbuf[cpos] == ' ') { cpos++; - state = state == OSTR ? STR2 : ++state; + if(state == OSTR) + state = STR2; + else + state++; return (SP); } break; @@ -1335,7 +1373,7 @@ help(struct tab *ctab, char *s) columns = 1; lines = (NCMDS + columns - 1) / columns; for (i = 0; i < lines; i++) { - strcpy_truncate (buf, " ", sizeof(buf)); + strlcpy (buf, " ", sizeof(buf)); for (j = 0; j < columns; j++) { c = ctab + j * lines + i; snprintf (buf + strlen(buf), @@ -1347,13 +1385,13 @@ help(struct tab *ctab, char *s) break; w = strlen(c->name) + 1; while (w < width) { - strcat_truncate (buf, + strlcat (buf, " ", sizeof(buf)); w++; } } - lreply(214, buf); + lreply(214, "%s", buf); } reply(214, "Direct comments to kth-krb-bugs@pdc.kth.se"); return; diff --git a/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h b/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h index 4bb3ad3..5cb4904 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h +++ b/crypto/kerberosIV/appl/ftp/ftpd/ftpd_locl.h @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -36,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: ftpd_locl.h,v 1.5.2.1 1999/07/22 03:24:42 assar Exp $ */ +/* $Id: ftpd_locl.h,v 1.9 1999/12/02 16:58:30 joda Exp $ */ #ifndef __ftpd_locl_h__ #define __ftpd_locl_h__ @@ -63,6 +58,9 @@ #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40 #include <sys/ioctl.h> #endif +#ifdef HAVE_SYS_IOCCOM_H +#include <sys/ioccom.h> +#endif #ifdef TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> @@ -159,6 +157,10 @@ extern int LIBPREFIX(fclose) (FILE *); #endif +/* SunOS doesn't have any declaration of fclose */ + +int fclose(FILE *stream); + int yyparse(); #ifndef LOG_FTP diff --git a/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c b/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c index 8a1a8e3..28e3596 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/gss_userok.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -40,7 +35,7 @@ #include <gssapi.h> #include <krb5.h> -RCSID("$Id: gss_userok.c,v 1.1 1998/05/12 12:15:22 joda Exp $"); +RCSID("$Id: gss_userok.c,v 1.2 1999/12/02 16:58:31 joda Exp $"); /* XXX a bit too much of krb5 dependency here... What is the correct way to do this? diff --git a/crypto/kerberosIV/appl/ftp/ftpd/kauth.c b/crypto/kerberosIV/appl/ftp/ftpd/kauth.c index 33795b6..dad4de5 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/kauth.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/kauth.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +33,7 @@ #include "ftpd_locl.h" -RCSID("$Id: kauth.c,v 1.22 1999/06/29 21:19:33 bg Exp $"); +RCSID("$Id: kauth.c,v 1.25 1999/12/02 16:58:31 joda Exp $"); static KTEXT_ST cip; static unsigned int lifetime; @@ -85,7 +80,7 @@ store_ticket(KTEXT cip) return(INTK_BADPW); /* extract server's name */ - strcpy_truncate(sp.name, ptr, sizeof(sp.name)); + strlcpy(sp.name, ptr, sizeof(sp.name)); ptr += len + 1; left -= len + 1; @@ -94,7 +89,7 @@ store_ticket(KTEXT cip) return(INTK_BADPW); /* extract server's instance */ - strcpy_truncate(sp.instance, ptr, sizeof(sp.instance)); + strlcpy(sp.instance, ptr, sizeof(sp.instance)); ptr += len + 1; left -= len + 1; @@ -103,7 +98,7 @@ store_ticket(KTEXT cip) return(INTK_BADPW); /* extract server's realm */ - strcpy_truncate(sp.realm, ptr, sizeof(sp.realm)); + strlcpy(sp.realm, ptr, sizeof(sp.realm)); ptr += len + 1; left -= len + 1; @@ -176,6 +171,10 @@ kauth(char *principal, char *ticket) char *p; int ret; + if(get_command_prot() != prot_private) { + reply(500, "Request denied (bad protection level)"); + return; + } ret = krb_parse_name(principal, &pr); if(ret){ reply(500, "Bad principal: %s.", krb_get_err_text(ret)); @@ -304,12 +303,12 @@ klist(void) " Issued", " Expires", " Principal (kvno)"); header = 0; } - strcpy_truncate(buf1, short_date(c.issue_date), sizeof(buf1)); + strlcpy(buf1, short_date(c.issue_date), sizeof(buf1)); c.issue_date = krb_life_to_time(c.issue_date, c.lifetime); if (time(0) < (unsigned long) c.issue_date) - strcpy_truncate(buf2, short_date(c.issue_date), sizeof(buf2)); + strlcpy(buf2, short_date(c.issue_date), sizeof(buf2)); else - strcpy_truncate(buf2, ">>> Expired <<< ", sizeof(buf2)); + strlcpy(buf2, ">>> Expired <<< ", sizeof(buf2)); lreply(200, "%s %s %s (%d)", buf1, buf2, krb_unparse_name_long(c.service, c.instance, c.realm), c.kvno); } diff --git a/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c b/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c index d948a5a..019cc2d 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/logwtmp.c @@ -14,12 +14,7 @@ * 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 Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors + * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -38,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: logwtmp.c,v 1.13 1999/03/01 09:49:37 joda Exp $"); +RCSID("$Id: logwtmp.c,v 1.14 1999/12/02 16:58:31 joda Exp $"); #endif #include <stdio.h> diff --git a/crypto/kerberosIV/appl/ftp/ftpd/ls.c b/crypto/kerberosIV/appl/ftp/ftpd/ls.c new file mode 100644 index 0000000..97eb77e --- /dev/null +++ b/crypto/kerberosIV/appl/ftp/ftpd/ls.c @@ -0,0 +1,572 @@ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * 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. Neither the name of KTH 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 KTH AND ITS 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 KTH OR ITS 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. */ + +#include "ftpd_locl.h" + +RCSID("$Id: ls.c,v 1.13 1999/11/20 20:49:41 assar Exp $"); + +struct fileinfo { + struct stat st; + int inode; + int bsize; + char mode[11]; + int n_link; + char *user; + char *group; + char *size; + char *major; + char *minor; + char *date; + char *filename; + char *link; +}; + +#define LS_DIRS 1 +#define LS_IGNORE_DOT 2 +#define LS_SORT_MODE 12 +#define SORT_MODE(f) ((f) & LS_SORT_MODE) +#define LS_SORT_NAME 4 +#define LS_SORT_MTIME 8 +#define LS_SORT_SIZE 12 +#define LS_SORT_REVERSE 16 + +#define LS_SIZE 32 +#define LS_INODE 64 + +#ifndef S_ISTXT +#define S_ISTXT S_ISVTX +#endif + +#ifndef S_ISSOCK +#define S_ISSOCK(mode) (((mode) & _S_IFMT) == S_IFSOCK) +#endif + +#ifndef S_ISLNK +#define S_ISLNK(mode) (((mode) & _S_IFMT) == S_IFLNK) +#endif + +static void +make_fileinfo(const char *filename, struct fileinfo *file, int flags) +{ + char buf[128]; + struct stat *st = &file->st; + + file->inode = st->st_ino; +#ifdef S_BLKSIZE + file->bsize = st->st_blocks * S_BLKSIZE / 1024; +#else + file->bsize = st->st_blocks * 512 / 1024; +#endif + + if(S_ISDIR(st->st_mode)) + file->mode[0] = 'd'; + else if(S_ISCHR(st->st_mode)) + file->mode[0] = 'c'; + else if(S_ISBLK(st->st_mode)) + file->mode[0] = 'b'; + else if(S_ISREG(st->st_mode)) + file->mode[0] = '-'; + else if(S_ISFIFO(st->st_mode)) + file->mode[0] = 'p'; + else if(S_ISLNK(st->st_mode)) + file->mode[0] = 'l'; + else if(S_ISSOCK(st->st_mode)) + file->mode[0] = 's'; +#ifdef S_ISWHT + else if(S_ISWHT(st->st_mode)) + file->mode[0] = 'w'; +#endif + else + file->mode[0] = '?'; + { + char *x[] = { "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx" }; + strcpy(file->mode + 1, x[(st->st_mode & S_IRWXU) >> 6]); + strcpy(file->mode + 4, x[(st->st_mode & S_IRWXG) >> 3]); + strcpy(file->mode + 7, x[(st->st_mode & S_IRWXO) >> 0]); + if((st->st_mode & S_ISUID)) { + if((st->st_mode & S_IXUSR)) + file->mode[3] = 's'; + else + file->mode[3] = 'S'; + } + if((st->st_mode & S_ISGID)) { + if((st->st_mode & S_IXGRP)) + file->mode[6] = 's'; + else + file->mode[6] = 'S'; + } + if((st->st_mode & S_ISTXT)) { + if((st->st_mode & S_IXOTH)) + file->mode[9] = 't'; + else + file->mode[9] = 'T'; + } + } + file->n_link = st->st_nlink; + { + struct passwd *pwd; + pwd = getpwuid(st->st_uid); + if(pwd == NULL) + asprintf(&file->user, "%u", (unsigned)st->st_uid); + else + file->user = strdup(pwd->pw_name); + } + { + struct group *grp; + grp = getgrgid(st->st_gid); + if(grp == NULL) + asprintf(&file->group, "%u", (unsigned)st->st_gid); + else + file->group = strdup(grp->gr_name); + } + + if(S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) { +#if defined(major) && defined(minor) + asprintf(&file->major, "%u", (unsigned)major(st->st_rdev)); + asprintf(&file->minor, "%u", (unsigned)minor(st->st_rdev)); +#else + /* Don't want to use the DDI/DKI crap. */ + asprintf(&file->major, "%u", (unsigned)st->st_rdev); + asprintf(&file->minor, "%u", 0); +#endif + } else + asprintf(&file->size, "%lu", (unsigned long)st->st_size); + + { + time_t t = time(NULL); + struct tm *tm = localtime(&st->st_mtime); + if((t - st->st_mtime > 6*30*24*60*60) || + (st->st_mtime - t > 6*30*24*60*60)) + strftime(buf, sizeof(buf), "%b %e %Y", tm); + else + strftime(buf, sizeof(buf), "%b %e %H:%M", tm); + file->date = strdup(buf); + } + { + const char *p = strrchr(filename, '/'); + if(p) + p++; + else + p = filename; + file->filename = strdup(p); + } + if(S_ISLNK(st->st_mode)) { + int n; + n = readlink((char *)filename, buf, sizeof(buf)); + if(n >= 0) { + buf[n] = '\0'; + file->link = strdup(buf); + } else + warn("%s: readlink", filename); + } +} + +static void +print_file(FILE *out, + int flags, + struct fileinfo *f, + int max_inode, + int max_bsize, + int max_n_link, + int max_user, + int max_group, + int max_size, + int max_major, + int max_minor, + int max_date) +{ + if(f->filename == NULL) + return; + + if(flags & LS_INODE) { + sec_fprintf2(out, "%*d", max_inode, f->inode); + sec_fprintf2(out, " "); + } + if(flags & LS_SIZE) { + sec_fprintf2(out, "%*d", max_bsize, f->bsize); + sec_fprintf2(out, " "); + } + sec_fprintf2(out, "%s", f->mode); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%*d", max_n_link, f->n_link); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%-*s", max_user, f->user); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%-*s", max_group, f->group); + sec_fprintf2(out, " "); + if(f->major != NULL && f->minor != NULL) + sec_fprintf2(out, "%*s, %*s", max_major, f->major, max_minor, f->minor); + else + sec_fprintf2(out, "%*s", max_size, f->size); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%*s", max_date, f->date); + sec_fprintf2(out, " "); + sec_fprintf2(out, "%s", f->filename); + if(f->link) + sec_fprintf2(out, " -> %s", f->link); + sec_fprintf2(out, "\r\n"); +} + +static int +compare_filename(struct fileinfo *a, struct fileinfo *b) +{ + if(a->filename == NULL) + return 1; + if(b->filename == NULL) + return -1; + return strcmp(a->filename, b->filename); +} + +static int +compare_mtime(struct fileinfo *a, struct fileinfo *b) +{ + if(a->filename == NULL) + return 1; + if(b->filename == NULL) + return -1; + return a->st.st_mtime - b->st.st_mtime; +} + +static int +compare_size(struct fileinfo *a, struct fileinfo *b) +{ + if(a->filename == NULL) + return 1; + if(b->filename == NULL) + return -1; + return a->st.st_size - b->st.st_size; +} + +static void +list_dir(FILE *out, const char *directory, int flags); + +static int +log10(int num) +{ + int i = 1; + while(num > 10) { + i++; + num /= 10; + } + return i; +} + +/* + * Operate as lstat but fake up entries for AFS mount points so we don't + * have to fetch them. + */ + +static int +lstat_file (const char *file, struct stat *sb) +{ +#ifdef KRB4 + if (k_hasafs() + && strcmp(file, ".") + && strcmp(file, "..")) + { + struct ViceIoctl a_params; + char *last; + char *path_bkp; + static ino_t ino_counter = 0, ino_last = 0; + int ret; + const int maxsize = 2048; + + path_bkp = strdup (file); + if (path_bkp == NULL) + return -1; + + a_params.out = malloc (maxsize); + if (a_params.out == NULL) { + free (path_bkp); + return -1; + } + + /* If path contains more than the filename alone - split it */ + + last = strrchr (path_bkp, '/'); + if (last != NULL) { + *last = '\0'; + a_params.in = last + 1; + } else + a_params.in = (char *)file; + + a_params.in_size = strlen (a_params.in) + 1; + a_params.out_size = maxsize; + + ret = k_pioctl (last ? path_bkp : "." , + VIOC_AFS_STAT_MT_PT, &a_params, 0); + free (a_params.out); + if (ret < 0) { + free (path_bkp); + + if (errno != EINVAL) + return ret; + else + /* if we get EINVAL this is probably not a mountpoint */ + return lstat (file, sb); + } + + /* + * wow this was a mountpoint, lets cook the struct stat + * use . as a prototype + */ + + ret = lstat (path_bkp, sb); + free (path_bkp); + if (ret < 0) + return ret; + + if (ino_last == sb->st_ino) + ino_counter++; + else { + ino_last = sb->st_ino; + ino_counter = 0; + } + sb->st_ino += ino_counter; + sb->st_nlink = 3; + + return 0; + } +#endif /* KRB4 */ + return lstat (file, sb); +} + +static void +list_files(FILE *out, char **files, int n_files, int flags) +{ + struct fileinfo *fi; + int i; + + fi = calloc(n_files, sizeof(*fi)); + if (fi == NULL) { + sec_fprintf2(out, "ouf of memory\r\n"); + return; + } + for(i = 0; i < n_files; i++) { + if(lstat_file(files[i], &fi[i].st) < 0) { + sec_fprintf2(out, "%s: %s\r\n", files[i], strerror(errno)); + fi[i].filename = NULL; + } else { + if((flags & LS_DIRS) == 0 && S_ISDIR(fi[i].st.st_mode)) { + if(n_files > 1) + sec_fprintf2(out, "%s:\r\n", files[i]); + list_dir(out, files[i], flags); + } else { + make_fileinfo(files[i], &fi[i], flags); + } + } + } + switch(SORT_MODE(flags)) { + case LS_SORT_NAME: + qsort(fi, n_files, sizeof(*fi), + (int (*)(const void*, const void*))compare_filename); + break; + case LS_SORT_MTIME: + qsort(fi, n_files, sizeof(*fi), + (int (*)(const void*, const void*))compare_mtime); + break; + case LS_SORT_SIZE: + qsort(fi, n_files, sizeof(*fi), + (int (*)(const void*, const void*))compare_size); + break; + } + { + int max_inode = 0; + int max_bsize = 0; + int max_n_link = 0; + int max_user = 0; + int max_group = 0; + int max_size = 0; + int max_major = 0; + int max_minor = 0; + int max_date = 0; + for(i = 0; i < n_files; i++) { + if(fi[i].filename == NULL) + continue; + if(fi[i].inode > max_inode) + max_inode = fi[i].inode; + if(fi[i].bsize > max_bsize) + max_bsize = fi[i].bsize; + if(fi[i].n_link > max_n_link) + max_n_link = fi[i].n_link; + if(strlen(fi[i].user) > max_user) + max_user = strlen(fi[i].user); + if(strlen(fi[i].group) > max_group) + max_group = strlen(fi[i].group); + if(fi[i].major != NULL && strlen(fi[i].major) > max_major) + max_major = strlen(fi[i].major); + if(fi[i].minor != NULL && strlen(fi[i].minor) > max_minor) + max_minor = strlen(fi[i].minor); + if(fi[i].size != NULL && strlen(fi[i].size) > max_size) + max_size = strlen(fi[i].size); + if(strlen(fi[i].date) > max_date) + max_date = strlen(fi[i].date); + } + if(max_size < max_major + max_minor + 2) + max_size = max_major + max_minor + 2; + else if(max_size - max_minor - 2 > max_major) + max_major = max_size - max_minor - 2; + max_inode = log10(max_inode); + max_bsize = log10(max_bsize); + max_n_link = log10(max_n_link); + + if(flags & LS_SORT_REVERSE) + for(i = n_files - 1; i >= 0; i--) + print_file(out, + flags, + &fi[i], + max_inode, + max_bsize, + max_n_link, + max_user, + max_group, + max_size, + max_major, + max_minor, + max_date); + else + for(i = 0; i < n_files; i++) + print_file(out, + flags, + &fi[i], + max_inode, + max_bsize, + max_n_link, + max_user, + max_group, + max_size, + max_major, + max_minor, + max_date); + } +} + +static void +free_files (char **files, int n) +{ + int i; + + for (i = 0; i < n; ++i) + free (files[i]); + free (files); +} + +static void +list_dir(FILE *out, const char *directory, int flags) +{ + DIR *d = opendir(directory); + struct dirent *ent; + char **files = NULL; + int n_files = 0; + + if(d == NULL) { + sec_fprintf2(out, "%s: %s\r\n", directory, strerror(errno)); + return; + } + while((ent = readdir(d)) != NULL) { + void *tmp; + + if(ent->d_name[0] == '.') { + if (flags & LS_IGNORE_DOT) + continue; + if (ent->d_name[1] == 0) /* Ignore . */ + continue; + if (ent->d_name[1] == '.' && ent->d_name[2] == 0) /* Ignore .. */ + continue; + } + tmp = realloc(files, (n_files + 1) * sizeof(*files)); + if (tmp == NULL) { + sec_fprintf2(out, "%s: out of memory\r\n", directory); + free_files (files, n_files); + closedir (d); + return; + } + files = tmp; + asprintf(&files[n_files], "%s/%s", directory, ent->d_name); + if (files[n_files] == NULL) { + sec_fprintf2(out, "%s: out of memory\r\n", directory); + free_files (files, n_files); + closedir (d); + return; + } + ++n_files; + } + closedir(d); + list_files(out, files, n_files, flags | LS_DIRS); +} + +void +builtin_ls(FILE *out, const char *file) +{ + int flags = LS_SORT_NAME; + + if(*file == '-') { + const char *p; + for(p = file + 1; *p; p++) { + switch(*p) { + case 'a': + case 'A': + flags &= ~LS_IGNORE_DOT; + break; + case 'C': + break; + case 'd': + flags |= LS_DIRS; + break; + case 'f': + flags = (flags & ~LS_SORT_MODE); + break; + case 'i': + flags |= flags | LS_INODE; + break; + case 'l': + break; + case 't': + flags = (flags & ~LS_SORT_MODE) | LS_SORT_MTIME; + break; + case 's': + flags |= LS_SIZE; + break; + case 'S': + flags = (flags & ~LS_SORT_MODE) | LS_SORT_SIZE; + break; + case 'r': + flags |= LS_SORT_REVERSE; + break; + } + } + file = "."; + } + list_files(out, &file, 1, flags); + sec_fflush(out); +} diff --git a/crypto/kerberosIV/appl/ftp/ftpd/popen.c b/crypto/kerberosIV/appl/ftp/ftpd/popen.c index 4bd5e04..5f36813 100644 --- a/crypto/kerberosIV/appl/ftp/ftpd/popen.c +++ b/crypto/kerberosIV/appl/ftp/ftpd/popen.c @@ -37,7 +37,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: popen.c,v 1.18 1998/06/09 19:24:24 joda Exp $"); +RCSID("$Id: popen.c,v 1.19 1999/09/16 20:38:45 assar Exp $"); #endif #include <sys/types.h> @@ -89,10 +89,10 @@ ftp_rooted(const char *path) if(!home[0]) if((pwd = k_getpwnam("ftp"))) - strcpy_truncate(home, pwd->pw_dir, sizeof(home)); + strlcpy(home, pwd->pw_dir, sizeof(home)); snprintf(newpath, sizeof(newpath), "%s/%s", home, path); if(access(newpath, X_OK)) - strcpy_truncate(newpath, path, sizeof(newpath)); + strlcpy(newpath, path, sizeof(newpath)); return newpath; } |