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