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