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