Better support unsigned time_t
[gnupg.git] / g10 / plaintext.c
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 /* Handle a plaintext packet.  If MFX is not NULL, update the MDs
44  * Note: We should have used the filter stuff here, but we have to add
45  * some easy mimic to set a read limit, so we calculate only the bytes
46  * from the plaintext.  */
47 int
48 handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
49                   int nooutput, int clearsig)
50 {
51   char *fname = NULL;
52   FILE *fp = NULL;
53   static off_t count = 0;
54   int rc = 0;
55   int c;
56   int convert = (pt->mode == 't' || pt->mode == 'u');
57 #ifdef __riscos__
58   int filetype = 0xfff;
59 #endif
60
61   /* Let people know what the plaintext info is. This allows the
62      receiving program to try and do something different based on the
63      format code (say, recode UTF-8 to local). */
64   if (!nooutput && is_status_enabled ())
65     {
66       char status[50];
67
68       /* Better make sure that stdout has been flushed in case the
69          output will be written to it.  This is to make sure that no
70          not-yet-flushed stuff will be written after the plaintext
71          status message.  */
72       fflush (stdout);
73
74       snprintf (status, sizeof status, 
75                 "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
76       write_status_text_and_buffer (STATUS_PLAINTEXT,
77                                     status, pt->name, pt->namelen, 0);
78       
79       if (!pt->is_partial)
80         {
81           sprintf (status, "%lu", (ulong) pt->len);
82           write_status_text (STATUS_PLAINTEXT_LENGTH, status);
83         }
84     }
85   
86   /* Create the filename as C string.  */
87   if (nooutput)
88     ;
89   else if (opt.outfp)
90     {
91       fname = xstrdup ("[FP]");
92     }
93   else if (opt.outfile)
94     {
95       fname = xstrdup (opt.outfile);
96     }
97   else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
98     {
99       log_info (_("data not saved; use option \"--output\" to save it\n"));
100       nooutput = 1;
101     }
102   else if (!opt.flags.use_embedded_filename)
103     {
104       fname = make_outfile_name (iobuf_get_real_fname (pt->buf));
105       if (!fname)
106         fname = ask_outfile_name (pt->name, pt->namelen);
107       if (!fname)
108         {
109           rc = gpg_error (GPG_ERR_GENERAL);     /* Can't create file. */
110           goto leave;
111         }
112     }
113   else
114     fname = utf8_to_native (pt->name, pt->namelen, 0);
115
116   if (nooutput)
117     ;
118   else if (opt.outfp)
119     {
120       fp = opt.outfp;
121 #ifdef HAVE_DOSISH_SYSTEM
122       setmode (fileno (fp), O_BINARY);
123 #endif
124     }
125   else if (iobuf_is_pipe_filename (fname) || !*fname)
126     {
127       /* No filename or "-" given; write to stdout. */
128       fp = stdout;
129 #ifdef HAVE_DOSISH_SYSTEM
130       setmode (fileno (fp), O_BINARY);
131 #endif
132     }
133   else
134     {
135       while (!overwrite_filep (fname))
136         {
137           char *tmp = ask_outfile_name (NULL, 0);
138           if (!tmp || !*tmp)
139             {
140               xfree (tmp);
141               /* FIXME: Below used to be G10ERR_CREATE_FILE */
142               rc = gpg_error (GPG_ERR_GENERAL); 
143               goto leave;
144             }
145           xfree (fname);
146           fname = tmp;
147         }
148     }
149   
150 #ifndef __riscos__
151   if (opt.outfp && is_secured_file (fileno (opt.outfp)))
152     {
153       rc = gpg_error (GPG_ERR_EPERM);
154       log_error (_("error creating `%s': %s\n"), fname, gpg_strerror (rc));
155       goto leave;
156     }
157   else if (fp || nooutput)
158     ;
159   else if (is_secured_filename (fname))
160     {
161       gpg_err_set_errno (EPERM);
162       rc = gpg_error_from_syserror ();
163       log_error (_("error creating `%s': %s\n"), fname, strerror (errno));
164       goto leave;
165     }
166   else if (!(fp = fopen (fname, "wb")))
167     {
168       rc = gpg_error_from_syserror ();
169       log_error (_("error creating `%s': %s\n"), fname, strerror (errno));
170       goto leave;
171     }
172 #else /* __riscos__ */
173   /* If no output filename was given, i.e. we constructed it, convert
174      all '.' in fname to '/' but not vice versa as we don't create
175      directories! */
176   if (!opt.outfile)
177     for (c = 0; fname[c]; ++c)
178       if (fname[c] == '.')
179         fname[c] = '/';
180
181   if (fp || nooutput)
182     ;
183   else
184     {
185       fp = fopen (fname, "wb");
186       if (!fp)
187         {
188           log_error (_("error creating `%s': %s\n"), fname, strerror (errno));
189           rc = G10ERR_CREATE_FILE;
190           if (errno == 106)
191             log_info ("Do output file and input file have the same name?\n");
192           goto leave;
193         }
194
195       /* If there's a ,xxx extension in the embedded filename,
196          use that, else check whether the user input (in fname)
197          has a ,xxx appended, then use that in preference */
198       if ((c = riscos_get_filetype_from_string (pt->name, pt->namelen)) != -1)
199         filetype = c;
200       if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
201         filetype = c;
202       riscos_set_filetype_by_number (fname, filetype);
203     }
204 #endif /* __riscos__ */
205
206   if (!pt->is_partial)
207     {
208       /* We have an actual length (which might be zero). */
209
210       if (clearsig)
211         {
212           log_error ("clearsig encountered while not expected\n");
213           rc = G10ERR_UNEXPECTED;
214           goto leave;
215         }
216
217       if (convert) /* Text mode.  */
218         {
219           for (; pt->len; pt->len--)
220             {
221               if ((c = iobuf_get (pt->buf)) == -1)
222                 {
223                   rc = gpg_error_from_syserror ();
224                   log_error ("problem reading source (%u bytes remaining)\n",
225                              (unsigned) pt->len);
226                   goto leave;
227                 }
228               if (mfx->md)
229                 gcry_md_putc (mfx->md, c);
230 #ifndef HAVE_DOSISH_SYSTEM
231               if (c == '\r')    /* convert to native line ending */
232                 continue;       /* fixme: this hack might be too simple */
233 #endif
234               if (fp)
235                 {
236                   if (opt.max_output && (++count) > opt.max_output)
237                     {
238                       log_error ("error writing to `%s': %s\n",
239                                  fname, "exceeded --max-output limit\n");
240                       rc = gpg_error (GPG_ERR_TOO_LARGE);
241                       goto leave;
242                     }
243                   else if (putc (c, fp) == EOF)
244                     {
245                       if (ferror (fp))
246                         rc = gpg_error_from_syserror ();
247                       else
248                         rc = gpg_error (GPG_ERR_EOF);
249                       log_error ("error writing to `%s': %s\n",
250                                  fname, strerror (errno));
251                       goto leave;
252                     }
253                 }
254             }
255         }
256       else  /* Binary mode.  */
257         {
258           byte *buffer = xmalloc (32768);
259           while (pt->len)
260             {
261               int len = pt->len > 32768 ? 32768 : pt->len;
262               len = iobuf_read (pt->buf, buffer, len);
263               if (len == -1)
264                 {
265                   rc = gpg_error_from_syserror ();
266                   log_error ("problem reading source (%u bytes remaining)\n",
267                              (unsigned) pt->len);
268                   xfree (buffer);
269                   goto leave;
270                 }
271               if (mfx->md)
272                 gcry_md_write (mfx->md, buffer, len);
273               if (fp)
274                 {
275                   if (opt.max_output && (count += len) > opt.max_output)
276                     {
277                       log_error ("error writing to `%s': %s\n",
278                                  fname, "exceeded --max-output limit\n");
279                       rc = gpg_error (GPG_ERR_TOO_LARGE);
280                       xfree (buffer);
281                       goto leave;
282                     }
283                   else if (fwrite (buffer, 1, len, fp) != len)
284                     {
285                       rc = gpg_error_from_syserror ();
286                       log_error ("error writing to `%s': %s\n",
287                                  fname, strerror (errno));
288                       xfree (buffer);
289                       goto leave;
290                     }
291                 }
292               pt->len -= len;
293             }
294           xfree (buffer);
295         }
296     }
297   else if (!clearsig)
298     {
299       if (convert)
300         {                       /* text mode */
301           while ((c = iobuf_get (pt->buf)) != -1)
302             {
303               if (mfx->md)
304                 gcry_md_putc (mfx->md, c);
305 #ifndef HAVE_DOSISH_SYSTEM
306               if (convert && c == '\r')
307                 continue;       /* fixme: this hack might be too simple */
308 #endif
309               if (fp)
310                 {
311                   if (opt.max_output && (++count) > opt.max_output)
312                     {
313                       log_error ("Error writing to `%s': %s\n",
314                                  fname, "exceeded --max-output limit\n");
315                       rc = gpg_error (GPG_ERR_TOO_LARGE);
316                       goto leave;
317                     }
318                   else if (putc (c, fp) == EOF)
319                     {
320                       if (ferror (fp))
321                         rc = gpg_error_from_syserror ();
322                       else
323                         rc = gpg_error (GPG_ERR_EOF);
324                       log_error ("error writing to `%s': %s\n",
325                                  fname, strerror (errno));
326                       goto leave;
327                     }
328                 }
329             }
330         }
331       else
332         {                       /* binary mode */
333           byte *buffer = xmalloc (32768);
334           int eof_seen = 0;
335
336           while (!eof_seen)
337             {
338               /* Why do we check for len < 32768:
339                * If we won't, we would practically read 2 EOFs but
340                * the first one has already popped the block_filter
341                * off and therefore we don't catch the boundary.
342                * So, always assume EOF if iobuf_read returns less bytes
343                * then requested */
344               int len = iobuf_read (pt->buf, buffer, 32768);
345               if (len == -1)
346                 break;
347               if (len < 32768)
348                 eof_seen = 1;
349               if (mfx->md)
350                 gcry_md_write (mfx->md, buffer, len);
351               if (fp)
352                 {
353                   if (opt.max_output && (count += len) > opt.max_output)
354                     {
355                       log_error ("error writing to `%s': %s\n",
356                                  fname, "exceeded --max-output limit\n");
357                       rc = gpg_error (GPG_ERR_TOO_LARGE);
358                       xfree (buffer);
359                       goto leave;
360                     }
361                   else if (fwrite (buffer, 1, len, fp) != len)
362                     {
363                       rc = (errno ? gpg_error_from_syserror ()
364                             : gpg_error (GPG_ERR_INTERNAL));
365                       log_error ("error writing to `%s': %s\n",
366                                  fname, strerror (errno));
367                       xfree (buffer);
368                       goto leave;
369                     }
370                 }
371             }
372           xfree (buffer);
373         }
374       pt->buf = NULL;
375     }
376   else /* Clear text signature - don't hash the last CR,LF.   */
377     { 
378       int state = 0;
379
380       while ((c = iobuf_get (pt->buf)) != -1)
381         {
382           if (fp)
383             {
384               if (opt.max_output && (++count) > opt.max_output)
385                 {
386                   log_error ("error writing to `%s': %s\n",
387                              fname, "exceeded --max-output limit\n");
388                   rc = gpg_error (GPG_ERR_TOO_LARGE);
389                   goto leave;
390                 }
391               else if (putc (c, fp) == EOF)
392                 {
393                   rc = (errno ? gpg_error_from_syserror ()
394                         : gpg_error (GPG_ERR_INTERNAL));
395                   log_error ("error writing to `%s': %s\n",
396                              fname, strerror (errno));
397                   goto leave;
398                 }
399             }
400           if (!mfx->md)
401             continue;
402           if (state == 2)
403             {
404               gcry_md_putc (mfx->md, '\r');
405               gcry_md_putc (mfx->md, '\n');
406               state = 0;
407             }
408           if (!state)
409             {
410               if (c == '\r')
411                 state = 1;
412               else if (c == '\n')
413                 state = 2;
414               else
415                 gcry_md_putc (mfx->md, c);
416             }
417           else if (state == 1)
418             {
419               if (c == '\n')
420                 state = 2;
421               else
422                 {
423                   gcry_md_putc (mfx->md, '\r');
424                   if (c == '\r')
425                     state = 1;
426                   else
427                     {
428                       state = 0;
429                       gcry_md_putc (mfx->md, c);
430                     }
431                 }
432             }
433         }
434       pt->buf = NULL;
435     }
436
437   if (fp && fp != stdout && fp != opt.outfp && fclose (fp))
438     {
439       rc = (errno ? gpg_error_from_syserror ()
440             : gpg_error (GPG_ERR_INTERNAL));
441       log_error ("error closing `%s': %s\n", fname, strerror (errno));
442       fp = NULL;
443       goto leave;
444     }
445   fp = NULL;
446
447  leave:
448   /* Make sure that stdout gets flushed after the plaintext has been
449      handled.  This is for extra security as we do a flush anyway
450      before checking the signature.  */
451   if (fflush (stdout))
452     {
453       /* We need to check the return code to detect errors like disk
454          full for short plaintexts.  See bug#1207.  Checking return
455          values is a good idea in any case.  */
456       if (!rc)
457         rc = gpg_error_from_syserror ();
458       log_error ("error flushing `%s': %s\n", "[stdout]", strerror (errno));
459     }
460
461   if (fp && fp != stdout && fp != opt.outfp)
462     fclose (fp);
463   xfree (fname);
464   return rc;
465 }
466
467
468 static void
469 do_hash (gcry_md_hd_t md, gcry_md_hd_t md2, IOBUF fp, int textmode)
470 {
471   text_filter_context_t tfx;
472   int c;
473
474   if (textmode)
475     {
476       memset (&tfx, 0, sizeof tfx);
477       iobuf_push_filter (fp, text_filter, &tfx);
478     }
479   if (md2)
480     {                           /* work around a strange behaviour in pgp2 */
481       /* It seems that at least PGP5 converts a single CR to a CR,LF too */
482       int lc = -1;
483       while ((c = iobuf_get (fp)) != -1)
484         {
485           if (c == '\n' && lc == '\r')
486             gcry_md_putc (md2, c);
487           else if (c == '\n')
488             {
489               gcry_md_putc (md2, '\r');
490               gcry_md_putc (md2, c);
491             }
492           else if (c != '\n' && lc == '\r')
493             {
494               gcry_md_putc (md2, '\n');
495               gcry_md_putc (md2, c);
496             }
497           else
498             gcry_md_putc (md2, c);
499
500           if (md)
501             gcry_md_putc (md, c);
502           lc = c;
503         }
504     }
505   else
506     {
507       while ((c = iobuf_get (fp)) != -1)
508         {
509           if (md)
510             gcry_md_putc (md, c);
511         }
512     }
513 }
514
515
516 /****************
517  * Ask for the detached datafile and calculate the digest from it.
518  * INFILE is the name of the input file.
519  */
520 int
521 ask_for_detached_datafile (gcry_md_hd_t md, gcry_md_hd_t md2,
522                            const char *inname, int textmode)
523 {
524   progress_filter_context_t *pfx;
525   char *answer = NULL;
526   IOBUF fp;
527   int rc = 0;
528
529   pfx = new_progress_context ();
530   fp = open_sigfile (inname, pfx);      /* Open default file. */
531
532   if (!fp && !opt.batch)
533     {
534       int any = 0;
535       tty_printf (_("Detached signature.\n"));
536       do
537         {
538           char *name;
539
540           xfree (answer);
541           tty_enable_completion (NULL);
542           name = cpr_get ("detached_signature.filename",
543                           _("Please enter name of data file: "));
544           tty_disable_completion ();
545           cpr_kill_prompt ();
546           answer = make_filename (name, (void *) NULL);
547           xfree (name);
548
549           if (any && !*answer)
550             {
551               rc = gpg_error (GPG_ERR_GENERAL); /*G10ERR_READ_FILE */
552               goto leave;
553             }
554           fp = iobuf_open (answer);
555           if (fp && is_secured_file (iobuf_get_fd (fp)))
556             {
557               iobuf_close (fp);
558               fp = NULL;
559               gpg_err_set_errno (EPERM);
560             }
561           if (!fp && errno == ENOENT)
562             {
563               tty_printf ("No such file, try again or hit enter to quit.\n");
564               any++;
565             }
566           else if (!fp)
567             {
568               rc = gpg_error_from_syserror ();
569               log_error (_("can't open `%s': %s\n"), answer,
570                          strerror (errno));
571               goto leave;
572             }
573         }
574       while (!fp);
575     }
576
577   if (!fp)
578     {
579       if (opt.verbose)
580         log_info (_("reading stdin ...\n"));
581       fp = iobuf_open (NULL);
582       assert (fp);
583     }
584   do_hash (md, md2, fp, textmode);
585   iobuf_close (fp);
586
587 leave:
588   xfree (answer);
589   release_progress_context (pfx);
590   return rc;
591 }
592
593
594
595 /****************
596  * Hash the given files and append the hash to hash context md.
597  * If FILES is NULL, hash stdin.
598  */
599 int
600 hash_datafiles (gcry_md_hd_t md, gcry_md_hd_t md2, strlist_t files,
601                 const char *sigfilename, int textmode)
602 {
603   progress_filter_context_t *pfx;
604   IOBUF fp;
605   strlist_t sl;
606
607   pfx = new_progress_context ();
608
609   if (!files)
610     {
611       /* check whether we can open the signed material */
612       fp = open_sigfile (sigfilename, pfx);
613       if (fp)
614         {
615           do_hash (md, md2, fp, textmode);
616           iobuf_close (fp);
617           release_progress_context (pfx);
618           return 0;
619         }
620       log_error (_("no signed data\n"));
621       release_progress_context (pfx);
622       return gpg_error (GPG_ERR_NO_DATA);
623     }
624
625
626   for (sl = files; sl; sl = sl->next)
627     {
628       fp = iobuf_open (sl->d);
629       if (fp && is_secured_file (iobuf_get_fd (fp)))
630         {
631           iobuf_close (fp);
632           fp = NULL;
633           gpg_err_set_errno (EPERM);
634         }
635       if (!fp)
636         {
637           int rc = gpg_error_from_syserror ();
638           log_error (_("can't open signed data `%s'\n"),
639                      print_fname_stdin (sl->d));
640           release_progress_context (pfx);
641           return rc;
642         }
643       handle_progress (pfx, fp, sl->d);
644       do_hash (md, md2, fp, textmode);
645       iobuf_close (fp);
646     }
647
648   release_progress_context (pfx);
649   return 0;
650 }
651
652
653 /* Hash the data from file descriptor DATA_FD and append the hash to hash
654    contexts MD and MD2.  */
655 int
656 hash_datafile_by_fd (gcry_md_hd_t md, gcry_md_hd_t md2, int data_fd,
657                      int textmode)
658 {
659   progress_filter_context_t *pfx = new_progress_context ();
660   iobuf_t fp;
661
662   if (is_secured_file (data_fd))
663     {
664       fp = NULL;
665       gpg_err_set_errno (EPERM);
666     }
667   else
668     fp = iobuf_fdopen_nc (data_fd, "rb");
669
670   if (!fp)
671     {
672       int rc = gpg_error_from_syserror ();
673       log_error (_("can't open signed data fd=%d: %s\n"),
674                  data_fd, strerror (errno));
675       release_progress_context (pfx);
676       return rc;
677     }
678
679   handle_progress (pfx, fp, NULL);
680
681   do_hash (md, md2, fp, textmode);
682
683   iobuf_close (fp);
684
685   release_progress_context (pfx);
686   return 0;
687 }
688
689
690 /* Set up a plaintext packet with the appropriate filename.  If there
691    is a --set-filename, use it (it's already UTF8).  If there is a
692    regular filename, UTF8-ize it if necessary.  If there is no
693    filenames at all, set the field empty. */
694
695 PKT_plaintext *
696 setup_plaintext_name (const char *filename, IOBUF iobuf)
697 {
698   PKT_plaintext *pt;
699
700   if ((filename && !iobuf_is_pipe_filename (filename))
701        || (opt.set_filename && !iobuf_is_pipe_filename (opt.set_filename)))
702     {
703       char *s;
704
705       if (opt.set_filename)
706         s = make_basename (opt.set_filename, iobuf_get_real_fname (iobuf));
707       else if (filename && !opt.flags.utf8_filename)
708         {
709           char *tmp = native_to_utf8 (filename);
710           s = make_basename (tmp, iobuf_get_real_fname (iobuf));
711           xfree (tmp);
712         }
713       else
714         s = make_basename (filename, iobuf_get_real_fname (iobuf));
715
716       pt = xmalloc (sizeof *pt + strlen (s) - 1);
717       pt->namelen = strlen (s);
718       memcpy (pt->name, s, pt->namelen);
719       xfree (s);
720     }
721   else
722     {
723       /* no filename */
724       pt = xmalloc (sizeof *pt - 1);
725       pt->namelen = 0;
726     }
727
728   return pt;
729 }