Line data Source code
1 : /* plaintext.c - process plaintext packets
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 : * 2006, 2009, 2010 Free Software Foundation, Inc.
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <errno.h>
26 : #include <assert.h>
27 : #include <sys/types.h>
28 : #ifdef HAVE_DOSISH_SYSTEM
29 : # include <fcntl.h> /* for setmode() */
30 : #endif
31 :
32 : #include "gpg.h"
33 : #include "util.h"
34 : #include "options.h"
35 : #include "packet.h"
36 : #include "ttyio.h"
37 : #include "filter.h"
38 : #include "main.h"
39 : #include "status.h"
40 : #include "i18n.h"
41 :
42 :
43 : /* Get the output filename. On success, the actual filename that is
44 : used is set in *FNAMEP and a filepointer is returned in *FP.
45 :
46 : EMBEDDED_NAME AND EMBEDDED_NAMELEN are normally stored in a
47 : plaintext packet. EMBEDDED_NAMELEN should not include any NUL
48 : terminator (EMBEDDED_NAME does not need to be NUL terminated).
49 :
50 : DATA is the iobuf containing the input data. We just use it to get
51 : the input file's filename.
52 :
53 : On success, the caller is responsible for calling xfree on *FNAMEP
54 : and calling es_close on *FPP. */
55 : gpg_error_t
56 529 : get_output_file (const byte *embedded_name, int embedded_namelen,
57 : iobuf_t data, char **fnamep, estream_t *fpp)
58 : {
59 529 : gpg_error_t err = 0;
60 529 : char *fname = NULL;
61 529 : estream_t fp = NULL;
62 529 : int nooutput = 0;
63 :
64 : /* Create the filename as C string. */
65 529 : if (opt.outfp)
66 : {
67 0 : fname = xtrystrdup ("[FP]");
68 0 : if (!fname)
69 : {
70 0 : err = gpg_error_from_syserror ();
71 0 : goto leave;
72 : }
73 : }
74 529 : else if (opt.outfile)
75 : {
76 515 : fname = xtrystrdup (opt.outfile);
77 515 : if (!fname)
78 : {
79 0 : err = gpg_error_from_syserror ();
80 0 : goto leave;
81 : }
82 : }
83 14 : else if (embedded_namelen == 8 && !memcmp (embedded_name, "_CONSOLE", 8))
84 : {
85 0 : log_info (_("data not saved; use option \"--output\" to save it\n"));
86 0 : nooutput = 1;
87 : }
88 14 : else if (!opt.flags.use_embedded_filename)
89 : {
90 14 : if (data)
91 14 : fname = make_outfile_name (iobuf_get_real_fname (data));
92 14 : if (!fname)
93 0 : fname = ask_outfile_name (embedded_name, embedded_namelen);
94 14 : if (!fname)
95 : {
96 0 : err = gpg_error (GPG_ERR_GENERAL); /* Can't create file. */
97 0 : goto leave;
98 : }
99 : }
100 : else
101 0 : fname = utf8_to_native (embedded_name, embedded_namelen, 0);
102 :
103 529 : if (nooutput)
104 : ;
105 529 : else if (opt.outfp)
106 : {
107 0 : fp = opt.outfp;
108 0 : es_set_binary (fp);
109 : }
110 529 : else if (iobuf_is_pipe_filename (fname) || !*fname)
111 : {
112 : /* No filename or "-" given; write to stdout. */
113 15 : fp = es_stdout;
114 15 : es_set_binary (fp);
115 : }
116 : else
117 : {
118 1028 : while (!overwrite_filep (fname))
119 : {
120 0 : char *tmp = ask_outfile_name (NULL, 0);
121 0 : if (!tmp || !*tmp)
122 : {
123 0 : xfree (tmp);
124 : /* FIXME: Below used to be GPG_ERR_CREATE_FILE */
125 0 : err = gpg_error (GPG_ERR_GENERAL);
126 0 : goto leave;
127 : }
128 0 : xfree (fname);
129 0 : fname = tmp;
130 : }
131 : }
132 :
133 : #ifndef __riscos__
134 529 : if (opt.outfp && is_secured_file (es_fileno (opt.outfp)))
135 : {
136 0 : err = gpg_error (GPG_ERR_EPERM);
137 0 : log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
138 0 : goto leave;
139 : }
140 529 : else if (fp || nooutput)
141 : ;
142 514 : else if (is_secured_filename (fname))
143 : {
144 0 : gpg_err_set_errno (EPERM);
145 0 : err = gpg_error_from_syserror ();
146 0 : log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
147 0 : goto leave;
148 : }
149 514 : else if (!(fp = es_fopen (fname, "wb")))
150 : {
151 0 : err = gpg_error_from_syserror ();
152 0 : log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
153 0 : goto leave;
154 : }
155 : #else /* __riscos__ */
156 : /* If no output filename was given, i.e. we constructed it, convert
157 : all '.' in fname to '/' but not vice versa as we don't create
158 : directories! */
159 : if (!opt.outfile)
160 : for (c = 0; fname[c]; ++c)
161 : if (fname[c] == '.')
162 : fname[c] = '/';
163 :
164 : if (fp || nooutput)
165 : ;
166 : else
167 : {
168 : /* Note: riscos stuff is not expected to wrok anymore. If we
169 : want to port it again to riscos we should do most of the suff
170 : in estream. FIXME: Consider to remove all riscos special
171 : cases. */
172 : fp = fopen (fname, "wb");
173 : if (!fp)
174 : {
175 : log_error (_("error creating '%s': %s\n"), fname, gpg_strerror (err));
176 : err = GPG_ERR_CREATE_FILE;
177 : if (errno == 106)
178 : log_info ("Do output file and input file have the same name?\n");
179 : goto leave;
180 : }
181 :
182 : /* If there's a ,xxx extension in the embedded filename,
183 : use that, else check whether the user input (in fname)
184 : has a ,xxx appended, then use that in preference */
185 : if ((c = riscos_get_filetype_from_string (embedded_name,
186 : embedded_namelen)) != -1)
187 : filetype = c;
188 : if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
189 : filetype = c;
190 : riscos_set_filetype_by_number (fname, filetype);
191 : }
192 : #endif /* __riscos__ */
193 :
194 : leave:
195 529 : if (err)
196 : {
197 0 : if (fp && fp != es_stdout && fp != opt.outfp)
198 0 : es_fclose (fp);
199 0 : xfree (fname);
200 0 : return err;
201 : }
202 :
203 529 : *fnamep = fname;
204 529 : *fpp = fp;
205 529 : return 0;
206 : }
207 :
208 : /* Handle a plaintext packet. If MFX is not NULL, update the MDs
209 : * Note: We should have used the filter stuff here, but we have to add
210 : * some easy mimic to set a read limit, so we calculate only the bytes
211 : * from the plaintext. */
212 : int
213 571 : handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
214 : int nooutput, int clearsig)
215 : {
216 571 : char *fname = NULL;
217 571 : estream_t fp = NULL;
218 : static off_t count = 0;
219 571 : int err = 0;
220 : int c;
221 571 : int convert = (pt->mode == 't' || pt->mode == 'u');
222 : #ifdef __riscos__
223 : int filetype = 0xfff;
224 : #endif
225 :
226 : /* Let people know what the plaintext info is. This allows the
227 : receiving program to try and do something different based on the
228 : format code (say, recode UTF-8 to local). */
229 571 : if (!nooutput && is_status_enabled ())
230 : {
231 : char status[50];
232 :
233 : /* Better make sure that stdout has been flushed in case the
234 : output will be written to it. This is to make sure that no
235 : not-yet-flushed stuff will be written after the plaintext
236 : status message. */
237 0 : es_fflush (es_stdout);
238 :
239 0 : snprintf (status, sizeof status,
240 0 : "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
241 0 : write_status_text_and_buffer (STATUS_PLAINTEXT,
242 0 : status, pt->name, pt->namelen, 0);
243 :
244 0 : if (!pt->is_partial)
245 : {
246 0 : snprintf (status, sizeof status, "%lu", (ulong) pt->len);
247 0 : write_status_text (STATUS_PLAINTEXT_LENGTH, status);
248 : }
249 : }
250 :
251 571 : if (! nooutput)
252 : {
253 529 : err = get_output_file (pt->name, pt->namelen, pt->buf, &fname, &fp);
254 529 : if (err)
255 0 : goto leave;
256 : }
257 :
258 571 : if (!pt->is_partial)
259 : {
260 : /* We have an actual length (which might be zero). */
261 :
262 538 : if (clearsig)
263 : {
264 0 : log_error ("clearsig encountered while not expected\n");
265 0 : err = gpg_error (GPG_ERR_UNEXPECTED);
266 0 : goto leave;
267 : }
268 :
269 538 : if (convert) /* Text mode. */
270 : {
271 46 : for (; pt->len; pt->len--)
272 : {
273 45 : if ((c = iobuf_get (pt->buf)) == -1)
274 : {
275 0 : err = gpg_error_from_syserror ();
276 0 : log_error ("problem reading source (%u bytes remaining)\n",
277 : (unsigned) pt->len);
278 0 : goto leave;
279 : }
280 45 : if (mfx->md)
281 45 : gcry_md_putc (mfx->md, c);
282 : #ifndef HAVE_DOSISH_SYSTEM
283 45 : if (c == '\r') /* convert to native line ending */
284 0 : continue; /* fixme: this hack might be too simple */
285 : #endif
286 45 : if (fp)
287 : {
288 45 : if (opt.max_output && (++count) > opt.max_output)
289 : {
290 0 : log_error ("error writing to '%s': %s\n",
291 : fname, "exceeded --max-output limit\n");
292 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
293 0 : goto leave;
294 : }
295 45 : else if (es_putc (c, fp) == EOF)
296 : {
297 0 : if (es_ferror (fp))
298 0 : err = gpg_error_from_syserror ();
299 : else
300 0 : err = gpg_error (GPG_ERR_EOF);
301 0 : log_error ("error writing to '%s': %s\n",
302 : fname, gpg_strerror (err));
303 0 : goto leave;
304 : }
305 : }
306 : }
307 : }
308 : else /* Binary mode. */
309 : {
310 537 : byte *buffer = xmalloc (32768);
311 1699 : while (pt->len)
312 : {
313 625 : int len = pt->len > 32768 ? 32768 : pt->len;
314 625 : len = iobuf_read (pt->buf, buffer, len);
315 625 : if (len == -1)
316 : {
317 0 : err = gpg_error_from_syserror ();
318 0 : log_error ("problem reading source (%u bytes remaining)\n",
319 : (unsigned) pt->len);
320 0 : xfree (buffer);
321 0 : goto leave;
322 : }
323 625 : if (mfx->md)
324 625 : gcry_md_write (mfx->md, buffer, len);
325 625 : if (fp)
326 : {
327 598 : if (opt.max_output && (count += len) > opt.max_output)
328 : {
329 0 : log_error ("error writing to '%s': %s\n",
330 : fname, "exceeded --max-output limit\n");
331 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
332 0 : xfree (buffer);
333 0 : goto leave;
334 : }
335 598 : else if (es_fwrite (buffer, 1, len, fp) != len)
336 : {
337 0 : err = gpg_error_from_syserror ();
338 0 : log_error ("error writing to '%s': %s\n",
339 : fname, gpg_strerror (err));
340 0 : xfree (buffer);
341 0 : goto leave;
342 : }
343 : }
344 625 : pt->len -= len;
345 : }
346 537 : xfree (buffer);
347 : }
348 : }
349 33 : else if (!clearsig)
350 : {
351 19 : if (convert)
352 : { /* text mode */
353 3144 : while ((c = iobuf_get (pt->buf)) != -1)
354 : {
355 3138 : if (mfx->md)
356 3138 : gcry_md_putc (mfx->md, c);
357 : #ifndef HAVE_DOSISH_SYSTEM
358 3138 : if (convert && c == '\r')
359 72 : continue; /* fixme: this hack might be too simple */
360 : #endif
361 3066 : if (fp)
362 : {
363 2665 : if (opt.max_output && (++count) > opt.max_output)
364 : {
365 0 : log_error ("Error writing to '%s': %s\n",
366 : fname, "exceeded --max-output limit\n");
367 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
368 0 : goto leave;
369 : }
370 2665 : else if (es_putc (c, fp) == EOF)
371 : {
372 0 : if (es_ferror (fp))
373 0 : err = gpg_error_from_syserror ();
374 : else
375 0 : err = gpg_error (GPG_ERR_EOF);
376 0 : log_error ("error writing to '%s': %s\n",
377 : fname, gpg_strerror (err));
378 0 : goto leave;
379 : }
380 : }
381 : }
382 : }
383 : else
384 : { /* binary mode */
385 : byte *buffer;
386 16 : int eof_seen = 0;
387 :
388 16 : buffer = xtrymalloc (32768);
389 16 : if (!buffer)
390 : {
391 0 : err = gpg_error_from_syserror ();
392 0 : goto leave;
393 : }
394 :
395 61 : while (!eof_seen)
396 : {
397 : /* Why do we check for len < 32768:
398 : * If we won't, we would practically read 2 EOFs but
399 : * the first one has already popped the block_filter
400 : * off and therefore we don't catch the boundary.
401 : * So, always assume EOF if iobuf_read returns less bytes
402 : * then requested */
403 29 : int len = iobuf_read (pt->buf, buffer, 32768);
404 29 : if (len == -1)
405 0 : break;
406 29 : if (len < 32768)
407 16 : eof_seen = 1;
408 29 : if (mfx->md)
409 29 : gcry_md_write (mfx->md, buffer, len);
410 29 : if (fp)
411 : {
412 29 : if (opt.max_output && (count += len) > opt.max_output)
413 : {
414 0 : log_error ("error writing to '%s': %s\n",
415 : fname, "exceeded --max-output limit\n");
416 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
417 0 : xfree (buffer);
418 0 : goto leave;
419 : }
420 29 : else if (es_fwrite (buffer, 1, len, fp) != len)
421 : {
422 0 : err = gpg_error_from_syserror ();
423 0 : log_error ("error writing to '%s': %s\n",
424 : fname, gpg_strerror (err));
425 0 : xfree (buffer);
426 0 : goto leave;
427 : }
428 : }
429 : }
430 16 : xfree (buffer);
431 : }
432 19 : pt->buf = NULL;
433 : }
434 : else /* Clear text signature - don't hash the last CR,LF. */
435 : {
436 14 : int state = 0;
437 :
438 204063 : while ((c = iobuf_get (pt->buf)) != -1)
439 : {
440 204035 : if (fp)
441 : {
442 0 : if (opt.max_output && (++count) > opt.max_output)
443 : {
444 0 : log_error ("error writing to '%s': %s\n",
445 : fname, "exceeded --max-output limit\n");
446 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
447 0 : goto leave;
448 : }
449 0 : else if (es_putc (c, fp) == EOF)
450 : {
451 0 : err = gpg_error_from_syserror ();
452 0 : log_error ("error writing to '%s': %s\n",
453 : fname, gpg_strerror (err));
454 0 : goto leave;
455 : }
456 : }
457 204035 : if (!mfx->md)
458 0 : continue;
459 204035 : if (state == 2)
460 : {
461 5236 : gcry_md_putc (mfx->md, '\r');
462 5236 : gcry_md_putc (mfx->md, '\n');
463 5236 : state = 0;
464 : }
465 204035 : if (!state)
466 : {
467 204035 : if (c == '\r')
468 0 : state = 1;
469 204035 : else if (c == '\n')
470 5250 : state = 2;
471 : else
472 198785 : gcry_md_putc (mfx->md, c);
473 : }
474 0 : else if (state == 1)
475 : {
476 0 : if (c == '\n')
477 0 : state = 2;
478 : else
479 : {
480 0 : gcry_md_putc (mfx->md, '\r');
481 0 : if (c == '\r')
482 0 : state = 1;
483 : else
484 : {
485 0 : state = 0;
486 0 : gcry_md_putc (mfx->md, c);
487 : }
488 : }
489 : }
490 : }
491 14 : pt->buf = NULL;
492 : }
493 :
494 571 : if (fp && fp != es_stdout && fp != opt.outfp && es_fclose (fp))
495 : {
496 0 : err = gpg_error_from_syserror ();
497 0 : log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
498 0 : fp = NULL;
499 0 : goto leave;
500 : }
501 571 : fp = NULL;
502 :
503 : leave:
504 : /* Make sure that stdout gets flushed after the plaintext has been
505 : handled. This is for extra security as we do a flush anyway
506 : before checking the signature. */
507 571 : if (es_fflush (es_stdout))
508 : {
509 : /* We need to check the return code to detect errors like disk
510 : full for short plaintexts. See bug#1207. Checking return
511 : values is a good idea in any case. */
512 0 : if (!err)
513 0 : err = gpg_error_from_syserror ();
514 0 : log_error ("error flushing '%s': %s\n", "[stdout]",
515 : gpg_strerror (err));
516 : }
517 :
518 571 : if (fp && fp != es_stdout && fp != opt.outfp)
519 0 : es_fclose (fp);
520 571 : xfree (fname);
521 571 : return err;
522 : }
523 :
524 :
525 : static void
526 16 : do_hash (gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode)
527 : {
528 : text_filter_context_t tfx;
529 : int c;
530 :
531 16 : if (textmode)
532 : {
533 0 : memset (&tfx, 0, sizeof tfx);
534 0 : iobuf_push_filter (fp, text_filter, &tfx);
535 : }
536 16 : if (md2)
537 : { /* work around a strange behaviour in pgp2 */
538 : /* It seems that at least PGP5 converts a single CR to a CR,LF too */
539 0 : int lc = -1;
540 0 : while ((c = iobuf_get (fp)) != -1)
541 : {
542 0 : if (c == '\n' && lc == '\r')
543 0 : gcry_md_putc (md2, c);
544 0 : else if (c == '\n')
545 : {
546 0 : gcry_md_putc (md2, '\r');
547 0 : gcry_md_putc (md2, c);
548 : }
549 0 : else if (c != '\n' && lc == '\r')
550 : {
551 0 : gcry_md_putc (md2, '\n');
552 0 : gcry_md_putc (md2, c);
553 : }
554 : else
555 0 : gcry_md_putc (md2, c);
556 :
557 0 : if (md)
558 0 : gcry_md_putc (md, c);
559 0 : lc = c;
560 : }
561 : }
562 : else
563 : {
564 496872 : while ((c = iobuf_get (fp)) != -1)
565 : {
566 496840 : if (md)
567 496840 : gcry_md_putc (md, c);
568 : }
569 : }
570 16 : }
571 :
572 :
573 : /****************
574 : * Ask for the detached datafile and calculate the digest from it.
575 : * INFILE is the name of the input file.
576 : */
577 : int
578 16 : ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
579 : const char *inname, int textmode)
580 : {
581 : progress_filter_context_t *pfx;
582 16 : char *answer = NULL;
583 : IOBUF fp;
584 16 : int rc = 0;
585 :
586 16 : pfx = new_progress_context ();
587 16 : fp = open_sigfile (inname, pfx); /* Open default file. */
588 :
589 16 : if (!fp && !opt.batch)
590 : {
591 0 : int any = 0;
592 0 : tty_printf (_("Detached signature.\n"));
593 : do
594 : {
595 : char *name;
596 :
597 0 : xfree (answer);
598 : tty_enable_completion (NULL);
599 0 : name = cpr_get ("detached_signature.filename",
600 0 : _("Please enter name of data file: "));
601 : tty_disable_completion ();
602 0 : cpr_kill_prompt ();
603 0 : answer = make_filename (name, (void *) NULL);
604 0 : xfree (name);
605 :
606 0 : if (any && !*answer)
607 : {
608 0 : rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE */
609 0 : goto leave;
610 : }
611 0 : fp = iobuf_open (answer);
612 0 : if (fp && is_secured_file (iobuf_get_fd (fp)))
613 : {
614 0 : iobuf_close (fp);
615 0 : fp = NULL;
616 0 : gpg_err_set_errno (EPERM);
617 : }
618 0 : if (!fp && errno == ENOENT)
619 : {
620 0 : tty_printf ("No such file, try again or hit enter to quit.\n");
621 0 : any++;
622 : }
623 0 : else if (!fp)
624 : {
625 0 : rc = gpg_error_from_syserror ();
626 0 : log_error (_("can't open '%s': %s\n"), answer,
627 0 : strerror (errno));
628 0 : goto leave;
629 : }
630 : }
631 0 : while (!fp);
632 : }
633 :
634 16 : if (!fp)
635 : {
636 16 : if (opt.verbose)
637 0 : log_info (_("reading stdin ...\n"));
638 16 : fp = iobuf_open (NULL);
639 16 : assert (fp);
640 : }
641 16 : do_hash (md, md2, fp, textmode);
642 16 : iobuf_close (fp);
643 :
644 : leave:
645 16 : xfree (answer);
646 16 : release_progress_context (pfx);
647 16 : return rc;
648 : }
649 :
650 :
651 :
652 : /* Hash the given files and append the hash to hash contexts MD and
653 : * MD2. If FILES is NULL, stdin is hashed. */
654 : int
655 0 : hash_datafiles (gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files,
656 : const char *sigfilename, int textmode)
657 : {
658 : progress_filter_context_t *pfx;
659 : IOBUF fp;
660 : strlist_t sl;
661 :
662 0 : pfx = new_progress_context ();
663 :
664 0 : if (!files)
665 : {
666 : /* Check whether we can open the signed material. We avoid
667 : trying to open a file if run in batch mode. This assumed
668 : data file for a sig file feature is just a convenience thing
669 : for the command line and the user needs to read possible
670 : warning messages. */
671 0 : if (!opt.batch)
672 : {
673 0 : fp = open_sigfile (sigfilename, pfx);
674 0 : if (fp)
675 : {
676 0 : do_hash (md, md2, fp, textmode);
677 0 : iobuf_close (fp);
678 0 : release_progress_context (pfx);
679 0 : return 0;
680 : }
681 : }
682 0 : log_error (_("no signed data\n"));
683 0 : release_progress_context (pfx);
684 0 : return gpg_error (GPG_ERR_NO_DATA);
685 : }
686 :
687 :
688 0 : for (sl = files; sl; sl = sl->next)
689 : {
690 0 : fp = iobuf_open (sl->d);
691 0 : if (fp && is_secured_file (iobuf_get_fd (fp)))
692 : {
693 0 : iobuf_close (fp);
694 0 : fp = NULL;
695 0 : gpg_err_set_errno (EPERM);
696 : }
697 0 : if (!fp)
698 : {
699 0 : int rc = gpg_error_from_syserror ();
700 0 : log_error (_("can't open signed data '%s'\n"),
701 0 : print_fname_stdin (sl->d));
702 0 : release_progress_context (pfx);
703 0 : return rc;
704 : }
705 0 : handle_progress (pfx, fp, sl->d);
706 0 : do_hash (md, md2, fp, textmode);
707 0 : iobuf_close (fp);
708 : }
709 :
710 0 : release_progress_context (pfx);
711 0 : return 0;
712 : }
713 :
714 :
715 : /* Hash the data from file descriptor DATA_FD and append the hash to hash
716 : contexts MD and MD2. */
717 : int
718 0 : hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd,
719 : int textmode)
720 : {
721 0 : progress_filter_context_t *pfx = new_progress_context ();
722 : iobuf_t fp;
723 :
724 0 : if (is_secured_file (data_fd))
725 : {
726 0 : fp = NULL;
727 0 : gpg_err_set_errno (EPERM);
728 : }
729 : else
730 0 : fp = iobuf_fdopen_nc (data_fd, "rb");
731 :
732 0 : if (!fp)
733 : {
734 0 : int rc = gpg_error_from_syserror ();
735 0 : log_error (_("can't open signed data fd=%d: %s\n"),
736 0 : data_fd, strerror (errno));
737 0 : release_progress_context (pfx);
738 0 : return rc;
739 : }
740 :
741 0 : handle_progress (pfx, fp, NULL);
742 :
743 0 : do_hash (md, md2, fp, textmode);
744 :
745 0 : iobuf_close (fp);
746 :
747 0 : release_progress_context (pfx);
748 0 : return 0;
749 : }
750 :
751 :
752 : /* Set up a plaintext packet with the appropriate filename. If there
753 : is a --set-filename, use it (it's already UTF8). If there is a
754 : regular filename, UTF8-ize it if necessary. If there is no
755 : filenames at all, set the field empty. */
756 :
757 : PKT_plaintext *
758 510 : setup_plaintext_name (const char *filename, IOBUF iobuf)
759 : {
760 : PKT_plaintext *pt;
761 :
762 510 : if ((filename && !iobuf_is_pipe_filename (filename))
763 14 : || (opt.set_filename && !iobuf_is_pipe_filename (opt.set_filename)))
764 496 : {
765 : char *s;
766 :
767 496 : if (opt.set_filename)
768 0 : s = make_basename (opt.set_filename, iobuf_get_real_fname (iobuf));
769 496 : else if (filename && !opt.flags.utf8_filename)
770 496 : {
771 496 : char *tmp = native_to_utf8 (filename);
772 496 : s = make_basename (tmp, iobuf_get_real_fname (iobuf));
773 496 : xfree (tmp);
774 : }
775 : else
776 0 : s = make_basename (filename, iobuf_get_real_fname (iobuf));
777 :
778 496 : pt = xmalloc (sizeof *pt + strlen (s) - 1);
779 496 : pt->namelen = strlen (s);
780 496 : memcpy (pt->name, s, pt->namelen);
781 496 : xfree (s);
782 : }
783 : else
784 : {
785 : /* no filename */
786 14 : pt = xmalloc (sizeof *pt - 1);
787 14 : pt->namelen = 0;
788 : }
789 :
790 510 : return pt;
791 : }
|