Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/ftp Forbid filenames returned from mget that aren't ...



details:   https://anonhg.NetBSD.org/src/rev/0e8b08fd492e
branches:  trunk
changeset: 572452:0e8b08fd492e
user:      lukem <lukem%NetBSD.org@localhost>
date:      Mon Jan 03 09:50:09 2005 +0000

description:
Forbid filenames returned from mget that aren't in (or below) the
current directory.
The previous behaviour (of trusting the remote server's response when
retrieving the list of files to mget with prompting disabled) has been
in ftp ~forever, and has been a "known issue" for a long time.
Recently an advisory was published by D.J. Bernstein on behalf of
Yosef Klein warning of the problems with the previous behaviour, so
to alleviate concern I've fixed this with a sledgehammer.

Remember the local cwd after any operation which may change it.
Use "remotecwd" instead of "remotepwd".

diffstat:

 usr.bin/ftp/cmds.c    |  68 ++++++++++++++++++++++++++--------------------
 usr.bin/ftp/extern.h  |   8 +++--
 usr.bin/ftp/ftp_var.h |   7 ++--
 usr.bin/ftp/util.c    |  74 ++++++++++++++++++++++++++++++++++++++------------
 usr.bin/ftp/version.h |   6 ++--
 5 files changed, 106 insertions(+), 57 deletions(-)

diffs (truncated from 365 to 300 lines):

diff -r e7fb5a934de0 -r 0e8b08fd492e usr.bin/ftp/cmds.c
--- a/usr.bin/ftp/cmds.c        Mon Jan 03 06:15:42 2005 +0000
+++ b/usr.bin/ftp/cmds.c        Mon Jan 03 09:50:09 2005 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: cmds.c,v 1.108 2004/10/30 17:36:31 dsl Exp $   */
+/*     $NetBSD: cmds.c,v 1.109 2005/01/03 09:50:09 lukem Exp $ */
 
 /*-
- * Copyright (c) 1996-2004 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -103,7 +103,7 @@
 #if 0
 static char sccsid[] = "@(#)cmds.c     8.6 (Berkeley) 10/9/94";
 #else
-__RCSID("$NetBSD: cmds.c,v 1.108 2004/10/30 17:36:31 dsl Exp $");
+__RCSID("$NetBSD: cmds.c,v 1.109 2005/01/03 09:50:09 lukem Exp $");
 #endif
 #endif /* not lint */
 
@@ -691,7 +691,14 @@
                        mflag = 0;
                        continue;
                }
-               if (! mflag || !confirm(argv[0], cp))
+               if (! mflag)
+                       continue;
+               if (! fileindir(cp, localcwd)) {
+                       fprintf(ttyout, "Skipping non-relative filename `%s'\n",
+                           cp);
+                       continue;
+               }
+               if (!confirm(argv[0], cp))
                        continue;
                tp = cp;
                if (mcase)
@@ -1133,7 +1140,7 @@
        }
        if (r == COMPLETE) {
                dirchange = 1;
-               updateremotepwd();
+               updateremotecwd();
        }
 }
 
@@ -1143,7 +1150,6 @@
 void
 lcd(int argc, char *argv[])
 {
-       char buf[MAXPATHLEN];
        char *locdir;
 
        code = -1;
@@ -1157,14 +1163,16 @@
        }
        if ((locdir = globulize(argv[1])) == NULL)
                return;
-       if (chdir(locdir) < 0)
-               warn("local: %s", locdir);
+       if (chdir(locdir) == -1)
+               warn("lcd %s", locdir);
        else {
-               if (getcwd(buf, sizeof(buf)) != NULL) {
-                       fprintf(ttyout, "Local directory now %s\n", buf);
+               updatelocalcwd();
+               if (localcwd[0]) {
+                       fprintf(ttyout, "Local directory now: %s\n", localcwd);
                        code = 0;
-               } else
-                       warn("getcwd: %s", locdir);
+               } else {
+                       fprintf(ttyout, "Unable to determine local directory\n");
+               }
        }
        (void)free(locdir);
 }
@@ -1176,7 +1184,6 @@
 delete(int argc, char *argv[])
 {
 
-
        if (argc == 0 || argc > 2 ||
            (argc == 1 && !another(&argc, &argv, "remote-file"))) {
                fprintf(ttyout, "usage: %s remote-file\n", argv[0]);
@@ -1512,19 +1519,20 @@
 void
 pwd(int argc, char *argv[])
 {
-       int oldverbose = verbose;
 
-       if (argc == 0) {
+       code = -1;
+       if (argc != 1) {
                fprintf(ttyout, "usage: %s\n", argv[0]);
-               code = -1;
                return;
        }
-       verbose = 1;    /* If we aren't verbose, this doesn't do anything! */
-       if (command("PWD") == ERROR && code == 500) {
-               fputs("PWD command not recognized, trying XPWD.\n", ttyout);
-               (void)command("XPWD");
+       if (! remotecwd[0])
+               updateremotecwd();
+       if (! remotecwd[0])
+               fprintf(ttyout, "Unable to determine remote directory\n");
+       else {
+               fprintf(ttyout, "Remote directory: %s\n", remotecwd);
+               code = 0;
        }
-       verbose = oldverbose;
 }
 
 /*
@@ -1533,19 +1541,19 @@
 void
 lpwd(int argc, char *argv[])
 {
-       char buf[MAXPATHLEN];
 
-       if (argc == 0) {
+       code = -1;
+       if (argc != 1) {
                fprintf(ttyout, "usage: %s\n", argv[0]);
-               code = -1;
                return;
        }
-       if (getcwd(buf, sizeof(buf)) != NULL) {
-               fprintf(ttyout, "Local directory %s\n", buf);
+       if (! localcwd[0])
+               updatelocalcwd();
+       if (! localcwd[0])
+               fprintf(ttyout, "Unable to determine local directory\n");
+       else {
+               fprintf(ttyout, "Local directory: %s\n", localcwd);
                code = 0;
-       } else {
-               warn("getcwd");
-               code = -1;
        }
 }
 
@@ -2311,7 +2319,7 @@
        }
        if (r == COMPLETE) {
                dirchange = 1;
-               updateremotepwd();
+               updateremotecwd();
        }
 }
 
diff -r e7fb5a934de0 -r 0e8b08fd492e usr.bin/ftp/extern.h
--- a/usr.bin/ftp/extern.h      Mon Jan 03 06:15:42 2005 +0000
+++ b/usr.bin/ftp/extern.h      Mon Jan 03 09:50:09 2005 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: extern.h,v 1.62 2003/08/07 11:13:54 agc Exp $  */
+/*     $NetBSD: extern.h,v 1.63 2005/01/03 09:50:09 lukem Exp $        */
 
 /*-
- * Copyright (c) 1996-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -136,6 +136,7 @@
 char   *dotrans(char *);
 void   feat(int, char **);
 void   fget(int, char **);
+int    fileindir(const char *, const char *);
 int    foregroundproc(void);
 void   formatbuf(char *, size_t, const char *);
 void   ftpvis(char *, size_t, const char *, size_t);
@@ -246,7 +247,8 @@
 void   syst(int, char **);
 int    togglevar(int, char **, int *, const char *);
 void   unsetoption(int, char **);
-void   updateremotepwd(void);
+void   updatelocalcwd(void);
+void   updateremotecwd(void);
 void   usage(void);
 void   user(int, char **);
 int    xconnect(int, const struct sockaddr *, int);
diff -r e7fb5a934de0 -r 0e8b08fd492e usr.bin/ftp/ftp_var.h
--- a/usr.bin/ftp/ftp_var.h     Mon Jan 03 06:15:42 2005 +0000
+++ b/usr.bin/ftp/ftp_var.h     Mon Jan 03 09:50:09 2005 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: ftp_var.h,v 1.68 2004/07/21 00:09:14 lukem Exp $       */
+/*     $NetBSD: ftp_var.h,v 1.69 2005/01/03 09:50:09 lukem Exp $       */
 
 /*-
- * Copyright (c) 1996-2004 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996-2005 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -269,7 +269,8 @@
 GLOBAL char   *hostname;       /* name of host connected to */
 GLOBAL int     unix_server;    /* server is unix, can use binary for ascii */
 GLOBAL int     unix_proxy;     /* proxy is unix, can use binary for ascii */
-GLOBAL char    remotepwd[MAXPATHLEN];  /* remote dir */
+GLOBAL char    localcwd[MAXPATHLEN];   /* local dir */
+GLOBAL char    remotecwd[MAXPATHLEN];  /* remote dir */
 GLOBAL char   *username;       /* name of user logged in as. (dynamic) */
 
 GLOBAL sa_family_t family;     /* address family to use for connections */
diff -r e7fb5a934de0 -r 0e8b08fd492e usr.bin/ftp/util.c
--- a/usr.bin/ftp/util.c        Mon Jan 03 06:15:42 2005 +0000
+++ b/usr.bin/ftp/util.c        Mon Jan 03 09:50:09 2005 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: util.c,v 1.116 2004/07/20 10:40:22 lukem Exp $ */
+/*     $NetBSD: util.c,v 1.117 2005/01/03 09:50:09 lukem Exp $ */
 
 /*-
- * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2005 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -71,13 +71,13 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: util.c,v 1.116 2004/07/20 10:40:22 lukem Exp $");
+__RCSID("$NetBSD: util.c,v 1.117 2005/01/03 09:50:09 lukem Exp $");
 #endif /* not lint */
 
 /*
  * FTP User Program -- Misc support routines
  */
-#include <sys/types.h>
+#include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
@@ -478,7 +478,8 @@
                        break;
                }
        }
-       updateremotepwd();
+       updatelocalcwd();
+       updateremotecwd();
 
  cleanup_ftp_login:
        if (user != NULL && freeuser)
@@ -773,10 +774,23 @@
 }
 
 /*
- * update global `remotepwd', which contains the state of the remote cwd
+ * Update global `localcwd', which contains the state of the local cwd
  */
 void
-updateremotepwd(void)
+updatelocalcwd(void)
+{
+
+       if (getcwd(localcwd, sizeof(localcwd)) == NULL)
+               localcwd[0] = '\0';
+       if (debug)
+               fprintf(ttyout, "got localcwd as `%s'\n", localcwd);
+}
+
+/*
+ * Update global `remotecwd', which contains the state of the remote cwd
+ */
+void
+updateremotecwd(void)
 {
        int      overbose, ocode, i;
        char    *cp;
@@ -786,31 +800,55 @@
        if (debug == 0)
                verbose = -1;
        if (command("PWD") != COMPLETE)
-               goto badremotepwd;
+               goto badremotecwd;
        cp = strchr(reply_string, ' ');
        if (cp == NULL || cp[0] == '\0' || cp[1] != '"')
-               goto badremotepwd;
+               goto badremotecwd;
        cp += 2;
-       for (i = 0; *cp && i < sizeof(remotepwd) - 1; i++, cp++) {
+       for (i = 0; *cp && i < sizeof(remotecwd) - 1; i++, cp++) {
                if (cp[0] == '"') {
                        if (cp[1] == '"')
                                cp++;
                        else
                                break;
                }
-               remotepwd[i] = *cp;
+               remotecwd[i] = *cp;
        }
-       remotepwd[i] = '\0';
+       remotecwd[i] = '\0';
        if (debug)
-               fprintf(ttyout, "got remotepwd as `%s'\n", remotepwd);
-       goto cleanupremotepwd;
- badremotepwd:
-       remotepwd[0]='\0';



Home | Main Index | Thread Index | Old Index