Coverage Report

Created: 2026-08-13 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/common/iobuf.c
Line
Count
Source
1
/* iobuf.c  -  File Handling for OpenPGP.
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008,
3
 *               2009, 2010, 2011  Free Software Foundation, Inc.
4
 * Copyright (C) 2015, 2023  g10 Code GmbH
5
 *
6
 * This file is part of GnuPG.
7
 *
8
 * This file is free software; you can redistribute it and/or modify
9
 * it under the terms of either
10
 *
11
 *   - the GNU Lesser General Public License as published by the Free
12
 *     Software Foundation; either version 3 of the License, or (at
13
 *     your option) any later version.
14
 *
15
 * or
16
 *
17
 *   - the GNU General Public License as published by the Free
18
 *     Software Foundation; either version 2 of the License, or (at
19
 *     your option) any later version.
20
 *
21
 * or both in parallel, as here.
22
 *
23
 * This file is distributed in the hope that it will be useful,
24
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 * GNU General Public License for more details.
27
 *
28
 * You should have received a copy of the GNU General Public License
29
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
30
 * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
31
 */
32
33
#include <config.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <string.h>
37
#include <errno.h>
38
#include <ctype.h>
39
#include <sys/types.h>
40
#include <sys/stat.h>
41
#include <fcntl.h>
42
#include <unistd.h>
43
#ifdef HAVE_W32_SYSTEM
44
# ifdef HAVE_WINSOCK2_H
45
#  include <winsock2.h>
46
# endif
47
# include <windows.h>
48
#endif
49
#ifdef __riscos__
50
# include <kernel.h>
51
# include <swis.h>
52
#endif /* __riscos__ */
53
54
#include <assuan.h>
55
56
#include "util.h"
57
#include "sysutils.h"
58
#include "iobuf.h"
59
60
/*-- Begin configurable part.  --*/
61
62
/* The standard size of the internal buffers.  */
63
#define DEFAULT_IOBUF_BUFFER_SIZE  (64*1024)
64
65
/* To avoid a potential DoS with compression packets we better limit
66
   the number of filters in a chain.  */
67
236k
#define MAX_NESTING_FILTER 64
68
69
/* The threshold for switching to use external buffers directly
70
   instead of the internal buffers. */
71
1.93M
#define IOBUF_ZEROCOPY_THRESHOLD_SIZE 1024
72
73
/*-- End configurable part.  --*/
74
75
/* The size of the iobuffers.  This can be changed using the
76
 * iobuf_set_buffer_size function.  */
77
static unsigned int iobuf_buffer_size = DEFAULT_IOBUF_BUFFER_SIZE;
78
79
80
#ifdef HAVE_W32_SYSTEM
81
# define FD_FOR_STDIN  (GetStdHandle (STD_INPUT_HANDLE))
82
# define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
83
#else /*!HAVE_W32_SYSTEM*/
84
89.6k
# define FD_FOR_STDIN  (0)
85
44.8k
# define FD_FOR_STDOUT (1)
86
#endif /*!HAVE_W32_SYSTEM*/
87
88
89
/* The context used by the file filter.  */
90
typedef struct
91
{
92
  gnupg_fd_t fp;       /* Open file pointer or handle.  */
93
  int keep_open;
94
  int no_cache;
95
  int eof_seen;
96
  int delayed_rc;
97
  int print_only_name; /* Flags indicating that fname is not a real file.  */
98
  char peeked[32];     /* Read ahead buffer.  */
99
  byte npeeked;        /* Number of bytes valid in peeked.  */
100
  byte upeeked;        /* Number of bytes used from peeked.  */
101
  char fname[1];       /* Name of the file.  */
102
} file_filter_ctx_t;
103
104
/* The context used by the estream filter.  */
105
typedef struct
106
{
107
  estream_t fp;        /* Open estream handle.  */
108
  int keep_open;
109
  int no_cache;
110
  int eof_seen;
111
  int use_readlimit;   /* Take care of the readlimit.  */
112
  size_t readlimit;    /* Number of bytes left to read.  */
113
  int print_only_name; /* Flags indicating that fname is not a real file.  */
114
  char fname[1];       /* Name of the file.  */
115
} file_es_filter_ctx_t;
116
117
118
/* Object to control the "close cache".  */
119
struct close_cache_s
120
{
121
  struct close_cache_s *next;
122
  gnupg_fd_t fp;
123
  char fname[1];
124
};
125
typedef struct close_cache_s *close_cache_t;
126
static close_cache_t close_cache;
127
128
int iobuf_debug_mode;
129
130
131
#ifdef HAVE_W32_SYSTEM
132
typedef struct
133
{
134
  int sock;
135
  int keep_open;
136
  int no_cache;
137
  int eof_seen;
138
  int print_only_name;  /* Flag indicating that fname is not a real file.  */
139
  char fname[1];  /* Name of the file */
140
141
} sock_filter_ctx_t;
142
#endif /*HAVE_W32_SYSTEM*/
143
144
/* The first partial length header block must be of size 512 to make
145
 * it easier (and more efficient) we use a min. block size of 512 for
146
 * all chunks (but the last one) */
147
0
#define OP_MIN_PARTIAL_CHUNK    512
148
0
#define OP_MIN_PARTIAL_CHUNK_2POW 9
149
150
/* The context we use for the block filter (used to handle OpenPGP
151
   length information header).  */
152
typedef struct
153
{
154
  int use;
155
  size_t size;
156
  size_t count;
157
  int partial;     /* 1 = partial header, 2 in last partial packet.  */
158
  char *buffer;    /* Used for partial header.  */
159
  size_t buflen;   /* Used size of buffer.  */
160
  int first_c;     /* First character of a partial header (which is > 0).  */
161
  int eof;
162
}
163
block_filter_ctx_t;
164
165
166
/* Local prototypes.  */
167
static int underflow (iobuf_t a, int clear_pending_eof);
168
static int underflow_target (iobuf_t a, int clear_pending_eof, size_t target);
169
static iobuf_t do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open);
170
171
172
/* Sends any pending data to the filter's FILTER function.  Note: this
173
   works on the filter and not on the whole pipeline.  That is,
174
   iobuf_flush doesn't necessarily cause data to be written to any
175
   underlying file; it just causes any data buffered at the filter A
176
   to be sent to A's filter function.
177
178
   If A is a IOBUF_OUTPUT_TEMP filter, then this also enlarges the
179
   buffer by iobuf_buffer_size.
180
181
   May only be called on an IOBUF_OUTPUT or IOBUF_OUTPUT_TEMP filters.  */
182
static int filter_flush (iobuf_t a);
183
184
185

186
/* This is a replacement for strcmp.  Under W32 it does not
187
   distinguish between backslash and slash.  */
188
static int
189
fd_cache_strcmp (const char *a, const char *b)
190
60.0k
{
191
#ifdef HAVE_DOSISH_SYSTEM
192
  for (; *a && *b; a++, b++)
193
    {
194
      if (*a != *b && !((*a == '/' && *b == '\\')
195
                        || (*a == '\\' && *b == '/')) )
196
        break;
197
    }
198
  return *(const unsigned char *)a - *(const unsigned char *)b;
199
#else
200
60.0k
  return strcmp (a, b);
201
60.0k
#endif
202
60.0k
}
203
204
205
/*
206
 * Invalidate (i.e. close) a cached iobuf
207
 */
208
static int
209
fd_cache_invalidate (const char *fname)
210
7.51k
{
211
7.51k
  close_cache_t cc;
212
7.51k
  int rc = 0;
213
214
7.51k
  log_assert (fname);
215
7.51k
  if (DBG_IOBUF)
216
7.51k
    log_debug ("fd_cache_invalidate (%s)\n", fname);
217
218
22.5k
  for (cc = close_cache; cc; cc = cc->next)
219
15.0k
    {
220
15.0k
      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
221
7.51k
  {
222
7.51k
    if (DBG_IOBUF)
223
7.51k
      log_debug ("                did (%s)\n", cc->fname);
224
#ifdef HAVE_W32_SYSTEM
225
    if (!CloseHandle (cc->fp))
226
            rc = -1;
227
#else
228
7.51k
    rc = close (cc->fp);
229
7.51k
#endif
230
7.51k
    cc->fp = GNUPG_INVALID_FD;
231
7.51k
  }
232
15.0k
    }
233
7.51k
  return rc;
234
7.51k
}
235
236
237
/* Try to sync changes to the disk.  This is to avoid data loss during
238
   a system crash in write/close/rename cycle on some file
239
   systems.  */
240
static int
241
fd_cache_synchronize (const char *fname)
242
0
{
243
0
  int err = 0;
244
245
0
#ifdef HAVE_FSYNC
246
0
  close_cache_t cc;
247
248
0
  if (DBG_IOBUF)
249
0
    log_debug ("fd_cache_synchronize (%s)\n", fname);
250
251
0
  for (cc=close_cache; cc; cc = cc->next )
252
0
    {
253
0
      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
254
0
  {
255
0
    if (DBG_IOBUF)
256
0
      log_debug ("                 did (%s)\n", cc->fname);
257
258
0
    err = fsync (cc->fp);
259
0
  }
260
0
    }
261
#else
262
  (void)fname;
263
#endif /*HAVE_FSYNC*/
264
265
0
  return err;
266
0
}
267
268
269
static gnupg_fd_t
270
direct_open (const char *fname, const char *mode, int mode700)
271
22.3k
{
272
#ifdef HAVE_W32_SYSTEM
273
  unsigned long da, cd, sm;
274
  HANDLE hfile;
275
276
  (void)mode700;
277
  /* Note, that we do not handle all mode combinations */
278
279
  /* According to the ReactOS source it seems that open() of the
280
   * standard MSW32 crt does open the file in shared mode which is
281
   * something new for MS applications ;-)
282
   */
283
  if (strchr (mode, '+'))
284
    {
285
      if (fd_cache_invalidate (fname))
286
        return GNUPG_INVALID_FD;
287
      da = GENERIC_READ | GENERIC_WRITE;
288
      cd = OPEN_EXISTING;
289
    }
290
  else if (strchr (mode, 'w'))
291
    {
292
      if (fd_cache_invalidate (fname))
293
        return GNUPG_INVALID_FD;
294
      da = GENERIC_WRITE;
295
      cd = CREATE_ALWAYS;
296
    }
297
  else
298
    {
299
      da = GENERIC_READ;
300
      cd = OPEN_EXISTING;
301
    }
302
  sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
303
304
  /* We always use the Unicode version because it supports file names
305
   * longer than MAX_PATH.  (requires gpgrt 1.45) */
306
  if (1)
307
    {
308
      wchar_t *wfname = gpgrt_fname_to_wchar (fname);
309
      if (wfname)
310
        {
311
          hfile = CreateFileW (wfname, da, sm, NULL, cd,
312
                               FILE_ATTRIBUTE_NORMAL, NULL);
313
          if (hfile == INVALID_HANDLE_VALUE)
314
            {
315
              gnupg_w32_set_errno (-1);
316
              if (DBG_IOBUF)
317
                log_debug ("iobuf:direct_open '%s' CreateFile failed: %s\n",
318
                           fname, gpg_strerror (gpg_error_from_syserror()));
319
            }
320
          xfree (wfname);
321
        }
322
      else
323
        hfile = INVALID_HANDLE_VALUE;
324
    }
325
326
  return hfile;
327
328
#else /*!HAVE_W32_SYSTEM*/
329
330
22.3k
  int oflag;
331
22.3k
  int cflag = S_IRUSR | S_IWUSR;
332
333
22.3k
  if (!mode700)
334
22.3k
    cflag |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
335
336
  /* Note, that we do not handle all mode combinations */
337
22.3k
  if (strchr (mode, '+'))
338
0
    {
339
0
      if (fd_cache_invalidate (fname))
340
0
        return GNUPG_INVALID_FD;
341
0
      oflag = O_RDWR;
342
0
    }
343
22.3k
  else if (strchr (mode, 'w'))
344
4
    {
345
4
      if (fd_cache_invalidate (fname))
346
0
        return GNUPG_INVALID_FD;
347
4
      oflag = O_WRONLY | O_CREAT | O_TRUNC;
348
4
    }
349
22.3k
  else
350
22.3k
    {
351
22.3k
      oflag = O_RDONLY;
352
22.3k
    }
353
#ifdef O_BINARY
354
  if (strchr (mode, 'b'))
355
    oflag |= O_BINARY;
356
#endif
357
358
#ifdef __riscos__
359
  {
360
    struct stat buf;
361
362
    /* Don't allow iobufs on directories */
363
    if (!stat (fname, &buf) && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
364
      return __set_errno (EISDIR);
365
  }
366
#endif
367
22.3k
  return open (fname, oflag, cflag);
368
369
22.3k
#endif /*!HAVE_W32_SYSTEM*/
370
22.3k
}
371
372
373
/*
374
 * Instead of closing an FD we keep it open and cache it for later reuse
375
 * Note that this caching strategy only works if the process does not chdir.
376
 */
377
static void
378
fd_cache_close (const char *fname, gnupg_fd_t fp)
379
44.8k
{
380
44.8k
  close_cache_t cc;
381
382
44.8k
  log_assert (fp);
383
44.8k
  if (!fname || !*fname)
384
14.8k
    {
385
#ifdef HAVE_W32_SYSTEM
386
      CloseHandle (fp);
387
#else
388
14.8k
      close (fp);
389
14.8k
#endif
390
14.8k
      if (DBG_IOBUF)
391
14.8k
  log_debug ("fd_cache_close (%d) real\n", FD_DBG (fp));
392
14.8k
      return;
393
14.8k
    }
394
  /* try to reuse a slot */
395
30.0k
  for (cc = close_cache; cc; cc = cc->next)
396
30.0k
    {
397
30.0k
      if (cc->fp == GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
398
30.0k
  {
399
30.0k
    cc->fp = fp;
400
30.0k
    if (DBG_IOBUF)
401
30.0k
      log_debug ("fd_cache_close (%s) used existing slot\n", fname);
402
30.0k
    return;
403
30.0k
  }
404
30.0k
    }
405
  /* add a new one */
406
8
  if (DBG_IOBUF)
407
8
    log_debug ("fd_cache_close (%s) new slot created\n", fname);
408
8
  cc = xcalloc (1, sizeof *cc + strlen (fname));
409
8
  strcpy (cc->fname, fname);
410
8
  cc->fp = fp;
411
8
  cc->next = close_cache;
412
8
  close_cache = cc;
413
8
}
414
415
/*
416
 * Do a direct_open on FNAME but first try to reuse one from the fd_cache
417
 */
418
static gnupg_fd_t
419
fd_cache_open (const char *fname, const char *mode)
420
44.8k
{
421
44.8k
  close_cache_t cc;
422
423
44.8k
  log_assert (fname);
424
89.5k
  for (cc = close_cache; cc; cc = cc->next)
425
67.1k
    {
426
67.1k
      if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
427
22.5k
  {
428
22.5k
    gnupg_fd_t fp = cc->fp;
429
22.5k
    cc->fp = GNUPG_INVALID_FD;
430
22.5k
    if (DBG_IOBUF)
431
22.5k
      log_debug ("fd_cache_open (%s) using cached fp\n", fname);
432
#ifdef HAVE_W32_SYSTEM
433
    if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff)
434
      {
435
              int ec = (int) GetLastError ();
436
        log_error ("rewind file failed on handle %p: ec=%d\n", fp, ec);
437
              gnupg_w32_set_errno (ec);
438
        fp = GNUPG_INVALID_FD;
439
      }
440
#else
441
22.5k
    if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
442
0
      {
443
0
        log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
444
0
        fp = GNUPG_INVALID_FD;
445
0
      }
446
22.5k
#endif
447
22.5k
    return fp;
448
22.5k
  }
449
67.1k
    }
450
22.3k
  if (DBG_IOBUF)
451
22.3k
    log_debug ("fd_cache_open (%s) not cached\n", fname);
452
22.3k
  return direct_open (fname, mode, 0);
453
44.8k
}
454
455
456
static int
457
file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
458
       size_t * ret_len)
459
175k
{
460
175k
  file_filter_ctx_t *a = opaque;
461
175k
  gnupg_fd_t f = a->fp;
462
175k
  size_t size = *ret_len;
463
175k
  size_t nbytes = 0;
464
175k
  int rc = 0;
465
466
175k
  (void)chain; /* Not used.  */
467
468
175k
  if (control == IOBUFCTRL_UNDERFLOW)
469
85.6k
    {
470
85.6k
      log_assert (size); /* We need a buffer.  */
471
85.6k
      if (a->npeeked > a->upeeked)
472
0
        {
473
0
          nbytes = a->npeeked - a->upeeked;
474
0
          if (nbytes > size)
475
0
            nbytes = size;
476
0
          memcpy (buf, a->peeked + a->upeeked, nbytes);
477
0
          a->upeeked += nbytes;
478
0
          *ret_len = nbytes;
479
0
        }
480
85.6k
      else if (a->eof_seen)
481
0
  {
482
0
    rc = -1;
483
0
    *ret_len = 0;
484
0
  }
485
85.6k
      else if (a->delayed_rc)
486
37.9k
        {
487
37.9k
          rc = a->delayed_rc;
488
37.9k
          a->delayed_rc = 0;
489
37.9k
          if (rc == -1)
490
37.9k
            a->eof_seen = -1;
491
37.9k
    *ret_len = 0;
492
37.9k
        }
493
47.7k
      else
494
47.7k
  {
495
#ifdef HAVE_W32_SYSTEM
496
    unsigned long nread;
497
498
    nbytes = 0;
499
    if (!ReadFile (f, buf, size, &nread, NULL))
500
      {
501
        int ec = (int) GetLastError ();
502
        if (ec != ERROR_BROKEN_PIPE)
503
    {
504
      rc = gpg_error_from_errno (ec);
505
      log_error ("%s: read error: %s (ec=%d)\n",
506
                             a->fname, gpg_strerror (rc), ec);
507
    }
508
      }
509
    else if (!nread)
510
      {
511
        a->eof_seen = 1;
512
        rc = -1;
513
      }
514
    else
515
      {
516
        nbytes = nread;
517
      }
518
519
#else
520
521
47.7k
    int n;
522
523
47.7k
    nbytes = 0;
524
92.4k
        read_more:
525
92.4k
          do
526
92.4k
            {
527
92.4k
              n = read (f, buf + nbytes, size - nbytes);
528
92.4k
            }
529
92.4k
          while (n == -1 && errno == EINTR);
530
92.4k
          if (n > 0)
531
47.6k
            {
532
47.6k
              nbytes += n;
533
47.6k
              if (nbytes < size)
534
44.7k
                goto read_more;
535
47.6k
            }
536
44.7k
          else if (!n) /* eof */
537
44.7k
            {
538
44.7k
              if (nbytes)
539
44.7k
                a->delayed_rc = -1;
540
59
              else
541
59
                {
542
59
                  a->eof_seen = 1;
543
59
                  rc = -1;
544
59
                }
545
44.7k
            }
546
0
          else /* error */
547
0
            {
548
0
              rc = gpg_error_from_syserror ();
549
0
              if (gpg_err_code (rc) != GPG_ERR_EPIPE)
550
0
                log_error ("%s: read error: %s\n", a->fname, gpg_strerror (rc));
551
0
              if (nbytes)
552
0
                {
553
0
                  a->delayed_rc = rc;
554
0
                  rc = 0;
555
0
                }
556
0
            }
557
47.7k
#endif
558
47.7k
    *ret_len = nbytes;
559
47.7k
  }
560
85.6k
    }
561
89.6k
  else if (control == IOBUFCTRL_FLUSH)
562
4
    {
563
4
      if (size)
564
0
  {
565
#ifdef HAVE_W32_SYSTEM
566
    byte *p = buf;
567
    unsigned long n;
568
569
    nbytes = size;
570
    do
571
      {
572
        if (size && !WriteFile (f, p, nbytes, &n, NULL))
573
    {
574
      int ec = gnupg_w32_set_errno (-1);
575
      rc = gpg_error_from_syserror ();
576
      log_error ("%s: write error: %s (ec=%d)\n",
577
                             a->fname, gpg_strerror (rc), ec);
578
      break;
579
    }
580
        p += n;
581
        nbytes -= n;
582
      }
583
    while (nbytes);
584
    nbytes = p - buf;
585
#else
586
0
    byte *p = buf;
587
0
    int n;
588
589
0
    nbytes = size;
590
0
    do
591
0
      {
592
0
        do
593
0
    {
594
0
      n = write (f, p, nbytes);
595
0
    }
596
0
        while (n == -1 && errno == EINTR);
597
0
        if (n > 0)
598
0
    {
599
0
      p += n;
600
0
      nbytes -= n;
601
0
    }
602
0
      }
603
0
    while (n != -1 && nbytes);
604
0
    if (n == -1)
605
0
      {
606
0
        rc = gpg_error_from_syserror ();
607
0
        log_error ("%s: write error: %s\n", a->fname, strerror (errno));
608
0
      }
609
0
    nbytes = p - buf;
610
0
#endif
611
0
  }
612
4
      *ret_len = nbytes;
613
4
    }
614
89.6k
  else if (control == IOBUFCTRL_INIT)
615
44.8k
    {
616
44.8k
      a->eof_seen = 0;
617
44.8k
      a->delayed_rc = 0;
618
44.8k
      a->keep_open = 0;
619
44.8k
      a->no_cache = 0;
620
44.8k
      a->npeeked = 0;
621
44.8k
      a->upeeked = 0;
622
44.8k
    }
623
44.8k
  else if (control == IOBUFCTRL_PEEK)
624
0
    {
625
      /* Peek on the input.  */
626
#ifdef HAVE_W32_SYSTEM
627
      unsigned long nread;
628
629
      nbytes = 0;
630
      if (!ReadFile (f, a->peeked, sizeof a->peeked, &nread, NULL))
631
        {
632
          int ec = (int) GetLastError ();
633
          if (ec != ERROR_BROKEN_PIPE)
634
            {
635
              rc = gpg_error_from_errno (ec);
636
              log_error ("%s: read error: %s (ec=%d)\n",
637
                         a->fname, gpg_strerror (rc), ec);
638
            }
639
          a->npeeked = 0;
640
        }
641
      else if (!nread)
642
        {
643
          a->eof_seen = 1;
644
          a->npeeked = 0;
645
        }
646
      else
647
        {
648
          a->npeeked = nread;
649
        }
650
651
#else /* Unix */
652
653
0
      int n;
654
655
0
    peek_more:
656
0
      do
657
0
        {
658
0
          n = read (f, a->peeked + a->npeeked, sizeof a->peeked - a->npeeked);
659
0
        }
660
0
      while (n == -1 && errno == EINTR);
661
0
      if (n > 0)
662
0
        {
663
0
          a->npeeked += n;
664
0
          if (a->npeeked < sizeof a->peeked)
665
0
            goto peek_more;
666
0
        }
667
0
      else if (!n) /* eof */
668
0
        {
669
0
          if (a->npeeked)
670
0
            a->delayed_rc = -1;
671
0
          else
672
0
            a->eof_seen = 1;
673
0
        }
674
0
      else /* error */
675
0
        {
676
0
          rc = gpg_error_from_syserror ();
677
0
          if (gpg_err_code (rc) != GPG_ERR_EPIPE)
678
0
            log_error ("%s: read error: %s\n", a->fname, gpg_strerror (rc));
679
0
          if (a->npeeked)
680
0
            a->delayed_rc = rc;
681
0
        }
682
0
#endif /* Unix */
683
684
0
      size = a->npeeked < size? a->npeeked : size;
685
0
      memcpy (buf, a->peeked, size);
686
0
      *ret_len = size;
687
0
      rc = 0;  /* Return success - the user needs to check ret_len.  */
688
0
    }
689
44.8k
  else if (control == IOBUFCTRL_DESC)
690
0
    {
691
0
      mem2str (buf, "file_filter(fd)", *ret_len);
692
0
    }
693
44.8k
  else if (control == IOBUFCTRL_FREE)
694
44.8k
    {
695
44.8k
      if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT)
696
44.8k
  {
697
44.8k
    if (DBG_IOBUF)
698
44.8k
      log_debug ("%s: close fd/handle %d\n", a->fname, FD_DBG (f));
699
44.8k
    if (!a->keep_open)
700
44.8k
      fd_cache_close (a->no_cache ? NULL : a->fname, f);
701
44.8k
  }
702
44.8k
      xfree (a); /* We can free our context now. */
703
44.8k
    }
704
705
175k
  return rc;
706
175k
}
707
708
709
/* Similar to file_filter but using the estream system.  */
710
static int
711
file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
712
                size_t * ret_len)
713
0
{
714
0
  file_es_filter_ctx_t *a = opaque;
715
0
  estream_t f = a->fp;
716
0
  size_t size = *ret_len;
717
0
  size_t nbytes = 0;
718
0
  int rc = 0;
719
720
0
  (void)chain; /* Not used.  */
721
722
0
  if (control == IOBUFCTRL_UNDERFLOW)
723
0
    {
724
0
      log_assert (size); /* We need a buffer.  */
725
0
      if (a->eof_seen)
726
0
  {
727
0
    rc = -1;
728
0
    *ret_len = 0;
729
0
  }
730
0
      else if (a->use_readlimit)
731
0
  {
732
0
          nbytes = 0;
733
0
          if (!a->readlimit)
734
0
      {     /* eof */
735
0
        a->eof_seen = 1;
736
0
        rc = -1;
737
0
      }
738
0
          else
739
0
            {
740
0
              if (size > a->readlimit)
741
0
                size = a->readlimit;
742
0
              rc = es_read (f, buf, size, &nbytes);
743
0
              if (rc == -1)
744
0
                {     /* error */
745
0
                  rc = gpg_error_from_syserror ();
746
0
                  log_error ("%s: read error: %s\n", a->fname,strerror (errno));
747
0
                }
748
0
              else if (!nbytes)
749
0
                {     /* eof */
750
0
                  a->eof_seen = 1;
751
0
                  rc = -1;
752
0
                }
753
0
              else
754
0
                a->readlimit -= nbytes;
755
0
            }
756
0
    *ret_len = nbytes;
757
0
  }
758
0
      else
759
0
  {
760
0
          nbytes = 0;
761
0
          rc = es_read (f, buf, size, &nbytes);
762
0
    if (rc == -1)
763
0
      {     /* error */
764
0
              rc = gpg_error_from_syserror ();
765
0
              log_error ("%s: read error: %s\n", a->fname, strerror (errno));
766
0
      }
767
0
    else if (!nbytes)
768
0
      {     /* eof */
769
0
        a->eof_seen = 1;
770
0
        rc = -1;
771
0
      }
772
0
    *ret_len = nbytes;
773
0
  }
774
0
    }
775
0
  else if (control == IOBUFCTRL_FLUSH)
776
0
    {
777
0
      if (size)
778
0
  {
779
0
    byte *p = buf;
780
0
    size_t nwritten;
781
782
0
    nbytes = size;
783
0
    do
784
0
      {
785
0
              nwritten = 0;
786
0
              if (es_write (f, p, nbytes, &nwritten))
787
0
                {
788
0
                  rc = gpg_error_from_syserror ();
789
0
                  log_error ("%s: write error: %s\n",
790
0
                             a->fname, strerror (errno));
791
0
                  break;
792
0
                }
793
0
              p += nwritten;
794
0
              nbytes -= nwritten;
795
0
      }
796
0
    while (nbytes);
797
0
    nbytes = p - buf;
798
0
  }
799
0
      *ret_len = nbytes;
800
0
    }
801
0
  else if (control == IOBUFCTRL_INIT)
802
0
    {
803
0
      a->eof_seen = 0;
804
0
      a->no_cache = 0;
805
0
    }
806
0
  else if (control == IOBUFCTRL_DESC)
807
0
    {
808
0
      mem2str (buf, "estream_filter", *ret_len);
809
0
    }
810
0
  else if (control == IOBUFCTRL_FREE)
811
0
    {
812
0
      if (f != es_stdin && f != es_stdout)
813
0
  {
814
0
    if (DBG_IOBUF)
815
0
      log_debug ("%s: es_fclose %p\n", a->fname, f);
816
0
    if (!a->keep_open)
817
0
      es_fclose (f);
818
0
  }
819
0
      f = NULL;
820
0
      xfree (a); /* We can free our context now. */
821
0
    }
822
823
0
  return rc;
824
0
}
825
826
827
#ifdef HAVE_W32_SYSTEM
828
/* Because network sockets are special objects under Lose32 we have to
829
   use a dedicated filter for them. */
830
static int
831
sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
832
       size_t * ret_len)
833
{
834
  sock_filter_ctx_t *a = opaque;
835
  size_t size = *ret_len;
836
  size_t nbytes = 0;
837
  int rc = 0;
838
839
  (void)chain;
840
841
  if (control == IOBUFCTRL_UNDERFLOW)
842
    {
843
      log_assert (size);    /* need a buffer */
844
      if (a->eof_seen)
845
  {
846
    rc = -1;
847
    *ret_len = 0;
848
  }
849
      else
850
  {
851
    int nread;
852
853
    nread = recv (a->sock, buf, size, 0);
854
    if (nread == SOCKET_ERROR)
855
      {
856
        int ec = (int) WSAGetLastError ();
857
        rc = gpg_error_from_errno (ec);
858
        log_error ("socket read error: ec=%d\n", ec);
859
      }
860
    else if (!nread)
861
      {
862
        a->eof_seen = 1;
863
        rc = -1;
864
      }
865
    else
866
      {
867
        nbytes = nread;
868
      }
869
    *ret_len = nbytes;
870
  }
871
    }
872
  else if (control == IOBUFCTRL_FLUSH)
873
    {
874
      if (size)
875
  {
876
    byte *p = buf;
877
    int n;
878
879
    nbytes = size;
880
    do
881
      {
882
        n = send (a->sock, p, nbytes, 0);
883
        if (n == SOCKET_ERROR)
884
    {
885
      int ec = (int) WSAGetLastError ();
886
      gnupg_w32_set_errno (ec);
887
      rc = gpg_error_from_syserror ();
888
      log_error ("socket write error: ec=%d\n", ec);
889
      break;
890
    }
891
        p += n;
892
        nbytes -= n;
893
      }
894
    while (nbytes);
895
    nbytes = p - buf;
896
  }
897
      *ret_len = nbytes;
898
    }
899
  else if (control == IOBUFCTRL_INIT)
900
    {
901
      a->eof_seen = 0;
902
      a->keep_open = 0;
903
      a->no_cache = 0;
904
    }
905
  else if (control == IOBUFCTRL_DESC)
906
    {
907
      mem2str (buf, "sock_filter", *ret_len);
908
    }
909
  else if (control == IOBUFCTRL_FREE)
910
    {
911
      if (!a->keep_open)
912
  closesocket (a->sock);
913
      xfree (a);    /* we can free our context now */
914
    }
915
  return rc;
916
}
917
#endif /*HAVE_W32_SYSTEM*/
918
919
/****************
920
 * This is used to implement the block write mode.
921
 * Block reading is done on a byte by byte basis in readbyte(),
922
 * without a filter
923
 */
924
static int
925
block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
926
        size_t * ret_len)
927
940k
{
928
940k
  block_filter_ctx_t *a = opaque;
929
940k
  char *buf = (char *)buffer;
930
940k
  size_t size = *ret_len;
931
940k
  int c, needed, rc = 0;
932
940k
  char *p;
933
934
940k
  if (control == IOBUFCTRL_UNDERFLOW)
935
501k
    {
936
501k
      size_t n = 0;
937
938
501k
      p = buf;
939
501k
      log_assert (size); /* need a buffer */
940
501k
      if (a->eof)    /* don't read any further */
941
212k
  rc = -1;
942
1.07M
      while (!rc && size)
943
784k
  {
944
784k
    if (!a->size)
945
714k
      {     /* get the length bytes */
946
714k
        if (a->partial == 2)
947
155k
    {
948
155k
      a->eof = 1;
949
155k
      if (!n)
950
0
        rc = -1;
951
155k
      break;
952
155k
    }
953
558k
        else if (a->partial)
954
558k
    {
955
      /* These OpenPGP introduced huffman like encoded length
956
       * bytes are really a mess :-( */
957
558k
      if (a->first_c)
958
219k
        {
959
219k
          c = a->first_c;
960
219k
          a->first_c = 0;
961
219k
        }
962
338k
      else if ((c = iobuf_get (chain)) == -1)
963
1.56k
        {
964
1.56k
          log_error ("block_filter: 1st length byte missing\n");
965
1.56k
          rc = GPG_ERR_BAD_DATA;
966
1.56k
          break;
967
1.56k
        }
968
556k
      if (c < 192)
969
210k
        {
970
210k
          a->size = c;
971
210k
          a->partial = 2;
972
210k
          if (!a->size)
973
55.1k
      {
974
55.1k
        a->eof = 1;
975
55.1k
        if (!n)
976
5
          rc = -1;
977
55.1k
        break;
978
55.1k
      }
979
210k
        }
980
346k
      else if (c < 224)
981
1.60k
        {
982
1.60k
          a->size = (c - 192) * 256;
983
1.60k
          if ((c = iobuf_get (chain)) == -1)
984
42
      {
985
42
        log_error
986
42
          ("block_filter: 2nd length byte missing\n");
987
42
        rc = GPG_ERR_BAD_DATA;
988
42
        break;
989
42
      }
990
1.56k
          a->size += c + 192;
991
1.56k
          a->partial = 2;
992
1.56k
          if (!a->size)
993
0
      {
994
0
        a->eof = 1;
995
0
        if (!n)
996
0
          rc = -1;
997
0
        break;
998
0
      }
999
1.56k
        }
1000
344k
      else if (c == 255)
1001
3.99k
        {
1002
3.99k
                      size_t len = 0;
1003
3.99k
                      int i;
1004
1005
19.7k
                      for (i = 0; i < 4; i++)
1006
15.8k
                        if ((c = iobuf_get (chain)) == -1)
1007
85
                          break;
1008
15.7k
                        else
1009
15.7k
                          len = ((len << 8) | c);
1010
1011
3.99k
                      if (i < 4)
1012
85
      {
1013
85
        log_error ("block_filter: invalid 4 byte length\n");
1014
85
        rc = GPG_ERR_BAD_DATA;
1015
85
        break;
1016
85
      }
1017
3.91k
                      a->size = len;
1018
3.91k
                      a->partial = 2;
1019
3.91k
                      if (!a->size)
1020
1.20k
                        {
1021
1.20k
                          a->eof = 1;
1022
1.20k
                          if (!n)
1023
0
                            rc = -1;
1024
1.20k
                          break;
1025
1.20k
      }
1026
3.91k
        }
1027
340k
      else
1028
340k
        { /* Next partial body length. */
1029
340k
          a->size = 1 << (c & 0x1f);
1030
340k
        }
1031
      /*  log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
1032
556k
    }
1033
0
        else
1034
0
    BUG ();
1035
714k
      }
1036
1037
1.14M
    while (!rc && size && a->size)
1038
570k
      {
1039
570k
        needed = size < a->size ? size : a->size;
1040
570k
        c = iobuf_read (chain, p, needed);
1041
570k
        if (c < needed)
1042
4.27k
    {
1043
4.27k
      if (c == -1)
1044
531
        c = 0;
1045
4.27k
      log_error
1046
4.27k
        ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
1047
4.27k
         a, (ulong) size + c, (ulong) a->size + c);
1048
4.27k
      rc = GPG_ERR_BAD_DATA;
1049
4.27k
    }
1050
565k
        else
1051
565k
    {
1052
565k
      size -= c;
1053
565k
      a->size -= c;
1054
565k
      p += c;
1055
565k
      n += c;
1056
565k
    }
1057
570k
      }
1058
570k
  }
1059
501k
      *ret_len = n;
1060
501k
    }
1061
438k
  else if (control == IOBUFCTRL_FLUSH)
1062
0
    {
1063
0
      if (a->partial)
1064
0
  {     /* the complicated openpgp scheme */
1065
0
    size_t blen, n, nbytes = size + a->buflen;
1066
1067
0
    log_assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
1068
0
    if (nbytes < OP_MIN_PARTIAL_CHUNK)
1069
0
      {
1070
        /* not enough to write a partial block out; so we store it */
1071
0
        if (!a->buffer)
1072
0
    a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
1073
0
        memcpy (a->buffer + a->buflen, buf, size);
1074
0
        a->buflen += size;
1075
0
      }
1076
0
    else
1077
0
      {     /* okay, we can write out something */
1078
        /* do this in a loop to use the most efficient block lengths */
1079
0
        p = buf;
1080
0
        do
1081
0
    {
1082
      /* find the best matching block length - this is limited
1083
       * by the size of the internal buffering */
1084
0
      for (blen = OP_MIN_PARTIAL_CHUNK * 2,
1085
0
           c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
1086
0
           blen *= 2, c++)
1087
0
        ;
1088
0
      blen /= 2;
1089
0
      c--;
1090
      /* write the partial length header */
1091
0
      log_assert (c <= 0x1f); /*;-) */
1092
0
      c |= 0xe0;
1093
0
      iobuf_put (chain, c);
1094
0
      if ((n = a->buflen))
1095
0
        {   /* write stuff from the buffer */
1096
0
          log_assert (n == OP_MIN_PARTIAL_CHUNK);
1097
0
          if (iobuf_write (chain, a->buffer, n))
1098
0
      rc = gpg_error_from_syserror ();
1099
0
          a->buflen = 0;
1100
0
          nbytes -= n;
1101
0
        }
1102
0
      if ((n = nbytes) > blen)
1103
0
        n = blen;
1104
0
      if (n && iobuf_write (chain, p, n))
1105
0
        rc = gpg_error_from_syserror ();
1106
0
      p += n;
1107
0
      nbytes -= n;
1108
0
    }
1109
0
        while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
1110
        /* store the rest in the buffer */
1111
0
        if (!rc && nbytes)
1112
0
    {
1113
0
      log_assert (!a->buflen);
1114
0
      log_assert (nbytes < OP_MIN_PARTIAL_CHUNK);
1115
0
      if (!a->buffer)
1116
0
        a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
1117
0
      memcpy (a->buffer, p, nbytes);
1118
0
      a->buflen = nbytes;
1119
0
    }
1120
0
      }
1121
0
  }
1122
0
      else
1123
0
  BUG ();
1124
0
    }
1125
438k
  else if (control == IOBUFCTRL_INIT)
1126
219k
    {
1127
219k
      if (DBG_IOBUF)
1128
219k
  log_debug ("init block_filter %p\n", a);
1129
219k
      if (a->partial)
1130
219k
  a->count = 0;
1131
0
      else if (a->use == IOBUF_INPUT)
1132
0
  a->count = a->size = 0;
1133
0
      else
1134
0
  a->count = a->size; /* force first length bytes */
1135
219k
      a->eof = 0;
1136
219k
      a->buffer = NULL;
1137
219k
      a->buflen = 0;
1138
219k
    }
1139
219k
  else if (control == IOBUFCTRL_DESC)
1140
0
    {
1141
0
      mem2str (buf, "block_filter", *ret_len);
1142
0
    }
1143
219k
  else if (control == IOBUFCTRL_FREE)
1144
219k
    {
1145
219k
      if (a->use == IOBUF_OUTPUT)
1146
0
  {     /* write the end markers */
1147
0
    if (a->partial)
1148
0
      {
1149
0
        u32 len;
1150
        /* write out the remaining bytes without a partial header
1151
         * the length of this header may be 0 - but if it is
1152
         * the first block we are not allowed to use a partial header
1153
         * and frankly we can't do so, because this length must be
1154
         * a power of 2. This is _really_ complicated because we
1155
         * have to check the possible length of a packet prior
1156
         * to it's creation: a chain of filters becomes complicated
1157
         * and we need a lot of code to handle compressed packets etc.
1158
         *   :-(((((((
1159
         */
1160
        /* construct header */
1161
0
        len = a->buflen;
1162
        /*log_debug("partial: remaining length=%u\n", len ); */
1163
0
        if (len < 192)
1164
0
    rc = iobuf_put (chain, len);
1165
0
        else if (len < 8384)
1166
0
    {
1167
0
      if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
1168
0
        rc = iobuf_put (chain, ((len - 192) % 256));
1169
0
    }
1170
0
        else
1171
0
    {   /* use a 4 byte header */
1172
0
      if (!(rc = iobuf_put (chain, 0xff)))
1173
0
        if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
1174
0
          if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
1175
0
      if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
1176
0
        rc = iobuf_put (chain, len & 0xff);
1177
0
    }
1178
0
        if (!rc && len)
1179
0
    rc = iobuf_write (chain, a->buffer, len);
1180
0
        if (rc)
1181
0
    {
1182
0
      log_error ("block_filter: write error: %s\n",
1183
0
           strerror (errno));
1184
0
      rc = gpg_error_from_syserror ();
1185
0
    }
1186
0
        xfree (a->buffer);
1187
0
        a->buffer = NULL;
1188
0
        a->buflen = 0;
1189
0
      }
1190
0
    else
1191
0
      BUG ();
1192
0
  }
1193
219k
      else if (a->size)
1194
5.28k
  {
1195
5.28k
    log_error ("block_filter: pending bytes!\n");
1196
5.28k
  }
1197
219k
      if (DBG_IOBUF)
1198
219k
  log_debug ("free block_filter %p\n", a);
1199
219k
      xfree (a);   /* we can free our context now */
1200
219k
    }
1201
1202
940k
  return rc;
1203
940k
}
1204
1205
1206
/* Change the default size for all IOBUFs to KILOBYTE.  This needs to
1207
 * be called before any iobufs are used and can only be used once.
1208
 * Returns the current value.  Using 0 has no effect except for
1209
 * returning the current value.  */
1210
unsigned int
1211
iobuf_set_buffer_size (unsigned int kilobyte)
1212
2.96k
{
1213
2.96k
  static int used;
1214
1215
2.96k
  if (!used && kilobyte)
1216
0
    {
1217
0
      if (kilobyte < 4)
1218
0
        kilobyte = 4;
1219
0
      else if (kilobyte > 16*1024)
1220
0
        kilobyte = 16*1024;
1221
1222
0
      iobuf_buffer_size = kilobyte * 1024;
1223
0
      used = 1;
1224
0
    }
1225
2.96k
  return iobuf_buffer_size / 1024;
1226
2.96k
}
1227
1228
1229
0
#define MAX_IOBUF_DESC 32
1230
/*
1231
 * Fill the buffer by the description of iobuf A.
1232
 * The buffer size should be MAX_IOBUF_DESC (or larger).
1233
 * Returns BUF as (const char *).
1234
 */
1235
static const char *
1236
iobuf_desc (iobuf_t a, byte *buf)
1237
0
{
1238
0
  size_t len = MAX_IOBUF_DESC;
1239
1240
0
  if (! a || ! a->filter)
1241
0
    memcpy (buf, "?", 2);
1242
0
  else
1243
0
    a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL, buf, &len);
1244
1245
0
  return buf;
1246
0
}
1247
1248
static void
1249
print_chain (iobuf_t a)
1250
224k
{
1251
224k
  if (!DBG_IOBUF)
1252
224k
    return;
1253
0
  for (; a; a = a->chain)
1254
0
    {
1255
0
      byte desc[MAX_IOBUF_DESC];
1256
1257
0
      log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
1258
0
     a->no, a->subno, iobuf_desc (a, desc), a->filter_eof,
1259
0
     (int) a->d.start, (int) a->d.len);
1260
0
    }
1261
0
}
1262
1263
int
1264
iobuf_print_chain (iobuf_t a)
1265
0
{
1266
0
  print_chain (a);
1267
0
  return 0;
1268
0
}
1269
1270
iobuf_t
1271
iobuf_alloc (int use, size_t bufsize)
1272
8.18M
{
1273
8.18M
  iobuf_t a;
1274
8.18M
  static int number = 0;
1275
1276
8.18M
  log_assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
1277
8.18M
              || use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
1278
8.18M
  if (bufsize == 0)
1279
0
    {
1280
0
      log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
1281
0
      bufsize = iobuf_buffer_size;
1282
0
    }
1283
1284
8.18M
  a = xcalloc (1, sizeof *a);
1285
8.18M
  a->use = use;
1286
8.18M
  a->d.buf = xmalloc (bufsize);
1287
8.18M
  a->d.size = bufsize;
1288
8.18M
  a->e_d.buf = NULL;
1289
8.18M
  a->e_d.len = 0;
1290
8.18M
  a->e_d.used = 0;
1291
8.18M
  a->e_d.preferred = 0;
1292
8.18M
  a->no = ++number;
1293
8.18M
  a->subno = 0;
1294
8.18M
  a->real_fname = NULL;
1295
8.18M
  return a;
1296
8.18M
}
1297
1298
int
1299
iobuf_close (iobuf_t a)
1300
9.09M
{
1301
9.09M
  iobuf_t a_chain;
1302
9.09M
  size_t dummy_len = 0;
1303
9.09M
  int rc = 0;
1304
1305
17.2M
  for (; a; a = a_chain)
1306
8.19M
    {
1307
8.19M
      byte desc[MAX_IOBUF_DESC];
1308
8.19M
      int rc2 = 0;
1309
1310
8.19M
      a_chain = a->chain;
1311
1312
8.19M
      if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1313
8.19M
  log_error ("filter_flush failed on close: %s\n", gpg_strerror (rc));
1314
1315
8.19M
      if (DBG_IOBUF)
1316
8.19M
  log_debug ("iobuf-%d.%d: close '%s'\n",
1317
0
       a->no, a->subno, iobuf_desc (a, desc));
1318
1319
8.19M
      if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1320
17.6k
           a->chain, NULL, &dummy_len)))
1321
8.19M
  log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1322
8.19M
      if (! rc && rc2)
1323
  /* Whoops!  An error occurred.  Save it in RC if we haven't
1324
     already recorded an error.  */
1325
0
  rc = rc2;
1326
1327
8.19M
      xfree (a->real_fname);
1328
8.19M
      if (a->d.buf)
1329
8.19M
  {
1330
8.19M
    memset (a->d.buf, 0, a->d.size);  /* erase the buffer */
1331
8.19M
    xfree (a->d.buf);
1332
8.19M
  }
1333
8.19M
      xfree (a);
1334
8.19M
    }
1335
9.09M
  return rc;
1336
9.09M
}
1337
1338
int
1339
iobuf_cancel (iobuf_t a)
1340
0
{
1341
0
  const char *s;
1342
0
  iobuf_t a2;
1343
0
  int rc;
1344
#if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1345
  char *remove_name = NULL;
1346
#endif
1347
1348
0
  if (a && a->use == IOBUF_OUTPUT)
1349
0
    {
1350
0
      s = iobuf_get_real_fname (a);
1351
0
      if (s && *s)
1352
0
  {
1353
#if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1354
    remove_name = xstrdup (s);
1355
#else
1356
0
    remove (s);
1357
0
#endif
1358
0
  }
1359
0
    }
1360
1361
  /* send a cancel message to all filters */
1362
0
  for (a2 = a; a2; a2 = a2->chain)
1363
0
    {
1364
0
      size_t dummy = 0;
1365
0
      if (a2->filter)
1366
0
  a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1367
0
    }
1368
1369
0
  rc = iobuf_close (a);
1370
#if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1371
  if (remove_name)
1372
    {
1373
      /* Argg, MSDOS does not allow removing open files.  So
1374
       * we have to do it here */
1375
      gnupg_remove (remove_name);
1376
1377
      xfree (remove_name);
1378
    }
1379
#endif
1380
0
  return rc;
1381
0
}
1382
1383
1384
iobuf_t
1385
iobuf_temp (void)
1386
8.12M
{
1387
8.12M
  return iobuf_alloc (IOBUF_OUTPUT_TEMP, iobuf_buffer_size);
1388
8.12M
}
1389
1390
iobuf_t
1391
iobuf_temp_with_content (const char *buffer, size_t length)
1392
12.6k
{
1393
12.6k
  iobuf_t a;
1394
12.6k
  int i;
1395
1396
12.6k
  a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
1397
12.6k
  log_assert (length == a->d.size);
1398
  /* memcpy (a->d.buf, buffer, length); */
1399
3.01G
  for (i=0; i < length; i++)
1400
3.01G
    a->d.buf[i] = buffer[i];
1401
12.6k
  a->d.len = length;
1402
1403
12.6k
  return a;
1404
12.6k
}
1405
1406
1407
int
1408
iobuf_is_pipe_filename (const char *fname)
1409
304k
{
1410
304k
  if (!fname || (*fname=='-' && !fname[1]) )
1411
789
    return 1;
1412
303k
  return gnupg_check_special_filename (fname) != GNUPG_INVALID_FD;
1413
304k
}
1414
1415
1416
static iobuf_t
1417
do_open (const char *fname, int special_filenames,
1418
   int use, const char *opentype, int mode700)
1419
44.8k
{
1420
44.8k
  iobuf_t a;
1421
44.8k
  gnupg_fd_t fp;
1422
44.8k
  file_filter_ctx_t *fcx;
1423
44.8k
  size_t len = 0;
1424
44.8k
  int print_only = 0;
1425
44.8k
  gnupg_fd_t fd;
1426
44.8k
  byte desc[MAX_IOBUF_DESC];
1427
1428
44.8k
  log_assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
1429
1430
44.8k
  if (special_filenames
1431
      /* NULL or '-'.  */
1432
44.8k
      && (!fname || (*fname == '-' && !fname[1])))
1433
0
    {
1434
0
      if (use == IOBUF_INPUT)
1435
0
  {
1436
0
    fp = FD_FOR_STDIN;
1437
0
    fname = "[stdin]";
1438
0
  }
1439
0
      else
1440
0
  {
1441
0
    fp = FD_FOR_STDOUT;
1442
0
    fname = "[stdout]";
1443
0
  }
1444
0
      print_only = 1;
1445
0
    }
1446
44.8k
  else if (!fname)
1447
0
    return NULL;
1448
44.8k
  else if (special_filenames
1449
44.8k
           && (fd = gnupg_check_special_filename (fname)) != GNUPG_INVALID_FD)
1450
0
    return do_iobuf_fdopen (fd, opentype, 0);
1451
44.8k
  else
1452
44.8k
    {
1453
44.8k
      if (use == IOBUF_INPUT)
1454
44.8k
  fp = fd_cache_open (fname, opentype);
1455
4
      else
1456
4
  fp = direct_open (fname, opentype, mode700);
1457
44.8k
      if (fp == GNUPG_INVALID_FD)
1458
0
  return NULL;
1459
44.8k
    }
1460
1461
44.8k
  a = iobuf_alloc (use, iobuf_buffer_size);
1462
44.8k
  fcx = xmalloc (sizeof *fcx + strlen (fname));
1463
44.8k
  fcx->fp = fp;
1464
44.8k
  fcx->print_only_name = print_only;
1465
44.8k
  strcpy (fcx->fname, fname);
1466
44.8k
  if (!print_only)
1467
44.8k
    a->real_fname = xstrdup (fname);
1468
44.8k
  a->filter = file_filter;
1469
44.8k
  a->filter_ov = fcx;
1470
44.8k
  file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1471
44.8k
  if (DBG_IOBUF)
1472
44.8k
    log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n",
1473
0
         a->no, a->subno, fname, iobuf_desc (a, desc),
1474
0
               FD_DBG (fcx->fp));
1475
1476
44.8k
  return a;
1477
44.8k
}
1478
1479
iobuf_t
1480
iobuf_open (const char *fname)
1481
44.8k
{
1482
44.8k
  return do_open (fname, 1, IOBUF_INPUT, "rb", 0);
1483
44.8k
}
1484
1485
iobuf_t
1486
iobuf_create (const char *fname, int mode700)
1487
4
{
1488
4
  return do_open (fname, 1, IOBUF_OUTPUT, "wb", mode700);
1489
4
}
1490
1491
iobuf_t
1492
iobuf_openrw (const char *fname)
1493
0
{
1494
0
  return do_open (fname, 0, IOBUF_OUTPUT, "r+b", 0);
1495
0
}
1496
1497
1498
static iobuf_t
1499
do_iobuf_fdopen (gnupg_fd_t fp, const char *mode, int keep_open)
1500
0
{
1501
0
  iobuf_t a;
1502
0
  file_filter_ctx_t *fcx;
1503
0
  size_t len = 0;
1504
1505
0
  a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1506
0
       iobuf_buffer_size);
1507
0
  fcx = xmalloc (sizeof *fcx + 20);
1508
0
  fcx->fp = fp;
1509
0
  fcx->print_only_name = 1;
1510
0
  fcx->keep_open = keep_open;
1511
0
  sprintf (fcx->fname, "[fd %d]", FD_DBG (fp));
1512
0
  a->filter = file_filter;
1513
0
  a->filter_ov = fcx;
1514
0
  file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1515
0
  if (DBG_IOBUF)
1516
0
    log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
1517
0
               a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1518
0
  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1519
0
  return a;
1520
0
}
1521
1522
1523
iobuf_t
1524
iobuf_fdopen (gnupg_fd_t fp, const char *mode)
1525
0
{
1526
0
  return do_iobuf_fdopen (fp, mode, 0);
1527
0
}
1528
1529
iobuf_t
1530
iobuf_fdopen_nc (gnupg_fd_t fp, const char *mode)
1531
0
{
1532
0
  return do_iobuf_fdopen (fp, mode, 1);
1533
0
}
1534
1535
1536
iobuf_t
1537
iobuf_esopen (estream_t estream, const char *mode, int keep_open,
1538
              size_t readlimit)
1539
0
{
1540
0
  iobuf_t a;
1541
0
  file_es_filter_ctx_t *fcx;
1542
0
  size_t len = 0;
1543
1544
0
  a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1545
0
       iobuf_buffer_size);
1546
0
  fcx = xtrymalloc (sizeof *fcx + 30);
1547
0
  fcx->fp = estream;
1548
0
  fcx->print_only_name = 1;
1549
0
  fcx->keep_open = keep_open;
1550
0
  fcx->readlimit = readlimit;
1551
0
  fcx->use_readlimit = !!readlimit;
1552
0
  snprintf (fcx->fname, 30, "[fd %p]", estream);
1553
0
  a->filter = file_es_filter;
1554
0
  a->filter_ov = fcx;
1555
0
  file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1556
0
  if (DBG_IOBUF)
1557
0
    log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
1558
0
               a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1559
0
  return a;
1560
0
}
1561
1562
1563
iobuf_t
1564
iobuf_sockopen (int fd, const char *mode)
1565
0
{
1566
0
  iobuf_t a;
1567
#ifdef HAVE_W32_SYSTEM
1568
  sock_filter_ctx_t *scx;
1569
  size_t len;
1570
1571
  a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1572
       iobuf_buffer_size);
1573
  scx = xmalloc (sizeof *scx + 25);
1574
  scx->sock = fd;
1575
  scx->print_only_name = 1;
1576
  sprintf (scx->fname, "[sock %d]", fd);
1577
  a->filter = sock_filter;
1578
  a->filter_ov = scx;
1579
  sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1580
  if (DBG_IOBUF)
1581
    log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
1582
  iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1583
#else
1584
0
  a = do_iobuf_fdopen (fd, mode, 0);
1585
0
#endif
1586
0
  return a;
1587
0
}
1588
1589
int
1590
iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
1591
22.3k
{
1592
22.3k
  byte desc[MAX_IOBUF_DESC];
1593
1594
22.3k
  if (cmd == IOBUF_IOCTL_KEEP_OPEN)
1595
0
    {
1596
      /* Keep system filepointer/descriptor open.  This was used in
1597
         the past by http.c; this ioctl is not directly used
1598
         anymore.  */
1599
0
      if (DBG_IOBUF)
1600
0
  log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
1601
0
       a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc),
1602
0
       intval);
1603
0
      for (; a; a = a->chain)
1604
0
  if (!a->chain && a->filter == file_filter)
1605
0
    {
1606
0
      file_filter_ctx_t *b = a->filter_ov;
1607
0
      b->keep_open = intval;
1608
0
      return 0;
1609
0
    }
1610
#ifdef HAVE_W32_SYSTEM
1611
  else if (!a->chain && a->filter == sock_filter)
1612
    {
1613
      sock_filter_ctx_t *b = a->filter_ov;
1614
      b->keep_open = intval;
1615
      return 0;
1616
    }
1617
#endif
1618
0
    }
1619
22.3k
  else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
1620
7.51k
    {
1621
7.51k
      if (DBG_IOBUF)
1622
7.51k
  log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
1623
0
       ptrval ? (char *) ptrval : "?");
1624
7.51k
      if (!a && !intval && ptrval)
1625
7.51k
  {
1626
7.51k
    if (fd_cache_invalidate (ptrval))
1627
0
            return -1;
1628
7.51k
    return 0;
1629
7.51k
  }
1630
7.51k
    }
1631
14.8k
  else if (cmd == IOBUF_IOCTL_NO_CACHE)
1632
14.8k
    {
1633
14.8k
      if (DBG_IOBUF)
1634
14.8k
  log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
1635
0
       a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc),
1636
0
       intval);
1637
14.8k
      for (; a; a = a->chain)
1638
14.8k
  if (!a->chain && a->filter == file_filter)
1639
14.8k
    {
1640
14.8k
      file_filter_ctx_t *b = a->filter_ov;
1641
14.8k
      b->no_cache = intval;
1642
14.8k
      return 0;
1643
14.8k
    }
1644
#ifdef HAVE_W32_SYSTEM
1645
  else if (!a->chain && a->filter == sock_filter)
1646
    {
1647
      sock_filter_ctx_t *b = a->filter_ov;
1648
      b->no_cache = intval;
1649
      return 0;
1650
    }
1651
#endif
1652
14.8k
    }
1653
0
  else if (cmd == IOBUF_IOCTL_FSYNC)
1654
0
    {
1655
      /* Do a fsync on the open fd and return any errors to the caller
1656
         of iobuf_ioctl.  Note that we work on a file name here. */
1657
0
      if (DBG_IOBUF)
1658
0
        log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
1659
0
                   ptrval? (const char*)ptrval:"<null>");
1660
1661
0
      if (!a && !intval && ptrval)
1662
0
        {
1663
0
          return fd_cache_synchronize (ptrval);
1664
0
        }
1665
0
    }
1666
0
  else if (cmd == IOBUF_IOCTL_PEEK)
1667
0
    {
1668
      /* Peek at a justed opened file.  Use this only directly after a
1669
       * file has been opened for reading.  Don't use it after you did
1670
       * a seek.  This works only if just file filter has been
1671
       * pushed.  Expects a buffer with size INTVAL at PTRVAL and returns
1672
       * the number of bytes put into the buffer.  */
1673
0
      if (DBG_IOBUF)
1674
0
  log_debug ("iobuf-%d.%d: ioctl '%s' peek\n",
1675
0
       a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a, desc));
1676
0
      if (a->filter == file_filter && ptrval && intval)
1677
0
        {
1678
0
          file_filter_ctx_t *fcx = a->filter_ov;
1679
0
          size_t len = intval;
1680
1681
0
          if (!file_filter (fcx, IOBUFCTRL_PEEK, NULL, ptrval, &len))
1682
0
            return (int)len;
1683
0
        }
1684
0
    }
1685
1686
1687
0
  return -1;
1688
22.3k
}
1689
1690
1691
/****************
1692
 * Register an i/o filter.
1693
 */
1694
int
1695
iobuf_push_filter (iobuf_t a,
1696
       int (*f) (void *opaque, int control,
1697
           iobuf_t chain, byte * buf, size_t * len),
1698
                   void *ov)
1699
236k
{
1700
236k
  return iobuf_push_filter2 (a, f, ov, 0);
1701
236k
}
1702
1703
int
1704
iobuf_push_filter2 (iobuf_t a,
1705
        int (*f) (void *opaque, int control,
1706
            iobuf_t chain, byte * buf, size_t * len),
1707
        void *ov, int rel_ov)
1708
236k
{
1709
236k
  iobuf_t b;
1710
236k
  size_t dummy_len = 0;
1711
236k
  int rc = 0;
1712
1713
236k
  if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1714
0
    return rc;
1715
1716
236k
  if (a->subno >= MAX_NESTING_FILTER)
1717
659
    {
1718
659
      log_error ("i/o filter too deeply nested - corrupted data?\n");
1719
659
      return GPG_ERR_BAD_DATA;
1720
659
    }
1721
1722
  /* We want to create a new filter and put it in front of A.  A
1723
   * simple implementation would do:
1724
   *
1725
   *    b = iobuf_alloc (...);
1726
   *    b->chain = a;
1727
   *    return a;
1728
   *
1729
   *  This is a bit problematic: A is the head of the pipeline and
1730
   *  there are potentially many pointers to it.  Requiring the caller
1731
   *  to update all of these pointers is a burden.
1732
   *
1733
   *  An alternative implementation would add a level of indirection.
1734
   *  For instance, we could use a pipeline object, which contains a
1735
   *  pointer to the first filter in the pipeline.  This is not what we
1736
   *  do either.
1737
   *
1738
   *  Instead, we allocate a new buffer (B) and copy the first filter's
1739
   *  state into that and use the initial buffer (A) for the new
1740
   *  filter.  One limitation of this approach is that it is not
1741
   *  practical to maintain a pointer to a specific filter's state.
1742
   *
1743
   *  Before:
1744
   *
1745
   *        A
1746
   *        |
1747
   *        v 0x100               0x200
1748
   *        +----------+          +----------+
1749
   *        | filter x |--------->| filter y |---->....
1750
   *        +----------+          +----------+
1751
   *
1752
   *  After:           B
1753
   *                   |
1754
   *                   v 0x300
1755
   *                   +----------+
1756
   *        A          | filter x |
1757
   *        |          +----------+
1758
   *        v 0x100    ^          v 0x200
1759
   *        +----------+          +----------+
1760
   *        | filter w |          | filter y |---->....
1761
   *        +----------+          +----------+
1762
   *
1763
   *  Note: filter x's address changed from 0x100 to 0x300, but A still
1764
   *  points to the head of the pipeline.
1765
   */
1766
1767
235k
  b = xmalloc (sizeof *b);
1768
235k
  memcpy (b, a, sizeof *b);
1769
  /* fixme: it is stupid to keep a copy of the name at every level
1770
   * but we need the name somewhere because the name known by file_filter
1771
   * may have been released when we need the name of the file */
1772
235k
  b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1773
  /* remove the filter stuff from the new stream */
1774
235k
  a->filter = NULL;
1775
235k
  a->filter_ov = NULL;
1776
235k
  a->filter_ov_owner = 0;
1777
235k
  a->filter_eof = 0;
1778
235k
  if (a->use == IOBUF_OUTPUT_TEMP)
1779
0
    {
1780
      /* A TEMP filter buffers any data sent to it; it does not
1781
       * forward any data down the pipeline.  If we add a new filter
1782
       * to the pipeline, it shouldn't also buffer data.  It should
1783
       * send it downstream to be buffered.  Thus, the correct type
1784
       * for a filter added in front of an IOBUF_OUTPUT_TEMP filter is
1785
       * IOBUF_OUPUT, not IOBUF_OUTPUT_TEMP.  */
1786
0
      a->use = IOBUF_OUTPUT;
1787
1788
      /* When pipeline is written to, the temp buffer's size is
1789
       * increased accordingly.  We don't need to allocate a 10 MB
1790
       * buffer for a non-terminal filter.  Just use the default
1791
       * size.  */
1792
0
      a->d.size = iobuf_buffer_size;
1793
0
    }
1794
235k
  else if (a->use == IOBUF_INPUT_TEMP)
1795
0
    {
1796
      /* Same idea as above.  */
1797
0
      a->use = IOBUF_INPUT;
1798
0
      a->d.size = iobuf_buffer_size;
1799
0
    }
1800
1801
  /* The new filter (A) gets a new buffer.
1802
   *
1803
   * If the pipeline is an output or temp pipeline, then giving the
1804
   * buffer to the new filter means that data that was written before
1805
   * the filter was pushed gets sent to the filter.  That's clearly
1806
   * wrong.
1807
   *
1808
   * If the pipeline is an input pipeline, then giving the buffer to
1809
   * the new filter (A) means that data that has read from (B), but
1810
   * not yet read from the pipeline won't be processed by the new
1811
   * filter (A)!  That's certainly not what we want.  */
1812
235k
  a->d.buf = xmalloc (a->d.size);
1813
235k
  a->d.len = 0;
1814
235k
  a->d.start = 0;
1815
1816
  /* Disable nlimit for the new stream.  */
1817
235k
  a->ntotal = b->ntotal + b->nbytes;
1818
235k
  a->nlimit = a->nbytes = 0;
1819
235k
  a->nofast = 0;
1820
  /* Make a link from the new stream to the original stream.  */
1821
235k
  a->chain = b;
1822
1823
  /* Setup the function on the new stream.  */
1824
235k
  a->filter = f;
1825
235k
  a->filter_ov = ov;
1826
235k
  a->filter_ov_owner = rel_ov;
1827
1828
235k
  a->subno = b->subno + 1;
1829
1830
235k
  if (DBG_IOBUF)
1831
0
    {
1832
0
      byte desc[MAX_IOBUF_DESC];
1833
0
      log_debug ("iobuf-%d.%d: push '%s'\n",
1834
0
     a->no, a->subno, iobuf_desc (a, desc));
1835
0
      print_chain (a);
1836
0
    }
1837
1838
  /* Now we can initialize the new function if we have one.  */
1839
235k
  if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1840
235k
            NULL, &dummy_len)))
1841
235k
    log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1842
235k
  return rc;
1843
236k
}
1844
1845
1846
/****************
1847
 * Remove an i/o filter.
1848
 */
1849
int
1850
iobuf_pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1851
                                       iobuf_t chain, byte * buf, size_t * len),
1852
                  void *ov)
1853
0
{
1854
0
  iobuf_t b;
1855
0
  size_t dummy_len = 0;
1856
0
  int rc = 0;
1857
0
  byte desc[MAX_IOBUF_DESC];
1858
1859
0
  if (DBG_IOBUF)
1860
0
    log_debug ("iobuf-%d.%d: pop '%s'\n",
1861
0
         a->no, a->subno, iobuf_desc (a, desc));
1862
0
  if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
1863
0
    {
1864
      /* This should be the last filter in the pipeline.  */
1865
0
      log_assert (! a->chain);
1866
0
      return 0;
1867
0
    }
1868
0
  if (!a->filter)
1869
0
    { /* (this is simple) */
1870
0
      b = a->chain;
1871
0
      log_assert (b);
1872
0
      xfree (a->d.buf);
1873
0
      xfree (a->real_fname);
1874
0
      memcpy (a, b, sizeof *a);
1875
0
      xfree (b);
1876
0
      return 0;
1877
0
    }
1878
0
  for (b = a; b; b = b->chain)
1879
0
    if (b->filter == f && (!ov || b->filter_ov == ov))
1880
0
      break;
1881
0
  if (!b)
1882
0
    log_bug ("iobuf_pop_filter(): filter function not found\n");
1883
1884
  /* Flush this stream if it is an output stream ... */
1885
0
  if (a->use == IOBUF_OUTPUT && (rc = filter_flush (b)))
1886
0
    {
1887
0
      log_error ("filter_flush failed in iobuf_pop_filter: %s\n",
1888
0
                 gpg_strerror (rc));
1889
0
      return rc;
1890
0
    }
1891
  /* and tell the filter to free it self  */
1892
0
  if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1893
0
            NULL, &dummy_len)))
1894
0
    {
1895
0
      log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1896
0
      return rc;
1897
0
    }
1898
0
  if (b->filter_ov && b->filter_ov_owner)
1899
0
    {
1900
0
      xfree (b->filter_ov);
1901
0
      b->filter_ov = NULL;
1902
0
    }
1903
1904
1905
  /* and see how to remove it */
1906
0
  if (a == b && !b->chain)
1907
0
    log_bug ("can't remove the last filter from the chain\n");
1908
0
  else if (a == b)
1909
0
    { /* Remove the first iobuf from the chain.
1910
       * Everything from B is copied to A.  This is save because
1911
       * a flush has been done on the to be removed entry.   */
1912
0
      b = a->chain;
1913
0
      xfree (a->d.buf);
1914
0
      xfree (a->real_fname);
1915
0
      memcpy (a, b, sizeof *a);
1916
0
      xfree (b);
1917
0
      if (DBG_IOBUF)
1918
0
  log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1919
0
    }
1920
0
  else if (!b->chain)
1921
0
    { /* Remove the last iobuf from the chain.  */
1922
0
      log_bug ("Ohh jeee, trying to remove a head filter\n");
1923
0
    }
1924
0
  else
1925
0
    { /* Remove an intermediate iobuf from the chain.  */
1926
0
      log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1927
0
    }
1928
1929
0
  return rc;
1930
0
}
1931
1932
1933
/****************
1934
 * read underflow: read at least one byte into the buffer and return
1935
 * the first byte or -1 on EOF.
1936
 */
1937
static int
1938
underflow (iobuf_t a, int clear_pending_eof)
1939
2.60G
{
1940
2.60G
  return underflow_target (a, clear_pending_eof, 1);
1941
2.60G
}
1942
1943
1944
/****************
1945
 * read underflow: read TARGET bytes into the buffer and return
1946
 * the first byte or -1 on EOF.
1947
 */
1948
static int
1949
underflow_target (iobuf_t a, int clear_pending_eof, size_t target)
1950
2.60G
{
1951
2.60G
  size_t len;
1952
2.60G
  int rc;
1953
1954
2.60G
  if (DBG_IOBUF)
1955
2.60G
    log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
1956
0
         a->no, a->subno,
1957
0
         (int) a->d.size, (int) (a->d.len - a->d.start),
1958
0
         (int) (a->d.size - (a->d.len - a->d.start)));
1959
1960
2.60G
  if (a->use == IOBUF_INPUT_TEMP)
1961
11.7k
    {
1962
      /* By definition, there isn't more data to read into the
1963
         buffer.  */
1964
11.7k
      return -1;
1965
11.7k
    }
1966
1967
2.60G
  log_assert (a->use == IOBUF_INPUT);
1968
1969
2.60G
  a->e_d.used = 0;
1970
1971
  /* If there is still some buffered data, then move it to the start
1972
   * of the buffer and try to fill the end of the buffer.  (This is
1973
   * useful if we are called from iobuf_peek().)  */
1974
2.60G
  log_assert (a->d.start <= a->d.len);
1975
2.60G
  a->d.len -= a->d.start;
1976
2.60G
  if (a->d.len)
1977
160
    memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
1978
2.60G
  a->d.start = 0;
1979
1980
2.60G
  if (a->d.len < target && a->filter_eof)
1981
30.8k
    {
1982
      /* The last time we tried to read from this filter, we got an
1983
       * EOF.  We couldn't return the EOF, because there was buffered
1984
       * data.  Since there is no longer any buffered data, return the
1985
       * error.  */
1986
30.8k
      if (DBG_IOBUF)
1987
30.8k
  log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
1988
0
       a->no, a->subno);
1989
30.8k
      if (! clear_pending_eof)
1990
80
  return -1;
1991
1992
30.7k
      if (a->chain)
1993
737
  {
1994
          /* A filter follows this one.  Free this filter.  */
1995
737
    iobuf_t b = a->chain;
1996
737
    if (DBG_IOBUF)
1997
737
      log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
1998
0
           a->no, a->subno);
1999
737
    xfree (a->d.buf);
2000
737
    xfree (a->real_fname);
2001
737
    memcpy (a, b, sizeof *a);
2002
737
    xfree (b);
2003
737
    print_chain (a);
2004
737
  }
2005
30.0k
      else
2006
30.0k
  a->filter_eof = 0; /* for the top level filter */
2007
30.7k
      return -1;   /* return one(!) EOF */
2008
30.8k
    }
2009
2010
2.60G
  if (a->d.len == 0 && a->error)
2011
38.8k
    {
2012
      /* The last time we tried to read from this filter, we got an
2013
       * error.  We couldn't return the error, because there was
2014
       * buffered data.  Since there is no longer any buffered data,
2015
       * return the error.  */
2016
38.8k
      if (DBG_IOBUF)
2017
38.8k
  log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
2018
0
       a->no, a->subno, gpg_strerror (a->error));
2019
38.8k
      return -1;
2020
38.8k
    }
2021
2022
2.60G
  if (a->filter && ! a->filter_eof && ! a->error)
2023
724k
    {
2024
      /* We have a filter function and the last time we tried to read
2025
       * we didn't get an EOF or an error.  Try to fill the buffer.
2026
       * Be careful to account for any buffered data.  */
2027
724k
      len = a->d.size - a->d.len;
2028
2029
724k
      if (a->e_d.preferred && a->d.len < IOBUF_ZEROCOPY_THRESHOLD_SIZE
2030
86.0k
    && (IOBUF_ZEROCOPY_THRESHOLD_SIZE - a->d.len) < len)
2031
86.0k
  {
2032
86.0k
    if (DBG_IOBUF)
2033
86.0k
      log_debug ("iobuf-%d.%d: limit buffering as external drain is "
2034
0
      "preferred\n",  a->no, a->subno);
2035
86.0k
    len = IOBUF_ZEROCOPY_THRESHOLD_SIZE - a->d.len;
2036
86.0k
  }
2037
2038
724k
      if (len == 0)
2039
0
        {
2040
          /* There is no space for more data.  Don't bother calling
2041
           * A->FILTER.  */
2042
0
          rc = 0;
2043
0
        }
2044
724k
      else
2045
724k
        {
2046
724k
          size_t tmplen;
2047
2048
          /* If no buffered data and drain buffer has been setup, and
2049
           * drain buffer is largish, read data directly to drain buffer. */
2050
724k
          if (a->d.len == 0
2051
724k
              && a->e_d.buf
2052
8.30k
              && a->e_d.len >= IOBUF_ZEROCOPY_THRESHOLD_SIZE)
2053
8.30k
            {
2054
8.30k
              len = a->e_d.len;
2055
2056
8.30k
              if (DBG_IOBUF)
2057
8.30k
                log_debug ("iobuf-%d.%d: underflow:"
2058
0
                           " A->FILTER (%lu bytes, to external drain)\n",
2059
0
                           a->no, a->subno, (ulong)len);
2060
2061
8.30k
              tmplen = len;  /* Used to check for bugs in the filter.  */
2062
8.30k
              rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
2063
8.30k
                              a->e_d.buf, &len);
2064
8.30k
              log_assert (len <= tmplen);
2065
8.30k
              a->e_d.used = len;
2066
8.30k
              len = 0;
2067
8.30k
            }
2068
716k
          else
2069
716k
            {
2070
716k
              if (DBG_IOBUF)
2071
716k
                log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
2072
0
                           a->no, a->subno, (ulong)len);
2073
2074
716k
              tmplen = len;
2075
716k
              rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
2076
716k
                              &a->d.buf[a->d.len], &len);
2077
716k
              log_assert (len <= tmplen);
2078
716k
            }
2079
724k
        }
2080
724k
      a->d.len += len;
2081
2082
724k
      if (DBG_IOBUF)
2083
724k
  log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s),"
2084
0
                   " read %lu bytes%s\n",
2085
0
       a->no, a->subno,
2086
0
       rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
2087
0
       (ulong)(a->e_d.used ? a->e_d.used : len),
2088
0
       a->e_d.used ? " (to external buffer)" : "");
2089
      /* if ( a->no == 1 ) */
2090
      /*   log_hexdump ("     data:", a->d.buf, len); */
2091
2092
724k
      if (rc == -1) /* EOF.  */
2093
262k
  {
2094
262k
    size_t dummy_len = 0;
2095
2096
    /* Tell the filter to free itself */
2097
262k
    if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
2098
262k
             NULL, &dummy_len)))
2099
262k
      log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
2100
2101
    /* Free everything except for the internal buffer.  */
2102
262k
    if (a->filter_ov && a->filter_ov_owner)
2103
0
      xfree (a->filter_ov);
2104
262k
    a->filter_ov = NULL;
2105
262k
    a->filter = NULL;
2106
262k
    a->filter_eof = 1;
2107
2108
262k
    if (clear_pending_eof && a->d.len == 0 && a->e_d.used == 0
2109
262k
        && a->chain)
2110
224k
      {
2111
              /* We don't need to keep this filter around at all:
2112
               *
2113
         *  - we got an EOF
2114
         *  - we have no buffered data
2115
         *  - a filter follows this one.
2116
               *
2117
               * Unlink this filter.  */
2118
224k
        iobuf_t b = a->chain;
2119
224k
        if (DBG_IOBUF)
2120
224k
    log_debug ("iobuf-%d.%d: pop in underflow"
2121
0
                           " (nothing buffered, got EOF)\n", a->no, a->subno);
2122
224k
        xfree (a->d.buf);
2123
224k
        xfree (a->real_fname);
2124
224k
        memcpy (a, b, sizeof *a);
2125
224k
        xfree (b);
2126
2127
224k
        print_chain (a);
2128
224k
        return -1;
2129
224k
      }
2130
38.7k
    else if (a->d.len == 0 && a->e_d.used == 0)
2131
37.9k
            {
2132
              /* We can't unlink this filter (it is the only one in
2133
               * the pipeline), but we can immediately return EOF.  */
2134
37.9k
              return -1;
2135
37.9k
            }
2136
2137
262k
  }
2138
461k
      else if (rc) /* Record the error.  */
2139
6.83k
  {
2140
6.83k
    a->error = rc;
2141
2142
          /* If there is no buffered data, immediately return EOF.  */
2143
6.83k
    if (a->d.len == 0 && a->e_d.used == 0)
2144
3.30k
      return -1;
2145
6.83k
  }
2146
724k
    }
2147
2148
2.60G
  log_assert (a->d.start <= a->d.len);
2149
2.60G
  if (a->e_d.used > 0)
2150
5.90k
    return 0;
2151
2.60G
  if (a->d.start < a->d.len)
2152
430k
    return a->d.buf[a->d.start++];
2153
2154
2.60G
  return -1; /* EOF.  */
2155
2.60G
}
2156
2157
2158
static int
2159
filter_flush (iobuf_t a)
2160
14.0k
{
2161
14.0k
  int external_used = 0;
2162
14.0k
  byte *src_buf;
2163
14.0k
  size_t src_len;
2164
14.0k
  size_t len;
2165
14.0k
  int rc;
2166
2167
14.0k
  a->e_d.used = 0;
2168
2169
14.0k
  if (a->use == IOBUF_OUTPUT_TEMP)
2170
14.0k
    { /* Increase the temp buffer. */
2171
14.0k
      size_t newsize = a->d.size + iobuf_buffer_size;
2172
2173
14.0k
      if (DBG_IOBUF)
2174
14.0k
  log_debug ("increasing temp iobuf from %lu to %lu\n",
2175
0
       (ulong) a->d.size, (ulong) newsize);
2176
2177
14.0k
      a->d.buf = xrealloc (a->d.buf, newsize);
2178
14.0k
      a->d.size = newsize;
2179
14.0k
      return 0;
2180
14.0k
    }
2181
4
  else if (a->use != IOBUF_OUTPUT)
2182
4
    log_bug ("flush on non-output iobuf\n");
2183
4
  else if (!a->filter)
2184
4
    log_bug ("filter_flush: no filter\n");
2185
2186
4
  if (a->d.len == 0 && a->e_d.buf && a->e_d.len > 0)
2187
0
    {
2188
0
      src_buf = a->e_d.buf;
2189
0
      src_len = a->e_d.len;
2190
0
      external_used = 1;
2191
0
    }
2192
4
  else
2193
4
    {
2194
4
      src_buf = a->d.buf;
2195
4
      src_len = a->d.len;
2196
4
      external_used = 0;
2197
4
    }
2198
2199
4
  len = src_len;
2200
4
  rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, src_buf, &len);
2201
4
  if (!rc && len != src_len)
2202
0
    {
2203
0
      log_info ("filter_flush did not write all!\n");
2204
0
      rc = GPG_ERR_INTERNAL;
2205
0
    }
2206
4
  else if (rc)
2207
0
    a->error = rc;
2208
4
  a->d.len = 0;
2209
4
  if (external_used)
2210
0
    a->e_d.used = len;
2211
2212
4
  return rc;
2213
14.0k
}
2214
2215
2216
int
2217
iobuf_readbyte (iobuf_t a)
2218
2.60G
{
2219
2.60G
  int c;
2220
2221
2.60G
  if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
2222
0
    {
2223
0
      log_bug ("iobuf_readbyte called on a non-INPUT pipeline!\n");
2224
0
      return -1;
2225
0
    }
2226
2227
2.60G
  log_assert (a->d.start <= a->d.len);
2228
2229
2.60G
  if (a->nlimit && a->nbytes >= a->nlimit)
2230
0
    return -1;     /* forced EOF */
2231
2232
2.60G
  if (a->d.start < a->d.len)
2233
2.97M
    {
2234
2.97M
      c = a->d.buf[a->d.start++];
2235
2.97M
    }
2236
2.60G
  else if ((c = underflow (a, 1)) == -1)
2237
2.60G
    return -1;      /* EOF */
2238
2239
2.60G
  log_assert (a->d.start <= a->d.len);
2240
2241
  /* Note: if underflow doesn't return EOF, then it returns the first
2242
     byte that was read and advances a->d.start appropriately.  */
2243
2244
3.26M
  a->nbytes++;
2245
3.26M
  return c;
2246
3.26M
}
2247
2248
2249
int
2250
iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
2251
46.6M
{
2252
46.6M
  unsigned char *buf = (unsigned char *)buffer;
2253
46.6M
  int c, n;
2254
2255
46.6M
  if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
2256
0
    {
2257
0
      log_bug ("iobuf_read called on a non-INPUT pipeline!\n");
2258
0
      return -1;
2259
0
    }
2260
2261
46.6M
  if (a->nlimit)
2262
0
    {
2263
      /* Handle special cases. */
2264
0
      for (n = 0; n < buflen; n++)
2265
0
  {
2266
0
    if ((c = iobuf_readbyte (a)) == -1)
2267
0
      {
2268
0
        if (!n)
2269
0
    return -1; /* eof */
2270
0
        break;
2271
0
      }
2272
2273
0
    if (buf)
2274
0
      {
2275
0
        *buf = c;
2276
0
        buf++;
2277
0
      }
2278
0
  }
2279
0
      return n;
2280
0
    }
2281
2282
46.6M
  a->e_d.buf = NULL;
2283
46.6M
  a->e_d.len = 0;
2284
2285
  /* Hint for how full to fill iobuf internal drain buffer. */
2286
46.6M
  a->e_d.preferred = (a->use != IOBUF_INPUT_TEMP)
2287
879k
    && (buf && buflen >= IOBUF_ZEROCOPY_THRESHOLD_SIZE);
2288
2289
46.6M
  n = 0;
2290
46.6M
  do
2291
46.7M
    {
2292
46.7M
      if (n < buflen && a->d.start < a->d.len)
2293
  /* Drain the buffer.  */
2294
46.7M
  {
2295
46.7M
    unsigned size = a->d.len - a->d.start;
2296
46.7M
    if (size > buflen - n)
2297
46.5M
      size = buflen - n;
2298
46.7M
    if (buf)
2299
46.6M
      memcpy (buf, a->d.buf + a->d.start, size);
2300
46.7M
    n += size;
2301
46.7M
    a->d.start += size;
2302
46.7M
    if (buf)
2303
46.6M
      buf += size;
2304
46.7M
  }
2305
46.7M
      if (n < buflen)
2306
  /* Draining the internal buffer didn't fill BUFFER.  Call
2307
     underflow to read more data into the filter's internal
2308
     buffer.  */
2309
174k
  {
2310
174k
    if (a->use != IOBUF_INPUT_TEMP && buf && n < buflen)
2311
86.8k
      {
2312
        /* Setup external drain buffer for faster moving of data
2313
         * (avoid memcpy). */
2314
86.8k
        a->e_d.buf = buf;
2315
86.8k
        a->e_d.len = (buflen - n) / IOBUF_ZEROCOPY_THRESHOLD_SIZE
2316
86.8k
          * IOBUF_ZEROCOPY_THRESHOLD_SIZE;
2317
86.8k
        if (a->e_d.len == 0)
2318
77.7k
    a->e_d.buf = NULL;
2319
86.8k
        if (a->e_d.buf && DBG_IOBUF)
2320
86.8k
    log_debug ("iobuf-%d.%d: reading to external buffer, %lu bytes\n",
2321
0
         a->no, a->subno, (ulong)a->e_d.len);
2322
86.8k
      }
2323
2324
174k
    if ((c = underflow (a, 1)) == -1)
2325
      /* EOF.  If we managed to read something, don't return EOF
2326
         now.  */
2327
67.5k
      {
2328
67.5k
        a->e_d.buf = NULL;
2329
67.5k
        a->e_d.len = 0;
2330
67.5k
        a->nbytes += n;
2331
67.5k
        return n ? n : -1 /*EOF*/;
2332
67.5k
      }
2333
2334
107k
    if (a->e_d.buf && a->e_d.used > 0)
2335
5.90k
      {
2336
        /* Drain buffer was used, 'c' only contains return code
2337
         * 0 or -1. */
2338
5.90k
        n += a->e_d.used;
2339
5.90k
        buf += a->e_d.used;
2340
5.90k
      }
2341
101k
    else
2342
101k
      {
2343
101k
        if (buf)
2344
72.5k
    *buf++ = c;
2345
101k
        n++;
2346
101k
      }
2347
2348
107k
    a->e_d.buf = NULL;
2349
107k
    a->e_d.len = 0;
2350
107k
  }
2351
46.7M
    }
2352
46.7M
  while (n < buflen);
2353
46.6M
  a->nbytes += n;
2354
46.6M
  return n;
2355
46.6M
}
2356
2357
2358
2359
int
2360
iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
2361
37.3k
{
2362
37.3k
  int n = 0;
2363
2364
37.3k
  log_assert (buflen > 0);
2365
37.3k
  log_assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
2366
2367
37.3k
  if (buflen > a->d.size)
2368
    /* We can't peek more than we can buffer.  */
2369
0
    buflen = a->d.size;
2370
2371
  /* Try to fill the internal buffer with enough data to satisfy the
2372
     request.  */
2373
74.7k
  while (buflen > a->d.len - a->d.start)
2374
37.4k
    {
2375
37.4k
      if (underflow_target (a, 0, buflen) == -1)
2376
  /* EOF.  We can't read any more.  */
2377
80
  break;
2378
2379
      /* Underflow consumes the first character (it's the return
2380
   value).  unget() it by resetting the "file position".  */
2381
37.4k
      log_assert (a->d.start == 1);
2382
37.4k
      a->d.start = 0;
2383
37.4k
    }
2384
2385
37.3k
  n = a->d.len - a->d.start;
2386
37.3k
  if (n > buflen)
2387
36.5k
    n = buflen;
2388
2389
37.3k
  if (n == 0)
2390
    /* EOF.  */
2391
0
    return -1;
2392
2393
37.3k
  memcpy (buf, &a->d.buf[a->d.start], n);
2394
2395
37.3k
  return n;
2396
37.3k
}
2397
2398
2399
2400
2401
int
2402
iobuf_writebyte (iobuf_t a, unsigned int c)
2403
133M
{
2404
133M
  int rc;
2405
2406
133M
  if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2407
0
    {
2408
0
      log_bug ("iobuf_writebyte called on an input pipeline!\n");
2409
0
      return -1;
2410
0
    }
2411
2412
133M
  if (a->d.len == a->d.size)
2413
470
    if ((rc=filter_flush (a)))
2414
0
      return rc;
2415
2416
133M
  log_assert (a->d.len < a->d.size);
2417
133M
  a->d.buf[a->d.len++] = c;
2418
133M
  return 0;
2419
133M
}
2420
2421
2422
int
2423
iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
2424
63.1M
{
2425
63.1M
  const unsigned char *buf = (const unsigned char *)buffer;
2426
63.1M
  int rc;
2427
2428
63.1M
  if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2429
0
    {
2430
0
      log_bug ("iobuf_write called on an input pipeline!\n");
2431
0
      return -1;
2432
0
    }
2433
2434
63.1M
  a->e_d.buf = NULL;
2435
63.1M
  a->e_d.len = 0;
2436
2437
  /* Hint for how full to fill iobuf internal drain buffer. */
2438
63.1M
  a->e_d.preferred = (a->use != IOBUF_OUTPUT_TEMP)
2439
0
    && (buflen >= IOBUF_ZEROCOPY_THRESHOLD_SIZE);
2440
2441
63.1M
  do
2442
63.1M
    {
2443
63.1M
      if ((a->use != IOBUF_OUTPUT_TEMP)
2444
0
    && a->d.len == 0 && buflen >= IOBUF_ZEROCOPY_THRESHOLD_SIZE)
2445
0
  {
2446
    /* Setup external drain buffer for faster moving of data
2447
      * (avoid memcpy). */
2448
0
    a->e_d.buf = (byte *)buf;
2449
0
    a->e_d.len = buflen / IOBUF_ZEROCOPY_THRESHOLD_SIZE
2450
0
      * IOBUF_ZEROCOPY_THRESHOLD_SIZE;
2451
0
    if (a->e_d.len == 0)
2452
0
      a->e_d.buf = NULL;
2453
0
    if (a->e_d.buf && DBG_IOBUF)
2454
0
      log_debug ("iobuf-%d.%d: writing from external buffer, %lu bytes\n",
2455
0
      a->no, a->subno, (ulong)a->e_d.len);
2456
0
  }
2457
2458
63.1M
      if (a->e_d.buf == NULL && buflen && a->d.len < a->d.size)
2459
63.1M
  {
2460
63.1M
    unsigned size;
2461
2462
63.1M
    if (a->e_d.preferred && a->d.len < IOBUF_ZEROCOPY_THRESHOLD_SIZE)
2463
0
      size = IOBUF_ZEROCOPY_THRESHOLD_SIZE - a->d.len;
2464
63.1M
    else
2465
63.1M
      size = a->d.size - a->d.len;
2466
2467
63.1M
    if (size > buflen)
2468
63.1M
      size = buflen;
2469
63.1M
    memcpy (a->d.buf + a->d.len, buf, size);
2470
63.1M
    buflen -= size;
2471
63.1M
    buf += size;
2472
63.1M
    a->d.len += size;
2473
63.1M
  }
2474
2475
63.1M
      if (buflen)
2476
13.5k
  {
2477
13.5k
    rc = filter_flush (a);
2478
13.5k
          if (rc)
2479
0
      {
2480
0
        a->e_d.buf = NULL;
2481
0
        a->e_d.len = 0;
2482
0
        return rc;
2483
0
      }
2484
13.5k
  }
2485
2486
63.1M
      if (a->e_d.buf && a->e_d.used > 0)
2487
0
  {
2488
0
    buf += a->e_d.used;
2489
0
    buflen -= a->e_d.used;
2490
0
  }
2491
2492
63.1M
      a->e_d.buf = NULL;
2493
63.1M
      a->e_d.len = 0;
2494
63.1M
    }
2495
63.1M
  while (buflen);
2496
63.1M
  return 0;
2497
63.1M
}
2498
2499
2500
int
2501
iobuf_writestr (iobuf_t a, const char *buf)
2502
0
{
2503
0
  if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2504
0
    {
2505
0
      log_bug ("iobuf_writestr called on an input pipeline!\n");
2506
0
      return -1;
2507
0
    }
2508
2509
0
  return iobuf_write (a, buf, strlen (buf));
2510
0
}
2511
2512
2513
2514
int
2515
iobuf_write_temp (iobuf_t dest, iobuf_t source)
2516
8.12M
{
2517
8.12M
  log_assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2518
8.12M
  log_assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
2519
2520
8.12M
  iobuf_flush_temp (source);
2521
8.12M
  return iobuf_write (dest, source->d.buf, source->d.len);
2522
8.12M
}
2523
2524
size_t
2525
iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
2526
0
{
2527
0
  byte desc[MAX_IOBUF_DESC];
2528
0
  size_t n;
2529
2530
0
  while (1)
2531
0
    {
2532
0
      int rc = filter_flush (a);
2533
0
      if (rc)
2534
0
  log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed.  Ignoring.\n",
2535
0
     a->no, a->subno, iobuf_desc (a, desc));
2536
0
      if (! a->chain)
2537
0
  break;
2538
0
      a = a->chain;
2539
0
    }
2540
2541
0
  n = a->d.len;
2542
0
  if (n > buflen)
2543
0
    n = buflen;
2544
0
  memcpy (buffer, a->d.buf, n);
2545
0
  return n;
2546
0
}
2547
2548
/* Copies the data from the input iobuf SOURCE to the output iobuf
2549
   DEST until either an error is encountered or EOF is reached.
2550
   Returns the number of bytes copies or (size_t)(-1) on error.  */
2551
size_t
2552
iobuf_copy (iobuf_t dest, iobuf_t source)
2553
0
{
2554
0
  char *temp;
2555
0
  size_t temp_size;
2556
0
  size_t nread;
2557
0
  size_t nwrote = 0;
2558
0
  size_t max_read = 0;
2559
0
  int err;
2560
2561
0
  log_assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP);
2562
0
  log_assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2563
2564
0
  if (iobuf_error (dest))
2565
0
    return (size_t)(-1);
2566
2567
  /* Use iobuf buffer size for temporary buffer. */
2568
0
  temp_size = iobuf_set_buffer_size(0) * 1024;
2569
2570
0
  temp = xmalloc (temp_size);
2571
0
  while (1)
2572
0
    {
2573
0
      nread = iobuf_read (source, temp, temp_size);
2574
0
      if (nread == -1)
2575
        /* EOF.  */
2576
0
        break;
2577
2578
0
      if (nread > max_read)
2579
0
        max_read = nread;
2580
2581
0
      err = iobuf_write (dest, temp, nread);
2582
0
      if (err)
2583
0
        break;
2584
0
      nwrote += nread;
2585
0
    }
2586
2587
  /* Burn the buffer.  */
2588
0
  if (max_read)
2589
0
    wipememory (temp, max_read);
2590
0
  xfree (temp);
2591
2592
0
  return nwrote;
2593
0
}
2594
2595
2596
void
2597
iobuf_flush_temp (iobuf_t temp)
2598
8.12M
{
2599
8.12M
  if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP)
2600
8.12M
    log_bug ("iobuf_flush_temp called on an input pipeline!\n");
2601
8.12M
  while (temp->chain)
2602
0
    iobuf_pop_filter (temp, temp->filter, NULL);
2603
8.12M
}
2604
2605
2606
void
2607
iobuf_set_limit (iobuf_t a, off_t nlimit)
2608
0
{
2609
0
  if (nlimit)
2610
0
    a->nofast = 1;
2611
0
  else
2612
0
    a->nofast = 0;
2613
0
  a->nlimit = nlimit;
2614
0
  a->ntotal += a->nbytes;
2615
0
  a->nbytes = 0;
2616
0
}
2617
2618
2619
/* Return the length of the file behind A.  If there is no file, return 0. */
2620
uint64_t
2621
iobuf_get_filelength (iobuf_t a)
2622
0
{
2623
  /* Hmmm: file_filter may have already been removed */
2624
0
  for ( ; a->chain; a = a->chain )
2625
0
    ;
2626
2627
0
  if (a->filter != file_filter)
2628
0
    return 0;
2629
2630
0
  {
2631
0
    file_filter_ctx_t *b = a->filter_ov;
2632
0
    gnupg_fd_t fp = b->fp;
2633
2634
#if defined(HAVE_W32_SYSTEM)
2635
    LARGE_INTEGER exsize;
2636
2637
    if (GetFileSizeEx (fp, &exsize))
2638
      return exsize.QuadPart;
2639
    log_error ("GetFileSize for handle %p failed: %s\n",
2640
         fp, w32_strerror (-1));
2641
#else /*!HAVE_W32_SYSTEM*/
2642
0
    struct stat st;
2643
2644
0
    if ( !fstat (fp, &st) )
2645
0
      return st.st_size;
2646
0
    log_error("fstat() failed: %s\n", strerror(errno) );
2647
0
#endif /*!HAVE_W32_SYSTEM*/
2648
0
  }
2649
2650
0
  return 0;
2651
0
}
2652
2653
2654
gnupg_fd_t
2655
iobuf_get_fd (iobuf_t a)
2656
37.1k
{
2657
37.1k
  for (; a->chain; a = a->chain)
2658
0
    ;
2659
2660
37.1k
  if (a->filter != file_filter)
2661
0
    return GNUPG_INVALID_FD;
2662
2663
37.1k
  {
2664
37.1k
    file_filter_ctx_t *b = a->filter_ov;
2665
37.1k
    gnupg_fd_t fp = b->fp;
2666
2667
37.1k
    return fp;
2668
37.1k
  }
2669
37.1k
}
2670
2671
2672
off_t
2673
iobuf_tell (iobuf_t a)
2674
0
{
2675
0
  return a->ntotal + a->nbytes;
2676
0
}
2677
2678
2679
#if !defined(HAVE_FSEEKO) && !defined(fseeko)
2680
2681
#ifdef HAVE_LIMITS_H
2682
# include <limits.h>
2683
#endif
2684
#ifndef LONG_MAX
2685
# define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2686
#endif
2687
#ifndef LONG_MIN
2688
# define LONG_MIN (-1 - LONG_MAX)
2689
#endif
2690
2691
/****************
2692
 * A substitute for fseeko, for hosts that don't have it.
2693
 */
2694
static int
2695
fseeko (FILE * stream, off_t newpos, int whence)
2696
{
2697
  while (newpos != (long) newpos)
2698
    {
2699
      long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2700
      if (fseek (stream, pos, whence) != 0)
2701
  return -1;
2702
      newpos -= pos;
2703
      whence = SEEK_CUR;
2704
    }
2705
  return fseek (stream, (long) newpos, whence);
2706
}
2707
#endif
2708
2709
int
2710
iobuf_seek (iobuf_t a, off_t newpos)
2711
0
{
2712
0
  file_filter_ctx_t *b = NULL;
2713
2714
0
  if (a->use == IOBUF_OUTPUT || a->use == IOBUF_INPUT)
2715
0
    {
2716
      /* Find the last filter in the pipeline.  */
2717
0
      for (; a->chain; a = a->chain)
2718
0
  ;
2719
2720
0
      if (a->filter != file_filter)
2721
0
  return -1;
2722
2723
0
      b = a->filter_ov;
2724
2725
#ifdef HAVE_W32_SYSTEM
2726
      if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2727
  {
2728
    log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2729
         b->fp, (int) GetLastError ());
2730
    return -1;
2731
  }
2732
#else
2733
0
      if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2734
0
  {
2735
0
    log_error ("can't lseek: %s\n", strerror (errno));
2736
0
    return -1;
2737
0
  }
2738
0
#endif
2739
      /* Discard the buffer it is not a temp stream.  */
2740
0
      a->d.len = 0;
2741
0
    }
2742
0
  a->d.start = 0;
2743
0
  a->nbytes = 0;
2744
0
  a->nlimit = 0;
2745
0
  a->nofast = 0;
2746
0
  a->ntotal = newpos;
2747
0
  a->error = 0;
2748
2749
  /* It is impossible for A->CHAIN to be non-NULL.  If A is an INPUT
2750
     or OUTPUT buffer, then we find the last filter, which is defined
2751
     as A->CHAIN being NULL.  If A is a TEMP filter, then A must be
2752
     the only filter in the pipe: when iobuf_push_filter adds a filter
2753
     to the front of a pipeline, it sets the new filter to be an
2754
     OUTPUT filter if the pipeline is an OUTPUT or TEMP pipeline and
2755
     to be an INPUT filter if the pipeline is an INPUT pipeline.
2756
     Thus, only the last filter in a TEMP pipeline can be a */
2757
2758
  /* remove filters, but the last */
2759
0
  if (a->chain)
2760
0
    log_debug ("iobuf_pop_filter called in iobuf_seek - please report\n");
2761
0
  while (a->chain)
2762
0
    iobuf_pop_filter (a, a->filter, NULL);
2763
2764
0
  return 0;
2765
0
}
2766
2767
2768
const char *
2769
iobuf_get_real_fname (iobuf_t a)
2770
677
{
2771
677
  if (a->real_fname)
2772
677
    return a->real_fname;
2773
2774
  /* the old solution */
2775
0
  for (; a; a = a->chain)
2776
0
    if (!a->chain && a->filter == file_filter)
2777
0
      {
2778
0
  file_filter_ctx_t *b = a->filter_ov;
2779
0
  return b->print_only_name ? NULL : b->fname;
2780
0
      }
2781
2782
0
  return NULL;
2783
0
}
2784
2785
const char *
2786
iobuf_get_fname (iobuf_t a)
2787
0
{
2788
0
  for (; a; a = a->chain)
2789
0
    if (!a->chain && a->filter == file_filter)
2790
0
      {
2791
0
  file_filter_ctx_t *b = a->filter_ov;
2792
0
  return b->fname;
2793
0
      }
2794
0
  return NULL;
2795
0
}
2796
2797
const char *
2798
iobuf_get_fname_nonnull (iobuf_t a)
2799
0
{
2800
0
  const char *fname;
2801
2802
0
  fname = iobuf_get_fname (a);
2803
0
  return fname? fname : "[?]";
2804
0
}
2805
2806
2807
/****************
2808
 * Enable or disable partial body length mode (RFC 4880 4.2.2.4).
2809
 *
2810
 * If LEN is 0, this disables partial block mode by popping the
2811
 * partial body length filter, which must be the most recently
2812
 * added filter.
2813
 *
2814
 * If LEN is non-zero, it pushes a partial body length filter.  If
2815
 * this is a read filter, LEN must be the length byte from the first
2816
 * chunk and A should be position just after this first partial body
2817
 * length header.
2818
 */
2819
void
2820
iobuf_set_partial_body_length_mode (iobuf_t a, size_t len)
2821
219k
{
2822
219k
  if (!len)
2823
    /* Disable partial body length mode.  */
2824
0
    {
2825
0
      if (a->use == IOBUF_INPUT)
2826
0
  log_debug ("iobuf_pop_filter called in set_partial_block_mode"
2827
0
       " - please report\n");
2828
2829
0
      log_assert (a->filter == block_filter);
2830
0
      iobuf_pop_filter (a, block_filter, NULL);
2831
0
    }
2832
219k
  else
2833
    /* Enabled partial body length mode.  */
2834
219k
    {
2835
219k
      block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2836
219k
      ctx->use = a->use;
2837
219k
      ctx->partial = 1;
2838
219k
      ctx->size = 0;
2839
219k
      ctx->first_c = len;
2840
219k
      iobuf_push_filter (a, block_filter, ctx);
2841
219k
    }
2842
219k
}
2843
2844
2845
2846
unsigned int
2847
iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2848
     unsigned *length_of_buffer, unsigned *max_length)
2849
4.91M
{
2850
4.91M
  int c;
2851
4.91M
  char *buffer = (char *)*addr_of_buffer;
2852
4.91M
  unsigned length = *length_of_buffer;
2853
4.91M
  unsigned nbytes = 0;
2854
4.91M
  unsigned maxlen = *max_length;
2855
4.91M
  char *p;
2856
2857
  /* The code assumes that we have space for at least a newline and a
2858
     NUL character in the buffer.  This requires at least 2 bytes.  We
2859
     don't complicate the code by handling the stupid corner case, but
2860
     simply assert that it can't happen.  */
2861
4.91M
  log_assert (!buffer || length >= 2 || maxlen >= 2);
2862
2863
4.91M
  if (!buffer || length <= 1)
2864
    /* must allocate a new buffer */
2865
16.4k
    {
2866
16.4k
      length = 256 <= maxlen ? 256 : maxlen;
2867
16.4k
      buffer = xrealloc (buffer, length);
2868
16.4k
      *addr_of_buffer = (unsigned char *)buffer;
2869
16.4k
      *length_of_buffer = length;
2870
16.4k
    }
2871
2872
4.91M
  p = buffer;
2873
4.94M
  while (1)
2874
4.94M
    {
2875
4.94M
      if (!a->nofast && a->d.start < a->d.len && nbytes < length - 1)
2876
  /* Fast path for finding '\n' by using standard C library's optimized
2877
     memchr.  */
2878
4.91M
  {
2879
4.91M
    unsigned size = a->d.len - a->d.start;
2880
4.91M
    byte *newline_pos;
2881
2882
4.91M
    if (size > length - 1 - nbytes)
2883
4.76M
      size = length - 1 - nbytes;
2884
2885
4.91M
    newline_pos = memchr (a->d.buf + a->d.start, '\n', size);
2886
4.91M
    if (newline_pos)
2887
4.88M
      {
2888
        /* Found newline, copy buffer and return. */
2889
4.88M
        size = (newline_pos - (a->d.buf + a->d.start)) + 1;
2890
4.88M
        memcpy (p, a->d.buf + a->d.start, size);
2891
4.88M
        p += size;
2892
4.88M
        nbytes += size;
2893
4.88M
        a->d.start += size;
2894
4.88M
        a->nbytes += size;
2895
4.88M
        break;
2896
4.88M
      }
2897
25.7k
    else
2898
25.7k
      {
2899
        /* No newline, copy buffer and continue. */
2900
25.7k
        memcpy (p, a->d.buf + a->d.start, size);
2901
25.7k
        p += size;
2902
25.7k
        nbytes += size;
2903
25.7k
        a->d.start += size;
2904
25.7k
        a->nbytes += size;
2905
25.7k
      }
2906
4.91M
  }
2907
32.0k
      else
2908
32.0k
  {
2909
32.0k
    c = iobuf_readbyte (a);
2910
32.0k
    if (c == -1)
2911
24.3k
      break;
2912
7.77k
    *p++ = c;
2913
7.77k
    nbytes++;
2914
7.77k
    if (c == '\n')
2915
119
      break;
2916
7.77k
  }
2917
2918
33.3k
      if (nbytes == length - 1)
2919
  /* We don't have enough space to add a \n and a \0.  Increase
2920
     the buffer size.  */
2921
13.6k
  {
2922
13.6k
    if (length == maxlen)
2923
      /* We reached the buffer's size limit!  */
2924
214
      {
2925
        /* Skip the rest of the line.  */
2926
8.01M
        while ((c = iobuf_get (a)) != -1 && c != '\n')
2927
8.01M
    ;
2928
2929
        /* p is pointing at the last byte in the buffer.  We
2930
     always terminate the line with "\n\0" so overwrite
2931
     the previous byte with a \n.  */
2932
214
        log_assert (p > buffer);
2933
214
        p[-1] = '\n';
2934
2935
        /* Indicate truncation.  */
2936
214
        *max_length = 0;
2937
214
        break;
2938
214
      }
2939
2940
13.3k
    length += length < 1024 ? 256 : 1024;
2941
13.3k
    if (length > maxlen)
2942
173
      length = maxlen;
2943
2944
13.3k
    buffer = xrealloc (buffer, length);
2945
13.3k
    *addr_of_buffer = (unsigned char *)buffer;
2946
13.3k
    *length_of_buffer = length;
2947
13.3k
    p = buffer + nbytes;
2948
13.3k
  }
2949
33.3k
    }
2950
  /* Add the terminating NUL.  */
2951
4.91M
  *p = 0;
2952
2953
  /* Return the number of characters written to the buffer including
2954
     the newline, but not including the terminating NUL.  */
2955
4.91M
  return nbytes;
2956
4.91M
}
2957
2958
2959
void
2960
iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2961
48.8M
{
2962
48.8M
  if ( partial )
2963
0
    {
2964
0
      for (;;)
2965
0
        {
2966
0
          if (a->nofast || a->d.start >= a->d.len)
2967
0
            {
2968
0
              if (iobuf_readbyte (a) == -1)
2969
0
                {
2970
0
                  break;
2971
0
                }
2972
0
      }
2973
0
          else
2974
0
            {
2975
0
              unsigned long count = a->d.len - a->d.start;
2976
0
              a->nbytes += count;
2977
0
              a->d.start = a->d.len;
2978
0
      }
2979
0
  }
2980
0
    }
2981
48.8M
  else
2982
48.8M
    {
2983
48.8M
      unsigned long remaining = n;
2984
49.1M
      while (remaining > 0)
2985
386k
        {
2986
386k
          if (a->nofast || a->d.start >= a->d.len)
2987
83.2k
            {
2988
83.2k
              if (iobuf_readbyte (a) == -1)
2989
66.4k
                {
2990
66.4k
                  break;
2991
66.4k
    }
2992
16.8k
              --remaining;
2993
16.8k
      }
2994
302k
          else
2995
302k
            {
2996
302k
              unsigned long count = a->d.len - a->d.start;
2997
302k
              if (count > remaining)
2998
242k
                {
2999
242k
                  count = remaining;
3000
242k
    }
3001
302k
              a->nbytes += count;
3002
302k
              a->d.start += count;
3003
302k
              remaining -= count;
3004
302k
      }
3005
386k
  }
3006
48.8M
    }
3007
48.8M
}
3008
3009
3010
/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed
3011
 * packet.  LEN should be at least 6.  */
3012
static int
3013
is_openpgp_compressed_packet (const unsigned char *buf, size_t len)
3014
0
{
3015
0
  int c, ctb, pkttype;
3016
0
  int lenbytes;
3017
3018
0
  ctb = *buf++; len--;
3019
0
  if (!(ctb & 0x80))
3020
0
    return 0; /* Invalid packet.  */
3021
3022
0
  if ((ctb & 0x40)) /* New style (OpenPGP) CTB.  */
3023
0
    {
3024
0
      pkttype = (ctb & 0x3f);
3025
0
      if (!len)
3026
0
        return 0; /* Expected first length octet missing.  */
3027
0
      c = *buf++; len--;
3028
0
      if (c < 192)
3029
0
        ;
3030
0
      else if (c < 224)
3031
0
        {
3032
0
          if (!len)
3033
0
            return 0; /* Expected second length octet missing. */
3034
0
        }
3035
0
      else if (c == 255)
3036
0
        {
3037
0
          if (len < 4)
3038
0
            return 0; /* Expected length octets missing */
3039
0
        }
3040
0
    }
3041
0
  else /* Old style CTB.  */
3042
0
    {
3043
0
      pkttype = (ctb>>2)&0xf;
3044
0
      lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
3045
0
      if (len < lenbytes)
3046
0
        return 0; /* Not enough length bytes.  */
3047
0
    }
3048
3049
0
  return (pkttype == 8);
3050
0
}
3051
3052
3053
/*
3054
 * Check if the file is compressed, by peeking the iobuf.  You need to
3055
 * pass the iobuf with INP.  Returns true if the buffer seems to be
3056
 * compressed.
3057
 */
3058
int
3059
is_file_compressed (iobuf_t inp)
3060
0
{
3061
0
  int i;
3062
0
  char buf[32];
3063
0
  int buflen;
3064
3065
0
  struct magic_compress_s
3066
0
  {
3067
0
    byte len;
3068
0
    byte extchk;
3069
0
    byte magic[6];
3070
0
  } magic[] =
3071
0
      {
3072
0
       { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */
3073
0
       { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */
3074
0
       { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */
3075
0
       { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */
3076
0
       { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */
3077
0
       { 5, 2, { 0x89, 'P','N','G', 0x0d} }, /* Likely PNG */
3078
0
       { 6, 0, { '7', 'z', 0xbc, 0xaf, 0x27, 0x1c} } /* 7z */
3079
0
  };
3080
3081
0
  if (!inp)
3082
0
    return 0;
3083
3084
0
  for ( ; inp->chain; inp = inp->chain )
3085
0
    ;
3086
3087
0
  buflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof buf, buf);
3088
0
  if (buflen < 0)
3089
0
    {
3090
0
      buflen = 0;
3091
0
      log_debug ("peeking at input failed\n");
3092
0
    }
3093
3094
0
  if ( buflen < 6 )
3095
0
    {
3096
0
      return 0;  /* Too short to check - assume uncompressed.  */
3097
0
    }
3098
3099
0
  for ( i = 0; i < DIM (magic); i++ )
3100
0
    {
3101
0
      if (!memcmp( buf, magic[i].magic, magic[i].len))
3102
0
        {
3103
0
          switch (magic[i].extchk)
3104
0
            {
3105
0
            case 0:
3106
0
              return 1; /* Is compressed.  */
3107
0
            case 1:
3108
0
              if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5))
3109
0
                return 1; /* JFIF: this likely a compressed JPEG.  */
3110
0
              break;
3111
0
            case 2:
3112
0
              if (buflen > 8
3113
0
                  && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a)
3114
0
                return 1; /* This is a PNG.  */
3115
0
              break;
3116
0
            default:
3117
0
              break;
3118
0
            }
3119
0
        }
3120
0
    }
3121
3122
0
  if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen))
3123
0
    {
3124
0
      return 1; /* Already compressed.  */
3125
0
    }
3126
3127
0
  return 0;  /* Not detected as compressed.  */
3128
0
}