Imported Upstream version 2.88
[platform/upstream/dnsmasq.git] / src / tftp.c
1 /* dnsmasq is Copyright (c) 2000-2022 Simon Kelley
2
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.
7  
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.
12      
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/>.
15 */
16
17 #include "dnsmasq.h"
18
19 #ifdef HAVE_TFTP
20
21 static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len);
22 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix, char *client);
23 static void free_transfer(struct tftp_transfer *transfer);
24 static ssize_t tftp_err(int err, char *packet, char *message, char *file, char *arg2);
25 static ssize_t tftp_err_oops(char *packet, const char *file);
26 static ssize_t get_block(char *packet, struct tftp_transfer *transfer);
27 static char *next(char **p, char *end);
28 static void sanitise(char *buf);
29
30 #define OP_RRQ  1
31 #define OP_WRQ  2
32 #define OP_DATA 3
33 #define OP_ACK  4
34 #define OP_ERR  5
35 #define OP_OACK 6
36
37 #define ERR_NOTDEF 0
38 #define ERR_FNF    1
39 #define ERR_PERM   2
40 #define ERR_FULL   3
41 #define ERR_ILL    4
42 #define ERR_TID    5
43
44 void tftp_request(struct listener *listen, time_t now)
45 {
46   ssize_t len;
47   char *packet = daemon->packet;
48   char *filename, *mode, *p, *end, *opt;
49   union mysockaddr addr, peer;
50   struct msghdr msg;
51   struct iovec iov;
52   struct ifreq ifr;
53   int is_err = 1, if_index = 0, mtu = 0;
54   struct iname *tmp;
55   struct tftp_transfer *transfer = NULL, **up;
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   union all_addr addra;
65   int family = listen->addr.sa.sa_family;
66   /* Can always get recvd interface for IPv6 */
67   int check_dest = !option_bool(OPT_NOWILD) || family == AF_INET6;
68   union {
69     struct cmsghdr align; /* this ensures alignment */
70     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
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(struct in_addr)) +
75                  CMSG_SPACE(sizeof(unsigned int))];
76 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
77     char control[CMSG_SPACE(sizeof(struct in_addr)) +
78                  CMSG_SPACE(sizeof(struct sockaddr_dl))];
79 #endif
80   } control_u; 
81
82   msg.msg_controllen = sizeof(control_u);
83   msg.msg_control = control_u.control;
84   msg.msg_flags = 0;
85   msg.msg_name = &peer;
86   msg.msg_namelen = sizeof(peer);
87   msg.msg_iov = &iov;
88   msg.msg_iovlen = 1;
89
90   iov.iov_base = packet;
91   iov.iov_len = daemon->packet_buff_sz;
92
93   /* we overwrote the buffer... */
94   daemon->srv_save = NULL;
95
96   if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
97     return;
98
99 #ifdef HAVE_DUMPFILE
100   dump_packet_udp(DUMP_TFTP, (void *)packet, len, (union mysockaddr *)&peer, NULL, listen->tftpfd);
101 #endif
102   
103   /* Can always get recvd interface for IPv6 */
104   if (!check_dest)
105     {
106       if (listen->iface)
107         {
108           addr = listen->iface->addr;
109           name = listen->iface->name;
110           mtu = listen->iface->mtu;
111           if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
112             mtu = daemon->tftp_mtu;
113         }
114       else
115         {
116           /* we're listening on an address that doesn't appear on an interface,
117              ask the kernel what the socket is bound to */
118           socklen_t tcp_len = sizeof(union mysockaddr);
119           if (getsockname(listen->tftpfd, (struct sockaddr *)&addr, &tcp_len) == -1)
120             return;
121         }
122     }
123   else
124     {
125       struct cmsghdr *cmptr;
126
127       if (msg.msg_controllen < sizeof(struct cmsghdr))
128         return;
129       
130       addr.sa.sa_family = family;
131       
132 #if defined(HAVE_LINUX_NETWORK)
133       if (family == AF_INET)
134         for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
135           if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
136             {
137               union {
138                 unsigned char *c;
139                 struct in_pktinfo *p;
140               } p;
141               p.c = CMSG_DATA(cmptr);
142               addr.in.sin_addr = p.p->ipi_spec_dst;
143               if_index = p.p->ipi_ifindex;
144             }
145       
146 #elif defined(HAVE_SOLARIS_NETWORK)
147       if (family == AF_INET)
148         for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
149           {
150             union {
151               unsigned char *c;
152               struct in_addr *a;
153               unsigned int *i;
154             } p;
155             p.c = CMSG_DATA(cmptr);
156             if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
157             addr.in.sin_addr = *(p.a);
158             else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
159             if_index = *(p.i);
160           }
161       
162 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
163       if (family == AF_INET)
164         for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
165           {
166             union {
167               unsigned char *c;
168               struct in_addr *a;
169               struct sockaddr_dl *s;
170             } p;
171             p.c = CMSG_DATA(cmptr);
172             if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
173               addr.in.sin_addr = *(p.a);
174             else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
175               if_index = p.s->sdl_index;
176           }
177           
178 #endif
179
180       if (family == AF_INET6)
181         {
182           for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
183             if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
184               {
185                 union {
186                   unsigned char *c;
187                   struct in6_pktinfo *p;
188                 } p;
189                 p.c = CMSG_DATA(cmptr);
190                   
191                 addr.in6.sin6_addr = p.p->ipi6_addr;
192                 if_index = p.p->ipi6_ifindex;
193               }
194         }
195       
196       if (!indextoname(listen->tftpfd, if_index, namebuff))
197         return;
198
199       name = namebuff;
200       
201       addra.addr4 = addr.in.sin_addr;
202
203       if (family == AF_INET6)
204         addra.addr6 = addr.in6.sin6_addr;
205
206       if (daemon->tftp_interfaces)
207         {
208           /* dedicated tftp interface list */
209           for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
210             if (tmp->name && wildcard_match(tmp->name, name))
211               break;
212
213           if (!tmp)
214             return;
215         }
216       else
217         {
218           /* Do the same as DHCP */
219           if (!iface_check(family, &addra, name, NULL))
220             {
221               if (!option_bool(OPT_CLEVERBIND))
222                 enumerate_interfaces(0); 
223               if (!loopback_exception(listen->tftpfd, family, &addra, name) &&
224                   !label_exception(if_index, family, &addra))
225                 return;
226             }
227           
228 #ifdef HAVE_DHCP      
229           /* allowed interfaces are the same as for DHCP */
230           for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
231             if (tmp->name && wildcard_match(tmp->name, name))
232               return;
233 #endif
234         }
235
236       safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
237       if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
238         {
239           mtu = ifr.ifr_mtu;  
240           if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
241             mtu = daemon->tftp_mtu;    
242         }
243     }
244
245   /* Failed to get interface mtu - can use configured value. */
246   if (mtu == 0)
247     mtu = daemon->tftp_mtu;
248
249   /* data transfer via server listening socket */
250   if (option_bool(OPT_SINGLE_PORT))
251     {
252       int tftp_cnt;
253
254       for (tftp_cnt = 0, transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; up = &transfer->next, transfer = transfer->next)
255         {
256           tftp_cnt++;
257
258           if (sockaddr_isequal(&peer, &transfer->peer))
259             {
260               if (ntohs(*((unsigned short *)packet)) == OP_RRQ)
261                 {
262                   /* Handle repeated RRQ or abandoned transfer from same host and port 
263                      by unlinking and reusing the struct transfer. */
264                   *up = transfer->next;
265                   break;
266                 }
267               else
268                 {
269                   handle_tftp(now, transfer, len);
270                   return;
271                 }
272             }
273         }
274       
275       /* Enforce simultaneous transfer limit. In non-single-port mode
276          this is doene by not listening on the server socket when
277          too many transfers are in progress. */
278       if (!transfer && tftp_cnt >= daemon->tftp_max)
279         return;
280     }
281   
282   if (name)
283     {
284       /* check for per-interface prefix */ 
285       for (pref = daemon->if_prefix; pref; pref = pref->next)
286         if (strcmp(pref->interface, name) == 0)
287           prefix = pref->prefix;  
288     }
289
290   if (family == AF_INET)
291     {
292       addr.in.sin_port = htons(port);
293 #ifdef HAVE_SOCKADDR_SA_LEN
294       addr.in.sin_len = sizeof(addr.in);
295 #endif
296     }
297   else
298     {
299       addr.in6.sin6_port = htons(port);
300       addr.in6.sin6_flowinfo = 0;
301       addr.in6.sin6_scope_id = 0;
302 #ifdef HAVE_SOCKADDR_SA_LEN
303       addr.in6.sin6_len = sizeof(addr.in6);
304 #endif
305     }
306
307   /* May reuse struct transfer from abandoned transfer in single port mode. */
308   if (!transfer && !(transfer = whine_malloc(sizeof(struct tftp_transfer))))
309     return;
310   
311   if (option_bool(OPT_SINGLE_PORT))
312     transfer->sockfd = listen->tftpfd;
313   else if ((transfer->sockfd = socket(family, SOCK_DGRAM, 0)) == -1)
314     {
315       free(transfer);
316       return;
317     }
318   
319   transfer->peer = peer;
320   transfer->source = addra;
321   transfer->if_index = if_index;
322   transfer->timeout = now + 2;
323   transfer->backoff = 1;
324   transfer->block = 1;
325   transfer->blocksize = 512;
326   transfer->offset = 0;
327   transfer->file = NULL;
328   transfer->opt_blocksize = transfer->opt_transize = 0;
329   transfer->netascii = transfer->carrylf = 0;
330  
331   (void)prettyprint_addr(&peer, daemon->addrbuff);
332   
333   /* if we have a nailed-down range, iterate until we find a free one. */
334   while (!option_bool(OPT_SINGLE_PORT))
335     {
336       if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
337 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
338           setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
339 #endif
340           !fix_fd(transfer->sockfd))
341         {
342           if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
343             {
344               if (++port <= daemon->end_tftp_port)
345                 { 
346                   if (family == AF_INET)
347                     addr.in.sin_port = htons(port);
348                   else
349                     addr.in6.sin6_port = htons(port);
350                   
351                   continue;
352                 }
353               my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
354             }
355           free_transfer(transfer);
356           return;
357         }
358       break;
359     }
360   
361   p = packet + 2;
362   end = packet + len;
363   
364   if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
365       !(filename = next(&p, end)) ||
366       !(mode = next(&p, end)) ||
367       (strcasecmp(mode, "octet") != 0 && strcasecmp(mode, "netascii") != 0))
368     {
369       len = tftp_err(ERR_ILL, packet, _("unsupported request from %s"), daemon->addrbuff, NULL);
370       is_err = 1;
371     }
372   else
373     {
374       if (strcasecmp(mode, "netascii") == 0)
375         transfer->netascii = 1;
376       
377       while ((opt = next(&p, end)))
378         {
379           if (strcasecmp(opt, "blksize") == 0)
380             {
381               if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
382                 {
383                   /* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
384                   int overhead = (family == AF_INET) ? 32 : 52;
385                   transfer->blocksize = atoi(opt);
386                   if (transfer->blocksize < 1)
387                     transfer->blocksize = 1;
388                   if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
389                     transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
390                   if (mtu != 0 && transfer->blocksize > (unsigned)mtu - overhead)
391                     transfer->blocksize = (unsigned)mtu - overhead;
392                   transfer->opt_blocksize = 1;
393                   transfer->block = 0;
394                 }
395             }
396           else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
397             {
398               transfer->opt_transize = 1;
399               transfer->block = 0;
400             }
401         }
402
403       /* cope with backslashes from windows boxen. */
404       for (p = filename; *p; p++)
405         if (*p == '\\')
406           *p = '/';
407         else if (option_bool(OPT_TFTP_LC))
408           *p = tolower(*p);
409                 
410       strcpy(daemon->namebuff, "/");
411       if (prefix)
412         {
413           if (prefix[0] == '/')
414             daemon->namebuff[0] = 0;
415           strncat(daemon->namebuff, prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
416           if (prefix[strlen(prefix)-1] != '/')
417             strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
418
419           if (option_bool(OPT_TFTP_APREF_IP))
420             {
421               size_t oldlen = strlen(daemon->namebuff);
422               struct stat statbuf;
423               
424               strncat(daemon->namebuff, daemon->addrbuff, (MAXDNAME-1) - strlen(daemon->namebuff));
425               strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
426               
427               /* remove unique-directory if it doesn't exist */
428               if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
429                 daemon->namebuff[oldlen] = 0;
430             }
431           
432           if (option_bool(OPT_TFTP_APREF_MAC))
433             {
434               unsigned char *macaddr = NULL;
435               unsigned char macbuf[DHCP_CHADDR_MAX];
436               
437 #ifdef HAVE_DHCP
438               if (daemon->dhcp && peer.sa.sa_family == AF_INET)
439                 {
440                   /* Check if the client IP is in our lease database */
441                   struct dhcp_lease *lease = lease_find_by_addr(peer.in.sin_addr);
442                   if (lease && lease->hwaddr_type == ARPHRD_ETHER && lease->hwaddr_len == ETHER_ADDR_LEN)
443                     macaddr = lease->hwaddr;
444                 }
445 #endif
446               
447               /* If no luck, try to find in ARP table. This only works if client is in same (V)LAN */
448               if (!macaddr && find_mac(&peer, macbuf, 1, now) > 0)
449                 macaddr = macbuf;
450               
451               if (macaddr)
452                 {
453                   size_t oldlen = strlen(daemon->namebuff);
454                   struct stat statbuf;
455
456                   snprintf(daemon->namebuff + oldlen, (MAXDNAME-1) - oldlen, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x/",
457                            macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
458                   
459                   /* remove unique-directory if it doesn't exist */
460                   if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
461                     daemon->namebuff[oldlen] = 0;
462                 }
463             }
464           
465           /* Absolute pathnames OK if they match prefix */
466           if (filename[0] == '/')
467             {
468               if (strstr(filename, daemon->namebuff) == filename)
469                 daemon->namebuff[0] = 0;
470               else
471                 filename++;
472             }
473         }
474       else if (filename[0] == '/')
475         daemon->namebuff[0] = 0;
476       strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
477       
478       /* check permissions and open file */
479       if ((transfer->file = check_tftp_fileperm(&len, prefix, daemon->addrbuff)))
480         {
481           if ((len = get_block(packet, transfer)) == -1)
482             len = tftp_err_oops(packet, daemon->namebuff);
483           else
484             is_err = 0;
485         }
486     }
487
488   send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), packet, len, &peer, &addra, if_index);
489
490 #ifdef HAVE_DUMPFILE
491   dump_packet_udp(DUMP_TFTP, (void *)packet, len, NULL, (union mysockaddr *)&peer, transfer->sockfd);
492 #endif
493   
494   if (is_err)
495     free_transfer(transfer);
496   else
497     {
498       transfer->next = daemon->tftp_trans;
499       daemon->tftp_trans = transfer;
500     }
501 }
502  
503 static struct tftp_file *check_tftp_fileperm(ssize_t *len, char *prefix, char *client)
504 {
505   char *packet = daemon->packet, *namebuff = daemon->namebuff;
506   struct tftp_file *file;
507   struct tftp_transfer *t;
508   uid_t uid = geteuid();
509   struct stat statbuf;
510   int fd = -1;
511
512   /* trick to ban moving out of the subtree */
513   if (prefix && strstr(namebuff, "/../"))
514     goto perm;
515   
516   if ((fd = open(namebuff, O_RDONLY)) == -1)
517     {
518       if (errno == ENOENT)
519         {
520           *len = tftp_err(ERR_FNF, packet, _("file %s not found for %s"), namebuff, client);
521           return NULL;
522         }
523       else if (errno == EACCES)
524         goto perm;
525       else
526         goto oops;
527     }
528   
529   /* stat the file descriptor to avoid stat->open races */
530   if (fstat(fd, &statbuf) == -1)
531     goto oops;
532   
533   /* running as root, must be world-readable */
534   if (uid == 0)
535     {
536       if (!(statbuf.st_mode & S_IROTH))
537         goto perm;
538     }
539   /* in secure mode, must be owned by user running dnsmasq */
540   else if (option_bool(OPT_TFTP_SECURE) && uid != statbuf.st_uid)
541     goto perm;
542       
543   /* If we're doing many transfers from the same file, only 
544      open it once this saves lots of file descriptors 
545      when mass-booting a big cluster, for instance. 
546      Be conservative and only share when inode and name match
547      this keeps error messages sane. */
548   for (t = daemon->tftp_trans; t; t = t->next)
549     if (t->file->dev == statbuf.st_dev && 
550         t->file->inode == statbuf.st_ino &&
551         strcmp(t->file->filename, namebuff) == 0)
552       {
553         close(fd);
554         t->file->refcount++;
555         return t->file;
556       }
557   
558   if (!(file = whine_malloc(sizeof(struct tftp_file) + strlen(namebuff) + 1)))
559     {
560       errno = ENOMEM;
561       goto oops;
562     }
563
564   file->fd = fd;
565   file->size = statbuf.st_size;
566   file->dev = statbuf.st_dev;
567   file->inode = statbuf.st_ino;
568   file->refcount = 1;
569   strcpy(file->filename, namebuff);
570   return file;
571   
572  perm:
573   *len =  tftp_err(ERR_PERM, packet, _("cannot access %s: %s"), namebuff, strerror(EACCES));
574   if (fd != -1)
575     close(fd);
576   return NULL;
577
578  oops:
579   *len =  tftp_err_oops(packet, namebuff);
580   if (fd != -1)
581     close(fd);
582   return NULL;
583 }
584
585 void check_tftp_listeners(time_t now)
586 {
587   struct tftp_transfer *transfer, *tmp, **up;
588   
589   /* In single port mode, all packets come via port 69 and tftp_request() */
590   if (!option_bool(OPT_SINGLE_PORT))
591     for (transfer = daemon->tftp_trans; transfer; transfer = transfer->next)
592       if (poll_check(transfer->sockfd, POLLIN))
593         {
594           union mysockaddr peer;
595           socklen_t addr_len = sizeof(union mysockaddr);
596           ssize_t len;
597           
598           /* we overwrote the buffer... */
599           daemon->srv_save = NULL;
600
601           if ((len = recvfrom(transfer->sockfd, daemon->packet, daemon->packet_buff_sz, 0, &peer.sa, &addr_len)) > 0)
602             {
603               if (sockaddr_isequal(&peer, &transfer->peer)) 
604                 handle_tftp(now, transfer, len);
605               else
606                 {
607                   /* Wrong source address. See rfc1350 para 4. */
608                   prettyprint_addr(&peer, daemon->addrbuff);
609                   len = tftp_err(ERR_TID, daemon->packet, _("ignoring packet from %s (TID mismatch)"), daemon->addrbuff, NULL);
610                   while(retry_send(sendto(transfer->sockfd, daemon->packet, len, 0, &peer.sa, sa_len(&peer))));
611
612 #ifdef HAVE_DUMPFILE
613                   dump_packet_udp(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&peer, transfer->sockfd);
614 #endif
615                 }
616             }
617         }
618           
619   for (transfer = daemon->tftp_trans, up = &daemon->tftp_trans; transfer; transfer = tmp)
620     {
621       tmp = transfer->next;
622       
623       if (difftime(now, transfer->timeout) >= 0.0)
624         {
625           int endcon = 0;
626           ssize_t len;
627
628           /* timeout, retransmit */
629           transfer->timeout += 1 + (1<<(transfer->backoff/2));
630                   
631           /* we overwrote the buffer... */
632           daemon->srv_save = NULL;
633
634           if ((len = get_block(daemon->packet, transfer)) == -1)
635             {
636               len = tftp_err_oops(daemon->packet, transfer->file->filename);
637               endcon = 1;
638             }
639           else if (++transfer->backoff > 7)
640             {
641               /* don't complain about timeout when we're awaiting the last
642                  ACK, some clients never send it */
643               if ((unsigned)len == transfer->blocksize + 4)
644                 endcon = 1;
645               len = 0;
646             }
647
648           if (len != 0)
649             {
650               send_from(transfer->sockfd, !option_bool(OPT_SINGLE_PORT), daemon->packet, len,
651                         &transfer->peer, &transfer->source, transfer->if_index);
652 #ifdef HAVE_DUMPFILE
653               dump_packet_udp(DUMP_TFTP, (void *)daemon->packet, len, NULL, (union mysockaddr *)&transfer->peer, transfer->sockfd);
654 #endif
655             }
656           
657           if (endcon || len == 0)
658             {
659               strcpy(daemon->namebuff, transfer->file->filename);
660               sanitise(daemon->namebuff);
661               (void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
662               my_syslog(MS_TFTP | LOG_INFO, endcon ? _("failed sending %s to %s") : _("sent %s to %s"), daemon->namebuff, daemon->addrbuff);
663               /* unlink */
664               *up = tmp;
665               if (endcon)
666                 free_transfer(transfer);
667               else
668                 {
669                   /* put on queue to be sent to script and deleted */
670                   transfer->next = daemon->tftp_done_trans;
671                   daemon->tftp_done_trans = transfer;
672                 }
673               continue;
674             }
675         }
676
677       up = &transfer->next;
678     }    
679 }
680           
681 /* packet in daemon->packet as this is called. */
682 static void handle_tftp(time_t now, struct tftp_transfer *transfer, ssize_t len)
683 {
684   struct ack {
685     unsigned short op, block;
686   } *mess = (struct ack *)daemon->packet;
687   
688   if (len >= (ssize_t)sizeof(struct ack))
689     {
690       if (ntohs(mess->op) == OP_ACK && ntohs(mess->block) == (unsigned short)transfer->block) 
691         {
692           /* Got ack, ensure we take the (re)transmit path */
693           transfer->timeout = now;
694           transfer->backoff = 0;
695           if (transfer->block++ != 0)
696             transfer->offset += transfer->blocksize - transfer->expansion;
697         }
698       else if (ntohs(mess->op) == OP_ERR)
699         {
700           char *p = daemon->packet + sizeof(struct ack);
701           char *end = daemon->packet + len;
702           char *err = next(&p, end);
703           
704           (void)prettyprint_addr(&transfer->peer, daemon->addrbuff);
705           
706           /* Sanitise error message */
707           if (!err)
708             err = "";
709           else
710             sanitise(err);
711           
712           my_syslog(MS_TFTP | LOG_ERR, _("error %d %s received from %s"),
713                     (int)ntohs(mess->block), err, 
714                     daemon->addrbuff);  
715           
716           /* Got err, ensure we take abort */
717           transfer->timeout = now;
718           transfer->backoff = 100;
719         }
720     }
721 }
722
723 static void free_transfer(struct tftp_transfer *transfer)
724 {
725   if (!option_bool(OPT_SINGLE_PORT))
726     close(transfer->sockfd);
727
728   if (transfer->file && (--transfer->file->refcount) == 0)
729     {
730       close(transfer->file->fd);
731       free(transfer->file);
732     }
733   
734   free(transfer);
735 }
736
737 static char *next(char **p, char *end)
738 {
739   char *ret = *p;
740   size_t len;
741
742   if (*(end-1) != 0 || 
743       *p == end ||
744       (len = strlen(ret)) == 0)
745     return NULL;
746
747   *p += len + 1;
748   return ret;
749 }
750
751 static void sanitise(char *buf)
752 {
753   unsigned char *q, *r;
754   for (q = r = (unsigned char *)buf; *r; r++)
755     if (isprint((int)*r))
756       *(q++) = *r;
757   *q = 0;
758
759 }
760
761 #define MAXMESSAGE 500 /* limit to make packet < 512 bytes and definitely smaller than buffer */ 
762 static ssize_t tftp_err(int err, char *packet, char *message, char *file, char *arg2)
763 {
764   struct errmess {
765     unsigned short op, err;
766     char message[];
767   } *mess = (struct errmess *)packet;
768   ssize_t len, ret = 4;
769     
770   memset(packet, 0, daemon->packet_buff_sz);
771   if (file)
772     sanitise(file);
773   
774   mess->op = htons(OP_ERR);
775   mess->err = htons(err);
776   len = snprintf(mess->message, MAXMESSAGE,  message, file, arg2);
777   ret += (len < MAXMESSAGE) ? len + 1 : MAXMESSAGE; /* include terminating zero */
778   
779   if (err != ERR_FNF || !option_bool(OPT_QUIET_TFTP))
780     my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
781   
782   return  ret;
783 }
784
785 static ssize_t tftp_err_oops(char *packet, const char *file)
786 {
787   /* May have >1 refs to file, so potentially mangle a copy of the name */
788   if (file != daemon->namebuff)
789     strcpy(daemon->namebuff, file);
790   return tftp_err(ERR_NOTDEF, packet, _("cannot read %s: %s"), daemon->namebuff, strerror(errno));
791 }
792
793 /* return -1 for error, zero for done. */
794 static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
795 {
796   memset(packet, 0, daemon->packet_buff_sz);
797   
798   if (transfer->block == 0)
799     {
800       /* send OACK */
801       char *p;
802       struct oackmess {
803         unsigned short op;
804         char data[];
805       } *mess = (struct oackmess *)packet;
806       
807       p = mess->data;
808       mess->op = htons(OP_OACK);
809       if (transfer->opt_blocksize)
810         {
811           p += (sprintf(p, "blksize") + 1);
812           p += (sprintf(p, "%u", transfer->blocksize) + 1);
813         }
814       if (transfer->opt_transize)
815         {
816           p += (sprintf(p,"tsize") + 1);
817           p += (sprintf(p, "%u", (unsigned int)transfer->file->size) + 1);
818         }
819
820       return p - packet;
821     }
822   else
823     {
824       /* send data packet */
825       struct datamess {
826         unsigned short op, block;
827         unsigned char data[];
828       } *mess = (struct datamess *)packet;
829       
830       size_t size = transfer->file->size - transfer->offset; 
831       
832       if (transfer->offset > transfer->file->size)
833         return 0; /* finished */
834       
835       if (size > transfer->blocksize)
836         size = transfer->blocksize;
837       
838       mess->op = htons(OP_DATA);
839       mess->block = htons((unsigned short)(transfer->block));
840       
841       if (lseek(transfer->file->fd, transfer->offset, SEEK_SET) == (off_t)-1 ||
842           !read_write(transfer->file->fd, mess->data, size, 1))
843         return -1;
844       
845       transfer->expansion = 0;
846       
847       /* Map '\n' to CR-LF in netascii mode */
848       if (transfer->netascii)
849         {
850           size_t i;
851           int newcarrylf;
852
853           for (i = 0, newcarrylf = 0; i < size; i++)
854             if (mess->data[i] == '\n' && ( i != 0 || !transfer->carrylf))
855               {
856                 transfer->expansion++;
857
858                 if (size != transfer->blocksize)
859                   size++; /* room in this block */
860                 else  if (i == size - 1)
861                   newcarrylf = 1; /* don't expand LF again if it moves to the next block */
862                   
863                 /* make space and insert CR */
864                 memmove(&mess->data[i+1], &mess->data[i], size - (i + 1));
865                 mess->data[i] = '\r';
866                 
867                 i++;
868               }
869           transfer->carrylf = newcarrylf;
870           
871         }
872
873       return size + 4;
874     }
875 }
876
877
878 int do_tftp_script_run(void)
879 {
880   struct tftp_transfer *transfer;
881
882   if ((transfer = daemon->tftp_done_trans))
883     {
884       daemon->tftp_done_trans = transfer->next;
885 #ifdef HAVE_SCRIPT
886       queue_tftp(transfer->file->size, transfer->file->filename, &transfer->peer);
887 #endif
888       free_transfer(transfer);
889       return 1;
890     }
891
892   return 0;
893 }
894 #endif