common: Add an assuan logging monitor.
[gnupg.git] / g10 / gpg.c
index cf0e645..9f7da05 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -60,6 +60,7 @@
 #include "call-dirmngr.h"
 #include "tofu.h"
 #include "../common/init.h"
+#include "../common/mbox-util.h"
 #include "../common/shareddefs.h"
 
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
@@ -81,6 +82,8 @@ enum cmd_and_opt_values
     aSym         = 'c',
     aDecrypt     = 'd',
     aEncr        = 'e',
+    oRecipientFile       = 'f',
+    oHiddenRecipientFile = 'F',
     oInteractive  = 'i',
     aListKeys    = 'k',
     oDryRun      = 'n',
@@ -97,6 +100,7 @@ enum cmd_and_opt_values
     aListSecretKeys = 'K',
     oBatch       = 500,
     oMaxOutput,
+    oInputSizeHint,
     oSigNotation,
     oCertNotation,
     oShowNotation,
@@ -167,6 +171,7 @@ enum cmd_and_opt_values
     aServer,
     aTOFUPolicy,
 
+    oMimemode,
     oTextmode,
     oNoTextmode,
     oExpert,
@@ -188,6 +193,11 @@ enum cmd_and_opt_values
     oWithKeygrip,
     oWithSecret,
     oWithWKDHash,
+    oWithColons,
+    oWithKeyData,
+    oWithTofuInfo,
+    oWithSigList,
+    oWithSigCheck,
     oAnswerYes,
     oAnswerNo,
     oKeyring,
@@ -254,10 +264,6 @@ enum cmd_and_opt_values
     oNoOptions,
     oNoBatch,
     oHomedir,
-    oWithColons,
-    oWithKeyData,
-    oWithSigList,
-    oWithSigCheck,
     oSkipVerify,
     oSkipHiddenRecipients,
     oNoSkipHiddenRecipients,
@@ -402,6 +408,7 @@ enum cmd_and_opt_values
     oUnwrap,
     oOnlySignTextIDs,
     oDisableSignerUID,
+    oSender,
 
     oNoop
   };
@@ -506,6 +513,8 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
   ARGPARSE_s_s (oHiddenRecipient, "hidden-recipient", "@"),
+  ARGPARSE_s_s (oRecipientFile, "recipient-file", "@"),
+  ARGPARSE_s_s (oHiddenRecipientFile, "hidden-recipient-file", "@"),
   ARGPARSE_s_s (oRecipient, "remote-user", "@"),  /* (old option name) */
   ARGPARSE_s_s (oDefRecipient, "default-recipient", "@"),
   ARGPARSE_s_n (oDefRecipientSelf,  "default-recipient-self", "@"),
@@ -519,6 +528,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oEncryptToDefaultKey, "encrypt-to-default-key", "@"),
   ARGPARSE_s_s (oLocalUser, "local-user",
                 N_("|USER-ID|use USER-ID to sign or decrypt")),
+  ARGPARSE_s_s (oSender, "sender", "@"),
 
   ARGPARSE_s_s (oTrySecretKey, "try-secret-key", "@"),
 
@@ -528,8 +538,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oBZ2CompressLevel, "bzip2-compress-level", "@"),
   ARGPARSE_s_n (oBZ2DecompressLowmem, "bzip2-decompress-lowmem", "@"),
 
+  ARGPARSE_s_n (oMimemode, "mimemode", "@"),
   ARGPARSE_s_n (oTextmodeShort, NULL, "@"),
-  ARGPARSE_s_n (oTextmode,      "textmode", N_("use canonical text mode")),
+  ARGPARSE_s_n (oTextmode,   "textmode", N_("use canonical text mode")),
   ARGPARSE_s_n (oNoTextmode, "no-textmode", "@"),
 
   ARGPARSE_s_n (oExpert,      "expert", "@"),
@@ -548,6 +559,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
   ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
+  ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"),
 
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
@@ -688,6 +700,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oHomedir, "homedir", "@"),
   ARGPARSE_s_n (oNoBatch, "no-batch", "@"),
   ARGPARSE_s_n (oWithColons, "with-colons", "@"),
+  ARGPARSE_s_n (oWithTofuInfo,"with-tofu-info", "@"),
   ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"),
   ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"),
   ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"),
@@ -703,7 +716,6 @@ static ARGPARSE_OPTS opts[] = {
 #endif
   ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
   ARGPARSE_s_s (oTOFUDefaultPolicy, "tofu-default-policy", "@"),
-  ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"),
   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
   ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"),
   ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"),
@@ -845,6 +857,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (opcscDriver, "pcsc-driver", "@"),
   ARGPARSE_s_n (oDisableCCID, "disable-ccid", "@"),
   ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
+  ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"),
 
   /* Dummy options.  */
   ARGPARSE_s_n (oNoop, "sk-comments", "@"),
@@ -2014,32 +2027,6 @@ parse_tofu_policy (const char *policystr)
   g10_exit (1);
 }
 
-static int
-parse_tofu_db_format (const char *db_format)
-{
-#ifdef USE_TOFU
-  if (ascii_strcasecmp (db_format, "auto") == 0)
-    return TOFU_DB_AUTO;
-  else if (ascii_strcasecmp (db_format, "split") == 0)
-    return TOFU_DB_SPLIT;
-  else if (ascii_strcasecmp (db_format, "flat") == 0)
-    return TOFU_DB_FLAT;
-  else if (ascii_strcasecmp (db_format, "help") == 0)
-    {
-      log_info ("available TOFU DB fomats: auto, split, flat\n");
-      g10_exit (1);
-    }
-  else
-#endif /*USE_TOFU*/
-    {
-      log_error (_("unknown TOFU DB format '%s'\n"), db_format);
-      if (!opt.quiet)
-        log_info (_("(use \"help\" to list choices)\n"));
-      g10_exit (1);
-    }
-}
-
-
 /* This function called to initialized a new control object.  It is
    assumed that this object has been zeroed out before calling this
    function. */
@@ -2167,15 +2154,19 @@ main (int argc, char **argv)
     int pwfd = -1;
     int fpr_maybe_cmd = 0; /* --fingerprint maybe a command.  */
     int any_explicit_recipient = 0;
-    int require_secmem=0,got_secmem=0;
+    int require_secmem = 0;
+    int got_secmem = 0;
     struct assuan_malloc_hooks malloc_hooks;
     ctrl_t ctrl;
 
+    static int print_dane_records;
+    static int print_pka_records;
+
+
 #ifdef __riscos__
     opt.lock_once = 1;
 #endif /* __riscos__ */
 
-
     /* Please note that we may running SUID(ROOT), so be very CAREFUL
        when adding any stuff between here and the call to
        secmem_init() somewhere after the option parsing. */
@@ -2185,20 +2176,12 @@ main (int argc, char **argv)
     gnupg_rl_initialize ();
     set_strusage (my_strusage);
     gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-    log_set_prefix (GPG_NAME, 1);
+    log_set_prefix (GPG_NAME, GPGRT_LOG_WITH_PREFIX);
 
     /* Make sure that our subsystems are ready.  */
     i18n_init();
     init_common_subsystems (&argc, &argv);
 
-    /* Check that the libraries are suitable.  Do it right here because the
-       option parsing may need services of the library.  */
-    if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
-      {
-        log_fatal ( _("libgcrypt is too old (need %s, have %s)\n"),
-                    NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
-      }
-
     /* Use our own logging handler for Libcgrypt.  */
     setup_libgcrypt_logging ();
 
@@ -2250,7 +2233,6 @@ main (int argc, char **argv)
     opt.trust_model = TM_AUTO;
 #endif
     opt.tofu_default_policy = TOFU_POLICY_AUTO;
-    opt.tofu_db_format = TOFU_DB_AUTO;
     opt.mangle_dos_filenames = 0;
     opt.min_cert_level = 2;
     set_screen_dimensions ();
@@ -2259,7 +2241,7 @@ main (int argc, char **argv)
     opt.def_cert_expire = "0";
     gnupg_set_homedir (NULL);
     opt.passphrase_repeat = 1;
-    opt.emit_version = 1; /* Limit to the major number.  */
+    opt.emit_version = 0;
     opt.weak_digests = NULL;
     additional_weak_digest("MD5");
 
@@ -2335,7 +2317,7 @@ main (int argc, char **argv)
     malloc_hooks.free = gcry_free;
     assuan_set_malloc_hooks (&malloc_hooks);
     assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-    setup_libassuan_logging (&opt.debug);
+    setup_libassuan_logging (&opt.debug, NULL);
 
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
@@ -2395,11 +2377,16 @@ main (int argc, char **argv)
       {
        switch( pargs.r_opt )
          {
-         case aCheckKeys:
          case aListConfig:
          case aListGcryptConfig:
           case aGPGConfList:
           case aGPGConfTest:
+            set_cmd (&cmd, pargs.r_opt);
+            /* Do not register a keyring for these commands.  */
+            default_keyring = -1;
+            break;
+
+         case aCheckKeys:
          case aListPackets:
          case aImport:
          case aFastImport:
@@ -2484,7 +2471,13 @@ main (int argc, char **argv)
 
          case oArmor: opt.armor = 1; opt.no_armor=0; break;
          case oOutput: opt.outfile = pargs.r.ret_str; break;
+
          case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
+
+          case oInputSizeHint:
+            opt.input_size_hint = string_to_u64 (pargs.r.ret_str);
+            break;
+
          case oQuiet: opt.quiet = 1; break;
          case oNoTTY: tty_no_terminal(1); break;
          case oDryRun: opt.dry_run = 1; break;
@@ -2664,6 +2657,8 @@ main (int argc, char **argv)
          case oHomedir: break;
          case oNoBatch: opt.batch = 0; break;
 
+          case oWithTofuInfo: opt.with_tofu_info = 1; break;
+
          case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/
          case oWithColons: opt.with_colons=':'; break;
 
@@ -2690,7 +2685,7 @@ main (int argc, char **argv)
            opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str);
            break;
          case oTOFUDBFormat:
-           opt.tofu_db_format = parse_tofu_db_format (pargs.r.ret_str);
+           obsolete_option (configname, configlineno, "tofu-db-format");
            break;
 
          case oForceOwnertrust:
@@ -2838,46 +2833,56 @@ main (int argc, char **argv)
             else
               opt.s2k_count = 0;  /* Auto-calibrate when needed.  */
            break;
-         case oNoEncryptTo: opt.no_encrypt_to = 1; break;
-         case oEncryptTo: /* store the recipient in the second list */
+
+         case oRecipient:
+         case oHiddenRecipient:
+         case oRecipientFile:
+         case oHiddenRecipientFile:
+            /* Store the recipient.  Note that we also store the
+             * option as private data in the flags.  This is achieved
+             * by shifting the option value to the left so to keep
+             * enough space for the flags.  */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO);
+           sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
             if (configfp)
               sl->flags |= PK_LIST_CONFIG;
+            if (pargs.r_opt == oHiddenRecipient
+                || pargs.r_opt == oHiddenRecipientFile)
+              sl->flags |= PK_LIST_HIDDEN;
+            if (pargs.r_opt == oRecipientFile
+                || pargs.r_opt == oHiddenRecipientFile)
+              sl->flags |= PK_LIST_FROM_FILE;
+            any_explicit_recipient = 1;
            break;
-         case oHiddenEncryptTo: /* store the recipient in the second list */
+
+         case oEncryptTo:
+         case oHiddenEncryptTo:
+            /* Store an additional recipient.  */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT)
-                         | PK_LIST_ENCRYPT_TO|PK_LIST_HIDDEN);
+           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO);
             if (configfp)
               sl->flags |= PK_LIST_CONFIG;
+            if (pargs.r_opt == oHiddenEncryptTo)
+              sl->flags |= PK_LIST_HIDDEN;
            break;
+
+         case oNoEncryptTo:
+            opt.no_encrypt_to = 1;
+            break;
           case oEncryptToDefaultKey:
             opt.encrypt_to_default_key = configfp ? 2 : 1;
             break;
-         case oRecipient: /* store the recipient */
-           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
-            if (configfp)
-              sl->flags |= PK_LIST_CONFIG;
-            any_explicit_recipient = 1;
-           break;
-         case oHiddenRecipient: /* store the recipient with a flag */
-           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_HIDDEN);
-            if (configfp)
-              sl->flags |= PK_LIST_CONFIG;
-            any_explicit_recipient = 1;
-           break;
 
          case oTrySecretKey:
            add_to_strlist2 (&opt.secret_keys_to_try,
                              pargs.r.ret_str, utf8_strings);
            break;
 
+          case oMimemode: opt.mimemode = opt.textmode = 1; break;
          case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
-         case oNoTextmode: opt.textmode=0;  break;
+         case oNoTextmode: opt.textmode=opt.mimemode=0;  break;
+
          case oExpert: opt.expert = 1; break;
          case oNoExpert: opt.expert = 0; break;
          case oDefSigExpire:
@@ -2914,6 +2919,19 @@ main (int argc, char **argv)
             if (configfp)
               sl->flags |= PK_LIST_CONFIG;
            break;
+         case oSender:
+            {
+              char *mbox = mailbox_from_userid (pargs.r.ret_str);
+              if (!mbox)
+                log_error (_("\"%s\" is not a proper mail address\n"),
+                           pargs.r.ret_str);
+              else
+                {
+                  add_to_strlist (&opt.sender_list, mbox);
+                  xfree (mbox);
+                }
+            }
+           break;
          case oCompress:
            /* this is the -z command line option */
            opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
@@ -3170,8 +3188,8 @@ main (int argc, char **argv)
          case oFastListMode: opt.fast_list_mode = 1; break;
          case oFixedListMode: /* Dummy */ break;
           case oLegacyListMode: opt.legacy_list_mode = 1; break;
-         case oPrintPKARecords: opt.print_pka_records = 1; break;
-         case oPrintDANERecords: opt.print_dane_records = 1; break;
+         case oPrintPKARecords: print_pka_records = 1; break;
+         case oPrintDANERecords: print_dane_records = 1; break;
          case oListOnly: opt.list_only=1; break;
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
@@ -3394,6 +3412,18 @@ main (int argc, char **argv)
     xfree (save_configname);
     xfree (default_configname);
 
+    if (print_dane_records)
+      log_error ("invalid option \"%s\"; use \"%s\" instead\n",
+                 "--print-dane-records",
+                 "--export-options export-dane");
+    if (print_pka_records)
+      log_error ("invalid option \"%s\"; use \"%s\" instead\n",
+                 "--print-pks-records",
+                 "--export-options export-pka");
+    if (log_get_errorcount (0))
+      g10_exit(2);
+
+
     if( nogreeting )
        greeting = 0;
 
@@ -3424,7 +3454,7 @@ main (int argc, char **argv)
     if (logfile && opt.batch)
       {
         log_set_file (logfile);
-        log_set_prefix (NULL, 1|2|4);
+        log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID);
       }
 
     if (opt.verbose > 2)
@@ -3435,6 +3465,10 @@ main (int argc, char **argv)
 
     if (opt.flags.rfc4880bis)
        log_info ("WARNING: using experimental features from RFC4880bis!\n");
+    else
+      {
+        opt.mimemode = 0; /* This will use text mode instead.  */
+      }
 
     if (eyes_only) {
       if (opt.set_filename)
@@ -3760,6 +3794,8 @@ main (int argc, char **argv)
       case aGenRandom:
       case aDeArmor:
       case aEnArmor:
+      case aListConfig:
+      case aListGcryptConfig:
        break;
       case aFixTrustDB:
       case aExportOwnerTrust:
@@ -4635,6 +4671,8 @@ main (int argc, char **argv)
          if (! hd)
             g10_exit (1);
 
+          tofu_begin_batch_update (ctrl);
+
          for (i = 1; i < argc; i ++)
            {
              KEYDB_SEARCH_DESC desc;
@@ -4692,8 +4730,9 @@ main (int argc, char **argv)
                g10_exit (1);
            }
 
-         keydb_release (hd);
+          tofu_end_batch_update (ctrl);
 
+         keydb_release (hd);
        }
 #endif /*USE_TOFU*/
        break;