Coverage Report

Created: 2025-12-27 06:42

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