* g10.c (main): Handle --strict and --no-strict from the command line
[gnupg.git] / g10 / g10.c
index f2cef6f..c2e095b 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <assert.h>
 #ifdef HAVE_DOSISH_SYSTEM
   #include <fcntl.h> /* for setmode() */
 #endif
+#ifdef HAVE_STAT
+#include <sys/stat.h> /* for stat() */
+#endif
 
 #define INCLUDED_BY_MAIN_MODULE 1
 #include "packet.h"
@@ -186,6 +190,7 @@ enum cmd_and_opt_values { aNull = 0,
     oTrustDBName,
     oNoSecmemWarn,
     oNoPermissionWarn,
+    oNoMDCWarn,
     oNoArmor,
     oNoDefKeyring,
     oNoGreeting,
@@ -237,6 +242,8 @@ enum cmd_and_opt_values { aNull = 0,
     oLockNever,
     oKeyServer,
     oKeyServerOptions,
+    oImportOptions,
+    oExportOptions,
     oTempDir,
     oExecPath,
     oEncryptTo,
@@ -261,8 +268,9 @@ enum cmd_and_opt_values { aNull = 0,
     oFastListMode,
     oListOnly,
     oIgnoreTimeConflict,
-    oIgnoreValidFrom,                         
-    oIgnoreCrcError,                          
+    oIgnoreValidFrom,
+    oIgnoreCrcError,
+    oIgnoreMDCError,
     oShowSessionKey,
     oOverrideSessionKey,
     oNoRandomSeedFile,
@@ -285,7 +293,6 @@ enum cmd_and_opt_values { aNull = 0,
     oPersonalCipherPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
-    oEmu3DESS2KBug,  /* will be removed in 1.1 */
     oEmuMDEncodeBug,
     oDisplay,
     oTTYname,
@@ -293,6 +300,8 @@ enum cmd_and_opt_values { aNull = 0,
     oLCctype,
     oLCmessages,
     oGroup,
+    oStrict,
+    oNoStrict,
 aTest };
 
 
@@ -396,7 +405,7 @@ static ARGPARSE_OPTS opts[] = {
     { oDisableMDC, "disable-mdc", 0, N_("never use a MDC for encryption") },
     { oNoDisableMDC, "no-disable-mdc", 0, "@" },
     { oDryRun, "dry-run",   0, N_("do not make any changes") },
-  /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
+    { oInteractive, "interactive", 0, N_("prompt before overwriting") },
     { oUseAgent, "use-agent",0, N_("use the gpg-agent")},
     { oNoUseAgent, "no-use-agent",0, "@"},
     { oGpgAgentInfo, "gpg-agent-info",2, "@"},
@@ -409,6 +418,8 @@ static ARGPARSE_OPTS opts[] = {
     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
     { oKeyServerOptions, "keyserver-options",2,"@"},
+    { oImportOptions, "import-options",2,"@"},
+    { oExportOptions, "export-options",2,"@"},
     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
     { oOptions, "options"   , 2, N_("read options from file")},
 
@@ -487,6 +498,7 @@ static ARGPARSE_OPTS opts[] = {
     { oTrustDBName, "trustdb-name", 2, "@" },
     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
     { oNoPermissionWarn, "no-permission-warning", 0, "@" },
+    { oNoMDCWarn, "no-mdc-warning", 0, "@" },
     { oNoArmor, "no-armor",   0, "@"},
     { oNoArmor, "no-armour",   0, "@"},
     { oNoDefKeyring, "no-default-keyring", 0, "@" },
@@ -549,6 +561,7 @@ static ARGPARSE_OPTS opts[] = {
     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
     { oIgnoreValidFrom,    "ignore-valid-from",    0, "@" },
     { oIgnoreCrcError, "ignore-crc-error", 0,"@" },
+    { oIgnoreMDCError, "ignore-mdc-error", 0,"@" },
     { oShowSessionKey, "show-session-key", 0, "@" },
     { oOverrideSessionKey, "override-session-key", 2, "@" },
     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
@@ -570,7 +583,6 @@ static ARGPARSE_OPTS opts[] = {
     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
-    { oEmu3DESS2KBug,  "emulate-3des-s2k-bug", 0, "@"},
     { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
     { oDisplay,    "display",     2, "@" },
     { oTTYname,    "ttyname",     2, "@" },
@@ -578,6 +590,8 @@ static ARGPARSE_OPTS opts[] = {
     { oLCctype,    "lc-ctype",    2, "@" },
     { oLCmessages, "lc-messages", 2, "@" },
     { oGroup,      "group",       2, "@" },
+    { oStrict,     "strict",      0, "@" },
+    { oNoStrict,   "no-strict",   0, "@" },
 {0} };
 
 
@@ -769,6 +783,17 @@ set_debug(void)
 }
 
 
+/* We need the home directory also in some other directories, so make
+   sure that both variables are always in sync. */
+static void
+set_homedir (char *dir)
+{
+  if (!dir)
+    dir = "";
+  g10_opt_homedir = opt.homedir = dir;
+}
+
+
 static void
 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
 {
@@ -805,10 +830,10 @@ static void add_group(char *string)
   STRLIST values=NULL;
 
   /* Break off the group name */
-  name=strsep(&string," ");
+  name=strsep(&string,"=");
   if(string==NULL)
     {
-      log_error(_("no values for group \"%s\"\n"),name);
+      log_error(_("no = sign found in group definition \"%s\"\n"),name);
       return;
     }
 
@@ -824,6 +849,209 @@ static void add_group(char *string)
   opt.grouplist=item;
 }
 
+/* We need to check three things.
+
+   0) The homedir.  It must be x00, a directory, and owned by the
+   user.
+
+   1) The options file.  Okay unless it or its containing directory is
+   group or other writable or not owned by us.  disable exec in this
+   case.
+
+   2) Extensions.  Same as #2.
+
+   Returns true if the item is unsafe. */
+static int
+check_permissions(const char *path,int item)
+{
+#if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
+  static int homedir_cache=-1;
+  char *tmppath,*dir;
+  struct stat statbuf,dirbuf;
+  int homedir=0,ret=0,checkonly=0;
+  int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0;
+
+  if(opt.no_perm_warn)
+    return 0;
+
+  assert(item==0 || item==1 || item==2);
+
+  /* extensions may attach a path */
+  if(item==2 && path[0]!=DIRSEP_C)
+    {
+      if(strchr(path,DIRSEP_C))
+       tmppath=make_filename(path,NULL);
+      else
+       tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
+    }
+  else
+    tmppath=m_strdup(path);
+
+  /* If the item is located in the homedir, but isn't the homedir,
+     don't continue if we already checked the homedir itself.  This is
+     to avoid user confusion with an extra options file warning which
+     could be rectified if the homedir itself had proper
+     permissions. */
+  if(item!=0 && homedir_cache>-1
+     && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
+    {
+      ret=homedir_cache;
+      goto end;
+    }
+
+  /* It's okay if the file or directory doesn't exist */
+  if(stat(tmppath,&statbuf)!=0)
+    {
+      ret=0;
+      goto end;
+    }
+
+  /* Now check the enclosing directory.  Theoretically, we could walk
+     this test up to the root directory /, but for the sake of sanity,
+     I'm stopping at one level down. */
+  dir=make_dirname(tmppath);
+
+  if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode))
+    {
+      /* Weird error */
+      ret=1;
+      goto end;
+    }
+
+  m_free(dir);
+
+  /* Assume failure */
+  ret=1;
+
+  if(item==0)
+    {
+      /* The homedir must be x00, a directory, and owned by the user. */
+
+      if(S_ISDIR(statbuf.st_mode))
+       {
+         if(statbuf.st_uid==getuid())
+           {
+             if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
+               ret=0;
+             else
+               perm=1;
+           }
+         else
+           own=1;
+
+         homedir_cache=ret;
+       }
+    }
+  else if(item==1 || item==2)
+    {
+      /* The options or extension file.  Okay unless it or its
+        containing directory is group or other writable or not owned
+        by us or root. */
+
+      if(S_ISREG(statbuf.st_mode))
+       {
+         if(statbuf.st_uid==getuid() || statbuf.st_uid==0)
+           {
+             if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
+               {
+                 /* it's not writable, so make sure the enclosing
+                     directory is also not writable */
+                 if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
+                   {
+                     if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
+                       ret=0;
+                     else
+                       enc_dir_perm=1;
+                   }
+                 else
+                   enc_dir_own=1;
+               }
+             else
+               {
+                 /* it's writable, so the enclosing directory had
+                     better not let people get to it. */
+                 if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
+                   {
+                     if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
+                       ret=0;
+                     else
+                       perm=enc_dir_perm=1; /* unclear which one to fix! */
+                   }
+                 else
+                   enc_dir_own=1;
+               }
+           }
+         else
+           own=1;
+       }
+    }
+  else
+    BUG();
+
+  if(!checkonly)
+    {
+      if(own)
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe ownership on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe ownership on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe ownership on "
+                      "extension \"%s\"\n"),tmppath);
+       }
+      if(perm)
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe permissions on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe permissions on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe permissions on "
+                      "extension \"%s\"\n"),tmppath);
+       }
+      if(enc_dir_own)
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe enclosing directory ownership on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe enclosing directory ownership on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe enclosing directory ownership on "
+                      "extension \"%s\"\n"),tmppath);
+       }
+      if(enc_dir_perm)
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe enclosing directory permissions on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe enclosing directory permissions on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe enclosing directory permissions on "
+                      "extension \"%s\"\n"),tmppath);
+       }
+    }
+
+ end:
+  m_free(tmppath);
+
+  if(homedir)
+    homedir_cache=ret;
+
+  return ret;
+
+#endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
+
+  return 0;
+}
 
 int
 main( int argc, char **argv )
@@ -835,8 +1063,6 @@ main( int argc, char **argv )
     char **orig_argv;
     const char *fname;
     char *username;
-    STRLIST unsafe_files=NULL;
-    STRLIST extensions=NULL;
     int may_coredump;
     STRLIST sl, remusr= NULL, locusr=NULL;
     STRLIST nrings=NULL, sec_nrings=NULL;
@@ -902,15 +1128,22 @@ main( int argc, char **argv )
     opt.pgp2_workarounds = 1;
     opt.force_v3_sigs = 1;
     opt.escape_from = 1;
+    opt.import_options=0;
+    opt.export_options=
+      EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
+    opt.keyserver_options.import_options=IMPORT_REPAIR_HKP_SUBKEY_BUG;
+    opt.keyserver_options.export_options=
+      EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
     opt.keyserver_options.include_subkeys=1;
+    opt.keyserver_options.include_revoked=1;
 #if defined (__MINGW32__) || defined (__CYGWIN32__)
-    opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
+    set_homedir ( read_w32_registry_string( NULL,
+                                    "Software\\GNU\\GnuPG", "HomeDir" ));
 #else
-    opt.homedir = getenv("GNUPGHOME");
+    set_homedir ( getenv("GNUPGHOME") );
 #endif
-    if( !opt.homedir || !*opt.homedir ) {
-       opt.homedir = GNUPG_HOMEDIR;
-    }
+    if( !*opt.homedir )
+       set_homedir ( GNUPG_HOMEDIR );
 
     /* check whether we have a config file on the commandline */
     orig_argc = argc;
@@ -930,7 +1163,19 @@ main( int argc, char **argv )
        else if( pargs.r_opt == oNoOptions )
            default_config = 0; /* --no-options */
        else if( pargs.r_opt == oHomedir )
-           opt.homedir = pargs.r.ret_str;
+           set_homedir ( pargs.r.ret_str );
+       else if( pargs.r_opt == oNoPermissionWarn )
+           opt.no_perm_warn=1;
+       else if (pargs.r_opt == oStrict )
+         {
+           opt.strict=1;
+           log_set_strict(1);
+         }
+       else if (pargs.r_opt == oNoStrict )
+         {
+           opt.strict=0;
+           log_set_strict(0);
+         }
       #ifdef USE_SHM_COPROCESSING
        else if( pargs.r_opt == oRunAsShmCP ) {
            /* does not make sense in a options file, we do it here,
@@ -953,7 +1198,7 @@ main( int argc, char **argv )
         for (d=buf,s=opt.homedir; *s; s++)
             *d++ = *s == '\\'? '/': *s;
         *d = 0;
-        opt.homedir = buf;
+        set_homedir (buf);
     }
 #endif
 #ifdef USE_SHM_COPROCESSING
@@ -966,21 +1211,37 @@ main( int argc, char **argv )
     maybe_setuid = 0;
     /* Okay, we are now working under our real uid */
 
-    if( default_config )
-       configname = make_filename(opt.homedir, "options", NULL );
+    set_native_charset (NULL); /* Try to auto set the character set */
 
+    if( default_config )
+      {
+       configname = make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
+        if (!access (configname, R_OK))
+          { /* Print a warning when both config files are present. */
+            char *p = make_filename(opt.homedir, "options", NULL );
+            if (!access (p, R_OK))
+              log_info (_("NOTE: old default options file `%s' ignored\n"), p);
+            m_free (p);
+          }
+        else
+          { /* Keep on using the old default one. */
+            m_free (configname);
+            configname = make_filename(opt.homedir, "options", NULL );
+          }
+      }
     argc = orig_argc;
     argv = orig_argv;
     pargs.argc = &argc;
     pargs.argv = &argv;
     pargs.flags=  1;  /* do not remove the args */
+
+    /* By this point we have a homedir, and cannot change it. */
+    check_permissions(opt.homedir,0);
+
   next_pass:
     if( configname ) {
-
-      if(check_permissions(configname,0,1))
+      if(check_permissions(configname,1))
        {
-         add_to_strlist(&unsafe_files,configname);
-
          /* If any options file is unsafe, then disable any external
             programs for keyserver calls or photo IDs.  Since the
             external program to call is set in the options file, a
@@ -1179,9 +1440,14 @@ main( int argc, char **argv )
          case oAlwaysTrust: opt.always_trust = 1; break;
          case oLoadExtension:
 #ifndef __riscos__
-           add_to_strlist(&extensions,pargs.r.ret_str);
-           register_cipher_extension(orig_argc? *orig_argv:NULL,
-                                     pargs.r.ret_str);
+#if defined(USE_DYNAMIC_LINKING) || defined(__MINGW32__)
+           if(check_permissions(pargs.r.ret_str,2))
+             log_info(_("cipher extension \"%s\" not loaded due to "
+                        "unsafe permissions\n"),pargs.r.ret_str);
+           else
+             register_cipher_extension(orig_argc? *orig_argv:NULL,
+                                       pargs.r.ret_str);
+#endif
 #else /* __riscos__ */
             not_implemented("load-extension");
 #endif /* __riscos__ */
@@ -1190,12 +1456,15 @@ main( int argc, char **argv )
            opt.rfc1991 = 1;
            opt.rfc2440 = 0;
            opt.force_v4_certs = 0;
-           opt.sk_comments = 0;
+           opt.disable_mdc = 1;
            opt.escape_from = 1;
            break;
          case oOpenPGP:
+           /* TODO: When 2440bis becomes a RFC, these may need
+               changing. */
            opt.rfc1991 = 0;
            opt.rfc2440 = 1;
+           opt.disable_mdc = 1;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
@@ -1218,17 +1487,15 @@ main( int argc, char **argv )
          case oNoPGP6: opt.pgp6 = 0; break;
          case oPGP7: opt.pgp7 = 1; break;
          case oNoPGP7: opt.pgp7 = 0; break;
-         case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
-         case oEmu3DESS2KBug:  opt.emulate_bugs |= EMUBUG_3DESS2K; break;
          case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break;
          case oCompressSigs: opt.compress_sigs = 1; break;
          case oRunAsShmCP:
 #ifndef __riscos__
-         #ifndef USE_SHM_COPROCESSING
+ifndef USE_SHM_COPROCESSING
            /* not possible in the option file,
             * but we print the warning here anyway */
            log_error("shared memory coprocessing is not available\n");
-         #endif
+endif
 #else /* __riscos__ */
             not_implemented("run-as-shm-coprocess");
 #endif /* __riscos__ */
@@ -1305,7 +1572,8 @@ main( int argc, char **argv )
          case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break;
          case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
          case oNoPermissionWarn: opt.no_perm_warn=1; break;
-         case oCharset:
+         case oNoMDCWarn: opt.no_mdc_warn=1; break;
+          case oCharset:
            if( set_native_charset( pargs.r.ret_str ) )
                log_error(_("%s is not a valid character set\n"),
                                                    pargs.r.ret_str);
@@ -1330,12 +1598,32 @@ main( int argc, char **argv )
          case oKeyServerOptions:
            parse_keyserver_options(pargs.r.ret_str);
            break;
+         case oImportOptions:
+           if(!parse_import_options(pargs.r.ret_str,&opt.import_options))
+             {
+               if(configname)
+                 log_error(_("%s:%d: invalid import options\n"),
+                           configname,configlineno);
+               else
+                 log_error(_("invalid import options\n"));
+             }
+           break;
+         case oExportOptions:
+           if(!parse_export_options(pargs.r.ret_str,&opt.export_options))
+             {
+               if(configname)
+                 log_error(_("%s:%d: invalid export options\n"),
+                           configname,configlineno);
+               else
+                 log_error(_("invalid export options\n"));
+             }
+           break;
          case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
          case oExecPath:
-#ifndef FIXED_EXEC_PATH
-           if(set_exec_path(pargs.r.ret_str))
+           if(set_exec_path(pargs.r.ret_str,0))
              log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
-#endif
+           else
+             opt.exec_path_set=1;
            break;
          case oNotation:
            add_notation_data( pargs.r.ret_str, 0 );
@@ -1374,6 +1662,7 @@ main( int argc, char **argv )
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
          case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
+         case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
          case oNoRandomSeedFile: use_random_seed = 0; break;
          case oAutoKeyRetrieve:
          case oNoAutoKeyRetrieve:
@@ -1418,6 +1707,8 @@ main( int argc, char **argv )
           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
          case oGroup: add_group(pargs.r.ret_str); break;
+         case oStrict: opt.strict=1; log_set_strict(1); break;
+         case oNoStrict: opt.strict=0; log_set_strict(0); break;
          default : pargs.err = configfp? 1:2; break;
        }
     }
@@ -1447,27 +1738,8 @@ main( int argc, char **argv )
     }
   #endif
 
-    check_permissions(opt.homedir,0,0);
-
-    if(unsafe_files)
-      {
-       STRLIST tmp;
-
-       for(tmp=unsafe_files;tmp;tmp=tmp->next)
-         check_permissions(tmp->d,0,0);
-
-       free_strlist(unsafe_files);
-      }
-
-    if(extensions)
-      {
-       STRLIST tmp;
-
-       for(tmp=extensions;tmp;tmp=tmp->next)
-         check_permissions(tmp->d,1,0);
-
-       free_strlist(extensions);
-      }
+    if (opt.verbose > 2)
+        log_info ("using character set `%s'\n", get_native_charset ());
 
     if( may_coredump && !opt.quiet )
        log_info(_("WARNING: program may create a core file!\n"));
@@ -1499,7 +1771,6 @@ main( int argc, char **argv )
     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
 
     set_debug();
-    g10_opt_homedir = opt.homedir;
 
     /* Do these after the switch(), so they can override settings. */
     if(opt.pgp2 && (opt.pgp6 || opt.pgp7))
@@ -1545,14 +1816,26 @@ main( int argc, char **argv )
                  }
                else if(cmd==aSym)
                  {
+                   /* This only sets IDEA for symmetric encryption
+                      since it is set via select_algo_from_prefs for
+                      pk encryption. */
                    m_free(def_cipher_string);
                    def_cipher_string = m_strdup("idea");
                  }
+
+               /* PGP2 can't handle the output from the textmode
+                  filter, so we disable it for anything that could
+                  create a literal packet (only encryption and
+                  symmetric encryption, since we disable signing
+                  above). */
+               if(!unusable)
+                 opt.textmode=0;
              }
 
            if(unusable)
              {
-               log_info(_("this message may not be usable by PGP 2.x\n"));
+               log_info(_("this message may not be usable by %s\n"),
+                        "PGP 2.x");
                opt.pgp2=0;
              }
            else
@@ -1576,13 +1859,17 @@ main( int argc, char **argv )
 
        if(opt.pgp6 || opt.pgp7)
          {
-           opt.force_mdc=0;
-           opt.disable_mdc=1;
            opt.sk_comments=0;
            opt.escape_from=1;
            opt.force_v3_sigs=1;
            opt.ask_sig_expire=0;
            opt.def_compress_algo=1;
+
+           if(opt.pgp6) /* pgp7 has MDC */
+             {
+               opt.force_mdc=0;
+               opt.disable_mdc=1;
+             }
          }
       }
 
@@ -1669,7 +1956,6 @@ main( int argc, char **argv )
     /* set the random seed file */
     if( use_random_seed ) {
        char *p = make_filename(opt.homedir, "random_seed", NULL );
-       check_permissions(p,0,0);
        set_random_seed_file(p);
        m_free(p);
     }
@@ -1992,8 +2278,9 @@ main( int argc, char **argv )
        break;
 
       case aFastImport:
+        opt.import_options |= IMPORT_FAST_IMPORT;
       case aImport:
-       import_keys( argc? argv:NULL, argc, (cmd == aFastImport), NULL );
+       import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
        break;
 
       case aExport:
@@ -2008,7 +2295,7 @@ main( int argc, char **argv )
        else if( cmd == aRecvKeys )
            keyserver_import( sl );
        else
-           export_pubkeys( sl, (cmd == aExport) );
+           export_pubkeys( sl, opt.export_options );
        free_strlist(sl);
        break;