Added new file to please Jan
[gnupg.git] / sm / gpgsm.c
index 3ca58d3..72e6d41 100644 (file)
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include <gcrypt.h>
 #include "gpgsm.h"
 #include "../assuan/assuan.h" /* malloc hooks */
+#include "../kbx/keybox.h" /* malloc hooks */
 #include "i18n.h"
+#include "keydb.h"
 
 enum cmd_and_opt_values {
   aNull = 0,
@@ -73,6 +76,9 @@ enum cmd_and_opt_values {
   aCheckKeys,
   aServer,                        
 
+  oEnableSpecialFilenames,
+
+
   oTextmode,
   oFingerprint,
   oWithFingerprint,
@@ -261,6 +267,10 @@ static ARGPARSE_OPTS opts[] = {
 
   /* hidden options */
     { oNoVerbose, "no-verbose", 0, "@"},
+
+    { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
+
+
     { oTrustDBName, "trustdb-name", 2, "@" },
     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
     { oNoArmor, "no-armor",   0, "@"},
@@ -297,13 +307,21 @@ static ARGPARSE_OPTS opts[] = {
 
 int gpgsm_errors_seen = 0;
 
+/* It is possible that we are currentlu running under setuid permissions */
 static int maybe_setuid = 1;
 
+/* Option --enable-special-filenames */
+static int allow_special_filenames;
+
+
 static char *build_list (const char *text,
                         const char *(*mapf)(int), int (*chkf)(int));
 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
                      enum cmd_and_opt_values new_cmd );
 
+static int check_special_filename (const char *fname);
+static int open_read (const char *filename);
+
 
 static int
 our_pk_test_algo (int algo)
@@ -441,7 +459,7 @@ set_debug(void)
 {
   if (opt.debug & DBG_MPI_VALUE)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
-  if (opt.debug & DBG_CIPHER_VALUE )
+  if (opt.debug & DBG_CRYPTO_VALUE )
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
 }
 
@@ -495,6 +513,7 @@ main ( int argc, char **argv)
   char *def_cipher_string = NULL;
   char *def_digest_string = NULL;
   enum cmd_and_opt_values cmd = 0;
+  struct server_control_s ctrl;
 
   /* FIXME: trap_unaligned ();*/
   set_strusage (my_strusage);
@@ -562,9 +581,16 @@ main ( int argc, char **argv)
      Now we are now working under our real uid 
   */
 
+  ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
-  /*  ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );*/
+  keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
 
+  /* Setup a default control structure */
+  memset (&ctrl, 0, sizeof ctrl);
+  ctrl.no_server = 1;
+  ctrl.status_fd = -1; /* not status output */
+
+  /* set the default option file */
   if (default_config )
     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
   
@@ -662,7 +688,7 @@ main ( int argc, char **argv)
         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
         case oDebugAll: opt.debug = ~0; break;
 
-        case oStatusFD: /* fixme: set_status_fd (pargs.r.ret_int );*/ break;
+        case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
         case oLoggerFD: /* fixme: log_set_logfile (NULL, pargs.r.ret_int );*/ break;
         case oWithFingerprint:
           with_fpr=1; /*fall thru*/
@@ -704,7 +730,7 @@ main ( int argc, char **argv)
           break;
 
         case oWithKeyData: opt.with_key_data=1; /* fall thru */
-        case oWithColons: opt.with_colons=':'; break;
+        case oWithColons: ctrl.with_colons = 1; break;
 
         case oSkipVerify: opt.skip_verify=1; break;
 
@@ -744,6 +770,8 @@ main ( int argc, char **argv)
 
         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
         case oNoRandomSeedFile: use_random_seed = 0; break;
+
+        case oEnableSpecialFilenames: allow_special_filenames =1; break;
           
         default: 
           pargs.err = configfp? 1:2; 
@@ -831,12 +859,10 @@ main ( int argc, char **argv)
   if (!cmd && opt.fingerprint && !with_fpr)
     set_cmd (&cmd, aListKeys);
   
-#if 0 /* fixme */
-  if (!nrings && default_keyring)  /* add default ring */
-    add_keyblock_resource ("pubcerts.gpg", 0, 0);
+  if (!nrings && default_keyring)  /* add default keybox */
+    keydb_add_resource ("pubcerts.kbx", 0, 0);
   for (sl = nrings; sl; sl = sl->next)
-    add_keyblock_resource( sl->d, 0, 0 );
-#endif
+    keydb_add_resource (sl->d, 0, 0);
   FREE_STRLIST(nrings);
   
   fname = argc? *argv : NULL;
@@ -911,8 +937,14 @@ main ( int argc, char **argv)
       break;
 
     case aVerify:
-/*        if ((rc = verify_signatures( argc, argv ) )) */
-/*          log_error ("verify signatures failed: %s\n", gpg_errstr(rc) ); */
+      if (!argc)
+        gpgsm_verify (&ctrl, 0, -1); /* normal signature from stdin */
+      else if (argc == 1)
+        gpgsm_verify (&ctrl, open_read (*argv), -1); /* normal signature */
+      else if (argc == 2) /* detached signature (sig, detached) */
+        gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1])); 
+      else
+        wrong_args (_("--verify [signature [detached_data]]"));
       break;
 
     case aVerifyFiles:
@@ -937,10 +969,9 @@ main ( int argc, char **argv)
       break;
 
     case aListKeys:
-      sl = NULL;
-      for ( ; argc; argc--, argv++ )
+      for (sl=NULL; argc; argc--, argv++)
         add_to_strlist (&sl, *argv);
-/*        public_key_list( sl ); */
+      gpgsm_list_keys (&ctrl, sl, stdout);
       free_strlist(sl);
       break;
 
@@ -968,8 +999,13 @@ main ( int argc, char **argv)
       break;
 
     case aImport:
-/*        import_keys (argc? argv:NULL, argc); */
-      gpgsm_import (0);
+      if (!argc)
+        gpgsm_import (&ctrl, 0);
+      else
+        {
+          for (; argc; argc--, argv++)
+            gpgsm_import (&ctrl, open_read (*argv));
+        }
       break;
       
     case aExport:
@@ -1022,6 +1058,8 @@ gpgsm_exit (int rc)
 #warning no update_random_seed_file
   update_random_seed_file();
   #endif
+#if 0
+  /* at this time a bit annoying */
   if (opt.debug & DBG_MEMSTAT_VALUE)
     {
       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
@@ -1029,7 +1067,51 @@ gpgsm_exit (int rc)
     }
   if (opt.debug)
     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
+#endif
   gcry_control (GCRYCTL_TERM_SECMEM );
   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
   exit (rc);
 }
+
+
+/* Check whether the filename has the form "-&nnnn", where n is a
+   non-zero number.  Returns this number or -1 if it is not the case.  */
+static int
+check_special_filename (const char *fname)
+{
+  if (allow_special_filenames
+      && fname && *fname == '-' && fname[1] == '&' ) {
+    int i;
+    
+    fname += 2;
+    for (i=0; isdigit (fname[i]); i++ )
+      ;
+    if ( !fname[i] ) 
+      return atoi (fname);
+  }
+  return -1;
+}
+
+
+
+/* Open the FILENAME for read and return the fieldescriptor.  Stop
+   with an error message in case of problems.  "-" denotes stdin and
+   if special filenames are allowed the given fd is opend instead. */
+static int 
+open_read (const char *filename)
+{
+  int fd;
+
+  if (filename[0] == '-' && !filename[1])
+    return 0; /* stdin */
+  fd = check_special_filename (filename);
+  if (fd != -1)
+    return fd;
+  fd = open (filename, O_RDONLY);
+  if (fd == -1)
+    {
+      log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
+      gpgsm_exit (2);
+    }
+  return fd;
+}