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