Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/tftpd Add a -b flag so that clients that return thei...
details: https://anonhg.NetBSD.org/src/rev/a38e7f9a3d1e
branches: trunk
changeset: 337969:a38e7f9a3d1e
user: buhrow <buhrow%NetBSD.org@localhost>
date: Tue May 05 05:50:31 2015 +0000
description:
Add a -b flag so that clients that return their acknowledgements to the
broadcast address can inter-operate with the tftpd server.
Discussed in bin/49868
diffstat:
libexec/tftpd/tftpd.8 | 10 ++++++-
libexec/tftpd/tftpd.c | 60 +++++++++++++++++++++++++++++++++++++-------------
2 files changed, 52 insertions(+), 18 deletions(-)
diffs (186 lines):
diff -r 8215dc41f33f -r a38e7f9a3d1e libexec/tftpd/tftpd.8
--- a/libexec/tftpd/tftpd.8 Tue May 05 00:28:25 2015 +0000
+++ b/libexec/tftpd/tftpd.8 Tue May 05 05:50:31 2015 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: tftpd.8,v 1.28 2010/04/29 21:34:04 wiz Exp $
+.\" $NetBSD: tftpd.8,v 1.29 2015/05/05 05:50:31 buhrow Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -39,7 +39,7 @@
Internet Trivial File Transfer Protocol server
.Sh SYNOPSIS
.Nm
-.Op Fl cdln
+.Op Fl bcdln
.Op Fl g Ar group
.Op Fl p Ar pathsep
.Op Fl s Ar directory
@@ -95,6 +95,12 @@
.Pp
The options are:
.Bl -tag -width "XsXdirectoryX"
+.It Fl b
+Allow clients which return acknowledgements to the broadcast address to
+communicate with the tftp server.
+Some tftp clients, notably ones resident in the ROMs of older Cisco
+equipment, return their acknowledgements to the broadcast address rather
+than the server's unicast address.
.It Fl c
Allow unrestricted creation of new files.
Without this flag, only existing publicly writable files can be overwritten.
diff -r 8215dc41f33f -r a38e7f9a3d1e libexec/tftpd/tftpd.c
--- a/libexec/tftpd/tftpd.c Tue May 05 00:28:25 2015 +0000
+++ b/libexec/tftpd/tftpd.c Tue May 05 05:50:31 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tftpd.c,v 1.43 2013/10/04 07:51:48 jnemeth Exp $ */
+/* $NetBSD: tftpd.c,v 1.44 2015/05/05 05:50:31 buhrow Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -36,7 +36,7 @@
#if 0
static char sccsid[] = "@(#)tftpd.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: tftpd.c,v 1.43 2013/10/04 07:51:48 jnemeth Exp $");
+__RCSID("$NetBSD: tftpd.c,v 1.44 2015/05/05 05:50:31 buhrow Exp $");
#endif
#endif /* not lint */
@@ -110,6 +110,7 @@
static char pathsep = '\0';
static char *securedir;
static int unrestricted_writes; /* uploaded files don't have to exist */
+static int broadcast_client = 0; /* Some clients ack to the broadcast address */
struct formats;
@@ -142,7 +143,7 @@
{
syslog(LOG_ERR,
- "Usage: %s [-cdln] [-g group] [-p pathsep] [-s directory] [-u user] [directory ...]",
+ "Usage: %s [-bcdln] [-g group] [-p pathsep] [-s directory] [-u user] [directory ...]",
getprogname());
exit(1);
}
@@ -172,8 +173,30 @@
curuid = getuid();
curgid = getgid();
- while ((ch = getopt(argc, argv, "cdg:lnp:s:u:")) != -1)
+ while ((ch = getopt(argc, argv, "bcdg:lnp:s:u:")) != -1)
switch (ch) {
+ case 'b':
+ /*
+ * Some clients, notably older Cisco boot loaders,
+ * send their acknowledgements to the broadcast address
+ * rather than the unicast address of the server.
+ * Allow those clients to inter-operate with us.
+ * It's worth noting that this interaction doesn't cause the
+ * server to change where it sends the responses, meaning
+ * servers that have this flag enabled are no more
+ * susceptible to magnifcation DOS attacks than those
+ * servers that don't use this flag. This flag merely
+ * permits the reception of acknowledgement traffic to the
+ * broadcast address/specific port number that's being used for
+ * this session as well as the unicast address/specific port
+ * number for this session. For example, if the session is
+ * expecting acks on 192.168.1.40:50201, then this flag
+ * would also allow acks to be returned to
+ * 192.168.1.255:50201, assuming that 192.168.1.255 is the
+ * broadcast address for the subnet containing 192.168.1.40.
+ */
+ broadcast_client = 1;
+ break;
case 'c':
unrestricted_writes = 1;
break;
@@ -393,14 +416,17 @@
syslog(LOG_ERR, "socket: %m");
exit(1);
}
+ if (broadcast_client) {
+ soopt = 1;
+ if (setsockopt(peer, SOL_SOCKET, SO_BROADCAST, (void *) &soopt, sizeof(soopt)) < 0) {
+ syslog(LOG_ERR, "set SO_BROADCAST: %m");
+ exit(1);
+ }
+ }
if (bind(peer, (struct sockaddr *)&me, me.ss_len) < 0) {
syslog(LOG_ERR, "bind: %m");
exit(1);
}
- if (connect(peer, (struct sockaddr *)&from, from.ss_len) < 0) {
- syslog(LOG_ERR, "connect: %m");
- exit(1);
- }
soopt = 65536; /* larger than we'll ever need */
if (setsockopt(peer, SOL_SOCKET, SO_SNDBUF, (void *) &soopt, sizeof(soopt)) < 0) {
syslog(LOG_ERR, "set SNDBUF: %m");
@@ -955,7 +981,7 @@
send_data:
if (!etftp && debug)
syslog(LOG_DEBUG, "Send DATA %u", block);
- if ((n = send(peer, dp, size + 4, 0)) != size + 4) {
+ if ((n = sendto(peer, dp, size + 4, 0, (struct sockaddr *)&from, fromlen)) != size + 4) {
syslog(LOG_ERR, "tftpd: write: %m");
goto abort;
}
@@ -963,7 +989,8 @@
read_ahead(file, tftp_blksize, pf->f_convert);
for ( ; ; ) {
alarm(rexmtval); /* read the ack */
- n = recv(peer, ackbuf, tftp_blksize, 0);
+ n = recvfrom(peer, ackbuf, tftp_blksize, 0,(struct sockaddr
+ *)&from, &fromlen );
alarm(0);
if (n < 0) {
syslog(LOG_ERR, "tftpd: read: %m");
@@ -1049,14 +1076,15 @@
(void) setjmp(timeoutbuf);
send_ack:
ap = (struct tftphdr *) (etftp ? oackbuf : ackbuf);
- if (send(peer, ap, acklength, 0) != acklength) {
+ if (sendto(peer, ap, acklength, 0, (struct sockaddr *)&from, fromlen) != acklength) {
syslog(LOG_ERR, "tftpd: write: %m");
goto abort;
}
write_behind(file, pf->f_convert);
for ( ; ; ) {
alarm(rexmtval);
- n = recv(peer, dp, tftp_blksize + 4, 0);
+ n = recvfrom(peer, dp, tftp_blksize + 4, 0, (struct sockaddr
+ *)&from, &fromlen);
alarm(0);
if (n < 0) { /* really? */
syslog(LOG_ERR, "tftpd: read: %m");
@@ -1108,16 +1136,16 @@
ap->th_block = htons((u_short)(block));
if (debug)
syslog(LOG_DEBUG, "Send final ACK %u", block);
- (void) send(peer, ackbuf, 4, 0);
+ (void) sendto(peer, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen);
signal(SIGALRM, justquit); /* just quit on timeout */
alarm(rexmtval);
- n = recv(peer, buf, sizeof (buf), 0); /* normally times out and quits */
+ n = recvfrom(peer, buf, sizeof (buf), 0, (struct sockaddr *)&from, &fromlen); /* normally times out and quits */
alarm(0);
if (n >= 4 && /* if read some data */
dp->th_opcode == DATA && /* and got a data block */
block == dp->th_block) { /* then my last ack was lost */
- (void) send(peer, ackbuf, 4, 0); /* resend final ack */
+ (void) sendto(peer, ackbuf, 4, 0, (struct sockaddr *)&from, fromlen); /* resend final ack */
}
abort:
return;
@@ -1185,7 +1213,7 @@
syslog(LOG_DEBUG, "Send NACK %s", tp->th_msg);
length = strlen(tp->th_msg);
msglen = &tp->th_msg[length + 1] - buf;
- if (send(peer, buf, msglen, 0) != (ssize_t)msglen)
+ if (sendto(peer, buf, msglen, 0, (struct sockaddr *)&from, fromlen) != (ssize_t)msglen)
syslog(LOG_ERR, "nak: %m");
}
Home |
Main Index |
Thread Index |
Old Index