gpg: Prepare some key cleaning function for use with secret key packets.
[gnupg.git] / g10 / gpg.c
index b33b61b..8c5b505 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -16,7 +16,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, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -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__)
@@ -99,6 +100,7 @@ enum cmd_and_opt_values
     aListSecretKeys = 'K',
     oBatch       = 500,
     oMaxOutput,
+    oInputSizeHint,
     oSigNotation,
     oCertNotation,
     oShowNotation,
@@ -121,6 +123,7 @@ enum cmd_and_opt_values
     aQuickAddUid,
     aQuickAddKey,
     aQuickRevUid,
+    aQuickSetExpire,
     aListConfig,
     aListGcryptConfig,
     aGPGConfList,
@@ -191,6 +194,11 @@ enum cmd_and_opt_values
     oWithKeygrip,
     oWithSecret,
     oWithWKDHash,
+    oWithColons,
+    oWithKeyData,
+    oWithTofuInfo,
+    oWithSigList,
+    oWithSigCheck,
     oAnswerYes,
     oAnswerNo,
     oKeyring,
@@ -217,6 +225,7 @@ enum cmd_and_opt_values
     oMarginalsNeeded,
     oMaxCertDepth,
     oLoadExtension,
+    oCompliance,
     oGnuPG,
     oRFC2440,
     oRFC4880,
@@ -225,6 +234,7 @@ enum cmd_and_opt_values
     oPGP6,
     oPGP7,
     oPGP8,
+    oDE_VS,
     oRFC2440Text,
     oNoRFC2440Text,
     oCipherAlgo,
@@ -257,10 +267,6 @@ enum cmd_and_opt_values
     oNoOptions,
     oNoBatch,
     oHomedir,
-    oWithColons,
-    oWithKeyData,
-    oWithSigList,
-    oWithSigCheck,
     oSkipVerify,
     oSkipHiddenRecipients,
     oNoSkipHiddenRecipients,
@@ -338,6 +344,7 @@ enum cmd_and_opt_values
     oIgnoreMDCError,
     oShowSessionKey,
     oOverrideSessionKey,
+    oOverrideSessionKeyFD,
     oNoRandomSeedFile,
     oAutoKeyRetrieve,
     oNoAutoKeyRetrieve,
@@ -401,10 +408,12 @@ enum cmd_and_opt_values
     oPrintDANERecords,
     oTOFUDefaultPolicy,
     oTOFUDBFormat,
+    oDefaultNewKeyAlgo,
     oWeakDigest,
     oUnwrap,
     oOnlySignTextIDs,
     oDisableSignerUID,
+    oSender,
 
     oNoop
   };
@@ -415,7 +424,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (300, N_("@Commands:\n ")),
 
   ARGPARSE_c (aSign, "sign", N_("make a signature")),
-  ARGPARSE_c (aClearsign, "clearsign", N_("make a clear text signature")),
+  ARGPARSE_c (aClearsign, "clear-sign", N_("make a clear text signature")),
+  ARGPARSE_c (aClearsign, "clearsign", "@"),
   ARGPARSE_c (aDetachedSign, "detach-sign", N_("make a detached signature")),
   ARGPARSE_c (aEncr, "encrypt",   N_("encrypt data")),
   ARGPARSE_c (aEncrFiles, "encrypt-files", "@"),
@@ -427,22 +437,35 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aVerifyFiles, "verify-files" , "@" ),
   ARGPARSE_c (aListKeys, "list-keys", N_("list keys")),
   ARGPARSE_c (aListKeys, "list-public-keys", "@" ),
-  ARGPARSE_c (aListSigs, "list-sigs", N_("list keys and signatures")),
-  ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")),
+  ARGPARSE_c (aListSigs, "list-signatures", N_("list keys and signatures")),
+  ARGPARSE_c (aListSigs, "list-sigs", "@"),
+  ARGPARSE_c (aCheckKeys, "check-signatures",
+             N_("list and check key signatures")),
+  ARGPARSE_c (aCheckKeys, "check-sigs", "@"),
   ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
   ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
-  ARGPARSE_c (aKeygen,     "gen-key",
+  ARGPARSE_c (aKeygen,     "generate-key",
               N_("generate a new key pair")),
-  ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
+  ARGPARSE_c (aKeygen,     "gen-key", "@"),
+  ARGPARSE_c (aQuickKeygen, "quick-generate-key" ,
               N_("quickly generate a new key pair")),
-  ARGPARSE_c (aQuickAddUid,  "quick-adduid",
+  ARGPARSE_c (aQuickKeygen, "quick-gen-key", "@"),
+  ARGPARSE_c (aQuickAddUid,  "quick-add-uid",
               N_("quickly add a new user-id")),
+  ARGPARSE_c (aQuickAddUid,  "quick-adduid", "@"),
+  ARGPARSE_c (aQuickAddKey,  "quick-add-key", "@"),
   ARGPARSE_c (aQuickAddKey,  "quick-addkey", "@"),
-  ARGPARSE_c (aQuickRevUid,  "quick-revuid",
+  ARGPARSE_c (aQuickRevUid,  "quick-revoke-uid",
               N_("quickly revoke a user-id")),
-  ARGPARSE_c (aFullKeygen,  "full-gen-key" ,
+  ARGPARSE_c (aQuickRevUid,  "quick-revuid", "@"),
+  ARGPARSE_c (aQuickSetExpire,  "quick-set-expire",
+              N_("quickly set a new expiration date")),
+  ARGPARSE_c (aFullKeygen,  "full-generate-key" ,
               N_("full featured key pair generation")),
-  ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
+  ARGPARSE_c (aFullKeygen,  "full-gen-key", "@"),
+  ARGPARSE_c (aGenRevoke, "generate-revocation",
+             N_("generate a revocation certificate")),
+  ARGPARSE_c (aGenRevoke, "gen-revoke", "@"),
   ARGPARSE_c (aDeleteKeys,"delete-keys",
               N_("remove keys from the public keyring")),
   ARGPARSE_c (aDeleteSecretKeys, "delete-secret-keys",
@@ -455,11 +478,14 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aLSignKey, "lsign-key"  ,N_("sign a key locally")),
   ARGPARSE_c (aEditKey,  "edit-key"   ,N_("sign or edit a key")),
   ARGPARSE_c (aEditKey,  "key-edit"   ,"@"),
-  ARGPARSE_c (aPasswd,   "passwd",     N_("change a passphrase")),
+  ARGPARSE_c (aPasswd,   "change-passphrase", N_("change a passphrase")),
+  ARGPARSE_c (aPasswd,   "passwd", "@"),
+  ARGPARSE_c (aDesigRevoke, "generate-designated-revocation", "@"),
   ARGPARSE_c (aDesigRevoke, "desig-revoke","@" ),
   ARGPARSE_c (aExport, "export"           , N_("export keys") ),
   ARGPARSE_c (aSendKeys, "send-keys"     , N_("export keys to a keyserver") ),
-  ARGPARSE_c (aRecvKeys, "recv-keys"     , N_("import keys from a keyserver") ),
+  ARGPARSE_c (aRecvKeys, "receive-keys" , N_("import keys from a keyserver") ),
+  ARGPARSE_c (aRecvKeys, "recv-keys"     , "@"),
   ARGPARSE_c (aSearchKeys, "search-keys" ,
               N_("search for keys on a keyserver") ),
   ARGPARSE_c (aRefreshKeys, "refresh-keys",
@@ -473,7 +499,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aFastImport, "fast-import", "@"),
 #ifdef ENABLE_CARD_SUPPORT
   ARGPARSE_c (aCardStatus,  "card-status", N_("print the card status")),
-  ARGPARSE_c (aCardEdit,   "card-edit",  N_("change data on a card")),
+  ARGPARSE_c (aCardEdit,   "edit-card",  N_("change data on a card")),
+  ARGPARSE_c (aCardEdit,   "card-edit", "@"),
   ARGPARSE_c (aChangePIN,  "change-pin", N_("change a card's PIN")),
 #endif
   ARGPARSE_c (aListConfig, "list-config", "@"),
@@ -524,6 +551,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", "@"),
 
@@ -554,6 +582,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",   "@"),
@@ -607,6 +636,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oLoadExtension, "load-extension", "@"),  /* Dummy.  */
 
+  ARGPARSE_s_s (oCompliance, "compliance",   "@"),
   ARGPARSE_s_n (oGnuPG, "gnupg",   "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp2", "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp6", "@"),
@@ -646,7 +676,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_group (303, N_("@\nExamples:\n\n"
     " -se -r Bob [file]          sign and encrypt for user Bob\n"
-    " --clearsign [file]         make a clear text signature\n"
+    " --clear-sign [file]        make a clear text signature\n"
     " --detach-sign [file]       make a detached signature\n"
     " --list-keys [names]        show keys\n"
     " --fingerprint [names]      show fingerprints\n")),
@@ -694,6 +724,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", "@"),
@@ -709,7 +740,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", "@"),
@@ -767,6 +797,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oIgnoreMDCError, "ignore-mdc-error", "@"),
   ARGPARSE_s_n (oShowSessionKey, "show-session-key", "@"),
   ARGPARSE_s_s (oOverrideSessionKey, "override-session-key", "@"),
+  ARGPARSE_s_i (oOverrideSessionKeyFD, "override-session-key-fd", "@"),
   ARGPARSE_s_n (oNoRandomSeedFile,  "no-random-seed-file", "@"),
   ARGPARSE_s_n (oAutoKeyRetrieve, "auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoAutoKeyRetrieve, "no-auto-key-retrieve", "@"),
@@ -825,6 +856,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoAllowMultipleMessages, "no-allow-multiple-messages", "@"),
   ARGPARSE_s_n (oAllowWeakDigestAlgos, "allow-weak-digest-algos", "@"),
 
+  ARGPARSE_s_s (oDefaultNewKeyAlgo, "default-new-key-algo", "@"),
+
   /* These two are aliases to help users of the PGP command line
      product use gpg with minimal pain.  Many commands are common
      already as they seem to have borrowed commands from us.  Now I'm
@@ -851,6 +884,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", "@"),
@@ -879,7 +913,6 @@ static struct debug_flags_s debug_flags [] =
     { DBG_MEMSTAT_VALUE, "memstat" },
     { DBG_TRUST_VALUE  , "trust"   },
     { DBG_HASHING_VALUE, "hashing" },
-    { DBG_CARD_IO_VALUE, "cardio"  },
     { DBG_IPC_VALUE    , "ipc"     },
     { DBG_CLOCK_VALUE  , "clock"   },
     { DBG_LOOKUP_VALUE , "lookup"  },
@@ -909,6 +942,7 @@ static void add_notation_data( const char *string, int which );
 static void add_policy_url( const char *string, int which );
 static void add_keyserver_url( const char *string, int which );
 static void emergency_cleanup (void);
+static void read_sessionkey_from_fd (int fd);
 
 
 static char *
@@ -1183,15 +1217,15 @@ set_debug (const char *level)
       g10_exit (2);
     }
 
-  if (opt.debug & DBG_MEMORY_VALUE )
+  if ((opt.debug & DBG_MEMORY_VALUE))
     memory_debug_mode = 1;
-  if (opt.debug & DBG_MEMSTAT_VALUE )
+  if ((opt.debug & DBG_MEMSTAT_VALUE))
     memory_stat_debug_mode = 1;
-  if (opt.debug & DBG_MPI_VALUE)
+  if (DBG_MPI)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
-  if (opt.debug & DBG_CRYPTO_VALUE )
+  if (DBG_CRYPTO)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
-  if (opt.debug & DBG_IOBUF_VALUE )
+  if ((opt.debug & DBG_IOBUF_VALUE))
     iobuf_debug_mode = 1;
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
@@ -1738,6 +1772,15 @@ list_config(char *items)
          any=1;
        }
 
+      if(show_all || ascii_strcasecmp (name, "compressname") == 0)
+       {
+         es_printf ("cfg:compressname:");
+         print_algo_names (check_compress_algo,
+                           compress_algo_to_string);
+         es_printf ("\n");
+         any=1;
+       }
+
       if (show_all || !ascii_strcasecmp(name,"ccid-reader-id"))
        {
           /* We ignore this for GnuPG 1.4 backward compatibility.  */
@@ -1800,11 +1843,13 @@ gpgconf_list (const char *configfile)
   es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
   es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
+  es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
 
   /* The next one is an info only item and should match the macros at
      the top of keygen.c  */
   es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
-             "RSA-2048");
+             get_default_pubkey_algo ());
 
   xfree (configfile_esc);
 }
@@ -2003,7 +2048,7 @@ parse_tofu_policy (const char *policystr)
 
   if (!ascii_strcasecmp (policystr, "help"))
     {
-      log_info (_("available TOFU policies:\n"));
+      log_info (_("valid values for option '%s':\n"), "--tofu-policy");
       for (i=0; i < DIM (list); i++)
         log_info ("  %s\n", list[i].keyword);
       g10_exit (1);
@@ -2020,32 +2065,113 @@ parse_tofu_policy (const char *policystr)
   g10_exit (1);
 }
 
+
+/* Parse the value of --compliance.  */
 static int
-parse_tofu_db_format (const char *db_format)
+parse_compliance_option (const char *string)
 {
-#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)
+  struct { const char *keyword; enum cmd_and_opt_values option; } list[] = {
+    { "gnupg",      oGnuPG },
+    { "openpgp",    oOpenPGP },
+    { "rfc4880bis", oRFC4880bis },
+    { "rfc4880",    oRFC4880 },
+    { "rfc2440",    oRFC2440 },
+    { "pgp6",       oPGP6 },
+    { "pgp7",       oPGP7 },
+    { "pgp8",       oPGP8 },
+    { "de-vs",      oDE_VS }
+  };
+  int i;
+
+  if (!ascii_strcasecmp (string, "help"))
     {
-      log_info ("available TOFU DB fomats: auto, split, flat\n");
+      log_info (_("valid values for option '%s':\n"), "--compliance");
+      for (i=0; i < DIM (list); i++)
+        log_info ("  %s\n", list[i].keyword);
       g10_exit (1);
     }
-  else
-#endif /*USE_TOFU*/
+
+  for (i=0; i < DIM (list); i++)
+    if (!ascii_strcasecmp (string, list[i].keyword))
+      return list[i].option;
+
+  log_error (_("invalid value for option '%s'\n"), "--compliance");
+  if (!opt.quiet)
+    log_info (_("(use \"help\" to list choices)\n"));
+  g10_exit (1);
+}
+
+
+
+/* Helper to set compliance related options.  This is a separte
+ * function so that it can also be used by the --compliance option
+ * parser.  */
+static void
+set_compliance_option (enum cmd_and_opt_values option)
+{
+  switch (option)
     {
-      log_error (_("unknown TOFU DB format '%s'\n"), db_format);
-      if (!opt.quiet)
-        log_info (_("(use \"help\" to list choices)\n"));
-      g10_exit (1);
+    case oRFC4880bis:
+      opt.flags.rfc4880bis = 1;
+      /* fall through.  */
+    case oOpenPGP:
+    case oRFC4880:
+      /* This is effectively the same as RFC2440, but with
+         "--enable-dsa2 --no-rfc2440-text --escape-from-lines
+         --require-cross-certification". */
+      opt.compliance = CO_RFC4880;
+      opt.flags.dsa2 = 1;
+      opt.flags.require_cross_cert = 1;
+      opt.rfc2440_text = 0;
+      opt.allow_non_selfsigned_uid = 1;
+      opt.allow_freeform_uid = 1;
+      opt.escape_from = 1;
+      opt.not_dash_escaped = 0;
+      opt.def_cipher_algo = 0;
+      opt.def_digest_algo = 0;
+      opt.cert_digest_algo = 0;
+      opt.compress_algo = -1;
+      opt.s2k_mode = 3; /* iterated+salted */
+      opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+      opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+      break;
+    case oRFC2440:
+      opt.compliance = CO_RFC2440;
+      opt.flags.dsa2 = 0;
+      opt.rfc2440_text = 1;
+      opt.allow_non_selfsigned_uid = 1;
+      opt.allow_freeform_uid = 1;
+      opt.escape_from = 0;
+      opt.not_dash_escaped = 0;
+      opt.def_cipher_algo = 0;
+      opt.def_digest_algo = 0;
+      opt.cert_digest_algo = 0;
+      opt.compress_algo = -1;
+      opt.s2k_mode = 3; /* iterated+salted */
+      opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+      opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+      break;
+    case oPGP6:  opt.compliance = CO_PGP6;  break;
+    case oPGP7:  opt.compliance = CO_PGP7;  break;
+    case oPGP8:  opt.compliance = CO_PGP8;  break;
+    case oGnuPG: opt.compliance = CO_GNUPG; break;
+
+    case oDE_VS:
+      set_compliance_option (oOpenPGP);
+      opt.compliance = CO_DE_VS;
+      /* Fixme: Change other options.  */
+      break;
+
+    default:
+      BUG ();
     }
 }
 
 
+
+
+
+
 /* This function called to initialized a new control object.  It is
    assumed that this object has been zeroed out before calling this
    function. */
@@ -2171,6 +2297,7 @@ main (int argc, char **argv)
     int eyes_only=0;
     int multifile=0;
     int pwfd = -1;
+    int ovrseskeyfd = -1;
     int fpr_maybe_cmd = 0; /* --fingerprint maybe a command.  */
     int any_explicit_recipient = 0;
     int require_secmem = 0;
@@ -2195,20 +2322,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 ();
 
@@ -2260,7 +2379,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 ();
@@ -2345,7 +2463,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 ();
@@ -2405,11 +2523,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:
@@ -2455,6 +2578,7 @@ main (int argc, char **argv)
          case aQuickAddUid:
          case aQuickAddKey:
          case aQuickRevUid:
+         case aQuickSetExpire:
          case aExportOwnerTrust:
          case aImportOwnerTrust:
           case aRebuildKeydbCaches:
@@ -2494,7 +2618,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;
@@ -2674,6 +2804,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;
 
@@ -2700,7 +2832,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:
@@ -2717,52 +2849,24 @@ main (int argc, char **argv)
             /* Dummy so that gpg 1.4 conf files can work. Should
                eventually be removed.  */
            break;
+
+          case oCompliance:
+            set_compliance_option (parse_compliance_option (pargs.r.ret_str));
+            break;
+          case oOpenPGP:
+          case oRFC2440:
+          case oRFC4880:
           case oRFC4880bis:
-            opt.flags.rfc4880bis = 1;
-            /* fall thru.  */
-         case oOpenPGP:
-         case oRFC4880:
-           /* This is effectively the same as RFC2440, but with
-              "--enable-dsa2 --no-rfc2440-text --escape-from-lines
-              --require-cross-certification". */
-           opt.compliance = CO_RFC4880;
-           opt.flags.dsa2 = 1;
-           opt.flags.require_cross_cert = 1;
-           opt.rfc2440_text = 0;
-           opt.allow_non_selfsigned_uid = 1;
-           opt.allow_freeform_uid = 1;
-           opt.escape_from = 1;
-           opt.not_dash_escaped = 0;
-           opt.def_cipher_algo = 0;
-           opt.def_digest_algo = 0;
-           opt.cert_digest_algo = 0;
-           opt.compress_algo = -1;
-            opt.s2k_mode = 3; /* iterated+salted */
-           opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
-           opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
-           break;
-         case oRFC2440:
-           opt.compliance = CO_RFC2440;
-           opt.flags.dsa2 = 0;
-           opt.rfc2440_text = 1;
-           opt.allow_non_selfsigned_uid = 1;
-           opt.allow_freeform_uid = 1;
-           opt.escape_from = 0;
-           opt.not_dash_escaped = 0;
-           opt.def_cipher_algo = 0;
-           opt.def_digest_algo = 0;
-           opt.cert_digest_algo = 0;
-           opt.compress_algo = -1;
-            opt.s2k_mode = 3; /* iterated+salted */
-           opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
-           opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
-           break;
-         case oPGP6:  opt.compliance = CO_PGP6;  break;
-         case oPGP7:  opt.compliance = CO_PGP7;  break;
-         case oPGP8:  opt.compliance = CO_PGP8;  break;
-         case oGnuPG: opt.compliance = CO_GNUPG; break;
-         case oRFC2440Text: opt.rfc2440_text=1; break;
-         case oNoRFC2440Text: opt.rfc2440_text=0; break;
+          case oPGP6:
+          case oPGP7:
+          case oPGP8:
+          case oGnuPG:
+            set_compliance_option (pargs.r_opt);
+            break;
+
+          case oRFC2440Text: opt.rfc2440_text=1; break;
+          case oNoRFC2440Text: opt.rfc2440_text=0; break;
+
          case oSetFilename:
             if(utf8_strings)
               opt.set_filename = pargs.r.ret_str;
@@ -2934,6 +3038,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;
@@ -3209,6 +3326,9 @@ main (int argc, char **argv)
          case oOverrideSessionKey:
                opt.override_session_key = pargs.r.ret_str;
                break;
+         case oOverrideSessionKeyFD:
+                ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
+               break;
          case oMergeOnly:
                deprecated_warning(configname,configlineno,"--merge-only",
                                   "--import-options ","merge-only");
@@ -3217,9 +3337,11 @@ main (int argc, char **argv)
           case oAllowSecretKeyImport: /* obsolete */ break;
          case oTryAllSecrets: opt.try_all_secrets = 1; break;
           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
+
           case oEnableSpecialFilenames:
-            iobuf_enable_special_filenames (1);
+            enable_special_filenames ();
             break;
+
           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
@@ -3380,6 +3502,10 @@ main (int argc, char **argv)
 
           case oNoAutostart: opt.autostart = 0; break;
 
+         case oDefaultNewKeyAlgo:
+            opt.def_new_key_algo = pargs.r.ret_str;
+            break;
+
          case oNoop: break;
 
          default:
@@ -3456,7 +3582,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)
@@ -3640,7 +3766,7 @@ main (int argc, char **argv)
            cmdname="--sign --encrypt";
            break;
          case aClearsign:
-           cmdname="--clearsign";
+           cmdname="--clear-sign";
            break;
          case aDetachedSign:
            cmdname="--detach-sign";
@@ -3776,8 +3902,11 @@ main (int argc, char **argv)
       g10_exit(0);
 
 
-    if( pwfd != -1 )  /* Read the passphrase now. */
-       read_passphrase_from_fd( pwfd );
+    if (pwfd != -1)  /* Read the passphrase now. */
+      read_passphrase_from_fd (pwfd);
+
+    if (ovrseskeyfd != -1 )  /* Read the sessionkey now. */
+      read_sessionkey_from_fd (ovrseskeyfd);
 
     fname = argc? *argv : NULL;
 
@@ -3796,6 +3925,8 @@ main (int argc, char **argv)
       case aGenRandom:
       case aDeArmor:
       case aEnArmor:
+      case aListConfig:
+      case aListGcryptConfig:
        break;
       case aFixTrustDB:
       case aExportOwnerTrust:
@@ -3880,7 +4011,7 @@ main (int argc, char **argv)
 
       case aStore: /* only store the file */
        if( argc > 1 )
-           wrong_args(_("--store [filename]"));
+           wrong_args("--store [filename]");
        if( (rc = encrypt_store(fname)) )
           {
             write_status_failure ("store", rc);
@@ -3890,7 +4021,7 @@ main (int argc, char **argv)
        break;
       case aSym: /* encrypt the given file only with the symmetric cipher */
        if( argc > 1 )
-           wrong_args(_("--symmetric [filename]"));
+           wrong_args("--symmetric [filename]");
        if( (rc = encrypt_symmetric(fname)) )
           {
             write_status_failure ("symencrypt", rc);
@@ -3905,7 +4036,7 @@ main (int argc, char **argv)
        else
          {
            if( argc > 1 )
-             wrong_args(_("--encrypt [filename]"));
+             wrong_args("--encrypt [filename]");
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) )
               {
                 write_status_failure ("encrypt", rc);
@@ -3921,7 +4052,7 @@ main (int argc, char **argv)
           might work with 7, but alas, I don't have a copy to test
           with right now. */
        if( argc > 1 )
-         wrong_args(_("--symmetric --encrypt [filename]"));
+         wrong_args("--symmetric --encrypt [filename]");
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --encrypt"
                      " with --s2k-mode 0\n"));
@@ -3947,7 +4078,7 @@ main (int argc, char **argv)
        }
        else {
            if( argc > 1 )
-               wrong_args(_("--sign [filename]"));
+               wrong_args("--sign [filename]");
            if( argc ) {
                sl = xmalloc_clear( sizeof *sl + strlen(fname));
                strcpy(sl->d, fname);
@@ -3963,7 +4094,7 @@ main (int argc, char **argv)
 
       case aSignEncr: /* sign and encrypt the given file */
        if( argc > 1 )
-           wrong_args(_("--sign --encrypt [filename]"));
+           wrong_args("--sign --encrypt [filename]");
        if( argc ) {
            sl = xmalloc_clear( sizeof *sl + strlen(fname));
            strcpy(sl->d, fname);
@@ -3981,7 +4112,7 @@ main (int argc, char **argv)
 
       case aSignEncrSym: /* sign and encrypt the given file */
        if( argc > 1 )
-           wrong_args(_("--symmetric --sign --encrypt [filename]"));
+           wrong_args("--symmetric --sign --encrypt [filename]");
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --sign --encrypt"
                      " with --s2k-mode 0\n"));
@@ -4010,7 +4141,7 @@ main (int argc, char **argv)
 
       case aSignSym: /* sign and conventionally encrypt the given file */
        if (argc > 1)
-           wrong_args(_("--sign --symmetric [filename]"));
+           wrong_args("--sign --symmetric [filename]");
        rc = sign_symencrypt_file (ctrl, fname, locusr);
         if (rc)
           {
@@ -4022,11 +4153,11 @@ main (int argc, char **argv)
 
       case aClearsign: /* make a clearsig */
        if( argc > 1 )
-           wrong_args(_("--clearsign [filename]"));
+           wrong_args("--clear-sign [filename]");
        if( (rc = clearsign_file (ctrl, fname, locusr, NULL)) )
           {
             write_status_failure ("sign", rc);
-           log_error("%s: clearsign failed: %s\n",
+           log_error("%s: clear-sign failed: %s\n",
                       print_fname_stdin(fname), gpg_strerror (rc) );
           }
        break;
@@ -4052,7 +4183,7 @@ main (int argc, char **argv)
        else
          {
            if( argc > 1 )
-             wrong_args(_("--decrypt [filename]"));
+             wrong_args("--decrypt [filename]");
            if( (rc = decrypt_message (ctrl, fname) ))
               {
                 write_status_failure ("decrypt", rc);
@@ -4079,11 +4210,11 @@ main (int argc, char **argv)
 
       case aSignKey:
        if( argc != 1 )
-         wrong_args(_("--sign-key user-id"));
+         wrong_args("--sign-key user-id");
        /* fall through */
       case aLSignKey:
        if( argc != 1 )
-         wrong_args(_("--lsign-key user-id"));
+         wrong_args("--lsign-key user-id");
        /* fall through */
 
        sl=NULL;
@@ -4104,7 +4235,7 @@ main (int argc, char **argv)
 
       case aEditKey: /* Edit a key signature */
        if( !argc )
-           wrong_args(_("--edit-key user-id [commands]"));
+           wrong_args("--edit-key user-id [commands]");
        username = make_username( fname );
        if( argc > 1 ) {
            sl = NULL;
@@ -4120,7 +4251,7 @@ main (int argc, char **argv)
 
       case aPasswd:
         if (argc != 1)
-          wrong_args (_("--passwd <user-id>"));
+          wrong_args("--change-passphrase <user-id>");
         else
           {
             username = make_username (fname);
@@ -4173,7 +4304,7 @@ main (int argc, char **argv)
           const char *x_algo, *x_usage, *x_expire;
 
           if (argc < 1 || argc > 4)
-            wrong_args("--quick-gen-key USER-ID [ALGO [USAGE [EXPIRE]]]");
+            wrong_args("--quick-generate-key USER-ID [ALGO [USAGE [EXPIRE]]]");
           username = make_username (fname);
           argv++, argc--;
           x_algo = "";
@@ -4199,20 +4330,20 @@ main (int argc, char **argv)
       case aKeygen: /* generate a key */
        if( opt.batch ) {
            if( argc > 1 )
-               wrong_args("--gen-key [parameterfile]");
+               wrong_args("--generate-key [parameterfile]");
            generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
        }
        else {
             if (opt.command_fd != -1 && argc)
               {
                 if( argc > 1 )
-                  wrong_args("--gen-key [parameterfile]");
+                  wrong_args("--generate-key [parameterfile]");
 
                 opt.batch = 1;
                 generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
               }
             else if (argc)
-              wrong_args ("--gen-key");
+              wrong_args ("--generate-key");
             else
               generate_keypair (ctrl, 0, NULL, NULL, 0);
        }
@@ -4222,13 +4353,13 @@ main (int argc, char **argv)
        if (opt.batch)
           {
            if (argc > 1)
-              wrong_args ("--full-gen-key [parameterfile]");
+              wrong_args ("--full-generate-key [parameterfile]");
            generate_keypair (ctrl, 1, argc? *argv : NULL, NULL, 0);
           }
        else
           {
            if (argc)
-              wrong_args("--full-gen-key");
+              wrong_args("--full-generate-key");
            generate_keypair (ctrl, 1, NULL, NULL, 0);
        }
        break;
@@ -4238,7 +4369,7 @@ main (int argc, char **argv)
           const char *uid, *newuid;
 
           if (argc != 2)
-            wrong_args ("--quick-adduid USER-ID NEW-USER-ID");
+            wrong_args ("--quick-add-uid USER-ID NEW-USER-ID");
           uid = *argv++; argc--;
           newuid = *argv++; argc--;
           keyedit_quick_adduid (ctrl, uid, newuid);
@@ -4250,7 +4381,7 @@ main (int argc, char **argv)
           const char *x_fpr, *x_algo, *x_usage, *x_expire;
 
           if (argc < 1 || argc > 4)
-            wrong_args ("--quick-addkey FINGERPRINT [ALGO [USAGE [EXPIRE]]]");
+            wrong_args ("--quick-add-key FINGERPRINT [ALGO [USAGE [EXPIRE]]]");
           x_fpr = *argv++; argc--;
           x_algo = "";
           x_usage = "";
@@ -4276,13 +4407,25 @@ main (int argc, char **argv)
           const char *uid, *uidtorev;
 
           if (argc != 2)
-            wrong_args ("--quick-revuid USER-ID USER-ID-TO-REVOKE");
+            wrong_args ("--quick-revoke-uid USER-ID USER-ID-TO-REVOKE");
           uid = *argv++; argc--;
           uidtorev = *argv++; argc--;
           keyedit_quick_revuid (ctrl, uid, uidtorev);
         }
        break;
 
+      case aQuickSetExpire:
+        {
+          const char *x_fpr, *x_expire;
+
+          if (argc != 2)
+            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
+          x_fpr = *argv++; argc--;
+          x_expire = *argv++; argc--;
+          keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
+        }
+       break;
+
       case aFastImport:
         opt.import_options |= IMPORT_FAST;
       case aImport:
@@ -4411,7 +4554,7 @@ main (int argc, char **argv)
 
       case aGenRevoke:
        if( argc != 1 )
-           wrong_args("--gen-revoke user-id");
+           wrong_args("--generate-revocation user-id");
        username =  make_username(*argv);
        gen_revoke( username );
        xfree( username );
@@ -4419,7 +4562,7 @@ main (int argc, char **argv)
 
       case aDesigRevoke:
        if (argc != 1)
-           wrong_args ("--desig-revoke user-id");
+           wrong_args ("--generate-designated-revocation user-id");
        username = make_username (*argv);
        gen_desig_revoke (ctrl, username, locusr);
        xfree (username);
@@ -4671,6 +4814,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;
@@ -4726,10 +4871,13 @@ main (int argc, char **argv)
              merge_keys_and_selfsig (kb);
              if (tofu_set_policy (ctrl, kb, policy))
                g10_exit (1);
+
+              release_kbnode (kb);
            }
 
-         keydb_release (hd);
+          tofu_end_batch_update (ctrl);
 
+         keydb_release (hd);
        }
 #endif /*USE_TOFU*/
        break;
@@ -4737,7 +4885,7 @@ main (int argc, char **argv)
       case aListPackets:
       default:
        if( argc > 1 )
-           wrong_args(_("[filename]"));
+           wrong_args("[filename]");
        /* Issue some output for the unix newbie */
        if (!fname && !opt.outfile
             && gnupg_isatty (fileno (stdin))
@@ -5127,3 +5275,34 @@ add_keyserver_url( const char *string, int which )
   if(critical)
     sl->flags |= 1;
 }
+
+
+static void
+read_sessionkey_from_fd (int fd)
+{
+  int i, len;
+  char *line;
+
+  for (line = NULL, i = len = 100; ; i++ )
+    {
+      if (i >= len-1 )
+        {
+          char *tmp = line;
+          len += 100;
+          line = xmalloc_secure (len);
+          if (tmp)
+            {
+              memcpy (line, tmp, i);
+              xfree (tmp);
+            }
+          else
+            i=0;
+       }
+      if (read (fd, line + i, 1) != 1 || line[i] == '\n')
+        break;
+    }
+  line[i] = 0;
+  log_debug ("seskey: %s\n", line);
+  gpgrt_annotate_leaked_object (line);
+  opt.override_session_key = line;
+}