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