Source-Changes-HG archive

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

[src/trunk]: src/libexec/tftpd Patrick Welche <prlw1%cam.ac.uk@localhost>



details:   https://anonhg.NetBSD.org/src/rev/207ce6e55b6a
branches:  trunk
changeset: 750631:207ce6e55b6a
user:      christos <christos%NetBSD.org@localhost>
date:      Fri Jan 08 21:05:14 2010 +0000

description:
Patrick Welche <prlw1%cam.ac.uk@localhost>
    - add -p pathsep option
    - make wrap to zero work, but produce a warning
While here:
    - fix gcc warnings, in particular variable clobbered warnings
      (compiling with fewer warnings does not really fix the problem)

diffstat:

 libexec/tftpd/Makefile |    4 +-
 libexec/tftpd/tftpd.8  |   22 ++++++--
 libexec/tftpd/tftpd.c  |  120 +++++++++++++++++++++++++++++-------------------
 3 files changed, 91 insertions(+), 55 deletions(-)

diffs (truncated from 376 to 300 lines):

diff -r 4b44544894c2 -r 207ce6e55b6a libexec/tftpd/Makefile
--- a/libexec/tftpd/Makefile    Fri Jan 08 19:53:10 2010 +0000
+++ b/libexec/tftpd/Makefile    Fri Jan 08 21:05:14 2010 +0000
@@ -1,7 +1,7 @@
-#      $NetBSD: Makefile,v 1.12 2009/03/16 02:24:57 lukem Exp $
+#      $NetBSD: Makefile,v 1.13 2010/01/08 21:05:14 christos Exp $
 #      from: @(#)Makefile      8.1 (Berkeley) 6/4/93
 
-WARNS?=        2               # XXX: setjmp clobber warnings
+WARNS?=        5
 
 .include <bsd.own.mk>
 
diff -r 4b44544894c2 -r 207ce6e55b6a libexec/tftpd/tftpd.8
--- a/libexec/tftpd/tftpd.8     Fri Jan 08 19:53:10 2010 +0000
+++ b/libexec/tftpd/tftpd.8     Fri Jan 08 21:05:14 2010 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: tftpd.8,v 1.21 2003/08/07 09:46:53 agc Exp $
+.\"    $NetBSD: tftpd.8,v 1.22 2010/01/08 21:05:14 christos Exp $
 .\"
 .\" Copyright (c) 1983, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"    from: @(#)tftpd.8       8.1 (Berkeley) 6/4/93
 .\"
-.Dd June 11, 2003
+.Dd January 8, 2010
 .Dt TFTPD 8
 .Os
 .Sh NAME
@@ -43,6 +43,7 @@
 .Op Fl g Ar group
 .Op Fl l
 .Op Fl n
+.Op Fl p Ar path separator
 .Op Fl s Ar directory
 .Op Fl u Ar user
 .Op Ar directory ...
@@ -107,6 +108,11 @@
 .It Fl n
 Suppresses negative acknowledgement of requests for nonexistent
 relative filenames.
+.It Fl p Ar path separator
+All occurances of the single character
+.Ar path separator
+in the requested filename are replaced with
+.Sq / .
 .It Fl s Ar directory
 .Nm
 will
@@ -193,11 +199,15 @@
 and first appeared in
 .Nx 2.0 .
 .Sh BUGS
-Files larger than 33488896 octets (65535 blocks) cannot be transferred
-without client and server supporting blocksize negotiation (RFCs
-2347 and 2348).
+Files larger than 33,553,919 octets (65535 blocks, last one <512
+octets) cannot be correctly transferred without client and server
+supporting blocksize negotiation (RFCs 2347 and 2348). As a kludge,
+.Nm
+accepts a sequence of block numbers which wrap to zero after 65535.
 .Pp
-Many tftp clients will not transfer files over 16744448 octets (32767 blocks).
+Many tftp clients will not transfer files over 16,776,703 octets
+(32767 blocks), as they incorrectly count the block number using
+a signed rather than unsigned 16-bit integer.
 .Sh SECURITY CONSIDERATIONS
 You are
 .Em strongly
diff -r 4b44544894c2 -r 207ce6e55b6a libexec/tftpd/tftpd.c
--- a/libexec/tftpd/tftpd.c     Fri Jan 08 19:53:10 2010 +0000
+++ b/libexec/tftpd/tftpd.c     Fri Jan 08 21:05:14 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tftpd.c,v 1.32 2009/03/16 01:56:21 lukem Exp $ */
+/*     $NetBSD: tftpd.c,v 1.33 2010/01/08 21:05:14 christos Exp $      */
 
 /*
  * Copyright (c) 1983, 1993
@@ -36,7 +36,7 @@
 #if 0
 static char sccsid[] = "@(#)tftpd.c    8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: tftpd.c,v 1.32 2009/03/16 01:56:21 lukem Exp $");
+__RCSID("$NetBSD: tftpd.c,v 1.33 2010/01/08 21:05:14 christos Exp $");
 #endif
 #endif /* not lint */
 
@@ -77,20 +77,20 @@
 
 #define        TIMEOUT         5
 
-int    peer;
-int    rexmtval = TIMEOUT;
-int    maxtimeout = 5*TIMEOUT;
+static int     peer;
+static int     rexmtval = TIMEOUT;
+static int     maxtimeout = 5*TIMEOUT;
 
-char   buf[MAXPKTSIZE];
-char   ackbuf[PKTSIZE];
-char   oackbuf[PKTSIZE];
-struct sockaddr_storage from;
-socklen_t      fromlen;
-int    debug;
+static char    buf[MAXPKTSIZE];
+static char    ackbuf[PKTSIZE];
+static char    oackbuf[PKTSIZE];
+static struct  sockaddr_storage from;
+static socklen_t       fromlen;
+static int     debug;
 
-int    tftp_opt_tsize = 0;
-int    tftp_blksize = SEGSIZE;
-int    tftp_tsize = 0;
+static int     tftp_opt_tsize = 0;
+static int     tftp_blksize = SEGSIZE;
+static int     tftp_tsize = 0;
 
 /*
  * Null-terminated directory prefix list for absolute pathname requests and
@@ -107,24 +107,24 @@
 static int     suppress_naks;
 static int     logging;
 static int     secure;
+static char    pathsep = '\0';
 static char    *securedir;
 
 struct formats;
 
 static const char *errtomsg(int);
-static void     nak(int);
-static void     tftp(struct tftphdr *, int);
-static void     usage(void);
+static void    nak(int);
+static void    tftp(struct tftphdr *, int);
+static void    usage(void) __attribute__((__noreturn__));
 static char    *verifyhost(struct sockaddr *);
-void   justquit(int);
-int    main(int, char **);
-void   recvfile(struct formats *, int, int);
-void   sendfile(struct formats *, int, int);
-void   timer(int);
+static void    justquit(int);
+static void    recvfile(struct formats *, int, int);
+static void    sendfile(struct formats *, int, int);
+static void    timer(int);
 static const char *opcode(int);
-int    validate_access(char **, int);
+static int     validate_access(char **, int);
 
-struct formats {
+static struct formats {
        const char      *f_mode;
        int             (*f_validate)(char **, int);
        void            (*f_send)(struct formats *, int, int);
@@ -133,7 +133,7 @@
 } formats[] = {
        { "netascii",   validate_access,        sendfile,       recvfile, 1 },
        { "octet",      validate_access,        sendfile,       recvfile, 0 },
-       { 0 }
+       { .f_mode = NULL }
 };
 
 static void
@@ -141,7 +141,7 @@
 {
 
        syslog(LOG_ERR,
-    "Usage: %s [-dln] [-u user] [-g group] [-s directory] [directory ...]",
+    "Usage: %s [-dln] [-u user] [-g group] [-s directory] [-p pathsep] [directory ...]",
                    getprogname());
        exit(1);
 }
@@ -153,7 +153,8 @@
        struct passwd   *pwent;
        struct group    *grent;
        struct tftphdr  *tp;
-       char            *tgtuser, *tgtgroup, *ep;
+       const char      *tgtuser, *tgtgroup;
+       char *ep;
        int     n, ch, on, fd;
        int     soopt;
        socklen_t len;
@@ -170,7 +171,7 @@
        curuid = getuid();
        curgid = getgid();
 
-       while ((ch = getopt(argc, argv, "dg:lns:u:")) != -1)
+       while ((ch = getopt(argc, argv, "dg:lnp:s:u:w:")) != -1)
                switch (ch) {
                case 'd':
                        debug++;
@@ -188,6 +189,12 @@
                        suppress_naks = 1;
                        break;
 
+               case 'p':
+                       if (optarg[0] == '\0' || optarg[1] != '\0')
+                               usage();
+                       pathsep = optarg[0];
+                       break;
+
                case 's':
                        secure = 1;
                        securedir = optarg;
@@ -536,15 +543,15 @@
        return 0;
 }
 
-struct tftp_options {
-       char *o_name;
+static const struct tftp_options {
+       const char *o_name;
        int (*o_handler)(struct tftphdr *, char *, char *, char *,
                         int *, int *);
 } options[] = {
        { "blksize", blk_handler },
        { "timeout", timeout_handler },
        { "tsize", tsize_handler },
-       { NULL, NULL }
+       { .o_name = NULL }
 };
 
 /*
@@ -555,7 +562,7 @@
 get_options(struct tftphdr *tp, char *cp, int size, char *ackb,
     int *alen, int *err)
 {
-       struct tftp_options *op;
+       const struct tftp_options *op;
        char *option, *value, *endp;
        int r, rv=0, ec=0;
 
@@ -609,7 +616,7 @@
        struct formats *pf;
        char    *cp;
        char    *filename, *mode;
-       int      first, ecode, alen, etftp=0, r;
+       int      first, ecode, alen, etftp = 0, r;
 
        ecode = 0;      /* XXX gcc */
        first = 1;
@@ -662,6 +669,16 @@
                        exit(1);
                }
        }
+       /*
+        * Globally replace the path separator given in the -p option
+        * with / to cope with clients expecting a non-unix path separator.
+        */
+       if (pathsep != '\0') {
+               for (cp = filename; *cp != '\0'; ++cp) {
+                       if (*cp == pathsep)
+                               *cp = '/';
+               }
+       }
        ecode = (*pf->f_validate)(&filename, tp->th_opcode);
        if (logging) {
                syslog(LOG_INFO, "%s: %s request for %s: %s",
@@ -821,10 +838,10 @@
        return (0);
 }
 
-int    timeout;
-jmp_buf        timeoutbuf;
+static int     timeout;
+static jmp_buf timeoutbuf;
 
-void
+static void
 timer(int dummy)
 {
 
@@ -853,7 +870,7 @@
        case OACK:
                return "OACK";
        default:
-               (void)snprintf(obuf, sizeof(obuf), "*code %d*", code);
+               (void)snprintf(obuf, sizeof(obuf), "*code 0x%x*", code);
                return obuf;
        }
 }
@@ -861,13 +878,14 @@
 /*
  * Send the requested file.
  */
-void
-sendfile(struct formats *pf, int etftp, int acklength)
+static void
+sendfile(struct formats *pf, volatile int etftp, int acklength)
 {
        volatile unsigned int block;
        struct tftphdr  *dp;
        struct tftphdr  *ap;    /* ack packet */
-       int              size, n;
+       volatile int     size;
+       int n;
 



Home | Main Index | Thread Index | Old Index