summaryrefslogtreecommitdiffstats
path: root/meta-networking/recipes-daemons/atftp
diff options
context:
space:
mode:
Diffstat (limited to 'meta-networking/recipes-daemons/atftp')
-rw-r--r--meta-networking/recipes-daemons/atftp/atftp/atftpd.service10
-rw-r--r--meta-networking/recipes-daemons/atftp/atftp_git.bb61
-rw-r--r--meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch94
-rw-r--r--meta-networking/recipes-daemons/atftp/files/atftpd-0.7_circumvent_tftp_size_restrictions.patch163
-rw-r--r--meta-networking/recipes-daemons/atftp/files/atftpd-0.7_unprotected_assignments_crash.patch152
-rw-r--r--meta-networking/recipes-daemons/atftp/files/atftpd.init37
6 files changed, 517 insertions, 0 deletions
diff --git a/meta-networking/recipes-daemons/atftp/atftp/atftpd.service b/meta-networking/recipes-daemons/atftp/atftp/atftpd.service
new file mode 100644
index 000000000..480bc702e
--- /dev/null
+++ b/meta-networking/recipes-daemons/atftp/atftp/atftpd.service
@@ -0,0 +1,10 @@
1[Unit]
2Description=Advanced TFTP Server
3After=syslog.target network.target
4
5[Service]
6Type=forking
7ExecStart=/usr/sbin/atftpd --daemon --port 69
8
9[Install]
10WantedBy=multi-user.target
diff --git a/meta-networking/recipes-daemons/atftp/atftp_git.bb b/meta-networking/recipes-daemons/atftp/atftp_git.bb
new file mode 100644
index 000000000..ee84f7725
--- /dev/null
+++ b/meta-networking/recipes-daemons/atftp/atftp_git.bb
@@ -0,0 +1,61 @@
1SUMMARY = "Advanced TFTP server and client"
2SECTION = "network"
3HOMEPAGE = "http://packages.debian.org/atftp"
4LICENSE = "GPLv2"
5LIC_FILES_CHKSUM = "file://LICENSE;md5=94d55d512a9ba36caa9b7df079bae19f"
6PV = "0.7.1+git${SRCPV}"
7PR = "r3"
8
9SRCREV = "be3291a18c069ae23a124ffdc56d64a5ff0bbec7"
10
11SRC_URI = "git://git.code.sf.net/p/atftp/code \
12 file://atftpd-0.7_circumvent_tftp_size_restrictions.patch \
13 file://atftpd-0.7_unprotected_assignments_crash.patch \
14 file://atftpd.init \
15 file://atftpd.service \
16 file://atftp-0.7-sorcerers_apprentice.patch \
17"
18S = "${WORKDIR}/git"
19
20inherit autotools update-rc.d useradd systemd
21
22PACKAGECONFIG ??= "tcp-wrappers"
23PACKAGECONFIG[pcre] = "--enable-libpcre,--disable-libpcre,libpcre"
24PACKAGECONFIG[tcp-wrappers] = "--enable-libwrap,--disable-libwrap,tcp-wrappers"
25PACKAGECONFIG[readline] = "--enable-libreadline,--disable-libreadline,readline"
26
27INITSCRIPT_PACKAGES = "${PN}d"
28INITSCRIPT_NAME_${PN}d = "atftpd"
29INITSCRIPT_PARAMS_${PN}d = "defaults 80"
30
31USERADD_PACKAGES = "${PN}d"
32USERADD_PARAM_${PN}d = "--system --no-create-home --shell /bin/false \
33 --user-group nobody"
34
35do_install_append() {
36 install -d ${D}${sysconfdir}/init.d
37 install -m 0755 ${WORKDIR}/atftpd.init ${D}${sysconfdir}/init.d/atftpd
38
39 install -d ${D}/srv/tftp
40
41 rm ${D}${sbindir}/in.tftpd
42
43 install -d ${D}${systemd_unitdir}/system
44 install -m 0644 ${WORKDIR}/atftpd.service ${D}${systemd_unitdir}/system
45}
46
47PACKAGES =+ "${PN}d"
48
49FILES_${PN} = "${bindir}/*"
50
51FILES_${PN}d = "${sbindir}/* \
52 ${sysconfdir} \
53 /srv/tftp \
54 ${systemd_unitdir}/system/atftpd.service \
55"
56
57SYSTEMD_PACKAGES = "${PN}d"
58SYSTEMD_SERVICE_${PN}d = "atftpd.service"
59RPROVIDES_${PN}d += "${PN}d-systemd"
60RREPLACES_${PN}d += "${PN}d-systemd"
61RCONFLICTS_${PN}d += "${PN}d-systemd"
diff --git a/meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch b/meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch
new file mode 100644
index 000000000..fc64291cd
--- /dev/null
+++ b/meta-networking/recipes-daemons/atftp/files/atftp-0.7-sorcerers_apprentice.patch
@@ -0,0 +1,94 @@
1atftp exhibits the well known "Sorcerer's Apprentice Syndrome"(SAS) problem.
2According to RFC 1350, the fix to SAS is quite simple: further copies of the
3acknowledgment for a particular data block would be ignored.
4
5Patch originally from OpenSUSE:
6https://build.opensuse.org/package/view_file?file=atftp-0.7-sorcerers_apprentice.patch&package=atftp.539&project=openSUSE%3A12.1%3AUpdate&rev=84569792975e00573d7df597d2a6e895
7
8Upstream-Status: Pending
9
10Signed-off-by: Roy.Li <rongqing.li@windriver.com>
11Index: atftp-0.7/tftp_file.c
12===================================================================
13--- atftp-0.7.orig/tftp_file.c 2011-11-22 15:12:53.792744083 +0100
14+++ atftp-0.7/tftp_file.c 2011-11-22 15:13:51.706421893 +0100
15@@ -605,6 +605,7 @@
16 int timeout_state = state; /* what state should we go on when timeout */
17 int result;
18 long block_number = 0;
19+ long last_requested_block = -1;
20 long last_block = -1;
21 int data_size; /* size of data received */
22 int sockfd = data->sockfd; /* just to simplify calls */
23@@ -765,6 +766,17 @@
24 connected = 1;
25 }
26 block_number = ntohs(tftphdr->th_block);
27+
28+ if (last_requested_block >= block_number)
29+ {
30+ if (data->trace)
31+ fprintf(stderr, "received duplicated ACK <block: %ld >= %ld>\n",
32+ last_requested_block, block_number);
33+ break;
34+ }
35+ else
36+ last_requested_block = block_number;
37+
38 if (data->trace)
39 fprintf(stderr, "received ACK <block: %ld>\n",
40 block_number);
41Index: atftp-0.7/tftpd_file.c
42===================================================================
43--- atftp-0.7.orig/tftpd_file.c 2011-11-22 15:12:53.793744112 +0100
44+++ atftp-0.7/tftpd_file.c 2011-11-22 15:15:04.617534260 +0100
45@@ -403,6 +403,7 @@
46 int timeout_state = state;
47 int result;
48 long block_number = 0;
49+ long last_requested_block = -1;
50 long last_block = -1;
51 int block_loops = 0;
52 int data_size;
53@@ -859,6 +860,32 @@
54 {
55 logger(LOG_DEBUG, "received ACK <block: %d>", block_number);
56 }
57+
58+ /* check whether the block request isn't already fulfilled */
59+
60+ /* multicast, block numbers could contain gaps */
61+ if (multicast) {
62+ if (last_requested_block >= block_number)
63+ {
64+ if (data->trace)
65+ logger(LOG_DEBUG, "received duplicated ACK <block: %d >= %d>", last_requested_block, block_number);
66+ break;
67+ }
68+ else
69+ last_requested_block = block_number;
70+ /* unicast, blocks should be requested one after another */
71+ } else {
72+ if (last_requested_block + 1 != block_number && last_requested_block != -1)
73+ {
74+ if (data->trace)
75+ logger(LOG_DEBUG, "received out of order ACK <block: %d != %d>", last_requested_block + 1, block_number);
76+ break;
77+ }
78+ else
79+ last_requested_block = block_number;
80+ }
81+
82+
83 if (ntohs(tftphdr->th_block) == 65535)
84 {
85 block_loops++;
86@@ -958,6 +985,8 @@
87 /* nedd to send an oack to that client */
88 state = S_SEND_OACK;
89 fseek(fp, 0, SEEK_SET);
90+ /* reset the last block received counter */
91+ last_requested_block = -1;
92 }
93 else
94 {
diff --git a/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_circumvent_tftp_size_restrictions.patch b/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_circumvent_tftp_size_restrictions.patch
new file mode 100644
index 000000000..280b570b2
--- /dev/null
+++ b/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_circumvent_tftp_size_restrictions.patch
@@ -0,0 +1,163 @@
1Fate #303031: Circumvent TFTP size restrictions in atftpd
2The size of a single image file that can be transferred with TFTP is limited to
32^(2*8) *BLOCKSIZE (as per RFC 1350 there are only two bytes for the block
4counter). This is problematic for one of our customers who needs to transfer
5100+ MB Windows images using a TFTP client (NT bootloader) which has a
6hardwared BLOCKSIZE setting of 1432).
7
8block rollover
9http://www.compuphase.com/tftp.htm
10
11Patch originally from OpenSUSE:
12https://build.opensuse.org/package/show?package=atftp&project=openSUSE%3A12.2
13
14Upstream-Status: Pending
15
16Index: git/tftp_def.h
17===================================================================
18--- git.orig/tftp_def.h 2012-11-19 16:28:50.221027144 -0800
19+++ git/tftp_def.h 2012-11-20 17:40:54.391206979 -0800
20@@ -32,6 +32,7 @@
21 #define TIMEOUT 5 /* Client timeout */
22 #define S_TIMEOUT 5 /* Server timout. */
23 #define NB_OF_RETRY 5
24+#define MAXBLOCKS 1000000 /* maximum number of blocks in a download */
25
26 /* definition to use tftp_options structure */
27 #define OPT_FILENAME 0
28Index: git/tftp_file.c
29===================================================================
30--- git.orig/tftp_file.c 2012-11-19 16:28:50.221027144 -0800
31+++ git/tftp_file.c 2012-11-19 16:28:51.201027167 -0800
32@@ -622,8 +622,8 @@
33 int state = S_SEND_REQ; /* current state in the state machine */
34 int timeout_state = state; /* what state should we go on when timeout */
35 int result;
36- int block_number = 0;
37- int last_block = -1;
38+ long block_number = 0;
39+ long last_block = -1;
40 int data_size; /* size of data received */
41 int sockfd = data->sockfd; /* just to simplify calls */
42 struct sockaddr_storage sa; /* a copy of data.sa_peer */
43@@ -637,8 +637,8 @@
44 int convert = 0; /* if true, do netascii convertion */
45 char string[MAXLEN];
46
47- int prev_block_number = 0; /* needed to support netascii convertion */
48- int prev_file_pos = 0;
49+ long prev_block_number = 0; /* needed to support netascii convertion */
50+ long prev_file_pos = 0;
51 int temp = 0;
52
53 data->file_size = 0;
54@@ -745,7 +745,7 @@
55 data_size, data->data_buffer);
56 data->file_size += data_size;
57 if (data->trace)
58- fprintf(stderr, "sent DATA <block: %d, size: %d>\n",
59+ fprintf(stderr, "sent DATA <block: %ld, size: %d>\n",
60 block_number + 1, data_size - 4);
61 state = S_WAIT_PACKET;
62 break;
63@@ -785,7 +785,7 @@
64 }
65 block_number = ntohs(tftphdr->th_block);
66 if (data->trace)
67- fprintf(stderr, "received ACK <block: %d>\n",
68+ fprintf(stderr, "received ACK <block: %ld>\n",
69 block_number);
70 if ((last_block != -1) && (block_number > last_block))
71 {
72Index: git/tftp_io.c
73===================================================================
74--- git.orig/tftp_io.c 2012-11-19 16:28:50.221027144 -0800
75+++ git/tftp_io.c 2012-11-19 16:28:51.201027167 -0800
76@@ -350,8 +350,8 @@
77 /*
78 * Read from file and do netascii conversion if needed
79 */
80-int tftp_file_read(FILE *fp, char *data_buffer, int data_buffer_size, int block_number,
81- int convert, int *prev_block_number, int *prev_file_pos, int *temp)
82+int tftp_file_read(FILE *fp, char *data_buffer, int data_buffer_size, long block_number,
83+ int convert, long *prev_block_number, long *prev_file_pos, int *temp)
84 {
85 int i;
86 int c;
87Index: git/tftp_io.h
88===================================================================
89--- git.orig/tftp_io.h 2012-11-19 16:28:50.221027144 -0800
90+++ git/tftp_io.h 2012-11-19 16:28:51.201027167 -0800
91@@ -52,8 +52,8 @@
92 int tftp_get_packet(int sock1, int sock2, int *sock, struct sockaddr_storage *sa,
93 struct sockaddr_storage *from, struct sockaddr_storage *to,
94 int timeout, int *size, char *data);
95-int tftp_file_read(FILE *fp, char *buffer, int buffer_size, int block_number, int convert,
96- int *prev_block_number, int *prev_file_pos, int *temp);
97+int tftp_file_read(FILE *fp, char *buffer, int buffer_size, long block_number, int convert,
98+ long *prev_block_number, long *prev_file_pos, int *temp);
99 int tftp_file_write(FILE *fp, char *data_buffer, int data_buffer_size, int block_number,
100 int data_size, int convert, int *prev_block_number, int *temp);
101 #endif
102Index: git/tftpd_file.c
103===================================================================
104--- git.orig/tftpd_file.c 2012-11-19 16:28:50.225027144 -0800
105+++ git/tftpd_file.c 2012-11-19 16:28:51.201027167 -0800
106@@ -407,8 +407,9 @@
107 int state = S_BEGIN;
108 int timeout_state = state;
109 int result;
110- int block_number = 0;
111- int last_block = -1;
112+ long block_number = 0;
113+ long last_block = -1;
114+ int block_loops = 0;
115 int data_size;
116 struct sockaddr_storage *sa = &data->client_info->client;
117 struct sockaddr_storage from;
118@@ -431,8 +432,8 @@
119 struct client_info *client_old = NULL;
120 struct tftp_opt options[OPT_NUMBER];
121
122- int prev_block_number = 0; /* needed to support netascii convertion */
123- int prev_file_pos = 0;
124+ long prev_block_number = 0; /* needed to support netascii convertion */
125+ long prev_file_pos = 0;
126 int temp = 0;
127
128 /* look for mode option */
129@@ -565,11 +566,12 @@
130 logger(LOG_INFO, "blksize option -> %d", result);
131 }
132
133- /* Verify that the file can be sent in 2^16 block of BLKSIZE octets */
134- if ((file_stat.st_size / (data->data_buffer_size - 4)) > 65535)
135+ /* Verify that the file can be sent in MAXBLOCKS blocks of BLKSIZE octets */
136+ if ((file_stat.st_size / (data->data_buffer_size - 4)) > MAXBLOCKS)
137 {
138 tftp_send_error(sockfd, sa, EUNDEF, data->data_buffer, data->data_buffer_size);
139- logger(LOG_NOTICE, "Requested file to big, increase BLKSIZE");
140+ logger(LOG_NOTICE, "Requested file too big, increase BLKSIZE");
141+ logger(LOG_NOTICE, "Only %d blocks of %d bytes can be served.", MAXBLOCKS, data->data_buffer_size);
142 if (data->trace)
143 logger(LOG_DEBUG, "sent ERROR <code: %d, msg: %s>", EUNDEF,
144 tftp_errmsg[EUNDEF]);
145@@ -880,10 +882,15 @@
146 }
147 /* The ACK is from the current client */
148 number_of_timeout = 0;
149- block_number = ntohs(tftphdr->th_block);
150+ block_number = (block_loops * 65536) + ntohs(tftphdr->th_block);
151 if (data->trace)
152- logger(LOG_DEBUG, "received ACK <block: %d>",
153- block_number);
154+ {
155+ logger(LOG_DEBUG, "received ACK <block: %d>", block_number);
156+ }
157+ if (ntohs(tftphdr->th_block) == 65535)
158+ {
159+ block_loops++;
160+ };
161 if ((last_block != -1) && (block_number > last_block))
162 {
163 state = S_END;
diff --git a/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_unprotected_assignments_crash.patch b/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_unprotected_assignments_crash.patch
new file mode 100644
index 000000000..28fba6cf5
--- /dev/null
+++ b/meta-networking/recipes-daemons/atftp/files/atftpd-0.7_unprotected_assignments_crash.patch
@@ -0,0 +1,152 @@
1Avoid assigning thread data outside of mutex lock
2
3Patch originally from OpenSUSE:
4https://build.opensuse.org/package/show?package=atftp&project=openSUSE%3A12.2
5
6Upstream-Status: Pending
7
8Index: git/tftpd_list.c
9===================================================================
10--- git.orig/tftpd_list.c 2012-10-24 21:48:47.000000000 -0700
11+++ git/tftpd_list.c 2012-10-24 21:52:04.266205076 -0700
12@@ -49,11 +49,11 @@
13 */
14 int tftpd_list_add(struct thread_data *new)
15 {
16- struct thread_data *current = thread_data;
17+ struct thread_data *current;
18 int ret;
19
20 pthread_mutex_lock(&thread_list_mutex);
21-
22+ current = thread_data;
23 number_of_thread++;
24
25 ret = number_of_thread;
26@@ -81,11 +81,13 @@
27 */
28 int tftpd_list_remove(struct thread_data *old)
29 {
30- struct thread_data *current = thread_data;
31+ struct thread_data *current;
32 int ret;
33
34 pthread_mutex_lock(&thread_list_mutex);
35
36+ current = thread_data;
37+
38 number_of_thread--;
39 ret = number_of_thread;
40
41@@ -137,23 +139,26 @@
42 struct thread_data *data,
43 struct client_info *client)
44 {
45- struct thread_data *current = thread_data; /* head of the list */
46- struct tftp_opt *tftp_options = data->tftp_options;
47+ struct thread_data *current; /* head of the list */
48+ struct tftp_opt *tftp_options;
49 struct client_info *tmp;
50 char options[MAXLEN];
51 char string[MAXLEN];
52 char *index;
53 int len;
54
55+ /* lock the whole list before walking it */
56+ pthread_mutex_lock(&thread_list_mutex);
57+
58 *thread = NULL;
59
60+ current = thread_data;
61+ tftp_options = data->tftp_options;
62+
63 opt_request_to_string(tftp_options, options, MAXLEN);
64 index = strstr(options, "multicast");
65 len = (int)index - (int)options;
66
67- /* lock the whole list before walking it */
68- pthread_mutex_lock(&thread_list_mutex);
69-
70 while (current)
71 {
72 if (current != data)
73@@ -214,9 +219,10 @@
74 void tftpd_clientlist_remove(struct thread_data *thread,
75 struct client_info *client)
76 {
77- struct client_info *tmp = thread->client_info;
78+ struct client_info *tmp;
79
80 pthread_mutex_lock(&thread->client_mutex);
81+ tmp = thread->client_info;
82 while ((tmp->next != client) && (tmp->next != NULL))
83 tmp = tmp->next;
84 if (tmp->next == NULL)
85@@ -231,9 +237,11 @@
86 void tftpd_clientlist_free(struct thread_data *thread)
87 {
88 struct client_info *tmp;
89- struct client_info *head = thread->client_info;
90+ struct client_info *head;
91
92 pthread_mutex_lock(&thread->client_mutex);
93+ head = thread->client_info;
94+
95 while (head)
96 {
97 tmp = head;
98@@ -250,9 +258,10 @@
99 struct client_info *client,
100 struct sockaddr_storage *sock)
101 {
102- struct client_info *head = thread->client_info;
103+ struct client_info *head;
104
105 pthread_mutex_lock(&thread->client_mutex);
106+ head = thread->client_info;
107
108 if (client)
109 {
110@@ -334,10 +343,10 @@
111
112 void tftpd_list_kill_threads(void)
113 {
114- struct thread_data *current = thread_data; /* head of list */
115+ struct thread_data *current; /* head of list */
116
117 pthread_mutex_lock(&thread_list_mutex);
118-
119+ current = thread_data;
120
121 while (current != NULL)
122 {
123Index: git/tftpd_mcast.c
124===================================================================
125--- git.orig/tftpd_mcast.c 2012-10-24 21:48:47.000000000 -0700
126+++ git/tftpd_mcast.c 2012-10-24 21:49:11.570201582 -0700
127@@ -51,9 +51,11 @@
128 */
129 int tftpd_mcast_get_tid(char **addr, short *port)
130 {
131- struct tid *current = tid_list;
132+ struct tid *current;
133
134 pthread_mutex_lock(&mcast_tid_list);
135+ current = tid_list;
136+
137 /* walk the list for a free tid */
138 while (current != NULL)
139 {
140@@ -74,9 +76,11 @@
141
142 int tftpd_mcast_free_tid(char *addr, short port)
143 {
144- struct tid *current = tid_list;
145+ struct tid *current;
146
147 pthread_mutex_lock(&mcast_tid_list);
148+ current = tid_list;
149+
150 while (current != NULL)
151 {
152 if ((current->used == 1) && (current->port == port) &&
diff --git a/meta-networking/recipes-daemons/atftp/files/atftpd.init b/meta-networking/recipes-daemons/atftp/files/atftpd.init
new file mode 100644
index 000000000..161d97aca
--- /dev/null
+++ b/meta-networking/recipes-daemons/atftp/files/atftpd.init
@@ -0,0 +1,37 @@
1#! /bin/sh
2#
3# This is an init script for openembedded
4# Copy it to /etc/init.d/atftpd and type
5# > update-rc.d atftpd defaults 60
6#
7
8
9test -f /usr/sbin/atftpd || exit 0
10
11test -d /srv/tftp || mkdir -p /srv/tftp
12
13case "$1" in
14 start)
15 echo -n "Starting tftp daemon: atftpd"
16 start-stop-daemon --start --quiet --exec /usr/sbin/atftpd -- --daemon --port 69
17 echo "."
18 ;;
19 stop)
20 echo -n "Stopping tftp daemon: atftpd"
21 start-stop-daemon --stop --quiet --exec /usr/sbin/atftpd
22 echo "."
23 ;;
24 reload|force-reload)
25 start-stop-daemon --stop --quiet --signal 1 --exec /usr/sbin/atftpd
26 ;;
27 restart)
28 $0 stop
29 sleep 1
30 $0 start
31 ;;
32 *)
33 echo "Usage: /etc/init.d/atftpd {start|stop|reload|restart|force-reload}"
34 exit 1
35esac
36
37exit 0