2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 static const char copyright
[] =
36 "@(#) Copyright (c) 1983, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
42 static char sccsid
[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93";
44 static const char rcsid
[] =
49 * Trivial file transfer protocol server.
51 * This version includes many modifications by Jim Guyton
55 #include <sys/param.h>
56 #include <sys/ioctl.h>
58 #include <sys/socket.h>
59 #include <sys/types.h>
62 #include <netinet/in.h>
63 #include <arpa/tftp.h>
64 #include <arpa/inet.h>
83 #define MAX_TIMEOUTS 5
86 int rexmtval
= TIMEOUT
;
87 int max_rexmtval
= 2*TIMEOUT
;
89 #define PKTSIZE SEGSIZE+4
92 struct sockaddr_storage from
;
94 void tftp(struct tftphdr
*, int);
95 static void unmappedaddr(struct sockaddr_in6
*);
98 * Null-terminated directory prefix list for absolute pathname requests and
99 * search list for relative pathname requests.
101 * MAXDIRS should be at least as large as the number of arguments that
102 * inetd allows (currently 20).
105 static struct dirlist
{
109 static int suppress_naks
;
112 static int create_new
= 0;
113 static char *newfile_format
= "%Y%m%d";
114 static int increase_name
= 0;
115 static mode_t mask
= S_IWGRP
|S_IWOTH
;
117 static const char *errtomsg(int);
118 static void nak(int);
119 static void oack(void);
121 static void timer(int);
122 static void justquit(int);
125 main(int argc
, char *argv
[])
128 socklen_t fromlen
, len
;
131 struct sockaddr_storage me
;
132 char *chroot_dir
= NULL
;
133 struct passwd
*nobody
;
134 const char *chuser
= "nobody";
136 tzset(); /* syslog in localtime */
138 openlog("tftpd", LOG_PID
| LOG_NDELAY
, LOG_FTP
);
139 while ((ch
= getopt(argc
, argv
, "cCF:lns:u:U:wW")) != -1) {
148 newfile_format
= optarg
;
163 mask
= strtol(optarg
, NULL
, 0);
173 syslog(LOG_WARNING
, "ignoring unknown option -%c", ch
);
177 struct dirlist
*dirp
;
179 /* Get list of directory prefixes. Skip relative pathnames. */
180 for (dirp
= dirs
; optind
< argc
&& dirp
< &dirs
[MAXDIRS
];
182 if (argv
[optind
][0] == '/') {
183 dirp
->name
= argv
[optind
];
184 dirp
->len
= strlen(dirp
->name
);
189 else if (chroot_dir
) {
193 if (ipchroot
> 0 && chroot_dir
== NULL
) {
194 syslog(LOG_ERR
, "-c requires -s");
201 if (ioctl(0, FIONBIO
, &on
) < 0) {
202 syslog(LOG_ERR
, "ioctl(FIONBIO): %m");
205 fromlen
= sizeof (from
);
206 n
= recvfrom(0, buf
, sizeof (buf
), 0,
207 (struct sockaddr
*)&from
, &fromlen
);
209 syslog(LOG_ERR
, "recvfrom: %m");
213 * Now that we have read the message out of the UDP
214 * socket, we fork and exit. Thus, inetd will go back
215 * to listening to the tftp port, and the next request
216 * to come in will start up a new instance of tftpd.
218 * We do this so that inetd can run tftpd in "wait" mode.
219 * The problem with tftpd running in "nowait" mode is that
220 * inetd may get one or more successful "selects" on the
221 * tftp port before we do our receive, so more than one
222 * instance of tftpd may be started up. Worse, if tftpd
223 * break before doing the above "recvfrom", inetd would
224 * spawn endless instances, clogging the system.
229 for (i
= 1; i
< 20; i
++) {
234 * flush out to most recently sent request.
236 * This may drop some request, but those
237 * will be resent by the clients when
238 * they timeout. The positive effect of
239 * this flush is to (try to) prevent more
240 * than one tftpd being started up to service
241 * a single request from a single client.
243 fromlen
= sizeof from
;
244 i
= recvfrom(0, buf
, sizeof (buf
), 0,
245 (struct sockaddr
*)&from
, &fromlen
);
254 syslog(LOG_ERR
, "fork: %m");
256 } else if (pid
!= 0) {
262 * Since we exit here, we should do that only after the above
263 * recvfrom to keep inetd from constantly forking should there
264 * be a problem. See the above comment about system clogging.
271 struct sockaddr_storage ss
;
272 char hbuf
[NI_MAXHOST
];
274 memcpy(&ss
, &from
, from
.ss_len
);
275 unmappedaddr((struct sockaddr_in6
*)&ss
);
276 getnameinfo((struct sockaddr
*)&ss
, ss
.ss_len
,
277 hbuf
, sizeof(hbuf
), NULL
, 0,
279 asprintf(&tempchroot
, "%s/%s", chroot_dir
, hbuf
);
281 statret
= stat(tempchroot
, &sb
);
283 (statret
== 0 && (sb
.st_mode
& S_IFDIR
)))
284 chroot_dir
= tempchroot
;
286 /* Must get this before chroot because /etc might go away */
287 if ((nobody
= getpwnam(chuser
)) == NULL
) {
288 syslog(LOG_ERR
, "%s: no such user", chuser
);
291 if (chroot(chroot_dir
)) {
292 syslog(LOG_ERR
, "chroot: %s: %m", chroot_dir
);
296 setgroups(1, &nobody
->pw_gid
);
297 setuid(nobody
->pw_uid
);
301 if (getsockname(0, (struct sockaddr
*)&me
, &len
) == 0) {
302 switch (me
.ss_family
) {
304 ((struct sockaddr_in
*)&me
)->sin_port
= 0;
307 ((struct sockaddr_in6
*)&me
)->sin6_port
= 0;
314 memset(&me
, 0, sizeof(me
));
315 me
.ss_family
= from
.ss_family
;
316 me
.ss_len
= from
.ss_len
;
321 peer
= socket(from
.ss_family
, SOCK_DGRAM
, 0);
323 syslog(LOG_ERR
, "socket: %m");
326 if (bind(peer
, (struct sockaddr
*)&me
, me
.ss_len
) < 0) {
327 syslog(LOG_ERR
, "bind: %m");
330 if (connect(peer
, (struct sockaddr
*)&from
, from
.ss_len
) < 0) {
331 syslog(LOG_ERR
, "connect: %m");
334 tp
= (struct tftphdr
*)buf
;
335 tp
->th_opcode
= ntohs(tp
->th_opcode
);
336 if (tp
->th_opcode
== RRQ
|| tp
->th_opcode
== WRQ
)
342 reduce_path(char *fn
)
346 /* Reduce all "/+./" to "/" (just in case we've got "/./../" later */
347 while ((slash
= strstr(fn
, "/./")) != NULL
) {
348 for (ptr
= slash
; ptr
> fn
&& ptr
[-1] == '/'; ptr
--)
355 /* Now reduce all "/something/+../" to "/" */
356 while ((slash
= strstr(fn
, "/../")) != NULL
) {
359 for (ptr
= slash
; ptr
> fn
&& ptr
[-1] == '/'; ptr
--)
361 for (ptr
--; ptr
>= fn
; ptr
--)
373 int validate_access(char **, int);
374 void xmitfile(struct formats
*);
375 void recvfile(struct formats
*);
379 int (*f_validate
)(char **, int);
380 void (*f_send
)(struct formats
*);
381 void (*f_recv
)(struct formats
*);
384 { "netascii", validate_access
, xmitfile
, recvfile
, 1 },
385 { "octet", validate_access
, xmitfile
, recvfile
, 0 },
387 { "mail", validate_user
, sendmail
, recvmail
, 1 },
389 { 0, NULL
, NULL
, NULL
, 0 }
395 int o_reply
; /* turn into union if need be */
397 { "tsize", NULL
, 0 }, /* OPT_TSIZE */
398 { "timeout", NULL
, 0 }, /* OPT_TIMEOUT */
408 * Handle initial connection protocol.
411 tftp(struct tftphdr
*tp
, int size
)
414 int i
, first
= 1, has_options
= 0, ecode
;
416 char *filename
, *mode
, *option
, *ccp
;
417 char fnbuf
[PATH_MAX
];
421 while (cp
< buf
+ size
) {
430 i
= cp
- tp
->th_stuff
;
431 if (i
>= sizeof(fnbuf
)) {
435 memcpy(fnbuf
, tp
->th_stuff
, i
);
444 for (cp
= mode
; *cp
; cp
++)
447 for (pf
= formats
; pf
->f_mode
; pf
++)
448 if (strcmp(pf
->f_mode
, mode
) == 0)
450 if (pf
->f_mode
== 0) {
454 while (++cp
< buf
+ size
) {
455 for (i
= 2, ccp
= cp
; i
> 0; ccp
++) {
456 if (ccp
>= buf
+ size
) {
458 * Don't reject the request, just stop trying
459 * to parse the option and get on with it.
460 * Some Apple Open Firmware versions have
461 * trailing garbage on the end of otherwise
465 } else if (*ccp
== '\0')
468 for (option
= cp
; *cp
; cp
++)
471 for (i
= 0; options
[i
].o_type
!= NULL
; i
++)
472 if (strcmp(option
, options
[i
].o_type
) == 0) {
473 options
[i
].o_request
= ++cp
;
480 if (options
[OPT_TIMEOUT
].o_request
) {
481 int to
= atoi(options
[OPT_TIMEOUT
].o_request
);
482 if (to
< 1 || to
> 255) {
486 else if (to
<= max_rexmtval
)
487 options
[OPT_TIMEOUT
].o_reply
= rexmtval
= to
;
489 options
[OPT_TIMEOUT
].o_request
= NULL
;
492 ecode
= (*pf
->f_validate
)(&filename
, tp
->th_opcode
);
493 if (has_options
&& ecode
== 0)
496 char hbuf
[NI_MAXHOST
];
498 getnameinfo((struct sockaddr
*)&from
, from
.ss_len
,
499 hbuf
, sizeof(hbuf
), NULL
, 0, 0);
500 syslog(LOG_INFO
, "%s: %s request for %s: %s", hbuf
,
501 tp
->th_opcode
== WRQ
? "write" : "read",
502 filename
, errtomsg(ecode
));
506 * Avoid storms of naks to a RRQ broadcast for a relative
507 * bootfile pathname from a diskless Sun.
509 if (suppress_naks
&& *filename
!= '/' && ecode
== ENOTFOUND
)
514 if (tp
->th_opcode
== WRQ
)
525 * Find the next value for YYYYMMDD.nn when the file to be written should
526 * be unique. Due to the limitations of nn, we will fail if nn reaches 100.
527 * Besides, that is four updates per hour on a file, which is kind of
531 find_next_name(char *filename
, int *fd
)
537 char yyyymmdd
[MAXPATHLEN
];
538 char newname
[MAXPATHLEN
];
542 /* Create the YYYYMMDD part of the filename */
544 lt
= *localtime(&tval
);
545 len
= strftime(yyyymmdd
, sizeof(yyyymmdd
), newfile_format
, <
);
548 "Filename suffix too long (%d characters maximum)",
553 /* Make sure the new filename is not too long */
554 if (strlen(filename
) > MAXPATHLEN
- len
- 5) {
556 "Filename too long (%d characters, %d maximum)",
557 strlen(filename
), MAXPATHLEN
- len
- 5);
561 /* Find the first file which doesn't exist */
562 for (i
= 0; i
< 100; i
++) {
563 sprintf(newname
, "%s.%s.%02d", filename
, yyyymmdd
, i
);
565 O_WRONLY
| O_CREAT
| O_EXCL
,
566 S_IRUSR
| S_IWUSR
| S_IRGRP
|
567 S_IWGRP
| S_IROTH
| S_IWOTH
);
576 * Validate file access. Since we
577 * have no uid or gid, for now require
578 * file to exist and be publicly
580 * If we were invoked with arguments
581 * from inetd then the file must also be
582 * in one of the given directory prefixes.
583 * Note also, full path name must be
584 * given as we have no login directory.
587 validate_access(char **filep
, int mode
)
592 struct dirlist
*dirp
;
593 static char pathname
[MAXPATHLEN
];
594 char *filename
= *filep
;
597 * Prevent tricksters from getting around the directory restrictions
599 if (strstr(filename
, "/../"))
602 if (*filename
== '/') {
604 * Allow the request if it's in one of the approved locations.
605 * Special case: check the null prefix ("/") by looking
606 * for length = 1 and relying on the arg. processing that
609 for (dirp
= dirs
; dirp
->name
!= NULL
; dirp
++) {
610 if (dirp
->len
== 1 ||
611 (!strncmp(filename
, dirp
->name
, dirp
->len
) &&
612 filename
[dirp
->len
] == '/'))
615 /* If directory list is empty, allow access to any file */
616 if (dirp
->name
== NULL
&& dirp
!= dirs
)
618 if (stat(filename
, &stbuf
) < 0)
619 return (errno
== ENOENT
? ENOTFOUND
: EACCESS
);
620 if ((stbuf
.st_mode
& S_IFMT
) != S_IFREG
)
623 if ((stbuf
.st_mode
& S_IROTH
) == 0)
626 if ((stbuf
.st_mode
& S_IWOTH
) == 0)
633 * Relative file name: search the approved locations for it.
634 * Don't allow write requests that avoid directory
638 if (!strncmp(filename
, "../", 3))
642 * If the file exists in one of the directories and isn't
643 * readable, continue looking. However, change the error code
644 * to give an indication that the file exists.
647 for (dirp
= dirs
; dirp
->name
!= NULL
; dirp
++) {
648 snprintf(pathname
, sizeof(pathname
), "%s/%s",
649 dirp
->name
, filename
);
650 if (stat(pathname
, &stbuf
) == 0 &&
651 (stbuf
.st_mode
& S_IFMT
) == S_IFREG
) {
652 if ((stbuf
.st_mode
& S_IROTH
) != 0) {
658 if (dirp
->name
!= NULL
)
659 *filep
= filename
= pathname
;
660 else if (mode
== RRQ
)
663 if (options
[OPT_TSIZE
].o_request
) {
665 options
[OPT_TSIZE
].o_reply
= stbuf
.st_size
;
667 /* XXX Allows writes of all sizes. */
668 options
[OPT_TSIZE
].o_reply
=
669 atoi(options
[OPT_TSIZE
].o_request
);
672 fd
= open(filename
, O_RDONLY
);
676 error
= find_next_name(filename
, &fd
);
678 return (error
+ 100);
681 O_WRONLY
| O_TRUNC
| O_CREAT
,
682 S_IRUSR
| S_IWUSR
| S_IRGRP
|
683 S_IWGRP
| S_IROTH
| S_IWOTH
);
685 fd
= open(filename
, O_WRONLY
| O_TRUNC
);
688 return (errno
+ 100);
689 file
= fdopen(fd
, (mode
== RRQ
)? "r":"w");
692 return (errno
+ 100);
701 timer(int sig __unused
)
703 if (++timeouts
> MAX_TIMEOUTS
)
705 longjmp(timeoutbuf
, 1);
709 * Send the requested file.
712 xmitfile(struct formats
*pf
)
715 struct tftphdr
*ap
; /* ack packet */
717 volatile unsigned short block
;
719 signal(SIGALRM
, timer
);
721 ap
= (struct tftphdr
*)ackbuf
;
724 size
= readit(file
, &dp
, pf
->f_convert
);
729 dp
->th_opcode
= htons((u_short
)DATA
);
730 dp
->th_block
= htons((u_short
)block
);
732 (void)setjmp(timeoutbuf
);
738 if (send(peer
, dp
, size
+ 4, 0) != size
+ 4) {
740 t
= (t
< 32) ? t
<< 1 : t
;
742 syslog(LOG_ERR
, "write: %m");
749 read_ahead(file
, pf
->f_convert
);
751 alarm(rexmtval
); /* read the ack */
752 n
= recv(peer
, ackbuf
, sizeof (ackbuf
), 0);
755 syslog(LOG_ERR
, "read: %m");
758 ap
->th_opcode
= ntohs((u_short
)ap
->th_opcode
);
759 ap
->th_block
= ntohs((u_short
)ap
->th_block
);
761 if (ap
->th_opcode
== ERROR
)
764 if (ap
->th_opcode
== ACK
) {
765 if (ap
->th_block
== block
)
767 /* Re-synchronize with the other side */
768 (void) synchnet(peer
);
769 if (ap
->th_block
== (block
-1))
775 } while (size
== SEGSIZE
);
781 justquit(int sig __unused
)
791 recvfile(struct formats
*pf
)
794 struct tftphdr
*ap
; /* ack buffer */
796 volatile unsigned short block
;
798 signal(SIGALRM
, timer
);
800 ap
= (struct tftphdr
*)ackbuf
;
804 ap
->th_opcode
= htons((u_short
)ACK
);
805 ap
->th_block
= htons((u_short
)block
);
807 (void) setjmp(timeoutbuf
);
809 if (send(peer
, ackbuf
, 4, 0) != 4) {
810 syslog(LOG_ERR
, "write: %m");
813 write_behind(file
, pf
->f_convert
);
816 n
= recv(peer
, dp
, PKTSIZE
, 0);
818 if (n
< 0) { /* really? */
819 syslog(LOG_ERR
, "read: %m");
822 dp
->th_opcode
= ntohs((u_short
)dp
->th_opcode
);
823 dp
->th_block
= ntohs((u_short
)dp
->th_block
);
824 if (dp
->th_opcode
== ERROR
)
826 if (dp
->th_opcode
== DATA
) {
827 if (dp
->th_block
== block
) {
830 /* Re-synchronize with the other side */
831 (void) synchnet(peer
);
832 if (dp
->th_block
== (block
-1))
833 goto send_ack
; /* rexmit */
836 /* size = write(file, dp->th_data, n - 4); */
837 size
= writeit(file
, &dp
, n
- 4, pf
->f_convert
);
838 if (size
!= (n
-4)) { /* ahem */
839 if (size
< 0) nak(errno
+ 100);
843 } while (size
== SEGSIZE
);
844 write_behind(file
, pf
->f_convert
);
845 (void) fclose(file
); /* close data file */
847 ap
->th_opcode
= htons((u_short
)ACK
); /* send the "final" ack */
848 ap
->th_block
= htons((u_short
)(block
));
849 (void) send(peer
, ackbuf
, 4, 0);
851 signal(SIGALRM
, justquit
); /* just quit on timeout */
853 n
= recv(peer
, buf
, sizeof (buf
), 0); /* normally times out and quits */
855 if (n
>= 4 && /* if read some data */
856 dp
->th_opcode
== DATA
&& /* and got a data block */
857 block
== dp
->th_block
) { /* then my last ack was lost */
858 (void) send(peer
, ackbuf
, 4, 0); /* resend final ack */
868 { EUNDEF
, "Undefined error code" },
869 { ENOTFOUND
, "File not found" },
870 { EACCESS
, "Access violation" },
871 { ENOSPACE
, "Disk full or allocation exceeded" },
872 { EBADOP
, "Illegal TFTP operation" },
873 { EBADID
, "Unknown transfer ID" },
874 { EEXISTS
, "File already exists" },
875 { ENOUSER
, "No such user" },
876 { EOPTNEG
, "Option negotiation" },
883 static char ebuf
[20];
887 for (pe
= errmsgs
; pe
->e_code
>= 0; pe
++)
888 if (pe
->e_code
== error
)
890 snprintf(ebuf
, sizeof(buf
), "error %d", error
);
895 * Send a nak packet (error message).
896 * Error code passed in is one of the
897 * standard TFTP codes, or a UNIX errno
907 tp
= (struct tftphdr
*)buf
;
908 tp
->th_opcode
= htons((u_short
)ERROR
);
909 tp
->th_code
= htons((u_short
)error
);
910 for (pe
= errmsgs
; pe
->e_code
>= 0; pe
++)
911 if (pe
->e_code
== error
)
913 if (pe
->e_code
< 0) {
914 pe
->e_msg
= strerror(error
- 100);
915 tp
->th_code
= EUNDEF
; /* set 'undef' errorcode */
917 strcpy(tp
->th_msg
, pe
->e_msg
);
918 length
= strlen(pe
->e_msg
);
919 tp
->th_msg
[length
] = '\0';
921 if (send(peer
, buf
, length
, 0) != length
)
922 syslog(LOG_ERR
, "nak: %m");
925 /* translate IPv4 mapped IPv6 address to IPv4 address */
927 unmappedaddr(struct sockaddr_in6
*sin6
)
929 struct sockaddr_in
*sin4
;
933 if (sin6
->sin6_family
!= AF_INET6
||
934 !IN6_IS_ADDR_V4MAPPED(&sin6
->sin6_addr
))
936 sin4
= (struct sockaddr_in
*)sin6
;
937 addr
= *(u_int32_t
*)&sin6
->sin6_addr
.s6_addr
[12];
938 port
= sin6
->sin6_port
;
939 memset(sin4
, 0, sizeof(struct sockaddr_in
));
940 sin4
->sin_addr
.s_addr
= addr
;
941 sin4
->sin_port
= port
;
942 sin4
->sin_family
= AF_INET
;
943 sin4
->sin_len
= sizeof(struct sockaddr_in
);
947 * Send an oack packet (option acknowledgement).
952 struct tftphdr
*tp
, *ap
;
956 tp
= (struct tftphdr
*)buf
;
958 size
= sizeof(buf
) - 2;
959 tp
->th_opcode
= htons((u_short
)OACK
);
960 for (i
= 0; options
[i
].o_type
!= NULL
; i
++) {
961 if (options
[i
].o_request
) {
962 n
= snprintf(bp
, size
, "%s%c%d", options
[i
].o_type
,
963 0, options
[i
].o_reply
);
967 syslog(LOG_ERR
, "oack: buffer overflow");
973 ap
= (struct tftphdr
*)ackbuf
;
974 signal(SIGALRM
, timer
);
977 (void)setjmp(timeoutbuf
);
978 if (send(peer
, buf
, size
, 0) != size
) {
979 syslog(LOG_INFO
, "oack: %m");
985 n
= recv(peer
, ackbuf
, sizeof (ackbuf
), 0);
988 syslog(LOG_ERR
, "recv: %m");
991 ap
->th_opcode
= ntohs((u_short
)ap
->th_opcode
);
992 ap
->th_block
= ntohs((u_short
)ap
->th_block
);
993 if (ap
->th_opcode
== ERROR
)
995 if (ap
->th_opcode
== ACK
&& ap
->th_block
== 0)