68#include <stdio.h> 69#include <stdlib.h> 70#include <string.h> 71#include <syslog.h> 72#include <tcpd.h> 73#include <unistd.h> 74 75#include "tftp-file.h" 76#include "tftp-io.h" 77#include "tftp-utils.h" 78#include "tftp-transfer.h" 79#include "tftp-options.h" 80 81static void tftp_wrq(int peer, char *, ssize_t); 82static void tftp_rrq(int peer, char *, ssize_t); 83 84/* 85 * Null-terminated directory prefix list for absolute pathname requests and 86 * search list for relative pathname requests. 87 * 88 * MAXDIRS should be at least as large as the number of arguments that 89 * inetd allows (currently 20). 90 */ 91#define MAXDIRS 20 92static struct dirlist { 93 const char *name; 94 int len; 95} dirs[MAXDIRS+1]; 96static int suppress_naks; 97static int logging; 98static int ipchroot; 99static int create_new = 0; 100static const char *newfile_format = "%Y%m%d"; 101static int increase_name = 0; 102static mode_t mask = S_IWGRP | S_IWOTH; 103 104struct formats; 105static void tftp_recvfile(int peer, const char *mode); 106static void tftp_xmitfile(int peer, const char *mode); 107static int validate_access(int peer, char **, int); 108static char peername[NI_MAXHOST]; 109 110static FILE *file; 111 112static struct formats { 113 const char *f_mode; 114 int f_convert; 115} formats[] = { 116 { "netascii", 1 }, 117 { "octet", 0 }, 118 { NULL, 0 } 119}; 120 121int 122main(int argc, char *argv[]) 123{ 124 struct tftphdr *tp; 125 int peer; 126 socklen_t peerlen, len; 127 ssize_t n; 128 int ch; 129 char *chroot_dir = NULL; 130 struct passwd *nobody; 131 const char *chuser = "nobody"; 132 char recvbuffer[MAXPKTSIZE]; 133 int allow_ro = 1, allow_wo = 1; 134 135 tzset(); /* syslog in localtime */ 136 acting_as_client = 0; 137 138 tftp_openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP); 139 while ((ch = getopt(argc, argv, "cCd:F:lnoOp:s:u:U:wW")) != -1) { 140 switch (ch) { 141 case 'c': 142 ipchroot = 1; 143 break; 144 case 'C': 145 ipchroot = 2; 146 break; 147 case 'd': 148 if (atoi(optarg) != 0) 149 debug += atoi(optarg); 150 else 151 debug |= debug_finds(optarg); 152 break; 153 case 'F': 154 newfile_format = optarg; 155 break; 156 case 'l': 157 logging = 1; 158 break; 159 case 'n': 160 suppress_naks = 1; 161 break; 162 case 'o': 163 options_rfc_enabled = 0; 164 break; 165 case 'O': 166 options_extra_enabled = 0; 167 break; 168 case 'p': 169 packetdroppercentage = atoi(optarg); 170 tftp_log(LOG_INFO, 171 "Randomly dropping %d out of 100 packets", 172 packetdroppercentage); 173 break; 174 case 's': 175 chroot_dir = optarg; 176 break; 177 case 'u': 178 chuser = optarg; 179 break; 180 case 'U': 181 mask = strtol(optarg, NULL, 0); 182 break; 183 case 'w': 184 create_new = 1; 185 break; 186 case 'W': 187 create_new = 1; 188 increase_name = 1; 189 break; 190 default: 191 tftp_log(LOG_WARNING, 192 "ignoring unknown option -%c", ch); 193 } 194 } 195 if (optind < argc) { 196 struct dirlist *dirp; 197 198 /* Get list of directory prefixes. Skip relative pathnames. */ 199 for (dirp = dirs; optind < argc && dirp < &dirs[MAXDIRS]; 200 optind++) { 201 if (argv[optind][0] == '/') { 202 dirp->name = argv[optind]; 203 dirp->len = strlen(dirp->name); 204 dirp++; 205 } 206 } 207 } 208 else if (chroot_dir) { 209 dirs->name = "/"; 210 dirs->len = 1; 211 } 212 if (ipchroot > 0 && chroot_dir == NULL) { 213 tftp_log(LOG_ERR, "-c requires -s"); 214 exit(1); 215 } 216 217 umask(mask); 218 219 { 220 int on = 1; 221 if (ioctl(0, FIONBIO, &on) < 0) { 222 tftp_log(LOG_ERR, "ioctl(FIONBIO): %s", strerror(errno)); 223 exit(1); 224 } 225 } 226 227 /* Find out who we are talking to and what we are going to do */ 228 peerlen = sizeof(peer_sock); 229 n = recvfrom(0, recvbuffer, MAXPKTSIZE, 0, 230 (struct sockaddr *)&peer_sock, &peerlen); 231 if (n < 0) { 232 tftp_log(LOG_ERR, "recvfrom: %s", strerror(errno)); 233 exit(1); 234 } 235 getnameinfo((struct sockaddr *)&peer_sock, peer_sock.ss_len, 236 peername, sizeof(peername), NULL, 0, NI_NUMERICHOST); 237 238 /* 239 * Now that we have read the message out of the UDP 240 * socket, we fork and exit. Thus, inetd will go back 241 * to listening to the tftp port, and the next request 242 * to come in will start up a new instance of tftpd. 243 * 244 * We do this so that inetd can run tftpd in "wait" mode. 245 * The problem with tftpd running in "nowait" mode is that 246 * inetd may get one or more successful "selects" on the 247 * tftp port before we do our receive, so more than one 248 * instance of tftpd may be started up. Worse, if tftpd 249 * break before doing the above "recvfrom", inetd would 250 * spawn endless instances, clogging the system. 251 */ 252 { 253 int i, pid; 254 255 for (i = 1; i < 20; i++) { 256 pid = fork(); 257 if (pid < 0) { 258 sleep(i); 259 /* 260 * flush out to most recently sent request. 261 * 262 * This may drop some request, but those 263 * will be resent by the clients when 264 * they timeout. The positive effect of 265 * this flush is to (try to) prevent more 266 * than one tftpd being started up to service 267 * a single request from a single client. 268 */ 269 peerlen = sizeof peer_sock; 270 i = recvfrom(0, recvbuffer, MAXPKTSIZE, 0, 271 (struct sockaddr *)&peer_sock, &peerlen); 272 if (i > 0) { 273 n = i; 274 } 275 } else { 276 break; 277 } 278 } 279 if (pid < 0) { 280 tftp_log(LOG_ERR, "fork: %s", strerror(errno)); 281 exit(1); 282 } else if (pid != 0) { 283 exit(0); 284 } 285 } 286 287 /* 288 * See if the client is allowed to talk to me. 289 * (This needs to be done before the chroot()) 290 */ 291 { 292 struct request_info req; 293 294 request_init(&req, RQ_CLIENT_ADDR, peername, 0); 295 request_set(&req, RQ_DAEMON, "tftpd", 0); 296 297 if (hosts_access(&req) == 0) { 298 if (debug&DEBUG_ACCESS) 299 tftp_log(LOG_WARNING, 300 "Access denied by 'tftpd' entry " 301 "in /etc/hosts.allow"); 302 303 /* 304 * Full access might be disabled, but maybe the 305 * client is allowed to do read-only access. 306 */ 307 request_set(&req, RQ_DAEMON, "tftpd-ro", 0); 308 allow_ro = hosts_access(&req); 309 310 request_set(&req, RQ_DAEMON, "tftpd-wo", 0); 311 allow_wo = hosts_access(&req); 312 313 if (allow_ro == 0 && allow_wo == 0) { 314 tftp_log(LOG_WARNING, 315 "Unauthorized access from %s", peername); 316 exit(1); 317 } 318 319 if (debug&DEBUG_ACCESS) { 320 if (allow_ro) 321 tftp_log(LOG_WARNING, 322 "But allowed readonly access " 323 "via 'tftpd-ro' entry"); 324 if (allow_wo) 325 tftp_log(LOG_WARNING, 326 "But allowed writeonly access " 327 "via 'tftpd-wo' entry"); 328 } 329 } else 330 if (debug&DEBUG_ACCESS) 331 tftp_log(LOG_WARNING, 332 "Full access allowed" 333 "in /etc/hosts.allow"); 334 } 335 336 /* 337 * Since we exit here, we should do that only after the above 338 * recvfrom to keep inetd from constantly forking should there 339 * be a problem. See the above comment about system clogging. 340 */ 341 if (chroot_dir) { 342 if (ipchroot > 0) { 343 char *tempchroot; 344 struct stat sb; 345 int statret; 346 struct sockaddr_storage ss; 347 char hbuf[NI_MAXHOST]; 348 349 statret = -1; 350 memcpy(&ss, &peer_sock, peer_sock.ss_len); 351 unmappedaddr((struct sockaddr_in6 *)&ss); 352 getnameinfo((struct sockaddr *)&ss, ss.ss_len, 353 hbuf, sizeof(hbuf), NULL, 0, 354 NI_NUMERICHOST); 355 asprintf(&tempchroot, "%s/%s", chroot_dir, hbuf); 356 if (ipchroot == 2) 357 statret = stat(tempchroot, &sb); 358 if (ipchroot == 1 || 359 (statret == 0 && (sb.st_mode & S_IFDIR))) 360 chroot_dir = tempchroot; 361 } 362 /* Must get this before chroot because /etc might go away */ 363 if ((nobody = getpwnam(chuser)) == NULL) { 364 tftp_log(LOG_ERR, "%s: no such user", chuser); 365 exit(1); 366 } 367 if (chroot(chroot_dir)) { 368 tftp_log(LOG_ERR, "chroot: %s: %s", 369 chroot_dir, strerror(errno)); 370 exit(1); 371 } 372 chdir("/"); 373 setgroups(1, &nobody->pw_gid); 374 if (setuid(nobody->pw_uid) != 0) { 375 tftp_log(LOG_ERR, "setuid failed"); 376 exit(1); 377 } 378 } 379 380 len = sizeof(me_sock); 381 if (getsockname(0, (struct sockaddr *)&me_sock, &len) == 0) { 382 switch (me_sock.ss_family) { 383 case AF_INET: 384 ((struct sockaddr_in *)&me_sock)->sin_port = 0; 385 break; 386 case AF_INET6: 387 ((struct sockaddr_in6 *)&me_sock)->sin6_port = 0; 388 break; 389 default: 390 /* unsupported */ 391 break; 392 } 393 } else { 394 memset(&me_sock, 0, sizeof(me_sock)); 395 me_sock.ss_family = peer_sock.ss_family; 396 me_sock.ss_len = peer_sock.ss_len; 397 } 398 close(0); 399 close(1); 400 peer = socket(peer_sock.ss_family, SOCK_DGRAM, 0); 401 if (peer < 0) { 402 tftp_log(LOG_ERR, "socket: %s", strerror(errno)); 403 exit(1); 404 } 405 if (bind(peer, (struct sockaddr *)&me_sock, me_sock.ss_len) < 0) { 406 tftp_log(LOG_ERR, "bind: %s", strerror(errno)); 407 exit(1); 408 } 409 410 tp = (struct tftphdr *)recvbuffer; 411 tp->th_opcode = ntohs(tp->th_opcode); 412 if (tp->th_opcode == RRQ) { 413 if (allow_ro) 414 tftp_rrq(peer, tp->th_stuff, n - 1); 415 else { 416 tftp_log(LOG_WARNING, 417 "%s read access denied", peername); 418 exit(1); 419 } 420 } 421 if (tp->th_opcode == WRQ) { 422 if (allow_wo) 423 tftp_wrq(peer, tp->th_stuff, n - 1); 424 else { 425 tftp_log(LOG_WARNING, 426 "%s write access denied", peername); 427 exit(1); 428 } 429 } 430 exit(1); 431} 432 433static void 434reduce_path(char *fn) 435{ 436 char *slash, *ptr; 437 438 /* Reduce all "/+./" to "/" (just in case we've got "/./../" later */ 439 while ((slash = strstr(fn, "/./")) != NULL) { 440 for (ptr = slash; ptr > fn && ptr[-1] == '/'; ptr--) 441 ; 442 slash += 2; 443 while (*slash) 444 *++ptr = *++slash; 445 } 446 447 /* Now reduce all "/something/+../" to "/" */ 448 while ((slash = strstr(fn, "/../")) != NULL) { 449 if (slash == fn) 450 break; 451 for (ptr = slash; ptr > fn && ptr[-1] == '/'; ptr--) 452 ; 453 for (ptr--; ptr >= fn; ptr--) 454 if (*ptr == '/') 455 break; 456 if (ptr < fn) 457 break; 458 slash += 3; 459 while (*slash) 460 *++ptr = *++slash; 461 } 462} 463 464static char * 465parse_header(int peer, char *recvbuffer, ssize_t size, 466 char **filename, char **mode) 467{ 468 char *cp; 469 int i; 470 struct formats *pf; 471 472 *mode = NULL; 473 cp = recvbuffer; 474 475 i = get_field(peer, recvbuffer, size); 476 if (i >= PATH_MAX) { 477 tftp_log(LOG_ERR, "Bad option - filename too long"); 478 send_error(peer, EBADOP); 479 exit(1); 480 } 481 *filename = recvbuffer; 482 tftp_log(LOG_INFO, "Filename: '%s'", *filename); 483 cp += i; 484 485 i = get_field(peer, cp, size); 486 *mode = cp; 487 cp += i; 488 489 /* Find the file transfer mode */ 490 for (cp = *mode; *cp; cp++) 491 if (isupper(*cp)) 492 *cp = tolower(*cp); 493 for (pf = formats; pf->f_mode; pf++) 494 if (strcmp(pf->f_mode, *mode) == 0) 495 break; 496 if (pf->f_mode == NULL) { 497 tftp_log(LOG_ERR, 498 "Bad option - Unknown transfer mode (%s)", *mode); 499 send_error(peer, EBADOP); 500 exit(1); 501 } 502 tftp_log(LOG_INFO, "Mode: '%s'", *mode); 503 504 return (cp + 1); 505} 506 507/* 508 * WRQ - receive a file from the client 509 */ 510void 511tftp_wrq(int peer, char *recvbuffer, ssize_t size) 512{ 513 char *cp; 514 int has_options = 0, ecode; 515 char *filename, *mode; 516 char fnbuf[PATH_MAX]; 517 518 cp = parse_header(peer, recvbuffer, size, &filename, &mode); 519 size -= (cp - recvbuffer) + 1; 520 521 strcpy(fnbuf, filename); 522 reduce_path(fnbuf); 523 filename = fnbuf; 524 525 if (size > 0) { 526 if (options_rfc_enabled) 527 has_options = !parse_options(peer, cp, size); 528 else 529 tftp_log(LOG_INFO, "Options found but not enabled"); 530 } 531 532 ecode = validate_access(peer, &filename, WRQ); 533 if (ecode == 0) { 534 if (has_options) 535 send_oack(peer); 536 else 537 send_ack(peer, 0); 538 } 539 if (logging) { 540 tftp_log(LOG_INFO, "%s: write request for %s: %s", peername, 541 filename, errtomsg(ecode)); 542 } 543 544 tftp_recvfile(peer, mode); 545 exit(0); 546} 547 548/* 549 * RRQ - send a file to the client 550 */ 551void 552tftp_rrq(int peer, char *recvbuffer, ssize_t size) 553{ 554 char *cp; 555 int has_options = 0, ecode; 556 char *filename, *mode; 557 char fnbuf[PATH_MAX]; 558 559 cp = parse_header(peer, recvbuffer, size, &filename, &mode); 560 size -= (cp - recvbuffer) + 1; 561 562 strcpy(fnbuf, filename); 563 reduce_path(fnbuf); 564 filename = fnbuf; 565 566 if (size > 0) { 567 if (options_rfc_enabled) 568 has_options = !parse_options(peer, cp, size); 569 else 570 tftp_log(LOG_INFO, "Options found but not enabled"); 571 } 572 573 ecode = validate_access(peer, &filename, RRQ); 574 if (ecode == 0) { 575 if (has_options) { 576 int n; 577 char lrecvbuffer[MAXPKTSIZE]; 578 struct tftphdr *rp = (struct tftphdr *)lrecvbuffer; 579 580 send_oack(peer); 581 n = receive_packet(peer, lrecvbuffer, MAXPKTSIZE, 582 NULL, timeoutpacket); 583 if (n < 0) { 584 if (debug&DEBUG_SIMPLE) 585 tftp_log(LOG_DEBUG, "Aborting: %s", 586 rp_strerror(n)); 587 return; 588 } 589 if (rp->th_opcode != ACK) { 590 if (debug&DEBUG_SIMPLE) 591 tftp_log(LOG_DEBUG, 592 "Expected ACK, got %s on OACK", 593 packettype(rp->th_opcode)); 594 return; 595 } 596 } 597 } 598 599 if (logging) 600 tftp_log(LOG_INFO, "%s: read request for %s: %s", peername, 601 filename, errtomsg(ecode)); 602 603 if (ecode) { 604 /* 605 * Avoid storms of naks to a RRQ broadcast for a relative 606 * bootfile pathname from a diskless Sun. 607 */ 608 if (suppress_naks && *filename != '/' && ecode == ENOTFOUND) 609 exit(0); 610 send_error(peer, ecode); 611 exit(1); 612 } 613 tftp_xmitfile(peer, mode); 614} 615 616/* 617 * Find the next value for YYYYMMDD.nn when the file to be written should 618 * be unique. Due to the limitations of nn, we will fail if nn reaches 100. 619 * Besides, that is four updates per hour on a file, which is kind of 620 * execessive anyway. 621 */ 622static int 623find_next_name(char *filename, int *fd) 624{ 625 int i; 626 time_t tval; 627 size_t len; 628 struct tm lt; 629 char yyyymmdd[MAXPATHLEN]; 630 char newname[MAXPATHLEN]; 631 632 /* Create the YYYYMMDD part of the filename */ 633 time(&tval); 634 lt = *localtime(&tval); 635 len = strftime(yyyymmdd, sizeof(yyyymmdd), newfile_format, <); 636 if (len == 0) { 637 syslog(LOG_WARNING, 638 "Filename suffix too long (%d characters maximum)", 639 MAXPATHLEN); 640 return (EACCESS); 641 } 642 643 /* Make sure the new filename is not too long */ 644 if (strlen(filename) > MAXPATHLEN - len - 5) { 645 syslog(LOG_WARNING, 646 "Filename too long (%zd characters, %zd maximum)", 647 strlen(filename), MAXPATHLEN - len - 5); 648 return (EACCESS); 649 } 650 651 /* Find the first file which doesn't exist */ 652 for (i = 0; i < 100; i++) { 653 sprintf(newname, "%s.%s.%02d", filename, yyyymmdd, i); 654 *fd = open(newname, 655 O_WRONLY | O_CREAT | O_EXCL, 656 S_IRUSR | S_IWUSR | S_IRGRP | 657 S_IWGRP | S_IROTH | S_IWOTH); 658 if (*fd > 0) 659 return 0; 660 } 661 662 return (EEXIST); 663} 664 665/* 666 * Validate file access. Since we 667 * have no uid or gid, for now require 668 * file to exist and be publicly 669 * readable/writable. 670 * If we were invoked with arguments 671 * from inetd then the file must also be 672 * in one of the given directory prefixes. 673 * Note also, full path name must be 674 * given as we have no login directory. 675 */ 676int 677validate_access(int peer, char **filep, int mode) 678{ 679 struct stat stbuf; 680 int fd; 681 int error; 682 struct dirlist *dirp; 683 static char pathname[MAXPATHLEN]; 684 char *filename = *filep; 685 686 /* 687 * Prevent tricksters from getting around the directory restrictions 688 */ 689 if (strstr(filename, "/../")) 690 return (EACCESS); 691 692 if (*filename == '/') { 693 /* 694 * Allow the request if it's in one of the approved locations. 695 * Special case: check the null prefix ("/") by looking 696 * for length = 1 and relying on the arg. processing that 697 * it's a /. 698 */ 699 for (dirp = dirs; dirp->name != NULL; dirp++) { 700 if (dirp->len == 1 || 701 (!strncmp(filename, dirp->name, dirp->len) && 702 filename[dirp->len] == '/')) 703 break; 704 } 705 /* If directory list is empty, allow access to any file */ 706 if (dirp->name == NULL && dirp != dirs) 707 return (EACCESS); 708 if (stat(filename, &stbuf) < 0) 709 return (errno == ENOENT ? ENOTFOUND : EACCESS); 710 if ((stbuf.st_mode & S_IFMT) != S_IFREG) 711 return (ENOTFOUND); 712 if (mode == RRQ) { 713 if ((stbuf.st_mode & S_IROTH) == 0) 714 return (EACCESS); 715 } else { 716 if ((stbuf.st_mode & S_IWOTH) == 0) 717 return (EACCESS); 718 } 719 } else { 720 int err; 721 722 /* 723 * Relative file name: search the approved locations for it. 724 * Don't allow write requests that avoid directory 725 * restrictions. 726 */ 727 728 if (!strncmp(filename, "../", 3)) 729 return (EACCESS); 730 731 /* 732 * If the file exists in one of the directories and isn't 733 * readable, continue looking. However, change the error code 734 * to give an indication that the file exists. 735 */ 736 err = ENOTFOUND; 737 for (dirp = dirs; dirp->name != NULL; dirp++) { 738 snprintf(pathname, sizeof(pathname), "%s/%s", 739 dirp->name, filename); 740 if (stat(pathname, &stbuf) == 0 && 741 (stbuf.st_mode & S_IFMT) == S_IFREG) { 742 if ((stbuf.st_mode & S_IROTH) != 0) { 743 break; 744 } 745 err = EACCESS; 746 } 747 } 748 if (dirp->name != NULL) 749 *filep = filename = pathname; 750 else if (mode == RRQ) 751 return (err); 752 } 753 754 /* 755 * This option is handled here because it (might) require(s) the 756 * size of the file. 757 */ 758 option_tsize(peer, NULL, mode, &stbuf); 759 760 if (mode == RRQ) 761 fd = open(filename, O_RDONLY); 762 else { 763 if (create_new) { 764 if (increase_name) { 765 error = find_next_name(filename, &fd); 766 if (error > 0) 767 return (error + 100); 768 } else 769 fd = open(filename, 770 O_WRONLY | O_TRUNC | O_CREAT, 771 S_IRUSR | S_IWUSR | S_IRGRP | 772 S_IWGRP | S_IROTH | S_IWOTH ); 773 } else 774 fd = open(filename, O_WRONLY | O_TRUNC); 775 } 776 if (fd < 0) 777 return (errno + 100); 778 file = fdopen(fd, (mode == RRQ)? "r":"w"); 779 if (file == NULL) { 780 close(fd); 781 return (errno + 100); 782 } 783 return (0); 784} 785 786static void 787tftp_xmitfile(int peer, const char *mode) 788{ 789 uint16_t block; 790 time_t now; 791 struct tftp_stats ts; 792 793 now = time(NULL); 794 if (debug&DEBUG_SIMPLE) 795 tftp_log(LOG_DEBUG, "Transmitting file"); 796 797 read_init(0, file, mode); 798 block = 1; 799 tftp_send(peer, &block, &ts); 800 read_close(); 801 if (debug&DEBUG_SIMPLE)
| 69#include <stdio.h> 70#include <stdlib.h> 71#include <string.h> 72#include <syslog.h> 73#include <tcpd.h> 74#include <unistd.h> 75 76#include "tftp-file.h" 77#include "tftp-io.h" 78#include "tftp-utils.h" 79#include "tftp-transfer.h" 80#include "tftp-options.h" 81 82static void tftp_wrq(int peer, char *, ssize_t); 83static void tftp_rrq(int peer, char *, ssize_t); 84 85/* 86 * Null-terminated directory prefix list for absolute pathname requests and 87 * search list for relative pathname requests. 88 * 89 * MAXDIRS should be at least as large as the number of arguments that 90 * inetd allows (currently 20). 91 */ 92#define MAXDIRS 20 93static struct dirlist { 94 const char *name; 95 int len; 96} dirs[MAXDIRS+1]; 97static int suppress_naks; 98static int logging; 99static int ipchroot; 100static int create_new = 0; 101static const char *newfile_format = "%Y%m%d"; 102static int increase_name = 0; 103static mode_t mask = S_IWGRP | S_IWOTH; 104 105struct formats; 106static void tftp_recvfile(int peer, const char *mode); 107static void tftp_xmitfile(int peer, const char *mode); 108static int validate_access(int peer, char **, int); 109static char peername[NI_MAXHOST]; 110 111static FILE *file; 112 113static struct formats { 114 const char *f_mode; 115 int f_convert; 116} formats[] = { 117 { "netascii", 1 }, 118 { "octet", 0 }, 119 { NULL, 0 } 120}; 121 122int 123main(int argc, char *argv[]) 124{ 125 struct tftphdr *tp; 126 int peer; 127 socklen_t peerlen, len; 128 ssize_t n; 129 int ch; 130 char *chroot_dir = NULL; 131 struct passwd *nobody; 132 const char *chuser = "nobody"; 133 char recvbuffer[MAXPKTSIZE]; 134 int allow_ro = 1, allow_wo = 1; 135 136 tzset(); /* syslog in localtime */ 137 acting_as_client = 0; 138 139 tftp_openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP); 140 while ((ch = getopt(argc, argv, "cCd:F:lnoOp:s:u:U:wW")) != -1) { 141 switch (ch) { 142 case 'c': 143 ipchroot = 1; 144 break; 145 case 'C': 146 ipchroot = 2; 147 break; 148 case 'd': 149 if (atoi(optarg) != 0) 150 debug += atoi(optarg); 151 else 152 debug |= debug_finds(optarg); 153 break; 154 case 'F': 155 newfile_format = optarg; 156 break; 157 case 'l': 158 logging = 1; 159 break; 160 case 'n': 161 suppress_naks = 1; 162 break; 163 case 'o': 164 options_rfc_enabled = 0; 165 break; 166 case 'O': 167 options_extra_enabled = 0; 168 break; 169 case 'p': 170 packetdroppercentage = atoi(optarg); 171 tftp_log(LOG_INFO, 172 "Randomly dropping %d out of 100 packets", 173 packetdroppercentage); 174 break; 175 case 's': 176 chroot_dir = optarg; 177 break; 178 case 'u': 179 chuser = optarg; 180 break; 181 case 'U': 182 mask = strtol(optarg, NULL, 0); 183 break; 184 case 'w': 185 create_new = 1; 186 break; 187 case 'W': 188 create_new = 1; 189 increase_name = 1; 190 break; 191 default: 192 tftp_log(LOG_WARNING, 193 "ignoring unknown option -%c", ch); 194 } 195 } 196 if (optind < argc) { 197 struct dirlist *dirp; 198 199 /* Get list of directory prefixes. Skip relative pathnames. */ 200 for (dirp = dirs; optind < argc && dirp < &dirs[MAXDIRS]; 201 optind++) { 202 if (argv[optind][0] == '/') { 203 dirp->name = argv[optind]; 204 dirp->len = strlen(dirp->name); 205 dirp++; 206 } 207 } 208 } 209 else if (chroot_dir) { 210 dirs->name = "/"; 211 dirs->len = 1; 212 } 213 if (ipchroot > 0 && chroot_dir == NULL) { 214 tftp_log(LOG_ERR, "-c requires -s"); 215 exit(1); 216 } 217 218 umask(mask); 219 220 { 221 int on = 1; 222 if (ioctl(0, FIONBIO, &on) < 0) { 223 tftp_log(LOG_ERR, "ioctl(FIONBIO): %s", strerror(errno)); 224 exit(1); 225 } 226 } 227 228 /* Find out who we are talking to and what we are going to do */ 229 peerlen = sizeof(peer_sock); 230 n = recvfrom(0, recvbuffer, MAXPKTSIZE, 0, 231 (struct sockaddr *)&peer_sock, &peerlen); 232 if (n < 0) { 233 tftp_log(LOG_ERR, "recvfrom: %s", strerror(errno)); 234 exit(1); 235 } 236 getnameinfo((struct sockaddr *)&peer_sock, peer_sock.ss_len, 237 peername, sizeof(peername), NULL, 0, NI_NUMERICHOST); 238 239 /* 240 * Now that we have read the message out of the UDP 241 * socket, we fork and exit. Thus, inetd will go back 242 * to listening to the tftp port, and the next request 243 * to come in will start up a new instance of tftpd. 244 * 245 * We do this so that inetd can run tftpd in "wait" mode. 246 * The problem with tftpd running in "nowait" mode is that 247 * inetd may get one or more successful "selects" on the 248 * tftp port before we do our receive, so more than one 249 * instance of tftpd may be started up. Worse, if tftpd 250 * break before doing the above "recvfrom", inetd would 251 * spawn endless instances, clogging the system. 252 */ 253 { 254 int i, pid; 255 256 for (i = 1; i < 20; i++) { 257 pid = fork(); 258 if (pid < 0) { 259 sleep(i); 260 /* 261 * flush out to most recently sent request. 262 * 263 * This may drop some request, but those 264 * will be resent by the clients when 265 * they timeout. The positive effect of 266 * this flush is to (try to) prevent more 267 * than one tftpd being started up to service 268 * a single request from a single client. 269 */ 270 peerlen = sizeof peer_sock; 271 i = recvfrom(0, recvbuffer, MAXPKTSIZE, 0, 272 (struct sockaddr *)&peer_sock, &peerlen); 273 if (i > 0) { 274 n = i; 275 } 276 } else { 277 break; 278 } 279 } 280 if (pid < 0) { 281 tftp_log(LOG_ERR, "fork: %s", strerror(errno)); 282 exit(1); 283 } else if (pid != 0) { 284 exit(0); 285 } 286 } 287 288 /* 289 * See if the client is allowed to talk to me. 290 * (This needs to be done before the chroot()) 291 */ 292 { 293 struct request_info req; 294 295 request_init(&req, RQ_CLIENT_ADDR, peername, 0); 296 request_set(&req, RQ_DAEMON, "tftpd", 0); 297 298 if (hosts_access(&req) == 0) { 299 if (debug&DEBUG_ACCESS) 300 tftp_log(LOG_WARNING, 301 "Access denied by 'tftpd' entry " 302 "in /etc/hosts.allow"); 303 304 /* 305 * Full access might be disabled, but maybe the 306 * client is allowed to do read-only access. 307 */ 308 request_set(&req, RQ_DAEMON, "tftpd-ro", 0); 309 allow_ro = hosts_access(&req); 310 311 request_set(&req, RQ_DAEMON, "tftpd-wo", 0); 312 allow_wo = hosts_access(&req); 313 314 if (allow_ro == 0 && allow_wo == 0) { 315 tftp_log(LOG_WARNING, 316 "Unauthorized access from %s", peername); 317 exit(1); 318 } 319 320 if (debug&DEBUG_ACCESS) { 321 if (allow_ro) 322 tftp_log(LOG_WARNING, 323 "But allowed readonly access " 324 "via 'tftpd-ro' entry"); 325 if (allow_wo) 326 tftp_log(LOG_WARNING, 327 "But allowed writeonly access " 328 "via 'tftpd-wo' entry"); 329 } 330 } else 331 if (debug&DEBUG_ACCESS) 332 tftp_log(LOG_WARNING, 333 "Full access allowed" 334 "in /etc/hosts.allow"); 335 } 336 337 /* 338 * Since we exit here, we should do that only after the above 339 * recvfrom to keep inetd from constantly forking should there 340 * be a problem. See the above comment about system clogging. 341 */ 342 if (chroot_dir) { 343 if (ipchroot > 0) { 344 char *tempchroot; 345 struct stat sb; 346 int statret; 347 struct sockaddr_storage ss; 348 char hbuf[NI_MAXHOST]; 349 350 statret = -1; 351 memcpy(&ss, &peer_sock, peer_sock.ss_len); 352 unmappedaddr((struct sockaddr_in6 *)&ss); 353 getnameinfo((struct sockaddr *)&ss, ss.ss_len, 354 hbuf, sizeof(hbuf), NULL, 0, 355 NI_NUMERICHOST); 356 asprintf(&tempchroot, "%s/%s", chroot_dir, hbuf); 357 if (ipchroot == 2) 358 statret = stat(tempchroot, &sb); 359 if (ipchroot == 1 || 360 (statret == 0 && (sb.st_mode & S_IFDIR))) 361 chroot_dir = tempchroot; 362 } 363 /* Must get this before chroot because /etc might go away */ 364 if ((nobody = getpwnam(chuser)) == NULL) { 365 tftp_log(LOG_ERR, "%s: no such user", chuser); 366 exit(1); 367 } 368 if (chroot(chroot_dir)) { 369 tftp_log(LOG_ERR, "chroot: %s: %s", 370 chroot_dir, strerror(errno)); 371 exit(1); 372 } 373 chdir("/"); 374 setgroups(1, &nobody->pw_gid); 375 if (setuid(nobody->pw_uid) != 0) { 376 tftp_log(LOG_ERR, "setuid failed"); 377 exit(1); 378 } 379 } 380 381 len = sizeof(me_sock); 382 if (getsockname(0, (struct sockaddr *)&me_sock, &len) == 0) { 383 switch (me_sock.ss_family) { 384 case AF_INET: 385 ((struct sockaddr_in *)&me_sock)->sin_port = 0; 386 break; 387 case AF_INET6: 388 ((struct sockaddr_in6 *)&me_sock)->sin6_port = 0; 389 break; 390 default: 391 /* unsupported */ 392 break; 393 } 394 } else { 395 memset(&me_sock, 0, sizeof(me_sock)); 396 me_sock.ss_family = peer_sock.ss_family; 397 me_sock.ss_len = peer_sock.ss_len; 398 } 399 close(0); 400 close(1); 401 peer = socket(peer_sock.ss_family, SOCK_DGRAM, 0); 402 if (peer < 0) { 403 tftp_log(LOG_ERR, "socket: %s", strerror(errno)); 404 exit(1); 405 } 406 if (bind(peer, (struct sockaddr *)&me_sock, me_sock.ss_len) < 0) { 407 tftp_log(LOG_ERR, "bind: %s", strerror(errno)); 408 exit(1); 409 } 410 411 tp = (struct tftphdr *)recvbuffer; 412 tp->th_opcode = ntohs(tp->th_opcode); 413 if (tp->th_opcode == RRQ) { 414 if (allow_ro) 415 tftp_rrq(peer, tp->th_stuff, n - 1); 416 else { 417 tftp_log(LOG_WARNING, 418 "%s read access denied", peername); 419 exit(1); 420 } 421 } 422 if (tp->th_opcode == WRQ) { 423 if (allow_wo) 424 tftp_wrq(peer, tp->th_stuff, n - 1); 425 else { 426 tftp_log(LOG_WARNING, 427 "%s write access denied", peername); 428 exit(1); 429 } 430 } 431 exit(1); 432} 433 434static void 435reduce_path(char *fn) 436{ 437 char *slash, *ptr; 438 439 /* Reduce all "/+./" to "/" (just in case we've got "/./../" later */ 440 while ((slash = strstr(fn, "/./")) != NULL) { 441 for (ptr = slash; ptr > fn && ptr[-1] == '/'; ptr--) 442 ; 443 slash += 2; 444 while (*slash) 445 *++ptr = *++slash; 446 } 447 448 /* Now reduce all "/something/+../" to "/" */ 449 while ((slash = strstr(fn, "/../")) != NULL) { 450 if (slash == fn) 451 break; 452 for (ptr = slash; ptr > fn && ptr[-1] == '/'; ptr--) 453 ; 454 for (ptr--; ptr >= fn; ptr--) 455 if (*ptr == '/') 456 break; 457 if (ptr < fn) 458 break; 459 slash += 3; 460 while (*slash) 461 *++ptr = *++slash; 462 } 463} 464 465static char * 466parse_header(int peer, char *recvbuffer, ssize_t size, 467 char **filename, char **mode) 468{ 469 char *cp; 470 int i; 471 struct formats *pf; 472 473 *mode = NULL; 474 cp = recvbuffer; 475 476 i = get_field(peer, recvbuffer, size); 477 if (i >= PATH_MAX) { 478 tftp_log(LOG_ERR, "Bad option - filename too long"); 479 send_error(peer, EBADOP); 480 exit(1); 481 } 482 *filename = recvbuffer; 483 tftp_log(LOG_INFO, "Filename: '%s'", *filename); 484 cp += i; 485 486 i = get_field(peer, cp, size); 487 *mode = cp; 488 cp += i; 489 490 /* Find the file transfer mode */ 491 for (cp = *mode; *cp; cp++) 492 if (isupper(*cp)) 493 *cp = tolower(*cp); 494 for (pf = formats; pf->f_mode; pf++) 495 if (strcmp(pf->f_mode, *mode) == 0) 496 break; 497 if (pf->f_mode == NULL) { 498 tftp_log(LOG_ERR, 499 "Bad option - Unknown transfer mode (%s)", *mode); 500 send_error(peer, EBADOP); 501 exit(1); 502 } 503 tftp_log(LOG_INFO, "Mode: '%s'", *mode); 504 505 return (cp + 1); 506} 507 508/* 509 * WRQ - receive a file from the client 510 */ 511void 512tftp_wrq(int peer, char *recvbuffer, ssize_t size) 513{ 514 char *cp; 515 int has_options = 0, ecode; 516 char *filename, *mode; 517 char fnbuf[PATH_MAX]; 518 519 cp = parse_header(peer, recvbuffer, size, &filename, &mode); 520 size -= (cp - recvbuffer) + 1; 521 522 strcpy(fnbuf, filename); 523 reduce_path(fnbuf); 524 filename = fnbuf; 525 526 if (size > 0) { 527 if (options_rfc_enabled) 528 has_options = !parse_options(peer, cp, size); 529 else 530 tftp_log(LOG_INFO, "Options found but not enabled"); 531 } 532 533 ecode = validate_access(peer, &filename, WRQ); 534 if (ecode == 0) { 535 if (has_options) 536 send_oack(peer); 537 else 538 send_ack(peer, 0); 539 } 540 if (logging) { 541 tftp_log(LOG_INFO, "%s: write request for %s: %s", peername, 542 filename, errtomsg(ecode)); 543 } 544 545 tftp_recvfile(peer, mode); 546 exit(0); 547} 548 549/* 550 * RRQ - send a file to the client 551 */ 552void 553tftp_rrq(int peer, char *recvbuffer, ssize_t size) 554{ 555 char *cp; 556 int has_options = 0, ecode; 557 char *filename, *mode; 558 char fnbuf[PATH_MAX]; 559 560 cp = parse_header(peer, recvbuffer, size, &filename, &mode); 561 size -= (cp - recvbuffer) + 1; 562 563 strcpy(fnbuf, filename); 564 reduce_path(fnbuf); 565 filename = fnbuf; 566 567 if (size > 0) { 568 if (options_rfc_enabled) 569 has_options = !parse_options(peer, cp, size); 570 else 571 tftp_log(LOG_INFO, "Options found but not enabled"); 572 } 573 574 ecode = validate_access(peer, &filename, RRQ); 575 if (ecode == 0) { 576 if (has_options) { 577 int n; 578 char lrecvbuffer[MAXPKTSIZE]; 579 struct tftphdr *rp = (struct tftphdr *)lrecvbuffer; 580 581 send_oack(peer); 582 n = receive_packet(peer, lrecvbuffer, MAXPKTSIZE, 583 NULL, timeoutpacket); 584 if (n < 0) { 585 if (debug&DEBUG_SIMPLE) 586 tftp_log(LOG_DEBUG, "Aborting: %s", 587 rp_strerror(n)); 588 return; 589 } 590 if (rp->th_opcode != ACK) { 591 if (debug&DEBUG_SIMPLE) 592 tftp_log(LOG_DEBUG, 593 "Expected ACK, got %s on OACK", 594 packettype(rp->th_opcode)); 595 return; 596 } 597 } 598 } 599 600 if (logging) 601 tftp_log(LOG_INFO, "%s: read request for %s: %s", peername, 602 filename, errtomsg(ecode)); 603 604 if (ecode) { 605 /* 606 * Avoid storms of naks to a RRQ broadcast for a relative 607 * bootfile pathname from a diskless Sun. 608 */ 609 if (suppress_naks && *filename != '/' && ecode == ENOTFOUND) 610 exit(0); 611 send_error(peer, ecode); 612 exit(1); 613 } 614 tftp_xmitfile(peer, mode); 615} 616 617/* 618 * Find the next value for YYYYMMDD.nn when the file to be written should 619 * be unique. Due to the limitations of nn, we will fail if nn reaches 100. 620 * Besides, that is four updates per hour on a file, which is kind of 621 * execessive anyway. 622 */ 623static int 624find_next_name(char *filename, int *fd) 625{ 626 int i; 627 time_t tval; 628 size_t len; 629 struct tm lt; 630 char yyyymmdd[MAXPATHLEN]; 631 char newname[MAXPATHLEN]; 632 633 /* Create the YYYYMMDD part of the filename */ 634 time(&tval); 635 lt = *localtime(&tval); 636 len = strftime(yyyymmdd, sizeof(yyyymmdd), newfile_format, <); 637 if (len == 0) { 638 syslog(LOG_WARNING, 639 "Filename suffix too long (%d characters maximum)", 640 MAXPATHLEN); 641 return (EACCESS); 642 } 643 644 /* Make sure the new filename is not too long */ 645 if (strlen(filename) > MAXPATHLEN - len - 5) { 646 syslog(LOG_WARNING, 647 "Filename too long (%zd characters, %zd maximum)", 648 strlen(filename), MAXPATHLEN - len - 5); 649 return (EACCESS); 650 } 651 652 /* Find the first file which doesn't exist */ 653 for (i = 0; i < 100; i++) { 654 sprintf(newname, "%s.%s.%02d", filename, yyyymmdd, i); 655 *fd = open(newname, 656 O_WRONLY | O_CREAT | O_EXCL, 657 S_IRUSR | S_IWUSR | S_IRGRP | 658 S_IWGRP | S_IROTH | S_IWOTH); 659 if (*fd > 0) 660 return 0; 661 } 662 663 return (EEXIST); 664} 665 666/* 667 * Validate file access. Since we 668 * have no uid or gid, for now require 669 * file to exist and be publicly 670 * readable/writable. 671 * If we were invoked with arguments 672 * from inetd then the file must also be 673 * in one of the given directory prefixes. 674 * Note also, full path name must be 675 * given as we have no login directory. 676 */ 677int 678validate_access(int peer, char **filep, int mode) 679{ 680 struct stat stbuf; 681 int fd; 682 int error; 683 struct dirlist *dirp; 684 static char pathname[MAXPATHLEN]; 685 char *filename = *filep; 686 687 /* 688 * Prevent tricksters from getting around the directory restrictions 689 */ 690 if (strstr(filename, "/../")) 691 return (EACCESS); 692 693 if (*filename == '/') { 694 /* 695 * Allow the request if it's in one of the approved locations. 696 * Special case: check the null prefix ("/") by looking 697 * for length = 1 and relying on the arg. processing that 698 * it's a /. 699 */ 700 for (dirp = dirs; dirp->name != NULL; dirp++) { 701 if (dirp->len == 1 || 702 (!strncmp(filename, dirp->name, dirp->len) && 703 filename[dirp->len] == '/')) 704 break; 705 } 706 /* If directory list is empty, allow access to any file */ 707 if (dirp->name == NULL && dirp != dirs) 708 return (EACCESS); 709 if (stat(filename, &stbuf) < 0) 710 return (errno == ENOENT ? ENOTFOUND : EACCESS); 711 if ((stbuf.st_mode & S_IFMT) != S_IFREG) 712 return (ENOTFOUND); 713 if (mode == RRQ) { 714 if ((stbuf.st_mode & S_IROTH) == 0) 715 return (EACCESS); 716 } else { 717 if ((stbuf.st_mode & S_IWOTH) == 0) 718 return (EACCESS); 719 } 720 } else { 721 int err; 722 723 /* 724 * Relative file name: search the approved locations for it. 725 * Don't allow write requests that avoid directory 726 * restrictions. 727 */ 728 729 if (!strncmp(filename, "../", 3)) 730 return (EACCESS); 731 732 /* 733 * If the file exists in one of the directories and isn't 734 * readable, continue looking. However, change the error code 735 * to give an indication that the file exists. 736 */ 737 err = ENOTFOUND; 738 for (dirp = dirs; dirp->name != NULL; dirp++) { 739 snprintf(pathname, sizeof(pathname), "%s/%s", 740 dirp->name, filename); 741 if (stat(pathname, &stbuf) == 0 && 742 (stbuf.st_mode & S_IFMT) == S_IFREG) { 743 if ((stbuf.st_mode & S_IROTH) != 0) { 744 break; 745 } 746 err = EACCESS; 747 } 748 } 749 if (dirp->name != NULL) 750 *filep = filename = pathname; 751 else if (mode == RRQ) 752 return (err); 753 } 754 755 /* 756 * This option is handled here because it (might) require(s) the 757 * size of the file. 758 */ 759 option_tsize(peer, NULL, mode, &stbuf); 760 761 if (mode == RRQ) 762 fd = open(filename, O_RDONLY); 763 else { 764 if (create_new) { 765 if (increase_name) { 766 error = find_next_name(filename, &fd); 767 if (error > 0) 768 return (error + 100); 769 } else 770 fd = open(filename, 771 O_WRONLY | O_TRUNC | O_CREAT, 772 S_IRUSR | S_IWUSR | S_IRGRP | 773 S_IWGRP | S_IROTH | S_IWOTH ); 774 } else 775 fd = open(filename, O_WRONLY | O_TRUNC); 776 } 777 if (fd < 0) 778 return (errno + 100); 779 file = fdopen(fd, (mode == RRQ)? "r":"w"); 780 if (file == NULL) { 781 close(fd); 782 return (errno + 100); 783 } 784 return (0); 785} 786 787static void 788tftp_xmitfile(int peer, const char *mode) 789{ 790 uint16_t block; 791 time_t now; 792 struct tftp_stats ts; 793 794 now = time(NULL); 795 if (debug&DEBUG_SIMPLE) 796 tftp_log(LOG_DEBUG, "Transmitting file"); 797 798 read_init(0, file, mode); 799 block = 1; 800 tftp_send(peer, &block, &ts); 801 read_close(); 802 if (debug&DEBUG_SIMPLE)
|