1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
22 * Use is subject to license terms.
23 * Copyright (c) 2016 by Delphix. All rights reserved.
24 */
25
26/*
27 * Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T
28 * All Rights Reserved.
29 */
30
31/*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California.
34 * All Rights Reserved.
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41/*
42 * Trivial file transfer protocol server.  A top level process runs in
43 * an infinite loop fielding new TFTP requests.  A child process,
44 * communicating via a pipe with the top level process, sends delayed
45 * NAKs for those that we can't handle.  A new child process is created
46 * to service each request that we can handle.  The top level process
47 * exits after a period of time during which no new requests are
48 * received.
49 */
50
51#include <sys/types.h>
52#include <sys/socket.h>
53#include <sys/wait.h>
54#include <sys/stat.h>
55#include <sys/time.h>
56
57#include <netinet/in.h>
58
59#include <arpa/inet.h>
60#include <dirent.h>
61#include <signal.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <unistd.h>
65#include <errno.h>
66#include <ctype.h>
67#include <netdb.h>
68#include <setjmp.h>
69#include <syslog.h>
70#include <sys/param.h>
71#include <fcntl.h>
72#include <pwd.h>
73#include <string.h>
74#include <priv_utils.h>
75#include "tftpcommon.h"
76
77#define	TIMEOUT		5
78#define	DELAY_SECS	3
79#define	DALLYSECS 60
80
81#define	SYSLOG_MSG(message) \
82	(syslog((((errno == ENETUNREACH) || (errno == EHOSTUNREACH) || \
83		(errno == ECONNREFUSED)) ? LOG_WARNING : LOG_ERR), message))
84
85static int			rexmtval = TIMEOUT;
86static int			maxtimeout = 5*TIMEOUT;
87static int			securetftp;
88static int			debug;
89static int			disable_pnp;
90static int			standalone;
91static uid_t			uid_nobody = UID_NOBODY;
92static uid_t			gid_nobody = GID_NOBODY;
93static int			reqsock = -1;
94				/* file descriptor of request socket */
95static socklen_t		fromlen;
96static socklen_t		fromplen;
97static struct sockaddr_storage	client;
98static struct sockaddr_in6 	*sin6_ptr;
99static struct sockaddr_in	*sin_ptr;
100static struct sockaddr_in6	*from6_ptr;
101static struct sockaddr_in	*from_ptr;
102static int			addrfmly;
103static int			peer;
104static off_t			tsize;
105static tftpbuf			ackbuf;
106static struct sockaddr_storage	from;
107static boolean_t		tsize_set;
108static pid_t			child;
109				/* pid of child handling delayed replys */
110static int			delay_fd [2];
111				/* pipe for communicating with child */
112static FILE			*file;
113static char			*filename;
114
115static union {
116	struct tftphdr	hdr;
117	char		data[SEGSIZE + 4];
118} buf;
119
120static union {
121	struct tftphdr	hdr;
122	char		data[SEGSIZE];
123} oackbuf;
124
125struct	delay_info {
126	long	timestamp;		/* time request received */
127	int	ecode;			/* error code to return */
128	struct	sockaddr_storage from;	/* address of client */
129};
130
131int	blocksize = SEGSIZE;	/* Number of data bytes in a DATA packet */
132
133/*
134 * Default directory for unqualified names
135 * Used by TFTP boot procedures
136 */
137static char	*homedir = "/tftpboot";
138
139struct formats {
140	char	*f_mode;
141	int	(*f_validate)(int);
142	void	(*f_send)(struct formats *, int);
143	void	(*f_recv)(struct formats *, int);
144	int	f_convert;
145};
146
147static void	delayed_responder(void);
148static void	tftp(struct tftphdr *, int);
149static int	validate_filename(int);
150static void	tftpd_sendfile(struct formats *, int);
151static void	tftpd_recvfile(struct formats *, int);
152static void	nak(int);
153static char	*blksize_handler(int, char *, int *);
154static char	*timeout_handler(int, char *, int *);
155static char	*tsize_handler(int, char *, int *);
156
157static struct formats formats[] = {
158	{ "netascii",	validate_filename, tftpd_sendfile, tftpd_recvfile, 1 },
159	{ "octet",	validate_filename, tftpd_sendfile, tftpd_recvfile, 0 },
160	{ NULL }
161};
162
163struct options {
164	char	*opt_name;
165	char	*(*opt_handler)(int, char *, int *);
166};
167
168static struct options options[] = {
169	{ "blksize",	blksize_handler },
170	{ "timeout",	timeout_handler },
171	{ "tsize",	tsize_handler },
172	{ NULL }
173};
174
175static char		optbuf[MAX_OPTVAL_LEN];
176static int		timeout;
177static sigjmp_buf	timeoutbuf;
178
179int
180main(int argc, char **argv)
181{
182	struct tftphdr *tp;
183	int n;
184	int c;
185	struct	passwd *pwd;		/* for "nobody" entry */
186	struct in_addr ipv4addr;
187	char abuf[INET6_ADDRSTRLEN];
188	socklen_t addrlen;
189
190	openlog("tftpd", LOG_PID, LOG_DAEMON);
191
192	pwd = getpwnam("nobody");
193	if (pwd != NULL) {
194		uid_nobody = pwd->pw_uid;
195		gid_nobody = pwd->pw_gid;
196	}
197
198	/* Tftp will not start new executables; clear the limit set.  */
199	(void) __init_daemon_priv(PU_CLEARLIMITSET, uid_nobody, gid_nobody,
200	    PRIV_PROC_CHROOT, PRIV_NET_PRIVADDR, NULL);
201
202	/* Remove the unneeded basic privileges everywhere. */
203	(void) priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_PROC_EXEC,
204	    PRIV_FILE_LINK_ANY, PRIV_PROC_INFO, PRIV_PROC_SESSION, NULL);
205
206	/* Remove the other privileges from E until we need them. */
207	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_CHROOT,
208	    PRIV_NET_PRIVADDR, NULL);
209
210	while ((c = getopt(argc, argv, "dspST:")) != EOF)
211		switch (c) {
212		case 'd':		/* enable debug */
213			debug++;
214			continue;
215		case 's':		/* secure daemon */
216			securetftp = 1;
217			continue;
218		case 'p':		/* disable name pnp mapping */
219			disable_pnp = 1;
220			continue;
221		case 'S':
222			standalone = 1;
223			continue;
224		case 'T':
225			rexmtval = atoi(optarg);
226			if (rexmtval <= 0 || rexmtval > MAX_TIMEOUT) {
227				(void) fprintf(stderr,
228				    "%s: Invalid retransmission "
229				    "timeout value: %s\n", argv[0], optarg);
230				exit(1);
231			}
232			maxtimeout = 5 * rexmtval;
233			continue;
234		case '?':
235		default:
236usage:
237			(void) fprintf(stderr,
238			    "usage: %s [-T rexmtval] [-spd] [home-directory]\n",
239			    argv[0]);
240			for (; optind < argc; optind++)
241				syslog(LOG_ERR, "bad argument %s",
242				    argv[optind]);
243			exit(1);
244		}
245
246	if (optind < argc)
247		if (optind == argc - 1 && *argv [optind] == '/')
248			homedir = argv [optind];
249		else
250			goto usage;
251
252	if (pipe(delay_fd) < 0) {
253		syslog(LOG_ERR, "pipe (main): %m");
254		exit(1);
255	}
256
257	(void) sigset(SIGCHLD, SIG_IGN); /* no zombies please */
258
259	if (standalone) {
260		socklen_t clientlen;
261
262		sin6_ptr = (struct sockaddr_in6 *)&client;
263		clientlen = sizeof (struct sockaddr_in6);
264		reqsock = socket(AF_INET6, SOCK_DGRAM, 0);
265		if (reqsock == -1) {
266			perror("socket");
267			exit(1);
268		}
269		(void) memset(&client, 0, clientlen);
270		sin6_ptr->sin6_family = AF_INET6;
271		sin6_ptr->sin6_port = htons(IPPORT_TFTP);
272
273		/* Enable privilege as tftp port is < 1024 */
274		(void) priv_set(PRIV_ON,
275		    PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, NULL);
276		if (bind(reqsock, (struct sockaddr *)&client,
277		    clientlen) == -1) {
278			perror("bind");
279			exit(1);
280		}
281		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_NET_PRIVADDR,
282		    NULL);
283
284		if (debug)
285			(void) puts("running in standalone mode...");
286	} else {
287		/* request socket passed on fd 0 by inetd */
288		reqsock = 0;
289	}
290	if (debug) {
291		int on = 1;
292
293		(void) setsockopt(reqsock, SOL_SOCKET, SO_DEBUG,
294		    (char *)&on, sizeof (on));
295	}
296
297	(void) chdir(homedir);
298
299	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
300	if ((child = fork()) < 0) {
301		syslog(LOG_ERR, "fork (main): %m");
302		exit(1);
303	}
304	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
305
306	if (child == 0) {
307		delayed_responder();
308	} /* child */
309
310	/* close read side of pipe */
311	(void) close(delay_fd[0]);
312
313
314	/*
315	 * Top level handling of incomming tftp requests.  Read a request
316	 * and pass it off to be handled.  If request is valid, handling
317	 * forks off and parent returns to this loop.  If no new requests
318	 * are received for DALLYSECS, exit and return to inetd.
319	 */
320
321	for (;;) {
322		fd_set readfds;
323		struct timeval dally;
324
325		FD_ZERO(&readfds);
326		FD_SET(reqsock, &readfds);
327		dally.tv_sec = DALLYSECS;
328		dally.tv_usec = 0;
329
330		n = select(reqsock + 1, &readfds, NULL, NULL, &dally);
331		if (n < 0) {
332			if (errno == EINTR)
333				continue;
334			syslog(LOG_ERR, "select: %m");
335			(void) kill(child, SIGKILL);
336			exit(1);
337		}
338		if (n == 0) {
339			/* Select timed out.  Its time to die. */
340			if (standalone)
341				continue;
342			else {
343				(void) kill(child, SIGKILL);
344				exit(0);
345			}
346		}
347		addrlen = sizeof (from);
348		if (getsockname(reqsock, (struct sockaddr  *)&from,
349		    &addrlen) < 0) {
350			syslog(LOG_ERR, "getsockname: %m");
351			exit(1);
352		}
353
354		switch (from.ss_family) {
355		case AF_INET:
356			fromlen = (socklen_t)sizeof (struct sockaddr_in);
357			break;
358		case AF_INET6:
359			fromlen = (socklen_t)sizeof (struct sockaddr_in6);
360			break;
361		default:
362			syslog(LOG_ERR,
363			    "Unknown address Family on peer connection %d",
364			    from.ss_family);
365			exit(1);
366		}
367
368		n = recvfrom(reqsock, &buf, sizeof (buf), 0,
369		    (struct sockaddr *)&from, &fromlen);
370		if (n < 0) {
371			if (errno == EINTR)
372				continue;
373			if (standalone)
374				perror("recvfrom");
375			else
376				syslog(LOG_ERR, "recvfrom: %m");
377			(void) kill(child, SIGKILL);
378			exit(1);
379		}
380
381		(void) alarm(0);
382
383		switch (from.ss_family) {
384		case AF_INET:
385			addrfmly = AF_INET;
386			fromplen = sizeof (struct sockaddr_in);
387			sin_ptr = (struct sockaddr_in *)&client;
388			(void) memset(&client, 0, fromplen);
389			sin_ptr->sin_family = AF_INET;
390			break;
391		case AF_INET6:
392			addrfmly = AF_INET6;
393			fromplen = sizeof (struct sockaddr_in6);
394			sin6_ptr = (struct sockaddr_in6 *)&client;
395			(void) memset(&client, 0, fromplen);
396			sin6_ptr->sin6_family = AF_INET6;
397			break;
398		default:
399			syslog(LOG_ERR,
400			    "Unknown address Family on peer connection");
401			exit(1);
402		}
403		peer = socket(addrfmly, SOCK_DGRAM, 0);
404		if (peer < 0) {
405			if (standalone)
406				perror("socket (main)");
407			else
408				syslog(LOG_ERR, "socket (main): %m");
409			(void) kill(child, SIGKILL);
410			exit(1);
411		}
412		if (debug) {
413			int on = 1;
414
415			(void) setsockopt(peer, SOL_SOCKET, SO_DEBUG,
416			    (char *)&on, sizeof (on));
417		}
418
419		if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) {
420			if (standalone)
421				perror("bind (main)");
422			else
423				syslog(LOG_ERR, "bind (main): %m");
424			(void) kill(child, SIGKILL);
425			exit(1);
426		}
427		if (standalone && debug) {
428			sin6_ptr = (struct sockaddr_in6 *)&client;
429			from6_ptr = (struct sockaddr_in6 *)&from;
430			if (IN6_IS_ADDR_V4MAPPED(&from6_ptr->sin6_addr)) {
431				IN6_V4MAPPED_TO_INADDR(&from6_ptr->sin6_addr,
432				    &ipv4addr);
433				(void) inet_ntop(AF_INET, &ipv4addr, abuf,
434				    sizeof (abuf));
435			} else {
436				(void) inet_ntop(AF_INET6,
437				    &from6_ptr->sin6_addr, abuf,
438				    sizeof (abuf));
439			}
440			/* get local port */
441			if (getsockname(peer, (struct sockaddr *)&client,
442			    &fromplen) < 0)
443				perror("getsockname (main)");
444			(void) fprintf(stderr,
445			    "request from %s port %d; local port %d\n",
446			    abuf, from6_ptr->sin6_port, sin6_ptr->sin6_port);
447		}
448		tp = &buf.hdr;
449		tp->th_opcode = ntohs((ushort_t)tp->th_opcode);
450		if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
451			tftp(tp, n);
452
453		(void) close(peer);
454		(void) fclose(file);
455	}
456
457	/*NOTREACHED*/
458	return (0);
459}
460
461static void
462delayed_responder(void)
463{
464	struct delay_info dinfo;
465	long now;
466
467	/* we don't use the descriptors passed in to the parent */
468	(void) close(0);
469	(void) close(1);
470	if (standalone)
471		(void) close(reqsock);
472
473	/* close write side of pipe */
474	(void) close(delay_fd[1]);
475
476	for (;;) {
477		int n;
478
479		if ((n = read(delay_fd[0], &dinfo,
480		    sizeof (dinfo))) != sizeof (dinfo)) {
481			if (n < 0) {
482				if (errno == EINTR)
483					continue;
484				if (standalone)
485					perror("read from pipe "
486					    "(delayed responder)");
487				else
488					syslog(LOG_ERR, "read from pipe: %m");
489			}
490			exit(1);
491		}
492		switch (dinfo.from.ss_family) {
493		case AF_INET:
494			addrfmly = AF_INET;
495			fromplen = sizeof (struct sockaddr_in);
496			sin_ptr = (struct sockaddr_in *)&client;
497			(void) memset(&client, 0, fromplen);
498			sin_ptr->sin_family = AF_INET;
499			break;
500		case AF_INET6:
501			addrfmly = AF_INET6;
502			fromplen = sizeof (struct sockaddr_in6);
503			sin6_ptr = (struct sockaddr_in6 *)&client;
504			(void) memset(&client, 0, fromplen);
505			sin6_ptr->sin6_family = AF_INET6;
506			break;
507		}
508		peer = socket(addrfmly, SOCK_DGRAM, 0);
509		if (peer == -1) {
510			if (standalone)
511				perror("socket (delayed responder)");
512			else
513				syslog(LOG_ERR, "socket (delay): %m");
514			exit(1);
515		}
516		if (debug) {
517			int on = 1;
518
519			(void) setsockopt(peer, SOL_SOCKET, SO_DEBUG,
520			    (char *)&on, sizeof (on));
521		}
522
523		if (bind(peer, (struct sockaddr *)&client, fromplen) < 0) {
524			if (standalone)
525				perror("bind (delayed responder)");
526			else
527				syslog(LOG_ERR, "bind (delay): %m");
528			exit(1);
529		}
530		if (client.ss_family == AF_INET) {
531			from_ptr = (struct sockaddr_in *)&dinfo.from;
532			from_ptr->sin_family = AF_INET;
533		} else {
534			from6_ptr = (struct sockaddr_in6 *)&dinfo.from;
535			from6_ptr->sin6_family = AF_INET6;
536		}
537		/*
538		 * Since a request hasn't been received from the client
539		 * before the delayed responder process is forked, the
540		 * from variable is uninitialized.  So set it to contain
541		 * the client address.
542		 */
543		from = dinfo.from;
544
545		/*
546		 * only sleep if DELAY_SECS has not elapsed since
547		 * original request was received.  Ensure that `now'
548		 * is not earlier than `dinfo.timestamp'
549		 */
550		now = time(0);
551		if ((uint_t)(now - dinfo.timestamp) < DELAY_SECS)
552			(void) sleep(DELAY_SECS - (now - dinfo.timestamp));
553		nak(dinfo.ecode);
554		(void) close(peer);
555	} /* for */
556
557	/* NOTREACHED */
558}
559
560/*
561 * Handle the Blocksize option.
562 * Return the blksize option value string to include in the OACK reply.
563 */
564/*ARGSUSED*/
565static char *
566blksize_handler(int opcode, char *optval, int *errcode)
567{
568	char *endp;
569	int value;
570
571	*errcode = -1;
572	errno = 0;
573	value = (int)strtol(optval, &endp, 10);
574	if (errno != 0 || value < MIN_BLKSIZE || *endp != '\0')
575		return (NULL);
576	/*
577	 * As the blksize value in the OACK reply can be less than the value
578	 * requested, to support broken clients if the value requested is larger
579	 * than allowed in the RFC, reply with the maximum value permitted.
580	 */
581	if (value > MAX_BLKSIZE)
582		value = MAX_BLKSIZE;
583
584	blocksize = value;
585	(void) snprintf(optbuf, sizeof (optbuf), "%d", blocksize);
586	return (optbuf);
587}
588
589/*
590 * Handle the Timeout Interval option.
591 * Return the timeout option value string to include in the OACK reply.
592 */
593/*ARGSUSED*/
594static char *
595timeout_handler(int opcode, char *optval, int *errcode)
596{
597	char *endp;
598	int value;
599
600	*errcode = -1;
601	errno = 0;
602	value = (int)strtol(optval, &endp, 10);
603	if (errno != 0 || *endp != '\0')
604		return (NULL);
605	/*
606	 * The timeout value in the OACK reply must match the value specified
607	 * by the client, so if an invalid timeout is requested don't include
608	 * the timeout option in the OACK reply.
609	 */
610	if (value < MIN_TIMEOUT || value > MAX_TIMEOUT)
611		return (NULL);
612
613	rexmtval = value;
614	maxtimeout = 5 * rexmtval;
615	(void) snprintf(optbuf, sizeof (optbuf), "%d", rexmtval);
616	return (optbuf);
617}
618
619/*
620 * Handle the Transfer Size option.
621 * Return the tsize option value string to include in the OACK reply.
622 */
623static char *
624tsize_handler(int opcode, char *optval, int *errcode)
625{
626	char *endp;
627	longlong_t value;
628
629	*errcode = -1;
630	errno = 0;
631	value = strtoll(optval, &endp, 10);
632	if (errno != 0 || value < 0 || *endp != '\0')
633		return (NULL);
634
635	if (opcode == RRQ) {
636		if (tsize_set == B_FALSE)
637			return (NULL);
638		/*
639		 * The tsize value should be 0 for a read request, but to
640		 * support broken clients we don't check that it is.
641		 */
642	} else {
643#if _FILE_OFFSET_BITS == 32
644		if (value > MAXOFF_T) {
645			*errcode = ENOSPACE;
646			return (NULL);
647		}
648#endif
649		tsize = value;
650		tsize_set = B_TRUE;
651	}
652	(void) snprintf(optbuf, sizeof (optbuf), OFF_T_FMT, tsize);
653	return (optbuf);
654}
655
656/*
657 * Process any options included by the client in the request packet.
658 * Return the size of the OACK reply packet built or 0 for no OACK reply.
659 */
660static int
661process_options(int opcode, char *opts, char *endopts)
662{
663	char *cp, *optname, *optval, *ostr, *oackend;
664	struct tftphdr *oackp;
665	int i, errcode;
666
667	/*
668	 * To continue to interoperate with broken TFTP clients, ignore
669	 * null padding appended to requests which don't include options.
670	 */
671	cp = opts;
672	while ((cp < endopts) && (*cp == '\0'))
673		cp++;
674	if (cp == endopts)
675		return (0);
676
677	/*
678	 * Construct an Option ACKnowledgement packet if any requested option
679	 * is recognized.
680	 */
681	oackp = &oackbuf.hdr;
682	oackend = oackbuf.data + sizeof (oackbuf.data);
683	oackp->th_opcode = htons((ushort_t)OACK);
684	cp = (char *)&oackp->th_stuff;
685	while (opts < endopts) {
686		optname = opts;
687		if ((optval = next_field(optname, endopts)) == NULL) {
688			nak(EOPTNEG);
689			exit(1);
690		}
691		if ((opts = next_field(optval, endopts)) == NULL) {
692			nak(EOPTNEG);
693			exit(1);
694		}
695		for (i = 0; options[i].opt_name != NULL; i++) {
696			if (strcasecmp(optname, options[i].opt_name) == 0)
697				break;
698		}
699		if (options[i].opt_name != NULL) {
700			ostr = options[i].opt_handler(opcode, optval, &errcode);
701			if (ostr != NULL) {
702				cp += strlcpy(cp, options[i].opt_name,
703				    oackend - cp) + 1;
704				if (cp <= oackend)
705					cp += strlcpy(cp, ostr, oackend - cp)
706					    + 1;
707
708				if (cp > oackend) {
709					nak(EOPTNEG);
710					exit(1);
711				}
712			} else if (errcode >= 0) {
713				nak(errcode);
714				exit(1);
715			}
716		}
717	}
718	if (cp != (char *)&oackp->th_stuff)
719		return (cp - oackbuf.data);
720	return (0);
721}
722
723/*
724 * Handle access errors caused by client requests.
725 */
726
727static void
728delay_exit(int ecode)
729{
730	struct delay_info dinfo;
731
732	/*
733	 * The most likely cause of an error here is that
734	 * something has broadcast an RRQ packet because it's
735	 * trying to boot and doesn't know who the server is.
736	 * Rather then sending an ERROR packet immediately, we
737	 * wait a while so that the real server has a better chance
738	 * of getting through (in case client has lousy Ethernet
739	 * interface).  We write to a child that handles delayed
740	 * ERROR packets to avoid delaying service to new
741	 * requests.  Of course, we would rather just not answer
742	 * RRQ packets that are broadcasted, but there's no way
743	 * for a user process to determine this.
744	 */
745
746	dinfo.timestamp = time(0);
747
748	/*
749	 * If running in secure mode, we map all errors to EACCESS
750	 * so that the client gets no information about which files
751	 * or directories exist.
752	 */
753	if (securetftp)
754		dinfo.ecode = EACCESS;
755	else
756		dinfo.ecode = ecode;
757
758	dinfo.from = from;
759	if (write(delay_fd[1], &dinfo, sizeof (dinfo)) !=
760	    sizeof (dinfo)) {
761		syslog(LOG_ERR, "delayed write failed.");
762		(void) kill(child, SIGKILL);
763		exit(1);
764	}
765	exit(0);
766}
767
768/*
769 * Handle initial connection protocol.
770 */
771static void
772tftp(struct tftphdr *tp, int size)
773{
774	char *cp;
775	int readmode, ecode;
776	struct formats *pf;
777	char *mode;
778	int fd;
779	static boolean_t firsttime = B_TRUE;
780	int oacklen;
781	struct stat statb;
782
783	readmode = (tp->th_opcode == RRQ);
784	filename = (char *)&tp->th_stuff;
785	mode = next_field(filename, &buf.data[size]);
786	cp = (mode != NULL) ? next_field(mode, &buf.data[size]) : NULL;
787	if (cp == NULL) {
788		nak(EBADOP);
789		exit(1);
790	}
791	if (debug && standalone) {
792		(void) fprintf(stderr, "%s for %s %s ",
793		    readmode ? "RRQ" : "WRQ", filename, mode);
794		print_options(stderr, cp, size + buf.data - cp);
795		(void) putc('\n', stderr);
796	}
797	for (pf = formats; pf->f_mode != NULL; pf++)
798		if (strcasecmp(pf->f_mode, mode) == 0)
799			break;
800	if (pf->f_mode == NULL) {
801		nak(EBADOP);
802		exit(1);
803	}
804
805	/*
806	 * XXX fork a new process to handle this request before
807	 * chroot(), otherwise the parent won't be able to create a
808	 * new socket as that requires library access to system files
809	 * and devices.
810	 */
811	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
812	switch (fork()) {
813	case -1:
814		syslog(LOG_ERR, "fork (tftp): %m");
815		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
816		return;
817	case 0:
818		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
819		break;
820	default:
821		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
822		return;
823	}
824
825	/*
826	 * Try to see if we can access the file.  The access can still
827	 * fail later if we are running in secure mode because of
828	 * the chroot() call.  We only want to execute the chroot()  once.
829	 */
830	if (securetftp && firsttime) {
831		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_CHROOT,
832		    NULL);
833		if (chroot(homedir) == -1) {
834			syslog(LOG_ERR,
835			    "tftpd: cannot chroot to directory %s: %m\n",
836			    homedir);
837			delay_exit(EACCESS);
838		}
839		else
840		{
841			firsttime = B_FALSE;
842		}
843		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_CHROOT,
844		    NULL);
845		(void) chdir("/");  /* cd to  new root */
846	}
847	(void) priv_set(PRIV_OFF, PRIV_ALLSETS, PRIV_PROC_CHROOT,
848	    PRIV_NET_PRIVADDR, NULL);
849
850	ecode = (*pf->f_validate)(tp->th_opcode);
851	if (ecode != 0)
852		delay_exit(ecode);
853
854	/* we don't use the descriptors passed in to the parent */
855	(void) close(STDIN_FILENO);
856	(void) close(STDOUT_FILENO);
857
858	/*
859	 * Try to open file as low-priv setuid/setgid.  Note that
860	 * a chroot() has already been done.
861	 */
862	fd = open(filename,
863	    (readmode ? O_RDONLY : (O_WRONLY|O_TRUNC)) | O_NONBLOCK);
864	if ((fd < 0) || (fstat(fd, &statb) < 0))
865		delay_exit((errno == ENOENT) ? ENOTFOUND : EACCESS);
866
867	if (((statb.st_mode & ((readmode) ? S_IROTH : S_IWOTH)) == 0) ||
868	    ((statb.st_mode & S_IFMT) != S_IFREG))
869		delay_exit(EACCESS);
870
871	file = fdopen(fd, readmode ? "r" : "w");
872	if (file == NULL)
873		delay_exit(errno + 100);
874
875	/* Don't know the size of transfers which involve conversion */
876	tsize_set = (readmode && (pf->f_convert == 0));
877	if (tsize_set)
878		tsize = statb.st_size;
879
880	/* Deal with any options sent by the client */
881	oacklen = process_options(tp->th_opcode, cp, buf.data + size);
882
883	if (tp->th_opcode == WRQ)
884		(*pf->f_recv)(pf, oacklen);
885	else
886		(*pf->f_send)(pf, oacklen);
887
888	exit(0);
889}
890
891/*
892 *	Maybe map filename into another one.
893 *
894 *	For PNP, we get TFTP boot requests for filenames like
895 *	<Unknown Hex IP Addr>.<Architecture Name>.   We must
896 *	map these to 'pnp.<Architecture Name>'.  Note that
897 *	uppercase is mapped to lowercase in the architecture names.
898 *
899 *	For names <Hex IP Addr> there are two cases.  First,
900 *	it may be a buggy prom that omits the architecture code.
901 *	So first check if <Hex IP Addr>.<arch> is on the filesystem.
902 *	Second, this is how most Sun3s work; assume <arch> is sun3.
903 */
904
905static char *
906pnp_check(char *origname)
907{
908	static char buf [MAXNAMLEN + 1];
909	char *arch, *s, *bufend;
910	in_addr_t ipaddr;
911	int len = (origname ? strlen(origname) : 0);
912	DIR *dir;
913	struct dirent *dp;
914
915	if (securetftp || disable_pnp || len < 8 || len > 14)
916		return (NULL);
917
918	/*
919	 * XXX see if this cable allows pnp; if not, return NULL
920	 * Requires YP support for determining this!
921	 */
922
923	ipaddr = htonl(strtol(origname, &arch, 16));
924	if ((arch == NULL) || (len > 8 && *arch != '.'))
925		return (NULL);
926	if (len == 8)
927		arch = "SUN3";
928	else
929		arch++;
930
931	/*
932	 * Allow <Hex IP Addr>* filename request to to be
933	 * satisfied by <Hex IP Addr><Any Suffix> rather
934	 * than enforcing this to be Sun3 systems.  Also serves
935	 * to make case of suffix a don't-care.
936	 */
937	if ((dir = opendir(homedir)) == NULL)
938		return (NULL);
939	while ((dp = readdir(dir)) != NULL) {
940		if (strncmp(origname, dp->d_name, 8) == 0) {
941			(void) strlcpy(buf, dp->d_name, sizeof (buf));
942			(void) closedir(dir);
943			return (buf);
944		}
945	}
946	(void) closedir(dir);
947
948	/*
949	 * XXX maybe call YP master for most current data iff
950	 * pnp is enabled.
951	 */
952
953	/*
954	 * only do mapping PNP boot file name for machines that
955	 * are not in the hosts database.
956	 */
957	if (gethostbyaddr((char *)&ipaddr, sizeof (ipaddr), AF_INET) != NULL)
958		return (NULL);
959
960	s = buf + strlcpy(buf, "pnp.", sizeof (buf));
961	bufend = &buf[sizeof (buf) - 1];
962	while ((*arch != '\0') && (s < bufend))
963		*s++ = tolower (*arch++);
964	*s = '\0';
965	return (buf);
966}
967
968
969/*
970 * Try to validate filename. If the filename doesn't exist try PNP mapping.
971 */
972static int
973validate_filename(int mode)
974{
975	struct stat stbuf;
976	char *origfile;
977
978	if (stat(filename, &stbuf) < 0) {
979		if (errno != ENOENT)
980			return (EACCESS);
981		if (mode == WRQ)
982			return (ENOTFOUND);
983
984		/* try to map requested filename into a pnp filename */
985		origfile = filename;
986		filename = pnp_check(origfile);
987		if (filename == NULL)
988			return (ENOTFOUND);
989
990		if (stat(filename, &stbuf) < 0)
991			return (errno == ENOENT ? ENOTFOUND : EACCESS);
992		syslog(LOG_NOTICE, "%s -> %s\n", origfile, filename);
993	}
994
995	return (0);
996}
997
998/* ARGSUSED */
999static void
1000timer(int signum)
1001{
1002	timeout += rexmtval;
1003	if (timeout >= maxtimeout)
1004		exit(1);
1005	siglongjmp(timeoutbuf, 1);
1006}
1007
1008/*
1009 * Send the requested file.
1010 */
1011static void
1012tftpd_sendfile(struct formats *pf, int oacklen)
1013{
1014	struct tftphdr *dp;
1015	volatile ushort_t block = 1;
1016	int size, n, serrno;
1017
1018	if (oacklen != 0) {
1019		(void) sigset(SIGALRM, timer);
1020		timeout = 0;
1021		(void) sigsetjmp(timeoutbuf, 1);
1022		if (debug && standalone) {
1023			(void) fputs("Sending OACK ", stderr);
1024			print_options(stderr, (char *)&oackbuf.hdr.th_stuff,
1025			    oacklen - 2);
1026			(void) putc('\n', stderr);
1027		}
1028		if (sendto(peer, &oackbuf, oacklen, 0,
1029		    (struct sockaddr *)&from, fromplen) != oacklen) {
1030			if (debug && standalone) {
1031				serrno = errno;
1032				perror("sendto (oack)");
1033				errno = serrno;
1034			}
1035			SYSLOG_MSG("sendto (oack): %m");
1036			goto abort;
1037		}
1038		(void) alarm(rexmtval); /* read the ack */
1039		for (;;) {
1040			(void) sigrelse(SIGALRM);
1041			n = recv(peer, &ackbuf, sizeof (ackbuf), 0);
1042			(void) sighold(SIGALRM);
1043			if (n < 0) {
1044				if (errno == EINTR)
1045					continue;
1046				serrno = errno;
1047				SYSLOG_MSG("recv (ack): %m");
1048				if (debug && standalone) {
1049					errno = serrno;
1050					perror("recv (ack)");
1051				}
1052				goto abort;
1053			}
1054			ackbuf.tb_hdr.th_opcode =
1055			    ntohs((ushort_t)ackbuf.tb_hdr.th_opcode);
1056			ackbuf.tb_hdr.th_block =
1057			    ntohs((ushort_t)ackbuf.tb_hdr.th_block);
1058
1059			if (ackbuf.tb_hdr.th_opcode == ERROR) {
1060				if (debug && standalone) {
1061					(void) fprintf(stderr,
1062					    "received ERROR %d",
1063					    ackbuf.tb_hdr.th_code);
1064					if (n > 4)
1065						(void) fprintf(stderr,
1066						    " %.*s", n - 4,
1067						    ackbuf.tb_hdr.th_msg);
1068					(void) putc('\n', stderr);
1069				}
1070				goto abort;
1071			}
1072
1073			if (ackbuf.tb_hdr.th_opcode == ACK) {
1074				if (debug && standalone)
1075					(void) fprintf(stderr,
1076					    "received ACK for block %d\n",
1077					    ackbuf.tb_hdr.th_block);
1078				if (ackbuf.tb_hdr.th_block == 0)
1079					break;
1080				/*
1081				 * Don't resend the OACK, avoids getting stuck
1082				 * in an OACK/ACK loop if the client keeps
1083				 * replying with a bad ACK. Client will either
1084				 * send a good ACK or timeout sending bad ones.
1085				 */
1086			}
1087		}
1088		cancel_alarm();
1089	}
1090	dp = r_init();
1091	do {
1092		(void) sigset(SIGALRM, timer);
1093		size = readit(file, &dp, pf->f_convert);
1094		if (size < 0) {
1095			nak(errno + 100);
1096			goto abort;
1097		}
1098		dp->th_opcode = htons((ushort_t)DATA);
1099		dp->th_block = htons((ushort_t)block);
1100		timeout = 0;
1101		(void) sigsetjmp(timeoutbuf, 1);
1102		if (debug && standalone)
1103			(void) fprintf(stderr, "Sending DATA block %d\n",
1104			    block);
1105		if (sendto(peer, dp, size + 4, 0,
1106		    (struct sockaddr *)&from,  fromplen) != size + 4) {
1107			if (debug && standalone) {
1108				serrno = errno;
1109				perror("sendto (data)");
1110				errno = serrno;
1111			}
1112			SYSLOG_MSG("sendto (data): %m");
1113			goto abort;
1114		}
1115		read_ahead(file, pf->f_convert);
1116		(void) alarm(rexmtval); /* read the ack */
1117		for (;;) {
1118			(void) sigrelse(SIGALRM);
1119			n = recv(peer, &ackbuf, sizeof (ackbuf), 0);
1120			(void) sighold(SIGALRM);
1121			if (n < 0) {
1122				if (errno == EINTR)
1123					continue;
1124				serrno = errno;
1125				SYSLOG_MSG("recv (ack): %m");
1126				if (debug && standalone) {
1127					errno = serrno;
1128					perror("recv (ack)");
1129				}
1130				goto abort;
1131			}
1132			ackbuf.tb_hdr.th_opcode =
1133			    ntohs((ushort_t)ackbuf.tb_hdr.th_opcode);
1134			ackbuf.tb_hdr.th_block =
1135			    ntohs((ushort_t)ackbuf.tb_hdr.th_block);
1136
1137			if (ackbuf.tb_hdr.th_opcode == ERROR) {
1138				if (debug && standalone) {
1139					(void) fprintf(stderr,
1140					    "received ERROR %d",
1141					    ackbuf.tb_hdr.th_code);
1142					if (n > 4)
1143						(void) fprintf(stderr,
1144						    " %.*s", n - 4,
1145						    ackbuf.tb_hdr.th_msg);
1146					(void) putc('\n', stderr);
1147				}
1148				goto abort;
1149			}
1150
1151			if (ackbuf.tb_hdr.th_opcode == ACK) {
1152				if (debug && standalone)
1153					(void) fprintf(stderr,
1154					    "received ACK for block %d\n",
1155					    ackbuf.tb_hdr.th_block);
1156				if (ackbuf.tb_hdr.th_block == block) {
1157					break;
1158				}
1159				/*
1160				 * Never resend the current DATA packet on
1161				 * receipt of a duplicate ACK, doing so would
1162				 * cause the "Sorcerer's Apprentice Syndrome".
1163				 */
1164			}
1165		}
1166		cancel_alarm();
1167		block++;
1168	} while (size == blocksize);
1169
1170abort:
1171	cancel_alarm();
1172	(void) fclose(file);
1173}
1174
1175/* ARGSUSED */
1176static void
1177justquit(int signum)
1178{
1179	exit(0);
1180}
1181
1182/*
1183 * Receive a file.
1184 */
1185static void
1186tftpd_recvfile(struct formats *pf, int oacklen)
1187{
1188	struct tftphdr *dp;
1189	struct tftphdr *ap;    /* ack buffer */
1190	ushort_t block = 0;
1191	int n, size, acklen, serrno;
1192
1193	dp = w_init();
1194	ap = &ackbuf.tb_hdr;
1195	do {
1196		(void) sigset(SIGALRM, timer);
1197		timeout = 0;
1198		if (oacklen == 0) {
1199			ap->th_opcode = htons((ushort_t)ACK);
1200			ap->th_block = htons((ushort_t)block);
1201			acklen = 4;
1202		} else {
1203			/* copy OACK packet to the ack buffer ready to send */
1204			(void) memcpy(&ackbuf, &oackbuf, oacklen);
1205			acklen = oacklen;
1206			oacklen = 0;
1207		}
1208		block++;
1209		(void) sigsetjmp(timeoutbuf, 1);
1210send_ack:
1211		if (debug && standalone) {
1212			if (ap->th_opcode == htons((ushort_t)ACK)) {
1213				(void) fprintf(stderr,
1214				    "Sending ACK for block %d\n", block - 1);
1215			} else {
1216				(void) fprintf(stderr, "Sending OACK ");
1217				print_options(stderr, (char *)&ap->th_stuff,
1218				    acklen - 2);
1219				(void) putc('\n', stderr);
1220			}
1221		}
1222		if (sendto(peer, &ackbuf, acklen, 0, (struct sockaddr *)&from,
1223		    fromplen) != acklen) {
1224			if (ap->th_opcode == htons((ushort_t)ACK)) {
1225				if (debug && standalone) {
1226					serrno = errno;
1227					perror("sendto (ack)");
1228					errno = serrno;
1229				}
1230				syslog(LOG_ERR, "sendto (ack): %m\n");
1231			} else {
1232				if (debug && standalone) {
1233					serrno = errno;
1234					perror("sendto (oack)");
1235					errno = serrno;
1236				}
1237				syslog(LOG_ERR, "sendto (oack): %m\n");
1238			}
1239			goto abort;
1240		}
1241		if (write_behind(file, pf->f_convert) < 0) {
1242			nak(errno + 100);
1243			goto abort;
1244		}
1245		(void) alarm(rexmtval);
1246		for (;;) {
1247			(void) sigrelse(SIGALRM);
1248			n = recv(peer, dp, blocksize + 4, 0);
1249			(void) sighold(SIGALRM);
1250			if (n < 0) { /* really? */
1251				if (errno == EINTR)
1252					continue;
1253				syslog(LOG_ERR, "recv (data): %m");
1254				goto abort;
1255			}
1256			dp->th_opcode = ntohs((ushort_t)dp->th_opcode);
1257			dp->th_block = ntohs((ushort_t)dp->th_block);
1258			if (dp->th_opcode == ERROR) {
1259				cancel_alarm();
1260				if (debug && standalone) {
1261					(void) fprintf(stderr,
1262					    "received ERROR %d", dp->th_code);
1263					if (n > 4)
1264						(void) fprintf(stderr,
1265						    " %.*s", n - 4, dp->th_msg);
1266					(void) putc('\n', stderr);
1267				}
1268				return;
1269			}
1270			if (dp->th_opcode == DATA) {
1271				if (debug && standalone)
1272					(void) fprintf(stderr,
1273					    "Received DATA block %d\n",
1274					    dp->th_block);
1275				if (dp->th_block == block) {
1276					break;   /* normal */
1277				}
1278				/* Re-synchronize with the other side */
1279				if (synchnet(peer) < 0) {
1280					nak(errno + 100);
1281					goto abort;
1282				}
1283				if (dp->th_block == (block-1))
1284					goto send_ack; /* rexmit */
1285			}
1286		}
1287		cancel_alarm();
1288		/*  size = write(file, dp->th_data, n - 4); */
1289		size = writeit(file, &dp, n - 4, pf->f_convert);
1290		if (size != (n - 4)) {
1291			nak((size < 0) ? (errno + 100) : ENOSPACE);
1292			goto abort;
1293		}
1294	} while (size == blocksize);
1295	if (write_behind(file, pf->f_convert) < 0) {
1296		nak(errno + 100);
1297		goto abort;
1298	}
1299	n = fclose(file);	/* close data file */
1300	file = NULL;
1301	if (n == EOF) {
1302		nak(errno + 100);
1303		goto abort;
1304	}
1305
1306	ap->th_opcode = htons((ushort_t)ACK);    /* send the "final" ack */
1307	ap->th_block = htons((ushort_t)(block));
1308	if (debug && standalone)
1309		(void) fprintf(stderr, "Sending ACK for block %d\n", block);
1310	if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from,
1311	    fromplen) == -1) {
1312		if (debug && standalone)
1313			perror("sendto (ack)");
1314	}
1315	(void) sigset(SIGALRM, justquit); /* just quit on timeout */
1316	(void) alarm(rexmtval);
1317	/* normally times out and quits */
1318	n = recv(peer, dp, blocksize + 4, 0);
1319	(void) alarm(0);
1320	dp->th_opcode = ntohs((ushort_t)dp->th_opcode);
1321	dp->th_block = ntohs((ushort_t)dp->th_block);
1322	if (n >= 4 &&		/* if read some data */
1323	    dp->th_opcode == DATA && /* and got a data block */
1324	    block == dp->th_block) {	/* then my last ack was lost */
1325		if (debug && standalone) {
1326			(void) fprintf(stderr, "Sending ACK for block %d\n",
1327			    block);
1328		}
1329		/* resend final ack */
1330		if (sendto(peer, &ackbuf, 4, 0, (struct sockaddr *)&from,
1331		    fromplen) == -1) {
1332			if (debug && standalone)
1333				perror("sendto (last ack)");
1334		}
1335	}
1336
1337abort:
1338	cancel_alarm();
1339	if (file != NULL)
1340		(void) fclose(file);
1341}
1342
1343/*
1344 * Send a nak packet (error message).
1345 * Error code passed in is one of the
1346 * standard TFTP codes, or a UNIX errno
1347 * offset by 100.
1348 * Handles connected as well as unconnected peer.
1349 */
1350static void
1351nak(int error)
1352{
1353	struct tftphdr *tp;
1354	int length;
1355	struct errmsg *pe;
1356	int ret;
1357
1358	tp = &buf.hdr;
1359	tp->th_opcode = htons((ushort_t)ERROR);
1360	tp->th_code = htons((ushort_t)error);
1361	for (pe = errmsgs; pe->e_code >= 0; pe++)
1362		if (pe->e_code == error)
1363			break;
1364	if (pe->e_code < 0) {
1365		pe->e_msg = strerror(error - 100);
1366		tp->th_code = EUNDEF;   /* set 'undef' errorcode */
1367	}
1368	(void) strlcpy(tp->th_msg, (pe->e_msg != NULL) ? pe->e_msg : "UNKNOWN",
1369	    sizeof (buf) - sizeof (struct tftphdr));
1370	length = strlen(tp->th_msg);
1371	length += sizeof (struct tftphdr);
1372	if (debug && standalone)
1373		(void) fprintf(stderr, "Sending NAK: %s\n", tp->th_msg);
1374
1375	ret = sendto(peer, &buf, length, 0, (struct sockaddr *)&from,
1376	    fromplen);
1377	if (ret == -1 && errno == EISCONN) {
1378		/* Try without an address */
1379		ret = send(peer, &buf, length, 0);
1380	}
1381	if (ret == -1) {
1382		if (standalone)
1383			perror("sendto (nak)");
1384		else
1385			syslog(LOG_ERR, "tftpd: nak: %m\n");
1386	} else if (ret != length) {
1387		if (standalone)
1388			perror("sendto (nak) lost data");
1389		else
1390			syslog(LOG_ERR, "tftpd: nak: %d lost\n", length - ret);
1391	}
1392}
1393