1 /* $OpenBSD: tftpd.c,v 1.19 2014/04/21 04:02:52 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 2012 David Gwynne <dlg@uq.edu.au> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Copyright (c) 1983 Regents of the University of California. 21 * All rights reserved. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the above copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. Neither the name of the University nor the names of its contributors 32 * may be used to endorse or promote products derived from this software 33 * without specific prior written permission. 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 36 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 38 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 39 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 40 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 41 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 42 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 43 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 44 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 45 * SUCH DAMAGE. 46 */ 47 48 /* 49 * Trivial file transfer protocol server. 50 * 51 * This version is based on src/libexec/tftpd which includes many 52 * modifications by Jim Guyton <guyton@rand-unix>. 53 * 54 * It was restructured to be a persistent event driven daemon 55 * supporting concurrent connections by dlg for use at the University 56 * of Queensland in the Faculty of Engineering Architecture and 57 * Information Technology. 58 */ 59 60 #include <sys/ioctl.h> 61 #include <sys/param.h> 62 #include <sys/types.h> 63 #include <sys/queue.h> 64 #include <sys/socket.h> 65 #include <sys/stat.h> 66 #include <sys/uio.h> 67 #include <sys/un.h> 68 69 #include <netinet/in.h> 70 #include <arpa/inet.h> 71 #include <arpa/tftp.h> 72 #include <netdb.h> 73 74 #include <err.h> 75 #include <ctype.h> 76 #include <errno.h> 77 #include <event.h> 78 #include <fcntl.h> 79 #include <poll.h> 80 #include <pwd.h> 81 #include <stdio.h> 82 #include <stdlib.h> 83 #include <string.h> 84 #include <stdarg.h> 85 #include <syslog.h> 86 #include <unistd.h> 87 #include <vis.h> 88 89 #define TIMEOUT 5 /* packet rexmt timeout */ 90 #define TIMEOUT_MIN 1 /* minimal packet rexmt timeout */ 91 #define TIMEOUT_MAX 255 /* maximal packet rexmt timeout */ 92 93 #define RETRIES 5 94 95 struct formats; 96 97 enum opt_enum { 98 OPT_TSIZE = 0, 99 OPT_TIMEOUT, 100 OPT_BLKSIZE, 101 NOPT 102 }; 103 104 static char *opt_names[] = { 105 "tsize", 106 "timeout", 107 "blksize" 108 }; 109 110 struct opt_client { 111 char *o_request; 112 long long o_reply; 113 }; 114 115 116 struct tftp_server { 117 struct event ev; 118 TAILQ_ENTRY(tftp_server) entry; 119 int s; 120 }; 121 122 TAILQ_HEAD(, tftp_server) tftp_servers; 123 124 struct tftp_client { 125 char buf[SEGSIZE_MAX + 4]; 126 struct event sev; 127 struct sockaddr_storage ss; 128 129 struct timeval tv; 130 131 TAILQ_ENTRY(tftp_client) entry; 132 133 struct opt_client *options; 134 135 size_t segment_size; 136 size_t packet_size; 137 size_t buflen; 138 139 FILE *file; 140 int (*fgetc)(struct tftp_client *); 141 int (*fputc)(struct tftp_client *, int); 142 143 u_int retries; 144 u_int16_t block; 145 146 int opcode; 147 int newline; 148 149 int sock; 150 }; 151 152 __dead void usage(void); 153 const char *getip(void *); 154 155 void rewrite_connect(const char *); 156 void rewrite_events(void); 157 void rewrite_map(struct tftp_client *, const char *); 158 void rewrite_req(int, short, void *); 159 void rewrite_res(int, short, void *); 160 161 int tftpd_listen(const char *, const char *, int); 162 void tftpd_events(void); 163 void tftpd_recv(int, short, void *); 164 int retry(struct tftp_client *); 165 int tftp_flush(struct tftp_client *); 166 void tftp_end(struct tftp_client *); 167 168 void tftp(struct tftp_client *, struct tftphdr *, size_t); 169 void tftp_open(struct tftp_client *, const char *); 170 void nak(struct tftp_client *, int); 171 int oack(struct tftp_client *); 172 void oack_done(int, short, void *); 173 174 void sendfile(struct tftp_client *); 175 void recvfile(struct tftp_client *); 176 int fget_octet(struct tftp_client *); 177 int fput_octet(struct tftp_client *, int); 178 int fget_netascii(struct tftp_client *); 179 int fput_netascii(struct tftp_client *, int); 180 void file_read(struct tftp_client *); 181 int tftp_wrq_ack_packet(struct tftp_client *); 182 void tftp_rrq_ack(int, short, void *); 183 void tftp_wrq_ack(struct tftp_client *client); 184 void tftp_wrq(int, short, void *); 185 void tftp_wrq_end(int, short, void *); 186 187 int parse_options(struct tftp_client *, char *, size_t, 188 struct opt_client *); 189 int validate_access(struct tftp_client *, const char *); 190 191 struct tftp_client * 192 client_alloc(void); 193 void client_free(struct tftp_client *client); 194 195 struct formats { 196 const char *f_mode; 197 int (*f_getc)(struct tftp_client *); 198 int (*f_putc)(struct tftp_client *, int); 199 } formats[] = { 200 { "octet", fget_octet, fput_octet }, 201 { "netascii", fget_netascii, fput_netascii }, 202 { NULL, NULL } 203 }; 204 205 struct errmsg { 206 int e_code; 207 const char *e_msg; 208 } errmsgs[] = { 209 { EUNDEF, "Undefined error code" }, 210 { ENOTFOUND, "File not found" }, 211 { EACCESS, "Access violation" }, 212 { ENOSPACE, "Disk full or allocation exceeded" }, 213 { EBADOP, "Illegal TFTP operation" }, 214 { EBADID, "Unknown transfer ID" }, 215 { EEXISTS, "File already exists" }, 216 { ENOUSER, "No such user" }, 217 { EOPTNEG, "Option negotiation failed" }, 218 { -1, NULL } 219 }; 220 221 struct loggers { 222 void (*err)(int, const char *, ...); 223 void (*errx)(int, const char *, ...); 224 void (*warn)(const char *, ...); 225 void (*warnx)(const char *, ...); 226 void (*info)(const char *, ...); 227 }; 228 229 const struct loggers conslogger = { 230 err, 231 errx, 232 warn, 233 warnx, 234 warnx 235 }; 236 237 void syslog_err(int, const char *, ...); 238 void syslog_errx(int, const char *, ...); 239 void syslog_warn(const char *, ...); 240 void syslog_warnx(const char *, ...); 241 void syslog_info(const char *, ...); 242 void syslog_vstrerror(int, int, const char *, va_list); 243 244 const struct loggers syslogger = { 245 syslog_err, 246 syslog_errx, 247 syslog_warn, 248 syslog_warnx, 249 syslog_info, 250 }; 251 252 const struct loggers *logger = &conslogger; 253 254 #define lerr(_e, _f...) logger->err((_e), _f) 255 #define lerrx(_e, _f...) logger->errx((_e), _f) 256 #define lwarn(_f...) logger->warn(_f) 257 #define lwarnx(_f...) logger->warnx(_f) 258 #define linfo(_f...) logger->info(_f) 259 260 __dead void 261 usage(void) 262 { 263 extern char *__progname; 264 fprintf(stderr, "usage: %s [-46cdv] [-l address] [-p port] [-r socket]" 265 " directory\n", __progname); 266 exit(1); 267 } 268 269 int cancreate = 0; 270 int verbose = 0; 271 272 int 273 main(int argc, char *argv[]) 274 { 275 extern char *__progname; 276 int debug = 0; 277 278 int c; 279 struct passwd *pw; 280 281 char *dir = NULL; 282 char *rewrite = NULL; 283 284 char *addr = NULL; 285 char *port = "tftp"; 286 int family = AF_UNSPEC; 287 288 while ((c = getopt(argc, argv, "46cdl:p:r:v")) != -1) { 289 switch (c) { 290 case '4': 291 family = AF_INET; 292 break; 293 case '6': 294 family = AF_INET6; 295 break; 296 case 'c': 297 cancreate = 1; 298 break; 299 case 'd': 300 verbose = debug = 1; 301 break; 302 case 'l': 303 addr = optarg; 304 break; 305 case 'p': 306 port = optarg; 307 break; 308 case 'r': 309 rewrite = optarg; 310 break; 311 case 'v': 312 verbose = 1; 313 break; 314 default: 315 usage(); 316 /* NOTREACHED */ 317 } 318 } 319 320 argc -= optind; 321 argv += optind; 322 323 if (argc != 1) 324 usage(); 325 326 dir = argv[0]; 327 328 if (geteuid() != 0) 329 errx(1, "need root privileges"); 330 331 pw = getpwnam("_tftpd"); 332 if (pw == NULL) 333 errx(1, "no _tftpd user"); 334 335 if (!debug) { 336 openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON); 337 tzset(); 338 logger = &syslogger; 339 } 340 341 if (rewrite != NULL) 342 rewrite_connect(rewrite); 343 344 tftpd_listen(addr, port, family); 345 346 if (chroot(dir)) 347 err(1, "chroot %s", dir); 348 if (chdir("/")) 349 err(1, "chdir %s", dir); 350 351 /* drop privs */ 352 if (setgroups(1, &pw->pw_gid) || 353 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 354 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 355 errx(1, "can't drop privileges"); 356 357 if (!debug && daemon(1, 0) == -1) 358 err(1, "unable to daemonize"); 359 360 event_init(); 361 362 if (rewrite != NULL) 363 rewrite_events(); 364 365 tftpd_events(); 366 367 event_dispatch(); 368 369 exit(0); 370 } 371 372 struct rewritemap { 373 struct event wrev; 374 struct event rdev; 375 struct evbuffer *wrbuf; 376 struct evbuffer *rdbuf; 377 378 TAILQ_HEAD(, tftp_client) clients; 379 380 int s; 381 }; 382 383 struct rewritemap *rwmap = NULL; 384 385 void 386 rewrite_connect(const char *path) 387 { 388 int s; 389 struct sockaddr_un remote; 390 size_t len; 391 int on = 1; 392 393 rwmap = malloc(sizeof(*rwmap)); 394 if (rwmap == NULL) 395 err(1, "rewrite event malloc"); 396 397 rwmap->wrbuf = evbuffer_new(); 398 if (rwmap->wrbuf == NULL) 399 err(1, "rewrite wrbuf"); 400 401 rwmap->rdbuf = evbuffer_new(); 402 if (rwmap->rdbuf == NULL) 403 err(1, "rewrite rdbuf"); 404 405 TAILQ_INIT(&rwmap->clients); 406 407 s = socket(AF_UNIX, SOCK_STREAM, 0); 408 if (s == -1) 409 err(1, "rewrite socket"); 410 411 remote.sun_family = AF_UNIX; 412 len = strlcpy(remote.sun_path, path, sizeof(remote.sun_path)); 413 if (len >= sizeof(remote.sun_path)) 414 errx(1, "rewrite socket path is too long"); 415 416 len += sizeof(remote.sun_family) + 1; 417 if (connect(s, (struct sockaddr *)&remote, len) == -1) 418 err(1, "%s", path); 419 420 if (ioctl(s, FIONBIO, &on) < 0) 421 err(1, "rewrite ioctl(FIONBIO)"); 422 423 rwmap->s = s; 424 } 425 426 void 427 rewrite_events(void) 428 { 429 event_set(&rwmap->wrev, rwmap->s, EV_WRITE, rewrite_req, NULL); 430 event_set(&rwmap->rdev, rwmap->s, EV_READ | EV_PERSIST, rewrite_res, NULL); 431 event_add(&rwmap->rdev, NULL); 432 } 433 434 void 435 rewrite_map(struct tftp_client *client, const char *filename) 436 { 437 char nicebuf[MAXPATHLEN]; 438 439 (void)strnvis(nicebuf, filename, MAXPATHLEN, VIS_SAFE|VIS_OCTAL); 440 441 if (evbuffer_add_printf(rwmap->wrbuf, "%s %s %s\n", getip(&client->ss), 442 client->opcode == WRQ ? "write" : "read", nicebuf) == -1) 443 lerr(1, "rwmap printf"); 444 445 TAILQ_INSERT_TAIL(&rwmap->clients, client, entry); 446 447 event_add(&rwmap->wrev, NULL); 448 } 449 450 void 451 rewrite_req(int fd, short events, void *arg) 452 { 453 if (evbuffer_write(rwmap->wrbuf, fd) == -1) 454 lerr(1, "rwmap read"); 455 456 if (EVBUFFER_LENGTH(rwmap->wrbuf)) 457 event_add(&rwmap->wrev, NULL); 458 } 459 460 void 461 rewrite_res(int fd, short events, void *arg) 462 { 463 struct tftp_client *client; 464 char *filename; 465 size_t len; 466 467 if (evbuffer_read(rwmap->rdbuf, fd, MAXPATHLEN) == -1) 468 lerr(1, "rwmap read"); 469 470 while ((filename = evbuffer_readln(rwmap->rdbuf, &len, 471 EVBUFFER_EOL_LF)) != NULL) { 472 client = TAILQ_FIRST(&rwmap->clients); 473 if (client == NULL) 474 lerrx(1, "unexpected rwmap reply"); 475 476 TAILQ_REMOVE(&rwmap->clients, client, entry); 477 478 tftp_open(client, filename); 479 480 free(filename); 481 }; 482 } 483 484 int 485 tftpd_listen(const char *addr, const char *port, int family) 486 { 487 struct tftp_server *server; 488 489 struct addrinfo hints, *res, *res0; 490 int error; 491 int s; 492 493 int saved_errno; 494 const char *cause = NULL; 495 496 int on = 1; 497 498 memset(&hints, 0, sizeof(hints)); 499 hints.ai_family = family; 500 hints.ai_socktype = SOCK_DGRAM; 501 hints.ai_flags = AI_PASSIVE; 502 503 TAILQ_INIT(&tftp_servers); 504 505 error = getaddrinfo(addr, port, &hints, &res0); 506 if (error) { 507 errx(1, "%s:%s: %s", addr ? addr : "*", port, 508 gai_strerror(error)); 509 } 510 511 for (res = res0; res != NULL; res = res->ai_next) { 512 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 513 if (s == -1) { 514 cause = "socket"; 515 continue; 516 } 517 518 if (bind(s, res->ai_addr, res->ai_addrlen) == -1) { 519 cause = "bind"; 520 saved_errno = errno; 521 close(s); 522 errno = saved_errno; 523 continue; 524 } 525 526 if (ioctl(s, FIONBIO, &on) < 0) 527 err(1, "ioctl(FIONBIO)"); 528 529 switch (res->ai_family) { 530 case AF_INET: 531 if (setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, 532 &on, sizeof(on)) == -1) 533 errx(1, "setsockopt(IP_RECVDSTADDR)"); 534 break; 535 case AF_INET6: 536 if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 537 &on, sizeof(on)) == -1) 538 errx(1, "setsockopt(IPV6_RECVPKTINFO)"); 539 break; 540 } 541 542 server = malloc(sizeof(*server)); 543 if (server == NULL) 544 err(1, "malloc"); 545 546 server->s = s; 547 TAILQ_INSERT_TAIL(&tftp_servers, server, entry); 548 } 549 550 if (TAILQ_EMPTY(&tftp_servers)) 551 err(1, "%s", cause); 552 553 return (0); 554 } 555 556 void 557 tftpd_events(void) 558 { 559 struct tftp_server *server; 560 TAILQ_FOREACH(server, &tftp_servers, entry) { 561 event_set(&server->ev, server->s, EV_READ | EV_PERSIST, 562 tftpd_recv, server); 563 event_add(&server->ev, NULL); 564 } 565 } 566 567 struct tftp_client * 568 client_alloc(void) 569 { 570 struct tftp_client *client; 571 572 client = calloc(1, sizeof(*client)); 573 if (client == NULL) 574 return (NULL); 575 576 client->segment_size = SEGSIZE; 577 client->packet_size = SEGSIZE + 4; 578 579 client->tv.tv_sec = TIMEOUT; 580 client->tv.tv_usec = 0; 581 582 client->sock = -1; 583 client->file = NULL; 584 client->newline = 0; 585 586 return (client); 587 } 588 589 void 590 client_free(struct tftp_client *client) 591 { 592 if (client->options != NULL) 593 free(client->options); 594 595 if (client->file != NULL) 596 fclose(client->file); 597 598 close(client->sock); 599 600 free(client); 601 } 602 603 void 604 tftpd_recv(int fd, short events, void *arg) 605 { 606 union { 607 struct cmsghdr hdr; 608 char buf[CMSG_SPACE(sizeof(struct sockaddr_storage))]; 609 } cmsgbuf; 610 struct cmsghdr *cmsg; 611 struct msghdr msg; 612 struct iovec iov; 613 614 ssize_t n; 615 struct sockaddr_storage s_in; 616 int dobind = 1; 617 int on = 1; 618 619 struct tftphdr *tp; 620 621 struct tftp_client *client; 622 623 client = client_alloc(); 624 if (client == NULL) { 625 char *buf = alloca(SEGSIZE_MAX + 4); 626 /* no memory! flush this request... */ 627 recv(fd, buf, SEGSIZE_MAX + 4, 0); 628 /* dont care if it fails */ 629 return; 630 } 631 632 bzero(&msg, sizeof(msg)); 633 iov.iov_base = client->buf; 634 iov.iov_len = client->packet_size; 635 msg.msg_name = &client->ss; 636 msg.msg_namelen = sizeof(client->ss); 637 msg.msg_iov = &iov; 638 msg.msg_iovlen = 1; 639 msg.msg_control = &cmsgbuf.buf; 640 msg.msg_controllen = sizeof(cmsgbuf.buf); 641 642 n = recvmsg(fd, &msg, 0); 643 if (n == -1) { 644 lwarn("recvmsg"); 645 goto err; 646 } 647 if (n < 4) 648 goto err; 649 650 client->sock = socket(client->ss.ss_family, SOCK_DGRAM, 0); 651 if (client->sock == -1) { 652 lwarn("socket"); 653 goto err; 654 } 655 memset(&s_in, 0, sizeof(s_in)); 656 s_in.ss_family = client->ss.ss_family; 657 s_in.ss_len = client->ss.ss_len; 658 659 /* get local address if possible */ 660 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; 661 cmsg = CMSG_NXTHDR(&msg, cmsg)) { 662 if (cmsg->cmsg_level == IPPROTO_IP && 663 cmsg->cmsg_type == IP_RECVDSTADDR) { 664 memcpy(&((struct sockaddr_in *)&s_in)->sin_addr, 665 CMSG_DATA(cmsg), sizeof(struct in_addr)); 666 if (((struct sockaddr_in *)&s_in)->sin_addr.s_addr == 667 INADDR_BROADCAST) 668 dobind = 0; 669 break; 670 } 671 if (cmsg->cmsg_level == IPPROTO_IPV6 && 672 cmsg->cmsg_type == IPV6_PKTINFO) { 673 struct in6_pktinfo *ipi; 674 675 ipi = (struct in6_pktinfo *)CMSG_DATA(cmsg); 676 memcpy(&((struct sockaddr_in6 *)&s_in)->sin6_addr, 677 &ipi->ipi6_addr, sizeof(struct in6_addr)); 678 #ifdef __KAME__ 679 if (IN6_IS_ADDR_LINKLOCAL(&ipi->ipi6_addr)) 680 ((struct sockaddr_in6 *)&s_in)->sin6_scope_id = 681 ipi->ipi6_ifindex; 682 #endif 683 break; 684 } 685 } 686 687 if (dobind) { 688 setsockopt(client->sock, SOL_SOCKET, SO_REUSEADDR, 689 &on, sizeof(on)); 690 setsockopt(client->sock, SOL_SOCKET, SO_REUSEPORT, 691 &on, sizeof(on)); 692 693 if (bind(client->sock, (struct sockaddr *)&s_in, 694 s_in.ss_len) < 0) { 695 lwarn("bind to %s", getip(&s_in)); 696 goto err; 697 } 698 } 699 if (connect(client->sock, (struct sockaddr *)&client->ss, 700 client->ss.ss_len) == -1) { 701 lwarn("connect to %s", getip(&client->ss)); 702 goto err; 703 } 704 705 if (ioctl(client->sock, FIONBIO, &on) < 0) 706 err(1, "client ioctl(FIONBIO)"); 707 708 tp = (struct tftphdr *)client->buf; 709 client->opcode = ntohs(tp->th_opcode); 710 if (client->opcode != RRQ && client->opcode != WRQ) { 711 /* bad request */ 712 goto err; 713 } 714 715 tftp(client, tp, n); 716 717 return; 718 719 err: 720 client_free(client); 721 } 722 723 int 724 parse_options(struct tftp_client *client, char *cp, size_t size, 725 struct opt_client *options) 726 { 727 char *option; 728 char *ccp; 729 int has_options = 0; 730 int i; 731 732 while (++cp < client->buf + size) { 733 for (i = 2, ccp = cp; i > 0; ccp++) { 734 if (ccp >= client->buf + size) { 735 /* 736 * Don't reject the request, just stop trying 737 * to parse the option and get on with it. 738 * Some Apple OpenFirmware versions have 739 * trailing garbage on the end of otherwise 740 * valid requests. 741 */ 742 return (has_options); 743 } else if (*ccp == '\0') 744 i--; 745 } 746 747 for (option = cp; *cp; cp++) 748 *cp = tolower((unsigned char)*cp); 749 750 for (i = 0; i < NOPT; i++) { 751 if (strcmp(option, opt_names[i]) == 0) { 752 options[i].o_request = ++cp; 753 has_options = 1; 754 } 755 } 756 cp = ccp - 1; 757 } 758 759 return (has_options); 760 } 761 762 /* 763 * Handle initial connection protocol. 764 */ 765 void 766 tftp(struct tftp_client *client, struct tftphdr *tp, size_t size) 767 { 768 struct opt_client *options; 769 770 char *cp; 771 int i, first = 1, ecode, to; 772 struct formats *pf; 773 char *mode = NULL; 774 char filename[MAXPATHLEN]; 775 const char *errstr; 776 777 if (size < 5) { 778 ecode = EBADOP; 779 goto error; 780 } 781 782 cp = tp->th_stuff; 783 again: 784 while (cp < client->buf + size) { 785 if (*cp == '\0') 786 break; 787 cp++; 788 } 789 if (*cp != '\0') { 790 ecode = EBADOP; 791 goto error; 792 } 793 i = cp - tp->th_stuff; 794 if (i >= sizeof(filename)) { 795 ecode = EBADOP; 796 goto error; 797 } 798 memcpy(filename, tp->th_stuff, i); 799 filename[i] = '\0'; 800 if (first) { 801 mode = ++cp; 802 first = 0; 803 goto again; 804 } 805 for (cp = mode; *cp; cp++) 806 *cp = tolower((unsigned char)*cp); 807 808 for (pf = formats; pf->f_mode; pf++) { 809 if (strcmp(pf->f_mode, mode) == 0) 810 break; 811 } 812 if (pf->f_mode == 0) { 813 ecode = EBADOP; 814 goto error; 815 } 816 client->fgetc = pf->f_getc; 817 client->fputc = pf->f_putc; 818 819 client->options = options = calloc(NOPT, sizeof(*client->options)); 820 if (options == NULL) { 821 ecode = 100 + ENOMEM; 822 goto error; 823 } 824 825 if (parse_options(client, cp, size, options)) { 826 if (options[OPT_TIMEOUT].o_request != NULL) { 827 to = strtonum(options[OPT_TIMEOUT].o_request, 828 TIMEOUT_MIN, TIMEOUT_MAX, &errstr); 829 if (errstr) { 830 ecode = EBADOP; 831 goto error; 832 } 833 options[OPT_TIMEOUT].o_reply = client->tv.tv_sec = to; 834 } 835 836 if (options[OPT_BLKSIZE].o_request) { 837 client->segment_size = strtonum( 838 options[OPT_BLKSIZE].o_request, 839 SEGSIZE_MIN, SEGSIZE_MAX, &errstr); 840 if (errstr) { 841 ecode = EBADOP; 842 goto error; 843 } 844 client->packet_size = client->segment_size + 4; 845 options[OPT_BLKSIZE].o_reply = client->segment_size; 846 } 847 } else { 848 free(options); 849 client->options = NULL; 850 } 851 852 if (verbose) { 853 char nicebuf[MAXPATHLEN]; 854 855 (void)strnvis(nicebuf, filename, MAXPATHLEN, 856 VIS_SAFE|VIS_OCTAL); 857 858 linfo("%s: %s request for '%s'", getip(&client->ss), 859 client->opcode == WRQ ? "write" : "read", nicebuf); 860 } 861 862 if (rwmap != NULL) 863 rewrite_map(client, filename); 864 else 865 tftp_open(client, filename); 866 867 return; 868 869 error: 870 nak(client, ecode); 871 } 872 873 void 874 tftp_open(struct tftp_client *client, const char *filename) 875 { 876 int ecode; 877 878 ecode = validate_access(client, filename); 879 if (ecode) 880 goto error; 881 882 if (client->options) { 883 if (oack(client) == -1) 884 goto error; 885 886 free(client->options); 887 client->options = NULL; 888 } else if (client->opcode == WRQ) { 889 recvfile(client); 890 } else 891 sendfile(client); 892 893 return; 894 error: 895 nak(client, ecode); 896 } 897 898 /* 899 * Validate file access. Since we 900 * have no uid or gid, for now require 901 * file to exist and be publicly 902 * readable/writable. 903 * If we were invoked with arguments 904 * from inetd then the file must also be 905 * in one of the given directory prefixes. 906 * Note also, full path name must be 907 * given as we have no login directory. 908 */ 909 int 910 validate_access(struct tftp_client *client, const char *filename) 911 { 912 int mode = client->opcode; 913 struct opt_client *options = client->options; 914 struct stat stbuf; 915 int fd, wmode; 916 const char *errstr; 917 918 /* 919 * We use a different permissions scheme if `cancreate' is 920 * set. 921 */ 922 wmode = O_TRUNC; 923 if (stat(filename, &stbuf) < 0) { 924 if (!cancreate) 925 return (errno == ENOENT ? ENOTFOUND : EACCESS); 926 else { 927 if ((errno == ENOENT) && (mode != RRQ)) 928 wmode |= O_CREAT; 929 else 930 return (EACCESS); 931 } 932 } else { 933 if (mode == RRQ) { 934 if ((stbuf.st_mode & (S_IRUSR >> 6)) == 0) 935 return (EACCESS); 936 } else { 937 if ((stbuf.st_mode & (S_IWUSR >> 6)) == 0) 938 return (EACCESS); 939 } 940 } 941 942 if (options != NULL && options[OPT_TSIZE].o_request) { 943 if (mode == RRQ) 944 options[OPT_TSIZE].o_reply = stbuf.st_size; 945 else { 946 /* allows writes of 65535 blocks * SEGSIZE_MAX bytes */ 947 options[OPT_TSIZE].o_reply = 948 strtonum(options[OPT_TSIZE].o_request, 949 1, 65535LL * SEGSIZE_MAX, &errstr); 950 if (errstr) 951 return (EOPTNEG); 952 } 953 } 954 fd = open(filename, mode == RRQ ? O_RDONLY : (O_WRONLY|wmode), 0666); 955 if (fd < 0) 956 return (errno + 100); 957 /* 958 * If the file was created, set default permissions. 959 */ 960 if ((wmode & O_CREAT) && fchmod(fd, 0666) < 0) { 961 int serrno = errno; 962 963 close(fd); 964 unlink(filename); 965 966 return (serrno + 100); 967 } 968 client->file = fdopen(fd, mode == RRQ ? "r" : "w"); 969 if (client->file == NULL) { 970 close(fd); 971 return (errno + 100); 972 } 973 974 return (0); 975 } 976 977 int 978 fget_octet(struct tftp_client *client) 979 { 980 return (getc(client->file)); 981 } 982 983 int 984 fput_octet(struct tftp_client *client, int c) 985 { 986 return (putc(c, client->file)); 987 } 988 989 int 990 fget_netascii(struct tftp_client *client) 991 { 992 int c = -1; 993 994 switch (client->newline) { 995 case 0: 996 c = getc(client->file); 997 if (c == EOF) 998 break; 999 1000 if (c == '\n' || c == '\r') { 1001 client->newline = c; 1002 c = '\r'; 1003 } 1004 break; 1005 case '\n': 1006 client->newline = 0; 1007 c = '\n'; 1008 break; 1009 case '\r': 1010 client->newline = 0; 1011 c = '\0'; 1012 break; 1013 } 1014 1015 return (c); 1016 } 1017 1018 int 1019 fput_netascii(struct tftp_client *client, int c) 1020 { 1021 if (client->newline == '\r') { 1022 client->newline = 0; 1023 1024 if (c == '\0') 1025 c = '\r'; 1026 1027 } else if (c == '\r') { 1028 client->newline = c; 1029 return (c); 1030 } 1031 1032 return (putc(c, client->file)); 1033 } 1034 1035 void 1036 sendfile(struct tftp_client *client) 1037 { 1038 event_set(&client->sev, client->sock, EV_READ, tftp_rrq_ack, client); 1039 client->block = 1; 1040 1041 file_read(client); 1042 } 1043 1044 void 1045 file_read(struct tftp_client *client) 1046 { 1047 u_int8_t *buf; 1048 struct tftphdr *dp; 1049 int i; 1050 int c; 1051 1052 dp = (struct tftphdr *)client->buf; 1053 dp->th_opcode = htons((u_short)DATA); 1054 dp->th_block = htons(client->block); 1055 buf = (u_int8_t *)dp->th_data; 1056 1057 for (i = 0; i < client->segment_size; i++) { 1058 c = client->fgetc(client); 1059 if (c == EOF) { 1060 if (ferror(client->file)) { 1061 nak(client, 100 + EIO); 1062 return; 1063 } 1064 1065 break; 1066 } 1067 buf[i] = c; 1068 } 1069 1070 client->buflen = i + 4; 1071 client->retries = RETRIES; 1072 1073 if (send(client->sock, client->buf, client->buflen, 0) == -1) { 1074 lwarn("send(block)"); 1075 client_free(client); 1076 return; 1077 } 1078 1079 event_add(&client->sev, &client->tv); 1080 } 1081 1082 void 1083 tftp_rrq_ack(int fd, short events, void *arg) 1084 { 1085 struct tftp_client *client = arg; 1086 struct tftphdr *ap; /* ack packet */ 1087 char rbuf[SEGSIZE_MIN]; 1088 ssize_t n; 1089 1090 if (events & EV_TIMEOUT) { 1091 if (retry(client) == -1) { 1092 lwarn("%s: retry", getip(&client->ss)); 1093 goto done; 1094 } 1095 1096 return; 1097 } 1098 1099 n = recv(fd, rbuf, sizeof(rbuf), 0); 1100 if (n == -1) { 1101 switch (errno) { 1102 case EINTR: 1103 case EAGAIN: 1104 event_add(&client->sev, &client->tv); 1105 return; 1106 1107 default: 1108 lwarn("%s: recv", getip(&client->ss)); 1109 goto done; 1110 } 1111 } 1112 1113 ap = (struct tftphdr *)rbuf; 1114 ap->th_opcode = ntohs((u_short)ap->th_opcode); 1115 ap->th_block = ntohs((u_short)ap->th_block); 1116 1117 switch (ap->th_opcode) { 1118 case ERROR: 1119 goto done; 1120 case ACK: 1121 break; 1122 default: 1123 goto retry; 1124 } 1125 1126 if (ap->th_block != client->block) { 1127 if (tftp_flush(client) == -1) { 1128 lwarnx("%s: flush", getip(&client->ss)); 1129 goto done; 1130 } 1131 1132 if (ap->th_block != (client->block - 1)) 1133 goto done; 1134 1135 goto retry; 1136 } 1137 1138 if (client->buflen != client->packet_size) { 1139 /* this was the last packet in the stream */ 1140 goto done; 1141 } 1142 1143 client->block++; 1144 file_read(client); 1145 return; 1146 1147 retry: 1148 event_add(&client->sev, &client->tv); 1149 return; 1150 1151 done: 1152 client_free(client); 1153 } 1154 1155 int 1156 tftp_flush(struct tftp_client *client) 1157 { 1158 char rbuf[SEGSIZE_MIN]; 1159 ssize_t n; 1160 1161 for (;;) { 1162 n = recv(client->sock, rbuf, sizeof(rbuf), 0); 1163 if (n == -1) { 1164 switch (errno) { 1165 case EAGAIN: 1166 return (0); 1167 1168 case EINTR: 1169 break; 1170 1171 default: 1172 return (-1); 1173 } 1174 } 1175 } 1176 } 1177 1178 void 1179 recvfile(struct tftp_client *client) 1180 { 1181 event_set(&client->sev, client->sock, EV_READ, tftp_wrq, client); 1182 tftp_wrq_ack(client); 1183 } 1184 1185 int 1186 tftp_wrq_ack_packet(struct tftp_client *client) 1187 { 1188 struct tftphdr *ap; /* ack packet */ 1189 1190 ap = (struct tftphdr *)client->buf; 1191 ap->th_opcode = htons((u_short)ACK); 1192 ap->th_block = htons(client->block); 1193 1194 client->buflen = 4; 1195 client->retries = RETRIES; 1196 1197 return (send(client->sock, client->buf, client->buflen, 0) != 4); 1198 } 1199 1200 void 1201 tftp_wrq_ack(struct tftp_client *client) 1202 { 1203 if (tftp_wrq_ack_packet(client) != 0) { 1204 lwarn("tftp wrq ack"); 1205 client_free(client); 1206 return; 1207 } 1208 1209 client->block++; 1210 event_add(&client->sev, &client->tv); 1211 } 1212 1213 void 1214 tftp_wrq(int fd, short events, void *arg) 1215 { 1216 char wbuf[SEGSIZE_MAX + 4]; 1217 struct tftp_client *client = arg; 1218 struct tftphdr *dp; 1219 ssize_t n; 1220 int i; 1221 1222 if (events & EV_TIMEOUT) { 1223 if (retry(client) == -1) { 1224 lwarn("%s", getip(&client->ss)); 1225 goto done; 1226 } 1227 1228 return; 1229 } 1230 1231 n = recv(fd, wbuf, client->packet_size, 0); 1232 if (n == -1) { 1233 switch (errno) { 1234 case EINTR: 1235 case EAGAIN: 1236 goto retry; 1237 1238 default: 1239 lwarn("tftp_wrq recv"); 1240 goto done; 1241 } 1242 } 1243 1244 if (n < 4) 1245 goto done; 1246 1247 dp = (struct tftphdr *)wbuf; 1248 dp->th_opcode = ntohs((u_short)dp->th_opcode); 1249 dp->th_block = ntohs((u_short)dp->th_block); 1250 1251 switch (dp->th_opcode) { 1252 case ERROR: 1253 goto done; 1254 case DATA: 1255 break; 1256 default: 1257 goto retry; 1258 } 1259 1260 if (dp->th_block != client->block) { 1261 if (tftp_flush(client) == -1) { 1262 lwarnx("%s: flush", getip(&client->ss)); 1263 goto done; 1264 } 1265 1266 if (dp->th_block != (client->block - 1)) 1267 goto done; 1268 1269 goto retry; 1270 } 1271 1272 for (i = 4; i < n; i++) { 1273 if (client->fputc(client, wbuf[i]) == EOF) { 1274 lwarn("tftp wrq"); 1275 goto done; 1276 } 1277 } 1278 1279 if (n < client->packet_size) { 1280 tftp_wrq_ack_packet(client); 1281 fclose(client->file); 1282 client->file = NULL; 1283 event_set(&client->sev, client->sock, EV_READ, 1284 tftp_wrq_end, client); 1285 event_add(&client->sev, &client->tv); 1286 return; 1287 } 1288 1289 tftp_wrq_ack(client); 1290 return; 1291 1292 retry: 1293 event_add(&client->sev, &client->tv); 1294 return; 1295 done: 1296 client_free(client); 1297 } 1298 1299 void 1300 tftp_wrq_end(int fd, short events, void *arg) 1301 { 1302 char wbuf[SEGSIZE_MAX + 4]; 1303 struct tftp_client *client = arg; 1304 struct tftphdr *dp; 1305 ssize_t n; 1306 1307 if (events & EV_TIMEOUT) { 1308 /* this was the last packet, we can clean up */ 1309 goto done; 1310 } 1311 1312 n = recv(fd, wbuf, client->packet_size, 0); 1313 if (n == -1) { 1314 switch (errno) { 1315 case EINTR: 1316 case EAGAIN: 1317 goto retry; 1318 1319 default: 1320 lwarn("tftp_wrq_end recv"); 1321 goto done; 1322 } 1323 } 1324 1325 if (n < 4) 1326 goto done; 1327 1328 dp = (struct tftphdr *)wbuf; 1329 dp->th_opcode = ntohs((u_short)dp->th_opcode); 1330 dp->th_block = ntohs((u_short)dp->th_block); 1331 1332 switch (dp->th_opcode) { 1333 case ERROR: 1334 goto done; 1335 case DATA: 1336 break; 1337 default: 1338 goto retry; 1339 } 1340 1341 if (dp->th_block != client->block) 1342 goto done; 1343 1344 retry: 1345 if (retry(client) == -1) { 1346 lwarn("%s", getip(&client->ss)); 1347 goto done; 1348 } 1349 return; 1350 done: 1351 client_free(client); 1352 return; 1353 } 1354 1355 1356 /* 1357 * Send a nak packet (error message). 1358 * Error code passed in is one of the 1359 * standard TFTP codes, or a UNIX errno 1360 * offset by 100. 1361 */ 1362 void 1363 nak(struct tftp_client *client, int error) 1364 { 1365 struct tftphdr *tp; 1366 struct errmsg *pe; 1367 size_t length; 1368 1369 tp = (struct tftphdr *)client->buf; 1370 tp->th_opcode = htons((u_short)ERROR); 1371 tp->th_code = htons((u_short)error); 1372 1373 for (pe = errmsgs; pe->e_code >= 0; pe++) { 1374 if (pe->e_code == error) 1375 break; 1376 } 1377 if (pe->e_code < 0) { 1378 pe->e_msg = strerror(error - 100); 1379 tp->th_code = htons(EUNDEF); /* set 'undef' errorcode */ 1380 } 1381 1382 length = strlcpy(tp->th_msg, pe->e_msg, client->packet_size - 5) + 5; 1383 if (length > client->packet_size) 1384 length = client->packet_size; 1385 1386 if (send(client->sock, client->buf, length, 0) != length) 1387 lwarn("nak"); 1388 1389 client_free(client); 1390 } 1391 1392 /* 1393 * Send an oack packet (option acknowledgement). 1394 */ 1395 int 1396 oack(struct tftp_client *client) 1397 { 1398 struct opt_client *options = client->options; 1399 struct tftphdr *tp; 1400 char *bp; 1401 int i, n, size; 1402 1403 tp = (struct tftphdr *)client->buf; 1404 bp = (char *)tp->th_stuff; 1405 size = sizeof(client->buf) - 2; 1406 1407 tp->th_opcode = htons((u_short)OACK); 1408 for (i = 0; i < NOPT; i++) { 1409 if (options[i].o_request == NULL) 1410 continue; 1411 1412 n = snprintf(bp, size, "%s%c%lld", opt_names[i], '\0', 1413 options[i].o_reply); 1414 if (n == -1 || n >= size) { 1415 lwarnx("oack: no buffer space"); 1416 goto error; 1417 } 1418 1419 bp += n + 1; 1420 size -= n + 1; 1421 if (size < 0) { 1422 lwarnx("oack: no buffer space"); 1423 goto error; 1424 } 1425 } 1426 1427 client->buflen = bp - client->buf; 1428 client->retries = RETRIES; 1429 1430 if (send(client->sock, client->buf, client->buflen, 0) == -1) { 1431 lwarn("oack"); 1432 goto error; 1433 } 1434 1435 /* no client ACK for write requests with options */ 1436 if (client->opcode == WRQ) { 1437 client->block = 1; 1438 event_set(&client->sev, client->sock, EV_READ, 1439 tftp_wrq, client); 1440 } else 1441 event_set(&client->sev, client->sock, EV_READ, 1442 oack_done, client); 1443 1444 event_add(&client->sev, &client->tv); 1445 return (0); 1446 1447 error: 1448 return (-1); 1449 } 1450 1451 int 1452 retry(struct tftp_client *client) 1453 { 1454 if (--client->retries == 0) { 1455 errno = ETIMEDOUT; 1456 return (-1); 1457 } 1458 1459 if (send(client->sock, client->buf, client->buflen, 0) == -1) 1460 return (-1); 1461 1462 event_add(&client->sev, &client->tv); 1463 1464 return (0); 1465 } 1466 1467 void 1468 oack_done(int fd, short events, void *arg) 1469 { 1470 struct tftp_client *client = arg; 1471 struct tftphdr *ap; 1472 ssize_t n; 1473 1474 if (events & EV_TIMEOUT) { 1475 if (retry(client) == -1) { 1476 lwarn("%s", getip(&client->ss)); 1477 goto done; 1478 } 1479 1480 return; 1481 } 1482 1483 n = recv(client->sock, client->buf, client->packet_size, 0); 1484 if (n == -1) { 1485 switch (errno) { 1486 case EINTR: 1487 case EAGAIN: 1488 event_add(&client->sev, &client->tv); 1489 return; 1490 1491 default: 1492 lwarn("%s: recv", getip(&client->ss)); 1493 goto done; 1494 } 1495 } 1496 1497 if (n < 4) 1498 goto done; 1499 1500 ap = (struct tftphdr *)client->buf; 1501 ap->th_opcode = ntohs((u_short)ap->th_opcode); 1502 ap->th_block = ntohs((u_short)ap->th_block); 1503 1504 if (ap->th_opcode != ACK || ap->th_block != 0) 1505 goto done; 1506 1507 sendfile(client); 1508 return; 1509 1510 done: 1511 client_free(client); 1512 } 1513 1514 const char * 1515 getip(void *s) 1516 { 1517 struct sockaddr *sa = s; 1518 static char hbuf[NI_MAXHOST]; 1519 1520 if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), 1521 NULL, 0, NI_NUMERICHOST)) 1522 strlcpy(hbuf, "0.0.0.0", sizeof(hbuf)); 1523 1524 return(hbuf); 1525 } 1526 1527 void 1528 syslog_vstrerror(int e, int priority, const char *fmt, va_list ap) 1529 { 1530 char *s; 1531 1532 if (vasprintf(&s, fmt, ap) == -1) { 1533 syslog(LOG_EMERG, "unable to alloc in syslog_vstrerror"); 1534 exit(1); 1535 } 1536 1537 syslog(priority, "%s: %s", s, strerror(e)); 1538 1539 free(s); 1540 } 1541 1542 void 1543 syslog_err(int ecode, const char *fmt, ...) 1544 { 1545 va_list ap; 1546 1547 va_start(ap, fmt); 1548 syslog_vstrerror(errno, LOG_EMERG, fmt, ap); 1549 va_end(ap); 1550 1551 exit(ecode); 1552 } 1553 1554 void 1555 syslog_errx(int ecode, const char *fmt, ...) 1556 { 1557 va_list ap; 1558 1559 va_start(ap, fmt); 1560 vsyslog(LOG_WARNING, fmt, ap); 1561 va_end(ap); 1562 1563 exit(ecode); 1564 } 1565 1566 void 1567 syslog_warn(const char *fmt, ...) 1568 { 1569 va_list ap; 1570 1571 va_start(ap, fmt); 1572 syslog_vstrerror(errno, LOG_WARNING, fmt, ap); 1573 va_end(ap); 1574 } 1575 1576 void 1577 syslog_warnx(const char *fmt, ...) 1578 { 1579 va_list ap; 1580 1581 va_start(ap, fmt); 1582 vsyslog(LOG_WARNING, fmt, ap); 1583 va_end(ap); 1584 } 1585 1586 void 1587 syslog_info(const char *fmt, ...) 1588 { 1589 va_list ap; 1590 1591 va_start(ap, fmt); 1592 vsyslog(LOG_INFO, fmt, ap); 1593 va_end(ap); 1594 } 1595 1596