1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2008 Edwin Groothuis. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <sys/stat.h>
31
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <arpa/tftp.h>
35
36 #include <assert.h>
37 #include <errno.h>
38 #include <poll.h>
39 #include <stddef.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <syslog.h>
44 #include <unistd.h>
45
46 #include "tftp-file.h"
47 #include "tftp-io.h"
48 #include "tftp-utils.h"
49 #include "tftp-options.h"
50
51 struct sockaddr_storage peer_sock;
52 struct sockaddr_storage me_sock;
53
54 static int send_packet(int peer, uint16_t block, char *pkt, int size);
55
56 static struct errmsg {
57 int e_code;
58 const char *e_msg;
59 } errmsgs[] = {
60 { EUNDEF, "Undefined error code" },
61 { ENOTFOUND, "File not found" },
62 { EACCESS, "Access violation" },
63 { ENOSPACE, "Disk full or allocation exceeded" },
64 { EBADOP, "Illegal TFTP operation" },
65 { EBADID, "Unknown transfer ID" },
66 { EEXISTS, "File already exists" },
67 { ENOUSER, "No such user" },
68 { EOPTNEG, "Option negotiation" },
69 { -1, NULL }
70 };
71
72 #define DROPPACKET(s) \
73 if (packetdroppercentage != 0 && \
74 arc4random()%100 < packetdroppercentage) { \
75 tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \
76 return; \
77 }
78 #define DROPPACKETn(s,n) \
79 if (packetdroppercentage != 0 && \
80 arc4random()%100 < packetdroppercentage) { \
81 tftp_log(LOG_DEBUG, "Artificial packet drop in %s", s); \
82 return (n); \
83 }
84
85 const char *
errtomsg(int error)86 errtomsg(int error)
87 {
88 static char ebuf[40];
89 struct errmsg *pe;
90
91 if (error == 0)
92 return ("success");
93 for (pe = errmsgs; pe->e_code >= 0; pe++)
94 if (pe->e_code == error)
95 return (pe->e_msg);
96 snprintf(ebuf, sizeof(ebuf), "error %d", error);
97 return (ebuf);
98 }
99
100 static int
send_packet(int peer,uint16_t block,char * pkt,int size)101 send_packet(int peer, uint16_t block, char *pkt, int size)
102 {
103 int i;
104 int t = 1;
105
106 for (i = 0; i < 12 ; i++) {
107 DROPPACKETn("send_packet", 0);
108
109 if (sendto(peer, pkt, size, 0, (struct sockaddr *)&peer_sock,
110 peer_sock.ss_len) == size) {
111 if (i)
112 tftp_log(LOG_ERR,
113 "%s block %d, attempt %d successful",
114 packettype(ntohs(((struct tftphdr *)
115 (pkt))->th_opcode)), block, i);
116 return (0);
117 }
118 tftp_log(LOG_ERR,
119 "%s block %d, attempt %d failed (Error %d: %s)",
120 packettype(ntohs(((struct tftphdr *)(pkt))->th_opcode)),
121 block, i, errno, strerror(errno));
122 sleep(t);
123 if (t < 32)
124 t <<= 1;
125 }
126 tftp_log(LOG_ERR, "send_packet: %s", strerror(errno));
127 return (1);
128 }
129
130 /*
131 * Send an ERROR packet (error message).
132 * Error code passed in is one of the
133 * standard TFTP codes, or a UNIX errno
134 * offset by 100.
135 */
136 void
send_error(int peer,int error)137 send_error(int peer, int error)
138 {
139 struct tftphdr *tp;
140 int length;
141 struct errmsg *pe;
142 char buf[MAXPKTSIZE];
143
144 if (debug & DEBUG_PACKETS)
145 tftp_log(LOG_DEBUG, "Sending ERROR %d", error);
146
147 DROPPACKET("send_error");
148
149 tp = (struct tftphdr *)buf;
150 tp->th_opcode = htons((u_short)ERROR);
151 tp->th_code = htons((u_short)error);
152 for (pe = errmsgs; pe->e_code >= 0; pe++)
153 if (pe->e_code == error)
154 break;
155 if (pe->e_code < 0) {
156 pe->e_msg = strerror(error - 100);
157 tp->th_code = EUNDEF; /* set 'undef' errorcode */
158 }
159 snprintf(tp->th_msg, MAXPKTSIZE - 4, "%s%n", pe->e_msg, &length);
160 length += 5; /* header and terminator */
161
162 if (debug & DEBUG_PACKETS)
163 tftp_log(LOG_DEBUG, "Sending ERROR %d: %s", error, tp->th_msg);
164
165 if (sendto(peer, buf, length, 0,
166 (struct sockaddr *)&peer_sock, peer_sock.ss_len) != length)
167 tftp_log(LOG_ERR, "send_error: %s", strerror(errno));
168 }
169
170 /*
171 * Send an WRQ packet (write request).
172 */
173 int
send_wrq(int peer,char * filename,char * mode)174 send_wrq(int peer, char *filename, char *mode)
175 {
176 int n;
177 struct tftphdr *tp;
178 char *bp;
179 char buf[MAXPKTSIZE];
180 int size;
181
182 if (debug & DEBUG_PACKETS)
183 tftp_log(LOG_DEBUG, "Sending WRQ: filename: '%s', mode '%s'",
184 filename, mode
185 );
186
187 DROPPACKETn("send_wrq", 0);
188
189 tp = (struct tftphdr *)buf;
190 tp->th_opcode = htons((u_short)WRQ);
191 size = offsetof(struct tftphdr, th_stuff);
192
193 bp = tp->th_stuff;
194 strlcpy(bp, filename, sizeof(buf) - size);
195 bp += strlen(filename);
196 *bp = 0;
197 bp++;
198 size += strlen(filename) + 1;
199
200 strlcpy(bp, mode, sizeof(buf) - size);
201 bp += strlen(mode);
202 *bp = 0;
203 bp++;
204 size += strlen(mode) + 1;
205
206 if (options_rfc_enabled)
207 size += make_options(peer, bp, sizeof(buf) - size);
208
209 n = sendto(peer, buf, size, 0,
210 (struct sockaddr *)&peer_sock, peer_sock.ss_len);
211 if (n != size) {
212 tftp_log(LOG_ERR, "send_wrq: %s", strerror(errno));
213 return (1);
214 }
215 return (0);
216 }
217
218 /*
219 * Send an RRQ packet (write request).
220 */
221 int
send_rrq(int peer,char * filename,char * mode)222 send_rrq(int peer, char *filename, char *mode)
223 {
224 int n;
225 struct tftphdr *tp;
226 char *bp;
227 char buf[MAXPKTSIZE];
228 int size;
229
230 if (debug & DEBUG_PACKETS)
231 tftp_log(LOG_DEBUG, "Sending RRQ: filename: '%s', mode '%s'",
232 filename, mode
233 );
234
235 DROPPACKETn("send_rrq", 0);
236
237 tp = (struct tftphdr *)buf;
238 tp->th_opcode = htons((u_short)RRQ);
239 size = offsetof(struct tftphdr, th_stuff);
240
241 bp = tp->th_stuff;
242 strlcpy(bp, filename, sizeof(buf) - size);
243 bp += strlen(filename);
244 *bp = 0;
245 bp++;
246 size += strlen(filename) + 1;
247
248 strlcpy(bp, mode, sizeof(buf) - size);
249 bp += strlen(mode);
250 *bp = 0;
251 bp++;
252 size += strlen(mode) + 1;
253
254 if (options_rfc_enabled) {
255 options_set_request(OPT_TSIZE, "0");
256 size += make_options(peer, bp, sizeof(buf) - size);
257 }
258
259 n = sendto(peer, buf, size, 0,
260 (struct sockaddr *)&peer_sock, peer_sock.ss_len);
261 if (n != size) {
262 tftp_log(LOG_ERR, "send_rrq: %d %s", n, strerror(errno));
263 return (1);
264 }
265 return (0);
266 }
267
268 /*
269 * Send an OACK packet (option acknowledgement).
270 */
271 int
send_oack(int peer)272 send_oack(int peer)
273 {
274 struct tftphdr *tp;
275 int size, i, n;
276 char *bp;
277 char buf[MAXPKTSIZE];
278
279 if (debug & DEBUG_PACKETS)
280 tftp_log(LOG_DEBUG, "Sending OACK");
281
282 DROPPACKETn("send_oack", 0);
283
284 /*
285 * Send back an options acknowledgement (only the ones with
286 * a reply for)
287 */
288 tp = (struct tftphdr *)buf;
289 bp = buf + 2;
290 size = sizeof(buf) - 2;
291 tp->th_opcode = htons((u_short)OACK);
292 for (i = 0; options[i].o_type != NULL; i++) {
293 if (options[i].o_reply != NULL) {
294 n = snprintf(bp, size, "%s%c%s", options[i].o_type,
295 0, options[i].o_reply);
296 bp += n+1;
297 size -= n+1;
298 if (size < 0) {
299 tftp_log(LOG_ERR, "oack: buffer overflow");
300 exit(1);
301 }
302 }
303 }
304 size = bp - buf;
305
306 if (sendto(peer, buf, size, 0,
307 (struct sockaddr *)&peer_sock, peer_sock.ss_len) != size) {
308 tftp_log(LOG_INFO, "send_oack: %s", strerror(errno));
309 return (1);
310 }
311
312 return (0);
313 }
314
315 /*
316 * Send an ACK packet (acknowledgement).
317 */
318 int
send_ack(int fp,uint16_t block)319 send_ack(int fp, uint16_t block)
320 {
321 struct tftphdr *tp;
322 int size;
323 char buf[MAXPKTSIZE];
324
325 if (debug & DEBUG_PACKETS)
326 tftp_log(LOG_DEBUG, "Sending ACK for block %d", block);
327
328 DROPPACKETn("send_ack", 0);
329
330 tp = (struct tftphdr *)buf;
331 tp->th_opcode = htons((u_short)ACK);
332 tp->th_block = htons((u_short)block);
333 size = 4;
334
335 if (sendto(fp, buf, size, 0,
336 (struct sockaddr *)&peer_sock, peer_sock.ss_len) != size) {
337 tftp_log(LOG_INFO, "send_ack: %s", strerror(errno));
338 return (1);
339 }
340
341 return (0);
342 }
343
344 /*
345 * Send a DATA packet
346 */
347 int
send_data(int peer,uint16_t block,char * data,int size)348 send_data(int peer, uint16_t block, char *data, int size)
349 {
350 char buf[MAXPKTSIZE];
351 struct tftphdr *pkt;
352 int n;
353
354 if (debug & DEBUG_PACKETS)
355 tftp_log(LOG_DEBUG, "Sending DATA packet %d of %d bytes",
356 block, size);
357
358 DROPPACKETn("send_data", 0);
359
360 pkt = (struct tftphdr *)buf;
361
362 pkt->th_opcode = htons((u_short)DATA);
363 pkt->th_block = htons((u_short)block);
364 memcpy(pkt->th_data, data, size);
365
366 n = send_packet(peer, block, (char *)pkt, size + 4);
367 return (n);
368 }
369
370
371 /*
372 * Receive a packet
373 *
374 * If timeout is negative, no error will be logged on timeout.
375 */
376 int
receive_packet(int peer,char * data,int size,struct sockaddr_storage * from,int timeout)377 receive_packet(int peer, char *data, int size, struct sockaddr_storage *from,
378 int timeout)
379 {
380 struct pollfd pfd;
381 struct tftphdr *pkt;
382 struct sockaddr_storage from_local;
383 struct sockaddr_storage *pfrom;
384 socklen_t fromlen;
385 int n;
386
387 if (debug & DEBUG_PACKETS)
388 tftp_log(LOG_DEBUG,
389 "Waiting %d seconds for packet", timeoutpacket);
390
391 pkt = (struct tftphdr *)data;
392
393 pfd.fd = peer;
394 pfd.events = POLLIN;
395 if (poll(&pfd, 1, 1000 * (timeout < 0 ? -timeout : timeout)) < 1) {
396 if (timeout > 0)
397 tftp_log(LOG_ERR, "receive_packet: timeout");
398 return (RP_TIMEOUT);
399 }
400
401 pfrom = (from == NULL) ? &from_local : from;
402 fromlen = sizeof(*pfrom);
403 n = recvfrom(peer, data, size, 0, (struct sockaddr *)pfrom, &fromlen);
404
405 DROPPACKETn("receive_packet", RP_TIMEOUT);
406
407 if (n < 0) {
408 /* No idea what could have happened if it isn't a timeout */
409 tftp_log(LOG_ERR, "receive_packet: %s", strerror(errno));
410 return (RP_RECVFROM);
411 }
412 if (n < 4) {
413 tftp_log(LOG_ERR,
414 "receive_packet: packet too small (%d bytes)", n);
415 return (RP_TOOSMALL);
416 }
417
418 pkt->th_opcode = ntohs((u_short)pkt->th_opcode);
419 if (pkt->th_opcode == DATA ||
420 pkt->th_opcode == ACK)
421 pkt->th_block = ntohs((u_short)pkt->th_block);
422
423 if (pkt->th_opcode == DATA && n > pktsize) {
424 tftp_log(LOG_ERR, "receive_packet: packet too big");
425 return (RP_TOOBIG);
426 }
427
428 if (((struct sockaddr_in *)(pfrom))->sin_addr.s_addr !=
429 ((struct sockaddr_in *)(&peer_sock))->sin_addr.s_addr) {
430 tftp_log(LOG_ERR,
431 "receive_packet: received packet from wrong source");
432 return (RP_WRONGSOURCE);
433 }
434
435 if (pkt->th_opcode == ERROR) {
436 tftp_log(pkt->th_code == EUNDEF ? LOG_DEBUG : LOG_ERR,
437 "Got ERROR packet: %s", pkt->th_msg);
438 return (RP_ERROR);
439 }
440
441 if (debug & DEBUG_PACKETS)
442 tftp_log(LOG_DEBUG, "Received %d bytes in a %s packet",
443 n, packettype(pkt->th_opcode));
444
445 return n - 4;
446 }
447