1 /*        $NetBSD: tftpd.c,v 1.45 2016/07/20 20:18:21 shm Exp $       */
2 
3 /*
4  * Copyright (c) 1983, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
35  The Regents of the University of California.  All rights reserved.");
36 #if 0
37 static char sccsid[] = "@(#)tftpd.c     8.1 (Berkeley) 6/4/93";
38 #else
39 __RCSID("$NetBSD: tftpd.c,v 1.45 2016/07/20 20:18:21 shm Exp $");
40 #endif
41 #endif /* not lint */
42 
43 /*
44  * Trivial file transfer protocol server.
45  *
46  * This version includes many modifications by Jim Guyton
47  * <guyton@rand-unix>.
48  */
49 
50 #include <sys/param.h>
51 #include <sys/ioctl.h>
52 #include <sys/stat.h>
53 #include <sys/socket.h>
54 
55 #include <netinet/in.h>
56 #include <arpa/tftp.h>
57 #include <arpa/inet.h>
58 
59 #include <ctype.h>
60 #include <errno.h>
61 #include <fcntl.h>
62 #include <grp.h>
63 #include <netdb.h>
64 #include <pwd.h>
65 #include <setjmp.h>
66 #include <signal.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <syslog.h>
71 #include <time.h>
72 #include <unistd.h>
73 
74 #include "tftpsubs.h"
75 
76 #define   DEFAULTUSER         "nobody"
77 
78 #define   TIMEOUT             5
79 
80 static int          peer;
81 static int          rexmtval = TIMEOUT;
82 static int          maxtimeout = 5*TIMEOUT;
83 
84 static char         buf[MAXPKTSIZE];
85 static char         ackbuf[PKTSIZE];
86 static char         oackbuf[PKTSIZE];
87 static struct       sockaddr_storage from;
88 static socklen_t    fromlen;
89 static int          debug;
90 
91 static int          tftp_opt_tsize = 0;
92 static int          tftp_blksize = SEGSIZE;
93 static int          tftp_tsize = 0;
94 
95 /*
96  * Null-terminated directory prefix list for absolute pathname requests and
97  * search list for relative pathname requests.
98  *
99  * MAXDIRS should be at least as large as the number of arguments that
100  * inetd allows (currently 20).
101  */
102 #define MAXDIRS     20
103 static struct dirlist {
104           char      *name;
105           int       len;
106 } dirs[MAXDIRS+1];
107 static int          suppress_naks;
108 static int          logging;
109 static int          secure;
110 static char         pathsep = '\0';
111 static char         *securedir;
112 static int          unrestricted_writes;    /* uploaded files don't have to exist */
113 static int          broadcast_client = 0; /* Some clients ack to the broadcast address */
114 
115 struct formats;
116 
117 static const char *errtomsg(int);
118 static void         nak(int);
119 __dead static void  tftp(struct tftphdr *, int);
120 __dead static void  usage(void);
121 static char         *verifyhost(struct sockaddr *);
122 __dead static void  justquit(int);
123 static void         recvfile(struct formats *, int, int);
124 static void         sendfile(struct formats *, int, int);
125 __dead static void  timer(int);
126 static const char *opcode(int);
127 static int          validate_access(char **, int);
128 
129 static struct formats {
130           const char          *f_mode;
131           int                 (*f_validate)(char **, int);
132           void                (*f_send)(struct formats *, int, int);
133           void                (*f_recv)(struct formats *, int, int);
134           int                 f_convert;
135 } formats[] = {
136           { "netascii",       validate_access,    sendfile, recvfile, 1 },
137           { "octet",          validate_access,    sendfile, recvfile, 0 },
138           { .f_mode = NULL }
139 };
140 
141 static void
usage(void)142 usage(void)
143 {
144 
145           syslog(LOG_ERR,
146     "Usage: %s [-bcdln] [-g group] [-p pathsep] [-s directory] [-u user] [directory ...]",
147                         getprogname());
148           exit(1);
149 }
150 
151 int
main(int argc,char * argv[])152 main(int argc, char *argv[])
153 {
154           struct sockaddr_storage me;
155           struct passwd       *pwent;
156           struct group        *grent;
157           struct tftphdr      *tp;
158           const char          *tgtuser, *tgtgroup;
159           char *ep;
160           int       n, ch, on, fd;
161           int       soopt;
162           socklen_t len;
163           uid_t     curuid, tgtuid;
164           gid_t     curgid, tgtgid;
165           long      nid;
166 
167           n = 0;
168           fd = 0;
169           tzset();
170           openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_DAEMON);
171           tgtuser = DEFAULTUSER;
172           tgtgroup = NULL;
173           curuid = getuid();
174           curgid = getgid();
175 
176           while ((ch = getopt(argc, argv, "bcdg:lnp:s:u:")) != -1)
177                     switch (ch) {
178                     case 'b':
179                               /*
180                                * Some clients, notably older Cisco boot loaders,
181                                * send their acknowledgements to the broadcast address
182                                * rather than the unicast address of the server.
183                                * Allow those clients to inter-operate with us.
184                                * It's worth noting that this interaction doesn't cause the
185                                * server to change where it sends the responses, meaning
186                                * servers that have this flag enabled are no more
187                                * susceptible to magnifcation DOS attacks than those
188                                * servers that don't use this flag.  This flag merely
189                                * permits the reception of acknowledgement traffic to the
190                                * broadcast address/specific port number that's being used for
191                                * this session as well as the unicast address/specific port
192                                * number for this session.  For example, if the session is
193                                * expecting acks on 192.168.1.40:50201, then this flag
194                                * would also allow acks to be returned to
195                                * 192.168.1.255:50201, assuming that 192.168.1.255 is the
196                                * broadcast address for the subnet containing 192.168.1.40.
197                                */
198                               broadcast_client = 1;
199                               break;
200                     case 'c':
201                               unrestricted_writes = 1;
202                               break;
203 
204                     case 'd':
205                               debug++;
206                               break;
207 
208                     case 'g':
209                               tgtgroup = optarg;
210                               break;
211 
212                     case 'l':
213                               logging = 1;
214                               break;
215 
216                     case 'n':
217                               suppress_naks = 1;
218                               break;
219 
220                     case 'p':
221                               if (optarg[0] == '\0' || optarg[1] != '\0')
222                                         usage();
223                               pathsep = optarg[0];
224                               break;
225 
226                     case 's':
227                               secure = 1;
228                               securedir = optarg;
229                               break;
230 
231                     case 'u':
232                               tgtuser = optarg;
233                               break;
234 
235                     default:
236                               usage();
237                               break;
238                     }
239 
240           if (optind < argc) {
241                     struct dirlist *dirp;
242 
243                     /* Get list of directory prefixes. Skip relative pathnames. */
244                     for (dirp = dirs; optind < argc && dirp < &dirs[MAXDIRS];
245                          optind++) {
246                               if (argv[optind][0] == '/') {
247                                         dirp->name = argv[optind];
248                                         dirp->len  = strlen(dirp->name);
249                                         dirp++;
250                               }
251                     }
252           }
253 
254           if (*tgtuser == '\0' || (tgtgroup != NULL && *tgtgroup == '\0'))
255                     usage();
256 
257           nid = (strtol(tgtuser, &ep, 10));
258           if (*ep == '\0') {
259                     if ((uid_t)nid > UID_MAX) {
260                               syslog(LOG_ERR, "uid %ld is too large", nid);
261                               exit(1);
262                     }
263                     pwent = getpwuid((uid_t)nid);
264           } else
265                     pwent = getpwnam(tgtuser);
266           if (pwent == NULL) {
267                     syslog(LOG_ERR, "unknown user `%s'", tgtuser);
268                     exit(1);
269           }
270           tgtuid = pwent->pw_uid;
271           tgtgid = pwent->pw_gid;
272 
273           if (tgtgroup != NULL) {
274                     nid = (strtol(tgtgroup, &ep, 10));
275                     if (*ep == '\0') {
276                               if ((uid_t)nid > GID_MAX) {
277                                         syslog(LOG_ERR, "gid %ld is too large", nid);
278                                         exit(1);
279                               }
280                               grent = getgrgid((gid_t)nid);
281                     } else
282                               grent = getgrnam(tgtgroup);
283                     if (grent != NULL)
284                               tgtgid = grent->gr_gid;
285                     else {
286                               syslog(LOG_ERR, "unknown group `%s'", tgtgroup);
287                               exit(1);
288                     }
289           }
290 
291           if (secure) {
292                     if (chdir(securedir) < 0) {
293                               syslog(LOG_ERR, "chdir %s: %m", securedir);
294                               exit(1);
295                     }
296                     if (chroot(".")) {
297                               syslog(LOG_ERR, "chroot: %m");
298                               exit(1);
299                     }
300           }
301 
302           if (logging)
303                     syslog(LOG_DEBUG, "running as user `%s' (%d), group `%s' (%d)",
304                         tgtuser, tgtuid, tgtgroup ? tgtgroup : "(unspecified)",
305                         tgtgid);
306           if (curgid != tgtgid) {
307                     if (setgid(tgtgid)) {
308                               syslog(LOG_ERR, "setgid to %d: %m", (int)tgtgid);
309                               exit(1);
310                     }
311                     if (setgroups(0, NULL)) {
312                               syslog(LOG_ERR, "setgroups: %m");
313                               exit(1);
314                     }
315           }
316 
317           if (curuid != tgtuid) {
318                     if (setuid(tgtuid)) {
319                               syslog(LOG_ERR, "setuid to %d: %m", (int)tgtuid);
320                               exit(1);
321                     }
322           }
323 
324           on = 1;
325           if (ioctl(fd, FIONBIO, &on) < 0) {
326                     syslog(LOG_ERR, "ioctl(FIONBIO): %m");
327                     exit(1);
328           }
329           fromlen = sizeof (from);
330           n = recvfrom(fd, buf, sizeof (buf), 0,
331               (struct sockaddr *)&from, &fromlen);
332           if (n < 0) {
333                     syslog(LOG_ERR, "recvfrom: %m");
334                     exit(1);
335           }
336           /*
337            * Now that we have read the message out of the UDP
338            * socket, we fork and exit.  Thus, inetd will go back
339            * to listening to the tftp port, and the next request
340            * to come in will start up a new instance of tftpd.
341            *
342            * We do this so that inetd can run tftpd in "wait" mode.
343            * The problem with tftpd running in "nowait" mode is that
344            * inetd may get one or more successful "selects" on the
345            * tftp port before we do our receive, so more than one
346            * instance of tftpd may be started up.  Worse, if tftpd
347            * break before doing the above "recvfrom", inetd would
348            * spawn endless instances, clogging the system.
349            */
350           {
351                     int pid;
352                     int i;
353                     socklen_t j;
354 
355                     for (i = 1; i < 20; i++) {
356                         pid = fork();
357                         if (pid < 0) {
358                                         sleep(i);
359                                         /*
360                                          * flush out to most recently sent request.
361                                          *
362                                          * This may drop some request, but those
363                                          * will be resent by the clients when
364                                          * they timeout.  The positive effect of
365                                          * this flush is to (try to) prevent more
366                                          * than one tftpd being started up to service
367                                          * a single request from a single client.
368                                          */
369                                         j = sizeof from;
370                                         i = recvfrom(fd, buf, sizeof (buf), 0,
371                                             (struct sockaddr *)&from, &j);
372                                         if (i > 0) {
373                                                   n = i;
374                                                   fromlen = j;
375                                         }
376                         } else {
377                                         break;
378                         }
379                     }
380                     if (pid < 0) {
381                               syslog(LOG_ERR, "fork: %m");
382                               exit(1);
383                     } else if (pid != 0) {
384                               exit(0);
385                     }
386           }
387 
388           /*
389            * remember what address this was sent to, so we can respond on the
390            * same interface
391            */
392           len = sizeof(me);
393           if (getsockname(fd, (struct sockaddr *)&me, &len) == 0) {
394                     switch (me.ss_family) {
395                     case AF_INET:
396                               ((struct sockaddr_in *)&me)->sin_port = 0;
397                               break;
398                     case AF_INET6:
399                               ((struct sockaddr_in6 *)&me)->sin6_port = 0;
400                               break;
401                     default:
402                               /* unsupported */
403                               break;
404                     }
405           } else {
406                     memset(&me, 0, sizeof(me));
407                     me.ss_family = from.ss_family;
408                     me.ss_len = from.ss_len;
409           }
410 
411           alarm(0);
412           close(fd);
413           close(1);
414           peer = socket(from.ss_family, SOCK_DGRAM, 0);
415           if (peer < 0) {
416                     syslog(LOG_ERR, "socket: %m");
417                     exit(1);
418           }
419           if (broadcast_client) {
420                     soopt = 1;
421                     if (setsockopt(peer, SOL_SOCKET, SO_BROADCAST, (void *) &soopt, sizeof(soopt)) < 0) {
422                               syslog(LOG_ERR, "set SO_BROADCAST: %m");
423                               exit(1);
424                     }
425           }
426           if (bind(peer, (struct sockaddr *)&me, me.ss_len) < 0) {
427                     syslog(LOG_ERR, "bind: %m");
428                     exit(1);
429           }
430           soopt = 65536;      /* larger than we'll ever need */
431           if (setsockopt(peer, SOL_SOCKET, SO_SNDBUF, (void *) &soopt, sizeof(soopt)) < 0) {
432                     syslog(LOG_ERR, "set SNDBUF: %m");
433                     exit(1);
434           }
435           if (setsockopt(peer, SOL_SOCKET, SO_RCVBUF, (void *) &soopt, sizeof(soopt)) < 0) {
436                     syslog(LOG_ERR, "set RCVBUF: %m");
437                     exit(1);
438           }
439 
440           tp = (struct tftphdr *)buf;
441           tp->th_opcode = ntohs(tp->th_opcode);
442           if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
443                     tftp(tp, n);
444           exit(1);
445 }
446 
447 static int
blk_handler(struct tftphdr * tp,const char * val,char * ack,size_t asize,size_t * ackl,int * ecode)448 blk_handler(struct tftphdr *tp, const char *val, char *ack, size_t asize,
449     size_t *ackl, int *ecode)
450 {
451           unsigned long bsize;
452           char *endp;
453           int l;
454 
455           /*
456            * On these failures, we could just ignore the blocksize option.
457            * Perhaps that should be a command-line option.
458            */
459           errno = 0;
460           bsize = strtoul(val, &endp, 10);
461           if ((bsize == ULONG_MAX && errno == ERANGE) || *endp) {
462                     syslog(LOG_NOTICE, "%s: %s request for %s: "
463                               "illegal value %s for blksize option",
464                               verifyhost((struct sockaddr *)&from),
465                               tp->th_opcode == WRQ ? "write" : "read",
466                               tp->th_stuff, val);
467                     *ecode = EBADOP;
468                     return -1;
469           }
470           if (bsize < 8 || bsize > 65464) {
471                     syslog(LOG_NOTICE, "%s: %s request for %s: "
472                               "out of range value %s for blksize option",
473                               verifyhost((struct sockaddr *)&from),
474                               tp->th_opcode == WRQ ? "write" : "read",
475                               tp->th_stuff, val);
476                     *ecode = EBADOP;
477                     return -1;
478           }
479 
480           tftp_blksize = bsize;
481           if (asize > *ackl && (l = snprintf(ack + *ackl, asize - *ackl,
482               "blksize%c%lu%c", 0, bsize, 0)) > 0) {
483                     *ackl += l;
484           } else {
485                     *ecode = EBADOP;
486                     return -1;
487           }
488 
489           return 0;
490 }
491 
492 static int
timeout_handler(struct tftphdr * tp,const char * val,char * ack,size_t asize,size_t * ackl,int * ecode)493 timeout_handler(struct tftphdr *tp, const char *val, char *ack, size_t asize,
494                     size_t *ackl, int *ecode)
495 {
496           unsigned long tout;
497           char *endp;
498           int l;
499 
500           errno = 0;
501           tout = strtoul(val, &endp, 10);
502           if ((tout == ULONG_MAX && errno == ERANGE) || *endp) {
503                     syslog(LOG_NOTICE, "%s: %s request for %s: "
504                               "illegal value %s for timeout option",
505                               verifyhost((struct sockaddr *)&from),
506                               tp->th_opcode == WRQ ? "write" : "read",
507                               tp->th_stuff, val);
508                     *ecode = EBADOP;
509                     return -1;
510           }
511           if (tout < 1 || tout > 255) {
512                     syslog(LOG_NOTICE, "%s: %s request for %s: "
513                               "out of range value %s for timeout option",
514                               verifyhost((struct sockaddr *)&from),
515                               tp->th_opcode == WRQ ? "write" : "read",
516                               tp->th_stuff, val);
517                     return 0;
518           }
519 
520           rexmtval = tout;
521           if (asize > *ackl && (l = snprintf(ack + *ackl, asize - *ackl,
522               "timeout%c%lu%c", 0, tout, 0)) > 0)
523                     *ackl += l;
524           else
525                     return -1;
526           /*
527            * Arbitrarily pick a maximum timeout on a request to 3
528            * retransmissions if the interval timeout is more than
529            * one minute.  Longest possible timeout is therefore
530            * 3 * 255 - 1, or 764 seconds.
531            */
532           if (rexmtval > 60) {
533                     maxtimeout = rexmtval * 3;
534           } else {
535                     maxtimeout = rexmtval * 5;
536           }
537 
538           return 0;
539 }
540 
541 static int
tsize_handler(struct tftphdr * tp,const char * val,char * ack,size_t asize,size_t * ackl,int * ecode)542 tsize_handler(struct tftphdr *tp, const char *val, char *ack, size_t asize,
543     size_t *ackl, int *ecode)
544 {
545           unsigned long fsize;
546           char *endp;
547 
548           /*
549            * Maximum file even with extended tftp is 65535 blocks of
550            * length 65464, or 4290183240 octets (4784056 less than 2^32).
551            * unsigned long is at least 32 bits on all NetBSD archs.
552            */
553 
554           errno = 0;
555           fsize = strtoul(val, &endp, 10);
556           if ((fsize == ULONG_MAX && errno == ERANGE) || *endp) {
557                     syslog(LOG_NOTICE, "%s: %s request for %s: "
558                               "illegal value %s for tsize option",
559                               verifyhost((struct sockaddr *)&from),
560                               tp->th_opcode == WRQ ? "write" : "read",
561                               tp->th_stuff, val);
562                     *ecode = EBADOP;
563                     return -1;
564           }
565           if (fsize > (unsigned long) 65535 * 65464) {
566                     syslog(LOG_NOTICE, "%s: %s request for %s: "
567                               "out of range value %s for tsize option",
568                               verifyhost((struct sockaddr *)&from),
569                               tp->th_opcode == WRQ ? "write" : "read",
570                               tp->th_stuff, val);
571                     *ecode = EBADOP;
572                     return -1;
573           }
574 
575           tftp_opt_tsize = 1;
576           tftp_tsize = fsize;
577           /*
578            * We will report this later -- either replying with the fsize (WRQ)
579            * or replying with the actual filesize (RRQ).
580            */
581 
582           return 0;
583 }
584 
585 static const struct tftp_options {
586           const char *o_name;
587           int (*o_handler)(struct tftphdr *, const char *, char *, size_t,
588                                size_t *, int *);
589 } options[] = {
590           { "blksize", blk_handler },
591           { "timeout", timeout_handler },
592           { "tsize", tsize_handler },
593           { .o_name = NULL }
594 };
595 
596 /*
597  * Get options for an extended tftp session.  Stuff the ones we
598  * recognize in oackbuf.
599  */
600 static int
get_options(struct tftphdr * tp,char * cp,int size,char * ackb,size_t asize,size_t * alen,int * ecode)601 get_options(struct tftphdr *tp, char *cp, int size, char *ackb, size_t asize,
602     size_t *alen, int *ecode)
603 {
604           const struct tftp_options *op;
605           char *option, *value, *endp;
606           int r, rv=0;
607 
608           endp = cp + size;
609           while (cp < endp) {
610                     option = cp;
611                     while (*cp && cp < endp) {
612                               *cp = tolower((unsigned char)*cp);
613                               cp++;
614                     }
615                     if (*cp) {
616                               /* if we have garbage at the end, just ignore it */
617                               break;
618                     }
619                     cp++;     /* skip over NUL */
620                     value = cp;
621                     while (*cp && cp < endp) {
622                               cp++;
623                     }
624                     if (*cp) {
625                               /* if we have garbage at the end, just ignore it */
626                               break;
627                     }
628                     cp++;
629                     for (op = options; op->o_name; op++) {
630                               if (strcmp(op->o_name, option) == 0)
631                                         break;
632                     }
633                     if (op->o_name) {
634                               r = op->o_handler(tp, value, ackb, asize, alen, ecode);
635                               if (r < 0) {
636                                         rv = -1;
637                                         break;
638                               }
639                               rv++;
640                     } /* else ignore unknown options */
641           }
642 
643           return rv;
644 }
645 
646 /*
647  * Handle initial connection protocol.
648  */
649 static void
tftp(struct tftphdr * tp,int size)650 tftp(struct tftphdr *tp, int size)
651 {
652           struct formats *pf;
653           char      *cp;
654           char      *filename, *mode;
655           int        first, ecode, etftp = 0, r;
656           size_t alen;
657 
658           ecode = 0;          /* XXX gcc */
659           first = 1;
660           mode = NULL;
661 
662           filename = cp = tp->th_stuff;
663 again:
664           while (cp < buf + size) {
665                     if (*cp == '\0')
666                               break;
667                     cp++;
668           }
669           if (*cp != '\0') {
670                     nak(EBADOP);
671                     exit(1);
672           }
673           if (first) {
674                     mode = ++cp;
675                     first = 0;
676                     goto again;
677           }
678           for (cp = mode; *cp; cp++)
679                     *cp = tolower((unsigned char)*cp);
680           for (pf = formats; pf->f_mode; pf++)
681                     if (strcmp(pf->f_mode, mode) == 0)
682                               break;
683           if (pf->f_mode == 0) {
684                     nak(EBADOP);
685                     exit(1);
686           }
687           /*
688            * cp currently points to the NUL byte following the mode.
689            *
690            * If we have some valid options, then let's assume that we're
691            * now dealing with an extended tftp session.  Note that if we
692            * don't get any options, then we *must* assume that we do not
693            * have an extended tftp session.  If we get options, we fill
694            * in the ack buf to acknowledge them.  If we skip that, then
695            * the client *must* assume that we are not using an extended
696            * session.
697            */
698           size -= (++cp - (char *) tp);
699           if (size > 0 && *cp) {
700                     alen = 2; /* Skip over opcode */
701                     r = get_options(tp, cp, size, oackbuf, sizeof(oackbuf),
702                         &alen, &ecode);
703                     if (r > 0) {
704                               etftp = 1;
705                     } else if (r < 0) {
706                               nak(ecode);
707                               exit(1);
708                     }
709           }
710           /*
711            * Globally replace the path separator given in the -p option
712            * with / to cope with clients expecting a non-unix path separator.
713            */
714           if (pathsep != '\0') {
715                     for (cp = filename; *cp != '\0'; ++cp) {
716                               if (*cp == pathsep)
717                                         *cp = '/';
718                     }
719           }
720           ecode = (*pf->f_validate)(&filename, tp->th_opcode);
721           if (logging) {
722                     syslog(LOG_INFO, "%s: %s request for %s: %s",
723                               verifyhost((struct sockaddr *)&from),
724                               tp->th_opcode == WRQ ? "write" : "read",
725                               filename, errtomsg(ecode));
726           }
727           if (ecode) {
728                     /*
729                      * Avoid storms of naks to a RRQ broadcast for a relative
730                      * bootfile pathname from a diskless Sun.
731                      */
732                     if (suppress_naks && *filename != '/' && ecode == ENOTFOUND)
733                               exit(0);
734                     nak(ecode);
735                     exit(1);
736           }
737 
738           if (etftp) {
739                     struct tftphdr *oack_h;
740 
741                     if (tftp_opt_tsize) {
742                               int l;
743 
744                               if (sizeof(oackbuf) > alen &&
745                                   (l = snprintf(oackbuf + alen,
746                                   sizeof(oackbuf) - alen, "tsize%c%u%c", 0,
747                                   tftp_tsize, 0)) > 0)
748                                         alen += l;
749                     }
750                     oack_h = (struct tftphdr *) oackbuf;
751                     oack_h->th_opcode = htons(OACK);
752           }
753 
754           if (tp->th_opcode == WRQ)
755                     (*pf->f_recv)(pf, etftp, alen);
756           else
757                     (*pf->f_send)(pf, etftp, alen);
758           exit(0);
759 }
760 
761 
762 FILE *file;
763 
764 /*
765  * Validate file access.  Since we
766  * have no uid or gid, for now require
767  * file to exist and be publicly
768  * readable/writable.
769  * If we were invoked with arguments
770  * from inetd then the file must also be
771  * in one of the given directory prefixes.
772  */
773 int
validate_access(char ** filep,int mode)774 validate_access(char **filep, int mode)
775 {
776           struct stat          stbuf;
777           struct dirlist      *dirp;
778           static char          pathname[MAXPATHLEN];
779           char                *filename;
780           int                  fd;
781           int                  create = 0;
782           int                  trunc = 0;
783 
784           filename = *filep;
785 
786           /*
787            * Prevent tricksters from getting around the directory restrictions
788            */
789           if (strstr(filename, "/../"))
790                     return (EACCESS);
791 
792           if (*filename == '/') {
793                     /*
794                      * Allow the request if it's in one of the approved locations.
795                      * Special case: check the null prefix ("/") by looking
796                      * for length = 1 and relying on the arg. processing that
797                      * it's a /.
798                      */
799                     for (dirp = dirs; dirp->name != NULL; dirp++) {
800                               if (dirp->len == 1 ||
801                                   (!strncmp(filename, dirp->name, dirp->len) &&
802                                    filename[dirp->len] == '/'))
803                                             break;
804                     }
805                     /* If directory list is empty, allow access to any file */
806                     if (dirp->name == NULL && dirp != dirs)
807                               return (EACCESS);
808                     if (stat(filename, &stbuf) < 0)
809                               return (errno == ENOENT ? ENOTFOUND : EACCESS);
810                     if (!S_ISREG(stbuf.st_mode))
811                               return (ENOTFOUND);
812                     if (mode == RRQ) {
813                               if ((stbuf.st_mode & S_IROTH) == 0)
814                                         return (EACCESS);
815                     } else {
816                               if ((stbuf.st_mode & S_IWOTH) == 0)
817                                         return (EACCESS);
818                     }
819           } else {
820                     /*
821                      * Relative file name: search the approved locations for it.
822                      */
823 
824                     if (!strncmp(filename, "../", 3))
825                               return (EACCESS);
826 
827                     /*
828                      * Find the first file that exists in any of the directories,
829                      * check access on it.
830                      */
831                     if (dirs[0].name != NULL) {
832                               for (dirp = dirs; dirp->name != NULL; dirp++) {
833                                         snprintf(pathname, sizeof pathname, "%s/%s",
834                                             dirp->name, filename);
835                                         if (stat(pathname, &stbuf) == 0 &&
836                                             (stbuf.st_mode & S_IFMT) == S_IFREG) {
837                                                   break;
838                                         }
839                               }
840                               if (dirp->name == NULL)
841                                         return (ENOTFOUND);
842                               if (mode == RRQ && !(stbuf.st_mode & S_IROTH))
843                                         return (EACCESS);
844                               if (mode == WRQ && !(stbuf.st_mode & S_IWOTH))
845                                         return (EACCESS);
846                               *filep = filename = pathname;
847                     } else {
848                               int stat_rc;
849 
850                               /*
851                                * If there's no directory list, take our cue from the
852                                * absolute file request check above (*filename == '/'),
853                                * and allow access to anything.
854                                */
855                               stat_rc = stat(filename, &stbuf);
856                               if (mode == RRQ) {
857                                         /* Read request */
858                                         if (stat_rc < 0)
859                                                return (errno == ENOENT ? ENOTFOUND : EACCESS);
860                                         if (!S_ISREG(stbuf.st_mode))
861                                                return (ENOTFOUND);
862                                         if ((stbuf.st_mode & S_IROTH) == 0)
863                                                   return (EACCESS);
864                               } else {
865                                         if (stat_rc < 0) {
866                                                /* Can't stat */
867                                                if (errno == EACCES) {
868                                                          /* Permission denied */
869                                                          return EACCESS;
870                                                } else {
871                                                          /* Not there */
872                                                          if (unrestricted_writes) {
873                                                                    /* need to creat new file! */
874                                                                    create = O_CREAT;
875                                                          } else {
876                                                                    /* Permission denied */
877                                                                    return EACCESS;
878                                                          }
879                                                }
880                                         } else {
881                                                /* Can stat */
882                                                if ((stbuf.st_mode & S_IWOTH) == 0) {
883                                                          return (EACCESS);
884                                                }
885                                                trunc = O_TRUNC;
886                                         }
887                               }
888                               *filep = filename;
889                     }
890           }
891 
892           if (tftp_opt_tsize && mode == RRQ)
893                     tftp_tsize = (unsigned long) stbuf.st_size;
894 
895           fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY | trunc | create,
896                               0644); /* debatable */
897           if (fd < 0)
898                     return (errno + 100);
899           file = fdopen(fd, (mode == RRQ)? "r":"w");
900           if (file == NULL) {
901                     close(fd);
902                     return (errno + 100);
903           }
904           return (0);
905 }
906 
907 static int          timeout;
908 static jmp_buf      timeoutbuf;
909 
910 static void
timer(int dummy)911 timer(int dummy)
912 {
913 
914           timeout += rexmtval;
915           if (timeout >= maxtimeout)
916                     exit(1);
917           longjmp(timeoutbuf, 1);
918 }
919 
920 static const char *
opcode(int code)921 opcode(int code)
922 {
923           static char obuf[64];
924 
925           switch (code) {
926           case RRQ:
927                     return "RRQ";
928           case WRQ:
929                     return "WRQ";
930           case DATA:
931                     return "DATA";
932           case ACK:
933                     return "ACK";
934           case ERROR:
935                     return "ERROR";
936           case OACK:
937                     return "OACK";
938           default:
939                     (void)snprintf(obuf, sizeof(obuf), "*code 0x%x*", code);
940                     return obuf;
941           }
942 }
943 
944 /*
945  * Send the requested file.
946  */
947 static void
sendfile(struct formats * pf,volatile int etftp,int acklength)948 sendfile(struct formats *pf, volatile int etftp, int acklength)
949 {
950           volatile unsigned int block;
951           struct tftphdr      *dp;
952           struct tftphdr      *ap;    /* ack packet */
953           volatile int         size;
954           int n;
955 
956           signal(SIGALRM, timer);
957           ap = (struct tftphdr *)ackbuf;
958           if (etftp) {
959                     dp = (struct tftphdr *)oackbuf;
960                     size = acklength - 4;
961                     block = 0;
962           } else {
963                     dp = r_init();
964                     size = 0;
965                     block = 1;
966           }
967 
968           do {
969                     if (block > 0) {
970                               size = readit(file, &dp, tftp_blksize, pf->f_convert);
971                               if (size < 0) {
972                                         nak(errno + 100);
973                                         goto abort;
974                               }
975                               dp->th_opcode = htons((u_short)DATA);
976                               dp->th_block = htons((u_short)block);
977                     }
978                     timeout = 0;
979                     (void)setjmp(timeoutbuf);
980 
981 send_data:
982                     if (!etftp && debug)
983                               syslog(LOG_DEBUG, "Send DATA %u", block);
984                     if ((n = sendto(peer, dp, size + 4, 0, (struct sockaddr *)&from, fromlen)) != size + 4) {
985                               syslog(LOG_ERR, "tftpd: write: %m");
986                               goto abort;
987                     }
988                     if (block)
989                               read_ahead(file, tftp_blksize, pf->f_convert);
990                     for ( ; ; ) {
991                               alarm(rexmtval);        /* read the ack */
992                               n = recvfrom(peer, ackbuf, tftp_blksize, 0,(struct sockaddr
993                               *)&from, &fromlen );
994                               alarm(0);
995                               if (n < 0) {
996                                         syslog(LOG_ERR, "tftpd: read: %m");
997                                         goto abort;
998                               }
999                               ap->th_opcode = ntohs((u_short)ap->th_opcode);
1000                               ap->th_block = ntohs((u_short)ap->th_block);
1001                               switch (ap->th_opcode) {
1002                               case ERROR:
1003                                         goto abort;
1004 
1005                               case ACK:
1006                                         if (etftp && ap->th_block == 0) {
1007                                                   etftp = 0;
1008                                                   acklength = 0;
1009                                                   dp = r_init();
1010                                                   goto done;
1011                                         }
1012                                         if (ap->th_block == (u_short)block)
1013                                                   goto done;
1014                                         if (debug)
1015                                                   syslog(LOG_DEBUG, "Resync ACK %u != %u",
1016                                                       (unsigned int)ap->th_block, block);
1017                                         /* Re-synchronize with the other side */
1018                                         (void) synchnet(peer, tftp_blksize);
1019                                         if (ap->th_block == (u_short)(block - 1))
1020                                                   goto send_data;
1021                                         /* FALLTHROUGH */
1022                               default:
1023                                         syslog(LOG_INFO, "Received %s in sendfile\n",
1024                                             opcode(dp->th_opcode));
1025                               }
1026 
1027                     }
1028 done:
1029                     if (debug)
1030                               syslog(LOG_DEBUG, "Received ACK for block %u", block);
1031                     if (block == UINT16_MAX && size == tftp_blksize)
1032                               syslog(LOG_WARNING,
1033                                   "Block number wrapped (hint: increase block size)");
1034                     block++;
1035           } while (size == tftp_blksize || block == 1);
1036 abort:
1037           (void) fclose(file);
1038 }
1039 
1040 static void
justquit(int dummy)1041 justquit(int dummy)
1042 {
1043 
1044           exit(0);
1045 }
1046 
1047 /*
1048  * Receive a file.
1049  */
1050 static void
recvfile(struct formats * pf,volatile int etftp,volatile int acklength)1051 recvfile(struct formats *pf, volatile int etftp, volatile int acklength)
1052 {
1053           volatile unsigned int block;
1054           struct tftphdr      *dp;
1055           struct tftphdr      *ap;    /* ack buffer */
1056           volatile int size;
1057           int n;
1058 
1059           signal(SIGALRM, timer);
1060           dp = w_init();
1061           ap = (struct tftphdr *)oackbuf;
1062           block = 0;
1063           do {
1064                     timeout = 0;
1065                     if (etftp == 0) {
1066                               ap = (struct tftphdr *)ackbuf;
1067                               ap->th_opcode = htons((u_short)ACK);
1068                               ap->th_block = htons((u_short)block);
1069                               acklength = 4;
1070                     }
1071                     if (debug)
1072                               syslog(LOG_DEBUG, "Sending ACK for block %u\n", block);
1073                     if (block == UINT16_MAX)
1074                               syslog(LOG_WARNING,
1075                                   "Block number wrapped (hint: increase block size)");
1076                     block++;
1077                     (void) setjmp(timeoutbuf);
1078 send_ack:
1079                     ap = (struct tftphdr *) (etftp ? oackbuf : ackbuf);
1080                     if (sendto(peer, ap, acklength, 0, (struct sockaddr *)&from, fromlen) != acklength) {
1081                               syslog(LOG_ERR, "tftpd: write: %m");
1082                               goto abort;
1083                     }
1084                     write_behind(file, pf->f_convert);
1085                     for ( ; ; ) {
1086                               alarm(rexmtval);
1087                               n = recvfrom(peer, dp, tftp_blksize + 4, 0, (struct sockaddr
1088                               *)&from, &fromlen);
1089                               alarm(0);
1090                               if (n < 0) {            /* really? */
1091                                         syslog(LOG_ERR, "tftpd: read: %m");
1092                                         goto abort;
1093                               }
1094                               etftp = 0;
1095                               dp->th_opcode = ntohs((u_short)dp->th_opcode);
1096                               dp->th_block = ntohs((u_short)dp->th_block);
1097                               if (debug)
1098                                         syslog(LOG_DEBUG, "Received %s for block %u",
1099                                             opcode(dp->th_opcode),
1100                                             (unsigned int)dp->th_block);
1101 
1102                               switch (dp->th_opcode) {
1103                               case ERROR:
1104                                         goto abort;
1105                               case DATA:
1106                                         if (dp->th_block == block)
1107                                                   goto done;   /* normal */
1108                                         if (debug)
1109                                                   syslog(LOG_DEBUG, "Resync %u != %u",
1110                                                       (unsigned int)dp->th_block, block);
1111                                         /* Re-synchronize with the other side */
1112                                         (void) synchnet(peer, tftp_blksize);
1113                                         if (dp->th_block == (block-1))
1114                                                   goto send_ack;          /* rexmit */
1115                                         break;
1116                               default:
1117                                         syslog(LOG_INFO, "Received %s in recvfile\n",
1118                                             opcode(dp->th_opcode));
1119                                         break;
1120                               }
1121                     }
1122 done:
1123                     if (debug)
1124                               syslog(LOG_DEBUG, "Got block %u", block);
1125                     /*  size = write(file, dp->th_data, n - 4); */
1126                     size = writeit(file, &dp, n - 4, pf->f_convert);
1127                     if (size != (n-4)) {                    /* ahem */
1128                               if (size < 0) nak(errno + 100);
1129                               else nak(ENOSPACE);
1130                               goto abort;
1131                     }
1132           } while (size == tftp_blksize);
1133           write_behind(file, pf->f_convert);
1134           (void) fclose(file);            /* close data file */
1135 
1136           ap->th_opcode = htons((u_short)ACK);    /* send the "final" ack */
1137           ap->th_block = htons((u_short)(block));
1138           if (debug)
1139                     syslog(LOG_DEBUG, "Send final ACK %u", block);
1140           (void) sendto(peer, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen);
1141 
1142           signal(SIGALRM, justquit);      /* just quit on timeout */
1143           alarm(rexmtval);
1144           n = recvfrom(peer, buf, sizeof (buf), 0, (struct sockaddr *)&from, &fromlen); /* normally times out and quits */
1145           alarm(0);
1146           if (n >= 4 &&                   /* if read some data */
1147               dp->th_opcode == DATA &&    /* and got a data block */
1148               block == dp->th_block) {  /* then my last ack was lost */
1149                     (void) sendto(peer, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen);     /* resend final ack */
1150           }
1151 abort:
1152           return;
1153 }
1154 
1155 const struct errmsg {
1156           int                  e_code;
1157           const char          *e_msg;
1158 } errmsgs[] = {
1159           { EUNDEF, "Undefined error code" },
1160           { ENOTFOUND,        "File not found" },
1161           { EACCESS,          "Access violation" },
1162           { ENOSPACE,         "Disk full or allocation exceeded" },
1163           { EBADOP, "Illegal TFTP operation" },
1164           { EBADID, "Unknown transfer ID" },
1165           { EEXISTS,          "File already exists" },
1166           { ENOUSER,          "No such user" },
1167           { EOPTNEG,          "Option negotiation failed" },
1168           { -1,               0 }
1169 };
1170 
1171 static const char *
errtomsg(int error)1172 errtomsg(int error)
1173 {
1174           static char ebuf[20];
1175           const struct errmsg *pe;
1176 
1177           if (error == 0)
1178                     return ("success");
1179           for (pe = errmsgs; pe->e_code >= 0; pe++)
1180                     if (pe->e_code == error)
1181                               return (pe->e_msg);
1182           snprintf(ebuf, sizeof(ebuf), "error %d", error);
1183           return (ebuf);
1184 }
1185 
1186 /*
1187  * Send a nak packet (error message).
1188  * Error code passed in is one of the
1189  * standard TFTP codes, or a UNIX errno
1190  * offset by 100.
1191  */
1192 static void
nak(int error)1193 nak(int error)
1194 {
1195           const struct errmsg *pe;
1196           struct tftphdr *tp;
1197           int       length;
1198           size_t    msglen;
1199 
1200           tp = (struct tftphdr *)buf;
1201           tp->th_opcode = htons((u_short)ERROR);
1202           msglen = sizeof(buf) - (&tp->th_msg[0] - buf);
1203           for (pe = errmsgs; pe->e_code >= 0; pe++)
1204                     if (pe->e_code == error)
1205                               break;
1206           if (pe->e_code < 0) {
1207                     tp->th_code = EUNDEF;   /* set 'undef' errorcode */
1208                     strlcpy(tp->th_msg, strerror(error - 100), msglen);
1209           } else {
1210                     tp->th_code = htons((u_short)error);
1211                     strlcpy(tp->th_msg, pe->e_msg, msglen);
1212           }
1213           if (debug)
1214                     syslog(LOG_DEBUG, "Send NACK %s", tp->th_msg);
1215           length = strlen(tp->th_msg);
1216           msglen = &tp->th_msg[length + 1] - buf;
1217           if (sendto(peer, buf, msglen, 0, (struct sockaddr *)&from, fromlen) != (ssize_t)msglen)
1218                     syslog(LOG_ERR, "nak: %m");
1219 }
1220 
1221 static char *
verifyhost(struct sockaddr * fromp)1222 verifyhost(struct sockaddr *fromp)
1223 {
1224           static char hbuf[MAXHOSTNAMELEN];
1225 
1226           if (getnameinfo(fromp, fromp->sa_len, hbuf, sizeof(hbuf), NULL, 0, 0))
1227                     strlcpy(hbuf, "?", sizeof(hbuf));
1228           return (hbuf);
1229 }
1230