1 /* plaintext.c - process plaintext packets
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 * 2006 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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 2 of the License, or
10 * (at your option) any later version.
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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
29 #include <sys/types.h>
30 #ifdef HAVE_DOSISH_SYSTEM
31 #include <fcntl.h> /* for setmode() */
46 * Handle a plaintext packet. If MFX is not NULL, update the MDs
47 * Note: we should use the filter stuff here, but we have to add some
48 * easy mimic to set a read limit, so we calculate only the
49 * bytes from the plaintext.
52 handle_plaintext( PKT_plaintext
*pt
, md_filter_context_t
*mfx
,
53 int nooutput
, int clearsig
)
60 int convert
= (pt
->mode
== 't' || pt
->mode
== 'u');
65 /* Let people know what the plaintext info is. This allows the
66 receiving program to try and do something different based on
67 the format code (say, recode UTF-8 to local). */
68 if(!nooutput
&& is_status_enabled())
72 sprintf(status
,"%X %lu ",(byte
)pt
->mode
,(ulong
)pt
->timestamp
);
73 write_status_text_and_buffer(STATUS_PLAINTEXT
,
74 status
,pt
->name
,pt
->namelen
,0);
78 sprintf(status
,"%lu",(ulong
)pt
->len
);
79 write_status_text(STATUS_PLAINTEXT_LENGTH
,status
);
83 /* create the filename as C string */
86 else if( opt
.outfile
) {
87 fname
= xmalloc( strlen( opt
.outfile
) + 1);
88 strcpy(fname
, opt
.outfile
);
90 else if( pt
->namelen
== 8 && !memcmp( pt
->name
, "_CONSOLE", 8 ) ) {
91 log_info(_("data not saved; use option \"--output\" to save it\n"));
94 else if( !opt
.flags
.use_embedded_filename
) {
95 fname
= make_outfile_name( iobuf_get_real_fname(pt
->buf
) );
97 fname
= ask_outfile_name( pt
->name
, pt
->namelen
);
99 rc
= gpg_error (GPG_ERR_GENERAL
); /* Can't create file. */
104 fname
=utf8_to_native(pt
->name
,pt
->namelen
,0);
108 else if ( iobuf_is_pipe_filename (fname
) || !*fname
)
110 /* No filename or "-" given; write to stdout. */
112 #ifdef HAVE_DOSISH_SYSTEM
113 setmode ( fileno(fp
) , O_BINARY
);
117 while( !overwrite_filep (fname
) ) {
118 char *tmp
= ask_outfile_name (NULL
, 0);
119 if ( !tmp
|| !*tmp
) {
121 rc
= gpg_error (GPG_ERR_GENERAL
); /* G10ERR_CREATE_FILE*/
132 else if (is_secured_filename (fname
))
135 rc
= gpg_error_from_syserror ();
136 log_error(_("error creating `%s': %s\n"), fname
, strerror(errno
) );
139 else if( !(fp
= fopen(fname
,"wb")) ) {
140 rc
= gpg_error_from_syserror ();
141 log_error(_("error creating `%s': %s\n"), fname
, strerror(errno
) );
144 #else /* __riscos__ */
145 /* If no output filename was given, i.e. we constructed it,
146 convert all '.' in fname to '/' but not vice versa as
147 we don't create directories! */
149 for( c
=0; fname
[c
]; ++c
)
150 if( fname
[c
] == '.' )
156 fp
= fopen(fname
,"wb");
158 log_error(_("error creating `%s': %s\n"), fname
, strerror(errno
) );
159 rc
= G10ERR_CREATE_FILE
;
161 log_info("Do output file and input file have the same name?\n");
165 /* If there's a ,xxx extension in the embedded filename,
166 use that, else check whether the user input (in fname)
167 has a ,xxx appended, then use that in preference */
168 if( (c
= riscos_get_filetype_from_string( pt
->name
,
169 pt
->namelen
)) != -1 )
171 if( (c
= riscos_get_filetype_from_string( fname
,
172 strlen(fname
) )) != -1 )
174 riscos_set_filetype_by_number(fname
, filetype
);
176 #endif /* __riscos__ */
178 if( !pt
->is_partial
) {
179 /* We have an actual length (which might be zero). */
182 log_error ("clearsig encountered while not expected\n");
183 rc
= G10ERR_UNEXPECTED
;
187 if( convert
) { /* text mode */
188 for( ; pt
->len
; pt
->len
-- ) {
189 if( (c
= iobuf_get(pt
->buf
)) == -1 ) {
190 rc
= gpg_error_from_syserror ();
191 log_error ("problem reading source (%u bytes remaining)\n",
196 gcry_md_putc (mfx
->md
, c
);
197 #ifndef HAVE_DOSISH_SYSTEM
198 if( c
== '\r' ) /* convert to native line ending */
199 continue; /* fixme: this hack might be too simple */
203 if(opt
.max_output
&& (++count
)>opt
.max_output
)
205 log_error ("error writing to `%s': %s\n",
206 fname
,"exceeded --max-output limit\n");
207 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
210 else if( putc( c
, fp
) == EOF
)
213 rc
= gpg_error_from_syserror ();
215 rc
= gpg_error (GPG_ERR_EOF
);
216 log_error ("error writing to `%s': %s\n",
217 fname
, strerror(errno
) );
223 else { /* binary mode */
224 byte
*buffer
= xmalloc( 32768 );
226 int len
= pt
->len
> 32768 ? 32768 : pt
->len
;
227 len
= iobuf_read( pt
->buf
, buffer
, len
);
229 rc
= gpg_error_from_syserror ();
230 log_error ("problem reading source (%u bytes remaining)\n",
236 gcry_md_write ( mfx
->md
, buffer
, len
);
239 if(opt
.max_output
&& (count
+=len
)>opt
.max_output
)
241 log_error ("error writing to `%s': %s\n",
242 fname
,"exceeded --max-output limit\n");
243 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
247 else if( fwrite( buffer
, 1, len
, fp
) != len
)
249 rc
= gpg_error_from_syserror ();
250 log_error ("error writing to `%s': %s\n",
251 fname
, strerror(errno
) );
261 else if( !clearsig
) {
262 if( convert
) { /* text mode */
263 while( (c
= iobuf_get(pt
->buf
)) != -1 ) {
265 gcry_md_putc (mfx
->md
, c
);
266 #ifndef HAVE_DOSISH_SYSTEM
267 if( convert
&& c
== '\r' )
268 continue; /* fixme: this hack might be too simple */
272 if(opt
.max_output
&& (++count
)>opt
.max_output
)
274 log_error("Error writing to `%s': %s\n",
275 fname
,"exceeded --max-output limit\n");
276 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
279 else if( putc( c
, fp
) == EOF
)
282 rc
= gpg_error_from_syserror ();
284 rc
= gpg_error (GPG_ERR_EOF
);
285 log_error("error writing to `%s': %s\n",
286 fname
, strerror(errno
) );
292 else { /* binary mode */
293 byte
*buffer
= xmalloc( 32768 );
295 for( eof
=0; !eof
; ) {
296 /* Why do we check for len < 32768:
297 * If we won't, we would practically read 2 EOFs but
298 * the first one has already popped the block_filter
299 * off and therefore we don't catch the boundary.
300 * So, always assume EOF if iobuf_read returns less bytes
302 int len
= iobuf_read( pt
->buf
, buffer
, 32768 );
308 gcry_md_write ( mfx
->md
, buffer
, len
);
311 if(opt
.max_output
&& (count
+=len
)>opt
.max_output
)
313 log_error("error writing to `%s': %s\n",
314 fname
,"exceeded --max-output limit\n");
315 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
319 else if( fwrite( buffer
, 1, len
, fp
) != len
) {
320 rc
= (errno
? gpg_error_from_syserror ()
321 : gpg_error (GPG_ERR_INTERNAL
));
322 log_error ("error writing to `%s': %s\n",
323 fname
, strerror(errno
) );
333 else { /* clear text signature - don't hash the last cr,lf */
336 while( (c
= iobuf_get(pt
->buf
)) != -1 ) {
339 if(opt
.max_output
&& (++count
)>opt
.max_output
)
341 log_error ("error writing to `%s': %s\n",
342 fname
,"exceeded --max-output limit\n");
343 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
346 else if( putc( c
, fp
) == EOF
)
348 rc
= (errno
? gpg_error_from_syserror ()
349 : gpg_error (GPG_ERR_INTERNAL
));
350 log_error ("error writing to `%s': %s\n",
351 fname
, strerror(errno
) );
358 gcry_md_putc (mfx
->md
, '\r' );
359 gcry_md_putc (mfx
->md
, '\n' );
368 gcry_md_putc(mfx
->md
, c
);
370 else if( state
== 1 ) {
374 gcry_md_putc(mfx
->md
, '\r' );
379 gcry_md_putc(mfx
->md
, c
);
387 if( fp
&& fp
!= stdout
&& fclose(fp
) ) {
388 rc
= (errno
? gpg_error_from_syserror ()
389 : gpg_error (GPG_ERR_INTERNAL
));
390 log_error ("error closing `%s': %s\n", fname
, strerror(errno
) );
397 if( fp
&& fp
!= stdout
)
404 do_hash( gcry_md_hd_t md
, gcry_md_hd_t md2
, IOBUF fp
, int textmode
)
406 text_filter_context_t tfx
;
410 memset( &tfx
, 0, sizeof tfx
);
411 iobuf_push_filter( fp
, text_filter
, &tfx
);
413 if( md2
) { /* work around a strange behaviour in pgp2 */
414 /* It seems that at least PGP5 converts a single CR to a CR,LF too */
416 while( (c
= iobuf_get(fp
)) != -1 ) {
417 if( c
== '\n' && lc
== '\r' )
418 gcry_md_putc (md2
, c
);
419 else if( c
== '\n' ) {
420 gcry_md_putc (md2
, '\r');
421 gcry_md_putc (md2
, c
);
423 else if( c
!= '\n' && lc
== '\r' ) {
424 gcry_md_putc (md2
, '\n');
425 gcry_md_putc (md2
, c
);
428 gcry_md_putc (md2
, c
);
431 gcry_md_putc (md
, c
);
436 while( (c
= iobuf_get(fp
)) != -1 ) {
438 gcry_md_putc (md
, c
);
445 * Ask for the detached datafile and calculate the digest from it.
446 * INFILE is the name of the input file.
449 ask_for_detached_datafile (gcry_md_hd_t md
, gcry_md_hd_t md2
,
450 const char *inname
, int textmode
)
452 progress_filter_context_t
*pfx
;
457 pfx
= new_progress_context ();
458 fp
= open_sigfile ( inname
, pfx
); /* Open default file. */
460 if( !fp
&& !opt
.batch
) {
462 tty_printf(_("Detached signature.\n"));
467 tty_enable_completion(NULL
);
468 name
= cpr_get("detached_signature.filename",
469 _("Please enter name of data file: "));
470 tty_disable_completion();
472 answer
=make_filename(name
,(void *)NULL
);
475 if( any
&& !*answer
) {
476 rc
= gpg_error (GPG_ERR_GENERAL
); /*G10ERR_READ_FILE*/
479 fp
= iobuf_open(answer
);
480 if (fp
&& is_secured_file (iobuf_get_fd (fp
)))
486 if( !fp
&& errno
== ENOENT
) {
487 tty_printf("No such file, try again or hit enter to quit.\n");
492 rc
= gpg_error_from_syserror ();
493 log_error(_("can't open `%s': %s\n"), answer
, strerror(errno
));
501 log_info(_("reading stdin ...\n"));
502 fp
= iobuf_open( NULL
);
505 do_hash( md
, md2
, fp
, textmode
);
510 release_progress_context (pfx
);
517 * Hash the given files and append the hash to hash context md.
518 * If FILES is NULL, hash stdin.
521 hash_datafiles( gcry_md_hd_t md
, gcry_md_hd_t md2
, strlist_t files
,
522 const char *sigfilename
, int textmode
)
524 progress_filter_context_t
*pfx
;
528 pfx
= new_progress_context ();
531 /* check whether we can open the signed material */
532 fp
= open_sigfile( sigfilename
, pfx
);
534 do_hash( md
, md2
, fp
, textmode
);
536 release_progress_context (pfx
);
539 log_error (_("no signed data\n"));
540 release_progress_context (pfx
);
541 return gpg_error (GPG_ERR_NO_DATA
);
545 for (sl
=files
; sl
; sl
= sl
->next
) {
546 fp
= iobuf_open( sl
->d
);
547 if (fp
&& is_secured_file (iobuf_get_fd (fp
)))
554 int rc
= gpg_error_from_syserror ();
555 log_error(_("can't open signed data `%s'\n"),
556 print_fname_stdin(sl
->d
));
557 release_progress_context (pfx
);
560 handle_progress (pfx
, fp
, sl
->d
);
561 do_hash( md
, md2
, fp
, textmode
);
565 release_progress_context (pfx
);
570 /* Hash the data from file descriptor DATA_FD and append the hash to hash
571 contexts MD and MD2. */
573 hash_datafile_by_fd ( gcry_md_hd_t md
, gcry_md_hd_t md2
, int data_fd
,
576 progress_filter_context_t
*pfx
= new_progress_context ();
579 fp
= iobuf_fdopen (data_fd
, "rb");
580 if (fp
&& is_secured_file (data_fd
))
588 int rc
= gpg_error_from_syserror ();
589 log_error ( _("can't open signed data fd=%d: %s\n"),
590 data_fd
, strerror (errno
));
591 release_progress_context (pfx
);
595 handle_progress (pfx
, fp
, NULL
);
597 do_hash ( md
, md2
, fp
, textmode
);
601 release_progress_context (pfx
);
606 /* Set up a plaintext packet with the appropriate filename. If there
607 is a --set-filename, use it (it's already UTF8). If there is a
608 regular filename, UTF8-ize it if necessary. If there is no
609 filenames at all, set the field empty. */
612 setup_plaintext_name(const char *filename
,IOBUF iobuf
)
616 if(filename
|| opt
.set_filename
)
621 s
=make_basename(opt
.set_filename
,iobuf_get_real_fname(iobuf
));
622 else if(filename
&& !opt
.flags
.utf8_filename
)
624 char *tmp
=native_to_utf8(filename
);
625 s
=make_basename(tmp
,iobuf_get_real_fname(iobuf
));
629 s
=make_basename(filename
,iobuf_get_real_fname(iobuf
));
631 pt
= xmalloc (sizeof *pt
+ strlen(s
) - 1);
632 pt
->namelen
= strlen (s
);
633 memcpy (pt
->name
, s
, pt
->namelen
);
639 pt
= xmalloc (sizeof *pt
- 1);