Dnsmasq: update to 2.66TEST16
[tomato.git] / release / src / router / dnsmasq / src / tftp.c
bloba3d111ec41248d61dc19d3c2900b889be74b366f
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 #ifdef HAVE_DHCP
53 struct iname *tmp;
54 #endif
55 struct tftp_transfer *transfer;
56 int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
57 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
58 int mtuflag = IP_PMTUDISC_DONT;
59 #endif
60 char namebuff[IF_NAMESIZE];
61 char *name = NULL;
62 char *prefix = daemon->tftp_prefix;
63 struct tftp_prefix *pref;
64 struct all_addr addra;
66 union {
67 struct cmsghdr align; /* this ensures alignment */
68 #ifdef HAVE_IPV6
69 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
70 #endif
71 #if defined(HAVE_LINUX_NETWORK)
72 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
73 #elif defined(HAVE_SOLARIS_NETWORK)
74 char control[CMSG_SPACE(sizeof(unsigned int))];
75 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
76 char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
77 #endif
78 } control_u;
80 msg.msg_controllen = sizeof(control_u);
81 msg.msg_control = control_u.control;
82 msg.msg_flags = 0;
83 msg.msg_name = &peer;
84 msg.msg_namelen = sizeof(peer);
85 msg.msg_iov = &iov;
86 msg.msg_iovlen = 1;
88 iov.iov_base = packet;
89 iov.iov_len = daemon->packet_buff_sz;
91 /* we overwrote the buffer... */
92 daemon->srv_save = NULL;
94 if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
95 return;
97 if (option_bool(OPT_NOWILD))
99 if (listen->iface)
101 addr = listen->iface->addr;
102 mtu = listen->iface->mtu;
103 name = listen->iface->name;
105 else
107 /* we're listening on an address that doesn't appear on an interface,
108 ask the kernel what the socket is bound to */
109 socklen_t tcp_len = sizeof(union mysockaddr);
110 if (getsockname(listen->tftpfd, (struct sockaddr *)&addr, &tcp_len) == -1)
111 return;
114 else
116 struct cmsghdr *cmptr;
118 if (msg.msg_controllen < sizeof(struct cmsghdr))
119 return;
121 addr.sa.sa_family = listen->family;
123 #if defined(HAVE_LINUX_NETWORK)
124 if (listen->family == AF_INET)
125 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
126 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
128 union {
129 unsigned char *c;
130 struct in_pktinfo *p;
131 } p;
132 p.c = CMSG_DATA(cmptr);
133 addr.in.sin_addr = p.p->ipi_spec_dst;
134 if_index = p.p->ipi_ifindex;
137 #elif defined(HAVE_SOLARIS_NETWORK)
138 if (listen->family == AF_INET)
139 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
141 union {
142 unsigned char *c;
143 struct in_addr *a;
144 unsigned int *i;
145 } p;
146 p.c = CMSG_DATA(cmptr);
147 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
148 addr.in.sin_addr = *(p.a);
149 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
150 if_index = *(p.i);
153 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
154 if (listen->family == AF_INET)
155 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
157 union {
158 unsigned char *c;
159 struct in_addr *a;
160 struct sockaddr_dl *s;
161 } p;
162 p.c = CMSG_DATA(cmptr);
163 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
164 addr.in.sin_addr = *(p.a);
165 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
166 if_index = p.s->sdl_index;
169 #endif
171 #ifdef HAVE_IPV6
172 if (listen->family == AF_INET6)
174 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
175 if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
177 union {
178 unsigned char *c;
179 struct in6_pktinfo *p;
180 } p;
181 p.c = CMSG_DATA(cmptr);
183 addr.in6.sin6_addr = p.p->ipi6_addr;
184 if_index = p.p->ipi6_ifindex;
187 #endif
189 if (!indextoname(listen->tftpfd, if_index, namebuff))
190 return;
192 name = namebuff;
194 addra.addr.addr4 = addr.in.sin_addr;
196 #ifdef HAVE_IPV6
197 if (listen->family == AF_INET6)
198 addra.addr.addr6 = addr.in6.sin6_addr;
199 #endif
201 if (!iface_check(listen->family, &addra, name, NULL))
203 if (!option_bool(OPT_CLEVERBIND))
204 enumerate_interfaces();
205 if (!loopback_exception(listen->tftpfd, listen->family, &addra, name))
206 return;
209 #ifdef HAVE_DHCP
210 /* allowed interfaces are the same as for DHCP */
211 for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
212 if (tmp->name && (strcmp(tmp->name, name) == 0))
213 return;
214 #endif
216 strncpy(ifr.ifr_name, name, IF_NAMESIZE);
217 if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
218 mtu = ifr.ifr_mtu;
221 if (name)
223 /* check for per-interface prefix */
224 for (pref = daemon->if_prefix; pref; pref = pref->next)
225 if (strcmp(pref->interface, name) == 0)
226 prefix = pref->prefix;
229 if (listen->family == AF_INET)
231 addr.in.sin_port = htons(port);
232 #ifdef HAVE_SOCKADDR_SA_LEN
233 addr.in.sin_len = sizeof(addr.in);
234 #endif
236 #ifdef HAVE_IPV6
237 else
239 addr.in6.sin6_port = htons(port);
240 addr.in6.sin6_flowinfo = 0;
241 addr.in6.sin6_scope_id = 0;
242 #ifdef HAVE_SOCKADDR_SA_LEN
243 addr.in6.sin6_len = sizeof(addr.in6);
244 #endif
246 #endif
248 if (!(transfer = whine_malloc(sizeof(struct tftp_transfer))))
249 return;
251 if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
253 free(transfer);
254 return;
257 transfer->peer = peer;
258 transfer->timeout = now + 2;
259 transfer->backoff = 1;
260 transfer->block = 1;
261 transfer->blocksize = 512;
262 transfer->offset = 0;
263 transfer->file = NULL;
264 transfer->opt_blocksize = transfer->opt_transize = 0;
265 transfer->netascii = transfer->carrylf = 0;
267 prettyprint_addr(&peer, daemon->addrbuff);
269 /* if we have a nailed-down range, iterate until we find a free one. */
270 while (1)
272 if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
273 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
274 setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
275 #endif
276 !fix_fd(transfer->sockfd))
278 if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
280 if (++port <= daemon->end_tftp_port)
282 if (listen->family == AF_INET)
283 addr.in.sin_port = htons(port);
284 #ifdef HAVE_IPV6
285 else
286 addr.in6.sin6_port = htons(port);
287 #endif
288 continue;
290 my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
292 free_transfer(transfer);
293 return;
295 break;
298 p = packet + 2;
299 end = packet + len;
301 if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
302 !(filename = next(&p, end)) ||
303 !(mode = next(&p, end)) ||
304 (strcasecmp(mode, "octet") != 0 && strcasecmp(mode, "netascii") != 0))
306 len = tftp_err(ERR_ILL, packet, _("unsupported request from %s"), daemon->addrbuff);
307 is_err = 1;
309 else
311 if (strcasecmp(mode, "netascii") == 0)
312 transfer->netascii = 1;
314 while ((opt = next(&p, end)))
316 if (strcasecmp(opt, "blksize") == 0)
318 if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
320 transfer->blocksize = atoi(opt);
321 if (transfer->blocksize < 1)
322 transfer->blocksize = 1;
323 if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
324 transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
325 /* 32 bytes for IP, UDP and TFTP headers */
326 if (mtu != 0 && transfer->blocksize > (unsigned)mtu - 32)
327 transfer->blocksize = (unsigned)mtu - 32;
328 transfer->opt_blocksize = 1;
329 transfer->block = 0;
332 else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
334 transfer->opt_transize = 1;
335 transfer->block = 0;
339 /* cope with backslashes from windows boxen. */
340 for (p = filename; *p; p++)
341 if (*p == '\\')
342 *p = '/';
343 else if (option_bool(OPT_TFTP_LC))
344 *p = tolower(*p);
346 strcpy(daemon->namebuff, "/");
347 if (prefix)
349 if (prefix[0] == '/')
350 daemon->namebuff[0] = 0;
351 strncat(daemon->namebuff, prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
352 if (prefix[strlen(prefix)-1] != '/')
353 strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
355 if (option_bool(OPT_TFTP_APREF))
357 size_t oldlen = strlen(daemon->namebuff);
358 struct stat statbuf;
360 strncat(daemon->namebuff, daemon->addrbuff, (MAXDNAME-1) - strlen(daemon->namebuff));
361 strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
363 /* remove unique-directory if it doesn't exist */
364 if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
365 daemon->namebuff[oldlen] = 0;
368 /* Absolute pathnames OK if they match prefix */
369 if (filename[0] == '/')
371 if (strstr(filename, daemon->namebuff) == filename)
372 daemon->namebuff[0] = 0;
373 else
374 filename++;
377 else if (filename[0] == '/')
378 daemon->namebuff[0] = 0;
379 strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
381 /* check permissions and open file */
382 if ((transfer->file = check_tftp_fileperm(&len, prefix)))
384 if ((len = get_block(packet, transfer)) == -1)
385 len = tftp_err_oops(packet, daemon->namebuff);
386 else
387 is_err = 0;
391 while (sendto(transfer->sockfd, packet, len, 0,
392 (struct sockaddr *)&peer, sa_len(&peer)) == -1 && errno == EINTR);
394 if (is_err)
395 free_transfer(transfer);
396 else
398 transfer->next = daemon->tftp_trans;
399 daemon->tftp_trans = transfer;
403 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix)
405 char *packet = daemon->packet, *namebuff = daemon->namebuff;
406 struct tftp_file *file;
407 struct tftp_transfer *t;
408 uid_t uid = geteuid();
409 struct stat statbuf;
410 int fd = -1;
412 /* trick to ban moving out of the subtree */
413 if (prefix && strstr(namebuff, "/../"))
414 goto perm;
416 if ((fd = open(namebuff, O_RDONLY)) == -1)
418 if (errno == ENOENT)
420 *len = tftp_err(ERR_FNF, packet, _("file %s not found"), namebuff);
421 return NULL;
423 else if (errno == EACCES)
424 goto perm;
425 else
426 goto oops;
429 /* stat the file descriptor to avoid stat->open races */
430 if (fstat(fd, &statbuf) == -1)
431 goto oops;
433 /* running as root, must be world-readable */
434 if (uid == 0)
436 if (!(statbuf.st_mode & S_IROTH))
437 goto perm;
439 /* in secure mode, must be owned by user running dnsmasq */
440 else if (option_bool(OPT_TFTP_SECURE) && uid != statbuf.st_uid)
441 goto perm;
443 /* If we're doing many tranfers from the same file, only
444 open it once this saves lots of file descriptors
445 when mass-booting a big cluster, for instance.
446 Be conservative and only share when inode and name match
447 this keeps error messages sane. */
448 for (t = daemon->tftp_trans; t; t = t->next)
449 if (t->file->dev == statbuf.st_dev &&
450 t->file->inode == statbuf.st_ino &&
451 strcmp(t->file->filename, namebuff) == 0)
453 close(fd);
454 t->file->refcount++;
455 return t->file;
458 if (!(file = whine_malloc(sizeof(struct tftp_file) + strlen(namebuff) + 1)))
460 errno = ENOMEM;
461 goto oops;
464 file->fd = fd;
465 file->size = statbuf.st_size;
466 file->dev = statbuf.st_dev;
467 file->inode = statbuf.st_ino;
468 file->refcount = 1;
469 strcpy(file->filename, namebuff);
470 return file;
472 perm:
473 errno = EACCES;
474 *len = tftp_err(ERR_PERM, packet, _("cannot access %s: %s"), namebuff);
475 if (fd != -1)
476 close(fd);
477 return NULL;
479 oops:
480 *len = tftp_err_oops(packet, namebuff);
481 if (fd != -1)
482 close(fd);
483 return NULL;
486 void check_tftp_listeners(fd_set *rset, time_t now)
488 struct tftp_transfer *transfer, *tmp, **up;
489 ssize_t len;
491 struct ack {
492 unsigned short op, block;
493 } *mess = (struct ack *)daemon->packet;
495 /* Check for activity on any existing transfers */
496 for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
498 tmp = transfer->next;
500 prettyprint_addr(&transfer->peer, daemon->addrbuff);
502 if (FD_ISSET(transfer->sockfd, rset))
504 /* we overwrote the buffer... */
505 daemon->srv_save = NULL;
507 if ((len = recv(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0)) >= (ssize_t)sizeof(struct ack))
509 if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block)
511 /* Got ack, ensure we take the (re)transmit path */
512 transfer->timeout = now;
513 transfer->backoff = 0;
514 if (transfer->block++ != 0)
515 transfer->offset += transfer->blocksize - transfer->expansion;
517 else if (ntohs(mess->op) == OP_ERR)
519 char *p = daemon->packet + sizeof(struct ack);
520 char *end = daemon->packet + len;
521 char *err = next(&p, end);
523 /* Sanitise error message */
524 if (!err)
525 err = "";
526 else
527 sanitise(err);
529 my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
530 (int)ntohs(mess->block), err,
531 daemon->addrbuff);
533 /* Got err, ensure we take abort */
534 transfer->timeout = now;
535 transfer->backoff = 100;
540 if (difftime(now, transfer->timeout) >= 0.0)
542 int endcon = 0;
544 /* timeout, retransmit */
545 transfer->timeout += 1 + (1<<transfer->backoff);
547 /* we overwrote the buffer... */
548 daemon->srv_save = NULL;
550 if ((len = get_block(daemon->packet, transfer)) == -1)
552 len = tftp_err_oops(daemon->packet, transfer->file->filename);
553 endcon = 1;
555 /* don't complain about timeout when we're awaiting the last
556 ACK, some clients never send it */
557 else if (++transfer->backoff > 5 && len != 0)
559 endcon = 1;
560 len = 0;
563 if (len != 0)
564 while(sendto(transfer->sockfd, daemon->packet, len, 0,
565 (struct sockaddr *)&transfer->peer, sa_len(&transfer->peer)) == -1 && errno == EINTR);
567 if (endcon || len == 0)
569 strcpy(daemon->namebuff, transfer->file->filename);
570 sanitise(daemon->namebuff);
571 my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
572 /* unlink */
573 *up = tmp;
574 if (endcon)
575 free_transfer(transfer);
576 else
578 /* put on queue to be sent to script and deleted */
579 transfer->next = daemon->tftp_done_trans;
580 daemon->tftp_done_trans = transfer;
582 continue;
586 up = &transfer->next;
590 static void free_transfer(struct tftp_transfer *transfer)
592 close(transfer->sockfd);
593 if (transfer->file && (--transfer->file->refcount) == 0)
595 close(transfer->file->fd);
596 free(transfer->file);
598 free(transfer);
601 static char *next(char **p, char *end)
603 char *ret = *p;
604 size_t len;
606 if (*(end-1) != 0 ||
607 *p == end ||
608 (len = strlen(ret)) == 0)
609 return NULL;
611 *p += len + 1;
612 return ret;
615 static void sanitise(char *buf)
617 unsigned char *q, *r;
618 for (q = r = (unsigned char *)buf; *r; r++)
619 if (isprint((int)*r))
620 *(q++) = *r;
621 *q = 0;
625 static ssize_t tftp_err(int err, char *packet, char *message, char *file)
627 struct errmess {
628 unsigned short op, err;
629 char message[];
630 } *mess = (struct errmess *)packet;
631 ssize_t ret = 4;
632 char *errstr = strerror(errno);
634 sanitise(file);
636 mess->op = htons(OP_ERR);
637 mess->err = htons(err);
638 ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
639 my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
641 return ret;
644 static ssize_t tftp_err_oops(char *packet, char *file)
646 /* May have >1 refs to file, so potentially mangle a copy of the name */
647 strcpy(daemon->namebuff, file);
648 return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), daemon->namebuff);
651 /* return -1 for error, zero for done. */
652 static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
654 if (transfer->block == 0)
656 /* send OACK */
657 char *p;
658 struct oackmess {
659 unsigned short op;
660 char data[];
661 } *mess = (struct oackmess *)packet;
663 p = mess->data;
664 mess->op = htons(OP_OACK);
665 if (transfer->opt_blocksize)
667 p += (sprintf(p, "blksize") + 1);
668 p += (sprintf(p, "%d", transfer->blocksize) + 1);
670 if (transfer->opt_transize)
672 p += (sprintf(p,"tsize") + 1);
673 p += (sprintf(p, "%u", (unsigned int)transfer->file->size) + 1);
676 return p - packet;
678 else
680 /* send data packet */
681 struct datamess {
682 unsigned short op, block;
683 unsigned char data[];
684 } *mess = (struct datamess *)packet;
686 size_t size = transfer->file->size - transfer->offset;
688 if (transfer->offset > transfer->file->size)
689 return 0; /* finished */
691 if (size > transfer->blocksize)
692 size = transfer->blocksize;
694 mess->op = htons(OP_DATA);
695 mess->block = htons((unsigned short)(transfer->block));
697 if (lseek(transfer->file->fd, transfer->offset, SEEK_SET) == (off_t)-1 ||
698 !read_write(transfer->file->fd, mess->data, size, 1))
699 return -1;
701 transfer->expansion = 0;
703 /* Map '\n' to CR-LF in netascii mode */
704 if (transfer->netascii)
706 size_t i;
707 int newcarrylf;
709 for (i = 0, newcarrylf = 0; i < size; i++)
710 if (mess->data[i] == '\n' && ( i != 0 || !transfer->carrylf))
712 transfer->expansion++;
714 if (size != transfer->blocksize)
715 size++; /* room in this block */
716 else if (i == size - 1)
717 newcarrylf = 1; /* don't expand LF again if it moves to the next block */
719 /* make space and insert CR */
720 memmove(&mess->data[i+1], &mess->data[i], size - (i + 1));
721 mess->data[i] = '\r';
723 i++;
725 transfer->carrylf = newcarrylf;
729 return size + 4;
734 int do_tftp_script_run(void)
736 struct tftp_transfer *transfer;
738 if ((transfer = daemon->tftp_done_trans))
740 daemon->tftp_done_trans = transfer->next;
741 #ifdef HAVE_SCRIPT
742 queue_tftp(transfer->file->size, transfer->file->filename, &transfer->peer);
743 #endif
744 free_transfer(transfer);
745 return 1;
748 return 0;
750 #endif