tftpd: allow IPv4/6-specific remapping rules
[tftp-hpa.git] / tftpd / tftpd.c
blob88d28120bc218ce9365e9ef0404f967bb0d0eaaa
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 *__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 socklen_t fromlen;
97 static off_t tsize;
98 static int tsize_ok;
100 static int ndirs;
101 static const char **dirs;
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;
110 struct formats;
111 #ifdef WITH_REGEX
112 static struct rule *rewrite_rules = NULL;
113 #endif
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 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 *file)
168 FILE *f;
169 struct rule *rulep;
171 f = fopen(file, "rt");
172 if (!f) {
173 syslog(LOG_ERR, "Cannot open map file: %s: %m", file);
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 #if defined(HAVE_FCNTL) && defined(HAVE_F_SETLK_DEFINITION)
189 struct flock fl;
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
203 static void set_socket_nonblock(int fd, int flag)
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);
223 static void pmtu_discovery_off(int fd)
225 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
226 int pmtu = IP_PMTUDISC_DONT;
228 setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu));
229 #endif
233 * Receive packet with synchronous timeout; timeout is adjusted
234 * to account for time spent waiting.
236 static int recv_time(int s, void *rbuf, int len, unsigned int flags,
237 unsigned long *timeout_us_p)
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;
245 gettimeofday(&t0, NULL);
246 timeout_left = timeout_us;
248 for (;;) {
249 FD_ZERO(&fdset);
250 FD_SET(s, &fdset);
252 do {
253 tmv.tv_sec = timeout_left / 1000000;
254 tmv.tv_usec = timeout_left % 1000000;
256 rv = select(s + 1, &fdset, NULL, NULL, &tmv);
257 err = errno;
259 gettimeofday(&t1, NULL);
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);
267 if (rv == 0) {
268 timer(0); /* Should not return */
269 return -1;
272 set_socket_nonblock(s, 1);
273 rv = recv(s, rbuf, len, flags);
274 err = errno;
275 set_socket_nonblock(s, 0);
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;
284 } else {
285 return rv;
290 static int split_port(char **ap, char **pp)
292 char *a, *p;
293 int ret = AF_UNSPEC;
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
313 struct in_addr in;
315 p = strrchr(a, ':');
316 if (p)
317 *p++ = 0;
318 if (inet_aton(a, &in))
319 ret = AF_INET;
321 *pp = p;
322 return ret;
325 enum long_only_options {
326 OPT_VERBOSITY = 256,
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 }
352 static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:";
354 int main(int argc, char **argv)
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;
387 /* basename() is way too much of a pain from a portability standpoint */
389 p = strrchr(argv[0], '/');
390 __progname = (p && p[1]) ? p + 1 : argv[0];
392 openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
394 srand(time(NULL) ^ getpid());
396 while ((c = getopt_long(argc, argv, short_options, long_options, NULL))
397 != -1)
398 switch (c) {
399 case '4':
400 ai_fam = AF_INET;
401 break;
402 #ifdef HAVE_IPV6
403 case '6':
404 ai_fam = AF_INET6;
405 force_ipv6 = 1;
406 break;
407 #endif
408 case 'c':
409 cancreate = 1;
410 break;
411 case 's':
412 secure = 1;
413 break;
414 case 'p':
415 unixperms = 1;
416 break;
417 case 'l':
418 standalone = 1;
419 break;
420 case 'L':
421 standalone = 1;
422 nodaemon = 1;
423 break;
424 case 'a':
425 address = optarg;
426 break;
427 case 't':
428 waittime = atoi(optarg);
429 break;
430 case 'B':
432 char *vp;
433 max_blksize = (unsigned int)strtoul(optarg, &vp, 10);
434 if (max_blksize < 512 || max_blksize > MAX_SEGSIZE || *vp) {
435 syslog(LOG_ERR,
436 "Bad maximum blocksize value (range 512-%d): %s",
437 MAX_SEGSIZE, optarg);
438 exit(EX_USAGE);
441 break;
442 case 'T':
444 char *vp;
445 unsigned long tov = strtoul(optarg, &vp, 10);
446 if (tov < 10000UL || tov > 255000000UL || *vp) {
447 syslog(LOG_ERR, "Bad timeout value: %s", optarg);
448 exit(EX_USAGE);
450 rexmtval = timeout = tov;
451 maxtimeout = rexmtval * TIMEOUT_LIMIT;
453 break;
454 case 'R':
456 if (sscanf(optarg, "%u:%u", &portrange_from, &portrange_to)
457 != 2 || portrange_from > portrange_to
458 || portrange_to >= 65535) {
459 syslog(LOG_ERR, "Bad port range: %s", optarg);
460 exit(EX_USAGE);
462 portrange = 1;
464 break;
465 case 'u':
466 user = optarg;
467 break;
468 case 'U':
469 my_umask = strtoul(optarg, &ep, 8);
470 if (*ep) {
471 syslog(LOG_ERR, "Invalid umask: %s", optarg);
472 exit(EX_USAGE);
474 spec_umask = 1;
475 break;
476 case 'r':
477 for (opt = options; opt->o_opt; opt++) {
478 if (!strcasecmp(optarg, opt->o_opt)) {
479 opt->o_opt = ""; /* Don't support this option */
480 break;
483 if (!opt->o_opt) {
484 syslog(LOG_ERR, "Unknown option: %s", optarg);
485 exit(EX_USAGE);
487 break;
488 #ifdef WITH_REGEX
489 case 'm':
490 if (rewrite_file) {
491 syslog(LOG_ERR, "Multiple -m options");
492 exit(EX_USAGE);
494 rewrite_file = optarg;
495 break;
496 #endif
497 case 'v':
498 verbosity++;
499 break;
500 case OPT_VERBOSITY:
501 verbosity = atoi(optarg);
502 break;
503 case 'V':
504 /* Print configuration to stdout and exit */
505 printf("%s\n", TFTPD_CONFIG_STR);
506 exit(0);
507 break;
508 case 'P':
509 pidfile = optarg;
510 break;
511 default:
512 syslog(LOG_ERR, "Unknown option: '%c'", optopt);
513 break;
516 dirs = xmalloc((argc - optind + 1) * sizeof(char *));
517 for (ndirs = 0; optind != argc; optind++)
518 dirs[ndirs++] = argv[optind];
520 dirs[ndirs] = NULL;
522 if (secure) {
523 if (ndirs == 0) {
524 syslog(LOG_ERR, "no -s directory");
525 exit(EX_USAGE);
527 if (ndirs > 1) {
528 syslog(LOG_ERR, "too many -s directories");
529 exit(EX_USAGE);
531 if (chdir(dirs[0])) {
532 syslog(LOG_ERR, "%s: %m", dirs[0]);
533 exit(EX_NOINPUT);
537 pw = getpwnam(user);
538 if (!pw) {
539 syslog(LOG_ERR, "no user %s: %m", user);
540 exit(EX_NOUSER);
543 #ifdef WITH_REGEX
544 if (rewrite_file)
545 rewrite_rules = read_remap_rules(rewrite_file);
546 #endif
548 if (pidfile && !standalone) {
549 syslog(LOG_WARNING, "not in standalone mode, ignoring pid file");
550 pidfile = NULL;
553 /* If we're running standalone, set up the input port */
554 if (standalone) {
555 FILE *pf;
556 #ifdef HAVE_IPV6
557 if (ai_fam != AF_INET6) {
558 #endif
559 fd4 = socket(AF_INET, SOCK_DGRAM, 0);
560 if (fd4 < 0) {
561 syslog(LOG_ERR, "cannot open IPv4 socket: %m");
562 exit(EX_OSERR);
564 #ifndef __CYGWIN__
565 set_socket_nonblock(fd4, 1);
566 #endif
567 memset(&bindaddr4, 0, sizeof bindaddr4);
568 bindaddr4.sin_family = AF_INET;
569 bindaddr4.sin_addr.s_addr = INADDR_ANY;
570 bindaddr4.sin_port = htons(IPPORT_TFTP);
571 #ifdef HAVE_IPV6
573 if (ai_fam != AF_INET) {
574 fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
575 if (fd6 < 0) {
576 if (fd4 < 0) {
577 syslog(LOG_ERR, "cannot open IPv6 socket: %m");
578 exit(EX_OSERR);
579 } else {
580 syslog(LOG_ERR,
581 "cannot open IPv6 socket, disable IPv6: %m");
584 #ifndef __CYGWIN__
585 set_socket_nonblock(fd6, 1);
586 #endif
587 memset(&bindaddr6, 0, sizeof bindaddr6);
588 bindaddr6.sin6_family = AF_INET6;
589 bindaddr6.sin6_port = htons(IPPORT_TFTP);
591 #endif
592 if (address) {
593 char *portptr = NULL, *eportptr;
594 int err;
595 struct servent *servent;
596 unsigned long port;
598 address = tfstrdup(address);
599 err = split_port(&address, &portptr);
600 switch (err) {
601 case AF_INET:
602 #ifdef HAVE_IPV6
603 if (fd6 >= 0) {
604 close(fd6);
605 fd6 = -1;
606 if (ai_fam == AF_INET6) {
607 syslog(LOG_ERR,
608 "Address %s is not in address family AF_INET6",
609 address);
610 exit(EX_USAGE);
612 ai_fam = AF_INET;
614 break;
615 case AF_INET6:
616 if (fd4 >= 0) {
617 close(fd4);
618 fd4 = -1;
619 if (ai_fam == AF_INET) {
620 syslog(LOG_ERR,
621 "Address %s is not in address family AF_INET",
622 address);
623 exit(EX_USAGE);
625 ai_fam = AF_INET6;
627 break;
628 #endif
629 case AF_UNSPEC:
630 break;
631 default:
632 syslog(LOG_ERR,
633 "Numeric IPv6 addresses need to be enclosed in []");
634 exit(EX_USAGE);
636 if (!portptr)
637 portptr = (char *)"tftp";
638 if (*address) {
639 if (fd4 >= 0) {
640 bindaddr4.sin_family = AF_INET;
641 err = set_sock_addr(address,
642 (union sock_addr *)&bindaddr4, NULL);
643 if (err) {
644 syslog(LOG_ERR,
645 "cannot resolve local IPv4 bind address: %s, %s",
646 address, gai_strerror(err));
647 exit(EX_NOINPUT);
650 #ifdef HAVE_IPV6
651 if (fd6 >= 0) {
652 bindaddr6.sin6_family = AF_INET6;
653 err = set_sock_addr(address,
654 (union sock_addr *)&bindaddr6, NULL);
655 if (err) {
656 if (fd4 >= 0) {
657 syslog(LOG_ERR,
658 "cannot resolve local IPv6 bind address: %s"
659 "(%s); using IPv4 only",
660 address, gai_strerror(err));
661 close(fd6);
662 fd6 = -1;
663 } else {
664 syslog(LOG_ERR,
665 "cannot resolve local IPv6 bind address: %s"
666 "(%s)", address, gai_strerror(err));
667 exit(EX_NOINPUT);
671 #endif
672 } else {
673 /* Default to using INADDR_ANY */
676 if (portptr && *portptr) {
677 servent = getservbyname(portptr, "udp");
678 if (servent) {
679 if (fd4 >= 0)
680 bindaddr4.sin_port = servent->s_port;
681 #ifdef HAVE_IPV6
682 if (fd6 >= 0)
683 bindaddr6.sin6_port = servent->s_port;
684 #endif
685 } else if ((port = strtoul(portptr, &eportptr, 0))
686 && !*eportptr) {
687 if (fd4 >= 0)
688 bindaddr4.sin_port = htons(port);
689 #ifdef HAVE_IPV6
690 if (fd6 >= 0)
691 bindaddr6.sin6_port = htons(port);
692 #endif
693 } else if (!strcmp(portptr, "tftp")) {
694 /* It's TFTP, we're OK */
695 } else {
696 syslog(LOG_ERR, "cannot resolve local bind port: %s",
697 portptr);
698 exit(EX_NOINPUT);
703 if (fd4 >= 0) {
704 if (bind(fd4, (struct sockaddr *)&bindaddr4,
705 sizeof(bindaddr4)) < 0) {
706 syslog(LOG_ERR, "cannot bind to local IPv4 socket: %m");
707 exit(EX_OSERR);
710 #ifdef HAVE_IPV6
711 if (fd6 >= 0) {
712 #if defined(IPV6_V6ONLY)
713 int on = 1;
714 if (fd4 >= 0 || force_ipv6)
715 if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on,
716 sizeof(on)))
717 syslog(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m");
718 #endif
719 if (bind(fd6, (struct sockaddr *)&bindaddr6,
720 sizeof(bindaddr6)) < 0) {
721 if (fd4 >= 0) {
722 syslog(LOG_ERR,
723 "cannot bind to local IPv6 socket,"
724 "IPv6 disabled: %m");
725 close(fd6);
726 fd6 = -1;
727 } else {
728 syslog(LOG_ERR, "cannot bind to local IPv6 socket: %m");
729 exit(EX_OSERR);
733 #endif
734 /* Daemonize this process */
735 /* Note: when running in secure mode (-s), we must not chdir, since
736 we are already in the proper directory. */
737 if (!nodaemon && daemon(secure, 0) < 0) {
738 syslog(LOG_ERR, "cannot daemonize: %m");
739 exit(EX_OSERR);
741 set_signal(SIGTERM, handle_exit, 0);
742 set_signal(SIGINT, handle_exit, 0);
743 if (pidfile) {
744 pf = fopen (pidfile, "w");
745 if (!pf) {
746 syslog(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile);
747 pidfile = NULL;
748 } else {
749 if (fprintf(pf, "%d\n", getpid()) < 0)
750 syslog(LOG_ERR, "error writing pid file '%s': %m", pidfile);
751 if (fclose(pf))
752 syslog(LOG_ERR, "error closing pid file '%s': %m", pidfile);
755 if (fd6 > fd4)
756 fdmax = fd6;
757 else
758 fdmax = fd4;
759 } else {
760 /* 0 is our socket descriptor */
761 close(1);
762 close(2);
763 fd = 0;
764 fdmax = 0;
765 /* Note: on Cygwin, select() on a nonblocking socket becomes
766 a nonblocking select. */
767 #ifndef __CYGWIN__
768 set_socket_nonblock(fd, 1);
769 #endif
772 /* Disable path MTU discovery */
773 pmtu_discovery_off(fd);
775 /* This means we don't want to wait() for children */
776 #ifdef SA_NOCLDWAIT
777 set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP | SA_NOCLDWAIT);
778 #else
779 set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP);
780 #endif
782 /* Take SIGHUP and use it to set a variable. This
783 is polled synchronously to make sure we don't
784 lose packets as a result. */
785 set_signal(SIGHUP, handle_sighup, 0);
787 if (spec_umask || !unixperms)
788 umask(my_umask);
790 while (1) {
791 fd_set readset;
792 struct timeval tv_waittime;
793 int rv;
795 if (exit_signal) { /* happens in standalone mode only */
796 if (pidfile && unlink(pidfile)) {
797 syslog(LOG_WARNING, "error removing pid file '%s': %m", pidfile);
798 exit(EX_OSERR);
799 } else {
800 exit(0);
804 if (caught_sighup) {
805 caught_sighup = 0;
806 if (standalone) {
807 #ifdef WITH_REGEX
808 if (rewrite_file) {
809 freerules(rewrite_rules);
810 rewrite_rules = read_remap_rules(rewrite_file);
812 #endif
813 } else {
814 /* Return to inetd for respawn */
815 exit(0);
819 FD_ZERO(&readset);
820 if (standalone) {
821 if (fd4 >= 0) {
822 FD_SET(fd4, &readset);
823 #ifdef __CYGWIN__
824 /* On Cygwin, select() on a nonblocking socket returns
825 immediately, with a rv of 0! */
826 set_socket_nonblock(fd4, 0);
827 #endif
829 if (fd6 >= 0) {
830 FD_SET(fd6, &readset);
831 #ifdef __CYGWIN__
832 /* On Cygwin, select() on a nonblocking socket returns
833 immediately, with a rv of 0! */
834 set_socket_nonblock(fd6, 0);
835 #endif
837 } else { /* fd always 0 */
838 fd = 0;
839 #ifdef __CYGWIN__
840 /* On Cygwin, select() on a nonblocking socket returns
841 immediately, with a rv of 0! */
842 set_socket_nonblock(fd, 0);
843 #endif
844 FD_SET(fd, &readset);
846 tv_waittime.tv_sec = waittime;
847 tv_waittime.tv_usec = 0;
850 /* Never time out if we're in standalone mode */
851 rv = select(fdmax + 1, &readset, NULL, NULL,
852 standalone ? NULL : &tv_waittime);
853 if (rv == -1 && errno == EINTR)
854 continue; /* Signal caught, reloop */
856 if (rv == -1) {
857 syslog(LOG_ERR, "select loop: %m");
858 exit(EX_IOERR);
859 } else if (rv == 0) {
860 exit(0); /* Timeout, return to inetd */
863 if (standalone) {
864 if ((fd4 >= 0) && FD_ISSET(fd4, &readset))
865 fd = fd4;
866 else if ((fd6 >= 0) && FD_ISSET(fd6, &readset))
867 fd = fd6;
868 else /* not in set ??? */
869 continue;
871 #ifdef __CYGWIN__
872 /* On Cygwin, select() on a nonblocking socket returns
873 immediately, with a rv of 0! */
874 set_socket_nonblock(fd, 0);
875 #endif
877 fromlen = sizeof(from);
878 n = myrecvfrom(fd, buf, sizeof(buf), 0,
879 (struct sockaddr *)&from, &fromlen, &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(__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, __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 #ifdef HAVE_INITGROUPS
983 setrv = initgroups(user, pw->pw_gid);
984 if (setrv) {
985 syslog(LOG_ERR, "cannot set groups for user %s", user);
986 exit(EX_OSERR);
988 #else
989 #ifdef HAVE_SETGROUPS
990 if (setgroups(0, NULL)) {
991 syslog(LOG_ERR, "cannot clear group list");
993 #endif
994 #endif
996 /* Chroot and drop privileges */
997 if (secure) {
998 if (chroot(".")) {
999 syslog(LOG_ERR, "chroot: %m");
1000 exit(EX_OSERR);
1002 #ifdef __CYGWIN__
1003 chdir("/"); /* Cygwin chroot() bug workaround */
1004 #endif
1006 #ifdef HAVE_SETREGID
1007 setrv = setregid(pw->pw_gid, pw->pw_gid);
1008 #else
1009 setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid);
1010 #endif
1012 #ifdef HAVE_SETREUID
1013 setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid);
1014 #else
1015 /* Important: setuid() must come first */
1016 setrv = setrv || setuid(pw->pw_uid) ||
1017 (geteuid() != pw->pw_uid && seteuid(pw->pw_uid));
1018 #endif
1020 if (setrv) {
1021 syslog(LOG_ERR, "cannot drop privileges: %m");
1022 exit(EX_OSERR);
1025 /* Process the request... */
1026 if (pick_port_bind(peer, &myaddr, portrange_from, portrange_to) < 0) {
1027 syslog(LOG_ERR, "bind: %m");
1028 exit(EX_IOERR);
1031 if (connect(peer, &from.sa, SOCKLEN(&from)) < 0) {
1032 syslog(LOG_ERR, "connect: %m");
1033 exit(EX_IOERR);
1036 /* Disable path MTU discovery */
1037 pmtu_discovery_off(peer);
1039 tp = (struct tftphdr *)buf;
1040 tp_opcode = ntohs(tp->th_opcode);
1041 if (tp_opcode == RRQ || tp_opcode == WRQ)
1042 tftp(tp, n);
1043 exit(0);
1046 static char *rewrite_access(char *, int, int, const char **);
1047 static int validate_access(char *, int, const struct formats *, const char **);
1048 static void tftp_sendfile(const struct formats *, struct tftphdr *, int);
1049 static void tftp_recvfile(const struct formats *, struct tftphdr *, int);
1051 struct formats {
1052 const char *f_mode;
1053 char *(*f_rewrite) (char *, int, int, const char **);
1054 int (*f_validate) (char *, int, const struct formats *, const char **);
1055 void (*f_send) (const struct formats *, struct tftphdr *, int);
1056 void (*f_recv) (const struct formats *, struct tftphdr *, int);
1057 int f_convert;
1059 static const struct formats formats[] = {
1061 "netascii", rewrite_access, validate_access, tftp_sendfile,
1062 tftp_recvfile, 1}, {
1063 "octet", rewrite_access, validate_access, tftp_sendfile,
1064 tftp_recvfile, 0}, {
1065 NULL, NULL, NULL, NULL, NULL, 0}
1069 * Handle initial connection protocol.
1071 int tftp(struct tftphdr *tp, int size)
1073 char *cp, *end;
1074 int argn, ecode;
1075 const struct formats *pf = NULL;
1076 char *origfilename;
1077 char *filename, *mode = NULL;
1078 const char *errmsgptr;
1079 u_short tp_opcode = ntohs(tp->th_opcode);
1081 char *val = NULL, *opt = NULL;
1082 char *ap = ackbuf + 2;
1084 ((struct tftphdr *)ackbuf)->th_opcode = htons(OACK);
1086 origfilename = cp = (char *)&(tp->th_stuff);
1087 argn = 0;
1089 end = (char *)tp + size;
1091 while (cp < end && *cp) {
1092 do {
1093 cp++;
1094 } while (cp < end && *cp);
1096 if (*cp) {
1097 nak(EBADOP, "Request not null-terminated");
1098 exit(0);
1101 argn++;
1102 if (argn == 1) {
1103 mode = ++cp;
1104 } else if (argn == 2) {
1105 for (cp = mode; *cp; cp++)
1106 *cp = tolower(*cp);
1107 for (pf = formats; pf->f_mode; pf++) {
1108 if (!strcmp(pf->f_mode, mode))
1109 break;
1111 if (!pf->f_mode) {
1112 nak(EBADOP, "Unknown mode");
1113 exit(0);
1115 if (!(filename = (*pf->f_rewrite)
1116 (origfilename, tp_opcode, from.sa.sa_family, &errmsgptr))) {
1117 nak(EACCESS, errmsgptr); /* File denied by mapping rule */
1118 exit(0);
1120 if (verbosity >= 1) {
1121 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1122 tmpbuf, INET6_ADDRSTRLEN);
1123 if (!tmp_p) {
1124 tmp_p = tmpbuf;
1125 strcpy(tmpbuf, "???");
1127 if (filename == origfilename
1128 || !strcmp(filename, origfilename))
1129 syslog(LOG_NOTICE, "%s from %s filename %s\n",
1130 tp_opcode == WRQ ? "WRQ" : "RRQ",
1131 tmp_p, filename);
1132 else
1133 syslog(LOG_NOTICE,
1134 "%s from %s filename %s remapped to %s\n",
1135 tp_opcode == WRQ ? "WRQ" : "RRQ",
1136 tmp_p, origfilename,
1137 filename);
1139 ecode =
1140 (*pf->f_validate) (filename, tp_opcode, pf, &errmsgptr);
1141 if (ecode) {
1142 nak(ecode, errmsgptr);
1143 exit(0);
1145 opt = ++cp;
1146 } else if (argn & 1) {
1147 val = ++cp;
1148 } else {
1149 do_opt(opt, val, &ap);
1150 opt = ++cp;
1154 if (!pf) {
1155 nak(EBADOP, "Missing mode");
1156 exit(0);
1159 if (ap != (ackbuf + 2)) {
1160 if (tp_opcode == WRQ)
1161 (*pf->f_recv) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1162 else
1163 (*pf->f_send) (pf, (struct tftphdr *)ackbuf, ap - ackbuf);
1164 } else {
1165 if (tp_opcode == WRQ)
1166 (*pf->f_recv) (pf, NULL, 0);
1167 else
1168 (*pf->f_send) (pf, NULL, 0);
1170 exit(0); /* Request completed */
1173 static int blksize_set;
1176 * Set a non-standard block size (c.f. RFC2348)
1178 static int set_blksize(uintmax_t *vp)
1180 uintmax_t sz = *vp;
1182 if (blksize_set)
1183 return 0;
1185 if (sz < 8)
1186 return 0;
1187 else if (sz > max_blksize)
1188 sz = max_blksize;
1190 *vp = segsize = sz;
1191 blksize_set = 1;
1192 return 1;
1196 * Set a power-of-two block size (nonstandard)
1198 static int set_blksize2(uintmax_t *vp)
1200 uintmax_t sz = *vp;
1202 if (blksize_set)
1203 return 0;
1205 if (sz < 8)
1206 return (0);
1207 else if (sz > max_blksize)
1208 sz = max_blksize;
1209 else
1211 /* Convert to a power of two */
1212 if (sz & (sz - 1)) {
1213 unsigned int sz1 = 1;
1214 /* Not a power of two - need to convert */
1215 while (sz >>= 1)
1216 sz1 <<= 1;
1217 sz = sz1;
1220 *vp = segsize = sz;
1221 blksize_set = 1;
1222 return 1;
1226 * Set the block number rollover value
1228 static int set_rollover(uintmax_t *vp)
1230 uintmax_t ro = *vp;
1232 if (ro > 65535)
1233 return 0;
1235 rollover_val = (uint16_t)ro;
1236 return 1;
1240 * Return a file size (c.f. RFC2349)
1241 * For netascii mode, we don't know the size ahead of time;
1242 * so reject the option.
1244 static int set_tsize(uintmax_t *vp)
1246 uintmax_t sz = *vp;
1248 if (!tsize_ok)
1249 return 0;
1251 if (sz == 0)
1252 sz = tsize;
1254 *vp = sz;
1255 return 1;
1259 * Set the timeout (c.f. RFC2349). This is supposed
1260 * to be the (default) retransmission timeout, but being an
1261 * integer in seconds it seems a bit limited.
1263 static int set_timeout(uintmax_t *vp)
1265 uintmax_t to = *vp;
1267 if (to < 1 || to > 255)
1268 return 0;
1270 rexmtval = timeout = to * 1000000UL;
1271 maxtimeout = rexmtval * TIMEOUT_LIMIT;
1273 return 1;
1276 /* Similar, but in microseconds. We allow down to 10 ms. */
1277 static int set_utimeout(uintmax_t *vp)
1279 uintmax_t to = *vp;
1281 if (to < 10000UL || to > 255000000UL)
1282 return 0;
1284 rexmtval = timeout = to;
1285 maxtimeout = rexmtval * TIMEOUT_LIMIT;
1287 return 1;
1291 * Conservative calculation for the size of a buffer which can hold an
1292 * arbitrary integer
1294 #define OPTBUFSIZE (sizeof(uintmax_t) * CHAR_BIT / 3 + 3)
1297 * Parse RFC2347 style options; we limit the arguments to positive
1298 * integers which matches all our current options.
1300 static void do_opt(const char *opt, const char *val, char **ap)
1302 struct options *po;
1303 char retbuf[OPTBUFSIZE];
1304 char *p = *ap;
1305 size_t optlen, retlen;
1306 char *vend;
1307 uintmax_t v;
1309 /* Global option-parsing variables initialization */
1310 blksize_set = 0;
1312 if (!*opt || !*val)
1313 return;
1315 errno = 0;
1316 v = strtoumax(val, &vend, 10);
1317 if (*vend || errno == ERANGE)
1318 return;
1320 for (po = options; po->o_opt; po++)
1321 if (!strcasecmp(po->o_opt, opt)) {
1322 if (po->o_fnc(&v)) {
1323 optlen = strlen(opt);
1324 retlen = sprintf(retbuf, "%"PRIuMAX, v);
1326 if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) {
1327 nak(EOPTNEG, "Insufficient space for options");
1328 exit(0);
1331 memcpy(p, opt, optlen+1);
1332 p += optlen+1;
1333 memcpy(p, retbuf, retlen+1);
1334 p += retlen+1;
1335 } else {
1336 nak(EOPTNEG, "Unsupported option(s) requested");
1337 exit(0);
1339 break;
1342 *ap = p;
1345 #ifdef WITH_REGEX
1348 * This is called by the remap engine when it encounters macros such
1349 * as \i. It should write the output in "output" if non-NULL, and
1350 * return the length of the output (generated or not).
1352 * Return -1 on failure.
1354 static int rewrite_macros(char macro, char *output)
1356 char *p, tb[INET6_ADDRSTRLEN];
1357 int l=0;
1359 switch (macro) {
1360 case 'i':
1361 p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1362 tb, INET6_ADDRSTRLEN);
1363 if (output && p)
1364 strcpy(output, p);
1365 if (!p)
1366 return 0;
1367 else
1368 return strlen(p);
1370 case 'x':
1371 if (output) {
1372 if (from.sa.sa_family == AF_INET) {
1373 sprintf(output, "%08lX",
1374 (unsigned long)ntohl(from.si.sin_addr.s_addr));
1375 l = 8;
1376 #ifdef HAVE_IPV6
1377 } else {
1378 unsigned char *c = (unsigned char *)SOCKADDR_P(&from);
1379 p = tb;
1380 for (l = 0; l < 16; l++) {
1381 sprintf(p, "%02X", *c);
1382 c++;
1383 p += 2;
1385 strcpy(output, tb);
1386 l = strlen(tb);
1387 #endif
1390 return l;
1392 default:
1393 return -1;
1398 * Modify the filename, if applicable. If it returns NULL, deny the access.
1400 static char *rewrite_access(char *filename, int mode, int af,
1401 const char **msg)
1403 if (rewrite_rules) {
1404 char *newname =
1405 rewrite_string(filename, rewrite_rules,
1406 mode != RRQ ? 'P' : 'G', af,
1407 rewrite_macros, msg);
1408 filename = newname;
1410 return filename;
1413 #else
1414 static char *rewrite_access(char *filename, int mode, int af, const char **msg)
1416 (void)mode; /* Avoid warning */
1417 (void)msg;
1418 (void)af;
1419 return filename;
1421 #endif
1423 static FILE *file;
1425 * Validate file access. Since we
1426 * have no uid or gid, for now require
1427 * file to exist and be publicly
1428 * readable/writable, unless -p specified.
1429 * If we were invoked with arguments
1430 * from inetd then the file must also be
1431 * in one of the given directory prefixes.
1432 * Note also, full path name must be
1433 * given as we have no login directory.
1435 static int validate_access(char *filename, int mode,
1436 const struct formats *pf, const char **errmsg)
1438 struct stat stbuf;
1439 int i, len;
1440 int fd, wmode, rmode;
1441 char *cp;
1442 const char **dirp;
1443 char stdio_mode[3];
1445 tsize_ok = 0;
1446 *errmsg = NULL;
1448 if (!secure) {
1449 if (*filename != '/') {
1450 *errmsg = "Only absolute filenames allowed";
1451 return (EACCESS);
1455 * prevent tricksters from getting around the directory
1456 * restrictions
1458 len = strlen(filename);
1459 for (i = 1; i < len - 3; i++) {
1460 cp = filename + i;
1461 if (*cp == '.' && memcmp(cp - 1, "/../", 4) == 0) {
1462 *errmsg = "Reverse path not allowed";
1463 return (EACCESS);
1467 for (dirp = dirs; *dirp; dirp++)
1468 if (strncmp(filename, *dirp, strlen(*dirp)) == 0)
1469 break;
1470 if (*dirp == 0 && dirp != dirs) {
1471 *errmsg = "Forbidden directory";
1472 return (EACCESS);
1477 * We use different a different permissions scheme if `cancreate' is
1478 * set.
1480 wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : O_BINARY);
1481 rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY);
1483 #ifndef HAVE_FTRUNCATE
1484 wmode |= O_TRUNC; /* This really sucks on a dupe */
1485 #endif
1487 fd = open(filename, mode == RRQ ? rmode : wmode, 0666);
1488 if (fd < 0) {
1489 switch (errno) {
1490 case ENOENT:
1491 case ENOTDIR:
1492 return ENOTFOUND;
1493 case ENOSPC:
1494 return ENOSPACE;
1495 case EEXIST:
1496 return EEXISTS;
1497 default:
1498 return errno + 100;
1502 if (fstat(fd, &stbuf) < 0)
1503 exit(EX_OSERR); /* This shouldn't happen */
1505 /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */
1506 if (lock_file(fd, mode != RRQ))
1507 exit(0);
1509 if (mode == RRQ) {
1510 if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) {
1511 *errmsg = "File must have global read permissions";
1512 return (EACCESS);
1514 tsize = stbuf.st_size;
1515 /* We don't know the tsize if conversion is needed */
1516 tsize_ok = !pf->f_convert;
1517 } else {
1518 if (!unixperms) {
1519 if ((stbuf.st_mode & (S_IWRITE >> 6)) == 0) {
1520 *errmsg = "File must have global write permissions";
1521 return (EACCESS);
1525 #ifdef HAVE_FTRUNCATE
1526 /* We didn't get to truncate the file at open() time */
1527 if (ftruncate(fd, (off_t) 0)) {
1528 *errmsg = "Cannot reset file size";
1529 return (EACCESS);
1531 #endif
1532 tsize = 0;
1533 tsize_ok = 1;
1536 stdio_mode[0] = (mode == RRQ) ? 'r' : 'w';
1537 stdio_mode[1] = (pf->f_convert) ? 't' : 'b';
1538 stdio_mode[2] = '\0';
1540 file = fdopen(fd, stdio_mode);
1541 if (file == NULL)
1542 exit(EX_OSERR); /* Internal error */
1544 return (0);
1548 * Send the requested file.
1550 static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
1552 struct tftphdr *dp;
1553 struct tftphdr *ap; /* ack packet */
1554 static u_short block = 1; /* Static to avoid longjmp funnies */
1555 u_short ap_opcode, ap_block;
1556 unsigned long r_timeout;
1557 int size, n;
1559 if (oap) {
1560 timeout = rexmtval;
1561 (void)sigsetjmp(timeoutbuf, 1);
1562 oack:
1563 r_timeout = timeout;
1564 if (send(peer, oap, oacklen, 0) != oacklen) {
1565 syslog(LOG_WARNING, "tftpd: oack: %m\n");
1566 goto abort;
1568 for (;;) {
1569 n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1570 if (n < 0) {
1571 syslog(LOG_WARNING, "tftpd: read: %m\n");
1572 goto abort;
1574 ap = (struct tftphdr *)ackbuf;
1575 ap_opcode = ntohs((u_short) ap->th_opcode);
1576 ap_block = ntohs((u_short) ap->th_block);
1578 if (ap_opcode == ERROR) {
1579 syslog(LOG_WARNING,
1580 "tftp: client does not accept options\n");
1581 goto abort;
1583 if (ap_opcode == ACK) {
1584 if (ap_block == 0)
1585 break;
1586 /* Resynchronize with the other side */
1587 (void)synchnet(peer);
1588 goto oack;
1593 dp = r_init();
1594 do {
1595 size = readit(file, &dp, pf->f_convert);
1596 if (size < 0) {
1597 nak(errno + 100, NULL);
1598 goto abort;
1600 dp->th_opcode = htons((u_short) DATA);
1601 dp->th_block = htons((u_short) block);
1602 timeout = rexmtval;
1603 (void)sigsetjmp(timeoutbuf, 1);
1605 r_timeout = timeout;
1606 if (send(peer, dp, size + 4, 0) != size + 4) {
1607 syslog(LOG_WARNING, "tftpd: write: %m");
1608 goto abort;
1610 read_ahead(file, pf->f_convert);
1611 for (;;) {
1612 n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout);
1613 if (n < 0) {
1614 syslog(LOG_WARNING, "tftpd: read(ack): %m");
1615 goto abort;
1617 ap = (struct tftphdr *)ackbuf;
1618 ap_opcode = ntohs((u_short) ap->th_opcode);
1619 ap_block = ntohs((u_short) ap->th_block);
1621 if (ap_opcode == ERROR)
1622 goto abort;
1624 if (ap_opcode == ACK) {
1625 if (ap_block == block) {
1626 break;
1628 /* Re-synchronize with the other side */
1629 (void)synchnet(peer);
1631 * RFC1129/RFC1350: We MUST NOT re-send the DATA
1632 * packet in response to an invalid ACK. Doing so
1633 * would cause the Sorcerer's Apprentice bug.
1638 if (!++block)
1639 block = rollover_val;
1640 } while (size == segsize);
1641 abort:
1642 (void)fclose(file);
1646 * Receive a file.
1648 static void tftp_recvfile(const struct formats *pf, struct tftphdr *oap, int oacklen)
1650 struct tftphdr *dp;
1651 int n, size;
1652 /* These are "static" to avoid longjmp funnies */
1653 static struct tftphdr *ap; /* ack buffer */
1654 static u_short block = 0;
1655 static int acksize;
1656 u_short dp_opcode, dp_block;
1657 unsigned long r_timeout;
1659 dp = w_init();
1660 do {
1661 timeout = rexmtval;
1663 if (!block && oap) {
1664 ap = (struct tftphdr *)ackbuf;
1665 acksize = oacklen;
1666 } else {
1667 ap = (struct tftphdr *)ackbuf;
1668 ap->th_opcode = htons((u_short) ACK);
1669 ap->th_block = htons((u_short) block);
1670 acksize = 4;
1671 /* If we're sending a regular ACK, that means we have successfully
1672 * sent the OACK. Clear oap so that we won't try to send another
1673 * OACK when the block number wraps back to 0. */
1674 oap = NULL;
1676 if (!++block)
1677 block = rollover_val;
1678 (void)sigsetjmp(timeoutbuf, 1);
1679 send_ack:
1680 r_timeout = timeout;
1681 if (send(peer, ackbuf, acksize, 0) != acksize) {
1682 syslog(LOG_WARNING, "tftpd: write(ack): %m");
1683 goto abort;
1685 write_behind(file, pf->f_convert);
1686 for (;;) {
1687 n = recv_time(peer, dp, PKTSIZE, 0, &r_timeout);
1688 if (n < 0) { /* really? */
1689 syslog(LOG_WARNING, "tftpd: read: %m");
1690 goto abort;
1692 dp_opcode = ntohs((u_short) dp->th_opcode);
1693 dp_block = ntohs((u_short) dp->th_block);
1694 if (dp_opcode == ERROR)
1695 goto abort;
1696 if (dp_opcode == DATA) {
1697 if (dp_block == block) {
1698 break; /* normal */
1700 /* Re-synchronize with the other side */
1701 (void)synchnet(peer);
1702 if (dp_block == (block - 1))
1703 goto send_ack; /* rexmit */
1706 /* size = write(file, dp->th_data, n - 4); */
1707 size = writeit(file, &dp, n - 4, pf->f_convert);
1708 if (size != (n - 4)) { /* ahem */
1709 if (size < 0)
1710 nak(errno + 100, NULL);
1711 else
1712 nak(ENOSPACE, NULL);
1713 goto abort;
1715 } while (size == segsize);
1716 write_behind(file, pf->f_convert);
1717 (void)fclose(file); /* close data file */
1719 ap->th_opcode = htons((u_short) ACK); /* send the "final" ack */
1720 ap->th_block = htons((u_short) (block));
1721 (void)send(peer, ackbuf, 4, 0);
1723 timeout_quit = 1; /* just quit on timeout */
1724 n = recv_time(peer, buf, sizeof(buf), 0, &timeout); /* normally times out and quits */
1725 timeout_quit = 0;
1727 if (n >= 4 && /* if read some data */
1728 dp_opcode == DATA && /* and got a data block */
1729 block == dp_block) { /* then my last ack was lost */
1730 (void)send(peer, ackbuf, 4, 0); /* resend final ack */
1732 abort:
1733 return;
1736 static const char *const errmsgs[] = {
1737 "Undefined error code", /* 0 - EUNDEF */
1738 "File not found", /* 1 - ENOTFOUND */
1739 "Access denied", /* 2 - EACCESS */
1740 "Disk full or allocation exceeded", /* 3 - ENOSPACE */
1741 "Illegal TFTP operation", /* 4 - EBADOP */
1742 "Unknown transfer ID", /* 5 - EBADID */
1743 "File already exists", /* 6 - EEXISTS */
1744 "No such user", /* 7 - ENOUSER */
1745 "Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */
1748 #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *))
1751 * Send a nak packet (error message).
1752 * Error code passed in is one of the
1753 * standard TFTP codes, or a UNIX errno
1754 * offset by 100.
1756 static void nak(int error, const char *msg)
1758 struct tftphdr *tp;
1759 int length;
1761 tp = (struct tftphdr *)buf;
1762 tp->th_opcode = htons((u_short) ERROR);
1764 if (error >= 100) {
1765 /* This is a Unix errno+100 */
1766 if (!msg)
1767 msg = strerror(error - 100);
1768 error = EUNDEF;
1769 } else {
1770 if ((unsigned)error >= ERR_CNT)
1771 error = EUNDEF;
1773 if (!msg)
1774 msg = errmsgs[error];
1777 tp->th_code = htons((u_short) error);
1779 length = strlen(msg) + 1;
1780 memcpy(tp->th_msg, msg, length);
1781 length += 4; /* Add space for header */
1783 if (verbosity >= 2) {
1784 tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from),
1785 tmpbuf, INET6_ADDRSTRLEN);
1786 if (!tmp_p) {
1787 tmp_p = tmpbuf;
1788 strcpy(tmpbuf, "???");
1790 syslog(LOG_INFO, "sending NAK (%d, %s) to %s",
1791 error, tp->th_msg, tmp_p);
1794 if (send(peer, buf, length, 0) != length)
1795 syslog(LOG_WARNING, "nak: %m");