1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * Copyright (c) 1999-2009 H. Peter Anvin
4  * Copyright (c) 2011 Intel Corporation; author: H. Peter Anvin
5  * 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. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include "config.h"             /* Must be included first */
37 #include "tftpd.h"
38 
39 /*
40  * Trivial file transfer protocol server.
41  *
42  * This version includes many modifications by Jim Guyton <guyton@rand-unix>
43  */
44 
45 #include <sys/ioctl.h>
46 #include <signal.h>
47 #include <ctype.h>
48 #include <pwd.h>
49 #include <limits.h>
50 #include <syslog.h>
51 
52 #include "common/tftpsubs.h"
53 #include "recvfrom.h"
54 #include "remap.h"
55 
56 #ifdef HAVE_SYS_FILIO_H
57 #include <sys/filio.h>          /* Necessary for FIONBIO on Solaris */
58 #endif
59 
60 #ifdef HAVE_TCPWRAPPERS
61 #include <tcpd.h>
62 
63 int deny_severity = LOG_WARNING;
64 int allow_severity = -1;        /* Don't log at all */
65 
66 static struct request_info wrap_request;
67 #endif
68 
69 #ifdef HAVE_IPV6
70 static int ai_fam = AF_UNSPEC;
71 #else
72 static int ai_fam = AF_INET;
73 #endif
74 
75 #define	TIMEOUT 1000000         /* Default timeout (us) */
76 #define TRIES   6               /* Number of attempts to send each packet */
77 #define TIMEOUT_LIMIT ((1 << TRIES)-1)
78 
79 extern const char *__progname;
80 static int peer;
81 static unsigned long timeout  = TIMEOUT;        /* Current timeout value */
82 static unsigned long rexmtval = TIMEOUT;       /* Basic timeout value */
83 static unsigned long maxtimeout = TIMEOUT_LIMIT * TIMEOUT;
84 static int timeout_quit = 0;
85 static sigjmp_buf timeoutbuf;
86 static uint16_t rollover_val = 0;
87 
88 #define	PKTSIZE	MAX_SEGSIZE+4
89 static char buf[PKTSIZE];
90 static char ackbuf[PKTSIZE];
91 static unsigned int max_blksize = MAX_SEGSIZE;
92 
93 static char tmpbuf[INET6_ADDRSTRLEN], *tmp_p;
94 
95 static union sock_addr from;
96 static socklen_t fromlen;
97 static off_t tsize;
98 static int tsize_ok;
99 
100 static int ndirs;
101 static const char **dirs;
102 
103 static int secure = 0;
104 int cancreate = 0;
105 int unixperms = 0;
106 int portrange = 0;
107 unsigned int portrange_from, portrange_to;
108 int verbosity = 0;
109 
110 struct formats;
111 #ifdef WITH_REGEX
112 static struct rule *rewrite_rules = NULL;
113 #endif
114 
115 int tftp(struct tftphdr *, int);
116 static void nak(int, const char *);
117 static void timer(int);
118 static void do_opt(const char *, const char *, char **);
119 
120 static int set_blksize(uintmax_t *);
121 static int set_blksize2(uintmax_t *);
122 static int set_tsize(uintmax_t *);
123 static int set_timeout(uintmax_t *);
124 static int set_utimeout(uintmax_t *);
125 static int set_rollover(uintmax_t *);
126 
127 struct options {
128     const char *o_opt;
129     int (*o_fnc)(uintmax_t *);
130 } options[] = {
131     {"blksize",  set_blksize},
132     {"blksize2", set_blksize2},
133     {"tsize",    set_tsize},
134     {"timeout",  set_timeout},
135     {"utimeout", set_utimeout},
136     {"rollover", set_rollover},
137     {NULL, NULL}
138 };
139 
140 /* Simple handler for SIGHUP */
141 static volatile sig_atomic_t caught_sighup = 0;
handle_sighup(int sig)142 static void handle_sighup(int sig)
143 {
144     (void)sig;                  /* Suppress unused warning */
145     caught_sighup = 1;
146 }
147 
148 /* Handle exit requests by SIGTERM and SIGINT */
149 static volatile sig_atomic_t exit_signal = 0;
handle_exit(int sig)150 static void handle_exit(int sig)
151 {
152     exit_signal = sig;
153 }
154 
155 /* Handle timeout signal or timeout event */
timer(int sig)156 void timer(int sig)
157 {
158     (void)sig;                  /* Suppress unused warning */
159     timeout <<= 1;
160     if (timeout >= maxtimeout || timeout_quit)
161         exit(0);
162     siglongjmp(timeoutbuf, 1);
163 }
164 
165 #ifdef WITH_REGEX
read_remap_rules(const char * file)166 static struct rule *read_remap_rules(const char *file)
167 {
168     FILE *f;
169     struct rule *rulep;
170 
171     f = fopen(file, "rt");
172     if (!f) {
173         syslog(LOG_ERR, "Cannot open map file: %s: %m", file);
174         exit(EX_NOINPUT);
175     }
176     rulep = parserulefile(f);
177     fclose(f);
178 
179     return rulep;
180 }
181 #endif
182 
183 /*
184  * Rules for locking files; return 0 on success, -1 on failure
185  */
lock_file(int fd,int lock_write)186 static int lock_file(int fd, int lock_write)
187 {
188 #if defined(HAVE_FCNTL) && defined(HAVE_F_SETLK_DEFINITION)
189   struct flock fl;
190 
191   fl.l_type   = lock_write ? F_WRLCK : F_RDLCK;
192   fl.l_whence = SEEK_SET;
193   fl.l_start  = 0;
194   fl.l_len    = 0;		/* Whole file */
195   return fcntl(fd, F_SETLK, &fl);
196 #elif defined(HAVE_LOCK_SH_DEFINITION)
197   return flock(fd, lock_write ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB);
198 #else
199   return 0;			/* Hope & pray... */
200 #endif
201 }
202 
set_socket_nonblock(int fd,int flag)203 static void set_socket_nonblock(int fd, int flag)
204 {
205     int err;
206     int flags;
207 #if defined(HAVE_FCNTL) && defined(HAVE_O_NONBLOCK_DEFINITION)
208     /* Posixly correct */
209     err = ((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
210         (fcntl
211          (fd, F_SETFL,
212           flag ? flags | O_NONBLOCK : flags & ~O_NONBLOCK) < 0);
213 #else
214     flags = flag ? 1 : 0;
215     err = (ioctl(fd, FIONBIO, &flags) < 0);
216 #endif
217     if (err) {
218         syslog(LOG_ERR, "Cannot set nonblock flag on socket: %m");
219         exit(EX_OSERR);
220     }
221 }
222 
pmtu_discovery_off(int fd)223 static void pmtu_discovery_off(int fd)
224 {
225 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
226     int pmtu = IP_PMTUDISC_DONT;
227 
228     setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
229 #endif
230 }
231 
232 /*
233  * Receive packet with synchronous timeout; timeout is adjusted
234  * to account for time spent waiting.
235  */
recv_time(int s,void * rbuf,int len,unsigned int flags,unsigned long * timeout_us_p)236 static int recv_time(int s, void *rbuf, int len, unsigned int flags,
237                      unsigned long *timeout_us_p)
238 {
239     fd_set fdset;
240     struct timeval tmv, t0, t1;
241     int rv, err;
242     unsigned long timeout_us = *timeout_us_p;
243     unsigned long timeout_left, dt;
244 
245     gettimeofday(&t0, NULL);
246     timeout_left = timeout_us;
247 
248     for (;;) {
249         FD_ZERO(&fdset);
250         FD_SET(s, &fdset);
251 
252         do {
253             tmv.tv_sec = timeout_left / 1000000;
254             tmv.tv_usec = timeout_left % 1000000;
255 
256             rv = select(s + 1, &fdset, NULL, NULL, &tmv);
257             err = errno;
258 
259             gettimeofday(&t1, NULL);
260 
261             dt = (t1.tv_sec - t0.tv_sec) * 1000000 +
262 		 (t1.tv_usec - t0.tv_usec);
263             *timeout_us_p = timeout_left =
264                 (dt >= timeout_us) ? 1 : (timeout_us - dt);
265         } while (rv == -1 && err == EINTR);
266 
267         if (rv == 0) {
268             timer(0);           /* Should not return */
269             return -1;
270         }
271 
272         set_socket_nonblock(s, 1);
273         rv = recv(s, rbuf, len, flags);
274         err = errno;
275         set_socket_nonblock(s, 0);
276 
277         if (rv < 0) {
278             if (E_WOULD_BLOCK(err) || err == EINTR) {
279                 continue;       /* Once again, with feeling... */
280             } else {
281                 errno = err;
282                 return rv;
283             }
284         } else {
285             return rv;
286         }
287     }
288 }
289 
split_port(char ** ap,char ** pp)290 static int split_port(char **ap, char **pp)
291 {
292     char *a, *p;
293     int  ret = AF_UNSPEC;
294 
295     a = *ap;
296 #ifdef HAVE_IPV6
297     if (is_numeric_ipv6(a)) {
298         if (*a++ != '[')
299             return -1;
300         *ap = a;
301         p = strrchr(a, ']');
302         if (!p)
303             return -1;
304         *p++ = 0;
305         a = p;
306         ret = AF_INET6;
307         p = strrchr(a, ':');
308         if (p)
309             *p++ = 0;
310     } else
311 #endif
312     {
313         struct in_addr in;
314 
315         p = strrchr(a, ':');
316         if (p)
317             *p++ = 0;
318         if (inet_aton(a, &in))
319             ret = AF_INET;
320     }
321     *pp = p;
322     return ret;
323 }
324 
325 enum long_only_options {
326     OPT_VERBOSITY	= 256,
327 };
328 
329 static struct option long_options[] = {
330     { "ipv4",        0, NULL, '4' },
331     { "ipv6",        0, NULL, '6' },
332     { "create",      0, NULL, 'c' },
333     { "secure",      0, NULL, 's' },
334     { "permissive",  0, NULL, 'p' },
335     { "verbose",     0, NULL, 'v' },
336     { "verbosity",   1, NULL, OPT_VERBOSITY },
337     { "version",     0, NULL, 'V' },
338     { "listen",      0, NULL, 'l' },
339     { "foreground",  0, NULL, 'L' },
340     { "address",     1, NULL, 'a' },
341     { "blocksize",   1, NULL, 'B' },
342     { "user",        1, NULL, 'u' },
343     { "umask",       1, NULL, 'U' },
344     { "refuse",      1, NULL, 'r' },
345     { "timeout",     1, NULL, 't' },
346     { "retransmit",  1, NULL, 'T' },
347     { "port-range",  1, NULL, 'R' },
348     { "map-file",    1, NULL, 'm' },
349     { "pidfile",     1, NULL, 'P' },
350     { NULL, 0, NULL, 0 }
351 };
352 static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
353 
main(int argc,char ** argv)354 int main(int argc, char **argv)
355 {
356     struct tftphdr *tp;
357     struct passwd *pw;
358     struct options *opt;
359     union sock_addr myaddr;
360     struct sockaddr_in bindaddr4;
361 #ifdef HAVE_IPV6
362     struct sockaddr_in6 bindaddr6;
363     int force_ipv6 = 0;
364 #endif
365     int n;
366     int fd = -1;
367     int fd4 = -1;
368     int fd6 = -1;
369     int fdmax = 0;
370     int standalone = 0;         /* Standalone (listen) mode */
371     int nodaemon = 0;           /* Do not detach process */
372     char *address = NULL;       /* Address to listen to */
373     pid_t pid;
374     mode_t my_umask = 0;
375     int spec_umask = 0;
376     int c;
377     int setrv;
378     int waittime = 900;         /* Default time to wait for a connect */
379     const char *user = "nobody";        /* Default user */
380     char *p, *ep;
381 #ifdef WITH_REGEX
382     char *rewrite_file = NULL;
383 #endif
384     const char *pidfile = NULL;
385     u_short tp_opcode;
386 
387     /* basename() is way too much of a pain from a portability standpoint */
388 
389     p = strrchr(argv[0], '/');
390     __progname = (p && p[1]) ? p + 1 : argv[0];
391 
392     tzset();
393     openlog(__progname, LOG_PID | LOG_NDELAY, LOG_FTP);
394 
395     srand(time(NULL) ^ getpid());
396 
397     while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
398            != -1)
399         switch (c) {
400         case '4':
401             ai_fam = AF_INET;
402             break;
403 #ifdef HAVE_IPV6
404         case '6':
405             ai_fam = AF_INET6;
406             force_ipv6 = 1;
407             break;
408 #endif
409         case 'c':
410             cancreate = 1;
411             break;
412         case 's':
413             secure = 1;
414             break;
415         case 'p':
416             unixperms = 1;
417             break;
418         case 'l':
419             standalone = 1;
420             break;
421         case 'L':
422             standalone = 1;
423             nodaemon = 1;
424             break;
425         case 'a':
426             address = optarg;
427             break;
428         case 't':
429             waittime = atoi(optarg);
430             break;
431         case 'B':
432             {
433                 char *vp;
434                 max_blksize = (unsigned int)strtoul(optarg, &vp, 10);
435                 if (max_blksize < 512 || max_blksize > MAX_SEGSIZE || *vp) {
436                     syslog(LOG_ERR,
437                            "Bad maximum blocksize value (range 512-%d): %s",
438                            MAX_SEGSIZE, optarg);
439                     exit(EX_USAGE);
440                 }
441             }
442             break;
443         case 'T':
444             {
445                 char *vp;
446                 unsigned long tov = strtoul(optarg, &vp, 10);
447                 if (tov < 10000UL || tov > 255000000UL || *vp) {
448                     syslog(LOG_ERR, "Bad timeout value: %s", optarg);
449                     exit(EX_USAGE);
450                 }
451                 rexmtval = timeout = tov;
452                 maxtimeout = rexmtval * TIMEOUT_LIMIT;
453             }
454             break;
455         case 'R':
456             {
457                 if (sscanf(optarg, "%u:%u", &portrange_from, &portrange_to)
458                     != 2 || portrange_from > portrange_to
459                     || portrange_to >= 65535) {
460                     syslog(LOG_ERR, "Bad port range: %s", optarg);
461                     exit(EX_USAGE);
462                 }
463                 portrange = 1;
464             }
465             break;
466         case 'u':
467             user = optarg;
468             break;
469         case 'U':
470             my_umask = strtoul(optarg, &ep, 8);
471             if (*ep) {
472                 syslog(LOG_ERR, "Invalid umask: %s", optarg);
473                 exit(EX_USAGE);
474             }
475             spec_umask = 1;
476             break;
477         case 'r':
478             for (opt = options; opt->o_opt; opt++) {
479                 if (!strcasecmp(optarg, opt->o_opt)) {
480                     opt->o_opt = "";    /* Don't support this option */
481                     break;
482                 }
483             }
484             if (!opt->o_opt) {
485                 syslog(LOG_ERR, "Unknown option: %s", optarg);
486                 exit(EX_USAGE);
487             }
488             break;
489 #ifdef WITH_REGEX
490         case 'm':
491             if (rewrite_file) {
492                 syslog(LOG_ERR, "Multiple -m options");
493                 exit(EX_USAGE);
494             }
495             rewrite_file = optarg;
496             break;
497 #endif
498         case 'v':
499             verbosity++;
500             break;
501         case OPT_VERBOSITY:
502             verbosity = atoi(optarg);
503             break;
504         case 'V':
505             /* Print configuration to stdout and exit */
506             printf("%s\n", TFTPD_CONFIG_STR);
507             exit(0);
508             break;
509         case 'P':
510             pidfile = optarg;
511             break;
512         default:
513             syslog(LOG_ERR, "Unknown option: '%c'", optopt);
514             break;
515         }
516 
517     dirs = xmalloc((argc - optind + 1) * sizeof(char *));
518     for (ndirs = 0; optind != argc; optind++)
519         dirs[ndirs++] = argv[optind];
520 
521     dirs[ndirs] = NULL;
522 
523     if (secure) {
524         if (ndirs == 0) {
525             syslog(LOG_ERR, "no -s directory");
526             exit(EX_USAGE);
527         }
528         if (ndirs > 1) {
529             syslog(LOG_ERR, "too many -s directories");
530             exit(EX_USAGE);
531         }
532         if (chdir(dirs[0])) {
533             syslog(LOG_ERR, "%s: %m", dirs[0]);
534             exit(EX_NOINPUT);
535         }
536     }
537 
538     pw = getpwnam(user);
539     if (!pw) {
540         syslog(LOG_ERR, "no user %s: %m", user);
541         exit(EX_NOUSER);
542     }
543 
544 #ifdef WITH_REGEX
545     if (rewrite_file)
546         rewrite_rules = read_remap_rules(rewrite_file);
547 #endif
548 
549     if (pidfile && !standalone) {
550         syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
551         pidfile = NULL;
552     }
553 
554     /* If we're running standalone, set up the input port */
555     if (standalone) {
556         FILE *pf;
557 #ifdef HAVE_IPV6
558         if (ai_fam != AF_INET6) {
559 #endif
560             fd4 = socket(AF_INET, SOCK_DGRAM, 0);
561             if (fd4 < 0) {
562                 syslog(LOG_ERR, "cannot open IPv4 socket: %m");
563                 exit(EX_OSERR);
564             }
565 #ifndef __CYGWIN__
566             set_socket_nonblock(fd4, 1);
567 #endif
568             memset(&bindaddr4, 0, sizeof bindaddr4);
569             bindaddr4.sin_family = AF_INET;
570             bindaddr4.sin_addr.s_addr = INADDR_ANY;
571             bindaddr4.sin_port = htons(IPPORT_TFTP);
572 #ifdef HAVE_IPV6
573         }
574         if (ai_fam != AF_INET) {
575             fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
576             if (fd6 < 0) {
577                 if (fd4 < 0) {
578                     syslog(LOG_ERR, "cannot open IPv6 socket: %m");
579                     exit(EX_OSERR);
580                 } else {
581                     syslog(LOG_ERR,
582                            "cannot open IPv6 socket, disable IPv6: %m");
583                 }
584             }
585 #ifndef __CYGWIN__
586             set_socket_nonblock(fd6, 1);
587 #endif
588             memset(&bindaddr6, 0, sizeof bindaddr6);
589             bindaddr6.sin6_family = AF_INET6;
590             bindaddr6.sin6_port = htons(IPPORT_TFTP);
591         }
592 #endif
593         if (address) {
594             char *portptr = NULL, *eportptr;
595             int err;
596             struct servent *servent;
597             unsigned long port;
598 
599             address = tfstrdup(address);
600             err = split_port(&address, &portptr);
601             switch (err) {
602             case AF_INET:
603 #ifdef HAVE_IPV6
604                 if (fd6 >= 0) {
605                     close(fd6);
606                     fd6 = -1;
607                     if (ai_fam == AF_INET6) {
608                         syslog(LOG_ERR,
609                                "Address %s is not in address family AF_INET6",
610                                address);
611                         exit(EX_USAGE);
612                     }
613                     ai_fam = AF_INET;
614                 }
615                 break;
616             case AF_INET6:
617                 if (fd4 >= 0) {
618                     close(fd4);
619                     fd4 = -1;
620                     if (ai_fam == AF_INET) {
621                         syslog(LOG_ERR,
622                                "Address %s is not in address family AF_INET",
623                                address);
624                         exit(EX_USAGE);
625                     }
626                     ai_fam = AF_INET6;
627                 }
628                 break;
629 #endif
630             case AF_UNSPEC:
631                 break;
632             default:
633                 syslog(LOG_ERR,
634                        "Numeric IPv6 addresses need to be enclosed in []");
635                 exit(EX_USAGE);
636             }
637             if (!portptr)
638                 portptr = (char *)"tftp";
639             if (*address) {
640                 if (fd4 >= 0) {
641                     bindaddr4.sin_family = AF_INET;
642                     err = set_sock_addr(address,
643                                         (union sock_addr *)&bindaddr4, NULL);
644                     if (err) {
645                         syslog(LOG_ERR,
646                                "cannot resolve local IPv4 bind address: %s, %s",
647                                address, gai_strerror(err));
648                         exit(EX_NOINPUT);
649                     }
650                 }
651 #ifdef HAVE_IPV6
652                 if (fd6 >= 0) {
653                     bindaddr6.sin6_family = AF_INET6;
654                     err = set_sock_addr(address,
655                                         (union sock_addr *)&bindaddr6, NULL);
656                     if (err) {
657                         if (fd4 >= 0) {
658                             syslog(LOG_ERR,
659                                    "cannot resolve local IPv6 bind address: %s"
660                                    "(%s); using IPv4 only",
661                                    address, gai_strerror(err));
662                             close(fd6);
663                             fd6 = -1;
664                         } else {
665                             syslog(LOG_ERR,
666                                    "cannot resolve local IPv6 bind address: %s"
667                                    "(%s)", address, gai_strerror(err));
668                             exit(EX_NOINPUT);
669                         }
670                     }
671                 }
672 #endif
673             } else {
674                 /* Default to using INADDR_ANY */
675             }
676 
677             if (portptr && *portptr) {
678                 servent = getservbyname(portptr, "udp");
679                 if (servent) {
680                     if (fd4 >= 0)
681                         bindaddr4.sin_port = servent->s_port;
682 #ifdef HAVE_IPV6
683                     if (fd6 >= 0)
684                         bindaddr6.sin6_port = servent->s_port;
685 #endif
686                 } else if ((port = strtoul(portptr, &eportptr, 0))
687                            && !*eportptr) {
688                     if (fd4 >= 0)
689                         bindaddr4.sin_port = htons(port);
690 #ifdef HAVE_IPV6
691                     if (fd6 >= 0)
692                         bindaddr6.sin6_port = htons(port);
693 #endif
694                 } else if (!strcmp(portptr, "tftp")) {
695                     /* It's TFTP, we're OK */
696                 } else {
697                     syslog(LOG_ERR, "cannot resolve local bind port: %s",
698                            portptr);
699                     exit(EX_NOINPUT);
700                 }
701             }
702         }
703 
704         if (fd4 >= 0) {
705             if (bind(fd4, (struct sockaddr *)&bindaddr4,
706               sizeof(bindaddr4)) < 0) {
707                 syslog(LOG_ERR, "cannot bind to local IPv4 socket: %m");
708                 exit(EX_OSERR);
709             }
710         }
711 #ifdef HAVE_IPV6
712         if (fd6 >= 0) {
713 #if defined(IPV6_V6ONLY)
714             int on = 1;
715             if (fd4 >= 0 || force_ipv6)
716                 if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on,
717                   sizeof(on)))
718                     syslog(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m");
719 #endif
720             if (bind(fd6, (struct sockaddr *)&bindaddr6,
721               sizeof(bindaddr6)) < 0) {
722                 if (fd4 >= 0) {
723                     syslog(LOG_ERR,
724                            "cannot bind to local IPv6 socket,"
725                            "IPv6 disabled: %m");
726                     close(fd6);
727                     fd6 = -1;
728                 } else {
729                     syslog(LOG_ERR, "cannot bind to local IPv6 socket: %m");
730                     exit(EX_OSERR);
731                 }
732             }
733         }
734 #endif
735         /* Daemonize this process */
736         /* Note: when running in secure mode (-s), we must not chdir, since
737            we are already in the proper directory. */
738         if (!nodaemon && daemon(secure, 0) < 0) {
739             syslog(LOG_ERR, "cannot daemonize: %m");
740             exit(EX_OSERR);
741         }
742         set_signal(SIGTERM, handle_exit, 0);
743         set_signal(SIGINT,  handle_exit, 0);
744         if (pidfile) {
745             pf = fopen (pidfile, "w");
746             if (!pf) {
747                 syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile);
748                 pidfile = NULL;
749             } else {
750                 if (fprintf(pf, "%d\n", getpid()) < 0)
751                     syslog(LOG_ERR, "error writing pid file '%s': %m", pidfile);
752                 if (fclose(pf))
753                     syslog(LOG_ERR, "error closing pid file '%s': %m", pidfile);
754             }
755         }
756         if (fd6 > fd4)
757             fdmax = fd6;
758         else
759             fdmax = fd4;
760     } else {
761         /* 0 is our socket descriptor */
762         close(1);
763         close(2);
764         fd = 0;
765         fdmax = 0;
766         /* Note: on Cygwin, select() on a nonblocking socket becomes
767            a nonblocking select. */
768 #ifndef __CYGWIN__
769         set_socket_nonblock(fd, 1);
770 #endif
771     }
772 
773     /* Disable path MTU discovery */
774     pmtu_discovery_off(fd);
775 
776     /* This means we don't want to wait() for children */
777 #ifdef SA_NOCLDWAIT
778     set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP | SA_NOCLDWAIT);
779 #else
780     set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP);
781 #endif
782 
783     /* Take SIGHUP and use it to set a variable.  This
784        is polled synchronously to make sure we don't
785        lose packets as a result. */
786     set_signal(SIGHUP, handle_sighup, 0);
787 
788     if (spec_umask || !unixperms)
789         umask(my_umask);
790 
791     while (1) {
792         fd_set readset;
793         struct timeval tv_waittime;
794         int rv;
795 
796         if (exit_signal) { /* happens in standalone mode only */
797             if (pidfile && unlink(pidfile)) {
798                 syslog(LOG_WARNING, "error removing pid file '%s': %m", pidfile);
799                 exit(EX_OSERR);
800             } else {
801                 exit(0);
802             }
803 	}
804 
805         if (caught_sighup) {
806             caught_sighup = 0;
807             if (standalone) {
808 #ifdef WITH_REGEX
809                 if (rewrite_file) {
810                     freerules(rewrite_rules);
811                     rewrite_rules = read_remap_rules(rewrite_file);
812                 }
813 #endif
814             } else {
815                 /* Return to inetd for respawn */
816                 exit(0);
817             }
818         }
819 
820         FD_ZERO(&readset);
821         if (standalone) {
822             if (fd4 >= 0) {
823                 FD_SET(fd4, &readset);
824 #ifdef __CYGWIN__
825                 /* On Cygwin, select() on a nonblocking socket returns
826                    immediately, with a rv of 0! */
827                 set_socket_nonblock(fd4, 0);
828 #endif
829             }
830             if (fd6 >= 0) {
831                 FD_SET(fd6, &readset);
832 #ifdef __CYGWIN__
833                 /* On Cygwin, select() on a nonblocking socket returns
834                    immediately, with a rv of 0! */
835                 set_socket_nonblock(fd6, 0);
836 #endif
837             }
838         } else { /* fd always 0 */
839             fd = 0;
840 #ifdef __CYGWIN__
841             /* On Cygwin, select() on a nonblocking socket returns
842                immediately, with a rv of 0! */
843             set_socket_nonblock(fd, 0);
844 #endif
845             FD_SET(fd, &readset);
846         }
847         tv_waittime.tv_sec = waittime;
848         tv_waittime.tv_usec = 0;
849 
850 
851         /* Never time out if we're in standalone mode */
852         rv = select(fdmax + 1, &readset, NULL, NULL,
853                     standalone ? NULL : &tv_waittime);
854         if (rv == -1 && errno == EINTR)
855             continue;           /* Signal caught, reloop */
856 
857         if (rv == -1) {
858             syslog(LOG_ERR, "select loop: %m");
859             exit(EX_IOERR);
860         } else if (rv == 0) {
861             exit(0);            /* Timeout, return to inetd */
862         }
863 
864         if (standalone) {
865             if ((fd4 >= 0) && FD_ISSET(fd4, &readset))
866                 fd = fd4;
867             else if ((fd6 >= 0) && FD_ISSET(fd6, &readset))
868                 fd = fd6;
869             else /* not in set ??? */
870                 continue;
871         }
872 #ifdef __CYGWIN__
873         /* On Cygwin, select() on a nonblocking socket returns
874            immediately, with a rv of 0! */
875         set_socket_nonblock(fd, 0);
876 #endif
877 
878         fromlen = sizeof(from);
879         n = myrecvfrom(fd, buf, sizeof(buf), 0,
880                        (struct sockaddr *)&from, &fromlen, &myaddr);
881 
882         if (n < 0) {
883             if (E_WOULD_BLOCK(errno) || errno == EINTR) {
884                 continue;       /* Again, from the top */
885             } else {
886                 syslog(LOG_ERR, "recvfrom: %m");
887                 exit(EX_IOERR);
888             }
889         }
890 #ifdef HAVE_IPV6
891         if ((from.sa.sa_family != AF_INET) && (from.sa.sa_family != AF_INET6)) {
892             syslog(LOG_ERR, "received address was not AF_INET/AF_INET6,"
893                    " please check your inetd config");
894 #else
895         if (from.sa.sa_family != AF_INET) {
896             syslog(LOG_ERR, "received address was not AF_INET,"
897                    " please check your inetd config");
898 #endif
899             exit(EX_PROTOCOL);
900         }
901 
902         if (standalone) {
903             if ((from.sa.sa_family == AF_INET) &&
904               (myaddr.si.sin_addr.s_addr == INADDR_ANY)) {
905                 /* myrecvfrom() didn't capture the source address; but we might
906                    have bound to a specific address, if so we should use it */
907                 memcpy(SOCKADDR_P(&myaddr), &bindaddr4.sin_addr,
908                        sizeof(bindaddr4.sin_addr));
909 #ifdef HAVE_IPV6
910             } else if ((from.sa.sa_family == AF_INET6) &&
911 		       IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)
912 					       SOCKADDR_P(&myaddr))) {
913 		memcpy(SOCKADDR_P(&myaddr), &bindaddr6.sin6_addr,
914 		       sizeof(bindaddr6.sin6_addr));
915 #endif
916             }
917         }
918 
919         /*
920          * Now that we have read the request packet from the UDP
921          * socket, we fork and go back to listening to the socket.
922          */
923         pid = fork();
924         if (pid < 0) {
925             syslog(LOG_ERR, "fork: %m");
926             exit(EX_OSERR);     /* Return to inetd, just in case */
927         } else if (pid == 0)
928             break;              /* Child exit, parent loop */
929     }
930 
931     /* Child process: handle the actual request here */
932 
933     /* Ignore SIGHUP */
934     set_signal(SIGHUP, SIG_IGN, 0);
935 
936     /* Make sure the log socket is still connected.  This has to be
937        done before the chroot, while /dev/log is still accessible.
938        When not running standalone, there is little chance that the
939        syslog daemon gets restarted by the time we get here. */
940     if (secure && standalone) {
941         closelog();
942         tzset();
943 	openlog(__progname, LOG_PID | LOG_NDELAY, LOG_FTP);
944     }
945 
946 #ifdef HAVE_TCPWRAPPERS
947     /* Verify if this was a legal request for us.  This has to be
948        done before the chroot, while /etc is still accessible. */
949     request_init(&wrap_request,
950                  RQ_DAEMON, __progname,
951                  RQ_FILE, fd,
952                  RQ_CLIENT_SIN, &from, RQ_SERVER_SIN, &myaddr, 0);
953     sock_methods(&wrap_request);
954 
955     tmp_p = (char *)inet_ntop(myaddr.sa.sa_family, SOCKADDR_P(&myaddr),
956                               tmpbuf, INET6_ADDRSTRLEN);
957     if (!tmp_p) {
958         tmp_p = tmpbuf;
959         strcpy(tmpbuf, "???");
960     }
961     if (hosts_access(&wrap_request) == 0) {
962         if (deny_severity != -1)
963             syslog(deny_severity, "connection refused from %s", tmp_p);
964         exit(EX_NOPERM);        /* Access denied */
965     } else if (allow_severity != -1) {
966         syslog(allow_severity, "connect from %s", tmp_p);
967     }
968 #endif
969 
970     /* Close file descriptors we don't need */
971     close(fd);
972 
973     /* Get a socket.  This has to be done before the chroot(), since
974        some systems require access to /dev to create a socket. */
975 
976     peer = socket(myaddr.sa.sa_family, SOCK_DGRAM, 0);
977     if (peer < 0) {
978         syslog(LOG_ERR, "socket: %m");
979         exit(EX_IOERR);
980     }
981 
982     /* Set up the supplementary group access list if possible */
983     /* /etc/group still need to be accessible at this point */
984 #ifdef HAVE_INITGROUPS
985     setrv = initgroups(user, pw->pw_gid);
986     if (setrv) {
987         syslog(LOG_ERR, "cannot set groups for user %s", user);
988         exit(EX_OSERR);
989     }
990 #else
991 #ifdef HAVE_SETGROUPS
992     if (setgroups(0, NULL)) {
993         syslog(LOG_ERR, "cannot clear group list");
994     }
995 #endif
996 #endif
997 
998     /* Chroot and drop privileges */
999     if (secure) {
1000         if (chroot(".")) {
1001             syslog(LOG_ERR, "chroot: %m");
1002             exit(EX_OSERR);
1003         }
1004 #ifdef __CYGWIN__
1005         chdir("/");             /* Cygwin chroot() bug workaround */
1006 #endif
1007     }
1008 #ifdef HAVE_SETREGID
1009     setrv = setregid(pw->pw_gid, pw->pw_gid);
1010 #else
1011     setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid);
1012 #endif
1013 
1014 #ifdef HAVE_SETREUID
1015     setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid);
1016 #else
1017     /* Important: setuid() must come first */
1018     setrv = setrv || setuid(pw->pw_uid) ||
1019         (geteuid() != pw->pw_uid && seteuid(pw->pw_uid));
1020 #endif
1021 
1022     if (setrv) {
1023         syslog(LOG_ERR, "cannot drop privileges: %m");
1024         exit(EX_OSERR);
1025     }
1026 
1027     /* Process the request... */
1028     if (pick_port_bind(peer, &myaddr, portrange_from, portrange_to) < 0) {
1029         syslog(LOG_ERR, "bind: %m");
1030         exit(EX_IOERR);
1031     }
1032 
1033     if (connect(peer, &from.sa, SOCKLEN(&from)) < 0) {
1034         syslog(LOG_ERR, "connect: %m");
1035         exit(EX_IOERR);
1036     }
1037 
1038     /* Disable path MTU discovery */
1039     pmtu_discovery_off(peer);
1040 
1041     tp = (struct tftphdr *)buf;
1042     tp_opcode = ntohs(tp->th_opcode);
1043     if (tp_opcode == RRQ || tp_opcode == WRQ)
1044         tftp(tp, n);
1045     exit(0);
1046 }
1047 
1048 static char *rewrite_access(char *, int, const char **);
1049 static int validate_access(char *, int, const struct formats *, const char **);
1050 static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
1051 static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
1052 
1053 struct formats {
1054     const char *f_mode;
1055     char *(*f_rewrite) (char *, int, const char **);
1056     int (*f_validate) (char *, int, const struct formats *, const char **);
1057     void (*f_send) (const struct formats *, struct tftphdr *, int);
1058     void (*f_recv) (const struct formats *, struct tftphdr *, int);
1059     int f_convert;
1060 };
1061 static const struct formats formats[] = {
1062     {
1063     "netascii", rewrite_access, validate_access, tftp_sendfile,
1064             tftp_recvfile, 1}, {
1065     "octet", rewrite_access, validate_access, tftp_sendfile,
1066             tftp_recvfile, 0}, {
1067     NULL, NULL, NULL, NULL, NULL, 0}
1068 };
1069 
1070 /*
1071  * Handle initial connection protocol.
1072  */
1073 int tftp(struct tftphdr *tp, int size)
1074 {
1075     char *cp, *end;
1076     int argn, ecode;
1077     const struct formats *pf = NULL;
1078     char *origfilename;
1079     char *filename, *mode = NULL;
1080     const char *errmsgptr;
1081     u_short tp_opcode = ntohs(tp->th_opcode);
1082 
1083     char *val = NULL, *opt = NULL;
1084     char *ap = ackbuf + 2;
1085 
1086     ((struct tftphdr *)ackbuf)->th_opcode = htons(OACK);
1087 
1088     origfilename = cp = (char *)&(tp->th_stuff);
1089     argn = 0;
1090 
1091     end = (char *)tp + size;
1092 
1093     while (cp < end && *cp) {
1094         do {
1095             cp++;
1096         } while (cp < end && *cp);
1097 
1098         if (*cp) {
1099             nak(EBADOP, "Request not null-terminated");
1100             exit(0);
1101         }
1102 
1103         argn++;
1104         if (argn == 1) {
1105             mode = ++cp;
1106         } else if (argn == 2) {
1107             for (cp = mode; *cp; cp++)
1108                 *cp = tolower(*cp);
1109             for (pf = formats; pf->f_mode; pf++) {
1110                 if (!strcmp(pf->f_mode, mode))
1111                     break;
1112             }
1113             if (!pf->f_mode) {
1114                 nak(EBADOP, "Unknown mode");
1115                 exit(0);
1116             }
1117             if (!(filename =
1118                   (*pf->f_rewrite) (origfilename, tp_opcode,
1119                                     &errmsgptr))) {
1120                 nak(EACCESS, errmsgptr);        /* File denied by mapping rule */
1121                 exit(0);
1122             }
1123             if (verbosity >= 1) {
1124                 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1125                                           tmpbuf, INET6_ADDRSTRLEN);
1126                 if (!tmp_p) {
1127                     tmp_p = tmpbuf;
1128                     strcpy(tmpbuf, "???");
1129                 }
1130                 if (filename == origfilename
1131                     || !strcmp(filename, origfilename))
1132                     syslog(LOG_NOTICE, "%s from %s filename %s\n",
1133                            tp_opcode == WRQ ? "WRQ" : "RRQ",
1134                            tmp_p, filename);
1135                 else
1136                     syslog(LOG_NOTICE,
1137                            "%s from %s filename %s remapped to %s\n",
1138                            tp_opcode == WRQ ? "WRQ" : "RRQ",
1139                            tmp_p, origfilename,
1140                            filename);
1141             }
1142             ecode =
1143                 (*pf->f_validate) (filename, tp_opcode, pf, &errmsgptr);
1144             if (ecode) {
1145                 nak(ecode, errmsgptr);
1146                 exit(0);
1147             }
1148             opt = ++cp;
1149         } else if (argn & 1) {
1150             val = ++cp;
1151         } else {
1152             do_opt(opt, val, &ap);
1153             opt = ++cp;
1154         }
1155     }
1156 
1157     if (!pf) {
1158         nak(EBADOP, "Missing mode");
1159         exit(0);
1160     }
1161 
1162     if (ap != (ackbuf + 2)) {
1163         if (tp_opcode == WRQ)
1164             (*pf->f_recv) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1165         else
1166             (*pf->f_send) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1167     } else {
1168         if (tp_opcode == WRQ)
1169             (*pf->f_recv) (pf, NULL, 0);
1170         else
1171             (*pf->f_send) (pf, NULL, 0);
1172     }
1173     exit(0);                    /* Request completed */
1174 }
1175 
1176 static int blksize_set;
1177 
1178 /*
1179  * Set a non-standard block size (c.f. RFC2348)
1180  */
1181 static int set_blksize(uintmax_t *vp)
1182 {
1183     uintmax_t sz = *vp;
1184 
1185     if (blksize_set)
1186         return 0;
1187 
1188     if (sz < 8)
1189         return 0;
1190     else if (sz > max_blksize)
1191         sz = max_blksize;
1192 
1193     *vp = segsize = sz;
1194     blksize_set = 1;
1195     return 1;
1196 }
1197 
1198 /*
1199  * Set a power-of-two block size (nonstandard)
1200  */
1201 static int set_blksize2(uintmax_t *vp)
1202 {
1203     uintmax_t sz = *vp;
1204 
1205     if (blksize_set)
1206         return 0;
1207 
1208     if (sz < 8)
1209         return (0);
1210     else if (sz > max_blksize)
1211         sz = max_blksize;
1212     else
1213 
1214     /* Convert to a power of two */
1215     if (sz & (sz - 1)) {
1216         unsigned int sz1 = 1;
1217         /* Not a power of two - need to convert */
1218         while (sz >>= 1)
1219             sz1 <<= 1;
1220         sz = sz1;
1221     }
1222 
1223     *vp = segsize = sz;
1224     blksize_set = 1;
1225     return 1;
1226 }
1227 
1228 /*
1229  * Set the block number rollover value
1230  */
1231 static int set_rollover(uintmax_t *vp)
1232 {
1233     uintmax_t ro = *vp;
1234 
1235     if (ro > 65535)
1236 	return 0;
1237 
1238     rollover_val = (uint16_t)ro;
1239     return 1;
1240 }
1241 
1242 /*
1243  * Return a file size (c.f. RFC2349)
1244  * For netascii mode, we don't know the size ahead of time;
1245  * so reject the option.
1246  */
1247 static int set_tsize(uintmax_t *vp)
1248 {
1249     uintmax_t sz = *vp;
1250 
1251     if (!tsize_ok)
1252         return 0;
1253 
1254     if (sz == 0)
1255         sz = tsize;
1256 
1257     *vp = sz;
1258     return 1;
1259 }
1260 
1261 /*
1262  * Set the timeout (c.f. RFC2349).  This is supposed
1263  * to be the (default) retransmission timeout, but being an
1264  * integer in seconds it seems a bit limited.
1265  */
1266 static int set_timeout(uintmax_t *vp)
1267 {
1268     uintmax_t to = *vp;
1269 
1270     if (to < 1 || to > 255)
1271         return 0;
1272 
1273     rexmtval = timeout = to * 1000000UL;
1274     maxtimeout = rexmtval * TIMEOUT_LIMIT;
1275 
1276     return 1;
1277 }
1278 
1279 /* Similar, but in microseconds.  We allow down to 10 ms. */
1280 static int set_utimeout(uintmax_t *vp)
1281 {
1282     uintmax_t to = *vp;
1283 
1284     if (to < 10000UL || to > 255000000UL)
1285         return 0;
1286 
1287     rexmtval = timeout = to;
1288     maxtimeout = rexmtval * TIMEOUT_LIMIT;
1289 
1290     return 1;
1291 }
1292 
1293 /*
1294  * Conservative calculation for the size of a buffer which can hold an
1295  * arbitrary integer
1296  */
1297 #define OPTBUFSIZE	(sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
1298 
1299 /*
1300  * Parse RFC2347 style options; we limit the arguments to positive
1301  * integers which matches all our current options.
1302  */
1303 static void do_opt(const char *opt, const char *val, char **ap)
1304 {
1305     struct options *po;
1306     char retbuf[OPTBUFSIZE];
1307     char *p = *ap;
1308     size_t optlen, retlen;
1309     char *vend;
1310     uintmax_t v;
1311 
1312     /* Global option-parsing variables initialization */
1313     blksize_set = 0;
1314 
1315     if (!*opt || !*val)
1316         return;
1317 
1318     errno = 0;
1319     v = strtoumax(val, &vend, 10);
1320     if (*vend || errno == ERANGE)
1321 	return;
1322 
1323     for (po = options; po->o_opt; po++)
1324         if (!strcasecmp(po->o_opt, opt)) {
1325             if (po->o_fnc(&v)) {
1326 		optlen = strlen(opt);
1327 		retlen = sprintf(retbuf, "%"PRIuMAX, v);
1328 
1329                 if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
1330                     nak(EOPTNEG, "Insufficient space for options");
1331                     exit(0);
1332                 }
1333 
1334 		memcpy(p, opt, optlen+1);
1335 		p += optlen+1;
1336 		memcpy(p, retbuf, retlen+1);
1337 		p += retlen+1;
1338             } else {
1339                 nak(EOPTNEG, "Unsupported option(s) requested");
1340                 exit(0);
1341             }
1342             break;
1343         }
1344 
1345     *ap = p;
1346 }
1347 
1348 #ifdef WITH_REGEX
1349 
1350 /*
1351  * This is called by the remap engine when it encounters macros such
1352  * as \i.  It should write the output in "output" if non-NULL, and
1353  * return the length of the output (generated or not).
1354  *
1355  * Return -1 on failure.
1356  */
1357 static int rewrite_macros(char macro, char *output)
1358 {
1359     char *p, tb[INET6_ADDRSTRLEN];
1360     int l=0;
1361 
1362     switch (macro) {
1363     case 'i':
1364         p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1365                               tb, INET6_ADDRSTRLEN);
1366         if (output && p)
1367             strcpy(output, p);
1368         if (!p)
1369             return 0;
1370         else
1371             return strlen(p);
1372 
1373     case 'x':
1374         if (output) {
1375             if (from.sa.sa_family == AF_INET) {
1376                 sprintf(output, "%08lX",
1377                     (unsigned long)ntohl(from.si.sin_addr.s_addr));
1378                 l = 8;
1379 #ifdef HAVE_IPV6
1380             } else {
1381                 unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
1382                 p = tb;
1383                 for (l = 0; l < 16; l++) {
1384                     sprintf(p, "%02X", *c);
1385                     c++;
1386                     p += 2;
1387                 }
1388                 strcpy(output, tb);
1389                 l = strlen(tb);
1390 #endif
1391             }
1392         }
1393         return l;
1394 
1395     default:
1396         return -1;
1397     }
1398 }
1399 
1400 /*
1401  * Modify the filename, if applicable.  If it returns NULL, deny the access.
1402  */
1403 static char *rewrite_access(char *filename, int mode, const char **msg)
1404 {
1405     if (rewrite_rules) {
1406         char *newname =
1407             rewrite_string(filename, rewrite_rules,
1408 			   mode != RRQ ? 'P' : 'G',
1409                            rewrite_macros, msg);
1410         filename = newname;
1411     }
1412     return filename;
1413 }
1414 
1415 #else
1416 static char *rewrite_access(char *filename, int mode, const char **msg)
1417 {
1418     (void)mode;                 /* Avoid warning */
1419     (void)msg;
1420     return filename;
1421 }
1422 #endif
1423 
1424 static FILE *file;
1425 /*
1426  * Validate file access.  Since we
1427  * have no uid or gid, for now require
1428  * file to exist and be publicly
1429  * readable/writable, unless -p specified.
1430  * If we were invoked with arguments
1431  * from inetd then the file must also be
1432  * in one of the given directory prefixes.
1433  * Note also, full path name must be
1434  * given as we have no login directory.
1435  */
1436 static int validate_access(char *filename, int mode,
1437 			   const struct formats *pf, const char **errmsg)
1438 {
1439     struct stat stbuf;
1440     int i, len;
1441     int fd, wmode, rmode;
1442     char *cp;
1443     const char **dirp;
1444     char stdio_mode[3];
1445 
1446     tsize_ok = 0;
1447     *errmsg = NULL;
1448 
1449     if (!secure) {
1450         if (*filename != '/') {
1451             *errmsg = "Only absolute filenames allowed";
1452             return (EACCESS);
1453         }
1454 
1455         /*
1456          * prevent tricksters from getting around the directory
1457          * restrictions
1458          */
1459         len = strlen(filename);
1460         for (i = 1; i < len - 3; i++) {
1461             cp = filename + i;
1462             if (*cp == '.' && memcmp(cp - 1, "/../", 4) == 0) {
1463                 *errmsg = "Reverse path not allowed";
1464                 return (EACCESS);
1465             }
1466         }
1467 
1468         for (dirp = dirs; *dirp; dirp++)
1469             if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
1470                 break;
1471         if (*dirp == 0 && dirp != dirs) {
1472             *errmsg = "Forbidden directory";
1473             return (EACCESS);
1474         }
1475     }
1476 
1477     /*
1478      * We use different a different permissions scheme if `cancreate' is
1479      * set.
1480      */
1481     wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
1482     rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY);
1483 
1484 #ifndef HAVE_FTRUNCATE
1485     wmode |= O_TRUNC;		/* This really sucks on a dupe */
1486 #endif
1487 
1488     fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
1489     if (fd < 0) {
1490         switch (errno) {
1491         case ENOENT:
1492         case ENOTDIR:
1493             return ENOTFOUND;
1494         case ENOSPC:
1495             return ENOSPACE;
1496         case EEXIST:
1497             return EEXISTS;
1498         default:
1499             return errno + 100;
1500         }
1501     }
1502 
1503     if (fstat(fd, &stbuf) < 0)
1504         exit(EX_OSERR);         /* This shouldn't happen */
1505 
1506     /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */
1507     if (lock_file(fd, mode != RRQ))
1508 	exit(0);
1509 
1510     if (mode == RRQ) {
1511         if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) {
1512             *errmsg = "File must have global read permissions";
1513             return (EACCESS);
1514         }
1515         tsize = stbuf.st_size;
1516         /* We don't know the tsize if conversion is needed */
1517         tsize_ok = !pf->f_convert;
1518     } else {
1519         if (!unixperms) {
1520             if ((stbuf.st_mode & (S_IWRITE >> 6)) == 0) {
1521                 *errmsg = "File must have global write permissions";
1522                 return (EACCESS);
1523             }
1524         }
1525 
1526 #ifdef HAVE_FTRUNCATE
1527 	/* We didn't get to truncate the file at open() time */
1528 	if (ftruncate(fd, (off_t) 0)) {
1529 	  *errmsg = "Cannot reset file size";
1530 	  return (EACCESS);
1531 	}
1532 #endif
1533         tsize = 0;
1534         tsize_ok = 1;
1535     }
1536 
1537     stdio_mode[0] = (mode == RRQ) ? 'r' : 'w';
1538     stdio_mode[1] = (pf->f_convert) ? 't' : 'b';
1539     stdio_mode[2] = '\0';
1540 
1541     file = fdopen(fd, stdio_mode);
1542     if (file == NULL)
1543         exit(EX_OSERR);         /* Internal error */
1544 
1545     return (0);
1546 }
1547 
1548 /*
1549  * Send the requested file.
1550  */
1551 static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
1552 {
1553     struct tftphdr *dp;
1554     struct tftphdr *ap;         /* ack packet */
1555     static u_short block = 1;   /* Static to avoid longjmp funnies */
1556     u_short ap_opcode, ap_block;
1557     unsigned long r_timeout;
1558     int size, n;
1559 
1560     if (oap) {
1561         timeout = rexmtval;
1562         (void)sigsetjmp(timeoutbuf, 1);
1563       oack:
1564         r_timeout = timeout;
1565         if (send(peer, oap, oacklen, 0) != oacklen) {
1566             syslog(LOG_WARNING, "tftpd: oack: %m\n");
1567             goto abort;
1568         }
1569         for (;;) {
1570             n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1571             if (n < 0) {
1572                 syslog(LOG_WARNING, "tftpd: read: %m\n");
1573                 goto abort;
1574             }
1575             ap = (struct tftphdr *)ackbuf;
1576             ap_opcode = ntohs((u_short) ap->th_opcode);
1577             ap_block = ntohs((u_short) ap->th_block);
1578 
1579             if (ap_opcode == ERROR) {
1580                 syslog(LOG_WARNING,
1581                        "tftp: client does not accept options\n");
1582                 goto abort;
1583             }
1584             if (ap_opcode == ACK) {
1585                 if (ap_block == 0)
1586                     break;
1587                 /* Resynchronize with the other side */
1588                 (void)synchnet(peer);
1589                 goto oack;
1590             }
1591         }
1592     }
1593 
1594     dp = r_init();
1595     do {
1596         size = readit(file, &dp, pf->f_convert);
1597         if (size < 0) {
1598             nak(errno + 100, NULL);
1599             goto abort;
1600         }
1601         dp->th_opcode = htons((u_short) DATA);
1602         dp->th_block = htons((u_short) block);
1603         timeout = rexmtval;
1604         (void)sigsetjmp(timeoutbuf, 1);
1605 
1606         r_timeout = timeout;
1607         if (send(peer, dp, size + 4, 0) != size + 4) {
1608             syslog(LOG_WARNING, "tftpd: write: %m");
1609             goto abort;
1610         }
1611         read_ahead(file, pf->f_convert);
1612         for (;;) {
1613             n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1614             if (n < 0) {
1615                 syslog(LOG_WARNING, "tftpd: read(ack): %m");
1616                 goto abort;
1617             }
1618             ap = (struct tftphdr *)ackbuf;
1619             ap_opcode = ntohs((u_short) ap->th_opcode);
1620             ap_block = ntohs((u_short) ap->th_block);
1621 
1622             if (ap_opcode == ERROR)
1623                 goto abort;
1624 
1625             if (ap_opcode == ACK) {
1626                 if (ap_block == block) {
1627                     break;
1628                 }
1629                 /* Re-synchronize with the other side */
1630                 (void)synchnet(peer);
1631                 /*
1632                  * RFC1129/RFC1350: We MUST NOT re-send the DATA
1633                  * packet in response to an invalid ACK.  Doing so
1634                  * would cause the Sorcerer's Apprentice bug.
1635                  */
1636             }
1637 
1638         }
1639 	if (!++block)
1640 	  block = rollover_val;
1641     } while (size == segsize);
1642   abort:
1643     (void)fclose(file);
1644 }
1645 
1646 /*
1647  * Receive a file.
1648  */
1649 static void tftp_recvfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
1650 {
1651     struct tftphdr *dp;
1652     int n, size;
1653     /* These are "static" to avoid longjmp funnies */
1654     static struct tftphdr *ap;  /* ack buffer */
1655     static u_short block = 0;
1656     static int acksize;
1657     u_short dp_opcode, dp_block;
1658     unsigned long r_timeout;
1659 
1660     dp = w_init();
1661     do {
1662         timeout = rexmtval;
1663 
1664         if (!block && oap) {
1665             ap = (struct tftphdr *)ackbuf;
1666             acksize = oacklen;
1667         } else {
1668             ap = (struct tftphdr *)ackbuf;
1669             ap->th_opcode = htons((u_short) ACK);
1670             ap->th_block = htons((u_short) block);
1671             acksize = 4;
1672             /* If we're sending a regular ACK, that means we have successfully
1673              * sent the OACK. Clear oap so that we won't try to send another
1674              * OACK when the block number wraps back to 0. */
1675             oap = NULL;
1676         }
1677         if (!++block)
1678 	  block = rollover_val;
1679         (void)sigsetjmp(timeoutbuf, 1);
1680       send_ack:
1681         r_timeout = timeout;
1682         if (send(peer, ackbuf, acksize, 0) != acksize) {
1683             syslog(LOG_WARNING, "tftpd: write(ack): %m");
1684             goto abort;
1685         }
1686         write_behind(file, pf->f_convert);
1687         for (;;) {
1688             n = recv_time(peer, dp, PKTSIZE, 0, &r_timeout);
1689             if (n < 0) {        /* really? */
1690                 syslog(LOG_WARNING, "tftpd: read: %m");
1691                 goto abort;
1692             }
1693             dp_opcode = ntohs((u_short) dp->th_opcode);
1694             dp_block = ntohs((u_short) dp->th_block);
1695             if (dp_opcode == ERROR)
1696                 goto abort;
1697             if (dp_opcode == DATA) {
1698                 if (dp_block == block) {
1699                     break;      /* normal */
1700                 }
1701                 /* Re-synchronize with the other side */
1702                 (void)synchnet(peer);
1703                 if (dp_block == (block - 1))
1704                     goto send_ack;      /* rexmit */
1705             }
1706         }
1707         /*  size = write(file, dp->th_data, n - 4); */
1708         size = writeit(file, &dp, n - 4, pf->f_convert);
1709         if (size != (n - 4)) {  /* ahem */
1710             if (size < 0)
1711                 nak(errno + 100, NULL);
1712             else
1713                 nak(ENOSPACE, NULL);
1714             goto abort;
1715         }
1716     } while (size == segsize);
1717     write_behind(file, pf->f_convert);
1718     (void)fclose(file);         /* close data file */
1719 
1720     ap->th_opcode = htons((u_short) ACK);       /* send the "final" ack */
1721     ap->th_block = htons((u_short) (block));
1722     (void)send(peer, ackbuf, 4, 0);
1723 
1724     timeout_quit = 1;           /* just quit on timeout */
1725     n = recv_time(peer, buf, sizeof(buf), 0, &timeout); /* normally times out and quits */
1726     timeout_quit = 0;
1727 
1728     if (n >= 4 &&               /* if read some data */
1729         dp_opcode == DATA &&    /* and got a data block */
1730         block == dp_block) {    /* then my last ack was lost */
1731         (void)send(peer, ackbuf, 4, 0); /* resend final ack */
1732     }
1733   abort:
1734     return;
1735 }
1736 
1737 static const char *const errmsgs[] = {
1738     "Undefined error code",     /* 0 - EUNDEF */
1739     "File not found",           /* 1 - ENOTFOUND */
1740     "Access denied",            /* 2 - EACCESS */
1741     "Disk full or allocation exceeded", /* 3 - ENOSPACE */
1742     "Illegal TFTP operation",   /* 4 - EBADOP */
1743     "Unknown transfer ID",      /* 5 - EBADID */
1744     "File already exists",      /* 6 - EEXISTS */
1745     "No such user",             /* 7 - ENOUSER */
1746     "Failure to negotiate RFC2347 options"      /* 8 - EOPTNEG */
1747 };
1748 
1749 #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *))
1750 
1751 /*
1752  * Send a nak packet (error message).
1753  * Error code passed in is one of the
1754  * standard TFTP codes, or a UNIX errno
1755  * offset by 100.
1756  */
1757 static void nak(int error, const char *msg)
1758 {
1759     struct tftphdr *tp;
1760     int length;
1761 
1762     tp = (struct tftphdr *)buf;
1763     tp->th_opcode = htons((u_short) ERROR);
1764 
1765     if (error >= 100) {
1766         /* This is a Unix errno+100 */
1767         if (!msg)
1768             msg = strerror(error - 100);
1769         error = EUNDEF;
1770     } else {
1771         if ((unsigned)error >= ERR_CNT)
1772             error = EUNDEF;
1773 
1774         if (!msg)
1775             msg = errmsgs[error];
1776     }
1777 
1778     tp->th_code = htons((u_short) error);
1779 
1780     length = strlen(msg) + 1;
1781     memcpy(tp->th_msg, msg, length);
1782     length += 4;                /* Add space for header */
1783 
1784     if (verbosity >= 2) {
1785         tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1786                                   tmpbuf, INET6_ADDRSTRLEN);
1787         if (!tmp_p) {
1788             tmp_p = tmpbuf;
1789             strcpy(tmpbuf, "???");
1790         }
1791         syslog(LOG_INFO, "sending NAK (%d, %s) to %s",
1792                error, tp->th_msg, tmp_p);
1793     }
1794 
1795     if (send(peer, buf, length, 0) != length)
1796         syslog(LOG_WARNING, "nak: %m");
1797 }
1798