Implement /run/user/UID/gnupg based sockets.
[gnupg.git] / sm / gpgsm.c
index 3398d17..e6fd703 100644 (file)
@@ -32,6 +32,8 @@
 #include <gcrypt.h>
 #include <assuan.h> /* malloc hooks */
 
+#include "passphrase.h"
+#include "../common/shareddefs.h"
 #include "../kbx/keybox.h" /* malloc hooks */
 #include "i18n.h"
 #include "keydb.h"
@@ -99,7 +101,6 @@ enum cmd_and_opt_values {
   oDebugAllowCoreDump,
   oDebugNoChainValidation,
   oDebugIgnoreExpiration,
-  oFixedPassphrase,
   oLogFile,
   oNoLogFile,
   oAuditLog,
@@ -121,6 +122,8 @@ enum cmd_and_opt_values {
   oProtectToolProgram,
   oFakedSystemTime,
 
+  oPassphraseFD,
+  oPinentryMode,
 
   oAssumeArmor,
   oAssumeBase64,
@@ -214,7 +217,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aExport, "export", N_("export certificates")),
 
   /* We use -raw and not -p1 for pkcs#1 secret key export so that it
-     won't accidently be used in case -p12 was intended.  */
+     won't accidentally be used in case -p12 was intended.  */
   ARGPARSE_c (aExportSecretKeyP12, "export-secret-key-p12", "@"),
   ARGPARSE_c (aExportSecretKeyP8,  "export-secret-key-p8", "@"),
   ARGPARSE_c (aExportSecretKeyRaw, "export-secret-key-raw", "@"),
@@ -244,6 +247,9 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oP12Charset, "p12-charset", "@"),
 
+  ARGPARSE_s_i (oPassphraseFD,    "passphrase-fd", "@"),
+  ARGPARSE_s_s (oPinentryMode,    "pinentry-mode", "@"),
+
   ARGPARSE_s_n (oAssumeArmor, "assume-armor",
                 N_("assume input is in PEM format")),
   ARGPARSE_s_n (oAssumeBase64, "assume-base64",
@@ -323,7 +329,7 @@ static ARGPARSE_OPTS opts[] = {
                 N_("|SPEC|use this keyserver to lookup keys")),
   ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")),
 
-  ARGPARSE_p_u (oDebug, "debug", "@"),
+  ARGPARSE_s_s (oDebug, "debug", "@"),
   ARGPARSE_s_s (oDebugLevel, "debug-level",
                 N_("|LEVEL|set the debugging level to LEVEL")),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
@@ -332,7 +338,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"),
   ARGPARSE_s_n (oDebugNoChainValidation, "debug-no-chain-validation", "@"),
   ARGPARSE_s_n (oDebugIgnoreExpiration,  "debug-ignore-expiration", "@"),
-  ARGPARSE_s_s (oFixedPassphrase, "fixed-passphrase", "@"),
 
   ARGPARSE_s_i (oStatusFD, "status-fd",
                 N_("|FD|write status info to this FD")),
@@ -406,6 +411,19 @@ static ARGPARSE_OPTS opts[] = {
 };
 
 
+/* The list of supported debug flags.  */
+static struct debug_flags_s debug_flags [] =
+  {
+    { DBG_X509_VALUE   , "x509"    },
+    { DBG_MPI_VALUE    , "mpi"     },
+    { DBG_CRYPTO_VALUE , "crypto"  },
+    { DBG_MEMORY_VALUE , "memory"  },
+    { DBG_CACHE_VALUE  , "cache"   },
+    { DBG_MEMSTAT_VALUE, "memstat" },
+    { DBG_HASHING_VALUE, "hashing" },
+    { DBG_IPC_VALUE    , "ipc"     },
+    { 0, NULL }
+  };
 
 
 /* Global variable to keep an error count. */
@@ -438,7 +456,7 @@ static int default_include_certs = DEFAULT_INCLUDE_CERTS;
 static int default_validation_model;
 
 /* The default cipher algo.  */
-#define DEFAULT_CIPHER_ALGO "3DES"  /*des-EDE3-CBC*/
+#define DEFAULT_CIPHER_ALGO "AES"
 
 
 static char *build_list (const char *text,
@@ -563,7 +581,7 @@ my_strusage( int level )
       break;
 
     case 31: p = "\nHome: "; break;
-    case 32: p = opt.homedir; break;
+    case 32: p = gnupg_homedir (); break;
     case 33: p = _("\nSupported algorithms:\n"); break;
     case 34:
       if (!ciphers)
@@ -617,7 +635,7 @@ build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
        }
     }
   if (p)
-    p = stpcpy(p, "\n" );
+    strcpy (p, "\n" );
   return list;
 }
 
@@ -670,11 +688,11 @@ set_debug (void)
   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
     opt.debug = 0;
   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
-    opt.debug = DBG_ASSUAN_VALUE;
+    opt.debug = DBG_IPC_VALUE;
   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
-    opt.debug = DBG_ASSUAN_VALUE|DBG_X509_VALUE;
+    opt.debug = DBG_IPC_VALUE|DBG_X509_VALUE;
   else if (!strcmp (debug_level, "expert")  || (numok && numlvl <= 8))
-    opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE
+    opt.debug = (DBG_IPC_VALUE|DBG_X509_VALUE
                  |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
   else if (!strcmp (debug_level, "guru") || numok)
     {
@@ -706,15 +724,7 @@ set_debug (void)
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
   if (opt.debug)
-    log_info ("enabled debug flags:%s%s%s%s%s%s%s%s\n",
-              (opt.debug & DBG_X509_VALUE   )? " x509":"",
-              (opt.debug & DBG_MPI_VALUE    )? " mpi":"",
-              (opt.debug & DBG_CRYPTO_VALUE )? " crypto":"",
-              (opt.debug & DBG_MEMORY_VALUE )? " memory":"",
-              (opt.debug & DBG_CACHE_VALUE  )? " cache":"",
-              (opt.debug & DBG_MEMSTAT_VALUE)? " memstat":"",
-              (opt.debug & DBG_HASHING_VALUE)? " hashing":"",
-              (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"" );
+    parse_debug_flag (NULL, &opt.debug, debug_flags);
 }
 
 
@@ -862,6 +872,7 @@ parse_keyserver_line (char *line,
     {
       log_info (_("%s:%u: skipping this line\n"), filename, lineno);
       keyserver_list_free (server);
+      server = NULL;
     }
 
   return server;
@@ -906,9 +917,10 @@ main ( int argc, char **argv)
   estream_t auditfp = NULL;
   estream_t htmlauditfp = NULL;
   struct assuan_malloc_hooks malloc_hooks;
-
+  int pwfd = -1;
   /*mtrace();*/
 
+  early_system_init ();
   gnupg_reopen_std (GPGSM_NAME);
   /* trap_unaligned ();*/
   gnupg_rl_initialize ();
@@ -952,8 +964,6 @@ main ( int argc, char **argv)
      remember to update the Gpgconflist entry as well.  */
   opt.def_cipher_algoid = DEFAULT_CIPHER_ALGO;
 
-  opt.homedir = default_homedir ();
-
 
   /* First check whether we have a config file on the commandline */
   orig_argc = argc;
@@ -977,7 +987,7 @@ main ( int argc, char **argv)
           opt.no_homedir_creation = 1;
         }
       else if (pargs.r_opt == oHomedir)
-        opt.homedir = pargs.r.ret_str;
+        gnupg_set_homedir (pargs.r.ret_str);
       else if (pargs.r_opt == aCallProtectTool)
         break; /* This break makes sure that --version and --help are
                   passed to the protect-tool. */
@@ -1012,9 +1022,10 @@ main ( int argc, char **argv)
 
   /* Set the default option file */
   if (default_config )
-    configname = make_filename (opt.homedir, GPGSM_NAME EXTSEP_S "conf", NULL);
+    configname = make_filename (gnupg_homedir (),
+                                GPGSM_NAME EXTSEP_S "conf", NULL);
   /* Set the default policy file */
-  opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
+  opt.policy_file = make_filename (gnupg_homedir (), "policies.txt", NULL);
 
   argc        = orig_argc;
   argv        = orig_argv;
@@ -1145,6 +1156,16 @@ main ( int argc, char **argv)
           opt.p12_charset = pargs.r.ret_str;
           break;
 
+        case oPassphraseFD:
+         pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
+         break;
+
+        case oPinentryMode:
+         opt.pinentry_mode = parse_pinentry_mode (pargs.r.ret_str);
+         if (opt.pinentry_mode == -1)
+            log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
+         break;
+
           /* Input encoding selection.  */
         case oAssumeArmor:
           ctrl.autodetect_encoding = 0;
@@ -1241,7 +1262,13 @@ main ( int argc, char **argv)
 
         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
 
-        case oDebug: debug_value |= pargs.r.ret_ulong; break;
+        case oDebug:
+          if (parse_debug_flag (pargs.r.ret_str, &debug_value, debug_flags))
+            {
+              pargs.r_opt = ARGPARSE_INVALID_ARG;
+              pargs.err = ARGPARSE_PRINT_ERROR;
+            }
+          break;
         case oDebugAll: debug_value = ~0; break;
         case oDebugNone: debug_value = 0; break;
         case oDebugLevel: debug_level = pargs.r.ret_str; break;
@@ -1251,7 +1278,6 @@ main ( int argc, char **argv)
           break;
         case oDebugNoChainValidation: opt.no_chain_validation = 1; break;
         case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break;
-        case oFixedPassphrase: opt.fixed_passphrase = pargs.r.ret_str; break;
 
         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
@@ -1277,7 +1303,7 @@ main ( int argc, char **argv)
            }
           break;
         case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
-        case oHomedir: opt.homedir = pargs.r.ret_str; break;
+        case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
 
         case oDisplay:
@@ -1441,13 +1467,16 @@ main ( int argc, char **argv)
   configname = NULL;
 
   if (!opt.config_filename)
-    opt.config_filename = make_filename (opt.homedir,
+    opt.config_filename = make_filename (gnupg_homedir (),
                                          GPGSM_NAME EXTSEP_S "conf",
                                          NULL);
 
   if (log_get_errorcount(0))
     gpgsm_exit(2);
 
+  if (pwfd != -1)      /* Read the passphrase now.  */
+    read_passphrase_from_fd (pwfd);
+
   /* Now that we have the options parsed we need to update the default
      control structure.  */
   gpgsm_init_default_ctrl (&ctrl);
@@ -1474,7 +1503,7 @@ main ( int argc, char **argv)
     log_info (_("WARNING: program may create a core file!\n"));
 
 /*   if (opt.qualsig_approval && !opt.quiet) */
-/*     log_info (_("This software has offically been approved to " */
+/*     log_info (_("This software has officially been approved to " */
 /*                 "create and verify\n" */
 /*                 "qualified signatures according to German law.\n")); */
 
@@ -1511,7 +1540,7 @@ main ( int argc, char **argv)
 
   set_debug ();
 
-  /* Although we alwasy use gpgsm_exit, we better install a regualr
+  /* Although we always use gpgsm_exit, we better install a regualr
      exit handler so that at least the secure memory gets wiped
      out. */
   if (atexit (emergency_cleanup))
@@ -1575,7 +1604,7 @@ main ( int argc, char **argv)
   /* Set the random seed file. */
   if (use_random_seed)
     {
-      char *p = make_filename (opt.homedir, "random_seed", NULL);
+      char *p = make_filename (gnupg_homedir (), "random_seed", NULL);
       gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
       xfree(p);
     }
@@ -2054,6 +2083,7 @@ gpgsm_init_default_ctrl (struct server_control_s *ctrl)
   ctrl->include_certs = default_include_certs;
   ctrl->use_ocsp = opt.enable_ocsp;
   ctrl->validation_model = default_validation_model;
+  ctrl->offline = opt.disable_dirmngr;
 }