dnsmasq: v2.67test16 patch Sept.25th/2013.
[tomato.git] / release / src / router / dnsmasq / src / tftp.c
blobd752e7125d00896b6c4a0785bc7081ed3cbb6f91
1 /* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "dnsmasq.h"
19 #ifdef HAVE_TFTP
21 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix);
22 static void free_transfer(struct tftp_transfer *transfer);
23 static ssize_t tftp_err(int err, char *packet, char *mess, char *file);
24 static ssize_t tftp_err_oops(char *packet, char *file);
25 static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
26 static char *next(char **p, char *end);
27 static void sanitise(char *buf);
29 #define OP_RRQ 1
30 #define OP_WRQ 2
31 #define OP_DATA 3
32 #define OP_ACK 4
33 #define OP_ERR 5
34 #define OP_OACK 6
36 #define ERR_NOTDEF 0
37 #define ERR_FNF 1
38 #define ERR_PERM 2
39 #define ERR_FULL 3
40 #define ERR_ILL 4
42 void tftp_request(struct listener *listen, time_t now)
44 ssize_t len;
45 char *packet = daemon->packet;
46 char *filename, *mode, *p, *end, *opt;
47 union mysockaddr addr, peer;
48 struct msghdr msg;
49 struct iovec iov;
50 struct ifreq ifr;
51 int is_err = 1, if_index = 0, mtu = 0;
52 struct iname *tmp;
53 struct tftp_transfer *transfer;
54 int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
55 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
56 int mtuflag = IP_PMTUDISC_DONT;
57 #endif
58 char namebuff[IF_NAMESIZE];
59 char *name = NULL;
60 char *prefix = daemon->tftp_prefix;
61 struct tftp_prefix *pref;
62 struct all_addr addra;
64 union {
65 struct cmsghdr align; /* this ensures alignment */
66 #ifdef HAVE_IPV6
67 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
68 #endif
69 #if defined(HAVE_LINUX_NETWORK)
70 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
71 #elif defined(HAVE_SOLARIS_NETWORK)
72 char control[CMSG_SPACE(sizeof(unsigned int))];
73 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
74 char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
75 #endif
76 } control_u;
78 msg.msg_controllen = sizeof(control_u);
79 msg.msg_control = control_u.control;
80 msg.msg_flags = 0;
81 msg.msg_name = &peer;
82 msg.msg_namelen = sizeof(peer);
83 msg.msg_iov = &iov;
84 msg.msg_iovlen = 1;
86 iov.iov_base = packet;
87 iov.iov_len = daemon->packet_buff_sz;
89 /* we overwrote the buffer... */
90 daemon->srv_save = NULL;
92 if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
93 return;
95 if (option_bool(OPT_NOWILD))
97 if (listen->iface)
99 addr = listen->iface->addr;
100 mtu = listen->iface->mtu;
101 name = listen->iface->name;
103 else
105 /* we're listening on an address that doesn't appear on an interface,
106 ask the kernel what the socket is bound to */
107 socklen_t tcp_len = sizeof(union mysockaddr);
108 if (getsockname(listen->tftpfd, (struct sockaddr *)&addr, &tcp_len) == -1)
109 return;
112 else
114 struct cmsghdr *cmptr;
116 if (msg.msg_controllen < sizeof(struct cmsghdr))
117 return;
119 addr.sa.sa_family = listen->family;
121 #if defined(HAVE_LINUX_NETWORK)
122 if (listen->family == AF_INET)
123 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
124 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
126 union {
127 unsigned char *c;
128 struct in_pktinfo *p;
129 } p;
130 p.c = CMSG_DATA(cmptr);
131 addr.in.sin_addr = p.p->ipi_spec_dst;
132 if_index = p.p->ipi_ifindex;
135 #elif defined(HAVE_SOLARIS_NETWORK)
136 if (listen->family == AF_INET)
137 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
139 union {
140 unsigned char *c;
141 struct in_addr *a;
142 unsigned int *i;
143 } p;
144 p.c = CMSG_DATA(cmptr);
145 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
146 addr.in.sin_addr = *(p.a);
147 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
148 if_index = *(p.i);
151 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
152 if (listen->family == AF_INET)
153 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
155 union {
156 unsigned char *c;
157 struct in_addr *a;
158 struct sockaddr_dl *s;
159 } p;
160 p.c = CMSG_DATA(cmptr);
161 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
162 addr.in.sin_addr = *(p.a);
163 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
164 if_index = p.s->sdl_index;
167 #endif
169 #ifdef HAVE_IPV6
170 if (listen->family == AF_INET6)
172 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
173 if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
175 union {
176 unsigned char *c;
177 struct in6_pktinfo *p;
178 } p;
179 p.c = CMSG_DATA(cmptr);
181 addr.in6.sin6_addr = p.p->ipi6_addr;
182 if_index = p.p->ipi6_ifindex;
185 #endif
187 if (!indextoname(listen->tftpfd, if_index, namebuff))
188 return;
190 name = namebuff;
192 addra.addr.addr4 = addr.in.sin_addr;
194 #ifdef HAVE_IPV6
195 if (listen->family == AF_INET6)
196 addra.addr.addr6 = addr.in6.sin6_addr;
197 #endif
199 if (daemon->tftp_interfaces)
201 /* dedicated tftp interface list */
202 for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
203 if (tmp->name && wildcard_match(tmp->name, name))
204 break;
206 if (!tmp)
207 return;
209 else
211 /* Do the same as DHCP */
212 if (!iface_check(listen->family, &addra, name, NULL))
214 if (!option_bool(OPT_CLEVERBIND))
215 enumerate_interfaces(0);
216 if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
217 !label_exception(if_index, listen->family, &addra) )
218 return;
221 #ifdef HAVE_DHCP
222 /* allowed interfaces are the same as for DHCP */
223 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
224 if (tmp->name && wildcard_match(tmp->name, name))
225 return;
226 #endif
229 strncpy(ifr.ifr_name, name, IF_NAMESIZE);
230 if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
231 mtu = ifr.ifr_mtu;
234 if (name)
236 /* check for per-interface prefix */
237 for (pref = daemon->if_prefix; pref; pref = pref->next)
238 if (strcmp(pref->interface, name) == 0)
239 prefix = pref->prefix;
242 if (listen->family == AF_INET)
244 addr.in.sin_port = htons(port);
245 #ifdef HAVE_SOCKADDR_SA_LEN
246 addr.in.sin_len = sizeof(addr.in);
247 #endif
249 #ifdef HAVE_IPV6
250 else
252 addr.in6.sin6_port = htons(port);
253 addr.in6.sin6_flowinfo = 0;
254 addr.in6.sin6_scope_id = 0;
255 #ifdef HAVE_SOCKADDR_SA_LEN
256 addr.in6.sin6_len = sizeof(addr.in6);
257 #endif
259 #endif
261 if (!(transfer = whine_malloc(sizeof(struct tftp_transfer))))
262 return;
264 if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
266 free(transfer);
267 return;
270 transfer->peer = peer;
271 transfer->timeout = now + 2;
272 transfer->backoff = 1;
273 transfer->block = 1;
274 transfer->blocksize = 512;
275 transfer->offset = 0;
276 transfer->file = NULL;
277 transfer->opt_blocksize = transfer->opt_transize = 0;
278 transfer->netascii = transfer->carrylf = 0;
280 prettyprint_addr(&peer, daemon->addrbuff);
282 /* if we have a nailed-down range, iterate until we find a free one. */
283 while (1)
285 if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
286 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
287 setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
288 #endif
289 !fix_fd(transfer->sockfd))
291 if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
293 if (++port <= daemon->end_tftp_port)
295 if (listen->family == AF_INET)
296 addr.in.sin_port = htons(port);
297 #ifdef HAVE_IPV6
298 else
299 addr.in6.sin6_port = htons(port);
300 #endif
301 continue;
303 my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
305 free_transfer(transfer);
306 return;
308 break;
311 p = packet + 2;
312 end = packet + len;
314 if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
315 !(filename = next(&p, end)) ||
316 !(mode = next(&p, end)) ||
317 (strcasecmp(mode, "octet") != 0 && strcasecmp(mode, "netascii") != 0))
319 len = tftp_err(ERR_ILL, packet, _("unsupported request from %s"), daemon->addrbuff);
320 is_err = 1;
322 else
324 if (strcasecmp(mode, "netascii") == 0)
325 transfer->netascii = 1;
327 while ((opt = next(&p, end)))
329 if (strcasecmp(opt, "blksize") == 0)
331 if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
333 transfer->blocksize = atoi(opt);
334 if (transfer->blocksize < 1)
335 transfer->blocksize = 1;
336 if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
337 transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
338 /* 32 bytes for IP, UDP and TFTP headers */
339 if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)
340 transfer->blocksize = (unsigned)mtu - 32;
341 transfer->opt_blocksize = 1;
342 transfer->block = 0;
345 else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
347 transfer->opt_transize = 1;
348 transfer->block = 0;
352 /* cope with backslashes from windows boxen. */
353 for (p = filename; *p; p++)
354 if (*p == '\\')
355 *p = '/';
356 else if (option_bool(OPT_TFTP_LC))
357 *p = tolower(*p);
359 strcpy(daemon->namebuff, "/");
360 if (prefix)
362 if (prefix[0] == '/')
363 daemon->namebuff[0] = 0;
364 strncat(daemon->namebuff, prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
365 if (prefix[strlen(prefix)-1] != '/')
366 strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
368 if (option_bool(OPT_TFTP_APREF))
370 size_t oldlen = strlen(daemon->namebuff);
371 struct stat statbuf;
373 strncat(daemon->namebuff, daemon->addrbuff, (MAXDNAME-1) - strlen(daemon->namebuff));
374 strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
376 /* remove unique-directory if it doesn't exist */
377 if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
378 daemon->namebuff[oldlen] = 0;
381 /* Absolute pathnames OK if they match prefix */
382 if (filename[0] == '/')
384 if (strstr(filename, daemon->namebuff) == filename)
385 daemon->namebuff[0] = 0;
386 else
387 filename++;
390 else if (filename[0] == '/')
391 daemon->namebuff[0] = 0;
392 strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
394 /* check permissions and open file */
395 if ((transfer->file = check_tftp_fileperm(&len, prefix)))
397 if ((len = get_block(packet, transfer)) == -1)
398 len = tftp_err_oops(packet, daemon->namebuff);
399 else
400 is_err = 0;
404 while (sendto(transfer->sockfd, packet, len, 0,
405 (struct sockaddr *)&peer, sa_len(&peer)) == -1 && errno == EINTR);
407 if (is_err)
408 free_transfer(transfer);
409 else
411 transfer->next = daemon->tftp_trans;
412 daemon->tftp_trans = transfer;
416 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix)
418 char *packet = daemon->packet, *namebuff = daemon->namebuff;
419 struct tftp_file *file;
420 struct tftp_transfer *t;
421 uid_t uid = geteuid();
422 struct stat statbuf;
423 int fd = -1;
425 /* trick to ban moving out of the subtree */
426 if (prefix && strstr(namebuff, "/../"))
427 goto perm;
429 if ((fd = open(namebuff, O_RDONLY)) == -1)
431 if (errno == ENOENT)
433 *len = tftp_err(ERR_FNF, packet, _("file %s not found"), namebuff);
434 return NULL;
436 else if (errno == EACCES)
437 goto perm;
438 else
439 goto oops;
442 /* stat the file descriptor to avoid stat->open races */
443 if (fstat(fd, &statbuf) == -1)
444 goto oops;
446 /* running as root, must be world-readable */
447 if (uid == 0)
449 if (!(statbuf.st_mode & S_IROTH))
450 goto perm;
452 /* in secure mode, must be owned by user running dnsmasq */
453 else if (option_bool(OPT_TFTP_SECURE) && uid != statbuf.st_uid)
454 goto perm;
456 /* If we're doing many tranfers from the same file, only
457 open it once this saves lots of file descriptors
458 when mass-booting a big cluster, for instance.
459 Be conservative and only share when inode and name match
460 this keeps error messages sane. */
461 for (t = daemon->tftp_trans; t; t = t->next)
462 if (t->file->dev == statbuf.st_dev &&
463 t->file->inode == statbuf.st_ino &&
464 strcmp(t->file->filename, namebuff) == 0)
466 close(fd);
467 t->file->refcount++;
468 return t->file;
471 if (!(file = whine_malloc(sizeof(struct tftp_file) + strlen(namebuff) + 1)))
473 errno = ENOMEM;
474 goto oops;
477 file->fd = fd;
478 file->size = statbuf.st_size;
479 file->dev = statbuf.st_dev;
480 file->inode = statbuf.st_ino;
481 file->refcount = 1;
482 strcpy(file->filename, namebuff);
483 return file;
485 perm:
486 errno = EACCES;
487 *len = tftp_err(ERR_PERM, packet, _("cannot access %s: %s"), namebuff);
488 if (fd != -1)
489 close(fd);
490 return NULL;
492 oops:
493 *len = tftp_err_oops(packet, namebuff);
494 if (fd != -1)
495 close(fd);
496 return NULL;
499 void check_tftp_listeners(fd_set *rset, time_t now)
501 struct tftp_transfer *transfer, *tmp, **up;
502 ssize_t len;
504 struct ack {
505 unsigned short op, block;
506 } *mess = (struct ack *)daemon->packet;
508 /* Check for activity on any existing transfers */
509 for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
511 tmp = transfer->next;
513 prettyprint_addr(&transfer->peer, daemon->addrbuff);
515 if (FD_ISSET(transfer->sockfd, rset))
517 /* we overwrote the buffer... */
518 daemon->srv_save = NULL;
520 if ((len = recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0)) >= (ssize_t)sizeof(struct ack))
522 if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block)
524 /* Got ack, ensure we take the (re)transmit path */
525 transfer->timeout = now;
526 transfer->backoff = 0;
527 if (transfer->block++ != 0)
528 transfer->offset += transfer->blocksize - transfer->expansion;
530 else if (ntohs(mess->op) == OP_ERR)
532 char *p = daemon->packet + sizeof(struct ack);
533 char *end = daemon->packet + len;
534 char *err = next(&p, end);
536 /* Sanitise error message */
537 if (!err)
538 err = "";
539 else
540 sanitise(err);
542 my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
543 (int)ntohs(mess->block), err,
544 daemon->addrbuff);
546 /* Got err, ensure we take abort */
547 transfer->timeout = now;
548 transfer->backoff = 100;
553 if (difftime(now, transfer->timeout) >= 0.0)
555 int endcon = 0;
557 /* timeout, retransmit */
558 transfer->timeout += 1 + (1<<transfer->backoff);
560 /* we overwrote the buffer... */
561 daemon->srv_save = NULL;
563 if ((len = get_block(daemon->packet, transfer)) == -1)
565 len = tftp_err_oops(daemon->packet, transfer->file->filename);
566 endcon = 1;
568 /* don't complain about timeout when we're awaiting the last
569 ACK, some clients never send it */
570 else if (++transfer->backoff > 7 && len != 0)
572 endcon = 1;
573 len = 0;
576 if (len != 0)
577 while(sendto(transfer->sockfd, daemon->packet, len, 0,
578 (struct sockaddr *)&transfer->peer, sa_len(&transfer->peer)) == -1 && errno == EINTR);
580 if (endcon || len == 0)
582 strcpy(daemon->namebuff, transfer->file->filename);
583 sanitise(daemon->namebuff);
584 my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
585 /* unlink */
586 *up = tmp;
587 if (endcon)
588 free_transfer(transfer);
589 else
591 /* put on queue to be sent to script and deleted */
592 transfer->next = daemon->tftp_done_trans;
593 daemon->tftp_done_trans = transfer;
595 continue;
599 up = &transfer->next;
603 static void free_transfer(struct tftp_transfer *transfer)
605 close(transfer->sockfd);
606 if (transfer->file && (--transfer->file->refcount) == 0)
608 close(transfer->file->fd);
609 free(transfer->file);
611 free(transfer);
614 static char *next(char **p, char *end)
616 char *ret = *p;
617 size_t len;
619 if (*(end-1) != 0 ||
620 *p == end ||
621 (len = strlen(ret)) == 0)
622 return NULL;
624 *p += len + 1;
625 return ret;
628 static void sanitise(char *buf)
630 unsigned char *q, *r;
631 for (q = r = (unsigned char *)buf; *r; r++)
632 if (isprint((int)*r))
633 *(q++) = *r;
634 *q = 0;
638 static ssize_t tftp_err(int err, char *packet, char *message, char *file)
640 struct errmess {
641 unsigned short op, err;
642 char message[];
643 } *mess = (struct errmess *)packet;
644 ssize_t ret = 4;
645 char *errstr = strerror(errno);
647 sanitise(file);
649 mess->op = htons(OP_ERR);
650 mess->err = htons(err);
651 ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
652 my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
654 return ret;
657 static ssize_t tftp_err_oops(char *packet, char *file)
659 /* May have >1 refs to file, so potentially mangle a copy of the name */
660 strcpy(daemon->namebuff, file);
661 return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), daemon->namebuff);
664 /* return -1 for error, zero for done. */
665 static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
667 if (transfer->block == 0)
669 /* send OACK */
670 char *p;
671 struct oackmess {
672 unsigned short op;
673 char data[];
674 } *mess = (struct oackmess *)packet;
676 p = mess->data;
677 mess->op = htons(OP_OACK);
678 if (transfer->opt_blocksize)
680 p += (sprintf(p, "blksize") + 1);
681 p += (sprintf(p, "%d", transfer->blocksize) + 1);
683 if (transfer->opt_transize)
685 p += (sprintf(p,"tsize") + 1);
686 p += (sprintf(p, "%u", (unsigned int)transfer->file->size) + 1);
689 return p - packet;
691 else
693 /* send data packet */
694 struct datamess {
695 unsigned short op, block;
696 unsigned char data[];
697 } *mess = (struct datamess *)packet;
699 size_t size = transfer->file->size - transfer->offset;
701 if (transfer->offset > transfer->file->size)
702 return 0; /* finished */
704 if (size > transfer->blocksize)
705 size = transfer->blocksize;
707 mess->op = htons(OP_DATA);
708 mess->block = htons((unsigned short)(transfer->block));
710 if (lseek(transfer->file->fd, transfer->offset, SEEK_SET) == (off_t)-1 ||
711 !read_write(transfer->file->fd, mess->data, size, 1))
712 return -1;
714 transfer->expansion = 0;
716 /* Map '\n' to CR-LF in netascii mode */
717 if (transfer->netascii)
719 size_t i;
720 int newcarrylf;
722 for (i = 0, newcarrylf = 0; i < size; i++)
723 if (mess->data[i] == '\n' && ( i != 0 || !transfer->carrylf))
725 transfer->expansion++;
727 if (size != transfer->blocksize)
728 size++; /* room in this block */
729 else if (i == size - 1)
730 newcarrylf = 1; /* don't expand LF again if it moves to the next block */
732 /* make space and insert CR */
733 memmove(&mess->data[i+1], &mess->data[i], size - (i + 1));
734 mess->data[i] = '\r';
736 i++;
738 transfer->carrylf = newcarrylf;
742 return size + 4;
747 int do_tftp_script_run(void)
749 struct tftp_transfer *transfer;
751 if ((transfer = daemon->tftp_done_trans))
753 daemon->tftp_done_trans = transfer->next;
754 #ifdef HAVE_SCRIPT
755 queue_tftp(transfer->file->size, transfer->file->filename, &transfer->peer);
756 #endif
757 free_transfer(transfer);
758 return 1;
761 return 0;
763 #endif