--- netkit-tftp-0.17.orig/MRULES +++ netkit-tftp-0.17/MRULES @@ -1,8 +1,8 @@ # Standard compilation rules (don't use make builtins) %.o: %.c - $(CC) $(CFLAGS) -I../include $< -c + $(CC) $(CFLAGS) $< -c %.o: %.cc - $(CC) $(CFLAGS) -I../include $< -c + $(CC) $(CFLAGS) $< -c --- netkit-tftp-0.17.orig/tftpd/tftpd.c +++ netkit-tftp-0.17/tftpd/tftpd.c @@ -89,28 +89,44 @@ static char buf[PKTSIZE]; static char ackbuf[PKTSIZE]; -static struct sockaddr_in from; +static struct sockaddr_storage from; static socklen_t fromlen; -#define MAXARG 4 -static char *dirs[MAXARG+1]; +static const char *default_dirs[] = { "/tftpboot", 0 }; +static const char **dirs = default_dirs; + +static int suppress_naks; +static int secure_tftp; int main(int ac, char **av) { - struct sockaddr_in sn; + struct sockaddr_storage sn; socklen_t snsize; int dobind=1; register struct tftphdr *tp; register int n = 0; int on = 1; + int ch; - ac--; av++; - if (ac==0) dirs[0] = "/tftpboot"; /* default directory */ - while (ac-- > 0 && n < MAXARG) - dirs[n++] = *av++; openlog("tftpd", LOG_PID, LOG_DAEMON); + opterr = 0; + while ((ch = getopt(ac, av, "ns")) != EOF) { + switch (ch) { + case 'n': + suppress_naks = 1; + break; + case 's': + secure_tftp = 1; + break; + default: + syslog(LOG_ERR, "unknown option -%c", ch); + exit(1); + } + } + + if (av[optind]) dirs = (const char **) &av[optind]; if (ioctl(0, FIONBIO, &on) < 0) { syslog(LOG_ERR, "ioctl(FIONBIO): %m\n"); exit(1); @@ -157,7 +173,7 @@ */ k = sizeof(from); i = recvfrom(0, buf, sizeof (buf), 0, - (struct sockaddr *)&from, &k); + (struct sockaddr *)&from, &k); if (i > 0) { n = i; fromlen = k; @@ -186,7 +202,6 @@ exit(1); } } - from.sin_family = AF_INET; alarm(0); /* @@ -197,15 +212,33 @@ * interface. */ snsize = sizeof(sn); - if (getsockname(0, (struct sockaddr *)&sn, &snsize)<0 || - sn.sin_addr.s_addr == INADDR_ANY) { + if (getsockname(0, (struct sockaddr *)&sn, &snsize) < 0) { dobind = 0; } - sn.sin_port = 0; + + if ( dobind ) { + /* Was the wildcard address contained in the socket? */ + if ( ((sn.ss_family == AF_INET) && + ((struct sockaddr_in *)&sn)->sin_addr.s_addr + == INADDR_ANY ) + || ((sn.ss_family == AF_INET6) && + IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)&sn)->sin6_addr)) + ) + { + /* Implicit binding suffices for wildcard addresses. */ + dobind = 0; + } + } + + if ( sn.ss_family == AF_INET ) + ((struct sockaddr_in *) &sn)->sin_port = 0; + else if ( sn.ss_family == AF_INET6 ) + ((struct sockaddr_in6 *) &sn)->sin6_port = 0; close(0); close(1); - peer = socket(AF_INET, SOCK_DGRAM, 0); + + peer = socket(from.ss_family, SOCK_DGRAM, 0); if (peer < 0) { syslog(LOG_ERR, "socket: %m\n"); exit(1); @@ -279,6 +312,12 @@ } ecode = (*pf->f_validate)(filename, tp->th_opcode); if (ecode) { + /* + * Avoid storms of naks to a RRQ broadcast for a relative + * bootfile pathname from a diskless Sun. + */ + if (suppress_naks && *filename != '/' && ecode == ENOTFOUND) + exit(0); nak(ecode); exit(1); } @@ -310,13 +349,17 @@ struct stat stbuf; int fd; const char *cp; - char **dirp; + const char **dirp; syslog(LOG_NOTICE, "tftpd: trying to get file: %s\n", filename); - if (*filename != '/') { + if (*filename != '/' || secure_tftp) { syslog(LOG_NOTICE, "tftpd: serving file from %s\n", dirs[0]); - chdir(dirs[0]); + /*chdir(dirs[0]);*/ + if ( chdir(dirs[0]) < 0 ) + return (EACCESS); + while (*filename == '/') + filename++; } else { for (dirp = dirs; *dirp; dirp++) if (strncmp(filename, *dirp, strlen(*dirp)) == 0) @@ -340,8 +383,11 @@ return(EACCESS); } } - if (stat(filename, &stbuf) < 0) - return (errno == ENOENT ? ENOTFOUND : EACCESS); + if (stat(filename, &stbuf) < 0) { + if (mode != WRQ) { + return (errno == ENOENT ? ENOTFOUND : EACCESS); + } + } #if 0 /* * The idea is that symlinks are dangerous. However, a symlink @@ -366,7 +412,8 @@ if ((stbuf.st_mode & S_IWOTH) == 0) return (EACCESS); } - fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY|O_TRUNC); + + fd = open(filename, mode == RRQ ? O_RDONLY : O_WRONLY|O_TRUNC|O_CREAT, 0600); if (fd < 0) return (errno + 100); file = fdopen(fd, (mode == RRQ)? "r":"w"); @@ -441,7 +488,7 @@ break; } /* Re-synchronize with the other side */ - (void) synchnet(peer); + (void) synchnet(peer, 0); if (ap->th_block == (block -1)) { goto send_data; } @@ -506,7 +553,7 @@ break; /* normal */ } /* Re-synchronize with the other side */ - (void) synchnet(peer); + (void) synchnet(peer, 0); if (dp->th_block == (block-1)) goto send_ack; /* rexmit */ } --- netkit-tftp-0.17.orig/tftpd/tftpd.8 +++ netkit-tftp-0.17/tftpd/tftpd.8 @@ -42,6 +42,8 @@ Trivial File Transfer Protocol server .Sh SYNOPSIS .Nm tftpd +.Op Fl n +.Op Fl s .Op Ar directory ... .Sh DESCRIPTION .Nm Tftpd @@ -111,6 +113,18 @@ can be used to ensure that replies go out from the correct address. These considerations are important, because most tftp clients will reject reply packets that appear to come from an unexpected address. +.Pp +The options are: +.Bl -tag -width Ds +.It Fl n +Suppresses negative acknowledgement of requests for nonexistent relative +filenames. +.It Fl s +All absolute filenames are treated as if they were preceded by the first +directory argument, or +.Pa /tftpboot +if there is none. +.El .Sh SEE ALSO .Xr tftp 1 , .Xr inetd 8 --- netkit-tftp-0.17.orig/tftpd/Makefile +++ netkit-tftp-0.17/tftpd/Makefile @@ -17,7 +17,7 @@ tftpd.o: ../version.h install: tftpd - install -s -m$(DAEMONMODE) tftpd $(INSTALLROOT)$(SBINDIR)/in.tftpd + install -m$(DAEMONMODE) tftpd $(INSTALLROOT)$(SBINDIR)/in.tftpd install -m$(MANMODE) tftpd.8 $(INSTALLROOT)$(MANDIR)/man8/in.tftpd.8 ln -sf in.tftpd.8 $(INSTALLROOT)$(MANDIR)/man8/tftpd.8 --- netkit-tftp-0.17.orig/tftp/tftp.c +++ netkit-tftp-0.17/tftp/tftp.c @@ -61,7 +61,8 @@ #include "../version.h" -extern struct sockaddr_in s_inn; /* filled in by main */ +extern struct sockaddr_storage s_inn; /* filled in by main */ +extern socklen_t s_inn_len; extern int f; /* the opened socket */ extern int trace; extern int verbose; @@ -71,6 +72,8 @@ void sendfile(int fd, char *name, char *modestr); void recvfile(int fd, char *name, char *modestr); +static struct sockaddr_storage from; /* most recent remote address */ +static socklen_t fromlen; static char ackbuf[PKTSIZE]; static int timeout; @@ -111,8 +114,6 @@ volatile u_int16_t block = 0; int n; volatile unsigned long amount = 0; - struct sockaddr_in from; - socklen_t fromlen; volatile int convert; /* true if doing nl->crlf conversion */ FILE *file; volatile int firsttrip = 1; @@ -123,6 +124,9 @@ file = fdopen(fd, "r"); convert = !strcmp(mode, "netascii"); + memcpy(&from, &s_inn, sizeof(from)); + fromlen = s_inn_len; + mysignal(SIGALRM, timer); do { if (firsttrip) { @@ -143,8 +147,8 @@ send_data: if (trace) tpacket("sent", dp, size + 4); - n = sendto(f, dp, size + 4, 0, - (struct sockaddr *)&s_inn, sizeof(s_inn)); + + n = sendto(f, dp, size + 4, 0, (struct sockaddr *)&from, fromlen); if (n != size + 4) { perror("tftp: sendto"); goto abort; @@ -162,7 +166,7 @@ perror("tftp: recvfrom"); goto abort; } - s_inn.sin_port = from.sin_port; /* added */ + if (trace) tpacket("received", ap, n); /* should verify packet came from server */ @@ -174,19 +178,13 @@ goto abort; } if (ap->th_opcode == ACK) { - volatile int j = 0; - if (ap->th_block == block) { break; } /* On an error, try to synchronize * both sides. */ - j = synchnet(f); - if (j && trace) { - printf("discarded %d packets\n", - j); - } + synchnet(f, trace); if (ap->th_block == (block-1)) { goto send_data; } @@ -197,14 +195,18 @@ } else { amount += size; + if (size != SEGSIZE) { + break; + } } block++; - } while (size == SEGSIZE); + } while (1); abort: fclose(file); stopclock(); if (amount > 0) printstats("Sent", amount); + initsock(from.ss_family); /* Synchronize address family. */ } /* @@ -219,8 +221,6 @@ volatile u_int16_t block = 1; int n; volatile unsigned long amount = 0; - struct sockaddr_in from; - socklen_t fromlen; volatile int firsttrip = 1; FILE *file; volatile int convert; /* true if converting crlf -> lf */ @@ -231,6 +231,9 @@ file = fdopen(fd, "w"); convert = !strcmp(mode, "netascii"); + memcpy(&from, &s_inn, sizeof(from)); + fromlen = s_inn_len; + mysignal(SIGALRM, timer); do { if (firsttrip) { @@ -247,8 +250,9 @@ send_ack: if (trace) tpacket("sent", ap, size); - if (sendto(f, ackbuf, size, 0, (struct sockaddr *)&s_inn, - sizeof (s_inn)) != size) { + + n = sendto(f, ackbuf, size, 0, (struct sockaddr *)&from, fromlen); + if ( n != size) { alarm(0); perror("tftp: sendto"); goto abort; @@ -266,7 +270,7 @@ perror("tftp: recvfrom"); goto abort; } - s_inn.sin_port = from.sin_port; /* added */ + if (trace) tpacket("received", dp, n); /* should verify client address */ @@ -278,18 +282,13 @@ goto abort; } if (dp->th_opcode == DATA) { - volatile int j = 0; - if (dp->th_block == block) { break; /* have next packet */ } /* On an error, try to synchronize * both sides. */ - j = synchnet(f); - if (j && trace) { - printf("discarded %d packets\n", j); - } + synchnet(f, trace); if (dp->th_block == (block-1)) { goto send_ack; /* resend ack */ } @@ -303,29 +302,35 @@ } amount += size; } while (size == SEGSIZE); -abort: /* ok to ack, since user */ + ap->th_opcode = htons((u_short)ACK); /* has seen err msg */ ap->th_block = htons((u_short)block); - (void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&s_inn, sizeof(s_inn)); + (void) sendto(f, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen); + +abort: write_behind(file, convert); /* flush last buffer */ fclose(file); stopclock(); if (amount > 0) printstats("Received", amount); + initsock(from.ss_family); /* Synchronize address family. */ } int makerequest(int request, char *name, struct tftphdr *tp, char *mode) { register char *cp; + int len; tp->th_opcode = htons((u_short)request); cp = tp->th_stuff; - strcpy(cp, name); - cp += strlen(name); + len = strlen(name); + memcpy(cp, name, len); + cp += len; *cp++ = '\0'; - strcpy(cp, mode); - cp += strlen(mode); + len = strlen(mode); + memcpy(cp, mode, len); + cp += len; *cp++ = '\0'; return (cp - (char *)tp); } @@ -372,8 +377,8 @@ length = strlen(pe->e_msg) + 4; if (trace) tpacket("sent", tp, length); - if (sendto(f, ackbuf, length, 0, (struct sockaddr *)&s_inn, - sizeof (s_inn)) != length) + if (sendto(f, ackbuf, length, 0, (struct sockaddr *)&from, fromlen) + != length) perror("nak"); } --- netkit-tftp-0.17.orig/tftp/tftp.1 +++ netkit-tftp-0.17/tftp/tftp.1 @@ -84,7 +84,7 @@ protocol, unlike the .Tn FTP protocol, -does not maintain connections betweeen transfers; thus, the +does not maintain connections betwen transfers; thus, the .Cm connect command does not actually create a connection, but merely remembers what host is to be used for transfers. --- netkit-tftp-0.17.orig/tftp/tftpsubs.c +++ netkit-tftp-0.17/tftp/tftpsubs.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #ifndef FIONREAD @@ -249,12 +250,12 @@ * when trace is active). */ -int -synchnet(int f /* socket to flush */) +void +synchnet(int f /* socket to flush */, int trace) { int i, j = 0; char rbuf[PKTSIZE]; - struct sockaddr_in from; + struct sockaddr_storage from; socklen_t fromlen; while (1) { @@ -265,7 +266,10 @@ (void) recvfrom(f, rbuf, sizeof (rbuf), 0, (struct sockaddr *)&from, &fromlen); } else { - return(j); + if (j && trace) { + printf("discarded %d packets\n", j); + } + return; } } } --- netkit-tftp-0.17.orig/tftp/tftpsubs.h +++ netkit-tftp-0.17/tftp/tftpsubs.h @@ -1,6 +1,7 @@ #define PKTSIZE SEGSIZE+4 /* should be moved to tftp.h */ -int synchnet(int); +void initsock(int); +void synchnet(int, int); struct tftphdr *r_init(void); struct tftphdr *w_init(void); int readit(FILE *file, struct tftphdr **dpp, int convert); --- netkit-tftp-0.17.orig/tftp/Makefile +++ netkit-tftp-0.17/tftp/Makefile @@ -12,7 +12,7 @@ tftp.o: ../version.h install: tftp - install -s -m$(BINMODE) tftp $(INSTALLROOT)$(BINDIR) + install -m$(BINMODE) tftp $(INSTALLROOT)$(BINDIR) install -m$(MANMODE) tftp.1 $(INSTALLROOT)$(MANDIR)/man1 clean: --- netkit-tftp-0.17.orig/tftp/main.c +++ netkit-tftp-0.17/tftp/main.c @@ -68,8 +68,9 @@ #define TIMEOUT 5 /* secs between rexmt's */ -struct sockaddr_in s_inn; -int f; +struct sockaddr_storage s_inn; +socklen_t s_inn_len; +int f = -1; int trace; int verbose; int rexmtval = TIMEOUT; @@ -79,8 +80,8 @@ void recvfile(int fd, char *name, char *modestr); -static int connected; -static short port; +static int connected = AF_UNSPEC; /* If non-zero, contains active address family! */ +static char service[NI_MAXSERV] = "tftp"; static char mode[32]; static char line[200]; static int margc; @@ -151,28 +152,38 @@ static struct cmd *getcmd(const char *name); static char *tail(char *filename); -int -main(int argc, char *argv[]) -{ - struct sockaddr_in s_in; - int top; +void initsock(int af) { + struct sockaddr_storage s_in; - sp = getservbyname("tftp", "udp"); - if (sp == 0) { - fprintf(stderr, "tftp: udp/tftp: unknown service\n"); - exit(1); - } - f = socket(AF_INET, SOCK_DGRAM, 0); + if (f >= 0) + close(f); + + f = socket(af, SOCK_DGRAM, 0); if (f < 0) { perror("tftp: socket"); exit(3); } + memset(&s_in, 0, sizeof(s_in)); - s_in.sin_family = AF_INET; + s_in.ss_family = af; if (bind(f, (struct sockaddr *)&s_in, sizeof (s_in)) < 0) { perror("tftp: bind"); exit(1); } +} + +int +main(int argc, char *argv[]) +{ + int top; + + /* Make a minimal sanity check. */ + sp = getservbyname("tftp", "udp"); + if (sp == 0) { + fprintf(stderr, "tftp: udp/tftp: unknown service\n"); + exit(1); + } + strcpy(mode, "netascii"); mysignal(SIGINT, intr); if (argc > 1) { @@ -185,12 +196,12 @@ command(top); } -static char hostname[100]; +static char hostname[NI_MAXHOST]; void setpeer(int argc, char *argv[]) { - struct hostent *host; + struct addrinfo hints, *aiptr, *ai; size_t len; if (argc < 2) { @@ -202,40 +213,61 @@ argc = margc; argv = margv; } - if (argc > 3) { + /* We should have 2 or 3 args now: the cmd and its + * parameters. If not, we bail out here. + */ + if (argc != 2 && argc != 3) { printf("usage: %s host-name [port]\n", argv[0]); return; } - host = gethostbyname(argv[1]); - if (host) { - s_inn.sin_family = host->h_addrtype; - if (host->h_length > (int)sizeof(s_inn.sin_addr)) { - host->h_length = sizeof(s_inn.sin_addr); - } - memcpy(&s_inn.sin_addr, host->h_addr, host->h_length); - strncpy(hostname, host->h_name, sizeof(hostname)); - hostname[sizeof(hostname)-1] = 0; - } - else { - s_inn.sin_family = AF_INET; - if (!inet_aton(argv[1], &s_inn.sin_addr)) { - connected = 0; - printf("%s: unknown host\n", argv[1]); - return; - } - strcpy(hostname, argv[1]); - } - port = sp->s_port; + + /* First we record the service name. Default is "tftp". + */ if (argc == 3) { - port = atoi(argv[2]); - if (port < 0) { - printf("%s: bad port number\n", argv[2]); + if (argv[2] == NULL || *argv[2] == '\0') { + printf("%s: bad port name\n", argv[2]); connected = 0; return; } - port = htons(port); + strncpy(service, argv[2], sizeof(service)); + service[sizeof(service)-1] = '\0'; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ALL | AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + if ( getaddrinfo(argv[1], service, &hints, &aiptr) ) { + connected = 0; + printf("%s: unknown host\n", argv[1]); + return; + } + + /* Choose first applicable address. */ + ai = aiptr; + + while ( ai && (ai->ai_family != AF_INET6) + && (ai->ai_family != AF_INET) ) + ai = ai->ai_next; + + + if ( ai == NULL ) { + connected = 0; + freeaddrinfo(aiptr); + printf("%s: unknown host\n", argv[1]); + return; } - connected = 1; + + memcpy(&s_inn, ai->ai_addr, ai->ai_addrlen); + s_inn_len = ai->ai_addrlen; + connected = ai->ai_family; + strncpy(hostname, aiptr->ai_canonname, sizeof(hostname)); + hostname[sizeof(hostname)-1] = '\0'; + freeaddrinfo(aiptr); + + /* Test and set socket for the relevant address family. */ + initsock(connected); } struct modes { @@ -336,7 +368,8 @@ targ = argv[argc - 1]; if (strchr(argv[argc - 1], ':')) { char *cp; - struct hostent *hp; + struct addrinfo hints, *aiptr, *ai; + int status; for (n = 1; n < argc - 1; n++) if (strchr(argv[n], ':')) { @@ -344,22 +377,39 @@ return; } cp = argv[argc - 1]; - targ = strchr(cp, ':'); + /* Last colon. Numerical IPv6 addresses! */ + targ = strrchr(cp, ':'); *targ++ = 0; - hp = gethostbyname(cp); - if (hp == NULL) { - fprintf(stderr, "tftp: %s: ", cp); - herror((char *)NULL); + + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + status = getaddrinfo(cp, service, &hints, &aiptr); + if ( status != 0 ) { + fprintf(stderr, "tftp: %s: %s\n", cp, gai_strerror(status)); return; } - if (hp->h_length > (int)sizeof(s_inn.sin_addr)) { - hp->h_length = sizeof(s_inn.sin_addr); + + ai = aiptr; + while ( ai && (ai->ai_family != AF_INET) + && (ai->ai_family != AF_INET6) ) + ai = ai->ai_next; + + if ( ai == NULL ) { + freeaddrinfo(aiptr); + fprintf(stderr, "tftp: %s: %s\n", cp, "Address not found"); + return; } - memcpy(&s_inn.sin_addr, hp->h_addr, hp->h_length); - s_inn.sin_family = hp->h_addrtype; - connected = 1; - strncpy(hostname, hp->h_name, sizeof(hostname)); - hostname[sizeof(hostname)-1] = 0; + + memcpy(&s_inn, ai->ai_addr, ai->ai_addrlen); + s_inn_len = ai->ai_addrlen; + connected = ai->ai_family; + strncpy(hostname, aiptr->ai_canonname, sizeof(hostname)); + hostname[sizeof(hostname)-1] = '\0'; + freeaddrinfo(aiptr); + initsock(connected); } if (!connected) { printf("No target machine specified.\n"); @@ -376,7 +426,7 @@ if (verbose) printf("putting %s to %s:%s [%s]\n", ccp, hostname, targ, mode); - s_inn.sin_port = port; + sendfile(fd, targ, mode); return; } @@ -394,7 +444,7 @@ if (verbose) printf("putting %s to %s:%s [%s]\n", argv[n], hostname, targ, mode); - s_inn.sin_port = port; + sendfile(fd, targ, mode); } } @@ -439,29 +489,50 @@ } } for (n = 1; n < argc ; n++) { - src = strchr(argv[n], ':'); + /* Last colon. Numerical IPv6 addresses! */ + src = strrchr(argv[n], ':'); if (src == NULL) src = argv[n]; else { - struct hostent *hp; + struct addrinfo hints, *aiptr, *ai; + int status; *src++ = 0; - hp = gethostbyname(argv[n]); - if (hp == NULL) { - fprintf(stderr, "tftp: %s: ", argv[n]); - herror(NULL); + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + status = getaddrinfo(argv[n], service, &hints, &aiptr); + if ( status ) { + fprintf(stderr, "tftp: %s: %s\n", argv[n], + gai_strerror(status)); continue; } - if (hp->h_length > (int)sizeof(s_inn.sin_addr)) { - hp->h_length = sizeof(s_inn.sin_addr); + + ai = aiptr; + while ( ai && (ai->ai_family != AF_INET) + && (ai->ai_family != AF_INET6) ) + ai = ai->ai_next; + + + if ( ai == NULL ) { + freeaddrinfo(aiptr); + fprintf(stderr, "tftp: %s: %s\n", argv[n], + "Address not found"); + continue; } - memcpy(&s_inn.sin_addr, hp->h_addr, hp->h_length); - s_inn.sin_family = hp->h_addrtype; - connected = 1; - strncpy(hostname, hp->h_name, sizeof(hostname)); + + memcpy(&s_inn, ai->ai_addr, ai->ai_addrlen); + s_inn_len = ai->ai_addrlen; + connected = ai->ai_family; + strncpy(hostname, aiptr->ai_canonname, + sizeof(hostname)); hostname[sizeof(hostname)-1] = 0; + freeaddrinfo(aiptr); + initsock(connected); } - if (argc < 4) { + if (argc == 2 || (argc == 3 && n == 1 && !strchr(argv[2], ':'))) { cp = argc == 3 ? argv[2] : tail(src); fd = creat(cp, 0644); if (fd < 0) { @@ -471,7 +542,7 @@ if (verbose) printf("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode); - s_inn.sin_port = port; + recvfile(fd, src, mode); break; } @@ -484,7 +555,7 @@ if (verbose) printf("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode); - s_inn.sin_port = port; + recvfile(fd, src, mode); } } @@ -493,7 +564,8 @@ getusage(const char *s) { printf("usage: %s host:file host:file ... file, or\n", s); - printf(" %s file file ... file if connected\n", s); + printf(" %s file file ... file if connected, or\n", s); + printf(" %s host:rfile lfile\n", s); } --- netkit-tftp-0.17.orig/debian/copyright +++ netkit-tftp-0.17/debian/copyright @@ -0,0 +1,15 @@ +This package was split from netstd by Herbert Xu herbert@debian.org on +Tue, 26 Oct 1999 12:29:16 +1000 + +netstd was created by Peter Tobias tobias@et-inf.fho-emden.de on +Wed, 20 Jul 1994 17:23:21 +0200. + +It was downloaded from ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/. + +Copyright: + +Copyright (c) 1983, 1991 The Regents of the University of California. + +The license can be found in /usr/share/common-licenses/BSD. + +$Id: copyright,v 1.2 2000/08/12 01:28:48 herbert Exp $ --- netkit-tftp-0.17.orig/debian/compat +++ netkit-tftp-0.17/debian/compat @@ -0,0 +1 @@ +7 --- netkit-tftp-0.17.orig/debian/tftpd.postinst +++ netkit-tftp-0.17/debian/tftpd.postinst @@ -0,0 +1,17 @@ +#!/bin/sh -e +# $Id: tftpd.postinst,v 1.1 1999/10/26 04:43:01 herbert Exp $ + +case "$1" in +abort-upgrade | abort-deconfigure | abort-remove) + update-inetd --enable tftp + ;; +configure) + update-inetd --group BOOT --add "tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp" + ;; +*) + printf "$0: incorrect arguments: $*\n" >&2 + exit 1 + ;; +esac + +#DEBHELPER# --- netkit-tftp-0.17.orig/debian/README.Debian +++ netkit-tftp-0.17/debian/README.Debian @@ -0,0 +1,8 @@ +tftpd for Debian +---------------- + +Please note that the default tftp directory is set to /boot by default in +inetd.conf. + +Herbert Xu, +$Id: README.Debian,v 1.1 2001/12/01 10:40:08 herbert Exp $ --- netkit-tftp-0.17.orig/debian/control +++ netkit-tftp-0.17/debian/control @@ -0,0 +1,31 @@ +Source: netkit-tftp +Section: net +Priority: optional +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Alberto Gonzalez Iniesta +Standards-Version: 3.9.0.0 +Build-Depends: debhelper (>= 7) +Homepage: http://www.hcs.harvard.edu/~dholland/computers/netkit.html + +Package: tftp +Architecture: any +Depends: netbase, ${shlibs:Depends}, ${misc:Depends} +Replaces: netstd +Description: Trivial file transfer protocol client + Tftp is the user interface to the Internet TFTP (Trivial File Transfer + Protocol), which allows users to transfer files to and from a remote machine. + The remote host may be specified on the command line, in which case tftp uses + host as the default host for future transfers. + +Package: tftpd +Architecture: any +Depends: xinetd | inet-superserver, ${shlibs:Depends}, ${misc:Depends} +Replaces: netstd +Description: Trivial file transfer protocol server + Tftpd is a server which supports the Internet Trivial File Transfer Protocol + (RFC 783). The TFTP server operates at the port indicated in the `tftp' + service description; see services(5). The server is normally started by + inetd(8). + Tftpd is not suitable for use with the PXE bootloader; for that, + use atftpd or tftpd-hpa. + --- netkit-tftp-0.17.orig/debian/tftp.dirs +++ netkit-tftp-0.17/debian/tftp.dirs @@ -0,0 +1,2 @@ +usr/bin +usr/share/man/man1 --- netkit-tftp-0.17.orig/debian/tftpd.postrm +++ netkit-tftp-0.17/debian/tftpd.postrm @@ -0,0 +1,19 @@ +#!/bin/sh -e +# $Id: tftpd.postrm,v 1.2 2002/12/22 05:17:12 herbert Exp $ + +case "$1" in +abort-install | abort-upgrade | upgrade | failed-upgrade | disappear) + ;; +purge|remove) + # If netbase is not installed, then we don't need to do the remove. + if command -v update-inetd >/dev/null 2>&1; then + update-inetd --remove tftp + fi + ;; +*) + echo "$0: incorrect arguments: $*" >&2 + exit 1 + ;; +esac + +#DEBHELPER# --- netkit-tftp-0.17.orig/debian/rules +++ netkit-tftp-0.17/debian/rules @@ -0,0 +1,95 @@ +#!/usr/bin/make -f +# GNU copyright 1997 to 1999 by Joey Hess. +# Copyright (c) 1999 Herbert Xu . + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatability version to use. +#export DH_COMPAT=2 + +# This has to be exported to make some magic below work. +export DH_OPTIONS + +build: build-stamp +build-stamp: + dh_testdir + + if [ ! -f MCONFIG ]; then \ + ./configure; \ + fi + $(MAKE) + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp install-stamp + + [ ! -f MCONFIG ] || $(MAKE) distclean + + dh_clean + +install: DH_OPTIONS= +install: build + dh_testdir + dh_testroot + dh_prep + dh_installdirs + + $(MAKE) -C tftp install INSTALLROOT=`pwd`/debian/tftp \ + MANDIR='/usr/share/man' + $(MAKE) -C tftpd install INSTALLROOT=`pwd`/debian/tftpd \ + MANDIR='/usr/share/man' + + touch install-stamp + +# This single target is used to build all the packages, all at once, or +# one at a time. So keep in mind: any options passed to commands here will +# affect _all_ packages. Anything you want to only affect one package +# should be put in another target, such as the install target. +binary-common: build install + # Need this version of debhelper for DH_OPTIONS to work. + #deprecated#dh_testversion 1.1.17 + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installemacsen +# dh_installpam +# dh_installinit + dh_installcron + dh_installinfo +# dh_undocumented + dh_installchangelogs ChangeLog + dh_link + dh_strip + dh_compress + dh_fixperms + # You may want to make some executables suid here. +# dh_makeshlibs + dh_installdeb +# dh_perl + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +# Build architecture independant packages using the common target. +binary-indep: +# (Uncomment this next line if you have such packages.) +# $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common + +# Build architecture dependant packages using the common target. +binary-arch: + $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common + +# Any other binary targets build just one binary package at a time. +binary-%: + make -f debian/rules binary-common DH_OPTIONS=-p$* + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install --- netkit-tftp-0.17.orig/debian/tftpd.docs +++ netkit-tftp-0.17/debian/tftpd.docs @@ -0,0 +1 @@ +README --- netkit-tftp-0.17.orig/debian/changelog +++ netkit-tftp-0.17/debian/changelog @@ -0,0 +1,236 @@ +netkit-tftp (0.17-18ubuntu2) natty; urgency=low + + * tftp/tftp.c: fix FORTIFY-detected potential memory corruption + (LP: #691345). + + -- Kees Cook Thu, 16 Dec 2010 18:14:49 -0800 + +netkit-tftp (0.17-18ubuntu1) natty; urgency=low + + * Merge from debian unstable (LP: #664710). Remaining changes: + - debian/control: Change dependency from openbsd-inetd to xinetd + so correct size is reported + - debian/control: Added Homepage field. + * Dropped change: (superceded in debian) + - debian/rules: Removed the sed to add -g to CFLAGS. This was not + working as currently defined (extra \$), and debug (-g) is not + required. + - Added debian/watch to monitor for new versions. + - Patch to return ENOTFOUND instead of EUNDEF for files that do not + exist applied to tftpd/tftpd.c + + -- Angel Abad Fri, 22 Oct 2010 18:16:14 +0200 + +netkit-tftp (0.17-18) unstable; urgency=low + + * debian/control: added ${misc:Depends} to binary packages + * debian/compat: moved to 7 + * Add IPv6 support, once again thanks to Mats Erik Andersson. + (Closes: #536509) + * Patch from Ubuntu (Closes: #494309), thanks Stefan Lesicnik: + - Return ENOTFOUND instead of EUNDEF for files that do not exist + - Adds debian/watch file (even when they won't happen...) + - debian/rules: Removes sed which adds -g (debug) option to gcc + * Removed '-s' from install calls in Makefiles and added dh_strip. + (Closes: #437617) + + -- Alberto Gonzalez Iniesta Fri, 24 Sep 2010 18:05:54 +0200 + +netkit-tftp (0.17-17ubuntu2) maverick; urgency=low + + * debian/control: + - Change dependency from openbsd-inetd to xinetd so correct + size is reported (LP: #105863) + + -- Mackenzie Morgan Fri, 20 Aug 2010 12:33:19 -0400 + +netkit-tftp (0.17-17ubuntu1) jaunty; urgency=low + + * Merge from debian unstable, remaining changes: (LP: #314084) + - debian/control: Added Homepage field. + - debian/rules: Removed the sed to add -g to CFLAGS. This was not + working as currently defined (extra \$), and debug (-g) is not + required. + - Added debian/watch to monitor for new versions. + - Patch to return ENOTFOUND instead of EUNDEF for files that do not + exist applied to tftpd/tftpd.c (Jerry Kotland - LP: #217537) + + -- Stefan Lesicnik Mon, 05 Jan 2009 16:37:32 +0200 + +netkit-tftp (0.17-17) unstable; urgency=low + + * Require hostname for connection name (Closes: #375365) + Thanks Michael Welle for the patch. + * Don't reset the socket before sending last ACK. (Closes: #351403) + Thanks Michael Welle for the patch. + * Don't ignore make clean errors to make lintian happy. + + -- Alberto Gonzalez Iniesta Tue, 30 Dec 2008 15:03:15 +0100 + +netkit-tftp (0.17-16ubuntu1) intrepid; urgency=low + + * Merge from debian unstable, remaining changes: + - No remaining changes. + * debian/rules: + - Removed the sed to add -g to CFLAGS. This was not working as + currently defined (extra \$), and debug (-g) is not required. + - Created if statement to check for the presence of MCONFIG to + decide if to run make distclean. + * Added debian/watch to monitor for new versions. + * debian/control: + - Added Homepage field. + * Patch to return ENOTFOUND instead of EUNDEF for files that + do not exist applied to tftpd/tftpd.c + (Jerry Kotland - closes LP: #217537) + + -- Stefan Lesicnik Fri, 08 Aug 2008 14:15:39 +0200 + +netkit-tftp (0.17-16) unstable; urgency=high + + * tftpd.c: Fixed security bug that made tftpd serve files from + the filesystem root directory when the tftpd root directory + was wrongly specified. Thanks Tomasz Nowiński for finding this + out. + * tftpd.c: Return 1 (File Not Found) instead of 0 (Not defined) to conform + to TFTP RFC. + * Revert patch that allowed uploading NEW files to the server. + Behaving just like the man page states (Closes: #335200) + * Bumped Standards-Version to 3.8.0.0, no change. + * Removed debian/tftpd.prerm, no need for it. + * Removed inetd entry on package removal (Closes: #351867) + * Replaced netbase Depends with openbsd-inetd | inet-superserver. + (Closes: #401888) + * Mention in package description that tftpd is not suitable for PXE + booting. (Closes: #401288) + + -- Alberto Gonzalez Iniesta Tue, 05 Aug 2008 13:15:15 +0200 + +netkit-tftp (0.17-15ubuntu2) intrepid; urgency=low + + * debian/control: + - Update Maintainer field as per spec (LP: #230350). + + -- Luca Falavigna Wed, 04 Jun 2008 23:26:06 +0200 + +netkit-tftp (0.17-15ubuntu1) feisty; urgency=low + + * debian/control: Add update-inetd to tftpd's dependencies + (Closes Ubuntu: #76160). + * debian/control: Add openbsd-inetd | inet-superserver dependencies + as tftpd needs an inet server to work + + -- Lionel Porcheron Sun, 17 Dec 2006 16:08:24 +0100 + +netkit-tftp (0.17-15) unstable; urgency=low + + * tftpd/tftpd.c: Fixed file mode when new files are uploaded. + + -- Alberto Gonzalez Iniesta Fri, 14 Oct 2005 11:33:37 +0200 + +netkit-tftp (0.17-14) unstable; urgency=low + + * Fix dyslexia problem. Actually made the default directory + /srv/tftp. + * tftpd/tftpd.c patched to allow uploading files that didn't exist + previously on the server. + Thanks Rodrigo Steinmüller Wanderley + for finding this out and the patch. + * Bumped Standards-Version to 3.6.2.0, no change. + * Moved to debhelper compatibility 4. Created debian/compat. + + -- Alberto Gonzalez Iniesta Thu, 13 Oct 2005 12:14:55 +0200 + +netkit-tftp (0.17-13) unstable; urgency=low + + * Fixed typo in man page. (Closes: #310347) + * Changed default tftpd directory to /svr/tftp (Closes: #255204) + + -- Alberto Gonzalez Iniesta Tue, 12 Jul 2005 19:44:36 +0200 + +netkit-tftp (0.17-12) unstable; urgency=low + + * Changed maintainer email address + * Reworded tftp and tftpd Descriptions + + -- Alberto Gonzalez Iniesta Fri, 25 Mar 2005 19:05:49 +0100 + +netkit-tftp (0.17-11) unstable; urgency=low + + * New Maintainer. (Closes: #249716) + * Added Depends on netbase to tftp. (Closes: #245764) + * Added versioned Build-Depends on debhelper. + * Bumped Standards-Version to 3.6.1, no change. + + -- Alberto Gonzalez Iniesta Wed, 19 May 2004 09:41:49 +0200 + +netkit-tftp (0.17-10) unstable; urgency=low + + * Fixed inetd service name in prerm/postrm (closes: #171178). + + -- Herbert Xu Sun, 22 Dec 2002 15:48:30 +1100 + +netkit-tftp (0.17-9) unstable; urgency=low + + * Always reopen socket after a get/put in tftp (closes: #130292). + + -- Herbert Xu Wed, 30 Jan 2002 20:56:47 +1100 + +netkit-tftp (0.17-8) unstable; urgency=low + + * Reopen socket on all errors in tftp (closes: #130292). + + -- Herbert Xu Mon, 28 Jan 2002 21:43:17 +1100 + +netkit-tftp (0.17-7) unstable; urgency=low + + * Call synchnet on all errors in tftp (closes: #130292). + + -- Herbert Xu Fri, 25 Jan 2002 19:06:31 +1100 + +netkit-tftp (0.17-6) unstable; urgency=low + + * Added note about default tftp location in README.Debian (closes: #121522). + + -- Herbert Xu Sat, 22 Dec 2001 13:07:55 +1100 + +netkit-tftp (0.17-5) unstable; urgency=low + + * Fixed loop condition in sendfile (closes: #92231). + + -- Herbert Xu Mon, 2 Apr 2001 21:38:15 +1000 + +netkit-tftp (0.17-4) unstable; urgency=low + + * Use arpa/tftp.h from glibc (closes: #88346). + + -- Herbert Xu Sun, 4 Mar 2001 10:23:45 +1100 + +netkit-tftp (0.17-3) unstable; urgency=low + + * Restored block == 1 check that was removed in 0.17 (closes: #88286). + + -- Herbert Xu Sat, 3 Mar 2001 10:19:40 +1100 + +netkit-tftp (0.17-2) unstable; urgency=low + + * Removed emacsism in this very file (closes: #74272). + * Merged option processing changes from Ian Jackson (closes: #74273). + + -- Herbert Xu Sat, 21 Oct 2000 12:12:28 +1100 + +netkit-tftp (0.17-1) unstable; urgency=low + + * New upstream release. + + -- Herbert Xu Sat, 12 Aug 2000 12:04:31 +1000 + +netkit-tftp (0.10-1) unstable; urgency=low + + * Initial Release. + * Based on netkit-tftp (closes: #39450). + * Implemented -n and -s (closes: #23917). + Note that -s was done without chroot. Instead all absolute filenames are + treated as relative ones. + + -- Herbert Xu Tue, 26 Oct 1999 12:23:51 +1000 + --- netkit-tftp-0.17.orig/debian/watch +++ netkit-tftp-0.17/debian/watch @@ -0,0 +1,2 @@ +version=2 +ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/netkit-tftp-(.*)\.tar\.gz --- netkit-tftp-0.17.orig/debian/tftpd.dirs +++ netkit-tftp-0.17/debian/tftpd.dirs @@ -0,0 +1,2 @@ +usr/sbin +usr/share/man/man8 --- netkit-tftp-0.17.orig/debian/tftp.docs +++ netkit-tftp-0.17/debian/tftp.docs @@ -0,0 +1 @@ +BUGS