autoconf: modernize and modularize
[tftp-hpa.git] / tftpd / tftpd.c
blobbec0f34940e5b7082681f055a23e78dfe08b67d8
1 /*
2 * Copyright (c) 1983 Regents of the University of California.
3 * Copyright (c) 1999-2009 H. Peter Anvin
4 * Copyright (c) 2011-2014 Intel Corporation; author: H. Peter Anvin
5 * All rights reserved.
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.
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.
36 #include "config.h" /* Must be included first */
37 #include "tftpd.h"
40 * Trivial file transfer protocol server.
42 * This version includes many modifications by Jim Guyton <guyton@rand-unix>
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>
52 #include "common/tftpsubs.h"
53 #include "recvfrom.h"
54 #include "remap.h"
56 #ifdef HAVE_SYS_FILIO_H
57 #include <sys/filio.h> /* Necessary for FIONBIO on Solaris */
58 #endif
60 #ifdef HAVE_TCPWRAPPERS
61 #include <tcpd.h>
63 int deny_severity = LOG_WARNING;
64 int allow_severity = -1; /* Don't log at all */
66 static struct request_info wrap_request;
67 #endif
69 #ifdef HAVE_IPV6
70 static int ai_fam = AF_UNSPEC;
71 #else
72 static int ai_fam = AF_INET;
73 #endif
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)
79 const char *tftpd_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;
88 #define PKTSIZE MAX_SEGSIZE+4
89 static char buf[PKTSIZE];
90 static char ackbuf[PKTSIZE];
91 static unsigned int max_blksize = MAX_SEGSIZE;
93 static char tmpbuf[INET6_ADDRSTRLEN], *tmp_p;
95 static union sock_addr from;
96 static off_t tsize;
97 static int tsize_ok;
99 static int ndirs;
100 static const char **dirs;
102 static int secure = 0;
103 int cancreate = 0;
104 int unixperms = 0;
105 int portrange = 0;
106 unsigned int portrange_from, portrange_to;
107 int verbosity = 0;
109 #ifdef WITH_REGEX
110 static struct rule *rewrite_rules = NULL;
111 #endif
113 static FILE *file;
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 **);
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 *);
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}
140 /* Simple handler for SIGHUP */
141 static volatile sig_atomic_t caught_sighup = 0;
142 static void handle_sighup(int sig)
144 (void)sig; /* Suppress unused warning */
145 caught_sighup = 1;
148 /* Handle exit requests by SIGTERM and SIGINT */
149 static volatile sig_atomic_t exit_signal = 0;
150 static void handle_exit(int sig)
152 exit_signal = sig;
155 /* Handle timeout signal or timeout event */
156 static void timer(int sig)
158 (void)sig; /* Suppress unused warning */
159 timeout <<= 1;
160 if (timeout >= maxtimeout || timeout_quit)
161 exit(0);
162 siglongjmp(timeoutbuf, 1);
165 #ifdef WITH_REGEX
166 static struct rule *read_remap_rules(const char *rulefile)
168 FILE *f;
169 struct rule *rulep;
171 f = fopen(rulefile, "rt");
172 if (!f) {
173 syslog(LOG_ERR, "Cannot open map file: %s: %m", rulefile);
174 exit(EX_NOINPUT);
176 rulep = parserulefile(f);
177 fclose(f);
179 return rulep;
181 #endif
184 * Rules for locking files; return 0 on success, -1 on failure
186 static int lock_file(int fd, int lock_write)
188 (void)lock_write;
189 #if defined(HAVE_FCNTL) && HAVE_DECL_F_SETLK
190 struct flock fl;
192 fl.l_type = lock_write ? F_WRLCK : F_RDLCK;
193 fl.l_whence = SEEK_SET;
194 fl.l_start = 0;
195 fl.l_len = 0; /* Whole file */
196 return fcntl(fd, F_SETLK, &fl);
197 #elif defined(HAVE_FLOCK) && HAVE_DECL_LOCK_SH && HAVE_DECL_LOCK_EX
198 return flock(fd, lock_write ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB);
199 #else
200 return 0; /* Hope & pray... */
201 #endif
204 static void set_socket_nonblock(int fd, int flag)
206 int err;
207 int flags;
208 #if defined(HAVE_FCNTL) && defined(HAVE_O_NONBLOCK_DEFINITION)
209 /* Posixly correct */
210 err = ((flags = fcntl(fd, F_GETFL, 0)) < 0) ||
211 (fcntl
212 (fd, F_SETFL,
213 flag ? flags | O_NONBLOCK : flags & ~O_NONBLOCK) < 0);
214 #else
215 flags = flag ? 1 : 0;
216 err = (ioctl(fd, FIONBIO, &flags) < 0);
217 #endif
218 if (err) {
219 syslog(LOG_ERR, "Cannot set nonblock flag on socket: %m");
220 exit(EX_OSERR);
224 static void pmtu_discovery_off(int fd)
226 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
227 int pmtu = IP_PMTUDISC_DONT;
229 setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
230 #endif
234 * Receive packet with synchronous timeout; timeout is adjusted
235 * to account for time spent waiting.
237 static int recv_time(int s, void *rbuf, int len, unsigned int flags,
238 unsigned long *timeout_us_p)
240 fd_set fdset;
241 struct timeval tmv, t0, t1;
242 int rv, err;
243 unsigned long timeout_us = *timeout_us_p;
244 unsigned long timeout_left, dt;
246 gettimeofday(&t0, NULL);
247 timeout_left = timeout_us;
249 for (;;) {
250 FD_ZERO(&fdset);
251 FD_SET(s, &fdset);
253 do {
254 tmv.tv_sec = timeout_left / 1000000;
255 tmv.tv_usec = timeout_left % 1000000;
257 rv = select(s + 1, &fdset, NULL, NULL, &tmv);
258 err = errno;
260 gettimeofday(&t1, NULL);
262 dt = (t1.tv_sec - t0.tv_sec) * 1000000 +
263 (t1.tv_usec - t0.tv_usec);
264 *timeout_us_p = timeout_left =
265 (dt >= timeout_us) ? 1 : (timeout_us - dt);
266 } while (rv == -1 && err == EINTR);
268 if (rv == 0) {
269 timer(0); /* Should not return */
270 return -1;
273 set_socket_nonblock(s, 1);
274 rv = recv(s, rbuf, len, flags);
275 err = errno;
276 set_socket_nonblock(s, 0);
278 if (rv < 0) {
279 if (E_WOULD_BLOCK(err) || err == EINTR) {
280 continue; /* Once again, with feeling... */
281 } else {
282 errno = err;
283 return rv;
285 } else {
286 return rv;
291 static int split_port(char **ap, char **pp)
293 char *a, *p;
294 int ret = AF_UNSPEC;
296 a = *ap;
297 #ifdef HAVE_IPV6
298 if (is_numeric_ipv6(a)) {
299 if (*a++ != '[')
300 return -1;
301 *ap = a;
302 p = strrchr(a, ']');
303 if (!p)
304 return -1;
305 *p++ = 0;
306 a = p;
307 ret = AF_INET6;
308 p = strrchr(a, ':');
309 if (p)
310 *p++ = 0;
311 } else
312 #endif
314 struct in_addr in;
316 p = strrchr(a, ':');
317 if (p)
318 *p++ = 0;
319 if (inet_aton(a, &in))
320 ret = AF_INET;
322 *pp = p;
323 return ret;
326 enum long_only_options {
327 OPT_VERBOSITY = 256,
330 static struct option long_options[] = {
331 { "ipv4", 0, NULL, '4' },
332 { "ipv6", 0, NULL, '6' },
333 { "create", 0, NULL, 'c' },
334 { "secure", 0, NULL, 's' },
335 { "permissive", 0, NULL, 'p' },
336 { "verbose", 0, NULL, 'v' },
337 { "verbosity", 1, NULL, OPT_VERBOSITY },
338 { "version", 0, NULL, 'V' },
339 { "listen", 0, NULL, 'l' },
340 { "foreground", 0, NULL, 'L' },
341 { "address", 1, NULL, 'a' },
342 { "blocksize", 1, NULL, 'B' },
343 { "user", 1, NULL, 'u' },
344 { "umask", 1, NULL, 'U' },
345 { "refuse", 1, NULL, 'r' },
346 { "timeout", 1, NULL, 't' },
347 { "retransmit", 1, NULL, 'T' },
348 { "port-range", 1, NULL, 'R' },
349 { "map-file", 1, NULL, 'm' },
350 { "pidfile", 1, NULL, 'P' },
351 { NULL, 0, NULL, 0 }
353 static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
355 int main(int argc, char **argv)
357 struct tftphdr *tp;
358 struct passwd *pw;
359 struct options *opt;
360 union sock_addr myaddr;
361 struct sockaddr_in bindaddr4;
362 #ifdef HAVE_IPV6
363 struct sockaddr_in6 bindaddr6;
364 int force_ipv6 = 0;
365 #endif
366 int n;
367 int fd = -1;
368 int fd4 = -1;
369 int fd6 = -1;
370 int fdmax = 0;
371 int standalone = 0; /* Standalone (listen) mode */
372 int nodaemon = 0; /* Do not detach process */
373 char *address = NULL; /* Address to listen to */
374 pid_t pid;
375 mode_t my_umask = 0;
376 int spec_umask = 0;
377 int c;
378 int setrv;
379 int die;
380 int waittime = 900; /* Default time to wait for a connect */
381 const char *user = "nobody"; /* Default user */
382 char *p, *ep;
383 #ifdef WITH_REGEX
384 char *rewrite_file = NULL;
385 #endif
386 const char *pidfile = NULL;
387 u_short tp_opcode;
389 /* basename() is way too much of a pain from a portability standpoint */
391 p = strrchr(argv[0], '/');
392 tftpd_progname = (p && p[1]) ? p + 1 : argv[0];
394 openlog(tftpd_progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
396 srand(time(NULL) ^ getpid());
398 while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
399 != -1)
400 switch (c) {
401 case '4':
402 ai_fam = AF_INET;
403 break;
404 #ifdef HAVE_IPV6
405 case '6':
406 ai_fam = AF_INET6;
407 force_ipv6 = 1;
408 break;
409 #endif
410 case 'c':
411 cancreate = 1;
412 break;
413 case 's':
414 secure = 1;
415 break;
416 case 'p':
417 unixperms = 1;
418 break;
419 case 'l':
420 standalone = 1;
421 break;
422 case 'L':
423 standalone = 1;
424 nodaemon = 1;
425 break;
426 case 'a':
427 address = optarg;
428 break;
429 case 't':
430 waittime = atoi(optarg);
431 break;
432 case 'B':
434 char *vp;
435 max_blksize = (unsigned int)strtoul(optarg, &vp, 10);
436 if (max_blksize < 512 || max_blksize > MAX_SEGSIZE || *vp) {
437 syslog(LOG_ERR,
438 "Bad maximum blocksize value (range 512-%d): %s",
439 MAX_SEGSIZE, optarg);
440 exit(EX_USAGE);
443 break;
444 case 'T':
446 char *vp;
447 unsigned long tov = strtoul(optarg, &vp, 10);
448 if (tov < 10000UL || tov > 255000000UL || *vp) {
449 syslog(LOG_ERR, "Bad timeout value: %s", optarg);
450 exit(EX_USAGE);
452 rexmtval = timeout = tov;
453 maxtimeout = rexmtval * TIMEOUT_LIMIT;
455 break;
456 case 'R':
458 if (sscanf(optarg, "%u:%u", &portrange_from, &portrange_to)
459 != 2 || portrange_from > portrange_to
460 || portrange_to >= 65535) {
461 syslog(LOG_ERR, "Bad port range: %s", optarg);
462 exit(EX_USAGE);
464 portrange = 1;
466 break;
467 case 'u':
468 user = optarg;
469 break;
470 case 'U':
471 my_umask = strtoul(optarg, &ep, 8);
472 if (*ep) {
473 syslog(LOG_ERR, "Invalid umask: %s", optarg);
474 exit(EX_USAGE);
476 spec_umask = 1;
477 break;
478 case 'r':
479 for (opt = options; opt->o_opt; opt++) {
480 if (!strcasecmp(optarg, opt->o_opt)) {
481 opt->o_opt = ""; /* Don't support this option */
482 break;
485 if (!opt->o_opt) {
486 syslog(LOG_ERR, "Unknown option: %s", optarg);
487 exit(EX_USAGE);
489 break;
490 #ifdef WITH_REGEX
491 case 'm':
492 if (rewrite_file) {
493 syslog(LOG_ERR, "Multiple -m options");
494 exit(EX_USAGE);
496 rewrite_file = optarg;
497 break;
498 #endif
499 case 'v':
500 verbosity++;
501 break;
502 case OPT_VERBOSITY:
503 verbosity = atoi(optarg);
504 break;
505 case 'V':
506 /* Print configuration to stdout and exit */
507 printf("%s\n", TFTPD_CONFIG_STR);
508 exit(0);
509 break;
510 case 'P':
511 pidfile = optarg;
512 break;
513 default:
514 syslog(LOG_ERR, "Unknown option: '%c'", optopt);
515 break;
518 dirs = xmalloc((argc - optind + 1) * sizeof(char *));
519 for (ndirs = 0; optind != argc; optind++)
520 dirs[ndirs++] = argv[optind];
522 dirs[ndirs] = NULL;
524 if (secure) {
525 if (ndirs == 0) {
526 syslog(LOG_ERR, "no -s directory");
527 exit(EX_USAGE);
529 if (ndirs > 1) {
530 syslog(LOG_ERR, "too many -s directories");
531 exit(EX_USAGE);
533 if (chdir(dirs[0])) {
534 syslog(LOG_ERR, "%s: %m", dirs[0]);
535 exit(EX_NOINPUT);
539 pw = getpwnam(user);
540 if (!pw) {
541 syslog(LOG_ERR, "no user %s: %m", user);
542 exit(EX_NOUSER);
545 #ifdef WITH_REGEX
546 if (rewrite_file)
547 rewrite_rules = read_remap_rules(rewrite_file);
548 #endif
550 if (pidfile && !standalone) {
551 syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
552 pidfile = NULL;
555 /* If we're running standalone, set up the input port */
556 if (standalone) {
557 FILE *pf;
558 #ifdef HAVE_IPV6
559 if (ai_fam != AF_INET6) {
560 #endif
561 fd4 = socket(AF_INET, SOCK_DGRAM, 0);
562 if (fd4 < 0) {
563 syslog(LOG_ERR, "cannot open IPv4 socket: %m");
564 exit(EX_OSERR);
566 #ifndef __CYGWIN__
567 set_socket_nonblock(fd4, 1);
568 #endif
569 memset(&bindaddr4, 0, sizeof bindaddr4);
570 bindaddr4.sin_family = AF_INET;
571 bindaddr4.sin_addr.s_addr = INADDR_ANY;
572 bindaddr4.sin_port = htons(IPPORT_TFTP);
573 #ifdef HAVE_IPV6
575 if (ai_fam != AF_INET) {
576 fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
577 if (fd6 < 0) {
578 if (fd4 < 0) {
579 syslog(LOG_ERR, "cannot open IPv6 socket: %m");
580 exit(EX_OSERR);
581 } else {
582 syslog(LOG_ERR,
583 "cannot open IPv6 socket, disable IPv6: %m");
586 #ifndef __CYGWIN__
587 set_socket_nonblock(fd6, 1);
588 #endif
589 memset(&bindaddr6, 0, sizeof bindaddr6);
590 bindaddr6.sin6_family = AF_INET6;
591 bindaddr6.sin6_port = htons(IPPORT_TFTP);
593 #endif
594 if (address) {
595 char *portptr = NULL, *eportptr;
596 int err;
597 struct servent *servent;
598 unsigned long port;
600 address = tfstrdup(address);
601 err = split_port(&address, &portptr);
602 switch (err) {
603 case AF_INET:
604 #ifdef HAVE_IPV6
605 if (fd6 >= 0) {
606 close(fd6);
607 fd6 = -1;
608 if (ai_fam == AF_INET6) {
609 syslog(LOG_ERR,
610 "Address %s is not in address family AF_INET6",
611 address);
612 exit(EX_USAGE);
614 ai_fam = AF_INET;
616 break;
617 case AF_INET6:
618 if (fd4 >= 0) {
619 close(fd4);
620 fd4 = -1;
621 if (ai_fam == AF_INET) {
622 syslog(LOG_ERR,
623 "Address %s is not in address family AF_INET",
624 address);
625 exit(EX_USAGE);
627 ai_fam = AF_INET6;
629 break;
630 #endif
631 case AF_UNSPEC:
632 break;
633 default:
634 syslog(LOG_ERR,
635 "Numeric IPv6 addresses need to be enclosed in []");
636 exit(EX_USAGE);
638 if (!portptr)
639 portptr = (char *)"tftp";
640 if (*address) {
641 if (fd4 >= 0) {
642 bindaddr4.sin_family = AF_INET;
643 err = set_sock_addr(address,
644 (union sock_addr *)&bindaddr4, NULL);
645 if (err) {
646 syslog(LOG_ERR,
647 "cannot resolve local IPv4 bind address: %s, %s",
648 address, gai_strerror(err));
649 exit(EX_NOINPUT);
652 #ifdef HAVE_IPV6
653 if (fd6 >= 0) {
654 bindaddr6.sin6_family = AF_INET6;
655 err = set_sock_addr(address,
656 (union sock_addr *)&bindaddr6, NULL);
657 if (err) {
658 if (fd4 >= 0) {
659 syslog(LOG_ERR,
660 "cannot resolve local IPv6 bind address: %s"
661 "(%s); using IPv4 only",
662 address, gai_strerror(err));
663 close(fd6);
664 fd6 = -1;
665 } else {
666 syslog(LOG_ERR,
667 "cannot resolve local IPv6 bind address: %s"
668 "(%s)", address, gai_strerror(err));
669 exit(EX_NOINPUT);
673 #endif
674 } else {
675 /* Default to using INADDR_ANY */
678 if (portptr && *portptr) {
679 servent = getservbyname(portptr, "udp");
680 if (servent) {
681 if (fd4 >= 0)
682 bindaddr4.sin_port = servent->s_port;
683 #ifdef HAVE_IPV6
684 if (fd6 >= 0)
685 bindaddr6.sin6_port = servent->s_port;
686 #endif
687 } else if ((port = strtoul(portptr, &eportptr, 0))
688 && !*eportptr) {
689 if (fd4 >= 0)
690 bindaddr4.sin_port = htons(port);
691 #ifdef HAVE_IPV6
692 if (fd6 >= 0)
693 bindaddr6.sin6_port = htons(port);
694 #endif
695 } else if (!strcmp(portptr, "tftp")) {
696 /* It's TFTP, we're OK */
697 } else {
698 syslog(LOG_ERR, "cannot resolve local bind port: %s",
699 portptr);
700 exit(EX_NOINPUT);
705 if (fd4 >= 0) {
706 if (bind(fd4, (struct sockaddr *)&bindaddr4,
707 sizeof(bindaddr4)) < 0) {
708 syslog(LOG_ERR, "cannot bind to local IPv4 socket: %m");
709 exit(EX_OSERR);
712 #ifdef HAVE_IPV6
713 if (fd6 >= 0) {
714 #if defined(IPV6_V6ONLY)
715 int on = 1;
716 if (fd4 >= 0 || force_ipv6)
717 if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on,
718 sizeof(on)))
719 syslog(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m");
720 #endif
721 if (bind(fd6, (struct sockaddr *)&bindaddr6,
722 sizeof(bindaddr6)) < 0) {
723 if (fd4 >= 0) {
724 syslog(LOG_ERR,
725 "cannot bind to local IPv6 socket,"
726 "IPv6 disabled: %m");
727 close(fd6);
728 fd6 = -1;
729 } else {
730 syslog(LOG_ERR, "cannot bind to local IPv6 socket: %m");
731 exit(EX_OSERR);
735 #endif
736 /* Daemonize this process */
737 /* Note: when running in secure mode (-s), we must not chdir, since
738 we are already in the proper directory. */
739 if (!nodaemon && daemon(secure, 0) < 0) {
740 syslog(LOG_ERR, "cannot daemonize: %m");
741 exit(EX_OSERR);
743 set_signal(SIGTERM, handle_exit, 0);
744 set_signal(SIGINT, handle_exit, 0);
745 if (pidfile) {
746 pf = fopen (pidfile, "w");
747 if (!pf) {
748 syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile);
749 pidfile = NULL;
750 } else {
751 if (fprintf(pf, "%d\n", getpid()) < 0)
752 syslog(LOG_ERR, "error writing pid file '%s': %m", pidfile);
753 if (fclose(pf))
754 syslog(LOG_ERR, "error closing pid file '%s': %m", pidfile);
757 if (fd6 > fd4)
758 fdmax = fd6;
759 else
760 fdmax = fd4;
761 } else {
762 /* 0 is our socket descriptor */
763 close(1);
764 close(2);
765 fd = 0;
766 fdmax = 0;
767 /* Note: on Cygwin, select() on a nonblocking socket becomes
768 a nonblocking select. */
769 #ifndef __CYGWIN__
770 set_socket_nonblock(fd, 1);
771 #endif
774 /* Disable path MTU discovery */
775 pmtu_discovery_off(fd);
777 /* This means we don't want to wait() for children */
778 #ifdef SA_NOCLDWAIT
779 set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP | SA_NOCLDWAIT);
780 #else
781 set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP);
782 #endif
784 /* Take SIGHUP and use it to set a variable. This
785 is polled synchronously to make sure we don't
786 lose packets as a result. */
787 set_signal(SIGHUP, handle_sighup, 0);
789 if (spec_umask || !unixperms)
790 umask(my_umask);
792 while (1) {
793 fd_set readset;
794 struct timeval tv_waittime;
795 int rv;
797 if (exit_signal) { /* happens in standalone mode only */
798 if (pidfile && unlink(pidfile)) {
799 syslog(LOG_WARNING, "error removing pid file '%s': %m", pidfile);
800 exit(EX_OSERR);
801 } else {
802 exit(0);
806 if (caught_sighup) {
807 caught_sighup = 0;
808 if (standalone) {
809 #ifdef WITH_REGEX
810 if (rewrite_file) {
811 freerules(rewrite_rules);
812 rewrite_rules = read_remap_rules(rewrite_file);
814 #endif
815 } else {
816 /* Return to inetd for respawn */
817 exit(0);
821 FD_ZERO(&readset);
822 if (standalone) {
823 if (fd4 >= 0) {
824 FD_SET(fd4, &readset);
825 #ifdef __CYGWIN__
826 /* On Cygwin, select() on a nonblocking socket returns
827 immediately, with a rv of 0! */
828 set_socket_nonblock(fd4, 0);
829 #endif
831 if (fd6 >= 0) {
832 FD_SET(fd6, &readset);
833 #ifdef __CYGWIN__
834 /* On Cygwin, select() on a nonblocking socket returns
835 immediately, with a rv of 0! */
836 set_socket_nonblock(fd6, 0);
837 #endif
839 } else { /* fd always 0 */
840 fd = 0;
841 #ifdef __CYGWIN__
842 /* On Cygwin, select() on a nonblocking socket returns
843 immediately, with a rv of 0! */
844 set_socket_nonblock(fd, 0);
845 #endif
846 FD_SET(fd, &readset);
848 tv_waittime.tv_sec = waittime;
849 tv_waittime.tv_usec = 0;
852 /* Never time out if we're in standalone mode */
853 rv = select(fdmax + 1, &readset, NULL, NULL,
854 standalone ? NULL : &tv_waittime);
855 if (rv == -1 && errno == EINTR)
856 continue; /* Signal caught, reloop */
858 if (rv == -1) {
859 syslog(LOG_ERR, "select loop: %m");
860 exit(EX_IOERR);
861 } else if (rv == 0) {
862 exit(0); /* Timeout, return to inetd */
865 if (standalone) {
866 if ((fd4 >= 0) && FD_ISSET(fd4, &readset))
867 fd = fd4;
868 else if ((fd6 >= 0) && FD_ISSET(fd6, &readset))
869 fd = fd6;
870 else /* not in set ??? */
871 continue;
873 #ifdef __CYGWIN__
874 /* On Cygwin, select() on a nonblocking socket returns
875 immediately, with a rv of 0! */
876 set_socket_nonblock(fd, 0);
877 #endif
879 n = myrecvfrom(fd, buf, sizeof(buf), 0, &from, &myaddr);
881 if (n < 0) {
882 if (E_WOULD_BLOCK(errno) || errno == EINTR) {
883 continue; /* Again, from the top */
884 } else {
885 syslog(LOG_ERR, "recvfrom: %m");
886 exit(EX_IOERR);
889 #ifdef HAVE_IPV6
890 if ((from.sa.sa_family != AF_INET) && (from.sa.sa_family != AF_INET6)) {
891 syslog(LOG_ERR, "received address was not AF_INET/AF_INET6,"
892 " please check your inetd config");
893 #else
894 if (from.sa.sa_family != AF_INET) {
895 syslog(LOG_ERR, "received address was not AF_INET,"
896 " please check your inetd config");
897 #endif
898 exit(EX_PROTOCOL);
901 if (standalone) {
902 if ((from.sa.sa_family == AF_INET) &&
903 (myaddr.si.sin_addr.s_addr == INADDR_ANY)) {
904 /* myrecvfrom() didn't capture the source address; but we might
905 have bound to a specific address, if so we should use it */
906 memcpy(SOCKADDR_P(&myaddr), &bindaddr4.sin_addr,
907 sizeof(bindaddr4.sin_addr));
908 #ifdef HAVE_IPV6
909 } else if ((from.sa.sa_family == AF_INET6) &&
910 IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)
911 SOCKADDR_P(&myaddr))) {
912 memcpy(SOCKADDR_P(&myaddr), &bindaddr6.sin6_addr,
913 sizeof(bindaddr6.sin6_addr));
914 #endif
919 * Now that we have read the request packet from the UDP
920 * socket, we fork and go back to listening to the socket.
922 pid = fork();
923 if (pid < 0) {
924 syslog(LOG_ERR, "fork: %m");
925 exit(EX_OSERR); /* Return to inetd, just in case */
926 } else if (pid == 0)
927 break; /* Child exit, parent loop */
930 /* Child process: handle the actual request here */
932 /* Ignore SIGHUP */
933 set_signal(SIGHUP, SIG_IGN, 0);
935 /* Make sure the log socket is still connected. This has to be
936 done before the chroot, while /dev/log is still accessible.
937 When not running standalone, there is little chance that the
938 syslog daemon gets restarted by the time we get here. */
939 if (secure && standalone) {
940 closelog();
941 openlog(tftpd_progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
944 #ifdef HAVE_TCPWRAPPERS
945 /* Verify if this was a legal request for us. This has to be
946 done before the chroot, while /etc is still accessible. */
947 request_init(&wrap_request,
948 RQ_DAEMON, tftpd_progname,
949 RQ_FILE, fd,
950 RQ_CLIENT_SIN, &from, RQ_SERVER_SIN, &myaddr, 0);
951 sock_methods(&wrap_request);
953 tmp_p = (char *)inet_ntop(myaddr.sa.sa_family, SOCKADDR_P(&myaddr),
954 tmpbuf, INET6_ADDRSTRLEN);
955 if (!tmp_p) {
956 tmp_p = tmpbuf;
957 strcpy(tmpbuf, "???");
959 if (hosts_access(&wrap_request) == 0) {
960 if (deny_severity != -1)
961 syslog(deny_severity, "connection refused from %s", tmp_p);
962 exit(EX_NOPERM); /* Access denied */
963 } else if (allow_severity != -1) {
964 syslog(allow_severity, "connect from %s", tmp_p);
966 #endif
968 /* Close file descriptors we don't need */
969 close(fd);
971 /* Get a socket. This has to be done before the chroot(), since
972 some systems require access to /dev to create a socket. */
974 peer = socket(myaddr.sa.sa_family, SOCK_DGRAM, 0);
975 if (peer < 0) {
976 syslog(LOG_ERR, "socket: %m");
977 exit(EX_IOERR);
980 /* Set up the supplementary group access list if possible
981 /etc/group still need to be accessible at this point.
982 If we get EPERM, this is already a restricted process, e.g.
983 using user namespaces on Linux. */
984 die = 0;
985 #ifdef HAVE_SETGROUPS
986 setrv = setgroups(0, NULL);
987 if (setrv && errno != EPERM) {
988 syslog(LOG_ERR, "cannot clear group list");
989 die = EX_OSERR;
991 #endif
992 #ifdef HAVE_INITGROUPS
993 setrv = initgroups(user, pw->pw_gid);
994 if (!setrv) {
995 die = 0;
996 } else if (errno != EPERM) {
997 syslog(LOG_ERR, "cannot set groups for user %s", user);
998 die = EX_OSERR;
1000 #endif
1001 if (die)
1002 exit(die);
1004 /* Chroot and drop privileges */
1005 if (secure) {
1006 if (chroot(".")) {
1007 syslog(LOG_ERR, "chroot: %m");
1008 exit(EX_OSERR);
1010 #ifdef __CYGWIN__
1011 chdir("/"); /* Cygwin chroot() bug workaround */
1012 #endif
1015 #ifdef HAVE_SETRESGID
1016 setrv = setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid);
1017 #elif defined(HAVE_SETREGID)
1018 setrv = setregid(pw->pw_gid, pw->pw_gid);
1019 #else
1020 setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid);
1021 #endif
1022 if (setrv && errno == EPERM) {
1023 setrv = 0; /* Assume already restricted by system policy */
1026 #ifdef HAVE_SETRESUID
1027 setrv = setrv || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid);
1028 #elif defined(HAVE_SETREUID)
1029 setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid);
1030 #else
1031 /* Important: setuid() must come first */
1032 setrv = setrv || setuid(pw->pw_uid) ||
1033 (geteuid() != pw->pw_uid && seteuid(pw->pw_uid));
1034 #endif
1035 if (setrv && errno == EPERM) {
1036 setrv = 0; /* Assume already restricted by system policy */
1039 if (setrv) {
1040 syslog(LOG_ERR, "cannot drop privileges: %m");
1041 exit(EX_OSERR);
1044 /* Process the request... */
1045 if (pick_port_bind(peer, &myaddr, portrange_from, portrange_to) < 0) {
1046 syslog(LOG_ERR, "bind: %m");
1047 exit(EX_IOERR);
1050 if (connect(peer, &from.sa, SOCKLEN(&from)) < 0) {
1051 syslog(LOG_ERR, "connect: %m");
1052 exit(EX_IOERR);
1055 /* Disable path MTU discovery */
1056 pmtu_discovery_off(peer);
1058 tp = (struct tftphdr *)buf;
1059 tp_opcode = ntohs(tp->th_opcode);
1060 if (tp_opcode == RRQ || tp_opcode == WRQ)
1061 tftp(tp, n);
1062 exit(0);
1065 static char *rewrite_access(const struct formats *,
1066 char *, int, int, const char **);
1067 static int validate_access(char *, int, const struct formats *, const char **);
1068 static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
1069 static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
1071 static const struct formats formats[] = {
1073 "netascii", rewrite_access, validate_access, tftp_sendfile,
1074 tftp_recvfile, 1}, {
1075 "octet", rewrite_access, validate_access, tftp_sendfile,
1076 tftp_recvfile, 0}, {
1077 NULL, NULL, NULL, NULL, NULL, 0}
1081 * Handle initial connection protocol.
1083 int tftp(struct tftphdr *tp, int size)
1085 char *cp, *end;
1086 int argn, ecode;
1087 const struct formats *pf = NULL;
1088 char *origfilename;
1089 char *filename, *mode = NULL;
1090 const char *errmsgptr;
1091 u_short tp_opcode = ntohs(tp->th_opcode);
1093 char *val = NULL, *opt = NULL;
1094 char *ap = ackbuf + 2;
1096 ((struct tftphdr *)ackbuf)->th_opcode = htons(OACK);
1098 origfilename = cp = (char *)&(tp->th_stuff);
1099 argn = 0;
1101 end = (char *)tp + size;
1103 while (cp < end && *cp) {
1104 do {
1105 cp++;
1106 } while (cp < end && *cp);
1108 if (*cp) {
1109 nak(EBADOP, "Request not null-terminated");
1110 exit(0);
1113 argn++;
1114 if (argn == 1) {
1115 mode = ++cp;
1116 } else if (argn == 2) {
1117 for (cp = mode; *cp; cp++)
1118 *cp = tolower(*cp);
1119 for (pf = formats; pf->f_mode; pf++) {
1120 if (!strcmp(pf->f_mode, mode))
1121 break;
1123 if (!pf->f_mode) {
1124 nak(EBADOP, "Unknown mode");
1125 exit(0);
1127 file = NULL;
1128 if (!(filename = (*pf->f_rewrite)
1129 (pf, origfilename, tp_opcode, from.sa.sa_family, &errmsgptr))) {
1130 nak(EACCESS, errmsgptr); /* File denied by mapping rule */
1131 exit(0);
1133 if (verbosity >= 1) {
1134 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1135 tmpbuf, INET6_ADDRSTRLEN);
1136 if (!tmp_p) {
1137 tmp_p = tmpbuf;
1138 strcpy(tmpbuf, "???");
1140 if (filename == origfilename
1141 || !strcmp(filename, origfilename))
1142 syslog(LOG_NOTICE, "%s from %s filename %s\n",
1143 tp_opcode == WRQ ? "WRQ" : "RRQ",
1144 tmp_p, filename);
1145 else
1146 syslog(LOG_NOTICE,
1147 "%s from %s filename %s remapped to %s\n",
1148 tp_opcode == WRQ ? "WRQ" : "RRQ",
1149 tmp_p, origfilename,
1150 filename);
1153 * If "file" is already set, then a file was already validated
1154 * and opened during remap processing.
1156 if (!file) {
1157 ecode =
1158 (*pf->f_validate) (filename, tp_opcode, pf, &errmsgptr);
1159 if (ecode) {
1160 nak(ecode, errmsgptr);
1161 exit(0);
1164 opt = ++cp;
1165 } else if (argn & 1) {
1166 val = ++cp;
1167 } else {
1168 do_opt(opt, val, &ap);
1169 opt = ++cp;
1173 if (!pf) {
1174 nak(EBADOP, "Missing mode");
1175 exit(0);
1178 if (ap != (ackbuf + 2)) {
1179 if (tp_opcode == WRQ)
1180 (*pf->f_recv) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1181 else
1182 (*pf->f_send) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1183 } else {
1184 if (tp_opcode == WRQ)
1185 (*pf->f_recv) (pf, NULL, 0);
1186 else
1187 (*pf->f_send) (pf, NULL, 0);
1189 exit(0); /* Request completed */
1192 static int blksize_set;
1195 * Set a non-standard block size (c.f. RFC2348)
1197 static int set_blksize(uintmax_t *vp)
1199 uintmax_t sz = *vp;
1201 if (blksize_set)
1202 return 0;
1204 if (sz < 8)
1205 return 0;
1206 else if (sz > max_blksize)
1207 sz = max_blksize;
1209 *vp = segsize = sz;
1210 blksize_set = 1;
1211 return 1;
1215 * Set a power-of-two block size (nonstandard)
1217 static int set_blksize2(uintmax_t *vp)
1219 uintmax_t sz = *vp;
1221 if (blksize_set)
1222 return 0;
1224 if (sz < 8)
1225 return (0);
1226 else if (sz > max_blksize)
1227 sz = max_blksize;
1228 else
1230 /* Convert to a power of two */
1231 if (sz & (sz - 1)) {
1232 unsigned int sz1 = 1;
1233 /* Not a power of two - need to convert */
1234 while (sz >>= 1)
1235 sz1 <<= 1;
1236 sz = sz1;
1239 *vp = segsize = sz;
1240 blksize_set = 1;
1241 return 1;
1245 * Set the block number rollover value
1247 static int set_rollover(uintmax_t *vp)
1249 uintmax_t ro = *vp;
1251 if (ro > 65535)
1252 return 0;
1254 rollover_val = (uint16_t)ro;
1255 return 1;
1259 * Return a file size (c.f. RFC2349)
1260 * For netascii mode, we don't know the size ahead of time;
1261 * so reject the option.
1263 static int set_tsize(uintmax_t *vp)
1265 uintmax_t sz = *vp;
1267 if (!tsize_ok)
1268 return 0;
1270 if (sz == 0)
1271 sz = tsize;
1273 *vp = sz;
1274 return 1;
1278 * Set the timeout (c.f. RFC2349). This is supposed
1279 * to be the (default) retransmission timeout, but being an
1280 * integer in seconds it seems a bit limited.
1282 static int set_timeout(uintmax_t *vp)
1284 uintmax_t to = *vp;
1286 if (to < 1 || to > 255)
1287 return 0;
1289 rexmtval = timeout = to * 1000000UL;
1290 maxtimeout = rexmtval * TIMEOUT_LIMIT;
1292 return 1;
1295 /* Similar, but in microseconds. We allow down to 10 ms. */
1296 static int set_utimeout(uintmax_t *vp)
1298 uintmax_t to = *vp;
1300 if (to < 10000UL || to > 255000000UL)
1301 return 0;
1303 rexmtval = timeout = to;
1304 maxtimeout = rexmtval * TIMEOUT_LIMIT;
1306 return 1;
1310 * Conservative calculation for the size of a buffer which can hold an
1311 * arbitrary integer
1313 #define OPTBUFSIZE (sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
1316 * Parse RFC2347 style options; we limit the arguments to positive
1317 * integers which matches all our current options.
1319 static void do_opt(const char *opt, const char *val, char **ap)
1321 struct options *po;
1322 char retbuf[OPTBUFSIZE];
1323 char *p = *ap;
1324 size_t optlen, retlen;
1325 char *vend;
1326 uintmax_t v;
1328 /* Global option-parsing variables initialization */
1329 blksize_set = 0;
1331 if (!*opt || !*val)
1332 return;
1334 errno = 0;
1335 v = strtoumax(val, &vend, 10);
1336 if (*vend || errno == ERANGE)
1337 return;
1339 for (po = options; po->o_opt; po++)
1340 if (!strcasecmp(po->o_opt, opt)) {
1341 if (po->o_fnc(&v)) {
1342 optlen = strlen(opt);
1343 retlen = sprintf(retbuf, "%"PRIuMAX, v);
1345 if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
1346 nak(EOPTNEG, "Insufficient space for options");
1347 exit(0);
1350 memcpy(p, opt, optlen+1);
1351 p += optlen+1;
1352 memcpy(p, retbuf, retlen+1);
1353 p += retlen+1;
1354 } else {
1355 nak(EOPTNEG, "Unsupported option(s) requested");
1356 exit(0);
1358 break;
1361 *ap = p;
1364 #ifdef WITH_REGEX
1367 * This is called by the remap engine when it encounters macros such
1368 * as \i. It should write the output in "output" if non-NULL, and
1369 * return the length of the output (generated or not).
1371 * Return -1 on failure.
1373 static int rewrite_macros(char macro, char *output)
1375 char *p, tb[INET6_ADDRSTRLEN];
1376 int l=0;
1378 switch (macro) {
1379 case 'i':
1380 p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1381 tb, INET6_ADDRSTRLEN);
1382 if (output && p)
1383 strcpy(output, p);
1384 if (!p)
1385 return 0;
1386 else
1387 return strlen(p);
1389 case 'x':
1390 if (output) {
1391 if (from.sa.sa_family == AF_INET) {
1392 sprintf(output, "%08lX",
1393 (unsigned long)ntohl(from.si.sin_addr.s_addr));
1394 l = 8;
1395 #ifdef HAVE_IPV6
1396 } else {
1397 unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
1398 p = tb;
1399 for (l = 0; l < 16; l++) {
1400 sprintf(p, "%02X", *c);
1401 c++;
1402 p += 2;
1404 strcpy(output, tb);
1405 l = strlen(tb);
1406 #endif
1409 return l;
1411 default:
1412 return -1;
1417 * Modify the filename, if applicable. If it returns NULL, deny the access.
1419 static char *rewrite_access(const struct formats *pf, char *filename,
1420 int mode, int af, const char **msg)
1422 if (rewrite_rules) {
1423 char *newname =
1424 rewrite_string(pf, filename, rewrite_rules, mode, af,
1425 rewrite_macros, msg);
1426 filename = newname;
1428 return filename;
1431 #else
1432 static char *rewrite_access(const struct formats *pf, char *filename,
1433 int mode, int af, const char **msg)
1435 (void)pf;
1436 (void)mode; /* Avoid warning */
1437 (void)msg;
1438 (void)af;
1439 return filename;
1441 #endif
1444 * Validate file access. Since we
1445 * have no uid or gid, for now require
1446 * file to exist and be publicly
1447 * readable/writable, unless -p specified.
1448 * If we were invoked with arguments
1449 * from inetd then the file must also be
1450 * in one of the given directory prefixes.
1451 * Note also, full path name must be
1452 * given as we have no login directory.
1454 static int validate_access(char *filename, int mode,
1455 const struct formats *pf, const char **errmsg)
1457 struct stat stbuf;
1458 int i, len;
1459 int fd, wmode, rmode;
1460 char *cp;
1461 const char **dirp;
1462 char stdio_mode[3];
1464 tsize_ok = 0;
1465 *errmsg = NULL;
1467 if (!secure) {
1468 if (*filename != '/') {
1469 *errmsg = "Only absolute filenames allowed";
1470 return (EACCESS);
1474 * prevent tricksters from getting around the directory
1475 * restrictions
1477 len = strlen(filename);
1478 for (i = 1; i < len - 3; i++) {
1479 cp = filename + i;
1480 if (*cp == '.' && memcmp(cp - 1, "/../", 4) == 0) {
1481 *errmsg = "Reverse path not allowed";
1482 return (EACCESS);
1486 for (dirp = dirs; *dirp; dirp++)
1487 if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
1488 break;
1489 if (*dirp == 0 && dirp != dirs) {
1490 *errmsg = "Forbidden directory";
1491 return (EACCESS);
1496 * We use different a different permissions scheme if `cancreate' is
1497 * set.
1499 wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
1500 rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY);
1502 #ifndef HAVE_FTRUNCATE
1503 wmode |= O_TRUNC; /* This really sucks on a dupe */
1504 #endif
1506 fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
1507 if (fd < 0) {
1508 switch (errno) {
1509 case ENOENT:
1510 case ENOTDIR:
1511 return ENOTFOUND;
1512 case ENOSPC:
1513 return ENOSPACE;
1514 case EEXIST:
1515 return EEXISTS;
1516 default:
1517 return errno + 100;
1521 if (fstat(fd, &stbuf) < 0)
1522 exit(EX_OSERR); /* This shouldn't happen */
1524 /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */
1525 if (lock_file(fd, mode != RRQ))
1526 exit(0);
1528 if (mode == RRQ) {
1529 if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) {
1530 *errmsg = "File must have global read permissions";
1531 return (EACCESS);
1533 tsize = stbuf.st_size;
1534 /* We don't know the tsize if conversion is needed */
1535 tsize_ok = !pf->f_convert;
1536 } else {
1537 if (!unixperms) {
1538 if ((stbuf.st_mode & (S_IWRITE >> 6)) == 0) {
1539 *errmsg = "File must have global write permissions";
1540 return (EACCESS);
1544 #ifdef HAVE_FTRUNCATE
1545 /* We didn't get to truncate the file at open() time */
1546 if (ftruncate(fd, (off_t) 0)) {
1547 *errmsg = "Cannot reset file size";
1548 return (EACCESS);
1550 #endif
1551 tsize = 0;
1552 tsize_ok = 1;
1555 stdio_mode[0] = (mode == RRQ) ? 'r' : 'w';
1556 stdio_mode[1] = (pf->f_convert) ? 't' : 'b';
1557 stdio_mode[2] = '\0';
1559 file = fdopen(fd, stdio_mode);
1560 if (file == NULL)
1561 exit(EX_OSERR); /* Internal error */
1563 return (0);
1567 * Send the requested file.
1569 static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
1571 struct tftphdr *dp;
1572 struct tftphdr *ap; /* ack packet */
1573 static u_short block = 1; /* Static to avoid longjmp funnies */
1574 u_short ap_opcode, ap_block;
1575 unsigned long r_timeout;
1576 int size, n;
1578 if (oap) {
1579 timeout = rexmtval;
1580 (void)sigsetjmp(timeoutbuf, 1);
1581 oack:
1582 r_timeout = timeout;
1583 if (send(peer, oap, oacklen, 0) != oacklen) {
1584 syslog(LOG_WARNING, "tftpd: oack: %m\n");
1585 goto abort;
1587 for (;;) {
1588 n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1589 if (n < 0) {
1590 syslog(LOG_WARNING, "tftpd: read: %m\n");
1591 goto abort;
1593 ap = (struct tftphdr *)ackbuf;
1594 ap_opcode = ntohs((u_short) ap->th_opcode);
1595 ap_block = ntohs((u_short) ap->th_block);
1597 if (ap_opcode == ERROR) {
1598 syslog(LOG_WARNING,
1599 "tftp: client does not accept options\n");
1600 goto abort;
1602 if (ap_opcode == ACK) {
1603 if (ap_block == 0)
1604 break;
1605 /* Resynchronize with the other side */
1606 (void)synchnet(peer);
1607 goto oack;
1612 dp = r_init();
1613 do {
1614 size = readit(file, &dp, pf->f_convert);
1615 if (size < 0) {
1616 nak(errno + 100, NULL);
1617 goto abort;
1619 dp->th_opcode = htons((u_short) DATA);
1620 dp->th_block = htons((u_short) block);
1621 timeout = rexmtval;
1622 (void)sigsetjmp(timeoutbuf, 1);
1624 r_timeout = timeout;
1625 if (send(peer, dp, size + 4, 0) != size + 4) {
1626 syslog(LOG_WARNING, "tftpd: write: %m");
1627 goto abort;
1629 read_ahead(file, pf->f_convert);
1630 for (;;) {
1631 n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1632 if (n < 0) {
1633 syslog(LOG_WARNING, "tftpd: read(ack): %m");
1634 goto abort;
1636 ap = (struct tftphdr *)ackbuf;
1637 ap_opcode = ntohs((u_short) ap->th_opcode);
1638 ap_block = ntohs((u_short) ap->th_block);
1640 if (ap_opcode == ERROR)
1641 goto abort;
1643 if (ap_opcode == ACK) {
1644 if (ap_block == block) {
1645 break;
1647 /* Re-synchronize with the other side */
1648 (void)synchnet(peer);
1650 * RFC1129/RFC1350: We MUST NOT re-send the DATA
1651 * packet in response to an invalid ACK. Doing so
1652 * would cause the Sorcerer's Apprentice bug.
1657 if (!++block)
1658 block = rollover_val;
1659 } while (size == segsize);
1660 abort:
1661 (void)fclose(file);
1665 * Receive a file.
1667 static void tftp_recvfile(const struct formats *pf,
1668 struct tftphdr *oack, int oacklen)
1670 struct tftphdr *dp;
1671 int n, size;
1672 /* These are "static" to avoid longjmp funnies */
1673 static struct tftphdr *oap;
1674 static struct tftphdr *ap; /* ack buffer */
1675 static u_short block = 0;
1676 static int acksize;
1677 u_short dp_opcode, dp_block;
1678 unsigned long r_timeout;
1680 oap = oack;
1682 dp = w_init();
1683 do {
1684 timeout = rexmtval;
1686 if (!block && oap) {
1687 ap = (struct tftphdr *)ackbuf;
1688 acksize = oacklen;
1689 } else {
1690 ap = (struct tftphdr *)ackbuf;
1691 ap->th_opcode = htons((u_short) ACK);
1692 ap->th_block = htons((u_short) block);
1693 acksize = 4;
1694 /* If we're sending a regular ACK, that means we have successfully
1695 * sent the OACK. Clear oap so that we won't try to send another
1696 * OACK when the block number wraps back to 0. */
1697 oap = NULL;
1699 if (!++block)
1700 block = rollover_val;
1701 (void)sigsetjmp(timeoutbuf, 1);
1702 send_ack:
1703 r_timeout = timeout;
1704 if (send(peer, ackbuf, acksize, 0) != acksize) {
1705 syslog(LOG_WARNING, "tftpd: write(ack): %m");
1706 goto abort;
1708 write_behind(file, pf->f_convert);
1709 for (;;) {
1710 n = recv_time(peer, dp, PKTSIZE, 0, &r_timeout);
1711 if (n < 0) { /* really? */
1712 syslog(LOG_WARNING, "tftpd: read: %m");
1713 goto abort;
1715 dp_opcode = ntohs((u_short) dp->th_opcode);
1716 dp_block = ntohs((u_short) dp->th_block);
1717 if (dp_opcode == ERROR)
1718 goto abort;
1719 if (dp_opcode == DATA) {
1720 if (dp_block == block) {
1721 break; /* normal */
1723 /* Re-synchronize with the other side */
1724 (void)synchnet(peer);
1725 if (dp_block == (block - 1))
1726 goto send_ack; /* rexmit */
1729 /* size = write(file, dp->th_data, n - 4); */
1730 size = writeit(file, &dp, n - 4, pf->f_convert);
1731 if (size != (n - 4)) { /* ahem */
1732 if (size < 0)
1733 nak(errno + 100, NULL);
1734 else
1735 nak(ENOSPACE, NULL);
1736 goto abort;
1738 } while (size == segsize);
1739 write_behind(file, pf->f_convert);
1740 (void)fclose(file); /* close data file */
1742 ap->th_opcode = htons((u_short) ACK); /* send the "final" ack */
1743 ap->th_block = htons((u_short) (block));
1744 (void)send(peer, ackbuf, 4, 0);
1746 timeout_quit = 1; /* just quit on timeout */
1747 n = recv_time(peer, buf, sizeof(buf), 0, &timeout); /* normally times out and quits */
1748 timeout_quit = 0;
1750 if (n >= 4 && /* if read some data */
1751 dp_opcode == DATA && /* and got a data block */
1752 block == dp_block) { /* then my last ack was lost */
1753 (void)send(peer, ackbuf, 4, 0); /* resend final ack */
1755 abort:
1756 return;
1759 static const char *const errmsgs[] = {
1760 "Undefined error code", /* 0 - EUNDEF */
1761 "File not found", /* 1 - ENOTFOUND */
1762 "Access denied", /* 2 - EACCESS */
1763 "Disk full or allocation exceeded", /* 3 - ENOSPACE */
1764 "Illegal TFTP operation", /* 4 - EBADOP */
1765 "Unknown transfer ID", /* 5 - EBADID */
1766 "File already exists", /* 6 - EEXISTS */
1767 "No such user", /* 7 - ENOUSER */
1768 "Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */
1771 #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *))
1774 * Send a nak packet (error message).
1775 * Error code passed in is one of the
1776 * standard TFTP codes, or a UNIX errno
1777 * offset by 100.
1779 static void nak(int error, const char *msg)
1781 struct tftphdr *tp;
1782 int length;
1784 tp = (struct tftphdr *)buf;
1785 tp->th_opcode = htons((u_short) ERROR);
1787 if (error >= 100) {
1788 /* This is a Unix errno+100 */
1789 if (!msg)
1790 msg = strerror(error - 100);
1791 error = EUNDEF;
1792 } else {
1793 if ((unsigned)error >= ERR_CNT)
1794 error = EUNDEF;
1796 if (!msg)
1797 msg = errmsgs[error];
1800 tp->th_code = htons((u_short) error);
1802 length = strlen(msg) + 1;
1803 memcpy(tp->th_msg, msg, length);
1804 length += 4; /* Add space for header */
1806 if (verbosity >= 2) {
1807 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1808 tmpbuf, INET6_ADDRSTRLEN);
1809 if (!tmp_p) {
1810 tmp_p = tmpbuf;
1811 strcpy(tmpbuf, "???");
1813 syslog(LOG_INFO, "sending NAK (%d, %s) to %s",
1814 error, tp->th_msg, tmp_p);
1817 if (send(peer, buf, length, 0) != length)
1818 syslog(LOG_WARNING, "nak: %m");