* g10.c (main): Handle --strict and --no-strict from the command line
[gnupg.git] / g10 / g10.c
index ca8d8ef..c2e095b 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <assert.h>
 #ifdef HAVE_DOSISH_SYSTEM
   #include <fcntl.h> /* for setmode() */
 #endif
@@ -292,7 +293,6 @@ enum cmd_and_opt_values { aNull = 0,
     oPersonalCipherPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
-    oEmu3DESS2KBug,  /* will be removed in 1.1 */
     oEmuMDEncodeBug,
     oDisplay,
     oTTYname,
@@ -300,6 +300,8 @@ enum cmd_and_opt_values { aNull = 0,
     oLCctype,
     oLCmessages,
     oGroup,
+    oStrict,
+    oNoStrict,
 aTest };
 
 
@@ -581,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, "@" },
@@ -589,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} };
 
 
@@ -780,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 )
 {
@@ -816,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;
     }
 
@@ -852,7 +866,7 @@ check_permissions(const char *path,int item)
 {
 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
   static int homedir_cache=-1;
-  char *tmppath,*isa,*dir;
+  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;
@@ -860,6 +874,8 @@ check_permissions(const char *path,int item)
   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)
     {
@@ -876,8 +892,8 @@ check_permissions(const char *path,int item)
      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_memcasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
+  if(item!=0 && homedir_cache>-1
+     && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
     {
       ret=homedir_cache;
       goto end;
@@ -909,8 +925,6 @@ check_permissions(const char *path,int item)
 
   if(item==0)
     {
-      isa="homedir";
-
       /* The homedir must be x00, a directory, and owned by the user. */
 
       if(S_ISDIR(statbuf.st_mode))
@@ -930,11 +944,6 @@ check_permissions(const char *path,int item)
     }
   else if(item==1 || item==2)
     {
-      if(item==1)
-       isa="configuration file";
-      else
-       isa="extension";
-
       /* The options or extension file.  Okay unless it or its
         containing directory is group or other writable or not owned
         by us or root. */
@@ -982,19 +991,53 @@ check_permissions(const char *path,int item)
   if(!checkonly)
     {
       if(own)
-       log_info(_("WARNING: unsafe ownership on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         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)
-       log_info(_("WARNING: unsafe permissions on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         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)
-       log_info(_("WARNING: unsafe enclosing directory "
-                  "ownership on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         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)
-       log_info(_("WARNING: unsafe enclosing directory "
-                  "permissions on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         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:
@@ -1092,14 +1135,15 @@ main( int argc, char **argv )
     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;
@@ -1119,9 +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,
@@ -1144,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
@@ -1157,6 +1211,8 @@ main( int argc, char **argv )
     maybe_setuid = 0;
     /* Okay, we are now working under our real uid */
 
+    set_native_charset (NULL); /* Try to auto set the character set */
+
     if( default_config )
       {
        configname = make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
@@ -1384,7 +1440,7 @@ main( int argc, char **argv )
          case oAlwaysTrust: opt.always_trust = 1; break;
          case oLoadExtension:
 #ifndef __riscos__
-#ifdef USE_DYNAMIC_LINKING
+#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);
@@ -1431,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__ */
@@ -1519,7 +1573,7 @@ main( int argc, char **argv )
          case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
          case oNoPermissionWarn: opt.no_perm_warn=1; break;
          case oNoMDCWarn: opt.no_mdc_warn=1; break;
-         case oCharset:
+          case oCharset:
            if( set_native_charset( pargs.r.ret_str ) )
                log_error(_("%s is not a valid character set\n"),
                                                    pargs.r.ret_str);
@@ -1653,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;
        }
     }
@@ -1682,6 +1738,9 @@ main( int argc, char **argv )
     }
   #endif
 
+    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"));
 
@@ -1712,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))
@@ -1758,9 +1816,20 @@ 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)
@@ -2209,9 +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, opt.import_options );
+       import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
        break;
 
       case aExport: