[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