tools/gpgtar: Implement symmetric encryption.
[gnupg.git] / tools / symcryptrun.c
index 1191212..4b90cd2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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 2 of the License, or
+ * 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,
@@ -14,9 +14,7 @@
  * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 
@@ -51,7 +49,7 @@
    The possible exit status codes:
 
    0   Success
-   1   Some error occured
+   1   Some error occurred
    2   No valid passphrase was provided
    3   The operation was canceled by the user
 
@@ -76,7 +74,9 @@
 #ifdef HAVE_PTY_H
 #include <pty.h>
 #endif
+#ifdef HAVE_UTMP_H
 #include <utmp.h>
+#endif
 #include <ctype.h>
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
 #endif
 #include <gpg-error.h>
 
-#define JNLIB_NEED_LOG_LOGV
 #include "i18n.h"
 #include "../common/util.h"
-#include "mkdtemp.h"
+#include "../common/init.h"
+#include "../common/sysutils.h"
 
 /* FIXME: Bah.  For spwq_secure_free.  */
 #define SIMPLE_PWQUERY_IMPLEMENTATION 1
 \f
 /* From simple-gettext.c.  */
 
-/* We assume to have `unsigned long int' value with at least 32 bits.  */
+/* We assume to have 'unsigned long int' value with at least 32 bits.  */
 #define HASHWORDBITS 32
 
-/* The so called `hashpjw' function by P.J. Weinberger
+/* The so called 'hashpjw' function by P.J. Weinberger
    [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
    1986, 1987 Bell Telephone Laboratories, Inc.]  */
 
@@ -155,9 +155,9 @@ static ARGPARSE_OPTS opts[] =
 
     { oDecrypt, "decrypt", 0, N_("decryption modus") },
     { oEncrypt, "encrypt", 0, N_("encryption modus") },
-    
+
     { 302, NULL, 0, N_("@\nOptions:\n ") },
-    
+
     { oClass, "class", 2, N_("tool class (confucius)") },
     { oProgram, "program", 2, N_("program filename") },
 
@@ -170,7 +170,7 @@ static ARGPARSE_OPTS opts[] =
 
     /* Hidden options.  */
     { oNoVerbose, "no-verbose",  0, "@" },
-    { oHomedir, "homedir", 2, "@" },   
+    { oHomedir, "homedir", 2, "@" },
     { oNoOptions, "no-options", 0, "@" },/* shortcut for --options /dev/null */
 
     {0}
@@ -199,12 +199,12 @@ my_strusage (int level)
 
   switch (level)
     {
-    case 11: p = "symcryptrun (GnuPG)";
+    case 11: p = "symcryptrun (@GNUPG@)";
       break;
     case 13: p = VERSION; break;
     case 17: p = PRINTABLE_OS_NAME; break;
-    case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
-      break;
+    case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
+
     case 1:
     case 40: p = _("Usage: symcryptrun [options] (-h for help)");
       break;
@@ -223,26 +223,11 @@ my_strusage (int level)
 }
 
 
-/* Initialize the gettext system.  */
-static void
-i18n_init(void)
-{
-#ifdef USE_SIMPLE_GETTEXT
-  set_gettext_file (PACKAGE_GT);
-#else
-# ifdef ENABLE_NLS
-  setlocale (LC_ALL, "");
-  bindtextdomain (PACKAGE_GT, LOCALEDIR);
-  textdomain (PACKAGE_GT);
-# endif
-#endif
-}
-
 \f
 /* This is in the GNU C library in unistd.h.  */
 
 #ifndef TEMP_FAILURE_RETRY
-/* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
+/* Evaluate EXPRESSION, and repeat as long as it returns -1 with 'errno'
    set to EINTR.  */
 
 # define TEMP_FAILURE_RETRY(expression) \
@@ -253,6 +238,8 @@ i18n_init(void)
        __result; }))
 #endif
 
+/* Include the implementation of map_spwq_error.  */
+MAP_SPWQ_ERROR_IMPL
 
 /* Unlink a file, and shred it if SHRED is true.  */
 int
@@ -269,10 +256,10 @@ remove_file (char *name, int shred)
       if (pid == 0)
        {
          /* Child.  */
-         
+
          /* -f forces file to be writable, and -u unlinks it afterwards.  */
          char *args[] = { SHRED, "-uf", name, NULL };
-         
+
          execv (SHRED, args);
          _exit (127);
        }
@@ -284,11 +271,11 @@ remove_file (char *name, int shred)
       else
        {
          /* Parent.  */
-         
+
          if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
            status = -1;
        }
-      
+
       if (!WIFEXITED (status))
        {
          log_error (_("%s on %s aborted with status %i\n"),
@@ -319,12 +306,18 @@ remove_file (char *name, int shred)
 static char *
 confucius_mktmpdir (void)
 {
-  char *name;
+  char *name, *p;
 
-  name = strdup ("/tmp/gpg-XXXXXX");
-  if (!name || !mkdtemp (name))
+  p = getenv ("TMPDIR");
+  if (!p || !*p)
+    p = "/tmp";
+  if (p[strlen (p) - 1] == '/')
+    name = xstrconcat (p, "gpg-XXXXXX", NULL);
+  else
+    name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
+  if (!name || !gnupg_mkdtemp (name))
     {
-      log_error (_("can't create temporary directory `%s': %s\n"),
+      log_error (_("can't create temporary directory '%s': %s\n"),
                  name?name:"", strerror (errno));
       return NULL;
     }
@@ -439,45 +432,17 @@ confucius_get_pass (const char *cacheid, int again, int *canceled)
 {
   int err;
   char *pw;
-#ifdef HAVE_LANGINFO_CODESET
-  char *orig_codeset = NULL;
-#endif
+  char *orig_codeset;
 
   if (canceled)
     *canceled = 0;
-  
-#ifdef ENABLE_NLS
-  /* The Assuan agent protocol requires us to transmit utf-8 strings */
-  orig_codeset = bind_textdomain_codeset (PACKAGE_GT, NULL);
-#ifdef HAVE_LANGINFO_CODESET
-  if (!orig_codeset)
-    orig_codeset = nl_langinfo (CODESET);
-#endif
-  if (orig_codeset && !strcmp (orig_codeset, "UTF-8"))
-    orig_codeset = NULL;
-  if (orig_codeset)
-    {
-      /* We only switch when we are able to restore the codeset later. */
-      orig_codeset = xstrdup (orig_codeset);
-      if (!bind_textdomain_codeset (PACKAGE_GT, "utf-8"))
-        {
-         xfree (orig_codeset);
-         orig_codeset = NULL; 
-       }
-    }
-#endif
 
+  orig_codeset = i18n_switchto_utf8 ();
   pw = simple_pwquery (cacheid,
                        again ? _("does not match - try again"):NULL,
                        _("Passphrase:"), NULL, 0, &err);
-
-#ifdef ENABLE_NLS
-  if (orig_codeset)
-    {
-      bind_textdomain_codeset (PACKAGE_GT, orig_codeset);
-      xfree (orig_codeset);
-    }
-#endif
+  err = map_spwq_error (err);
+  i18n_switchback (orig_codeset);
 
   if (!pw)
     {
@@ -489,7 +454,7 @@ confucius_get_pass (const char *cacheid, int again, int *canceled)
          log_info (_("cancelled\n"));
          if (canceled)
            *canceled = 1;
-       }      
+       }
     }
 
   return pw;
@@ -598,7 +563,7 @@ confucius_process (int mode, char *infile, char *outfile,
       free (args);
       return 1;
     }
-  else if (pid == 0) 
+  else if (pid == 0)
     {
       /* Child.  */
 
@@ -671,7 +636,7 @@ confucius_process (int mode, char *infile, char *outfile,
                  close (cstderr[0]);
                  return 1;
                }
-             else  
+             else
                {
                  char *newline;
 
@@ -897,7 +862,7 @@ confucius_main (int mode, int argc, char *argv[])
       rmdir (tmpdir);
       return res;
     }
-  
+
   remove_file (outfile, mode == oDecrypt);
   if (infile_from_stdin)
     remove_file (infile, mode == oEncrypt);
@@ -917,19 +882,19 @@ main (int argc, char **argv)
   char **orig_argv;
   FILE *configfp = NULL;
   char *configname = NULL;
-  unsigned configlineno; 
+  unsigned configlineno;
   int mode = 0;
   int res;
   char *logfile = NULL;
   int default_config = 1;
 
+  early_system_init ();
   set_strusage (my_strusage);
   log_set_prefix ("symcryptrun", 1);
 
-  /* Try to auto set the character set.  */
-  set_native_charset (NULL); 
-
+  /* Make sure that our subsystems are ready.  */
   i18n_init();
+  init_common_subsystems (&argc, &argv);
 
   opt.homedir = default_homedir ();
 
@@ -955,7 +920,7 @@ main (int argc, char **argv)
 
   if (default_config)
     configname = make_filename (opt.homedir, "symcryptrun.conf", NULL );
-  
+
   argc = orig_argc;
   argv = orig_argv;
   pargs.argc = &argc;
@@ -970,11 +935,11 @@ main (int argc, char **argv)
         {
           if (!default_config)
             {
-              log_error (_("option file `%s': %s\n"),
+              log_error (_("option file '%s': %s\n"),
                          configname, strerror(errno) );
               exit(1);
            }
-          xfree (configname); 
+          xfree (configname);
           configname = NULL;
        }
       default_config = 0;
@@ -991,7 +956,7 @@ main (int argc, char **argv)
        case oQuiet:     opt.quiet = 1; break;
         case oVerbose:   opt.verbose++; break;
         case oNoVerbose: opt.verbose = 0; break;
-         
+
        case oClass:    opt.class = pargs.r.ret_str; break;
        case oProgram:  opt.program = pargs.r.ret_str; break;
        case oKeyfile:  opt.keyfile = pargs.r.ret_str; break;
@@ -1043,13 +1008,22 @@ main (int argc, char **argv)
   setup_libgcrypt_logging ();
   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
 
+  /* Tell simple-pwquery about the the standard socket name.  */
+  {
+    char *tmp = make_filename (opt.homedir, GPG_AGENT_SOCK_NAME, NULL);
+    simple_pw_set_socket (tmp);
+    xfree (tmp);
+  }
+
   if (!opt.class)
     {
       log_error (_("no class provided\n"));
       res = 1;
     }
   else if (!strcmp (opt.class, "confucius"))
-    res = confucius_main (mode, argc, argv);
+    {
+      res = confucius_main (mode, argc, argv);
+    }
   else
     {
       log_error (_("class %s is not supported\n"), opt.class);