forked from pool/atftp
Pedro Monreal Gonzalez
222c2ec04b
- Removed old initscript conditionals and atftpd.init file - Update to version 0.7.2 [bsc#1133114, CVE-2019-11365][bsc#1133145, CVE-2019-11366] * atftpd.c: Fixed a potential DoS bug (introduced by the IPv6 patch) * Fix Debian Bug deb#613582 and deb#258998 atftpd: does not reply properly when there's more than 1 interface * Fix Debian Bug deb#622840 atftpd: Forgets port if both --port and --bind-address are used * Fix Debian Bug deb#606969 atftp exits with no error after a get when disk is full * Fix Debian Bug deb#575831 atftp: error return value when tftp put file * Fix missing default port from Ubuntu bug lp#972834 * Merged patches to improve debugging and warning messages * Merged patch from Gentoo distribution: add support for proprietary password extension necessary for transferring files to linksys routers (atftp client) * Added patch from Gentoo bug #322601: client fails for filenames containing spaces * Listening Address configuration fixed * Added Patch "Blksize option can be smaller than SEGSIZE" * Fix Debian Bug deb#609813 Apply patch listen on requested port when in daemon mode. * Fix Debian Bug deb#598474 Fixed use of sendto() over a connected datagram socket on FreeBSD * Fix Debian Bug deb#580473 Apply IPv6 support patch by Ben Hutchings. Add AC_GNU_SOURCE to configure.ac to address FTBFS. * Fix Debian Bug deb#536295 Updated config.sub .guess. * Fix Debian Bug deb#535604 Make sure we have the --daemon option before starting atftpd * Fix Debian Bug deb#514521 Crash fix * Fix Debian Bug deb#484739 Added support for logging to stdout. * Fix Debian Bug deb#484932 inetd.conf: change udp to udp4 * Fix Debian Bug deb#436310 Fixed the FTBFS. * Fix Debian Bug deb#420900 Use CLOCKS_PER_SEC instead of CLK_TCK. Fixed a FTBFS. * Fix Debian Bug deb#271816 Random segfaults fixed * Fix Debian Bug deb#291829 Segfault fixed on AMD64. * Fix Debian Bug deb#290062 Copyright fixed. OBS-URL: https://build.opensuse.org/request/show/698118 OBS-URL: https://build.opensuse.org/package/show/network/atftp?expand=0&rev=38
223 lines
9.3 KiB
Diff
223 lines
9.3 KiB
Diff
Index: tftp_file.c
|
|
===================================================================
|
|
--- tftp_file.c.orig
|
|
+++ tftp_file.c
|
|
@@ -49,6 +49,7 @@
|
|
#define NB_BLOCK 2048
|
|
|
|
extern int tftp_cancel;
|
|
+extern int tftp_prevent_sas;
|
|
|
|
/*
|
|
* Find a hole in the file bitmap.
|
|
@@ -629,6 +631,7 @@ int tftp_send_file(struct client_data *d
|
|
int timeout_state = state; /* what state should we go on when timeout */
|
|
int result;
|
|
long block_number = 0;
|
|
+ long last_requested_block = -1;
|
|
long last_block = -1;
|
|
int data_size; /* size of data received */
|
|
int sockfd = data->sockfd; /* just to simplify calls */
|
|
@@ -791,6 +794,18 @@ int tftp_send_file(struct client_data *d
|
|
}
|
|
block_number = tftp_rollover_blocknumber(
|
|
ntohs(tftphdr->th_block), prev_block_number, 0);
|
|
+
|
|
+ /* if turned on, check whether the block request isn't already fulfilled */
|
|
+ if (tftp_prevent_sas) {
|
|
+ if (last_requested_block >= block_number) {
|
|
+ if (data->trace)
|
|
+ fprintf(stderr, "received duplicated ACK <block: %ld >= %ld>\n",
|
|
+ last_requested_block, block_number);
|
|
+ break;
|
|
+ } else
|
|
+ last_requested_block = block_number;
|
|
+ }
|
|
+
|
|
if (data->trace)
|
|
fprintf(stderr, "received ACK <block: %ld>\n",
|
|
block_number);
|
|
Index: tftpd_file.c
|
|
===================================================================
|
|
--- tftpd_file.c.orig
|
|
+++ tftpd_file.c
|
|
@@ -55,6 +55,7 @@
|
|
extern char directory[MAXLEN];
|
|
/* read only except for the main thread */
|
|
extern int tftpd_cancel;
|
|
+extern int tftpd_prevent_sas;
|
|
|
|
#ifdef HAVE_PCRE
|
|
extern tftpd_pcre_self_t *pcre_top;
|
|
@@ -407,6 +408,7 @@ int tftpd_send_file(struct thread_data *
|
|
int timeout_state = state;
|
|
int result;
|
|
long block_number = 0;
|
|
+ long last_requested_block = -1;
|
|
long last_block = -1;
|
|
int data_size;
|
|
struct sockaddr_storage *sa = &data->client_info->client;
|
|
@@ -818,6 +820,10 @@ int tftpd_send_file(struct thread_data *
|
|
sockaddr_get_port(
|
|
&client_info->client));
|
|
sa = &client_info->client;
|
|
+
|
|
+ /* rewind the last_requested_block counter */
|
|
+ last_requested_block = -1;
|
|
+
|
|
state = S_SEND_OACK;
|
|
break;
|
|
}
|
|
@@ -903,6 +909,28 @@ int tftpd_send_file(struct thread_data *
|
|
if (data->trace)
|
|
logger(LOG_DEBUG, "received ACK <block: %ld>",
|
|
block_number);
|
|
+
|
|
+ /* if turned on, check whether the block request isn't already fulfilled */
|
|
+ if (tftpd_prevent_sas) {
|
|
+ /* multicast, block numbers could contain gaps */
|
|
+ if (multicast) {
|
|
+ if (last_requested_block >= block_number) {
|
|
+ if (data->trace)
|
|
+ logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", last_requested_block, block_number);
|
|
+ break;
|
|
+ } else
|
|
+ last_requested_block = block_number;
|
|
+ /* unicast, blocks should be requested one after another */
|
|
+ } else {
|
|
+ if (last_requested_block + 1 != block_number && last_requested_block != -1) {
|
|
+ if (data->trace)
|
|
+ logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", last_requested_block + 1, block_number);
|
|
+ break;
|
|
+ } else
|
|
+ last_requested_block = block_number;
|
|
+ }
|
|
+ }
|
|
+
|
|
if ((last_block != -1) && (block_number > last_block))
|
|
{
|
|
state = S_END;
|
|
@@ -1001,6 +1029,8 @@ int tftpd_send_file(struct thread_data *
|
|
/* nedd to send an oack to that client */
|
|
state = S_SEND_OACK;
|
|
fseek(fp, 0, SEEK_SET);
|
|
+ /* reset the last block received counter */
|
|
+ last_requested_block = -1;
|
|
}
|
|
else
|
|
{
|
|
Index: tftpd.c
|
|
===================================================================
|
|
--- tftpd.c.orig
|
|
+++ tftpd.c
|
|
@@ -65,6 +65,7 @@ int listen_local = 0;
|
|
|
|
int tftpd_daemon = 0; /* By default we are started by inetd */
|
|
int tftpd_daemon_no_fork = 0; /* For who want a false daemon mode */
|
|
+int tftpd_prevent_sas = 0; /* For who don't want the sorcerer's apprentice syndrome */
|
|
short tftpd_port = 69; /* Port atftpd listen to */
|
|
char tftpd_addr[MAXLEN] = ""; /* IP address atftpd binds to */
|
|
|
|
@@ -922,6 +923,7 @@ int tftpd_cmd_line_options(int argc, cha
|
|
{ "mtftp", 1, NULL, OPT_MTFTP },
|
|
{ "mtftp-port", 1, NULL, OPT_MTFTP_PORT },
|
|
#endif
|
|
+ { "prevent-sas", 0, NULL, 'X' },
|
|
{ "no-source-port-checking", 0, NULL, OPT_PORT_CHECK },
|
|
{ "mcast-switch-client", 0, NULL, OPT_MCAST_SWITCH },
|
|
{ "version", 0, NULL, 'V' },
|
|
@@ -991,6 +993,9 @@ int tftpd_cmd_line_options(int argc, cha
|
|
case 'N':
|
|
tftpd_daemon_no_fork = 1;
|
|
break;
|
|
+ case 'X':
|
|
+ tftpd_prevent_sas = 1;
|
|
+ break;
|
|
case 'U':
|
|
tmp = strtok(optarg, ".");
|
|
if (tmp != NULL)
|
|
@@ -1223,6 +1228,7 @@ void tftpd_usage(void)
|
|
" --listen-local : force listen on local network address\n"
|
|
" --daemon : run atftpd standalone (no inetd)\n"
|
|
" --no-fork : run as a daemon, don't fork\n"
|
|
+ " --prevent-sas : prevent Sorcerer's Apprentice Syndrome\n"
|
|
" --user <user[.group]> : default is nobody\n"
|
|
" --group <group> : default is nogroup\n"
|
|
" --port <port> : port on which atftp listen\n"
|
|
Index: tftp.c
|
|
===================================================================
|
|
--- tftp.c.orig
|
|
+++ tftp.c
|
|
@@ -58,6 +58,7 @@
|
|
/* defined as extern in tftp_file.c and mtftp_file.c, set by the signal
|
|
handler */
|
|
int tftp_cancel = 0;
|
|
+int tftp_prevent_sas = 0;
|
|
|
|
/* local flags */
|
|
int interactive = 1; /* if false, we run in batch mode */
|
|
@@ -1006,6 +1007,7 @@ int tftp_cmd_line_options(int argc, char
|
|
#endif
|
|
{ "mtftp", 1, NULL, '1'},
|
|
{ "no-source-port-checking", 0, NULL, '0'},
|
|
+ { "prevent-sas", 0, NULL, 'X'},
|
|
{ "verbose", 0, NULL, 'v'},
|
|
{ "trace", 0, NULL, 'd'},
|
|
#if DEBUG
|
|
@@ -1115,6 +1117,9 @@ int tftp_cmd_line_options(int argc, char
|
|
case '0':
|
|
data.checkport = 0;
|
|
break;
|
|
+ case 'X':
|
|
+ tftp_prevent_sas = 1;
|
|
+ break;
|
|
case 'v':
|
|
snprintf(string, sizeof(string), "verbose on");
|
|
make_arg(string, &ac, &av);
|
|
@@ -1226,6 +1231,7 @@ void tftp_usage(void)
|
|
" --mtftp <\"name value\"> : set mtftp variable to value\n"
|
|
#endif
|
|
" --no-source-port-checking: violate RFC, see man page\n"
|
|
+ " --prevent-sas : prevent Sorcerer's Apprentice Syndrome\n"
|
|
" --verbose : set verbose mode on\n"
|
|
" --trace : set trace mode on\n"
|
|
#if DEBUG
|
|
Index: atftpd.8
|
|
===================================================================
|
|
--- atftpd.8.orig
|
|
+++ atftpd.8
|
|
@@ -181,6 +181,14 @@ implication. Be aware that this option v
|
|
option has effect only for non-multicast transfer.
|
|
|
|
.TP
|
|
+.B \-\-prevent\-sas
|
|
+Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350.
|
|
+This RFC requires repeated responses to a single packet to be
|
|
+rejected. Thus a block will only get retransmitted on a timeout.
|
|
+For backward compatibility, the default stays to ignore this RFC.
|
|
+So blocks get transmitted on every request.
|
|
+
|
|
+.TP
|
|
.B \-\-mcast\-switch\-client
|
|
This option allow the server to proceed with the next multicast client
|
|
as soon as the current client timeout. When the current master client
|
|
Index: atftp.1
|
|
===================================================================
|
|
--- atftp.1.orig
|
|
+++ atftp.1
|
|
@@ -88,6 +88,14 @@ to configure client side port to use.
|
|
See atftpd's man page.
|
|
|
|
.TP
|
|
+.B \-\-prevent\-sas
|
|
+Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350.
|
|
+This RFC requires repeated responses to a single packet to be
|
|
+rejected. Thus a block will only get retransmitted on a timeout.
|
|
+For backward compatibility, the default stays to ignore this RFC.
|
|
+So blocks get transmitted on every request.
|
|
+
|
|
+.TP
|
|
.B \-\-verbose
|
|
Instruct atftp to be verbose. It will print more information about
|
|
what's going on.
|