1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T 28 * All Rights Reserved. 29 */ 30 31 /* 32 * University Copyright- Copyright (c) 1982, 1986, 1988 33 * The Regents of the University of California. 34 * All Rights Reserved. 35 * 36 * University Acknowledgment- Portions of this document are derived from 37 * software developed by the University of California, Berkeley, and its 38 * contributors. 39 */ 40 41 #pragma ident "%Z%%M% %I% %E% SMI" 42 43 /* 44 * Trivial file transfer protocol server. A top level process runs in 45 * an infinite loop fielding new TFTP requests. A child process, 46 * communicating via a pipe with the top level process, sends delayed 47 * NAKs for those that we can't handle. A new child process is created 48 * to service each request that we can handle. The top level process 49 * exits after a period of time during which no new requests are 50 * received. 51 */ 52 53 #include <sys/types.h> 54 #include <sys/socket.h> 55 #include <sys/wait.h> 56 #include <sys/stat.h> 57 #include <sys/time.h> 58 59 #include <netinet/in.h> 60 61 #include <arpa/inet.h> 62 #include <dirent.h> 63 #include <signal.h> 64 #include <stdio.h> 65 #include <stdlib.h> 66 #include <unistd.h> 67 #include <errno.h> 68 #include <ctype.h> 69 #include <netdb.h> 70 #include <setjmp.h> 71 #include <syslog.h> 72 #include <sys/param.h> 73 #include <fcntl.h> 74 #include <pwd.h> 75 #include <string.h> 76 #include <priv_utils.h> 77 #include "tftpcommon.h" 78 79 #define TIMEOUT 5 80 #define DELAY_SECS 3 81 #define DALLYSECS 60 82 83 #define SYSLOG_MSG(message) \ 84 (syslog((((errno == ENETUNREACH) || (errno == EHOSTUNREACH) || \ 85 (errno == ECONNREFUSED)) ? LOG_WARNING : LOG_ERR), message)) 86 87 static int rexmtval = TIMEOUT; 88 static int maxtimeout = 5*TIMEOUT; 89 static int securetftp; 90 static int debug; 91 static int disable_pnp; 92 static int standalone; 93 static uid_t uid_nobody = UID_NOBODY; 94 static uid_t gid_nobody = GID_NOBODY; 95 static int reqsock = -1; 96 /* file descriptor of request socket */ 97 static socklen_t fromlen; 98 static socklen_t fromplen; 99 static struct sockaddr_storage client; 100 static struct sockaddr_in6 *sin6_ptr; 101 static struct sockaddr_in *sin_ptr; 102 static struct sockaddr_in6 *from6_ptr; 103 static struct sockaddr_in *from_ptr; 104 static int addrfmly; 105 static int peer; 106 static off_t tsize; 107 static tftpbuf ackbuf; 108 static struct sockaddr_storage from; 109 static boolean_t tsize_set; 110 static pid_t child; 111 /* pid of child handling delayed replys */ 112 static int delay_fd [2]; 113 /* pipe for communicating with child */ 114 static FILE *file; 115 static char *filename; 116 117 static union { 118 struct tftphdr hdr; 119 char data[SEGSIZE + 4]; 120 } buf; 121 122 static union { 123 struct tftphdr hdr; 124 char data[SEGSIZE]; 125 } oackbuf; 126 127 struct delay_info { 128 long timestamp; /* time request received */ 129 int ecode; /* error code to return */ 130 struct sockaddr_storage from; /* address of client */ 131 }; 132 133 int blocksize = SEGSIZE; /* Number of data bytes in a DATA packet */ 134 135 /* 136 * Default directory for unqualified names 137 * Used by TFTP boot procedures 138 */ 139 static char *homedir = "/tftpboot"; 140 141 struct formats { 142 char *f_mode; 143 int (*f_validate)(int); 144 void (*f_send)(struct formats *, int); 145 void (*f_recv)(struct formats *, int); 146 int f_convert; 147 }; 148 149 static void delayed_responder(void); 150 static void tftp(struct tftphdr *, int); 151 static int validate_filename(int); 152 static void tftpd_sendfile(struct formats *, int); 153 static void tftpd_recvfile(struct formats *, int); 154 static void nak(int); 155 static char *blksize_handler(int, char *, int *); 156 static char *timeout_handler(int, char *, int *); 157 static char *tsize_handler(int, char *, int *); 158 159 static struct formats formats[] = { 160 { "netascii", validate_filename, tftpd_sendfile, tftpd_recvfile, 1 }, 161 { "octet", validate_filename, tftpd_sendfile, tftpd_recvfile, 0 }, 162 { NULL } 163 }; 164 165 struct options { 166 char *opt_name; 167 char *(*opt_handler)(int, char *, int *); 168 }; 169 170 static struct options options[] = { 171 { "blksize", blksize_handler }, 172 { "timeout", timeout_handler }, 173 { "tsize", tsize_handler }, 174 { NULL } 175 }; 176 177 static char optbuf[MAX_OPTVAL_LEN]; 178 static int timeout; 179 static sigjmp_buf timeoutbuf; 180 181 int 182 main(int argc, char **argv) 183 { 184 struct tftphdr *tp; 185 int n; 186 int c; 187 struct passwd *pwd; /* for "nobody" entry */ 188 struct in_addr ipv4addr; 189 char abuf[INET6_ADDRSTRLEN]; 190 socklen_t addrlen; 191 192 openlog("tftpd", LOG_PID, LOG_DAEMON); 193 194 pwd = getpwnam("nobody"); 195 if (pwd != NULL) { 196 uid_nobody = pwd->pw_uid; 197 gid_nobody = pwd->pw_gid; 198 } 199 200 (void) __init_daemon_priv( 201 PU_LIMITPRIVS, 202 uid_nobody, gid_nobody, 203 PRIV_PROC_FORK, PRIV_PROC_CHROOT, NULL); 204 205 /* 206 * Limit set is still "all." Trim it down to just what we need: 207 * fork and chroot. 208 */ 209 (void) priv_set(PRIV_SET, 210 PRIV_ALLSETS, PRIV_PROC_FORK, PRIV_PROC_CHROOT, NULL); 211 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL); 212 (void) priv_set(PRIV_SET, PRIV_INHERITABLE, NULL); 213 214 while ((c = getopt(argc, argv, "dspS")) != EOF) 215 switch (c) { 216 case 'd': /* enable debug */ 217 debug++; 218 continue; 219 case 's': /* secure daemon */ 220 securetftp = 1; 221 continue; 222 case 'p': /* disable name pnp mapping */ 223 disable_pnp = 1; 224 continue; 225 case 'S': 226 standalone = 1; 227 continue; 228 case '?': 229 default: 230 usage: 231 (void) fprintf(stderr, 232 "usage: %s [-spd] [home-directory]\n", argv[0]); 233 for (; optind < argc; optind++) 234 syslog(LOG_ERR, "bad argument %s", 235 argv[optind]); 236 exit(1); 237 } 238 239 if (optind < argc) 240 if (optind == argc - 1 && *argv [optind] == '/') 241 homedir = argv [optind]; 242 else 243 goto usage; 244 245 if (pipe(delay_fd) < 0) { 246 syslog(LOG_ERR, "pipe (main): %m"); 247 exit(1); 248 } 249 250 (void) sigset(SIGCHLD, SIG_IGN); /* no zombies please */ 251 252 if (standalone) { 253 socklen_t clientlen; 254 255 sin6_ptr = (struct sockaddr_in6 *)&client; 256 clientlen = sizeof (struct sockaddr_in6); 257 reqsock = socket(AF_INET6, SOCK_DGRAM, 0); 258 if (reqsock == -1) { 259 perror("socket"); 260 exit(1); 261 } 262 (void) memset(&client, 0, clientlen); 263 sin6_ptr->sin6_family = AF_INET6; 264 sin6_ptr->sin6_port = htons(IPPORT_TFTP); 265 if (bind(reqsock, (struct sockaddr *)&client, 266 clientlen) == -1) { 267 perror("bind"); 268 exit(1); 269 } 270 if (debug) 271 (void) puts("running in standalone mode..."); 272 } else { 273 /* request socket passed on fd 0 by inetd */ 274 reqsock = 0; 275 } 276 if (debug) { 277 int on = 1; 278 279 (void) setsockopt(reqsock, SOL_SOCKET, SO_DEBUG, 280 (char *)&on, sizeof (on)); 281 } 282 283 (void) chdir(homedir); 284 285 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL); 286 if ((child = fork()) < 0) { 287 syslog(LOG_ERR, "fork (main): %m"); 288 exit(1); 289 } 290 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL); 291 292 if (child == 0) { 293 (void) priv_set(PRIV_SET, PRIV_ALLSETS, NULL); 294 delayed_responder(); 295 } /* child */ 296 297 /* close read side of pipe */ 298 (void) close(delay_fd[0]); 299 300 301 /* 302 * Top level handling of incomming tftp requests. Read a request 303 * and pass it off to be handled. If request is valid, handling 304 * forks off and parent returns to this loop. If no new requests 305 * are received for DALLYSECS, exit and return to inetd. 306 */ 307 308 for (;;) { 309 fd_set readfds; 310 struct timeval dally; 311 312 FD_ZERO(&readfds); 313 FD_SET(reqsock, &readfds); 314 dally.tv_sec = DALLYSECS; 315 dally.tv_usec = 0; 316 317 n = select(reqsock + 1, &readfds, NULL, NULL, &dally); 318 if (n < 0) { 319 if (errno == EINTR) 320 continue; 321 syslog(LOG_ERR, "select: %m"); 322 (void) kill(child, SIGKILL); 323 exit(1); 324 } 325 if (n == 0) { 326 /* Select timed out. Its time to die. */ 327 if (standalone) 328 continue; 329 else { 330 (void) kill(child, SIGKILL); 331 exit(0); 332 } 333 } 334 addrlen = sizeof (from); 335 if (getsockname(reqsock, (struct sockaddr *)&from, 336 &addrlen) < 0) { 337 syslog(LOG_ERR, "getsockname: %m"); 338 exit(1); 339 } 340 341 switch (from.ss_family) { 342 case AF_INET: 343 fromlen = (socklen_t)sizeof (struct sockaddr_in); 344 break; 345 case AF_INET6: 346 fromlen = (socklen_t)sizeof (struct sockaddr_in6); 347 break; 348 default: 349 syslog(LOG_ERR, 350 "Unknown address Family on peer connection %d", 351 from.ss_family); 352 exit(1); 353 } 354 355 n = recvfrom(reqsock, &buf, sizeof (buf), 0, 356 (struct sockaddr *)&from, &fromlen); 357 if (n < 0) { 358 if (errno == EINTR) 359 continue; 360 if (standalone) 361 perror("recvfrom"); 362 else 363 syslog(LOG_ERR, "recvfrom: %m"); 364 (void) kill(child, SIGKILL); 365 exit(1); 366 } 367 368 (void) alarm(0); 369 370 switch (from.ss_family) { 371 case AF_INET: 372 addrfmly = AF_INET; 373 fromplen = sizeof (struct sockaddr_in); 374 sin_ptr = (struct sockaddr_in *)&client; 375 (void) memset(&client, 0, fromplen); 376 sin_ptr->sin_family = AF_INET; 377 break; 378 case AF_INET6: 379 addrfmly = AF_INET6; 380 fromplen = sizeof (struct sockaddr_in6); 381 sin6_ptr = (struct sockaddr_in6 *)&client; 382 (void) memset(&client, 0, fromplen); 383 sin6_ptr->sin6_family = AF_INET6; 384 break; 385 default: 386 syslog(LOG_ERR, 387 "Unknown address Family on peer connection"); 388 exit(1); 389 } 390 peer = socket(addrfmly, SOCK_DGRAM, 0); 391 if (peer < 0) { 392 if (standalone) 393 perror("socket (main)"); 394 else 395 syslog(LOG_ERR, "socket (main): %m"); 396 (void) kill(child, SIGKILL); 397 exit(1); 398 } 399 if (debug) { 400 int on = 1; 401 402 (void) setsockopt(peer, SOL_SOCKET, SO_DEBUG, 403 (char *)&on, sizeof (on)); 404 } 405 406 if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) { 407 if (standalone) 408 perror("bind (main)"); 409 else 410 syslog(LOG_ERR, "bind (main): %m"); 411 (void) kill(child, SIGKILL); 412 exit(1); 413 } 414 if (standalone && debug) { 415 sin6_ptr = (struct sockaddr_in6 *)&client; 416 from6_ptr = (struct sockaddr_in6 *)&from; 417 if (IN6_IS_ADDR_V4MAPPED(&from6_ptr->sin6_addr)) { 418 IN6_V4MAPPED_TO_INADDR(&from6_ptr->sin6_addr, 419 &ipv4addr); 420 (void) inet_ntop(AF_INET, &ipv4addr, abuf, 421 sizeof (abuf)); 422 } else { 423 (void) inet_ntop(AF_INET6, 424 &from6_ptr->sin6_addr, abuf, 425 sizeof (abuf)); 426 } 427 /* get local port */ 428 if (getsockname(peer, (struct sockaddr *)&client, 429 &fromplen) < 0) 430 perror("getsockname (main)"); 431 (void) fprintf(stderr, 432 "request from %s port %d; local port %d\n", 433 abuf, from6_ptr->sin6_port, sin6_ptr->sin6_port); 434 } 435 tp = &buf.hdr; 436 tp->th_opcode = ntohs((ushort_t)tp->th_opcode); 437 if (tp->th_opcode == RRQ || tp->th_opcode == WRQ) 438 tftp(tp, n); 439 440 (void) close(peer); 441 (void) fclose(file); 442 } 443 444 /*NOTREACHED*/ 445 return (0); 446 } 447 448 static void 449 delayed_responder(void) 450 { 451 struct delay_info dinfo; 452 long now; 453 454 /* we don't use the descriptors passed in to the parent */ 455 (void) close(0); 456 (void) close(1); 457 if (standalone) 458 (void) close(reqsock); 459 460 /* close write side of pipe */ 461 (void) close(delay_fd[1]); 462 463 for (;;) { 464 int n; 465 466 if ((n = read(delay_fd[0], &dinfo, 467 sizeof (dinfo))) != sizeof (dinfo)) { 468 if (n < 0) { 469 if (errno == EINTR) 470 continue; 471 if (standalone) 472 perror("read from pipe " 473 "(delayed responder)"); 474 else 475 syslog(LOG_ERR, "read from pipe: %m"); 476 } 477 exit(1); 478 } 479 switch (dinfo.from.ss_family) { 480 case AF_INET: 481 addrfmly = AF_INET; 482 fromplen = sizeof (struct sockaddr_in); 483 sin_ptr = (struct sockaddr_in *)&client; 484 (void) memset(&client, 0, fromplen); 485 sin_ptr->sin_family = AF_INET; 486 break; 487 case AF_INET6: 488 addrfmly = AF_INET6; 489 fromplen = sizeof (struct sockaddr_in6); 490 sin6_ptr = (struct sockaddr_in6 *)&client; 491 (void) memset(&client, 0, fromplen); 492 sin6_ptr->sin6_family = AF_INET6; 493 break; 494 } 495 peer = socket(addrfmly, SOCK_DGRAM, 0); 496 if (peer == -1) { 497 if (standalone) 498 perror("socket (delayed responder)"); 499 else 500 syslog(LOG_ERR, "socket (delay): %m"); 501 exit(1); 502 } 503 if (debug) { 504 int on = 1; 505 506 (void) setsockopt(peer, SOL_SOCKET, SO_DEBUG, 507 (char *)&on, sizeof (on)); 508 } 509 510 if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) { 511 if (standalone) 512 perror("bind (delayed responder)"); 513 else 514 syslog(LOG_ERR, "bind (delay): %m"); 515 exit(1); 516 } 517 if (client.ss_family == AF_INET) { 518 from_ptr = (struct sockaddr_in *)&dinfo.from; 519 from_ptr->sin_family = AF_INET; 520 } else { 521 from6_ptr = (struct sockaddr_in6 *)&dinfo.from; 522 from6_ptr->sin6_family = AF_INET6; 523 } 524 /* 525 * Since a request hasn't been received from the client 526 * before the delayed responder process is forked, the 527 * from variable is uninitialized. So set it to contain 528 * the client address. 529 */ 530 from = dinfo.from; 531 532 /* 533 * only sleep if DELAY_SECS has not elapsed since 534 * original request was received. Ensure that `now' 535 * is not earlier than `dinfo.timestamp' 536 */ 537 now = time(0); 538 if ((uint_t)(now - dinfo.timestamp) < DELAY_SECS) 539 (void) sleep(DELAY_SECS - (now - dinfo.timestamp)); 540 nak(dinfo.ecode); 541 (void) close(peer); 542 } /* for */ 543 544 /* NOTREACHED */ 545 } 546 547 /* 548 * Handle the Blocksize option. 549 * Return the blksize option value string to include in the OACK reply. 550 */ 551 /*ARGSUSED*/ 552 static char * 553 blksize_handler(int opcode, char *optval, int *errcode) 554 { 555 char *endp; 556 int value; 557 558 *errcode = -1; 559 errno = 0; 560 value = (int)strtol(optval, &endp, 10); 561 if (errno != 0 || value < MIN_BLKSIZE || *endp != '\0') 562 return (NULL); 563 /* 564 * As the blksize value in the OACK reply can be less than the value 565 * requested, to support broken clients if the value requested is larger 566 * than allowed in the RFC, reply with the maximum value permitted. 567 */ 568 if (value > MAX_BLKSIZE) 569 value = MAX_BLKSIZE; 570 571 blocksize = value; 572 (void) snprintf(optbuf, sizeof (optbuf), "%d", blocksize); 573 return (optbuf); 574 } 575 576 /* 577 * Handle the Timeout Interval option. 578 * Return the timeout option value string to include in the OACK reply. 579 */ 580 /*ARGSUSED*/ 581 static char * 582 timeout_handler(int opcode, char *optval, int *errcode) 583 { 584 char *endp; 585 int value; 586 587 *errcode = -1; 588 errno = 0; 589 value = (int)strtol(optval, &endp, 10); 590 if (errno != 0 || *endp != '\0') 591 return (NULL); 592 /* 593 * The timeout value in the OACK reply must match the value specified 594 * by the client, so if an invalid timeout is requested don't include 595 * the timeout option in the OACK reply. 596 */ 597 if (value < MIN_TIMEOUT || value > MAX_TIMEOUT) 598 return (NULL); 599 600 rexmtval = value; 601 maxtimeout = 5 * rexmtval; 602 (void) snprintf(optbuf, sizeof (optbuf), "%d", rexmtval); 603 return (optbuf); 604 } 605 606 /* 607 * Handle the Transfer Size option. 608 * Return the tsize option value string to include in the OACK reply. 609 */ 610 static char * 611 tsize_handler(int opcode, char *optval, int *errcode) 612 { 613 char *endp; 614 longlong_t value; 615 616 *errcode = -1; 617 errno = 0; 618 value = strtoll(optval, &endp, 10); 619 if (errno != 0 || value < 0 || *endp != '\0') 620 return (NULL); 621 622 if (opcode == RRQ) { 623 if (tsize_set == B_FALSE) 624 return (NULL); 625 /* 626 * The tsize value should be 0 for a read request, but to 627 * support broken clients we don't check that it is. 628 */ 629 } else { 630 #if _FILE_OFFSET_BITS == 32 631 if (value > MAXOFF_T) { 632 *errcode = ENOSPACE; 633 return (NULL); 634 } 635 #endif 636 tsize = value; 637 tsize_set = B_TRUE; 638 } 639 (void) snprintf(optbuf, sizeof (optbuf), OFF_T_FMT, tsize); 640 return (optbuf); 641 } 642 643 /* 644 * Process any options included by the client in the request packet. 645 * Return the size of the OACK reply packet built or 0 for no OACK reply. 646 */ 647 static int 648 process_options(int opcode, char *opts, char *endopts) 649 { 650 char *cp, *optname, *optval, *ostr, *oackend; 651 struct tftphdr *oackp; 652 int i, errcode; 653 654 /* 655 * To continue to interoperate with broken TFTP clients, ignore 656 * null padding appended to requests which don't include options. 657 */ 658 cp = opts; 659 while ((cp < endopts) && (*cp == '\0')) 660 cp++; 661 if (cp == endopts) 662 return (0); 663 664 /* 665 * Construct an Option ACKnowledgement packet if any requested option 666 * is recognized. 667 */ 668 oackp = &oackbuf.hdr; 669 oackend = oackbuf.data + sizeof (oackbuf.data); 670 oackp->th_opcode = htons((ushort_t)OACK); 671 cp = (char *)&oackp->th_stuff; 672 while (opts < endopts) { 673 optname = opts; 674 if ((optval = next_field(optname, endopts)) == NULL) { 675 nak(EOPTNEG); 676 exit(1); 677 } 678 if ((opts = next_field(optval, endopts)) == NULL) { 679 nak(EOPTNEG); 680 exit(1); 681 } 682 for (i = 0; options[i].opt_name != NULL; i++) { 683 if (strcasecmp(optname, options[i].opt_name) == 0) 684 break; 685 } 686 if (options[i].opt_name != NULL) { 687 ostr = options[i].opt_handler(opcode, optval, &errcode); 688 if (ostr != NULL) { 689 cp += strlcpy(cp, options[i].opt_name, 690 oackend - cp) + 1; 691 if (cp <= oackend) 692 cp += strlcpy(cp, ostr, oackend - cp) 693 + 1; 694 695 if (cp > oackend) { 696 nak(EOPTNEG); 697 exit(1); 698 } 699 } else if (errcode >= 0) { 700 nak(errcode); 701 exit(1); 702 } 703 } 704 } 705 if (cp != (char *)&oackp->th_stuff) 706 return (cp - oackbuf.data); 707 return (0); 708 } 709 710 /* 711 * Handle access errors caused by client requests. 712 */ 713 714 static void 715 delay_exit(int ecode) 716 { 717 struct delay_info dinfo; 718 719 /* 720 * The most likely cause of an error here is that 721 * someone has broadcast an RRQ packet because s/he's 722 * trying to boot and doesn't know who the server is. 723 * Rather then sending an ERROR packet immediately, we 724 * wait a while so that the real server has a better chance 725 * of getting through (in case client has lousy Ethernet 726 * interface). We write to a child that handles delayed 727 * ERROR packets to avoid delaying service to new 728 * requests. Of course, we would rather just not answer 729 * RRQ packets that are broadcasted, but there's no way 730 * for a user process to determine this. 731 */ 732 733 dinfo.timestamp = time(0); 734 735 /* 736 * If running in secure mode, we map all errors to EACCESS 737 * so that the client gets no information about which files 738 * or directories exist. 739 */ 740 if (securetftp) 741 dinfo.ecode = EACCESS; 742 else 743 dinfo.ecode = ecode; 744 745 dinfo.from = from; 746 if (write(delay_fd[1], &dinfo, sizeof (dinfo)) != 747 sizeof (dinfo)) { 748 syslog(LOG_ERR, "delayed write failed."); 749 (void) kill(child, SIGKILL); 750 exit(1); 751 } 752 exit(0); 753 } 754 755 /* 756 * Handle initial connection protocol. 757 */ 758 static void 759 tftp(struct tftphdr *tp, int size) 760 { 761 char *cp; 762 int readmode, ecode; 763 struct formats *pf; 764 char *mode; 765 int fd; 766 static boolean_t firsttime = B_TRUE; 767 int oacklen; 768 struct stat statb; 769 770 readmode = (tp->th_opcode == RRQ); 771 filename = (char *)&tp->th_stuff; 772 mode = next_field(filename, &buf.data[size]); 773 cp = (mode != NULL) ? next_field(mode, &buf.data[size]) : NULL; 774 if (cp == NULL) { 775 nak(EBADOP); 776 exit(1); 777 } 778 if (debug && standalone) { 779 (void) fprintf(stderr, "%s for %s %s ", 780 readmode ? "RRQ" : "WRQ", filename, mode); 781 print_options(stderr, cp, size + buf.data - cp); 782 (void) putc('\n', stderr); 783 } 784 for (pf = formats; pf->f_mode != NULL; pf++) 785 if (strcasecmp(pf->f_mode, mode) == 0) 786 break; 787 if (pf->f_mode == NULL) { 788 nak(EBADOP); 789 exit(1); 790 } 791 792 /* 793 * XXX fork a new process to handle this request before 794 * chroot(), otherwise the parent won't be able to create a 795 * new socket as that requires library access to system files 796 * and devices. 797 */ 798 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL); 799 switch (fork()) { 800 case -1: 801 syslog(LOG_ERR, "fork (tftp): %m"); 802 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL); 803 return; 804 case 0: 805 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL); 806 break; 807 default: 808 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL); 809 return; 810 } 811 812 /* 813 * Try to see if we can access the file. The access can still 814 * fail later if we are running in secure mode because of 815 * the chroot() call. We only want to execute the chroot() once. 816 */ 817 if (securetftp && firsttime) { 818 (void) priv_set( 819 PRIV_SET, PRIV_EFFECTIVE, PRIV_PROC_CHROOT, NULL); 820 if (chroot(homedir) == -1) { 821 syslog(LOG_ERR, 822 "tftpd: cannot chroot to directory %s: %m\n", 823 homedir); 824 delay_exit(EACCESS); 825 } 826 else 827 { 828 firsttime = B_FALSE; 829 } 830 (void) priv_set(PRIV_SET, PRIV_EFFECTIVE, NULL); 831 (void) chdir("/"); /* cd to new root */ 832 } 833 (void) priv_set(PRIV_SET, PRIV_ALLSETS, NULL); 834 835 ecode = (*pf->f_validate)(tp->th_opcode); 836 if (ecode != 0) 837 delay_exit(ecode); 838 839 /* we don't use the descriptors passed in to the parent */ 840 (void) close(STDIN_FILENO); 841 (void) close(STDOUT_FILENO); 842 843 /* 844 * Try to open file as low-priv setuid/setgid. Note that 845 * a chroot() has already been done. 846 */ 847 fd = open(filename, 848 (readmode ? O_RDONLY : (O_WRONLY|O_TRUNC)) | O_NONBLOCK); 849 if ((fd < 0) || (fstat(fd, &statb) < 0)) 850 delay_exit((errno == ENOENT) ? ENOTFOUND : EACCESS); 851 852 if (((statb.st_mode & ((readmode) ? S_IROTH : S_IWOTH)) == 0) || 853 ((statb.st_mode & S_IFMT) != S_IFREG)) 854 delay_exit(EACCESS); 855 856 file = fdopen(fd, readmode ? "r" : "w"); 857 if (file == NULL) 858 delay_exit(errno + 100); 859 860 /* Don't know the size of transfers which involve conversion */ 861 tsize_set = (readmode && (pf->f_convert == 0)); 862 if (tsize_set) 863 tsize = statb.st_size; 864 865 /* Deal with any options sent by the client */ 866 oacklen = process_options(tp->th_opcode, cp, buf.data + size); 867 868 if (tp->th_opcode == WRQ) 869 (*pf->f_recv)(pf, oacklen); 870 else 871 (*pf->f_send)(pf, oacklen); 872 873 exit(0); 874 } 875 876 /* 877 * Maybe map filename into another one. 878 * 879 * For PNP, we get TFTP boot requests for filenames like 880 * <Unknown Hex IP Addr>.<Architecture Name>. We must 881 * map these to 'pnp.<Architecture Name>'. Note that 882 * uppercase is mapped to lowercase in the architecture names. 883 * 884 * For names <Hex IP Addr> there are two cases. First, 885 * it may be a buggy prom that omits the architecture code. 886 * So first check if <Hex IP Addr>.<arch> is on the filesystem. 887 * Second, this is how most Sun3s work; assume <arch> is sun3. 888 */ 889 890 static char * 891 pnp_check(char *origname) 892 { 893 static char buf [MAXNAMLEN + 1]; 894 char *arch, *s, *bufend; 895 in_addr_t ipaddr; 896 int len = (origname ? strlen(origname) : 0); 897 DIR *dir; 898 struct dirent *dp; 899 900 if (securetftp || disable_pnp || len < 8 || len > 14) 901 return (NULL); 902 903 /* 904 * XXX see if this cable allows pnp; if not, return NULL 905 * Requires YP support for determining this! 906 */ 907 908 ipaddr = htonl(strtol(origname, &arch, 16)); 909 if ((arch == NULL) || (len > 8 && *arch != '.')) 910 return (NULL); 911 if (len == 8) 912 arch = "SUN3"; 913 else 914 arch++; 915 916 /* 917 * Allow <Hex IP Addr>* filename request to to be 918 * satisfied by <Hex IP Addr><Any Suffix> rather 919 * than enforcing this to be Sun3 systems. Also serves 920 * to make case of suffix a don't-care. 921 */ 922 if ((dir = opendir(homedir)) == NULL) 923 return (NULL); 924 while ((dp = readdir(dir)) != NULL) { 925 if (strncmp(origname, dp->d_name, 8) == 0) { 926 (void) strlcpy(buf, dp->d_name, sizeof (buf)); 927 (void) closedir(dir); 928 return (buf); 929 } 930 } 931 (void) closedir(dir); 932 933 /* 934 * XXX maybe call YP master for most current data iff 935 * pnp is enabled. 936 */ 937 938 /* 939 * only do mapping PNP boot file name for machines that 940 * are not in the hosts database. 941 */ 942 if (gethostbyaddr((char *)&ipaddr, sizeof (ipaddr), AF_INET) != NULL) 943 return (NULL); 944 945 s = buf + strlcpy(buf, "pnp.", sizeof (buf)); 946 bufend = &buf[sizeof (buf) - 1]; 947 while ((*arch != '\0') && (s < bufend)) 948 *s++ = tolower (*arch++); 949 *s = '\0'; 950 return (buf); 951 } 952 953 954 /* 955 * Try to validate filename. If the filename doesn't exist try PNP mapping. 956 */ 957 static int 958 validate_filename(int mode) 959 { 960 struct stat stbuf; 961 char *origfile; 962 963 if (stat(filename, &stbuf) < 0) { 964 if (errno != ENOENT) 965 return (EACCESS); 966 if (mode == WRQ) 967 return (ENOTFOUND); 968 969 /* try to map requested filename into a pnp filename */ 970 origfile = filename; 971 filename = pnp_check(origfile); 972 if (filename == NULL) 973 return (ENOTFOUND); 974 975 if (stat(filename, &stbuf) < 0) 976 return (errno == ENOENT ? ENOTFOUND : EACCESS); 977 syslog(LOG_NOTICE, "%s -> %s\n", origfile, filename); 978 } 979 980 return (0); 981 } 982 983 /* ARGSUSED */ 984 static void 985 timer(int signum) 986 { 987 timeout += rexmtval; 988 if (timeout >= maxtimeout) 989 exit(1); 990 siglongjmp(timeoutbuf, 1); 991 } 992 993 /* 994 * Send the requested file. 995 */ 996 static void 997 tftpd_sendfile(struct formats *pf, int oacklen) 998 { 999 struct tftphdr *dp; 1000 volatile int block = 1; 1001 int size, n, serrno; 1002 1003 if (oacklen != 0) { 1004 (void) sigset(SIGALRM, timer); 1005 timeout = 0; 1006 (void) sigsetjmp(timeoutbuf, 1); 1007 if (debug && standalone) { 1008 (void) fputs("Sending OACK ", stderr); 1009 print_options(stderr, (char *)&oackbuf.hdr.th_stuff, 1010 oacklen - 2); 1011 (void) putc('\n', stderr); 1012 } 1013 if (sendto(peer, &oackbuf, oacklen, 0, 1014 (struct sockaddr *)&from, fromplen) != oacklen) { 1015 if (debug && standalone) { 1016 serrno = errno; 1017 perror("sendto (oack)"); 1018 errno = serrno; 1019 } 1020 SYSLOG_MSG("sendto (oack): %m"); 1021 goto abort; 1022 } 1023 (void) alarm(rexmtval); /* read the ack */ 1024 for (;;) { 1025 (void) sigrelse(SIGALRM); 1026 n = recv(peer, &ackbuf, sizeof (ackbuf), 0); 1027 (void) sighold(SIGALRM); 1028 if (n < 0) { 1029 if (errno == EINTR) 1030 continue; 1031 serrno = errno; 1032 SYSLOG_MSG("recv (ack): %m"); 1033 if (debug && standalone) { 1034 errno = serrno; 1035 perror("recv (ack)"); 1036 } 1037 goto abort; 1038 } 1039 ackbuf.tb_hdr.th_opcode = 1040 ntohs((ushort_t)ackbuf.tb_hdr.th_opcode); 1041 ackbuf.tb_hdr.th_block = 1042 ntohs((ushort_t)ackbuf.tb_hdr.th_block); 1043 1044 if (ackbuf.tb_hdr.th_opcode == ERROR) { 1045 if (debug && standalone) { 1046 (void) fprintf(stderr, 1047 "received ERROR %d", 1048 ackbuf.tb_hdr.th_code); 1049 if (n > 4) 1050 (void) fprintf(stderr, 1051 " %.*s", n - 4, 1052 ackbuf.tb_hdr.th_msg); 1053 (void) putc('\n', stderr); 1054 } 1055 goto abort; 1056 } 1057 1058 if (ackbuf.tb_hdr.th_opcode == ACK) { 1059 if (debug && standalone) 1060 (void) fprintf(stderr, 1061 "received ACK for block %d\n", 1062 ackbuf.tb_hdr.th_block); 1063 if (ackbuf.tb_hdr.th_block == 0) 1064 break; 1065 /* 1066 * Don't resend the OACK, avoids getting stuck 1067 * in an OACK/ACK loop if the client keeps 1068 * replying with a bad ACK. Client will either 1069 * send a good ACK or timeout sending bad ones. 1070 */ 1071 } 1072 } 1073 cancel_alarm(); 1074 } 1075 dp = r_init(); 1076 do { 1077 (void) sigset(SIGALRM, timer); 1078 size = readit(file, &dp, pf->f_convert); 1079 if (size < 0) { 1080 nak(errno + 100); 1081 goto abort; 1082 } 1083 dp->th_opcode = htons((ushort_t)DATA); 1084 dp->th_block = htons((ushort_t)block); 1085 timeout = 0; 1086 (void) sigsetjmp(timeoutbuf, 1); 1087 if (debug && standalone) 1088 (void) fprintf(stderr, "Sending DATA block %d\n", 1089 block); 1090 if (sendto(peer, dp, size + 4, 0, 1091 (struct sockaddr *)&from, fromplen) != size + 4) { 1092 if (debug && standalone) { 1093 serrno = errno; 1094 perror("sendto (data)"); 1095 errno = serrno; 1096 } 1097 SYSLOG_MSG("sendto (data): %m"); 1098 goto abort; 1099 } 1100 read_ahead(file, pf->f_convert); 1101 (void) alarm(rexmtval); /* read the ack */ 1102 for (;;) { 1103 (void) sigrelse(SIGALRM); 1104 n = recv(peer, &ackbuf, sizeof (ackbuf), 0); 1105 (void) sighold(SIGALRM); 1106 if (n < 0) { 1107 if (errno == EINTR) 1108 continue; 1109 serrno = errno; 1110 SYSLOG_MSG("recv (ack): %m"); 1111 if (debug && standalone) { 1112 errno = serrno; 1113 perror("recv (ack)"); 1114 } 1115 goto abort; 1116 } 1117 ackbuf.tb_hdr.th_opcode = 1118 ntohs((ushort_t)ackbuf.tb_hdr.th_opcode); 1119 ackbuf.tb_hdr.th_block = 1120 ntohs((ushort_t)ackbuf.tb_hdr.th_block); 1121 1122 if (ackbuf.tb_hdr.th_opcode == ERROR) { 1123 if (debug && standalone) { 1124 (void) fprintf(stderr, 1125 "received ERROR %d", 1126 ackbuf.tb_hdr.th_code); 1127 if (n > 4) 1128 (void) fprintf(stderr, 1129 " %.*s", n - 4, 1130 ackbuf.tb_hdr.th_msg); 1131 (void) putc('\n', stderr); 1132 } 1133 goto abort; 1134 } 1135 1136 if (ackbuf.tb_hdr.th_opcode == ACK) { 1137 if (debug && standalone) 1138 (void) fprintf(stderr, 1139 "received ACK for block %d\n", 1140 ackbuf.tb_hdr.th_block); 1141 if (ackbuf.tb_hdr.th_block == block) { 1142 break; 1143 } 1144 /* 1145 * Never resend the current DATA packet on 1146 * receipt of a duplicate ACK, doing so would 1147 * cause the "Sorcerer's Apprentice Syndrome". 1148 */ 1149 } 1150 } 1151 cancel_alarm(); 1152 block++; 1153 } while (size == blocksize); 1154 1155 abort: 1156 cancel_alarm(); 1157 (void) fclose(file); 1158 } 1159 1160 /* ARGSUSED */ 1161 static void 1162 justquit(int signum) 1163 { 1164 exit(0); 1165 } 1166 1167 /* 1168 * Receive a file. 1169 */ 1170 static void 1171 tftpd_recvfile(struct formats *pf, int oacklen) 1172 { 1173 struct tftphdr *dp; 1174 struct tftphdr *ap; /* ack buffer */ 1175 int block = 0, n, size, acklen, serrno; 1176 1177 dp = w_init(); 1178 ap = &ackbuf.tb_hdr; 1179 do { 1180 (void) sigset(SIGALRM, timer); 1181 timeout = 0; 1182 if (oacklen == 0) { 1183 ap->th_opcode = htons((ushort_t)ACK); 1184 ap->th_block = htons((ushort_t)block); 1185 acklen = 4; 1186 } else { 1187 /* copy OACK packet to the ack buffer ready to send */ 1188 (void) memcpy(&ackbuf, &oackbuf, oacklen); 1189 acklen = oacklen; 1190 oacklen = 0; 1191 } 1192 block++; 1193 (void) sigsetjmp(timeoutbuf, 1); 1194 send_ack: 1195 if (debug && standalone) { 1196 if (ap->th_opcode == htons((ushort_t)ACK)) { 1197 (void) fprintf(stderr, 1198 "Sending ACK for block %d\n", block - 1); 1199 } else { 1200 (void) fprintf(stderr, "Sending OACK "); 1201 print_options(stderr, (char *)&ap->th_stuff, 1202 acklen - 2); 1203 (void) putc('\n', stderr); 1204 } 1205 } 1206 if (sendto(peer, &ackbuf, acklen, 0, (struct sockaddr *)&from, 1207 fromplen) != acklen) { 1208 if (ap->th_opcode == htons((ushort_t)ACK)) { 1209 if (debug && standalone) { 1210 serrno = errno; 1211 perror("sendto (ack)"); 1212 errno = serrno; 1213 } 1214 syslog(LOG_ERR, "sendto (ack): %m\n"); 1215 } else { 1216 if (debug && standalone) { 1217 serrno = errno; 1218 perror("sendto (oack)"); 1219 errno = serrno; 1220 } 1221 syslog(LOG_ERR, "sendto (oack): %m\n"); 1222 } 1223 goto abort; 1224 } 1225 if (write_behind(file, pf->f_convert) < 0) { 1226 nak(errno + 100); 1227 goto abort; 1228 } 1229 (void) alarm(rexmtval); 1230 for (;;) { 1231 (void) sigrelse(SIGALRM); 1232 n = recv(peer, dp, blocksize + 4, 0); 1233 (void) sighold(SIGALRM); 1234 if (n < 0) { /* really? */ 1235 if (errno == EINTR) 1236 continue; 1237 syslog(LOG_ERR, "recv (data): %m"); 1238 goto abort; 1239 } 1240 dp->th_opcode = ntohs((ushort_t)dp->th_opcode); 1241 dp->th_block = ntohs((ushort_t)dp->th_block); 1242 if (dp->th_opcode == ERROR) { 1243 cancel_alarm(); 1244 if (debug && standalone) { 1245 (void) fprintf(stderr, 1246 "received ERROR %d", dp->th_code); 1247 if (n > 4) 1248 (void) fprintf(stderr, 1249 " %.*s", n - 4, dp->th_msg); 1250 (void) putc('\n', stderr); 1251 } 1252 return; 1253 } 1254 if (dp->th_opcode == DATA) { 1255 if (debug && standalone) 1256 (void) fprintf(stderr, 1257 "Received DATA block %d\n", 1258 dp->th_block); 1259 if (dp->th_block == block) { 1260 break; /* normal */ 1261 } 1262 /* Re-synchronize with the other side */ 1263 if (synchnet(peer) < 0) { 1264 nak(errno + 100); 1265 goto abort; 1266 } 1267 if (dp->th_block == (block-1)) 1268 goto send_ack; /* rexmit */ 1269 } 1270 } 1271 cancel_alarm(); 1272 /* size = write(file, dp->th_data, n - 4); */ 1273 size = writeit(file, &dp, n - 4, pf->f_convert); 1274 if (size != (n - 4)) { 1275 nak((size < 0) ? (errno + 100) : ENOSPACE); 1276 goto abort; 1277 } 1278 } while (size == blocksize); 1279 if (write_behind(file, pf->f_convert) < 0) { 1280 nak(errno + 100); 1281 goto abort; 1282 } 1283 n = fclose(file); /* close data file */ 1284 file = NULL; 1285 if (n == EOF) { 1286 nak(errno + 100); 1287 goto abort; 1288 } 1289 1290 ap->th_opcode = htons((ushort_t)ACK); /* send the "final" ack */ 1291 ap->th_block = htons((ushort_t)(block)); 1292 if (debug && standalone) 1293 (void) fprintf(stderr, "Sending ACK for block %d\n", block); 1294 if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from, 1295 fromplen) == -1) { 1296 if (debug && standalone) 1297 perror("sendto (ack)"); 1298 } 1299 (void) sigset(SIGALRM, justquit); /* just quit on timeout */ 1300 (void) alarm(rexmtval); 1301 /* normally times out and quits */ 1302 n = recv(peer, dp, blocksize + 4, 0); 1303 (void) alarm(0); 1304 dp->th_opcode = ntohs((ushort_t)dp->th_opcode); 1305 dp->th_block = ntohs((ushort_t)dp->th_block); 1306 if (n >= 4 && /* if read some data */ 1307 dp->th_opcode == DATA && /* and got a data block */ 1308 block == dp->th_block) { /* then my last ack was lost */ 1309 if (debug && standalone) { 1310 (void) fprintf(stderr, "Sending ACK for block %d\n", 1311 block); 1312 } 1313 /* resend final ack */ 1314 if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from, 1315 fromplen) == -1) { 1316 if (debug && standalone) 1317 perror("sendto (last ack)"); 1318 } 1319 } 1320 1321 abort: 1322 cancel_alarm(); 1323 if (file != NULL) 1324 (void) fclose(file); 1325 } 1326 1327 /* 1328 * Send a nak packet (error message). 1329 * Error code passed in is one of the 1330 * standard TFTP codes, or a UNIX errno 1331 * offset by 100. 1332 * Handles connected as well as unconnected peer. 1333 */ 1334 static void 1335 nak(int error) 1336 { 1337 struct tftphdr *tp; 1338 int length; 1339 struct errmsg *pe; 1340 int ret; 1341 1342 tp = &buf.hdr; 1343 tp->th_opcode = htons((ushort_t)ERROR); 1344 tp->th_code = htons((ushort_t)error); 1345 for (pe = errmsgs; pe->e_code >= 0; pe++) 1346 if (pe->e_code == error) 1347 break; 1348 if (pe->e_code < 0) { 1349 pe->e_msg = strerror(error - 100); 1350 tp->th_code = EUNDEF; /* set 'undef' errorcode */ 1351 } 1352 (void) strlcpy(tp->th_msg, (pe->e_msg != NULL) ? pe->e_msg : "UNKNOWN", 1353 sizeof (buf) - sizeof (struct tftphdr)); 1354 length = strlen(tp->th_msg); 1355 length += sizeof (struct tftphdr); 1356 if (debug && standalone) 1357 (void) fprintf(stderr, "Sending NAK: %s\n", tp->th_msg); 1358 1359 ret = sendto(peer, &buf, length, 0, (struct sockaddr *)&from, 1360 fromplen); 1361 if (ret == -1 && errno == EISCONN) { 1362 /* Try without an address */ 1363 ret = send(peer, &buf, length, 0); 1364 } 1365 if (ret == -1) { 1366 if (standalone) 1367 perror("sendto (nak)"); 1368 else 1369 syslog(LOG_ERR, "tftpd: nak: %m\n"); 1370 } else if (ret != length) { 1371 if (standalone) 1372 perror("sendto (nak) lost data"); 1373 else 1374 syslog(LOG_ERR, "tftpd: nak: %d lost\n", length - ret); 1375 } 1376 } 1377