[svn] GnuPG - r5172 - trunk/g10
svn author wk
cvs at cvs.gnupg.org
Fri Oct 2 16:57:56 CEST 2009
Author: wk
Date: 2009-10-02 16:57:55 +0200 (Fri, 02 Oct 2009)
New Revision: 5172
Added:
trunk/g10/decrypt-data.c
Removed:
trunk/g10/encr-data.c
Modified:
trunk/g10/ChangeLog
trunk/g10/Makefile.am
trunk/g10/decrypt.c
trunk/g10/encrypt.c
trunk/g10/gpg.c
trunk/g10/main.h
trunk/g10/openfile.c
trunk/g10/options.h
trunk/g10/packet.h
trunk/g10/plaintext.c
trunk/g10/server.c
Log:
Implement the server comamnd DECRYPT.
Use int instead of gnupg_fd_t in the server.
Comment fixes.
Rename encr-data.c -> decrypt-data.c
Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/ChangeLog 2009-10-02 14:57:55 UTC (rev 5172)
@@ -1,5 +1,15 @@
2009-10-02 Werner Koch <wk at g10code.com>
+ * server.c (cmd_encrypt, cmd_decrypt): Implement.
+ * decrypt.c (decrypt_message_fd): New.
+ * options.h (struct opt): Add field OUTFP.
+ * plaintext.c (handle_plaintext): Support opt.outfp.
+
+ * encr-data.c: Rename to decrypt-data.c to reflect the action and
+ not the processed packet type.
+
+2009-10-02 Werner Koch <wk at g10code.com>
+
* encr-data.c (decode_filter_context_s): Add fields PARTIAL and
LENGTH.
(decrypt_data): Set them. Simplify premature EOF detection.
Modified: trunk/g10/Makefile.am
===================================================================
--- trunk/g10/Makefile.am 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/Makefile.am 2009-10-02 14:57:55 UTC (rev 5172)
@@ -79,13 +79,13 @@
pubkey-enc.c \
passphrase.c \
seckey-cert.c \
- encr-data.c \
+ decrypt.c \
+ decrypt-data.c \
cipher.c \
encrypt.c \
sign.c \
verify.c \
revoke.c \
- decrypt.c \
keyedit.c \
dearmor.c \
import.c \
Copied: trunk/g10/decrypt-data.c (from rev 5171, trunk/g10/encr-data.c)
===================================================================
--- trunk/g10/decrypt-data.c (rev 0)
+++ trunk/g10/decrypt-data.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -0,0 +1,446 @@
+/* decrypt-data.c - Decrypt an encrypted data packet
+ * Copyright (C) 1998, 1999, 2000, 2001, 2005,
+ * 2006, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "gpg.h"
+#include "util.h"
+#include "packet.h"
+#include "cipher.h"
+#include "options.h"
+#include "i18n.h"
+
+
+static int mdc_decode_filter ( void *opaque, int control, IOBUF a,
+ byte *buf, size_t *ret_len);
+static int decode_filter ( void *opaque, int control, IOBUF a,
+ byte *buf, size_t *ret_len);
+
+typedef struct decode_filter_context_s
+{
+ gcry_cipher_hd_t cipher_hd;
+ gcry_md_hd_t mdc_hash;
+ char defer[22];
+ int defer_filled;
+ int eof_seen;
+ int refcount;
+ int partial; /* Working on a partial length packet. */
+ size_t length; /* If !partial: Remaining bytes in the packet. */
+} *decode_filter_ctx_t;
+
+
+/* Helper to release the decode context. */
+static void
+release_dfx_context (decode_filter_ctx_t dfx)
+{
+ if (!dfx)
+ return;
+
+ assert (dfx->refcount);
+ if ( !--dfx->refcount )
+ {
+ gcry_cipher_close (dfx->cipher_hd);
+ dfx->cipher_hd = NULL;
+ gcry_md_close (dfx->mdc_hash);
+ dfx->mdc_hash = NULL;
+ xfree (dfx);
+ }
+}
+
+
+
+/****************
+ * Decrypt the data, specified by ED with the key DEK.
+ */
+int
+decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek )
+{
+ decode_filter_ctx_t dfx;
+ byte *p;
+ int rc=0, c, i;
+ byte temp[32];
+ unsigned blocksize;
+ unsigned nprefix;
+
+ dfx = xtrycalloc (1, sizeof *dfx);
+ if (!dfx)
+ return gpg_error_from_syserror ();
+ dfx->refcount = 1;
+
+ if ( opt.verbose && !dek->algo_info_printed )
+ {
+ if (!openpgp_cipher_test_algo (dek->algo))
+ log_info (_("%s encrypted data\n"),
+ openpgp_cipher_algo_name (dek->algo));
+ else
+ log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
+ dek->algo_info_printed = 1;
+ }
+ rc = openpgp_cipher_test_algo (dek->algo);
+ if (rc)
+ goto leave;
+ blocksize = openpgp_cipher_get_algo_blklen (dek->algo);
+ if ( !blocksize || blocksize > 16 )
+ log_fatal ("unsupported blocksize %u\n", blocksize );
+ nprefix = blocksize;
+ if ( ed->len && ed->len < (nprefix+2) )
+ BUG();
+
+ if ( ed->mdc_method )
+ {
+ if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 ))
+ BUG ();
+ if ( DBG_HASHING )
+ gcry_md_start_debug (dfx->mdc_hash, "checkmdc");
+ }
+
+ rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo,
+ GCRY_CIPHER_MODE_CFB,
+ (GCRY_CIPHER_SECURE
+ | ((ed->mdc_method || dek->algo >= 100)?
+ 0 : GCRY_CIPHER_ENABLE_SYNC)));
+ if (rc)
+ {
+ /* We should never get an error here cause we already checked
+ * that the algorithm is available. */
+ BUG();
+ }
+
+
+ /* log_hexdump( "thekey", dek->key, dek->keylen );*/
+ rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen);
+ if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY )
+ {
+ log_info(_("WARNING: message was encrypted with"
+ " a weak key in the symmetric cipher.\n"));
+ rc=0;
+ }
+ else if( rc )
+ {
+ log_error("key setup failed: %s\n", g10_errstr(rc) );
+ goto leave;
+ }
+
+ if (!ed->buf)
+ {
+ log_error(_("problem handling encrypted packet\n"));
+ goto leave;
+ }
+
+ gcry_cipher_setiv (dfx->cipher_hd, NULL, 0);
+
+ if ( ed->len )
+ {
+ for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- )
+ {
+ if ( (c=iobuf_get(ed->buf)) == -1 )
+ break;
+ else
+ temp[i] = c;
+ }
+ }
+ else
+ {
+ for (i=0; i < (nprefix+2); i++ )
+ if ( (c=iobuf_get(ed->buf)) == -1 )
+ break;
+ else
+ temp[i] = c;
+ }
+
+ gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0);
+ gcry_cipher_sync (dfx->cipher_hd);
+ p = temp;
+ /* log_hexdump( "prefix", temp, nprefix+2 ); */
+ if (dek->symmetric
+ && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) )
+ {
+ rc = gpg_error (GPG_ERR_BAD_KEY);
+ goto leave;
+ }
+
+ if ( dfx->mdc_hash )
+ gcry_md_write (dfx->mdc_hash, temp, nprefix+2);
+
+ dfx->refcount++;
+ dfx->partial = ed->is_partial;
+ dfx->length = ed->len;
+ if ( ed->mdc_method )
+ iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx );
+ else
+ iobuf_push_filter ( ed->buf, decode_filter, dfx );
+
+ proc_packets ( procctx, ed->buf );
+ ed->buf = NULL;
+ if (dfx->eof_seen > 1 )
+ rc = gpg_error (GPG_ERR_INV_PACKET);
+ else if ( ed->mdc_method )
+ {
+ /* We used to let parse-packet.c handle the MDC packet but this
+ turned out to be a problem with compressed packets: With old
+ style packets there is no length information available and
+ the decompressor uses an implicit end. However we can't know
+ this implicit end beforehand (:-) and thus may feed the
+ decompressor with more bytes than actually needed. It would
+ be possible to unread the extra bytes but due to our weird
+ iobuf system any unread is non reliable due to filters
+ already popped off. The easy and sane solution is to care
+ about the MDC packet only here and never pass it to the
+ packet parser. Fortunatley the OpenPGP spec requires a
+ strict format for the MDC packet so that we know that 22
+ bytes are appended. */
+ int datalen = gcry_md_get_algo_dlen (ed->mdc_method);
+
+ assert (dfx->cipher_hd);
+ assert (dfx->mdc_hash);
+ gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0);
+ gcry_md_write (dfx->mdc_hash, dfx->defer, 2);
+ gcry_md_final (dfx->mdc_hash);
+
+ if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' )
+ {
+ log_error("mdc_packet with invalid encoding\n");
+ rc = gpg_error (GPG_ERR_INV_PACKET);
+ }
+ else if (datalen != 20
+ || memcmp (gcry_md_read (dfx->mdc_hash, 0),
+ dfx->defer+2,datalen ))
+ rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
+ /* log_printhex("MDC message:", dfx->defer, 22); */
+ /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */
+ }
+
+
+ leave:
+ release_dfx_context (dfx);
+ return rc;
+}
+
+
+
+static int
+mdc_decode_filter (void *opaque, int control, IOBUF a,
+ byte *buf, size_t *ret_len)
+{
+ decode_filter_ctx_t dfx = opaque;
+ size_t n, size = *ret_len;
+ int rc = 0;
+ int c;
+
+ /* Note: We need to distinguish between a partial and a fixed length
+ packet. The first is the usual case as created by GPG. However
+ for short messages the format degrades to a fixed length packet
+ and other implementations might use fixed length as well. Only
+ looking for the EOF on fixed data works only if the encrypted
+ packet is not followed by other data. This used to be a long
+ standing bug which was fixed on 2009-10-02. */
+
+ if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
+ {
+ *ret_len = 0;
+ rc = -1;
+ }
+ else if( control == IOBUFCTRL_UNDERFLOW )
+ {
+ assert (a);
+ assert (size > 44); /* Our code requires at least this size. */
+
+ /* Get at least 22 bytes and put it ahead in the buffer. */
+ if (dfx->partial)
+ {
+ for (n=22; n < 44; n++)
+ {
+ if ( (c = iobuf_get(a)) == -1 )
+ break;
+ buf[n] = c;
+ }
+ }
+ else
+ {
+ for (n=22; n < 44 && dfx->length; n++, dfx->length--)
+ {
+ c = iobuf_get (a);
+ if (c == -1)
+ break; /* Premature EOF. */
+ buf[n] = c;
+ }
+ }
+ if (n == 44)
+ {
+ /* We have enough stuff - flush the deferred stuff. */
+ if ( !dfx->defer_filled ) /* First time. */
+ {
+ memcpy (buf, buf+22, 22);
+ n = 22;
+ }
+ else
+ {
+ memcpy (buf, dfx->defer, 22);
+ }
+ /* Fill up the buffer. */
+ if (dfx->partial)
+ {
+ for (; n < size; n++ )
+ {
+ if ( (c = iobuf_get(a)) == -1 )
+ {
+ dfx->eof_seen = 1; /* Normal EOF. */
+ break;
+ }
+ buf[n] = c;
+ }
+ }
+ else
+ {
+ for (; n < size && dfx->length; n++, dfx->length--)
+ {
+ c = iobuf_get(a);
+ if (c == -1)
+ {
+ dfx->eof_seen = 3; /* Premature EOF. */
+ break;
+ }
+ buf[n] = c;
+ }
+ if (!dfx->length)
+ dfx->eof_seen = 1; /* Normal EOF. */
+ }
+
+ /* Move the trailing 22 bytes back to the defer buffer. We
+ have at least 44 bytes thus a memmove is not needed. */
+ n -= 22;
+ memcpy (dfx->defer, buf+n, 22 );
+ dfx->defer_filled = 1;
+ }
+ else if ( !dfx->defer_filled ) /* EOF seen but empty defer buffer. */
+ {
+ /* This is bad because it means an incomplete hash. */
+ n -= 22;
+ memcpy (buf, buf+22, n );
+ dfx->eof_seen = 2; /* EOF with incomplete hash. */
+ }
+ else /* EOF seen (i.e. read less than 22 bytes). */
+ {
+ memcpy (buf, dfx->defer, 22 );
+ n -= 22;
+ memcpy (dfx->defer, buf+n, 22 );
+ dfx->eof_seen = 1; /* Normal EOF. */
+ }
+
+ if ( n )
+ {
+ if ( dfx->cipher_hd )
+ gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
+ if ( dfx->mdc_hash )
+ gcry_md_write (dfx->mdc_hash, buf, n);
+ }
+ else
+ {
+ assert ( dfx->eof_seen );
+ rc = -1; /* Return EOF. */
+ }
+ *ret_len = n;
+ }
+ else if ( control == IOBUFCTRL_FREE )
+ {
+ release_dfx_context (dfx);
+ }
+ else if ( control == IOBUFCTRL_DESC )
+ {
+ *(char**)buf = "mdc_decode_filter";
+ }
+ return rc;
+}
+
+
+static int
+decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
+{
+ decode_filter_ctx_t fc = opaque;
+ size_t size = *ret_len;
+ size_t n;
+ int c, rc = 0;
+
+
+ if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen )
+ {
+ *ret_len = 0;
+ rc = -1;
+ }
+ else if ( control == IOBUFCTRL_UNDERFLOW )
+ {
+ assert(a);
+
+ if (fc->partial)
+ {
+ for (n=0; n < size; n++ )
+ {
+ c = iobuf_get(a);
+ if (c == -1)
+ {
+ fc->eof_seen = 1; /* Normal EOF. */
+ break;
+ }
+ buf[n] = c;
+ }
+ }
+ else
+ {
+ for (n=0; n < size && fc->length; n++, fc->length--)
+ {
+ c = iobuf_get(a);
+ if (c == -1)
+ {
+ fc->eof_seen = 3; /* Premature EOF. */
+ break;
+ }
+ buf[n] = c;
+ }
+ if (!fc->length)
+ fc->eof_seen = 1; /* Normal EOF. */
+ }
+ if (n)
+ {
+ if (fc->cipher_hd)
+ gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
+ }
+ else
+ {
+ if (!fc->eof_seen)
+ fc->eof_seen = 1;
+ rc = -1; /* Return EOF. */
+ }
+ *ret_len = n;
+ }
+ else if ( control == IOBUFCTRL_FREE )
+ {
+ release_dfx_context (fc);
+ }
+ else if ( control == IOBUFCTRL_DESC )
+ {
+ *(char**)buf = "decode_filter";
+ }
+ return rc;
+}
+
Property changes on: trunk/g10/decrypt-data.c
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:mergeinfo
+
Name: svn:eol-style
+ native
Modified: trunk/g10/decrypt.c
===================================================================
--- trunk/g10/decrypt.c 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/decrypt.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -97,6 +97,73 @@
}
+/* Same as decrypt_message but takes a file descriptor for input and
+ output. */
+gpg_error_t
+decrypt_message_fd (int input_fd, int output_fd)
+{
+ gpg_error_t err;
+ IOBUF fp;
+ armor_filter_context_t *afx = NULL;
+ progress_filter_context_t *pfx;
+
+ if (opt.outfp)
+ return gpg_error (GPG_ERR_BUG);
+
+ pfx = new_progress_context ();
+
+ /* Open the message file. */
+ fp = iobuf_open_fd_or_name (input_fd, NULL, "rb");
+ if (fp && is_secured_file (iobuf_get_fd (fp)))
+ {
+ iobuf_close (fp);
+ fp = NULL;
+ errno = EPERM;
+ }
+ if (!fp)
+ {
+ char xname[64];
+
+ err = gpg_error_from_syserror ();
+ snprintf (xname, sizeof xname, "[fd %d]", input_fd);
+ log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (err));
+ release_progress_context (pfx);
+ return err;
+ }
+
+ opt.outfp = fdopen (dup (output_fd), "wb");
+ if (!opt.outfp)
+ {
+ char xname[64];
+
+ err = gpg_error_from_syserror ();
+ snprintf (xname, sizeof xname, "[fd %d]", output_fd);
+ log_error (_("can't open `%s': %s\n"), xname, gpg_strerror (err));
+ iobuf_close (fp);
+ release_progress_context (pfx);
+ return err;
+ }
+
+ if (!opt.no_armor)
+ {
+ if (use_armor_filter (fp))
+ {
+ afx = new_armor_context ();
+ push_armor_filter ( afx, fp );
+ }
+ }
+
+ err = proc_encryption_packets ( NULL, fp );
+
+ iobuf_close (fp);
+ fclose (opt.outfp);
+ opt.outfp = NULL;
+ release_armor_context (afx);
+ release_progress_context (pfx);
+ return err;
+}
+
+
void
decrypt_messages (int nfiles, char *files[])
{
Deleted: trunk/g10/encr-data.c
Modified: trunk/g10/encrypt.c
===================================================================
--- trunk/g10/encrypt.c 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/encrypt.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -264,8 +264,7 @@
do_compress = 0;
}
- if ( rc || (rc = open_outfile (GNUPG_INVALID_FD, filename,
- opt.armor? 1:0, &out )))
+ if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, &out )))
{
iobuf_cancel (inp);
xfree (cfx.dek);
@@ -462,9 +461,9 @@
* PROVIDED_PKS; if not the function builds a list of keys on its own.
*/
int
-encrypt_crypt (gnupg_fd_t filefd, const char *filename,
+encrypt_crypt (int filefd, const char *filename,
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
- gnupg_fd_t outputfd)
+ int outputfd)
{
iobuf_t inp = NULL;
iobuf_t out = NULL;
@@ -482,7 +481,7 @@
PK_LIST pk_list, work_list;
int do_compress;
- if (filefd != GNUPG_INVALID_FD && filename)
+ if (filefd != -1 && filename)
return gpg_error (GPG_ERR_INV_ARG);
do_compress = opt.compress_algo && !RFC1991;
@@ -539,7 +538,7 @@
char xname[64];
rc = gpg_error_from_syserror ();
- if (filefd != GNUPG_INVALID_FD)
+ if (filefd != -1)
snprintf (xname, sizeof xname, "[fd %d]", filefd);
else if (!filename)
strcpy (xname, "[stdin]");
@@ -652,7 +651,7 @@
if (!opt.no_literal)
pt = setup_plaintext_name (filename, inp);
- if (filefd != GNUPG_INVALID_FD
+ if (filefd != -1
&& !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
{
off_t tmpsize;
@@ -964,8 +963,7 @@
}
line[strlen(line)-1] = '\0';
print_file_status(STATUS_FILE_START, line, 2);
- rc = encrypt_crypt (GNUPG_INVALID_FD, line, remusr, 0,
- NULL, GNUPG_INVALID_FD);
+ rc = encrypt_crypt (-1, line, remusr, 0, NULL, -1);
if (rc)
log_error ("encryption of `%s' failed: %s\n",
print_fname_stdin(line), g10_errstr(rc) );
@@ -977,8 +975,7 @@
while (nfiles--)
{
print_file_status(STATUS_FILE_START, *files, 2);
- if ( (rc = encrypt_crypt (GNUPG_INVALID_FD, *files, remusr, 0,
- NULL, GNUPG_INVALID_FD)) )
+ if ( (rc = encrypt_crypt (-1, *files, remusr, 0, NULL, -1)) )
log_error("encryption of `%s' failed: %s\n",
print_fname_stdin(*files), g10_errstr(rc) );
write_status( STATUS_FILE_DONE );
Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/gpg.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -3434,8 +3434,7 @@
{
if( argc > 1 )
wrong_args(_("--encrypt [filename]"));
- if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname,
- remusr, 0, NULL, GNUPG_INVALID_FD)) )
+ if( (rc = encrypt_crypt (-1, fname, remusr, 0, NULL, -1)) )
log_error("%s: encryption failed: %s\n",
print_fname_stdin(fname), g10_errstr(rc) );
}
@@ -3456,8 +3455,7 @@
" while in %s mode\n"),compliance_option_string());
else
{
- if( (rc = encrypt_crypt (GNUPG_INVALID_FD, fname,
- remusr, 1, NULL, GNUPG_INVALID_FD)) )
+ if( (rc = encrypt_crypt (-1, fname, remusr, 1, NULL, -1)) )
log_error("%s: encryption failed: %s\n",
print_fname_stdin(fname), g10_errstr(rc) );
}
Modified: trunk/g10/main.h
===================================================================
--- trunk/g10/main.h 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/main.h 2009-10-02 14:57:55 UTC (rev 5172)
@@ -185,9 +185,9 @@
int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
int encrypt_symmetric (const char *filename );
int encrypt_store (const char *filename );
-int encrypt_crypt (gnupg_fd_t filefd, const char *filename,
+int encrypt_crypt (int filefd, const char *filename,
strlist_t remusr, int use_symkey, pk_list_t provided_keys,
- gnupg_fd_t outputfd);
+ int outputfd);
void encrypt_crypt_files (int nfiles, char **files, strlist_t remusr);
int encrypt_filter (void *opaque, int control,
iobuf_t a, byte *buf, size_t *ret_len);
@@ -245,7 +245,7 @@
int overwrite_filep( const char *fname );
char *make_outfile_name( const char *iname );
char *ask_outfile_name( const char *name, size_t namelen );
-int open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a);
+int open_outfile (int inp_fd, const char *iname, int mode, iobuf_t *a);
iobuf_t open_sigfile( const char *iname, progress_filter_context_t *pfx );
void try_make_homedir( const char *fname );
@@ -319,6 +319,7 @@
/*-- decrypt.c --*/
int decrypt_message( const char *filename );
+gpg_error_t decrypt_message_fd (int input_fd, int output_fd);
void decrypt_messages(int nfiles, char *files[]);
/*-- plaintext.c --*/
Modified: trunk/g10/openfile.c
===================================================================
--- trunk/g10/openfile.c 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/openfile.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -178,24 +178,24 @@
* Mode 0 = use ".gpg"
* 1 = use ".asc"
* 2 = use ".sig"
-
- * If INP_FD is not GNUPG_INVALID_FD the function will simply create
- * an IOBUF for that file descriptor and ignore a INAME and MODE.
- * Note that INP_FD won't be closed if the returned IOBUF is closed.
+ *
+ * If INP_FD is not -1 the function simply creates an IOBUF for that
+ * file descriptor and ignorea INAME and MODE. Note that INP_FD won't
+ * be closed if the returned IOBUF is closed.
*/
int
-open_outfile (gnupg_fd_t inp_fd, const char *iname, int mode, iobuf_t *a)
+open_outfile (int inp_fd, const char *iname, int mode, iobuf_t *a)
{
int rc = 0;
*a = NULL;
- if (inp_fd != GNUPG_INVALID_FD)
+ if (inp_fd != -1)
{
char xname[64];
- gnupg_fd_t fd2;
+ int fd2;
- fd2 = INT2FD (dup (FD2INT (inp_fd)));
- if (fd2 == GNUPG_INVALID_FD)
+ fd2 = dup (inp_fd);
+ if (fd2 == -1)
*a = NULL;
else
*a = iobuf_fdopen (fd2, "wb");
Modified: trunk/g10/options.h
===================================================================
--- trunk/g10/options.h 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/options.h 2009-10-02 14:57:55 UTC (rev 5172)
@@ -43,6 +43,7 @@
unsigned debug;
int armor;
char *outfile;
+ FILE *outfp; /* Hack, sometimes used in place of outfile. */
off_t max_output;
int dry_run;
int list_only;
Modified: trunk/g10/packet.h
===================================================================
--- trunk/g10/packet.h 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/packet.h 2009-10-02 14:57:55 UTC (rev 5172)
@@ -289,8 +289,8 @@
} PKT_compressed;
typedef struct {
- u32 len; /* length of encrypted data */
- int extralen; /* this is (blocksize+2) */
+ u32 len; /* Remaining length of encrypted data. */
+ int extralen; /* This is (blocksize+2). Used by build_packet. */
byte new_ctb; /* uses a new CTB */
byte is_partial; /* partial length encoded */
byte mdc_method; /* > 0: integrity protected encrypted data packet */
Modified: trunk/g10/plaintext.c
===================================================================
--- trunk/g10/plaintext.c 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/plaintext.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -86,10 +86,13 @@
/* Create the filename as C string. */
if (nooutput)
;
+ else if (opt.outfp)
+ {
+ fname = xstrdup ("[FP]");
+ }
else if (opt.outfile)
{
- fname = xmalloc (strlen (opt.outfile) + 1);
- strcpy (fname, opt.outfile);
+ fname = xstrdup (opt.outfile);
}
else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
{
@@ -112,6 +115,13 @@
if (nooutput)
;
+ else if (opt.outfp)
+ {
+ fp = opt.outfp;
+#ifdef HAVE_DOSISH_SYSTEM
+ setmode (fileno (fp), O_BINARY);
+#endif
+ }
else if (iobuf_is_pipe_filename (fname) || !*fname)
{
/* No filename or "-" given; write to stdout. */
@@ -138,7 +148,13 @@
}
#ifndef __riscos__
- if (fp || nooutput)
+ if (opt.outfp && is_secured_file (fileno (opt.outfp)))
+ {
+ rc = gpg_error (GPG_ERR_EPERM);
+ log_error (_("error creating `%s': %s\n"), fname, gpg_strerror (rc));
+ goto leave;
+ }
+ else if (fp || nooutput)
;
else if (is_secured_filename (fname))
{
@@ -154,9 +170,9 @@
goto leave;
}
#else /* __riscos__ */
- /* If no output filename was given, i.e. we constructed it,
- convert all '.' in fname to '/' but not vice versa as
- we don't create directories! */
+ /* If no output filename was given, i.e. we constructed it, convert
+ all '.' in fname to '/' but not vice versa as we don't create
+ directories! */
if (!opt.outfile)
for (c = 0; fname[c]; ++c)
if (fname[c] == '.')
@@ -418,7 +434,7 @@
pt->buf = NULL;
}
- if (fp && fp != stdout && fclose (fp))
+ if (fp && fp != stdout && fp != opt.outfp && fclose (fp))
{
rc = (errno ? gpg_error_from_syserror ()
: gpg_error (GPG_ERR_INTERNAL));
@@ -434,7 +450,7 @@
before checking the signature. */
fflush (stdout);
- if (fp && fp != stdout)
+ if (fp && fp != stdout && fp != opt.outfp)
fclose (fp);
xfree (fname);
return rc;
Modified: trunk/g10/server.c
===================================================================
--- trunk/g10/server.c 2009-10-02 12:31:14 UTC (rev 5171)
+++ trunk/g10/server.c 2009-10-02 14:57:55 UTC (rev 5172)
@@ -362,7 +362,7 @@
if (out_fd == -1)
return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
- err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ err = decrypt_message_fd (inp_fd, out_fd);
/* Close and reset the fds. */
close_message_fd (ctrl);
More information about the Gnupg-commits
mailing list