Line data Source code
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 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 <http://www.gnu.org/licenses/>.
30 : */
31 :
32 : #include <config.h>
33 : #include <stdio.h>
34 : #include <stdlib.h>
35 : #include <string.h>
36 : #include <errno.h>
37 : #include <ctype.h>
38 : #include <assert.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 size of the internal buffers.
63 : NOTE: If you change this value you MUST also adjust the regression
64 : test "armored_key_8192" in armor.test! */
65 : #define IOBUF_BUFFER_SIZE 8192
66 :
67 : /* To avoid a potential DoS with compression packets we better limit
68 : the number of filters in a chain. */
69 : #define MAX_NESTING_FILTER 64
70 :
71 : /*-- End configurable part. --*/
72 :
73 :
74 : #ifdef HAVE_W32_SYSTEM
75 : # ifdef HAVE_W32CE_SYSTEM
76 : # define FD_FOR_STDIN (es_fileno (es_stdin))
77 : # define FD_FOR_STDOUT (es_fileno (es_stdout))
78 : # else
79 : # define FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
80 : # define FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
81 : # endif
82 : #else /*!HAVE_W32_SYSTEM*/
83 : # define FD_FOR_STDIN (0)
84 : # define FD_FOR_STDOUT (1)
85 : #endif /*!HAVE_W32_SYSTEM*/
86 :
87 :
88 : /* The context used by the file filter. */
89 : typedef struct
90 : {
91 : gnupg_fd_t fp; /* Open file pointer or handle. */
92 : int keep_open;
93 : int no_cache;
94 : int eof_seen;
95 : int print_only_name; /* Flags indicating that fname is not a real file. */
96 : char fname[1]; /* Name of the file. */
97 : } file_filter_ctx_t;
98 :
99 : /* The context used by the estream filter. */
100 : typedef struct
101 : {
102 : estream_t fp; /* Open estream handle. */
103 : int keep_open;
104 : int no_cache;
105 : int eof_seen;
106 : int print_only_name; /* Flags indicating that fname is not a real file. */
107 : char fname[1]; /* Name of the file. */
108 : } file_es_filter_ctx_t;
109 :
110 :
111 : /* Object to control the "close cache". */
112 : struct close_cache_s
113 : {
114 : struct close_cache_s *next;
115 : gnupg_fd_t fp;
116 : char fname[1];
117 : };
118 : typedef struct close_cache_s *close_cache_t;
119 : static close_cache_t close_cache;
120 :
121 :
122 :
123 : #ifdef HAVE_W32_SYSTEM
124 : typedef struct
125 : {
126 : int sock;
127 : int keep_open;
128 : int no_cache;
129 : int eof_seen;
130 : int print_only_name; /* Flag indicating that fname is not a real file. */
131 : char fname[1]; /* Name of the file */
132 :
133 : } sock_filter_ctx_t;
134 : #endif /*HAVE_W32_SYSTEM*/
135 :
136 : /* The first partial length header block must be of size 512 to make
137 : * it easier (and more efficient) we use a min. block size of 512 for
138 : * all chunks (but the last one) */
139 : #define OP_MIN_PARTIAL_CHUNK 512
140 : #define OP_MIN_PARTIAL_CHUNK_2POW 9
141 :
142 : /* The context we use for the block filter (used to handle OpenPGP
143 : length information header). */
144 : typedef struct
145 : {
146 : int use;
147 : size_t size;
148 : size_t count;
149 : int partial; /* 1 = partial header, 2 in last partial packet. */
150 : char *buffer; /* Used for partial header. */
151 : size_t buflen; /* Used size of buffer. */
152 : int first_c; /* First character of a partial header (which is > 0). */
153 : int eof;
154 : }
155 : block_filter_ctx_t;
156 :
157 :
158 : /* Global flag to tell whether special file names are enabled. See
159 : gpg.c for an explanation of these file names. FIXME: This does not
160 : belong in the iobuf subsystem. */
161 : static int special_names_enabled;
162 :
163 : /* Local prototypes. */
164 : static int underflow (iobuf_t a, int clear_pending_eof);
165 : static int translate_file_handle (int fd, int for_write);
166 :
167 : /* Sends any pending data to the filter's FILTER function. Note: this
168 : works on the filter and not on the whole pipeline. That is,
169 : iobuf_flush doesn't necessarily cause data to be written to any
170 : underlying file; it just causes any data buffered at the filter A
171 : to be sent to A's filter function.
172 :
173 : If A is a IOBUF_OUTPUT_TEMP filter, then this also enlarges the
174 : buffer by IOBUF_BUFFER_SIZE.
175 :
176 : May only be called on an IOBUF_OUTPUT or IOBUF_OUTPUT_TEMP filters. */
177 : static int filter_flush (iobuf_t a);
178 :
179 :
180 :
181 : /* This is a replacement for strcmp. Under W32 it does not
182 : distinguish between backslash and slash. */
183 : static int
184 268 : fd_cache_strcmp (const char *a, const char *b)
185 : {
186 : #ifdef HAVE_DOSISH_SYSTEM
187 : for (; *a && *b; a++, b++)
188 : {
189 : if (*a != *b && !((*a == '/' && *b == '\\')
190 : || (*a == '\\' && *b == '/')) )
191 : break;
192 : }
193 : return *(const unsigned char *)a - *(const unsigned char *)b;
194 : #else
195 268 : return strcmp (a, b);
196 : #endif
197 : }
198 :
199 : /*
200 : * Invalidate (i.e. close) a cached iobuf
201 : */
202 : static int
203 546 : fd_cache_invalidate (const char *fname)
204 : {
205 : close_cache_t cc;
206 546 : int rc = 0;
207 :
208 546 : assert (fname);
209 546 : if (DBG_IOBUF)
210 0 : log_debug ("fd_cache_invalidate (%s)\n", fname);
211 :
212 772 : for (cc = close_cache; cc; cc = cc->next)
213 : {
214 226 : if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
215 : {
216 20 : if (DBG_IOBUF)
217 0 : log_debug (" did (%s)\n", cc->fname);
218 : #ifdef HAVE_W32_SYSTEM
219 : if (!CloseHandle (cc->fp))
220 : rc = -1;
221 : #else
222 20 : rc = close (cc->fp);
223 : #endif
224 20 : cc->fp = GNUPG_INVALID_FD;
225 : }
226 : }
227 546 : return rc;
228 : }
229 :
230 :
231 : /* Try to sync changes to the disk. This is to avoid data loss during
232 : a system crash in write/close/rename cycle on some file
233 : systems. */
234 : static int
235 0 : fd_cache_synchronize (const char *fname)
236 : {
237 0 : int err = 0;
238 :
239 : #ifdef HAVE_FSYNC
240 : close_cache_t cc;
241 :
242 0 : if (DBG_IOBUF)
243 0 : log_debug ("fd_cache_synchronize (%s)\n", fname);
244 :
245 0 : for (cc=close_cache; cc; cc = cc->next )
246 : {
247 0 : if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
248 : {
249 0 : if (DBG_IOBUF)
250 0 : log_debug (" did (%s)\n", cc->fname);
251 :
252 0 : err = fsync (cc->fp);
253 : }
254 : }
255 : #else
256 : (void)fname;
257 : #endif /*HAVE_FSYNC*/
258 :
259 0 : return err;
260 : }
261 :
262 :
263 : static gnupg_fd_t
264 2003 : direct_open (const char *fname, const char *mode, int mode700)
265 : {
266 : #ifdef HAVE_W32_SYSTEM
267 : unsigned long da, cd, sm;
268 : HANDLE hfile;
269 :
270 : /* Note, that we do not handle all mode combinations */
271 :
272 : /* According to the ReactOS source it seems that open() of the
273 : * standard MSW32 crt does open the file in shared mode which is
274 : * something new for MS applications ;-)
275 : */
276 : if (strchr (mode, '+'))
277 : {
278 : if (fd_cache_invalidate (fname))
279 : return GNUPG_INVALID_FD;
280 : da = GENERIC_READ | GENERIC_WRITE;
281 : cd = OPEN_EXISTING;
282 : sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
283 : }
284 : else if (strchr (mode, 'w'))
285 : {
286 : if (fd_cache_invalidate (fname))
287 : return GNUPG_INVALID_FD;
288 : da = GENERIC_WRITE;
289 : cd = CREATE_ALWAYS;
290 : sm = FILE_SHARE_WRITE;
291 : }
292 : else
293 : {
294 : da = GENERIC_READ;
295 : cd = OPEN_EXISTING;
296 : sm = FILE_SHARE_READ;
297 : }
298 :
299 : #ifdef HAVE_W32CE_SYSTEM
300 : {
301 : wchar_t *wfname = utf8_to_wchar (fname);
302 : if (wfname)
303 : {
304 : hfile = CreateFile (wfname, da, sm, NULL, cd,
305 : FILE_ATTRIBUTE_NORMAL, NULL);
306 : xfree (wfname);
307 : }
308 : else
309 : hfile = INVALID_HANDLE_VALUE;
310 : }
311 : #else
312 : hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
313 : #endif
314 : return hfile;
315 :
316 : #else /*!HAVE_W32_SYSTEM*/
317 :
318 : int oflag;
319 2003 : int cflag = S_IRUSR | S_IWUSR;
320 :
321 2003 : if (!mode700)
322 2001 : cflag |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
323 :
324 : /* Note, that we do not handle all mode combinations */
325 2003 : if (strchr (mode, '+'))
326 : {
327 0 : if (fd_cache_invalidate (fname))
328 0 : return GNUPG_INVALID_FD;
329 0 : oflag = O_RDWR;
330 : }
331 2003 : else if (strchr (mode, 'w'))
332 : {
333 525 : if (fd_cache_invalidate (fname))
334 0 : return GNUPG_INVALID_FD;
335 525 : oflag = O_WRONLY | O_CREAT | O_TRUNC;
336 : }
337 : else
338 : {
339 1478 : oflag = O_RDONLY;
340 : }
341 : #ifdef O_BINARY
342 : if (strchr (mode, 'b'))
343 : oflag |= O_BINARY;
344 : #endif
345 :
346 : #ifdef __riscos__
347 : {
348 : struct stat buf;
349 :
350 : /* Don't allow iobufs on directories */
351 : if (!stat (fname, &buf) && S_ISDIR (buf.st_mode) && !S_ISREG (buf.st_mode))
352 : return __set_errno (EISDIR);
353 : }
354 : #endif
355 2003 : return open (fname, oflag, cflag);
356 :
357 : #endif /*!HAVE_W32_SYSTEM*/
358 : }
359 :
360 :
361 : /*
362 : * Instead of closing an FD we keep it open and cache it for later reuse
363 : * Note that this caching strategy only works if the process does not chdir.
364 : */
365 : static void
366 2003 : fd_cache_close (const char *fname, gnupg_fd_t fp)
367 : {
368 : close_cache_t cc;
369 :
370 2003 : assert (fp);
371 2003 : if (!fname || !*fname)
372 : {
373 : #ifdef HAVE_W32_SYSTEM
374 : CloseHandle (fp);
375 : #else
376 931 : close (fp);
377 : #endif
378 931 : if (DBG_IOBUF)
379 0 : log_debug ("fd_cache_close (%d) real\n", (int)fp);
380 931 : return;
381 : }
382 : /* try to reuse a slot */
383 1117 : for (cc = close_cache; cc; cc = cc->next)
384 : {
385 45 : if (cc->fp == GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
386 : {
387 0 : cc->fp = fp;
388 0 : if (DBG_IOBUF)
389 0 : log_debug ("fd_cache_close (%s) used existing slot\n", fname);
390 0 : return;
391 : }
392 : }
393 : /* add a new one */
394 1072 : if (DBG_IOBUF)
395 0 : log_debug ("fd_cache_close (%s) new slot created\n", fname);
396 1072 : cc = xcalloc (1, sizeof *cc + strlen (fname));
397 1072 : strcpy (cc->fname, fname);
398 1072 : cc->fp = fp;
399 1072 : cc->next = close_cache;
400 1072 : close_cache = cc;
401 : }
402 :
403 : /*
404 : * Do a direct_open on FNAME but first try to reuse one from the fd_cache
405 : */
406 : static gnupg_fd_t
407 1478 : fd_cache_open (const char *fname, const char *mode)
408 : {
409 : close_cache_t cc;
410 :
411 1478 : assert (fname);
412 1523 : for (cc = close_cache; cc; cc = cc->next)
413 : {
414 45 : if (cc->fp != GNUPG_INVALID_FD && !fd_cache_strcmp (cc->fname, fname))
415 : {
416 0 : gnupg_fd_t fp = cc->fp;
417 0 : cc->fp = GNUPG_INVALID_FD;
418 0 : if (DBG_IOBUF)
419 0 : log_debug ("fd_cache_open (%s) using cached fp\n", fname);
420 : #ifdef HAVE_W32_SYSTEM
421 : if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff)
422 : {
423 : log_error ("rewind file failed on handle %p: ec=%d\n",
424 : fp, (int) GetLastError ());
425 : fp = GNUPG_INVALID_FD;
426 : }
427 : #else
428 0 : if (lseek (fp, 0, SEEK_SET) == (off_t) - 1)
429 : {
430 0 : log_error ("can't rewind fd %d: %s\n", fp, strerror (errno));
431 0 : fp = GNUPG_INVALID_FD;
432 : }
433 : #endif
434 0 : return fp;
435 : }
436 : }
437 1478 : if (DBG_IOBUF)
438 0 : log_debug ("fd_cache_open (%s) not cached\n", fname);
439 1478 : return direct_open (fname, mode, 0);
440 : }
441 :
442 :
443 : static int
444 10731 : file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
445 : size_t * ret_len)
446 : {
447 10731 : file_filter_ctx_t *a = opaque;
448 10731 : gnupg_fd_t f = a->fp;
449 10731 : size_t size = *ret_len;
450 10731 : size_t nbytes = 0;
451 10731 : int rc = 0;
452 :
453 : (void)chain; /* Not used. */
454 :
455 10731 : if (control == IOBUFCTRL_UNDERFLOW)
456 : {
457 4248 : assert (size); /* We need a buffer. */
458 4248 : if (a->eof_seen)
459 : {
460 0 : rc = -1;
461 0 : *ret_len = 0;
462 : }
463 : else
464 : {
465 : #ifdef HAVE_W32_SYSTEM
466 : unsigned long nread;
467 :
468 : nbytes = 0;
469 : if (!ReadFile (f, buf, size, &nread, NULL))
470 : {
471 : int ec = (int) GetLastError ();
472 : if (ec != ERROR_BROKEN_PIPE)
473 : {
474 : rc = gpg_error_from_errno (ec);
475 : log_error ("%s: read error: ec=%d\n", a->fname, ec);
476 : }
477 : }
478 : else if (!nread)
479 : {
480 : a->eof_seen = 1;
481 : rc = -1;
482 : }
483 : else
484 : {
485 : nbytes = nread;
486 : }
487 :
488 : #else
489 :
490 : int n;
491 :
492 4248 : nbytes = 0;
493 : do
494 : {
495 4248 : n = read (f, buf, size);
496 : }
497 4248 : while (n == -1 && errno == EINTR);
498 4248 : if (n == -1)
499 : { /* error */
500 0 : if (errno != EPIPE)
501 : {
502 0 : rc = gpg_error_from_syserror ();
503 0 : log_error ("%s: read error: %s\n",
504 0 : a->fname, strerror (errno));
505 : }
506 : }
507 4248 : else if (!n)
508 : { /* eof */
509 1194 : a->eof_seen = 1;
510 1194 : rc = -1;
511 : }
512 : else
513 : {
514 3054 : nbytes = n;
515 : }
516 : #endif
517 4248 : *ret_len = nbytes;
518 : }
519 : }
520 6483 : else if (control == IOBUFCTRL_FLUSH)
521 : {
522 2249 : if (size)
523 : {
524 : #ifdef HAVE_W32_SYSTEM
525 : byte *p = buf;
526 : unsigned long n;
527 :
528 : nbytes = size;
529 : do
530 : {
531 : if (size && !WriteFile (f, p, nbytes, &n, NULL))
532 : {
533 : int ec = (int) GetLastError ();
534 : rc = gpg_error_from_errno (ec);
535 : log_error ("%s: write error: ec=%d\n", a->fname, ec);
536 : break;
537 : }
538 : p += n;
539 : nbytes -= n;
540 : }
541 : while (nbytes);
542 : nbytes = p - buf;
543 : #else
544 2144 : byte *p = buf;
545 : int n;
546 :
547 2144 : nbytes = size;
548 : do
549 : {
550 : do
551 : {
552 2144 : n = write (f, p, nbytes);
553 : }
554 2144 : while (n == -1 && errno == EINTR);
555 2144 : if (n > 0)
556 : {
557 2144 : p += n;
558 2144 : nbytes -= n;
559 : }
560 : }
561 2144 : while (n != -1 && nbytes);
562 2144 : if (n == -1)
563 : {
564 0 : rc = gpg_error_from_syserror ();
565 0 : log_error ("%s: write error: %s\n", a->fname, strerror (errno));
566 : }
567 2144 : nbytes = p - buf;
568 : #endif
569 : }
570 2249 : *ret_len = nbytes;
571 : }
572 4234 : else if (control == IOBUFCTRL_INIT)
573 : {
574 2117 : a->eof_seen = 0;
575 2117 : a->keep_open = 0;
576 2117 : a->no_cache = 0;
577 : }
578 2117 : else if (control == IOBUFCTRL_DESC)
579 : {
580 0 : *(char **) buf = "file_filter(fd)";
581 : }
582 2117 : else if (control == IOBUFCTRL_FREE)
583 : {
584 2117 : if (f != FD_FOR_STDIN && f != FD_FOR_STDOUT)
585 : {
586 2003 : if (DBG_IOBUF)
587 0 : log_debug ("%s: close fd/handle %d\n", a->fname, FD2INT (f));
588 2003 : if (!a->keep_open)
589 2003 : fd_cache_close (a->no_cache ? NULL : a->fname, f);
590 : }
591 2117 : f = GNUPG_INVALID_FD;
592 2117 : xfree (a); /* We can free our context now. */
593 : }
594 :
595 10731 : return rc;
596 : }
597 :
598 :
599 : /* Similar to file_filter but using the estream system. */
600 : static int
601 0 : file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf,
602 : size_t * ret_len)
603 : {
604 0 : file_es_filter_ctx_t *a = opaque;
605 0 : estream_t f = a->fp;
606 0 : size_t size = *ret_len;
607 0 : size_t nbytes = 0;
608 0 : int rc = 0;
609 :
610 : (void)chain; /* Not used. */
611 :
612 0 : if (control == IOBUFCTRL_UNDERFLOW)
613 : {
614 0 : assert (size); /* We need a buffer. */
615 0 : if (a->eof_seen)
616 : {
617 0 : rc = -1;
618 0 : *ret_len = 0;
619 : }
620 : else
621 : {
622 0 : nbytes = 0;
623 0 : rc = es_read (f, buf, size, &nbytes);
624 0 : if (rc == -1)
625 : { /* error */
626 0 : rc = gpg_error_from_syserror ();
627 0 : log_error ("%s: read error: %s\n", a->fname, strerror (errno));
628 : }
629 0 : else if (!nbytes)
630 : { /* eof */
631 0 : a->eof_seen = 1;
632 0 : rc = -1;
633 : }
634 0 : *ret_len = nbytes;
635 : }
636 : }
637 0 : else if (control == IOBUFCTRL_FLUSH)
638 : {
639 0 : if (size)
640 : {
641 0 : byte *p = buf;
642 : size_t nwritten;
643 :
644 0 : nbytes = size;
645 : do
646 : {
647 0 : nwritten = 0;
648 0 : if (es_write (f, p, nbytes, &nwritten))
649 : {
650 0 : rc = gpg_error_from_syserror ();
651 0 : log_error ("%s: write error: %s\n",
652 0 : a->fname, strerror (errno));
653 0 : break;
654 : }
655 0 : p += nwritten;
656 0 : nbytes -= nwritten;
657 : }
658 0 : while (nbytes);
659 0 : nbytes = p - buf;
660 : }
661 0 : *ret_len = nbytes;
662 : }
663 0 : else if (control == IOBUFCTRL_INIT)
664 : {
665 0 : a->eof_seen = 0;
666 0 : a->no_cache = 0;
667 : }
668 0 : else if (control == IOBUFCTRL_DESC)
669 : {
670 0 : *(char **) buf = "estream_filter";
671 : }
672 0 : else if (control == IOBUFCTRL_FREE)
673 : {
674 0 : if (f != es_stdin && f != es_stdout)
675 : {
676 0 : if (DBG_IOBUF)
677 0 : log_debug ("%s: es_fclose %p\n", a->fname, f);
678 0 : if (!a->keep_open)
679 0 : es_fclose (f);
680 : }
681 0 : f = NULL;
682 0 : xfree (a); /* We can free our context now. */
683 : }
684 :
685 0 : return rc;
686 : }
687 :
688 :
689 : #ifdef HAVE_W32_SYSTEM
690 : /* Because network sockets are special objects under Lose32 we have to
691 : use a dedicated filter for them. */
692 : static int
693 : sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
694 : size_t * ret_len)
695 : {
696 : sock_filter_ctx_t *a = opaque;
697 : size_t size = *ret_len;
698 : size_t nbytes = 0;
699 : int rc = 0;
700 :
701 : (void)chain;
702 :
703 : if (control == IOBUFCTRL_UNDERFLOW)
704 : {
705 : assert (size); /* need a buffer */
706 : if (a->eof_seen)
707 : {
708 : rc = -1;
709 : *ret_len = 0;
710 : }
711 : else
712 : {
713 : int nread;
714 :
715 : nread = recv (a->sock, buf, size, 0);
716 : if (nread == SOCKET_ERROR)
717 : {
718 : int ec = (int) WSAGetLastError ();
719 : rc = gpg_error_from_errno (ec);
720 : log_error ("socket read error: ec=%d\n", ec);
721 : }
722 : else if (!nread)
723 : {
724 : a->eof_seen = 1;
725 : rc = -1;
726 : }
727 : else
728 : {
729 : nbytes = nread;
730 : }
731 : *ret_len = nbytes;
732 : }
733 : }
734 : else if (control == IOBUFCTRL_FLUSH)
735 : {
736 : if (size)
737 : {
738 : byte *p = buf;
739 : int n;
740 :
741 : nbytes = size;
742 : do
743 : {
744 : n = send (a->sock, p, nbytes, 0);
745 : if (n == SOCKET_ERROR)
746 : {
747 : int ec = (int) WSAGetLastError ();
748 : rc = gpg_error_from_errno (ec);
749 : log_error ("socket write error: ec=%d\n", ec);
750 : break;
751 : }
752 : p += n;
753 : nbytes -= n;
754 : }
755 : while (nbytes);
756 : nbytes = p - buf;
757 : }
758 : *ret_len = nbytes;
759 : }
760 : else if (control == IOBUFCTRL_INIT)
761 : {
762 : a->eof_seen = 0;
763 : a->keep_open = 0;
764 : a->no_cache = 0;
765 : }
766 : else if (control == IOBUFCTRL_DESC)
767 : {
768 : *(char **) buf = "sock_filter";
769 : }
770 : else if (control == IOBUFCTRL_FREE)
771 : {
772 : if (!a->keep_open)
773 : closesocket (a->sock);
774 : xfree (a); /* we can free our context now */
775 : }
776 : return rc;
777 : }
778 : #endif /*HAVE_W32_SYSTEM*/
779 :
780 : /****************
781 : * This is used to implement the block write mode.
782 : * Block reading is done on a byte by byte basis in readbyte(),
783 : * without a filter
784 : */
785 : static int
786 3958 : block_filter (void *opaque, int control, iobuf_t chain, byte * buffer,
787 : size_t * ret_len)
788 : {
789 3958 : block_filter_ctx_t *a = opaque;
790 3958 : char *buf = (char *)buffer;
791 3958 : size_t size = *ret_len;
792 3958 : int c, needed, rc = 0;
793 : char *p;
794 :
795 3958 : if (control == IOBUFCTRL_UNDERFLOW)
796 : {
797 1300 : size_t n = 0;
798 :
799 1300 : p = buf;
800 1300 : assert (size); /* need a buffer */
801 1300 : if (a->eof) /* don't read any further */
802 299 : rc = -1;
803 4455 : while (!rc && size)
804 : {
805 2154 : if (!a->size)
806 : { /* get the length bytes */
807 2130 : if (a->partial == 2)
808 : {
809 299 : a->eof = 1;
810 299 : if (!n)
811 0 : rc = -1;
812 299 : break;
813 : }
814 1831 : else if (a->partial)
815 : {
816 : /* These OpenPGP introduced huffman like encoded length
817 : * bytes are really a mess :-( */
818 1831 : if (a->first_c)
819 : {
820 299 : c = a->first_c;
821 299 : a->first_c = 0;
822 : }
823 1532 : else if ((c = iobuf_get (chain)) == -1)
824 : {
825 0 : log_error ("block_filter: 1st length byte missing\n");
826 0 : rc = GPG_ERR_BAD_DATA;
827 0 : break;
828 : }
829 1831 : if (c < 192)
830 : {
831 86 : a->size = c;
832 86 : a->partial = 2;
833 86 : if (!a->size)
834 : {
835 0 : a->eof = 1;
836 0 : if (!n)
837 0 : rc = -1;
838 0 : break;
839 : }
840 : }
841 1745 : else if (c < 224)
842 : {
843 213 : a->size = (c - 192) * 256;
844 213 : if ((c = iobuf_get (chain)) == -1)
845 : {
846 0 : log_error
847 : ("block_filter: 2nd length byte missing\n");
848 0 : rc = GPG_ERR_BAD_DATA;
849 0 : break;
850 : }
851 213 : a->size += c + 192;
852 213 : a->partial = 2;
853 213 : if (!a->size)
854 : {
855 0 : a->eof = 1;
856 0 : if (!n)
857 0 : rc = -1;
858 0 : break;
859 : }
860 : }
861 1532 : else if (c == 255)
862 : {
863 0 : a->size = (size_t)iobuf_get (chain) << 24;
864 0 : a->size |= iobuf_get (chain) << 16;
865 0 : a->size |= iobuf_get (chain) << 8;
866 0 : if ((c = iobuf_get (chain)) == -1)
867 : {
868 0 : log_error ("block_filter: invalid 4 byte length\n");
869 0 : rc = GPG_ERR_BAD_DATA;
870 0 : break;
871 : }
872 0 : a->size |= c;
873 0 : a->partial = 2;
874 0 : if (!a->size)
875 : {
876 0 : a->eof = 1;
877 0 : if (!n)
878 0 : rc = -1;
879 0 : break;
880 : }
881 : }
882 : else
883 : { /* Next partial body length. */
884 1532 : a->size = 1 << (c & 0x1f);
885 : }
886 : /* log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size); */
887 : }
888 : else
889 0 : BUG ();
890 : }
891 :
892 5565 : while (!rc && size && a->size)
893 : {
894 1855 : needed = size < a->size ? size : a->size;
895 1855 : c = iobuf_read (chain, p, needed);
896 1855 : if (c < needed)
897 : {
898 0 : if (c == -1)
899 0 : c = 0;
900 0 : log_error
901 : ("block_filter %p: read error (size=%lu,a->size=%lu)\n",
902 0 : a, (ulong) size + c, (ulong) a->size + c);
903 0 : rc = GPG_ERR_BAD_DATA;
904 : }
905 : else
906 : {
907 1855 : size -= c;
908 1855 : a->size -= c;
909 1855 : p += c;
910 1855 : n += c;
911 : }
912 : }
913 : }
914 1300 : *ret_len = n;
915 : }
916 2658 : else if (control == IOBUFCTRL_FLUSH)
917 : {
918 1096 : if (a->partial)
919 : { /* the complicated openpgp scheme */
920 1096 : size_t blen, n, nbytes = size + a->buflen;
921 :
922 1096 : assert (a->buflen <= OP_MIN_PARTIAL_CHUNK);
923 1096 : if (nbytes < OP_MIN_PARTIAL_CHUNK)
924 : {
925 : /* not enough to write a partial block out; so we store it */
926 227 : if (!a->buffer)
927 227 : a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
928 227 : memcpy (a->buffer + a->buflen, buf, size);
929 227 : a->buflen += size;
930 : }
931 : else
932 : { /* okay, we can write out something */
933 : /* do this in a loop to use the most efficient block lengths */
934 869 : p = buf;
935 : do
936 : {
937 : /* find the best matching block length - this is limited
938 : * by the size of the internal buffering */
939 6035 : for (blen = OP_MIN_PARTIAL_CHUNK * 2,
940 1015 : c = OP_MIN_PARTIAL_CHUNK_2POW + 1; blen <= nbytes;
941 2990 : blen *= 2, c++)
942 : ;
943 1015 : blen /= 2;
944 1015 : c--;
945 : /* write the partial length header */
946 1015 : assert (c <= 0x1f); /*;-) */
947 1015 : c |= 0xe0;
948 1015 : iobuf_put (chain, c);
949 1015 : if ((n = a->buflen))
950 : { /* write stuff from the buffer */
951 0 : assert (n == OP_MIN_PARTIAL_CHUNK);
952 0 : if (iobuf_write (chain, a->buffer, n))
953 0 : rc = gpg_error_from_syserror ();
954 0 : a->buflen = 0;
955 0 : nbytes -= n;
956 : }
957 1015 : if ((n = nbytes) > blen)
958 401 : n = blen;
959 1015 : if (n && iobuf_write (chain, p, n))
960 0 : rc = gpg_error_from_syserror ();
961 1015 : p += n;
962 1015 : nbytes -= n;
963 : }
964 1015 : while (!rc && nbytes >= OP_MIN_PARTIAL_CHUNK);
965 : /* store the rest in the buffer */
966 869 : if (!rc && nbytes)
967 : {
968 255 : assert (!a->buflen);
969 255 : assert (nbytes < OP_MIN_PARTIAL_CHUNK);
970 255 : if (!a->buffer)
971 255 : a->buffer = xmalloc (OP_MIN_PARTIAL_CHUNK);
972 255 : memcpy (a->buffer, p, nbytes);
973 255 : a->buflen = nbytes;
974 : }
975 : }
976 : }
977 : else
978 0 : BUG ();
979 : }
980 1562 : else if (control == IOBUFCTRL_INIT)
981 : {
982 781 : if (DBG_IOBUF)
983 0 : log_debug ("init block_filter %p\n", a);
984 781 : if (a->partial)
985 781 : a->count = 0;
986 0 : else if (a->use == IOBUF_INPUT)
987 0 : a->count = a->size = 0;
988 : else
989 0 : a->count = a->size; /* force first length bytes */
990 781 : a->eof = 0;
991 781 : a->buffer = NULL;
992 781 : a->buflen = 0;
993 : }
994 781 : else if (control == IOBUFCTRL_DESC)
995 : {
996 0 : *(char **) buf = "block_filter";
997 : }
998 781 : else if (control == IOBUFCTRL_FREE)
999 : {
1000 781 : if (a->use == IOBUF_OUTPUT)
1001 : { /* write the end markers */
1002 482 : if (a->partial)
1003 : {
1004 : u32 len;
1005 : /* write out the remaining bytes without a partial header
1006 : * the length of this header may be 0 - but if it is
1007 : * the first block we are not allowed to use a partial header
1008 : * and frankly we can't do so, because this length must be
1009 : * a power of 2. This is _really_ complicated because we
1010 : * have to check the possible length of a packet prior
1011 : * to it's creation: a chain of filters becomes complicated
1012 : * and we need a lot of code to handle compressed packets etc.
1013 : * :-(((((((
1014 : */
1015 : /* construct header */
1016 482 : len = a->buflen;
1017 : /*log_debug("partial: remaining length=%u\n", len ); */
1018 482 : if (len < 192)
1019 281 : rc = iobuf_put (chain, len);
1020 201 : else if (len < 8384)
1021 : {
1022 201 : if (!(rc = iobuf_put (chain, ((len - 192) / 256) + 192)))
1023 201 : rc = iobuf_put (chain, ((len - 192) % 256));
1024 : }
1025 : else
1026 : { /* use a 4 byte header */
1027 0 : if (!(rc = iobuf_put (chain, 0xff)))
1028 0 : if (!(rc = iobuf_put (chain, (len >> 24) & 0xff)))
1029 0 : if (!(rc = iobuf_put (chain, (len >> 16) & 0xff)))
1030 0 : if (!(rc = iobuf_put (chain, (len >> 8) & 0xff)))
1031 0 : rc = iobuf_put (chain, len & 0xff);
1032 : }
1033 482 : if (!rc && len)
1034 482 : rc = iobuf_write (chain, a->buffer, len);
1035 482 : if (rc)
1036 : {
1037 0 : log_error ("block_filter: write error: %s\n",
1038 0 : strerror (errno));
1039 0 : rc = gpg_error_from_syserror ();
1040 : }
1041 482 : xfree (a->buffer);
1042 482 : a->buffer = NULL;
1043 482 : a->buflen = 0;
1044 : }
1045 : else
1046 0 : BUG ();
1047 : }
1048 299 : else if (a->size)
1049 : {
1050 0 : log_error ("block_filter: pending bytes!\n");
1051 : }
1052 781 : if (DBG_IOBUF)
1053 0 : log_debug ("free block_filter %p\n", a);
1054 781 : xfree (a); /* we can free our context now */
1055 : }
1056 :
1057 3958 : return rc;
1058 : }
1059 :
1060 : static const char *
1061 0 : iobuf_desc (iobuf_t a)
1062 : {
1063 0 : size_t dummy_len = 0;
1064 0 : const char *desc = "?";
1065 :
1066 0 : if (! a || ! a->filter)
1067 0 : return desc;
1068 :
1069 0 : a->filter (a->filter_ov, IOBUFCTRL_DESC, NULL,
1070 : (byte *) & desc, &dummy_len);
1071 :
1072 0 : return desc;
1073 : }
1074 :
1075 : static void
1076 1564 : print_chain (iobuf_t a)
1077 : {
1078 1564 : if (!DBG_IOBUF)
1079 3128 : return;
1080 0 : for (; a; a = a->chain)
1081 : {
1082 :
1083 0 : log_debug ("iobuf chain: %d.%d '%s' filter_eof=%d start=%d len=%d\n",
1084 : a->no, a->subno, iobuf_desc (a), a->filter_eof,
1085 0 : (int) a->d.start, (int) a->d.len);
1086 : }
1087 : }
1088 :
1089 : int
1090 0 : iobuf_print_chain (iobuf_t a)
1091 : {
1092 0 : print_chain (a);
1093 0 : return 0;
1094 : }
1095 :
1096 : iobuf_t
1097 5722 : iobuf_alloc (int use, size_t bufsize)
1098 : {
1099 : iobuf_t a;
1100 : static int number = 0;
1101 :
1102 5722 : assert (use == IOBUF_INPUT || use == IOBUF_INPUT_TEMP
1103 : || use == IOBUF_OUTPUT || use == IOBUF_OUTPUT_TEMP);
1104 5722 : if (bufsize == 0)
1105 : {
1106 0 : log_bug ("iobuf_alloc() passed a bufsize of 0!\n");
1107 : bufsize = IOBUF_BUFFER_SIZE;
1108 : }
1109 :
1110 5722 : a = xcalloc (1, sizeof *a);
1111 5722 : a->use = use;
1112 5722 : a->d.buf = xmalloc (bufsize);
1113 5722 : a->d.size = bufsize;
1114 5722 : a->no = ++number;
1115 5722 : a->subno = 0;
1116 5722 : a->real_fname = NULL;
1117 5722 : return a;
1118 : }
1119 :
1120 : int
1121 10779 : iobuf_close (iobuf_t a)
1122 : {
1123 : iobuf_t a_chain;
1124 10779 : size_t dummy_len = 0;
1125 10779 : int rc = 0;
1126 :
1127 17892 : for (; a; a = a_chain)
1128 : {
1129 7113 : int rc2 = 0;
1130 :
1131 7113 : a_chain = a->chain;
1132 :
1133 7113 : if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1134 0 : log_error ("filter_flush failed on close: %s\n", gpg_strerror (rc));
1135 :
1136 7113 : if (DBG_IOBUF)
1137 0 : log_debug ("iobuf-%d.%d: close '%s'\n",
1138 : a->no, a->subno, iobuf_desc (a));
1139 :
1140 7113 : if (a->filter && (rc2 = a->filter (a->filter_ov, IOBUFCTRL_FREE,
1141 : a->chain, NULL, &dummy_len)))
1142 0 : log_error ("IOBUFCTRL_FREE failed on close: %s\n", gpg_strerror (rc));
1143 7113 : if (! rc && rc2)
1144 : /* Whoops! An error occured. Save it in RC if we haven't
1145 : already recorded an error. */
1146 0 : rc = rc2;
1147 :
1148 7113 : xfree (a->real_fname);
1149 7113 : if (a->d.buf)
1150 : {
1151 7113 : memset (a->d.buf, 0, a->d.size); /* erase the buffer */
1152 7113 : xfree (a->d.buf);
1153 : }
1154 7113 : xfree (a);
1155 : }
1156 10779 : return rc;
1157 : }
1158 :
1159 : int
1160 0 : iobuf_cancel (iobuf_t a)
1161 : {
1162 : const char *s;
1163 : iobuf_t a2;
1164 : int rc;
1165 : #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1166 : char *remove_name = NULL;
1167 : #endif
1168 :
1169 0 : if (a && a->use == IOBUF_OUTPUT)
1170 : {
1171 0 : s = iobuf_get_real_fname (a);
1172 0 : if (s && *s)
1173 : {
1174 : #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1175 : remove_name = xstrdup (s);
1176 : #else
1177 0 : remove (s);
1178 : #endif
1179 : }
1180 : }
1181 :
1182 : /* send a cancel message to all filters */
1183 0 : for (a2 = a; a2; a2 = a2->chain)
1184 : {
1185 : size_t dummy;
1186 0 : if (a2->filter)
1187 0 : a2->filter (a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain, NULL, &dummy);
1188 : }
1189 :
1190 0 : rc = iobuf_close (a);
1191 : #if defined(HAVE_W32_SYSTEM) || defined(__riscos__)
1192 : if (remove_name)
1193 : {
1194 : /* Argg, MSDOS does not allow to remove open files. So
1195 : * we have to do it here */
1196 : #ifdef HAVE_W32CE_SYSTEM
1197 : wchar_t *wtmp = utf8_to_wchar (remove_name);
1198 : if (wtmp)
1199 : DeleteFile (wtmp);
1200 : xfree (wtmp);
1201 : #else
1202 : remove (remove_name);
1203 : #endif
1204 : xfree (remove_name);
1205 : }
1206 : #endif
1207 0 : return rc;
1208 : }
1209 :
1210 :
1211 : iobuf_t
1212 1141 : iobuf_temp (void)
1213 : {
1214 1141 : return iobuf_alloc (IOBUF_OUTPUT_TEMP, IOBUF_BUFFER_SIZE);
1215 : }
1216 :
1217 : iobuf_t
1218 2464 : iobuf_temp_with_content (const char *buffer, size_t length)
1219 : {
1220 : iobuf_t a;
1221 : int i;
1222 :
1223 2464 : a = iobuf_alloc (IOBUF_INPUT_TEMP, length);
1224 2464 : assert (length == a->d.size);
1225 : /* memcpy (a->d.buf, buffer, length); */
1226 2083466 : for (i=0; i < length; i++)
1227 2081002 : a->d.buf[i] = buffer[i];
1228 2464 : a->d.len = length;
1229 :
1230 2464 : return a;
1231 : }
1232 :
1233 : void
1234 0 : iobuf_enable_special_filenames (int yes)
1235 : {
1236 0 : special_names_enabled = yes;
1237 0 : }
1238 :
1239 :
1240 : /* See whether the filename has the form "-&nnnn", where n is a
1241 : non-zero number. Returns this number or -1 if it is not the
1242 : case. */
1243 : static int
1244 5485 : check_special_filename (const char *fname)
1245 : {
1246 5485 : if (special_names_enabled && fname && *fname == '-' && fname[1] == '&')
1247 : {
1248 : int i;
1249 :
1250 0 : fname += 2;
1251 0 : for (i = 0; digitp (fname+i); i++)
1252 : ;
1253 0 : if (!fname[i])
1254 0 : return atoi (fname);
1255 : }
1256 5485 : return -1;
1257 : }
1258 :
1259 :
1260 : int
1261 3668 : iobuf_is_pipe_filename (const char *fname)
1262 : {
1263 3668 : if (!fname || (*fname=='-' && !fname[1]) )
1264 186 : return 1;
1265 3482 : return check_special_filename (fname) != -1;
1266 : }
1267 :
1268 : static iobuf_t
1269 2117 : do_open (const char *fname, int special_filenames,
1270 : int use, const char *opentype, int mode700)
1271 : {
1272 : iobuf_t a;
1273 : gnupg_fd_t fp;
1274 : file_filter_ctx_t *fcx;
1275 2117 : size_t len = 0;
1276 2117 : int print_only = 0;
1277 : int fd;
1278 :
1279 2117 : assert (use == IOBUF_INPUT || use == IOBUF_OUTPUT);
1280 :
1281 2117 : if (special_filenames
1282 : /* NULL or '-'. */
1283 2117 : && (!fname || (*fname == '-' && !fname[1])))
1284 : {
1285 114 : if (use == IOBUF_INPUT)
1286 : {
1287 80 : fp = FD_FOR_STDIN;
1288 80 : fname = "[stdin]";
1289 : }
1290 : else
1291 : {
1292 34 : fp = FD_FOR_STDOUT;
1293 34 : fname = "[stdout]";
1294 : }
1295 114 : print_only = 1;
1296 : }
1297 2003 : else if (!fname)
1298 0 : return NULL;
1299 2003 : else if (special_filenames && (fd = check_special_filename (fname)) != -1)
1300 0 : return iobuf_fdopen (translate_file_handle (fd, use == IOBUF_INPUT ? 0 : 1),
1301 : opentype);
1302 : else
1303 : {
1304 2003 : if (use == IOBUF_INPUT)
1305 1478 : fp = fd_cache_open (fname, opentype);
1306 : else
1307 525 : fp = direct_open (fname, opentype, mode700);
1308 2003 : if (fp == GNUPG_INVALID_FD)
1309 0 : return NULL;
1310 : }
1311 :
1312 2117 : a = iobuf_alloc (use, IOBUF_BUFFER_SIZE);
1313 2117 : fcx = xmalloc (sizeof *fcx + strlen (fname));
1314 2117 : fcx->fp = fp;
1315 2117 : fcx->print_only_name = print_only;
1316 2117 : strcpy (fcx->fname, fname);
1317 2117 : if (!print_only)
1318 2003 : a->real_fname = xstrdup (fname);
1319 2117 : a->filter = file_filter;
1320 2117 : a->filter_ov = fcx;
1321 2117 : file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1322 2117 : if (DBG_IOBUF)
1323 0 : log_debug ("iobuf-%d.%d: open '%s' desc=%s fd=%d\n",
1324 : a->no, a->subno, fname, iobuf_desc (a), FD2INT (fcx->fp));
1325 :
1326 2117 : return a;
1327 : }
1328 :
1329 : iobuf_t
1330 1558 : iobuf_open (const char *fname)
1331 : {
1332 1558 : return do_open (fname, 1, IOBUF_INPUT, "rb", 0);
1333 : }
1334 :
1335 : iobuf_t
1336 559 : iobuf_create (const char *fname, int mode700)
1337 : {
1338 559 : return do_open (fname, 1, IOBUF_OUTPUT, "wb", mode700);
1339 : }
1340 :
1341 : iobuf_t
1342 0 : iobuf_openrw (const char *fname)
1343 : {
1344 0 : return do_open (fname, 0, IOBUF_OUTPUT, "r+b", 0);
1345 : }
1346 :
1347 :
1348 : static iobuf_t
1349 0 : do_iobuf_fdopen (int fd, const char *mode, int keep_open)
1350 : {
1351 : iobuf_t a;
1352 : gnupg_fd_t fp;
1353 : file_filter_ctx_t *fcx;
1354 : size_t len;
1355 :
1356 0 : fp = INT2FD (fd);
1357 :
1358 0 : a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1359 : IOBUF_BUFFER_SIZE);
1360 0 : fcx = xmalloc (sizeof *fcx + 20);
1361 0 : fcx->fp = fp;
1362 0 : fcx->print_only_name = 1;
1363 0 : fcx->keep_open = keep_open;
1364 0 : sprintf (fcx->fname, "[fd %d]", fd);
1365 0 : a->filter = file_filter;
1366 0 : a->filter_ov = fcx;
1367 0 : file_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1368 0 : if (DBG_IOBUF)
1369 0 : log_debug ("iobuf-%d.%d: fdopen%s '%s'\n",
1370 0 : a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1371 0 : iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1372 0 : return a;
1373 : }
1374 :
1375 :
1376 : iobuf_t
1377 0 : iobuf_fdopen (int fd, const char *mode)
1378 : {
1379 0 : return do_iobuf_fdopen (fd, mode, 0);
1380 : }
1381 :
1382 : iobuf_t
1383 0 : iobuf_fdopen_nc (int fd, const char *mode)
1384 : {
1385 0 : return do_iobuf_fdopen (fd, mode, 1);
1386 : }
1387 :
1388 :
1389 : iobuf_t
1390 0 : iobuf_esopen (estream_t estream, const char *mode, int keep_open)
1391 : {
1392 : iobuf_t a;
1393 : file_es_filter_ctx_t *fcx;
1394 : size_t len;
1395 :
1396 0 : a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1397 : IOBUF_BUFFER_SIZE);
1398 0 : fcx = xtrymalloc (sizeof *fcx + 30);
1399 0 : fcx->fp = estream;
1400 0 : fcx->print_only_name = 1;
1401 0 : fcx->keep_open = keep_open;
1402 0 : sprintf (fcx->fname, "[fd %p]", estream);
1403 0 : a->filter = file_es_filter;
1404 0 : a->filter_ov = fcx;
1405 0 : file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len);
1406 0 : if (DBG_IOBUF)
1407 0 : log_debug ("iobuf-%d.%d: esopen%s '%s'\n",
1408 0 : a->no, a->subno, keep_open? "_nc":"", fcx->fname);
1409 0 : return a;
1410 : }
1411 :
1412 :
1413 : iobuf_t
1414 0 : iobuf_sockopen (int fd, const char *mode)
1415 : {
1416 : iobuf_t a;
1417 : #ifdef HAVE_W32_SYSTEM
1418 : sock_filter_ctx_t *scx;
1419 : size_t len;
1420 :
1421 : a = iobuf_alloc (strchr (mode, 'w') ? IOBUF_OUTPUT : IOBUF_INPUT,
1422 : IOBUF_BUFFER_SIZE);
1423 : scx = xmalloc (sizeof *scx + 25);
1424 : scx->sock = fd;
1425 : scx->print_only_name = 1;
1426 : sprintf (scx->fname, "[sock %d]", fd);
1427 : a->filter = sock_filter;
1428 : a->filter_ov = scx;
1429 : sock_filter (scx, IOBUFCTRL_INIT, NULL, NULL, &len);
1430 : if (DBG_IOBUF)
1431 : log_debug ("iobuf-%d.%d: sockopen '%s'\n", a->no, a->subno, scx->fname);
1432 : iobuf_ioctl (a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
1433 : #else
1434 0 : a = iobuf_fdopen (fd, mode);
1435 : #endif
1436 0 : return a;
1437 : }
1438 :
1439 : int
1440 1002 : iobuf_ioctl (iobuf_t a, iobuf_ioctl_t cmd, int intval, void *ptrval)
1441 : {
1442 1002 : if (cmd == IOBUF_IOCTL_KEEP_OPEN)
1443 : {
1444 : /* Keep system filepointer/descriptor open. This was used in
1445 : the past by http.c; this ioctl is not directly used
1446 : anymore. */
1447 0 : if (DBG_IOBUF)
1448 0 : log_debug ("iobuf-%d.%d: ioctl '%s' keep_open=%d\n",
1449 : a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
1450 : intval);
1451 0 : for (; a; a = a->chain)
1452 0 : if (!a->chain && a->filter == file_filter)
1453 : {
1454 0 : file_filter_ctx_t *b = a->filter_ov;
1455 0 : b->keep_open = intval;
1456 0 : return 0;
1457 : }
1458 : #ifdef HAVE_W32_SYSTEM
1459 : else if (!a->chain && a->filter == sock_filter)
1460 : {
1461 : sock_filter_ctx_t *b = a->filter_ov;
1462 : b->keep_open = intval;
1463 : return 0;
1464 : }
1465 : #endif
1466 : }
1467 1002 : else if (cmd == IOBUF_IOCTL_INVALIDATE_CACHE)
1468 : {
1469 21 : if (DBG_IOBUF)
1470 0 : log_debug ("iobuf-*.*: ioctl '%s' invalidate\n",
1471 : ptrval ? (char *) ptrval : "?");
1472 21 : if (!a && !intval && ptrval)
1473 : {
1474 21 : if (fd_cache_invalidate (ptrval))
1475 0 : return -1;
1476 21 : return 0;
1477 : }
1478 : }
1479 981 : else if (cmd == IOBUF_IOCTL_NO_CACHE)
1480 : {
1481 981 : if (DBG_IOBUF)
1482 0 : log_debug ("iobuf-%d.%d: ioctl '%s' no_cache=%d\n",
1483 : a ? a->no : -1, a ? a->subno : -1, iobuf_desc (a),
1484 : intval);
1485 981 : for (; a; a = a->chain)
1486 981 : if (!a->chain && a->filter == file_filter)
1487 : {
1488 981 : file_filter_ctx_t *b = a->filter_ov;
1489 981 : b->no_cache = intval;
1490 981 : return 0;
1491 : }
1492 : #ifdef HAVE_W32_SYSTEM
1493 : else if (!a->chain && a->filter == sock_filter)
1494 : {
1495 : sock_filter_ctx_t *b = a->filter_ov;
1496 : b->no_cache = intval;
1497 : return 0;
1498 : }
1499 : #endif
1500 : }
1501 0 : else if (cmd == IOBUF_IOCTL_FSYNC)
1502 : {
1503 : /* Do a fsync on the open fd and return any errors to the caller
1504 : of iobuf_ioctl. Note that we work on a file name here. */
1505 0 : if (DBG_IOBUF)
1506 0 : log_debug ("iobuf-*.*: ioctl '%s' fsync\n",
1507 : ptrval? (const char*)ptrval:"<null>");
1508 :
1509 0 : if (!a && !intval && ptrval)
1510 : {
1511 0 : return fd_cache_synchronize (ptrval);
1512 : }
1513 : }
1514 :
1515 :
1516 0 : return -1;
1517 : }
1518 :
1519 :
1520 : /****************
1521 : * Register an i/o filter.
1522 : */
1523 : int
1524 2038 : iobuf_push_filter (iobuf_t a,
1525 : int (*f) (void *opaque, int control,
1526 : iobuf_t chain, byte * buf, size_t * len),
1527 : void *ov)
1528 : {
1529 2038 : return iobuf_push_filter2 (a, f, ov, 0);
1530 : }
1531 :
1532 : int
1533 3088 : iobuf_push_filter2 (iobuf_t a,
1534 : int (*f) (void *opaque, int control,
1535 : iobuf_t chain, byte * buf, size_t * len),
1536 : void *ov, int rel_ov)
1537 : {
1538 : iobuf_t b;
1539 3088 : size_t dummy_len = 0;
1540 3088 : int rc = 0;
1541 :
1542 3088 : if (a->use == IOBUF_OUTPUT && (rc = filter_flush (a)))
1543 0 : return rc;
1544 :
1545 3088 : if (a->subno >= MAX_NESTING_FILTER)
1546 : {
1547 0 : log_error ("i/o filter too deeply nested - corrupted data?\n");
1548 0 : return GPG_ERR_BAD_DATA;
1549 : }
1550 :
1551 : /* We want to create a new filter and put it in front of A. A
1552 : simple implementation would do:
1553 :
1554 : b = iobuf_alloc (...);
1555 : b->chain = a;
1556 : return a;
1557 :
1558 : This is a bit problematic: A is the head of the pipeline and
1559 : there are potentially many pointers to it. Requiring the caller
1560 : to update all of these pointers is a burden.
1561 :
1562 : An alternative implementation would add a level of indirection.
1563 : For instance, we could use a pipeline object, which contains a
1564 : pointer to the first filter in the pipeline. This is not what we
1565 : do either.
1566 :
1567 : Instead, we allocate a new buffer (B) and copy the first filter's
1568 : state into that and use the initial buffer (A) for the new
1569 : filter. One limitation of this approach is that it is not
1570 : practical to maintain a pointer to a specific filter's state.
1571 :
1572 : Before:
1573 :
1574 : A
1575 : |
1576 : v 0x100 0x200
1577 : +----------+ +----------+
1578 : | filter x |--------->| filter y |---->....
1579 : +----------+ +----------+
1580 :
1581 : After: B
1582 : |
1583 : v 0x300
1584 : +----------+
1585 : A | filter x |
1586 : | +----------+
1587 : v 0x100 ^ v 0x200
1588 : +----------+ +----------+
1589 : | filter w | | filter y |---->....
1590 : +----------+ +----------+
1591 :
1592 : Note: filter x's address changed from 0x100 to 0x300, but A still
1593 : points to the head of the pipeline.
1594 : */
1595 :
1596 3088 : b = xmalloc (sizeof *b);
1597 3088 : memcpy (b, a, sizeof *b);
1598 : /* fixme: it is stupid to keep a copy of the name at every level
1599 : * but we need the name somewhere because the name known by file_filter
1600 : * may have been released when we need the name of the file */
1601 3088 : b->real_fname = a->real_fname ? xstrdup (a->real_fname) : NULL;
1602 : /* remove the filter stuff from the new stream */
1603 3088 : a->filter = NULL;
1604 3088 : a->filter_ov = NULL;
1605 3088 : a->filter_ov_owner = 0;
1606 3088 : a->filter_eof = 0;
1607 3088 : if (a->use == IOBUF_OUTPUT_TEMP)
1608 : /* A TEMP filter buffers any data sent to it; it does not forward
1609 : any data down the pipeline. If we add a new filter to the
1610 : pipeline, it shouldn't also buffer data. It should send it
1611 : downstream to be buffered. Thus, the correct type for a filter
1612 : added in front of an IOBUF_OUTPUT_TEMP filter is IOBUF_OUPUT, not
1613 : IOBUF_OUTPUT_TEMP. */
1614 : {
1615 1 : a->use = IOBUF_OUTPUT;
1616 :
1617 : /* When pipeline is written to, the temp buffer's size is
1618 : increased accordingly. We don't need to allocate a 10 MB
1619 : buffer for a non-terminal filter. Just use the default
1620 : size. */
1621 1 : a->d.size = IOBUF_BUFFER_SIZE;
1622 : }
1623 3087 : else if (a->use == IOBUF_INPUT_TEMP)
1624 : /* Same idea as above. */
1625 : {
1626 4 : a->use = IOBUF_INPUT;
1627 4 : a->d.size = IOBUF_BUFFER_SIZE;
1628 : }
1629 :
1630 : /* The new filter (A) gets a new buffer.
1631 :
1632 : If the pipeline is an output or temp pipeline, then giving the
1633 : buffer to the new filter means that data that was written before
1634 : the filter was pushed gets sent to the filter. That's clearly
1635 : wrong.
1636 :
1637 : If the pipeline is an input pipeline, then giving the buffer to
1638 : the new filter (A) means that data that has read from (B), but
1639 : not yet read from the pipeline won't be processed by the new
1640 : filter (A)! That's certainly not what we want. */
1641 3088 : a->d.buf = xmalloc (a->d.size);
1642 3088 : a->d.len = 0;
1643 3088 : a->d.start = 0;
1644 :
1645 : /* disable nlimit for the new stream */
1646 3088 : a->ntotal = b->ntotal + b->nbytes;
1647 3088 : a->nlimit = a->nbytes = 0;
1648 3088 : a->nofast = 0;
1649 : /* make a link from the new stream to the original stream */
1650 3088 : a->chain = b;
1651 :
1652 : /* setup the function on the new stream */
1653 3088 : a->filter = f;
1654 3088 : a->filter_ov = ov;
1655 3088 : a->filter_ov_owner = rel_ov;
1656 :
1657 3088 : a->subno = b->subno + 1;
1658 :
1659 3088 : if (DBG_IOBUF)
1660 : {
1661 0 : log_debug ("iobuf-%d.%d: push '%s'\n",
1662 : a->no, a->subno, iobuf_desc (a));
1663 0 : print_chain (a);
1664 : }
1665 :
1666 : /* now we can initialize the new function if we have one */
1667 3088 : if (a->filter && (rc = a->filter (a->filter_ov, IOBUFCTRL_INIT, a->chain,
1668 : NULL, &dummy_len)))
1669 0 : log_error ("IOBUFCTRL_INIT failed: %s\n", gpg_strerror (rc));
1670 3088 : return rc;
1671 : }
1672 :
1673 : /****************
1674 : * Remove an i/o filter.
1675 : */
1676 : static int
1677 28 : pop_filter (iobuf_t a, int (*f) (void *opaque, int control,
1678 : iobuf_t chain, byte * buf, size_t * len),
1679 : void *ov)
1680 : {
1681 : iobuf_t b;
1682 28 : size_t dummy_len = 0;
1683 28 : int rc = 0;
1684 :
1685 28 : if (DBG_IOBUF)
1686 0 : log_debug ("iobuf-%d.%d: pop '%s'\n",
1687 : a->no, a->subno, iobuf_desc (a));
1688 28 : if (a->use == IOBUF_INPUT_TEMP || a->use == IOBUF_OUTPUT_TEMP)
1689 : {
1690 : /* This should be the last filter in the pipeline. */
1691 0 : assert (! a->chain);
1692 0 : return 0;
1693 : }
1694 28 : if (!a->filter)
1695 : { /* this is simple */
1696 0 : b = a->chain;
1697 0 : assert (b);
1698 0 : xfree (a->d.buf);
1699 0 : xfree (a->real_fname);
1700 0 : memcpy (a, b, sizeof *a);
1701 0 : xfree (b);
1702 0 : return 0;
1703 : }
1704 28 : for (b = a; b; b = b->chain)
1705 28 : if (b->filter == f && (!ov || b->filter_ov == ov))
1706 : break;
1707 28 : if (!b)
1708 0 : log_bug ("pop_filter(): filter function not found\n");
1709 :
1710 : /* flush this stream if it is an output stream */
1711 28 : if (a->use == IOBUF_OUTPUT && (rc = filter_flush (b)))
1712 : {
1713 0 : log_error ("filter_flush failed in pop_filter: %s\n", gpg_strerror (rc));
1714 0 : return rc;
1715 : }
1716 : /* and tell the filter to free it self */
1717 28 : if (b->filter && (rc = b->filter (b->filter_ov, IOBUFCTRL_FREE, b->chain,
1718 : NULL, &dummy_len)))
1719 : {
1720 0 : log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1721 0 : return rc;
1722 : }
1723 28 : if (b->filter_ov && b->filter_ov_owner)
1724 : {
1725 0 : xfree (b->filter_ov);
1726 0 : b->filter_ov = NULL;
1727 : }
1728 :
1729 :
1730 : /* and see how to remove it */
1731 28 : if (a == b && !b->chain)
1732 0 : log_bug ("can't remove the last filter from the chain\n");
1733 28 : else if (a == b)
1734 : { /* remove the first iobuf from the chain */
1735 : /* everything from b is copied to a. This is save because
1736 : * a flush has been done on the to be removed entry
1737 : */
1738 28 : b = a->chain;
1739 28 : xfree (a->d.buf);
1740 28 : xfree (a->real_fname);
1741 28 : memcpy (a, b, sizeof *a);
1742 28 : xfree (b);
1743 28 : if (DBG_IOBUF)
1744 0 : log_debug ("iobuf-%d.%d: popped filter\n", a->no, a->subno);
1745 : }
1746 0 : else if (!b->chain)
1747 : { /* remove the last iobuf from the chain */
1748 0 : log_bug ("Ohh jeee, trying to remove a head filter\n");
1749 : }
1750 : else
1751 : { /* remove an intermediate iobuf from the chain */
1752 0 : log_bug ("Ohh jeee, trying to remove an intermediate filter\n");
1753 : }
1754 :
1755 28 : return rc;
1756 : }
1757 :
1758 :
1759 : /****************
1760 : * read underflow: read more bytes into the buffer and return
1761 : * the first byte or -1 on EOF.
1762 : */
1763 : static int
1764 537669 : underflow (iobuf_t a, int clear_pending_eof)
1765 : {
1766 : size_t len;
1767 : int rc;
1768 :
1769 537669 : if (DBG_IOBUF)
1770 0 : log_debug ("iobuf-%d.%d: underflow: buffer size: %d; still buffered: %d => space for %d bytes\n",
1771 : a->no, a->subno,
1772 0 : (int) a->d.size, (int) (a->d.len - a->d.start),
1773 0 : (int) (a->d.size - (a->d.len - a->d.start)));
1774 :
1775 537669 : if (a->use == IOBUF_INPUT_TEMP)
1776 : /* By definition, there isn't more data to read into the
1777 : buffer. */
1778 2465 : return -1;
1779 :
1780 535204 : assert (a->use == IOBUF_INPUT);
1781 :
1782 : /* If there is still some buffered data, then move it to the start
1783 : of the buffer and try to fill the end of the buffer. (This is
1784 : useful if we are called from iobuf_peek().) */
1785 535204 : assert (a->d.start <= a->d.len);
1786 535204 : a->d.len -= a->d.start;
1787 535204 : memmove (a->d.buf, &a->d.buf[a->d.start], a->d.len);
1788 535204 : a->d.start = 0;
1789 :
1790 535204 : if (a->d.len == 0 && a->filter_eof)
1791 : /* The last time we tried to read from this filter, we got an EOF.
1792 : We couldn't return the EOF, because there was buffered data.
1793 : Since there is no longer any buffered data, return the
1794 : error. */
1795 : {
1796 1568 : if (DBG_IOBUF)
1797 0 : log_debug ("iobuf-%d.%d: underflow: eof (pending eof)\n",
1798 : a->no, a->subno);
1799 1568 : if (! clear_pending_eof)
1800 0 : return -1;
1801 :
1802 1568 : if (a->chain)
1803 : /* A filter follows this one. Free this filter. */
1804 : {
1805 540 : iobuf_t b = a->chain;
1806 540 : if (DBG_IOBUF)
1807 0 : log_debug ("iobuf-%d.%d: filter popped (pending EOF returned)\n",
1808 : a->no, a->subno);
1809 540 : xfree (a->d.buf);
1810 540 : xfree (a->real_fname);
1811 540 : memcpy (a, b, sizeof *a);
1812 540 : xfree (b);
1813 540 : print_chain (a);
1814 : }
1815 : else
1816 1028 : a->filter_eof = 0; /* for the top level filter */
1817 1568 : return -1; /* return one(!) EOF */
1818 : }
1819 :
1820 533636 : if (a->d.len == 0 && a->error)
1821 : /* The last time we tried to read from this filter, we got an
1822 : error. We couldn't return the error, because there was
1823 : buffered data. Since there is no longer any buffered data,
1824 : return the error. */
1825 : {
1826 0 : if (DBG_IOBUF)
1827 0 : log_debug ("iobuf-%d.%d: pending error (%s) returned\n",
1828 0 : a->no, a->subno, gpg_strerror (a->error));
1829 0 : return -1;
1830 : }
1831 :
1832 533636 : if (a->filter && ! a->filter_eof && ! a->error)
1833 : /* We have a filter function and the last time we tried to read we
1834 : didn't get an EOF or an error. Try to fill the buffer. */
1835 : {
1836 : /* Be careful to account for any buffered data. */
1837 533494 : len = a->d.size - a->d.len;
1838 533494 : if (DBG_IOBUF)
1839 0 : log_debug ("iobuf-%d.%d: underflow: A->FILTER (%lu bytes)\n",
1840 : a->no, a->subno, (ulong) len);
1841 533494 : if (len == 0)
1842 : /* There is no space for more data. Don't bother calling
1843 : A->FILTER. */
1844 0 : rc = 0;
1845 : else
1846 1066988 : rc = a->filter (a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
1847 533494 : &a->d.buf[a->d.len], &len);
1848 533494 : a->d.len += len;
1849 :
1850 533494 : if (DBG_IOBUF)
1851 0 : log_debug ("iobuf-%d.%d: A->FILTER() returned rc=%d (%s), read %lu bytes\n",
1852 : a->no, a->subno,
1853 0 : rc, rc == 0 ? "ok" : rc == -1 ? "EOF" : gpg_strerror (rc),
1854 : (ulong) len);
1855 : /* if( a->no == 1 ) */
1856 : /* log_hexdump (" data:", a->d.buf, len); */
1857 :
1858 533494 : if (rc == -1)
1859 : /* EOF. */
1860 : {
1861 2758 : size_t dummy_len = 0;
1862 :
1863 : /* Tell the filter to free itself */
1864 2758 : if ((rc = a->filter (a->filter_ov, IOBUFCTRL_FREE, a->chain,
1865 : NULL, &dummy_len)))
1866 0 : log_error ("IOBUFCTRL_FREE failed: %s\n", gpg_strerror (rc));
1867 :
1868 : /* Free everything except for the internal buffer. */
1869 2758 : if (a->filter_ov && a->filter_ov_owner)
1870 0 : xfree (a->filter_ov);
1871 2758 : a->filter_ov = NULL;
1872 2758 : a->filter = NULL;
1873 2758 : a->filter_eof = 1;
1874 :
1875 2758 : if (clear_pending_eof && a->d.len == 0 && a->chain)
1876 : /* We don't need to keep this filter around at all:
1877 :
1878 : - we got an EOF
1879 : - we have no buffered data
1880 : - a filter follows this one.
1881 :
1882 : Unlink this filter. */
1883 : {
1884 1024 : iobuf_t b = a->chain;
1885 1024 : if (DBG_IOBUF)
1886 0 : log_debug ("iobuf-%d.%d: pop in underflow (nothing buffered, got EOF)\n",
1887 : a->no, a->subno);
1888 1024 : xfree (a->d.buf);
1889 1024 : xfree (a->real_fname);
1890 1024 : memcpy (a, b, sizeof *a);
1891 1024 : xfree (b);
1892 :
1893 1024 : print_chain (a);
1894 :
1895 3242 : return -1;
1896 : }
1897 1734 : else if (a->d.len == 0)
1898 : /* We can't unlink this filter (it is the only one in the
1899 : pipeline), but we can immediately return EOF. */
1900 1194 : return -1;
1901 : }
1902 530736 : else if (rc)
1903 : /* Record the error. */
1904 : {
1905 0 : a->error = rc;
1906 :
1907 0 : if (a->d.len == 0)
1908 : /* There is no buffered data. Immediately return EOF. */
1909 0 : return -1;
1910 : }
1911 : }
1912 :
1913 531418 : assert (a->d.start <= a->d.len);
1914 531418 : if (a->d.start < a->d.len)
1915 531274 : return a->d.buf[a->d.start++];
1916 :
1917 : /* EOF. */
1918 144 : return -1;
1919 : }
1920 :
1921 :
1922 : static int
1923 6326 : filter_flush (iobuf_t a)
1924 : {
1925 : size_t len;
1926 : int rc;
1927 :
1928 6326 : if (a->use == IOBUF_OUTPUT_TEMP)
1929 : { /* increase the temp buffer */
1930 47 : size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
1931 :
1932 47 : if (DBG_IOBUF)
1933 0 : log_debug ("increasing temp iobuf from %lu to %lu\n",
1934 : (ulong) a->d.size, (ulong) newsize);
1935 :
1936 47 : a->d.buf = xrealloc (a->d.buf, newsize);
1937 47 : a->d.size = newsize;
1938 47 : return 0;
1939 : }
1940 6279 : else if (a->use != IOBUF_OUTPUT)
1941 0 : log_bug ("flush on non-output iobuf\n");
1942 6279 : else if (!a->filter)
1943 0 : log_bug ("filter_flush: no filter\n");
1944 6279 : len = a->d.len;
1945 6279 : rc = a->filter (a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len);
1946 6279 : if (!rc && len != a->d.len)
1947 : {
1948 0 : log_info ("filter_flush did not write all!\n");
1949 0 : rc = GPG_ERR_INTERNAL;
1950 : }
1951 6279 : else if (rc)
1952 0 : a->error = rc;
1953 6279 : a->d.len = 0;
1954 :
1955 6279 : return rc;
1956 : }
1957 :
1958 :
1959 : int
1960 8133 : iobuf_readbyte (iobuf_t a)
1961 : {
1962 : int c;
1963 :
1964 8133 : if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
1965 : {
1966 0 : log_bug ("iobuf_readbyte called on a non-INPUT pipeline!\n");
1967 : return -1;
1968 : }
1969 :
1970 8133 : assert (a->d.start <= a->d.len);
1971 :
1972 8133 : if (a->nlimit && a->nbytes >= a->nlimit)
1973 0 : return -1; /* forced EOF */
1974 :
1975 8133 : if (a->d.start < a->d.len)
1976 : {
1977 854 : c = a->d.buf[a->d.start++];
1978 : }
1979 7279 : else if ((c = underflow (a, 1)) == -1)
1980 4736 : return -1; /* EOF */
1981 :
1982 3397 : assert (a->d.start <= a->d.len);
1983 :
1984 : /* Note: if underflow doesn't return EOF, then it returns the first
1985 : byte that was read and advances a->d.start appropriately. */
1986 :
1987 3397 : a->nbytes++;
1988 3397 : return c;
1989 : }
1990 :
1991 :
1992 : int
1993 25487 : iobuf_read (iobuf_t a, void *buffer, unsigned int buflen)
1994 : {
1995 25487 : unsigned char *buf = (unsigned char *)buffer;
1996 : int c, n;
1997 :
1998 25487 : if (a->use == IOBUF_OUTPUT || a->use == IOBUF_OUTPUT_TEMP)
1999 : {
2000 0 : log_bug ("iobuf_read called on a non-INPUT pipeline!\n");
2001 : return -1;
2002 : }
2003 :
2004 25487 : if (a->nlimit)
2005 : {
2006 : /* Handle special cases. */
2007 0 : for (n = 0; n < buflen; n++)
2008 : {
2009 0 : if ((c = iobuf_readbyte (a)) == -1)
2010 : {
2011 0 : if (!n)
2012 0 : return -1; /* eof */
2013 0 : break;
2014 : }
2015 :
2016 0 : if (buf)
2017 : {
2018 0 : *buf = c;
2019 0 : buf++;
2020 : }
2021 : }
2022 0 : return n;
2023 : }
2024 :
2025 25487 : n = 0;
2026 : do
2027 : {
2028 553629 : if (n < buflen && a->d.start < a->d.len)
2029 : /* Drain the buffer. */
2030 : {
2031 551870 : unsigned size = a->d.len - a->d.start;
2032 551870 : if (size > buflen - n)
2033 22750 : size = buflen - n;
2034 551870 : if (buf)
2035 27572 : memcpy (buf, a->d.buf + a->d.start, size);
2036 551870 : n += size;
2037 551870 : a->d.start += size;
2038 551870 : if (buf)
2039 27572 : buf += size;
2040 : }
2041 553629 : if (n < buflen)
2042 : /* Draining the internal buffer didn't fill BUFFER. Call
2043 : underflow to read more data into the filter's internal
2044 : buffer. */
2045 : {
2046 529802 : if ((c = underflow (a, 1)) == -1)
2047 : /* EOF. If we managed to read something, don't return EOF
2048 : now. */
2049 : {
2050 1659 : a->nbytes += n;
2051 1659 : return n ? n : -1 /*EOF*/;
2052 : }
2053 528143 : if (buf)
2054 3854 : *buf++ = c;
2055 528143 : n++;
2056 : }
2057 : }
2058 551970 : while (n < buflen);
2059 23828 : a->nbytes += n;
2060 23828 : return n;
2061 : }
2062 :
2063 :
2064 :
2065 : int
2066 588 : iobuf_peek (iobuf_t a, byte * buf, unsigned buflen)
2067 : {
2068 588 : int n = 0;
2069 :
2070 588 : assert (buflen > 0);
2071 588 : assert (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP);
2072 :
2073 588 : if (buflen > a->d.size)
2074 : /* We can't peek more than we can buffer. */
2075 0 : buflen = a->d.size;
2076 :
2077 : /* Try to fill the internal buffer with enough data to satisfy the
2078 : request. */
2079 1764 : while (buflen > a->d.len - a->d.start)
2080 : {
2081 588 : if (underflow (a, 0) == -1)
2082 : /* EOF. We can't read any more. */
2083 0 : break;
2084 :
2085 : /* Underflow consumes the first character (it's the return
2086 : value). unget() it by resetting the "file position". */
2087 588 : assert (a->d.start == 1);
2088 588 : a->d.start = 0;
2089 : }
2090 :
2091 588 : n = a->d.len - a->d.start;
2092 588 : if (n > buflen)
2093 588 : n = buflen;
2094 :
2095 588 : if (n == 0)
2096 : /* EOF. */
2097 0 : return -1;
2098 :
2099 588 : memcpy (buf, &a->d.buf[a->d.start], n);
2100 :
2101 588 : return n;
2102 : }
2103 :
2104 :
2105 :
2106 :
2107 : int
2108 706769 : iobuf_writebyte (iobuf_t a, unsigned int c)
2109 : {
2110 : int rc;
2111 :
2112 706769 : if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2113 : {
2114 0 : log_bug ("iobuf_writebyte called on an input pipeline!\n");
2115 : return -1;
2116 : }
2117 :
2118 706769 : if (a->d.len == a->d.size)
2119 76 : if ((rc=filter_flush (a)))
2120 0 : return rc;
2121 :
2122 706769 : assert (a->d.len < a->d.size);
2123 706769 : a->d.buf[a->d.len++] = c;
2124 706769 : return 0;
2125 : }
2126 :
2127 :
2128 : int
2129 32936 : iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen)
2130 : {
2131 32936 : const unsigned char *buf = (const unsigned char *)buffer;
2132 : int rc;
2133 :
2134 32936 : if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2135 : {
2136 0 : log_bug ("iobuf_write called on an input pipeline!\n");
2137 : return -1;
2138 : }
2139 :
2140 : do
2141 : {
2142 35534 : if (buflen && a->d.len < a->d.size)
2143 : {
2144 34492 : unsigned size = a->d.size - a->d.len;
2145 34492 : if (size > buflen)
2146 31893 : size = buflen;
2147 34492 : memcpy (a->d.buf + a->d.len, buf, size);
2148 34492 : buflen -= size;
2149 34492 : buf += size;
2150 34492 : a->d.len += size;
2151 : }
2152 35534 : if (buflen)
2153 : {
2154 2598 : rc = filter_flush (a);
2155 2598 : if (rc)
2156 0 : return rc;
2157 : }
2158 : }
2159 35534 : while (buflen);
2160 32936 : return 0;
2161 : }
2162 :
2163 :
2164 : int
2165 11232 : iobuf_writestr (iobuf_t a, const char *buf)
2166 : {
2167 11232 : if (a->use == IOBUF_INPUT || a->use == IOBUF_INPUT_TEMP)
2168 : {
2169 0 : log_bug ("iobuf_writestr called on an input pipeline!\n");
2170 : return -1;
2171 : }
2172 :
2173 11232 : return iobuf_write (a, buf, strlen (buf));
2174 : }
2175 :
2176 :
2177 :
2178 : int
2179 1034 : iobuf_write_temp (iobuf_t dest, iobuf_t source)
2180 : {
2181 1034 : assert (source->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2182 1034 : assert (dest->use == IOBUF_OUTPUT || dest->use == IOBUF_OUTPUT_TEMP);
2183 :
2184 1034 : iobuf_flush_temp (source);
2185 1034 : return iobuf_write (dest, source->d.buf, source->d.len);
2186 : }
2187 :
2188 : size_t
2189 47 : iobuf_temp_to_buffer (iobuf_t a, byte * buffer, size_t buflen)
2190 : {
2191 : size_t n;
2192 :
2193 : while (1)
2194 : {
2195 47 : int rc = filter_flush (a);
2196 47 : if (rc)
2197 0 : log_bug ("Flushing iobuf %d.%d (%s) from iobuf_temp_to_buffer failed. Ignoring.\n",
2198 : a->no, a->subno, iobuf_desc (a));
2199 47 : if (! a->chain)
2200 46 : break;
2201 1 : a = a->chain;
2202 1 : }
2203 :
2204 46 : n = a->d.len;
2205 46 : if (n > buflen)
2206 0 : n = buflen;
2207 46 : memcpy (buffer, a->d.buf, n);
2208 46 : return n;
2209 : }
2210 :
2211 : /* Copies the data from the input iobuf SOURCE to the output iobuf
2212 : DEST until either an error is encountered or EOF is reached.
2213 : Returns the number of bytes copies. */
2214 : size_t
2215 0 : iobuf_copy (iobuf_t dest, iobuf_t source)
2216 : {
2217 : char *temp;
2218 : /* Use a 1 MB buffer. */
2219 0 : const size_t temp_size = 1024 * 1024;
2220 :
2221 : size_t nread;
2222 0 : size_t nwrote = 0;
2223 : int err;
2224 :
2225 0 : assert (source->use == IOBUF_INPUT || source->use == IOBUF_INPUT_TEMP);
2226 0 : assert (dest->use == IOBUF_OUTPUT || source->use == IOBUF_OUTPUT_TEMP);
2227 :
2228 0 : temp = xmalloc (temp_size);
2229 : while (1)
2230 : {
2231 0 : nread = iobuf_read (source, temp, temp_size);
2232 0 : if (nread == -1)
2233 : /* EOF. */
2234 0 : break;
2235 :
2236 0 : err = iobuf_write (dest, temp, nread);
2237 0 : if (err)
2238 0 : break;
2239 0 : nwrote += nread;
2240 0 : }
2241 0 : xfree (temp);
2242 :
2243 0 : return nwrote;
2244 : }
2245 :
2246 :
2247 : void
2248 1034 : iobuf_flush_temp (iobuf_t temp)
2249 : {
2250 1034 : if (temp->use == IOBUF_INPUT || temp->use == IOBUF_INPUT_TEMP)
2251 0 : log_bug ("iobuf_writestr called on an input pipeline!\n");
2252 2068 : while (temp->chain)
2253 0 : pop_filter (temp, temp->filter, NULL);
2254 1034 : }
2255 :
2256 :
2257 : void
2258 0 : iobuf_set_limit (iobuf_t a, off_t nlimit)
2259 : {
2260 0 : if (nlimit)
2261 0 : a->nofast = 1;
2262 : else
2263 0 : a->nofast = 0;
2264 0 : a->nlimit = nlimit;
2265 0 : a->ntotal += a->nbytes;
2266 0 : a->nbytes = 0;
2267 0 : }
2268 :
2269 :
2270 :
2271 : off_t
2272 860 : iobuf_get_filelength (iobuf_t a, int *overflow)
2273 : {
2274 : struct stat st;
2275 :
2276 860 : if (overflow)
2277 860 : *overflow = 0;
2278 :
2279 : /* Hmmm: file_filter may have already been removed */
2280 860 : for ( ; a->chain; a = a->chain )
2281 : ;
2282 :
2283 860 : if (a->filter != file_filter)
2284 0 : return 0;
2285 :
2286 : {
2287 860 : file_filter_ctx_t *b = a->filter_ov;
2288 860 : gnupg_fd_t fp = b->fp;
2289 :
2290 : #if defined(HAVE_W32_SYSTEM)
2291 : ulong size;
2292 : static int (* __stdcall get_file_size_ex) (void *handle,
2293 : LARGE_INTEGER *r_size);
2294 : static int get_file_size_ex_initialized;
2295 :
2296 : if (!get_file_size_ex_initialized)
2297 : {
2298 : void *handle;
2299 :
2300 : handle = dlopen ("kernel32.dll", RTLD_LAZY);
2301 : if (handle)
2302 : {
2303 : get_file_size_ex = dlsym (handle, "GetFileSizeEx");
2304 : if (!get_file_size_ex)
2305 : dlclose (handle);
2306 : }
2307 : get_file_size_ex_initialized = 1;
2308 : }
2309 :
2310 : if (get_file_size_ex)
2311 : {
2312 : /* This is a newer system with GetFileSizeEx; we use this
2313 : then because it seem that GetFileSize won't return a
2314 : proper error in case a file is larger than 4GB. */
2315 : LARGE_INTEGER exsize;
2316 :
2317 : if (get_file_size_ex (fp, &exsize))
2318 : {
2319 : if (!exsize.u.HighPart)
2320 : return exsize.u.LowPart;
2321 : if (overflow)
2322 : *overflow = 1;
2323 : return 0;
2324 : }
2325 : }
2326 : else
2327 : {
2328 : if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
2329 : return size;
2330 : }
2331 : log_error ("GetFileSize for handle %p failed: %s\n",
2332 : fp, w32_strerror (0));
2333 : #else
2334 860 : if ( !fstat (FD2INT (fp), &st) )
2335 860 : return st.st_size;
2336 0 : log_error("fstat() failed: %s\n", strerror(errno) );
2337 : #endif
2338 : }
2339 :
2340 0 : return 0;
2341 : }
2342 :
2343 :
2344 : int
2345 1178 : iobuf_get_fd (iobuf_t a)
2346 : {
2347 1178 : for (; a->chain; a = a->chain)
2348 : ;
2349 :
2350 1178 : if (a->filter != file_filter)
2351 0 : return -1;
2352 :
2353 : {
2354 1178 : file_filter_ctx_t *b = a->filter_ov;
2355 1178 : gnupg_fd_t fp = b->fp;
2356 :
2357 1178 : return FD2INT (fp);
2358 : }
2359 : }
2360 :
2361 :
2362 : off_t
2363 6 : iobuf_tell (iobuf_t a)
2364 : {
2365 6 : return a->ntotal + a->nbytes;
2366 : }
2367 :
2368 :
2369 : #if !defined(HAVE_FSEEKO) && !defined(fseeko)
2370 :
2371 : #ifdef HAVE_LIMITS_H
2372 : # include <limits.h>
2373 : #endif
2374 : #ifndef LONG_MAX
2375 : # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
2376 : #endif
2377 : #ifndef LONG_MIN
2378 : # define LONG_MIN (-1 - LONG_MAX)
2379 : #endif
2380 :
2381 : /****************
2382 : * A substitute for fseeko, for hosts that don't have it.
2383 : */
2384 : static int
2385 : fseeko (FILE * stream, off_t newpos, int whence)
2386 : {
2387 : while (newpos != (long) newpos)
2388 : {
2389 : long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
2390 : if (fseek (stream, pos, whence) != 0)
2391 : return -1;
2392 : newpos -= pos;
2393 : whence = SEEK_CUR;
2394 : }
2395 : return fseek (stream, (long) newpos, whence);
2396 : }
2397 : #endif
2398 :
2399 : int
2400 0 : iobuf_seek (iobuf_t a, off_t newpos)
2401 : {
2402 0 : file_filter_ctx_t *b = NULL;
2403 :
2404 0 : if (a->use == IOBUF_OUTPUT || a->use == IOBUF_INPUT)
2405 : {
2406 : /* Find the last filter in the pipeline. */
2407 0 : for (; a->chain; a = a->chain)
2408 : ;
2409 :
2410 0 : if (a->filter != file_filter)
2411 0 : return -1;
2412 :
2413 0 : b = a->filter_ov;
2414 :
2415 : #ifdef HAVE_W32_SYSTEM
2416 : if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff)
2417 : {
2418 : log_error ("SetFilePointer failed on handle %p: ec=%d\n",
2419 : b->fp, (int) GetLastError ());
2420 : return -1;
2421 : }
2422 : #else
2423 0 : if (lseek (b->fp, newpos, SEEK_SET) == (off_t) - 1)
2424 : {
2425 0 : log_error ("can't lseek: %s\n", strerror (errno));
2426 0 : return -1;
2427 : }
2428 : #endif
2429 : /* Discard the buffer it is not a temp stream. */
2430 0 : a->d.len = 0;
2431 : }
2432 0 : a->d.start = 0;
2433 0 : a->nbytes = 0;
2434 0 : a->nlimit = 0;
2435 0 : a->nofast = 0;
2436 0 : a->ntotal = newpos;
2437 0 : a->error = 0;
2438 :
2439 : /* It is impossible for A->CHAIN to be non-NULL. If A is an INPUT
2440 : or OUTPUT buffer, then we find the last filter, which is defined
2441 : as A->CHAIN being NULL. If A is a TEMP filter, then A must be
2442 : the only filter in the pipe: when iobuf_push_filter adds a filter
2443 : to the front of a pipeline, it sets the new filter to be an
2444 : OUTPUT filter if the pipeline is an OUTPUT or TEMP pipeline and
2445 : to be an INPUT filter if the pipeline is an INPUT pipeline.
2446 : Thus, only the last filter in a TEMP pipeline can be a */
2447 :
2448 : /* remove filters, but the last */
2449 0 : if (a->chain)
2450 0 : log_debug ("pop_filter called in iobuf_seek - please report\n");
2451 0 : while (a->chain)
2452 0 : pop_filter (a, a->filter, NULL);
2453 :
2454 0 : return 0;
2455 : }
2456 :
2457 :
2458 : const char *
2459 526 : iobuf_get_real_fname (iobuf_t a)
2460 : {
2461 526 : if (a->real_fname)
2462 512 : return a->real_fname;
2463 :
2464 : /* the old solution */
2465 53 : for (; a; a = a->chain)
2466 53 : if (!a->chain && a->filter == file_filter)
2467 : {
2468 14 : file_filter_ctx_t *b = a->filter_ov;
2469 14 : return b->print_only_name ? NULL : b->fname;
2470 : }
2471 :
2472 0 : return NULL;
2473 : }
2474 :
2475 : const char *
2476 0 : iobuf_get_fname (iobuf_t a)
2477 : {
2478 0 : for (; a; a = a->chain)
2479 0 : if (!a->chain && a->filter == file_filter)
2480 : {
2481 0 : file_filter_ctx_t *b = a->filter_ov;
2482 0 : return b->fname;
2483 : }
2484 0 : return NULL;
2485 : }
2486 :
2487 : const char *
2488 0 : iobuf_get_fname_nonnull (iobuf_t a)
2489 : {
2490 : const char *fname;
2491 :
2492 0 : fname = iobuf_get_fname (a);
2493 0 : return fname? fname : "[?]";
2494 : }
2495 :
2496 :
2497 : /****************
2498 : * enable partial block mode as described in the OpenPGP draft.
2499 : * LEN is the first length byte on read, but ignored on writes.
2500 : */
2501 : void
2502 809 : iobuf_set_partial_block_mode (iobuf_t a, size_t len)
2503 : {
2504 809 : block_filter_ctx_t *ctx = xcalloc (1, sizeof *ctx);
2505 :
2506 809 : ctx->use = a->use;
2507 809 : if (!len)
2508 : {
2509 28 : if (a->use == IOBUF_INPUT)
2510 0 : log_debug ("pop_filter called in set_partial_block_mode"
2511 : " - please report\n");
2512 : /* XXX: This pop_filter doesn't make sense. Since we haven't
2513 : actually added the filter to the pipeline yet, why are we
2514 : popping anything? Moreover, since we don't report an error,
2515 : the caller won't directly see an error. I think that it
2516 : would be better to push the filter and set a->error to
2517 : GPG_ERR_BAD_DATA, but Werner thinks it's impossible for len
2518 : to be 0 (but he doesn't want to remove the check just in
2519 : case). */
2520 28 : pop_filter (a, block_filter, NULL);
2521 : }
2522 : else
2523 : {
2524 781 : ctx->partial = 1;
2525 781 : ctx->size = 0;
2526 781 : ctx->first_c = len;
2527 781 : iobuf_push_filter (a, block_filter, ctx);
2528 : }
2529 809 : }
2530 :
2531 :
2532 :
2533 : unsigned int
2534 28997 : iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
2535 : unsigned *length_of_buffer, unsigned *max_length)
2536 : {
2537 : int c;
2538 28997 : char *buffer = (char *)*addr_of_buffer;
2539 28997 : unsigned length = *length_of_buffer;
2540 28997 : unsigned nbytes = 0;
2541 28997 : unsigned maxlen = *max_length;
2542 : char *p;
2543 :
2544 : /* The code assumes that we have space for at least a newline and a
2545 : NUL character in the buffer. This requires at least 2 bytes. We
2546 : don't complicate the code by handling the stupid corner case, but
2547 : simply assert that it can't happen. */
2548 28997 : assert (length >= 2 || maxlen >= 2);
2549 :
2550 28997 : if (!buffer || length <= 1)
2551 : /* must allocate a new buffer */
2552 : {
2553 146 : length = 256 <= maxlen ? 256 : maxlen;
2554 146 : buffer = xrealloc (buffer, length);
2555 146 : *addr_of_buffer = (unsigned char *)buffer;
2556 146 : *length_of_buffer = length;
2557 : }
2558 :
2559 28997 : p = buffer;
2560 1579344 : while ((c = iobuf_get (a)) != -1)
2561 : {
2562 1550067 : *p++ = c;
2563 1550067 : nbytes++;
2564 1550067 : if (c == '\n')
2565 28715 : break;
2566 :
2567 1521352 : if (nbytes == length - 1)
2568 : /* We don't have enough space to add a \n and a \0. Increase
2569 : the buffer size. */
2570 : {
2571 4 : if (length == maxlen)
2572 : /* We reached the buffer's size limit! */
2573 : {
2574 : /* Skip the rest of the line. */
2575 2 : while (c != '\n' && (c = iobuf_get (a)) != -1)
2576 : ;
2577 :
2578 : /* p is pointing at the last byte in the buffer. We
2579 : always terminate the line with "\n\0" so overwrite
2580 : the previous byte with a \n. */
2581 2 : assert (p > buffer);
2582 2 : p[-1] = '\n';
2583 :
2584 : /* Indicate truncation. */
2585 2 : *max_length = 0;
2586 2 : break;
2587 : }
2588 :
2589 2 : length += length < 1024 ? 256 : 1024;
2590 2 : if (length > maxlen)
2591 1 : length = maxlen;
2592 :
2593 2 : buffer = xrealloc (buffer, length);
2594 2 : *addr_of_buffer = (unsigned char *)buffer;
2595 2 : *length_of_buffer = length;
2596 2 : p = buffer + nbytes;
2597 : }
2598 : }
2599 : /* Add the terminating NUL. */
2600 28997 : *p = 0;
2601 :
2602 : /* Return the number of characters written to the buffer including
2603 : the newline, but not including the terminating NUL. */
2604 28997 : return nbytes;
2605 : }
2606 :
2607 : static int
2608 0 : translate_file_handle (int fd, int for_write)
2609 : {
2610 : #if defined(HAVE_W32CE_SYSTEM)
2611 : /* This is called only with one of the special filenames. Under
2612 : W32CE the FD here is not a file descriptor but a rendezvous id,
2613 : thus we need to finish the pipe first. */
2614 : fd = _assuan_w32ce_finish_pipe (fd, for_write);
2615 : #elif defined(HAVE_W32_SYSTEM)
2616 : {
2617 : int x;
2618 :
2619 : (void)for_write;
2620 :
2621 : if (fd == 0)
2622 : x = (int) GetStdHandle (STD_INPUT_HANDLE);
2623 : else if (fd == 1)
2624 : x = (int) GetStdHandle (STD_OUTPUT_HANDLE);
2625 : else if (fd == 2)
2626 : x = (int) GetStdHandle (STD_ERROR_HANDLE);
2627 : else
2628 : x = fd;
2629 :
2630 : if (x == -1)
2631 : log_debug ("GetStdHandle(%d) failed: ec=%d\n",
2632 : fd, (int) GetLastError ());
2633 :
2634 : fd = x;
2635 : }
2636 : #else
2637 : (void)for_write;
2638 : #endif
2639 0 : return fd;
2640 : }
2641 :
2642 :
2643 : void
2644 12018 : iobuf_skip_rest (iobuf_t a, unsigned long n, int partial)
2645 : {
2646 12018 : if ( partial )
2647 : {
2648 : for (;;)
2649 : {
2650 0 : if (a->nofast || a->d.start >= a->d.len)
2651 : {
2652 0 : if (iobuf_readbyte (a) == -1)
2653 : {
2654 0 : break;
2655 : }
2656 : }
2657 : else
2658 : {
2659 0 : unsigned long count = a->d.len - a->d.start;
2660 0 : a->nbytes += count;
2661 0 : a->d.start = a->d.len;
2662 : }
2663 0 : }
2664 : }
2665 : else
2666 : {
2667 12018 : unsigned long remaining = n;
2668 24037 : while (remaining > 0)
2669 : {
2670 2 : if (a->nofast || a->d.start >= a->d.len)
2671 : {
2672 1 : if (iobuf_readbyte (a) == -1)
2673 : {
2674 1 : break;
2675 : }
2676 0 : --remaining;
2677 : }
2678 : else
2679 : {
2680 1 : unsigned long count = a->d.len - a->d.start;
2681 1 : if (count > remaining)
2682 : {
2683 0 : count = remaining;
2684 : }
2685 1 : a->nbytes += count;
2686 1 : a->d.start += count;
2687 1 : remaining -= count;
2688 : }
2689 : }
2690 : }
2691 12018 : }
|