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