[Pkg-gnupg-commit] [gnupg2] 109/241: gpg: Add support for unwrapping the outer level of encryption.

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Dec 9 20:32:02 UTC 2015


This is an automated email from the git hooks/post-receive script.

dkg pushed a commit to branch master
in repository gnupg2.

commit ec409e62aea6cc829299be794f9d035d033cb51b
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Nov 5 12:20:42 2015 +0100

    gpg: Add support for unwrapping the outer level of encryption.
    
    * g10/decrypt-data.c (decrypt_data): If OPT.UNWRAP_ENCRYPTION is set,
    copy the data to the output file instead of continuing to process it.
    * g10/gpg.c (enum cmd_and_opt_values): Add new value oUnwrap.
    (opts): Handle oUnwrap.
    (main): Likewise.
    * g10/options.h (opt): Add field unwrap_encryption.
    * g10/plaintext.c (handle_plaintext): Break the output file selection
    functionality into ...
    (get_output_file): ... this new function.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>
    GnuPG-bug-id: 1060
    Debian-bug-id: 282061
---
 g10/decrypt-data.c |  33 ++++++++++++-
 g10/gpg.c          |   5 ++
 g10/options.h      |   2 +
 g10/packet.h       |   2 +
 g10/plaintext.c    | 136 +++++++++++++++++++++++++++++++++++------------------
 5 files changed, 130 insertions(+), 48 deletions(-)

diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
index 570a71d..b575f39 100644
--- a/g10/decrypt-data.c
+++ b/g10/decrypt-data.c
@@ -221,7 +221,38 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
   else
     iobuf_push_filter ( ed->buf, decode_filter, dfx );
 
-  proc_packets (ctrl, procctx, ed->buf );
+  if (opt.unwrap_encryption)
+    {
+      char *filename;
+      estream_t fp;
+      rc = get_output_file ("", 0, ed->buf, &filename, &fp);
+      if (! rc)
+        {
+          iobuf_t output = iobuf_esopen (fp, "w", 0);
+          armor_filter_context_t *afx = NULL;
+
+          if (opt.armor)
+            {
+              afx = new_armor_context ();
+              push_armor_filter (afx, output);
+            }
+
+          iobuf_copy (output, ed->buf);
+          if ((rc = iobuf_error (ed->buf)))
+            log_error (_("error reading: %s\n"),
+                       filename, gpg_strerror (rc));
+          else if ((rc = iobuf_error (output)))
+            log_error (_("error writing output ('%s'): %s\n"),
+                       filename, gpg_strerror (rc));
+
+          iobuf_close (output);
+          if (afx)
+            release_armor_context (afx);
+        }
+    }
+  else
+    proc_packets (ctrl, procctx, ed->buf );
+
   ed->buf = NULL;
   if (dfx->eof_seen > 1 )
     rc = gpg_error (GPG_ERR_INV_PACKET);
diff --git a/g10/gpg.c b/g10/gpg.c
index cdf7b0d..ef283b4 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -391,6 +391,7 @@ enum cmd_and_opt_values
     oTOFUDefaultPolicy,
     oTOFUDBFormat,
     oWeakDigest,
+    oUnwrap,
 
     oNoop
   };
@@ -753,6 +754,7 @@ static ARGPARSE_OPTS opts[] = {
                                          "personal-compress-preferences", "@"),
   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
   ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
+  ARGPARSE_s_n (oUnwrap, "unwrap", "@"),
 
   /* Aliases.  I constantly mistype these, and assume other people do
      as well. */
@@ -3147,6 +3149,9 @@ main (int argc, char **argv)
           case oWeakDigest:
 	    additional_weak_digest(pargs.r.ret_str);
 	    break;
+          case oUnwrap:
+            opt.unwrap_encryption = 1;
+            break;
 
           case oDisplay:
             set_opt_session_env ("DISPLAY", pargs.r.ret_str);
diff --git a/g10/options.h b/g10/options.h
index bc92dd7..c8541b2 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -262,6 +262,8 @@ struct
 
   int passphrase_repeat;
   int pinentry_mode;
+
+  int unwrap_encryption;
 } opt;
 
 /* CTRL is used to keep some global variables we currently can't
diff --git a/g10/packet.h b/g10/packet.h
index 21c80f3..387a5b5 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -663,6 +663,8 @@ int handle_compressed (ctrl_t ctrl, void *ctx, PKT_compressed *cd,
 int decrypt_data (ctrl_t ctrl, void *ctx, PKT_encrypted *ed, DEK *dek );
 
 /*-- plaintext.c --*/
+gpg_error_t get_output_file (const byte *embedded_name, int embedded_namelen,
+                             iobuf_t data, char **fnamep, estream_t *fpp);
 int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
 					int nooutput, int clearsig );
 int ask_for_detached_datafile( gcry_md_hd_t md, gcry_md_hd_t md2,
diff --git a/g10/plaintext.c b/g10/plaintext.c
index 7929f66..aeee2ac 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -40,53 +40,29 @@
 #include "i18n.h"
 
 
-/* Handle a plaintext packet.  If MFX is not NULL, update the MDs
- * Note: We should have used the filter stuff here, but we have to add
- * some easy mimic to set a read limit, so we calculate only the bytes
- * from the plaintext.  */
-int
-handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
-		  int nooutput, int clearsig)
-{
-  char *fname = NULL;
-  estream_t fp = NULL;
-  static off_t count = 0;
-  int err = 0;
-  int c;
-  int convert = (pt->mode == 't' || pt->mode == 'u');
-#ifdef __riscos__
-  int filetype = 0xfff;
-#endif
+/* Get the output filename.  On success, the actual filename that is
+   used is set in *FNAMEP and a filepointer is returned in *FP.
 
-  /* Let people know what the plaintext info is. This allows the
-     receiving program to try and do something different based on the
-     format code (say, recode UTF-8 to local). */
-  if (!nooutput && is_status_enabled ())
-    {
-      char status[50];
+   EMBEDDED_NAME AND EMBEDDED_NAMELEN are normally stored in a
+   plaintext packet.  EMBEDDED_NAMELEN should not include any NUL
+   terminator (EMBEDDED_NAME does not need to be NUL terminated).
 
-      /* Better make sure that stdout has been flushed in case the
-         output will be written to it.  This is to make sure that no
-         not-yet-flushed stuff will be written after the plaintext
-         status message.  */
-      es_fflush (es_stdout);
-
-      snprintf (status, sizeof status,
-                "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
-      write_status_text_and_buffer (STATUS_PLAINTEXT,
-				    status, pt->name, pt->namelen, 0);
+   DATA is the iobuf containing the input data.  We just use it to get
+   the input file's filename.
 
-      if (!pt->is_partial)
-	{
-	  snprintf (status, sizeof status, "%lu", (ulong) pt->len);
-	  write_status_text (STATUS_PLAINTEXT_LENGTH, status);
-	}
-    }
+   On success, the caller is responsible for calling xfree on *FNAMEP
+   and calling es_close on *FPP.  */
+gpg_error_t
+get_output_file (const byte *embedded_name, int embedded_namelen,
+                 iobuf_t data, char **fnamep, estream_t *fpp)
+{
+  gpg_error_t err = 0;
+  char *fname = NULL;
+  estream_t fp = NULL;
+  int nooutput = 0;
 
   /* Create the filename as C string.  */
-  if (nooutput)
-    ;
-  else if (opt.outfp)
+  if (opt.outfp)
     {
       fname = xtrystrdup ("[FP]");
       if (!fname)
@@ -104,16 +80,17 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
           goto leave;
         }
     }
-  else if (pt->namelen == 8 && !memcmp (pt->name, "_CONSOLE", 8))
+  else if (embedded_namelen == 8 && !memcmp (embedded_name, "_CONSOLE", 8))
     {
       log_info (_("data not saved; use option \"--output\" to save it\n"));
       nooutput = 1;
     }
   else if (!opt.flags.use_embedded_filename)
     {
-      fname = make_outfile_name (iobuf_get_real_fname (pt->buf));
+      if (data)
+        fname = make_outfile_name (iobuf_get_real_fname (data));
       if (!fname)
-	fname = ask_outfile_name (pt->name, pt->namelen);
+	fname = ask_outfile_name (embedded_name, embedded_namelen);
       if (!fname)
 	{
 	  err = gpg_error (GPG_ERR_GENERAL);	/* Can't create file. */
@@ -121,7 +98,7 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
 	}
     }
   else
-    fname = utf8_to_native (pt->name, pt->namelen, 0);
+    fname = utf8_to_native (embedded_name, embedded_namelen, 0);
 
   if (nooutput)
     ;
@@ -205,7 +182,8 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
       /* If there's a ,xxx extension in the embedded filename,
          use that, else check whether the user input (in fname)
          has a ,xxx appended, then use that in preference */
-      if ((c = riscos_get_filetype_from_string (pt->name, pt->namelen)) != -1)
+      if ((c = riscos_get_filetype_from_string (embedded_name,
+                                                embedded_namelen)) != -1)
 	filetype = c;
       if ((c = riscos_get_filetype_from_string (fname, strlen (fname))) != -1)
 	filetype = c;
@@ -213,6 +191,70 @@ handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
     }
 #endif /* __riscos__ */
 
+ leave:
+  if (err)
+    {
+      if (fp && fp != es_stdout && fp != opt.outfp)
+        es_fclose (fp);
+      xfree (fname);
+      return err;
+    }
+
+  *fnamep = fname;
+  *fpp = fp;
+  return 0;
+}
+
+/* Handle a plaintext packet.  If MFX is not NULL, update the MDs
+ * Note: We should have used the filter stuff here, but we have to add
+ * some easy mimic to set a read limit, so we calculate only the bytes
+ * from the plaintext.  */
+int
+handle_plaintext (PKT_plaintext * pt, md_filter_context_t * mfx,
+		  int nooutput, int clearsig)
+{
+  char *fname = NULL;
+  estream_t fp = NULL;
+  static off_t count = 0;
+  int err = 0;
+  int c;
+  int convert = (pt->mode == 't' || pt->mode == 'u');
+#ifdef __riscos__
+  int filetype = 0xfff;
+#endif
+
+  /* Let people know what the plaintext info is. This allows the
+     receiving program to try and do something different based on the
+     format code (say, recode UTF-8 to local). */
+  if (!nooutput && is_status_enabled ())
+    {
+      char status[50];
+
+      /* Better make sure that stdout has been flushed in case the
+         output will be written to it.  This is to make sure that no
+         not-yet-flushed stuff will be written after the plaintext
+         status message.  */
+      es_fflush (es_stdout);
+
+      snprintf (status, sizeof status,
+                "%X %lu ", (byte) pt->mode, (ulong) pt->timestamp);
+      write_status_text_and_buffer (STATUS_PLAINTEXT,
+				    status, pt->name, pt->namelen, 0);
+
+      if (!pt->is_partial)
+	{
+	  snprintf (status, sizeof status, "%lu", (ulong) pt->len);
+	  write_status_text (STATUS_PLAINTEXT_LENGTH, status);
+	}
+    }
+
+  if (! nooutput)
+    {
+      err = get_output_file (pt->name, pt->namelen, pt->buf, &fname, &fp);
+      if (err)
+        goto leave;
+    }
+
   if (!pt->is_partial)
     {
       /* We have an actual length (which might be zero). */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/gnupg2.git



More information about the Pkg-gnupg-commit mailing list