tools: Add encryption and decryption support to gpgtar.
authorJustus Winter <justus@g10code.com>
Tue, 24 Nov 2015 17:39:30 +0000 (18:39 +0100)
committerJustus Winter <justus@g10code.com>
Wed, 25 Nov 2015 11:19:50 +0000 (12:19 +0100)
* tools/Makefile.am: Amend CFLAGS and LDADD.
* tools/gpgtar-create.c (gpgtar_create): Add encrypt flag and encrypt
stream if requested.
* tools/gpgtar-extract.c (gpgtar_extract): Likewise for decryption.
* tools/gpgtar-list.c (gpgtar_list): Likewise.
* tools/gpgtar.c (main): Initialize npth and assuan.  Parse recipient
and local user, and note which flags are currently ignored.  Adapt
calls to gpgtar_list and friends.
(tar_and_encrypt): Drop stub function and prototype.
(decrypt_and_untar): Likewise.
(decrypt_and_list): Likewise.
* tools/gpgtar.h (gpgtar_{create,extract,list}): Add encryption or
decryption argument.

Signed-off-by: Justus Winter <justus@g10code.com>
tools/Makefile.am
tools/gpgtar-create.c
tools/gpgtar-extract.c
tools/gpgtar-list.c
tools/gpgtar.c
tools/gpgtar.h

index 496b1a6..a793cca 100644 (file)
@@ -142,9 +142,9 @@ gpgtar_SOURCES = \
        gpgtar-extract.c \
        gpgtar-list.c \
        no-libgcrypt.c
-gpgtar_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
-#gpgtar_LDADD = $(commonpth_libs) $(PTH_LIBS) $(GPG_ERROR_LIBS)
-gpgtar_LDADD = $(common_libs) $(GPG_ERROR_LIBS) \
+gpgtar_CFLAGS = $(GPG_ERROR_CFLAGS) $(NPTH_CFLAGS) $(LIBASSUAN_CFLAGS)
+gpgtar_LDADD = $(libcommonpth) $(GPG_ERROR_LIBS) \
+               $(NPTH_LIBS) $(LIBASSUAN_LIBS) \
                $(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS)
 
 
index fad6d57..59b88bf 100644 (file)
@@ -36,6 +36,7 @@
 #include <assert.h>
 
 #include "i18n.h"
+#include "../common/call-gpg.h"
 #include "../common/sysutils.h"
 #include "gpgtar.h"
 
@@ -740,13 +741,14 @@ write_eof_mark (estream_t stream)
    INPATTERN is NULL take the pattern as null terminated strings from
    stdin.  */
 void
-gpgtar_create (char **inpattern)
+gpgtar_create (char **inpattern, int encrypt)
 {
   gpg_error_t err = 0;
   struct scanctrl_s scanctrl_buffer;
   scanctrl_t scanctrl = &scanctrl_buffer;
   tar_header_t hdr, *start_tail;
   estream_t outstream = NULL;
+  estream_t cipher_stream = NULL;
   int eof_seen = 0;
 
   if (!inpattern)
@@ -863,6 +865,17 @@ gpgtar_create (char **inpattern)
   if (outstream == es_stdout)
     es_set_binary (es_stdout);
 
+  if (encrypt)
+    {
+      cipher_stream = outstream;
+      outstream = es_fopenmem (0, "rwb");
+      if (! outstream)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+    }
+
   for (hdr = scanctrl->flist; hdr; hdr = hdr->next)
     {
       err = write_file (outstream, hdr);
@@ -870,6 +883,22 @@ gpgtar_create (char **inpattern)
         goto leave;
     }
   err = write_eof_mark (outstream);
+  if (err)
+    goto leave;
+
+  if (encrypt)
+    {
+      err = es_fseek (outstream, 0, SEEK_SET);
+      if (err)
+        goto leave;
+
+      err = gpg_encrypt_stream (NULL, NULL,
+                                outstream,
+                                opt.recipients,
+                                cipher_stream);
+      if (err)
+        goto leave;
+    }
 
  leave:
   if (!err)
@@ -879,6 +908,11 @@ gpgtar_create (char **inpattern)
       else
         err = es_fflush (outstream);
       outstream = NULL;
+      if (cipher_stream != es_stdout)
+        err = es_fclose (cipher_stream);
+      else
+        err = es_fflush (cipher_stream);
+      cipher_stream = NULL;
     }
   if (err)
     {
@@ -886,6 +920,8 @@ gpgtar_create (char **inpattern)
                  es_fname_get (outstream), gpg_strerror (err));
       if (outstream && outstream != es_stdout)
         es_fclose (outstream);
+      if (cipher_stream && cipher_stream != es_stdout)
+        es_fclose (cipher_stream);
       if (opt.outfile)
         gnupg_remove (opt.outfile);
     }
index 6e506d9..19db0eb 100644 (file)
@@ -28,6 +28,7 @@
 #include <assert.h>
 
 #include "i18n.h"
+#include "../common/call-gpg.h"
 #include "../common/sysutils.h"
 #include "gpgtar.h"
 
@@ -265,10 +266,11 @@ create_directory (const char *dirprefix)
 
 \f
 void
-gpgtar_extract (const char *filename)
+gpgtar_extract (const char *filename, int decrypt)
 {
   gpg_error_t err;
   estream_t stream;
+  estream_t cipher_stream = NULL;
   tar_header_t header = NULL;
   const char *dirprefix = NULL;
   char *dirname = NULL;
@@ -292,6 +294,24 @@ gpgtar_extract (const char *filename)
   if (stream == es_stdin)
     es_set_binary (es_stdin);
 
+  if (decrypt)
+    {
+      cipher_stream = stream;
+      stream = es_fopenmem (0, "rwb");
+      if (! stream)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      err = gpg_decrypt_stream (NULL, NULL, cipher_stream, stream);
+      if (err)
+        goto leave;
+
+      err = es_fseek (stream, 0, SEEK_SET);
+      if (err)
+        goto leave;
+    }
+
   if (filename)
     {
       dirprefix = strrchr (filename, '/');
@@ -340,5 +360,7 @@ gpgtar_extract (const char *filename)
   xfree (dirname);
   if (stream != es_stdin)
     es_fclose (stream);
+  if (stream != cipher_stream)
+    es_fclose (cipher_stream);
   return;
 }
index d525d24..41e08db 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "i18n.h"
 #include "gpgtar.h"
+#include "../common/call-gpg.h"
 
 
 \f
@@ -267,10 +268,11 @@ print_header (tar_header_t header, estream_t out)
 /* List the tarball FILENAME or, if FILENAME is NULL, the tarball read
    from stdin.  */
 void
-gpgtar_list (const char *filename)
+gpgtar_list (const char *filename, int decrypt)
 {
   gpg_error_t err;
   estream_t stream;
+  estream_t cipher_stream = NULL;
   tar_header_t header;
 
   if (filename)
@@ -292,6 +294,24 @@ gpgtar_list (const char *filename)
   if (stream == es_stdin)
     es_set_binary (es_stdin);
 
+  if (decrypt)
+    {
+      cipher_stream = stream;
+      stream = es_fopenmem (0, "rwb");
+      if (! stream)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      err = gpg_decrypt_stream (NULL, NULL, cipher_stream, stream);
+      if (err)
+        goto leave;
+
+      err = es_fseek (stream, 0, SEEK_SET);
+      if (err)
+        goto leave;
+    }
+
   for (;;)
     {
       header = read_header (stream);
@@ -311,6 +331,8 @@ gpgtar_list (const char *filename)
   xfree (header);
   if (stream != es_stdin)
     es_fclose (stream);
+  if (stream != cipher_stream)
+    es_fclose (cipher_stream);
   return;
 }
 
index 4d3954b..a86aafe 100644 (file)
@@ -27,7 +27,9 @@
    gpg.  So here we go.  */
 
 #include <config.h>
+#include <assuan.h>
 #include <errno.h>
+#include <npth.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -100,13 +102,6 @@ static ARGPARSE_OPTS opts[] = {
 
 
 \f
-static void tar_and_encrypt (char **inpattern);
-static void decrypt_and_untar (const char *fname);
-static void decrypt_and_list (const char *fname);
-
-
-
-\f
 /* Print usage information and and provide strings for help. */
 static const char *
 my_strusage( int level )
@@ -156,6 +151,7 @@ set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
   *ret_cmd = cmd;
 }
 
+ASSUAN_SYSTEM_NPTH_IMPL;
 
 \f
 /* gpgtar main. */
@@ -179,6 +175,11 @@ main (int argc, char **argv)
   /* Make sure that our subsystems are ready.  */
   i18n_init();
   init_common_subsystems (&argc, &argv);
+  npth_init ();
+  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
+  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
+  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
+  assuan_sock_init ();
 
   /* Parse the command line. */
   pargs.argc  = &argc;
@@ -203,7 +204,17 @@ main (int argc, char **argv)
           set_cmd (&cmd, pargs.r_opt);
          break;
 
+        case oRecipient:
+          add_to_strlist (&opt.recipients, pargs.r.ret_str);
+          break;
+
+        case oUser:
+          log_info ("note: ignoring option --user\n");
+          opt.user = pargs.r.ret_str;
+          break;
+
         case oSymmetric:
+          log_info ("note: ignoring option --symmetric\n");
           set_cmd (&cmd, aEncrypt);
           opt.symmetric = 1;
           break;
@@ -237,6 +248,10 @@ main (int argc, char **argv)
           log_info (_("NOTE: '%s' is not considered an option\n"), argv[i]);
     }
 
+  if (opt.verbose > 1)
+    opt.debug_level = 1024;
+  setup_libassuan_logging (&opt.debug_level);
+
   switch (cmd)
     {
     case aList:
@@ -247,10 +262,7 @@ main (int argc, char **argv)
         log_info ("note: ignoring option --set-filename\n");
       if (files_from)
         log_info ("note: ignoring option --files-from\n");
-      if (skip_crypto)
-        gpgtar_list (fname);
-      else
-        decrypt_and_list (fname);
+      gpgtar_list (fname, !skip_crypto);
       break;
 
     case aEncrypt:
@@ -259,10 +271,7 @@ main (int argc, char **argv)
         usage (1);
       if (opt.filename)
         log_info ("note: ignoring option --set-filename\n");
-      if (skip_crypto)
-        gpgtar_create (null_names? NULL :argv);
-      else
-        tar_and_encrypt (null_names? NULL : argv);
+      gpgtar_create (null_names? NULL :argv, !skip_crypto);
       break;
 
     case aDecrypt:
@@ -273,10 +282,7 @@ main (int argc, char **argv)
       if (files_from)
         log_info ("note: ignoring option --files-from\n");
       fname = argc ? *argv : NULL;
-      if (skip_crypto)
-        gpgtar_extract (fname);
-      else
-        decrypt_and_untar (fname);
+      gpgtar_extract (fname, !skip_crypto);
       break;
 
     default:
@@ -378,31 +384,3 @@ openpgp_message_p (estream_t fp)
   return 0;
 }
 #endif
-
-
-
-\f
-static void
-tar_and_encrypt (char **inpattern)
-{
-  (void)inpattern;
-  log_error ("tar_and_encrypt has not yet been implemented\n");
-}
-
-
-\f
-static void
-decrypt_and_untar (const char *fname)
-{
-  (void)fname;
-  log_error ("decrypt_and_untar has not yet been implemented\n");
-}
-
-
-\f
-static void
-decrypt_and_list (const char *fname)
-{
-  (void)fname;
-  log_error ("decrypt_and_list has not yet been implemented\n");
-}
index 08dfcf8..a96ee09 100644 (file)
 #define GPGTAR_H
 
 #include "../common/util.h"
+#include "../common/strlist.h"
 
 /* We keep all global options in the structure OPT.  */
 struct
 {
   int verbose;
+  unsigned int debug_level;
   int quiet;
   const char *outfile;
+  strlist_t recipients;
+  const char *user;
   int symmetric;
   const char *filename;
 } opt;
@@ -111,13 +115,13 @@ gpg_error_t read_record (estream_t stream, void *record);
 gpg_error_t write_record (estream_t stream, const void *record);
 
 /*-- gpgtar-create.c --*/
-void gpgtar_create (char **inpattern);
+void gpgtar_create (char **inpattern, int encrypt);
 
 /*-- gpgtar-extract.c --*/
-void gpgtar_extract (const char *filename);
+void gpgtar_extract (const char *filename, int decrypt);
 
 /*-- gpgtar-list.c --*/
-void gpgtar_list (const char *filename);
+void gpgtar_list (const char *filename, int decrypt);
 tar_header_t gpgtar_read_header (estream_t stream);
 void gpgtar_print_header (tar_header_t header, estream_t out);