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