Added new directory common to enable sharing of some code and error
authorWerner Koch <wk@gnupg.org>
Sat, 24 Nov 2001 17:43:43 +0000 (17:43 +0000)
committerWerner Koch <wk@gnupg.org>
Sat, 24 Nov 2001 17:43:43 +0000 (17:43 +0000)
numbers between gpg, gpgsm and gpg-agent.  Move some files and code to
there.

21 files changed:
agent/ChangeLog
agent/gpg-agent.c [new file with mode: 0644]
common/Makefile.am [new file with mode: 0644]
common/README [new file with mode: 0644]
common/errors.h [new file with mode: 0644]
common/i18n.h [new file with mode: 0644]
common/maperror.c [new file with mode: 0644]
common/mkerrors [moved from sm/mkerrors with 86% similarity]
common/util.h [moved from sm/util.h with 83% similarity]
kbx/kbxutil.c
sm/Makefile.am
sm/certchain.c
sm/certcheck.c
sm/certpath.c
sm/gpgsm.h
sm/import.c
sm/keydb.c
sm/keylist.c
sm/misc.c
sm/sign.c
sm/verify.c

index e69de29..1ccdf29 100644 (file)
@@ -0,0 +1,26 @@
+2001-11-19  Werner Koch  <wk@gnupg.org>
+
+       * gpg-agent.c: Removed all GUI code, removed code for old
+       protocol.  New code to use the Assuan protocol as a server and
+       also to communicate with a new ask-passphrase utility.
+
+2000-11-22  Werner Koch  <wk@gnupg.org>
+
+       * gpg-agent.c (main): csh support by Dan Winship, new options --sh
+       and --csh and set default by consulting $SHELL.
+
+Mon Aug 21 17:59:17 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * gpg-agent.c (passphrase_dialog): Cleanup the window and added the
+        user supplied text to the window.
+        (main): Fixed segv in gtk_init when used without a command to start.
+
+        * gpg-agent.c: --flush option.
+        (req_flush): New.
+        (req_clear_passphrase): Implemented.
+
+Fri Aug 18 14:27:14 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * gpg-agent.c: New.
+        * Makefile.am: New.
+
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
new file mode 100644 (file)
index 0000000..b0c6c95
--- /dev/null
@@ -0,0 +1,984 @@
+/* gpg-agent.c  -  The GnuPG Agent
+ *     Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ * How to use the client mode:
+ *  printf '\0\0\0\002AAAAAAAAAAAAAAAAAAAAAPlease enter the passphrase for\n 
+ *          key 0x12345678\nJoe Hacker <joe@hackworld.foo>\n' 
+ *     | ./gpg-agent --client | od
+ * Or use a builtin command to shut the agent down.
+ *   ./gpg-agent --shutdown | od
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <gcrypt.h>
+
+#include "util.h"
+#include "../assuan/assuan.h" /* malloc hooks */
+#include "i18n.h"
+
+
+enum cmd_and_opt_values 
+{ aNull = 0,
+  oCsh           = 'c',
+  oQuiet         = 'q',
+  oSh            = 's',
+  oVerbose       = 'v',
+  
+  oNoVerbose = 500,
+  oOptions,
+  oDebug,
+  oDebugAll,
+  oNoGreeting,
+  oNoOptions,
+  oHomedir,
+  oNoDetach,
+  oNoGrab,
+  oClient,
+  oShutdown,
+  oFlush,
+  oLogFile,
+  oServer,
+aTest };
+
+
+static ARGPARSE_OPTS opts[] = {
+  
+  { 301, NULL, 0, N_("@Options:\n ") },
+
+  /* FIXME: add option --server */
+  { oServer,   "server",     0, N_("run in server mode") },
+  { oVerbose, "verbose",   0, N_("verbose") },
+  { oQuiet,    "quiet",     0, N_("be somewhat more quiet") },
+  { oSh,       "sh",        0, N_("sh-style command output") },
+  { oCsh,      "csh",       0, N_("csh-style command output") },
+  { oOptions, "options"  , 2, N_("read options from file")},
+  { oDebug,    "debug"     ,4|16, N_("set debugging flags")},
+  { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
+  { oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
+  { oNoGrab, "no-grab"     ,0, N_("do not grab keyboard and mouse")},
+  { oClient, "client"      ,0, N_("run in client mode for testing")},
+  { oLogFile, "log-file"   ,2, N_("use a log file for the server")},
+  { oShutdown, "shutdown"  ,0, N_("shutdown the agent")},
+  { oFlush   , "flush"     ,0, N_("flush the cache")},
+  {0}
+};
+
+
+static struct {
+  const char *homedir;
+  int client;
+  int verbose;
+  int quiet;
+  unsigned int debug;
+  int nodetach;
+  int grab;
+  const char *logfile;
+  int csh_style;
+} opt;
+
+typedef struct {
+    int used;
+    char fpr[20];
+    char *pw;
+    size_t pwlen;
+    size_t totlen;
+} CACHE_SLOT;
+
+#define MAX_CACHE_ENTRIES 10
+#define MAX_CACHE_AGE  1000 /* should fit into an integer */
+static volatile int caught_fatal_sig = 0;
+static volatile int shut_me_down = 0;
+static CACHE_SLOT the_cache[MAX_CACHE_ENTRIES];
+static char *socket_name = NULL;
+
+#define buftou32( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
+                      (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
+#define u32tobuf( p, a ) do {                                  \
+                           ((byte*)p)[0] = (byte)((a) >> 24);  \
+                           ((byte*)p)[1] = (byte)((a) >> 16);  \
+                           ((byte*)p)[2] = (byte)((a) >>  8);  \
+                           ((byte*)p)[3] = (byte)((a)      );  \
+                       } while(0)
+
+
+static int start_listening ( const char *name );
+static int writen ( int fd, const void *buf, size_t nbytes );
+static int readn ( int fd, void *buf, size_t buflen, size_t *ret_nread );
+
+static void process_request ( int fd );
+
+
+static const char *
+my_strusage( int level )
+{
+    const char *p;
+    switch( level ) {
+      case 11: p = "gpg-agent (GnuPG)";
+       break;
+      case 13: p = VERSION; break;
+      case 17: p = PRINTABLE_OS_NAME; break;
+      case 19: p =
+           _("Please report bugs to <bug-gnupg@gnu.org>.\n");
+       break;
+      case 1:
+      case 40: p =
+           _("Usage: gpg-agent [options] (-h for help)");
+       break;
+      case 41: p =
+           _("Syntax: gpg-agent [options] [command [args]]\n"
+             "Secret key management for GnuPG\n");
+       break;
+
+      default: p = NULL;
+    }
+    return p;
+}
+
+
+
+static void
+i18n_init (void)
+{
+  #ifdef USE_SIMPLE_GETTEXT
+    set_gettext_file( PACKAGE );
+  #else
+  #ifdef ENABLE_NLS
+    /* gtk_set_locale (); HMMM: We have not yet called gtk_init */
+    bindtextdomain( PACKAGE, GNUPG_LOCALEDIR );
+    textdomain( PACKAGE );
+  #endif
+  #endif
+}
+
+static void
+cleanup (void)
+{
+  if (socket_name)
+    {
+      char *p = socket_name;
+      socket_name = NULL;
+      remove ( p );
+      gcry_free (p);
+    }
+}
+
+static RETSIGTYPE
+cleanup_sh (int sig)
+{
+  if (caught_fatal_sig)
+    raise (sig);
+  caught_fatal_sig = 1;
+  shut_me_down = 1;
+
+  /* gcry_control( GCRYCTL_TERM_SECMEM );*/
+  cleanup ();
+
+#ifndef HAVE_DOSISH_SYSTEM
+  {    /* reset action to default action and raise signal again */
+    struct sigaction nact;
+    nact.sa_handler = SIG_DFL;
+    sigemptyset( &nact.sa_mask );
+    nact.sa_flags = 0;
+    sigaction( sig, &nact, NULL);
+  }
+#endif
+  raise( sig );
+}
+
+int
+main (int argc, char **argv )
+{
+  ARGPARSE_ARGS pargs;
+  int orig_argc;
+  char **orig_argv;
+  FILE *configfp = NULL;
+  char *configname = NULL;
+  const char *shell;
+  unsigned configlineno;
+  int parse_debug = 0;
+  int default_config =1;
+  int greeting = 0;
+  int nogreeting = 0;
+  int server_mode = 0;
+  int do_shutdown = 0;
+  int do_flush = 0;
+
+  set_strusage( my_strusage );
+  /*   log_set_name ("gpg-agent"); */
+  srand (time (NULL)); /* the about dialog uses rand() */
+  i18n_init ();
+
+  /* check that the libraries are suitable.  Do it here because
+     the option parsing may need services of the library */
+  if (!gcry_check_version ( "1.1.4" ) )
+    {
+      log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
+                 VERSION, gcry_check_version (NULL) );
+    }
+
+  assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
+
+
+  shell = getenv("SHELL");
+  if (shell && strlen(shell) >= 3 && !strcmp(shell+strlen(shell)-3, "csh") )
+    opt.csh_style = 1;
+  
+  opt.homedir = getenv("GNUPGHOME");
+  if (!opt.homedir || !*opt.homedir)
+    {
+#ifdef HAVE_DRIVE_LETTERS
+      opt.homedir = "c:/gnupg-test";
+#else
+      opt.homedir = "~/.gnupg-test";
+#endif
+    }
+  opt.grab = 1;
+
+  /* check whether we have a config file on the commandline */
+  orig_argc = argc;
+  orig_argv = argv;
+  pargs.argc = &argc;
+  pargs.argv = &argv;
+  pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
+  while (arg_parse( &pargs, opts))
+    {
+      if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
+        parse_debug++;
+      else if (pargs.r_opt == oOptions)
+        { /* yes there is one, so we do not try the default one, but
+            read the option file when it is encountered at the
+            commandline */
+          default_config = 0;
+       }
+       else if (pargs.r_opt == oNoOptions)
+          default_config = 0; /* --no-options */
+       else if (pargs.r_opt == oHomedir)
+          opt.homedir = pargs.r.ret_str;
+    }
+
+  if (default_config)
+    configname = make_filename (opt.homedir, "gpg-agent.conf", NULL );
+  
+  argc = orig_argc;
+  argv = orig_argv;
+  pargs.argc = &argc;
+  pargs.argv = &argv;
+  pargs.flags=  1;  /* do not remove the args */
+ next_pass:
+  if (configname)
+    {
+      configlineno = 0;
+      configfp = fopen (configname, "r");
+      if (!configfp)
+        {
+          if (default_config)
+            {
+              if( parse_debug )
+                log_info (_("NOTE: no default option file `%s'\n"),
+                          configname );
+           }
+          else
+            {
+              log_error (_("option file `%s': %s\n"),
+                         configname, strerror(errno) );
+              exit(2);
+           }
+          xfree (configname); 
+          configname = NULL;
+       }
+      if (parse_debug && configname )
+        log_info (_("reading options from `%s'\n"), configname );
+      default_config = 0;
+    }
+
+  while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
+    {
+      switch (pargs.r_opt)
+        {
+        case oQuiet: opt.quiet = 1; break;
+        case oVerbose: opt.verbose++; break;
+
+        case oDebug: opt.debug |= pargs.r.ret_ulong; break;
+        case oDebugAll: opt.debug = ~0; break;
+
+        case oOptions:
+          /* config files may not be nested (silently ignore them) */
+          if (!configfp)
+            {
+               xfree(configname);
+               configname = xstrdup(pargs.r.ret_str);
+               goto next_pass;
+           }
+          break;
+        case oNoGreeting: nogreeting = 1; break;
+        case oNoVerbose: opt.verbose = 0; break;
+        case oNoOptions: break; /* no-options */
+        case oHomedir: opt.homedir = pargs.r.ret_str; break;
+        case oNoDetach: opt.nodetach = 1; break;
+        case oNoGrab: opt.grab = 0; break;
+        case oClient: opt.client = 1; break;
+        case oShutdown: opt.client = 1; do_shutdown = 1; break;
+        case oFlush: opt.client = 1; do_flush = 1; break;
+        case oLogFile: opt.logfile = pargs.r.ret_str; break;
+        case oCsh: opt.csh_style = 1; break;
+        case oSh: opt.csh_style = 0; break;
+        case oServer: server_mode = 1; break;
+
+        default : pargs.err = configfp? 1:2; break;
+       }
+    }
+  if (configfp)
+    {
+      fclose( configfp );
+      configfp = NULL;
+      xfree(configname);
+      configname = NULL;
+      goto next_pass;
+    }
+  xfree (configname);
+  configname = NULL;
+  if (log_get_errorcount(0))
+    exit(2);
+  if (nogreeting )
+    greeting = 0;
+
+  if (greeting)
+    {
+      fprintf (stderr, "%s %s; %s\n",
+                 strusage(11), strusage(13), strusage(14) );
+      fprintf (stderr, "%s\n", strusage(15) );
+    }
+#ifdef IS_DEVELOPMENT_VERSION
+  log_info ("NOTE: this is a development version!\n");
+#endif
+
+  socket_name =  make_filename (opt.homedir, "S.gpg-agent", NULL );
+  if (strchr ( socket_name, ':') )
+    {
+      log_error ("colons are not allowed in the socket name\n");
+      exit (1);
+    }
+   
+  if (opt.client)
+    { /* a client for testing this agent */
+#if 0 /* FIXME: We are going to use assuan here */
+      int fd;
+      struct sockaddr_un client_addr;
+      size_t len;
+      char buffer[1000];
+      int nread;
+
+      if ( strlen (socket_name)+1 >= sizeof client_addr.sun_path ) {
+        log_error ("name of socket to long\n");
+        exit (1);
+      }
+
+      if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
+        log_fatal("can't create socket: %s\n", strerror(errno) );
+
+      memset( &client_addr, 0, sizeof client_addr );
+      client_addr.sun_family = AF_UNIX;
+      strcpy( client_addr.sun_path, socket_name );
+      len = offsetof (struct sockaddr_un, sun_path)
+        + strlen(client_addr.sun_path) + 1;
+
+      if( connect( fd, (struct sockaddr*)&client_addr, len ) == -1 ) {
+        log_error ( "connect() failed: %s\n", strerror (errno) );
+        exit (1);
+      }
+
+      if ( do_shutdown ) {
+        u32tobuf (buffer+4, GPGA_PROT_SHUTDOWN );
+        nread = 4;
+      }
+      else if ( do_flush ) {
+        u32tobuf (buffer+4, GPGA_PROT_FLUSH );
+        nread = 4;
+      }
+      else {
+        nread =  fread ( buffer+4, 1, DIM(buffer)-4, stdin );
+            
+        if ( opt.verbose )
+          log_info ( "%d bytes read from stdin\n", nread );
+      }
+      u32tobuf (buffer, nread );
+      writen ( fd, "GPGA\0\0\0\x01", 8 );
+      writen ( fd, buffer, nread + 4 );
+      /* now read the response */
+      readn ( fd, buffer, DIM(buffer), &nread );
+      if ( opt.verbose )
+        log_info ( "%d bytes got from agent\n", nread );
+
+      fwrite ( buffer, 1, nread, stdout );
+      close (fd );
+#endif
+    }
+  else
+    { /* regular server mode */
+      int listen_fd;
+      pid_t child;
+      int i;
+        
+      listen_fd = start_listening (socket_name);
+      if (listen_fd == -1)
+        {
+          cleanup ();
+          exit (1);
+        }
+
+
+      fflush (NULL);
+      child = fork ();
+      if (child == -1) 
+        {
+          log_fatal ("fork failed: %s\n", strerror (errno) );
+          cleanup ();
+          exit (1);
+        }
+      else if ( child ) 
+        { /* parent */
+          char *infostr;
+          
+          close (listen_fd );
+          
+          /* create the info string */
+          infostr = xmalloc ( 20 + strlen(socket_name) + 30 + 2 );
+          sprintf ( infostr, "GPG_AGENT_INFO=%s:%lu",
+                    socket_name, (ulong)child );
+          if ( argc ) 
+            { /* run the program given on the commandline */
+              if (putenv (infostr))
+                {
+                  log_error ("failed to set environment: %s\n",
+                             strerror (errno) );
+                  kill (child, SIGTERM );
+                  cleanup ();
+                  exit (1);
+                }
+              execvp (argv[0], argv);
+              log_error ("failed to run the command: %s\n",
+                         strerror (errno));    
+              kill (child, SIGTERM);
+              cleanup ();
+              exit (1);
+            }
+          /* print the environment string, so that the caller can use
+             eval to set it */
+          if (opt.csh_style)
+            {
+              *strchr (infostr, '=') = ' ';
+              printf ( "setenv %s\n", infostr);
+           }
+          else
+            {
+              printf ( "%s; export GPG_AGENT_INFO;\n", infostr);
+           }
+          exit (0); 
+        } /* end parent */
+
+      if ( (opt.debug & 1) )
+        sleep( 20 ); /* give us some time to attach gdb to the child */
+
+      if (opt.logfile)
+        {
+          /* FIXME:log_set_logfile (opt.logfile, -1);*/
+        }
+       
+      if ( atexit( cleanup ) )
+        {
+          log_error ("atexit failed\n");
+          cleanup ();
+          exit (1);
+        }
+
+      if ( !opt.nodetach )
+        {
+          for (i=0 ; i <= 2; i++ ) 
+            {
+              if ( log_get_fd () != i)
+                close ( i );
+            }
+            
+          if (setsid() == -1)
+            {
+              log_error ("setsid() failed: %s\n", strerror(errno) );
+              cleanup ();
+              exit (1);
+            }
+        }
+
+      {
+        struct sigaction oact, nact;
+        
+        nact.sa_handler = cleanup_sh;
+        sigemptyset ( &nact.sa_mask );
+        nact.sa_flags = 0;
+        
+        sigaction ( SIGHUP, NULL, &oact );
+        if ( oact.sa_handler != SIG_IGN )
+          sigaction( SIGHUP, &nact, NULL);
+        sigaction( SIGTERM, NULL, &oact );
+        if ( oact.sa_handler != SIG_IGN )
+          sigaction( SIGTERM, &nact, NULL);
+        nact.sa_handler = SIG_IGN;
+        sigaction( SIGPIPE, &nact, NULL );
+        sigaction( SIGINT, &nact, NULL );
+      }
+
+      if ( chdir("/") )
+        {
+          log_error ("chdir to / failed: %s\n", strerror (errno) );
+          exit (1);
+        }
+
+      /* for now there is no need for concurrent requests because we
+         are asking for passphrases which might pop up a window to get
+         the users respond.  In future the agent may provide other
+         services which won't need a user interaction */
+#if 0
+      while (!shut_me_down)
+        {
+          struct sockaddr_un clnt_addr;
+          size_t len = sizeof clnt_addr;
+          int fd;
+          /* FIXME: convert to assuan */     
+          fd = accept ( listen_fd, (struct sockaddr*)&clnt_addr, &len );
+          if ( fd == -1 )
+            log_error ( "accept() failed: %s\n", strerror (errno));
+          else
+            {
+              process_request ( fd );
+              close (fd );
+            }
+        }
+#endif
+      close (listen_fd);
+    }
+  
+  return 0;
+}
+
+
+static int
+start_listening (const char *name)
+{
+#if 0
+  int len;
+  int fd;
+  struct sockaddr_un serv_addr;
+  
+  if (opt.verbose)
+    log_info ("using socket `%s'\n", socket_name );
+
+  if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) 
+    {
+      log_error ("name of socket to long\n");
+      return -1;
+    }
+
+  if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
+    log_fatal("can't create socket: %s\n", strerror(errno) );
+
+  memset( &serv_addr, 0, sizeof serv_addr );
+  serv_addr.sun_family = AF_UNIX;
+  strcpy( serv_addr.sun_path, socket_name );
+  len = (offsetof (struct sockaddr_un, sun_path)
+         + strlen(serv_addr.sun_path) + 1);
+  
+  remove (socket_name); errno = 0;
+  if (bind( fd, (struct sockaddr*)&serv_addr, len ) == -1 )
+    {
+      log_error ( "error binding address `%s': %m\n", serv_addr.sun_path );
+      close (fd );
+      return -1;
+    }
+  
+  if (listen (fd, 5 ) == -1)
+    {
+      log_error ( "listen() failed: %s\n", strerror (errno) );
+      close ( fd );
+      return -1;
+    }
+#endif
+  return -1;
+}
+
+/* Look for the passprase as given by the 20 bytes DATA and return it's
+  slot number.  If this passphrase is not in the cache, return -1 */
+static int
+open_cached_passphrase ( const char *fpr )
+{
+  int i;
+  
+  for (i=0; i < MAX_CACHE_ENTRIES; i++ ) 
+    {
+      if (the_cache[i].used && !memcmp (the_cache[i].fpr, fpr, 20))
+        {
+          if ( the_cache[i].used < MAX_CACHE_AGE )
+            the_cache[i].used++;
+          return i;
+        }
+    }
+  
+  return -1;
+}
+
+/* Get pointers to the cached passphrase and return the real length
+   PWLEN as well as the somewhat larger BLOCKLEN */
+static const char * 
+read_cached_passphrase (int slot, size_t *pwlen, size_t *blocklen)
+{
+  assert (slot >=0 && slot < MAX_CACHE_ENTRIES);
+  *pwlen    = the_cache[slot].pwlen;
+  *blocklen = the_cache[slot].totlen;
+  return the_cache[slot].pw;
+}
+
+static const void
+clear_cached_passphrase ( int slot )
+{
+  assert ( slot >=0 && slot < MAX_CACHE_ENTRIES );
+  xfree (the_cache[slot].pw ); 
+  the_cache[slot].pw = NULL; 
+  the_cache[slot].used = 0;
+}
+
+static void
+close_cached_passphrase ( int slot )
+{
+  /* not yet needed */
+}
+
+
+static void
+set_cached_passphrase ( const char *fpr, const char *pw )
+{
+  int i, min_used = MAX_CACHE_AGE, slot = -1;
+    
+  for (i=0; i < 20 && !fpr[i]; i++ )
+    ;
+  if (i== 20)
+    return; /* never cache an all empty fingerprint */
+
+  /* first see whether we have already cached this one */
+  for (i=0; i < MAX_CACHE_ENTRIES; i++ ) 
+    {
+      if ( the_cache[i].used && !memcmp (the_cache[i].fpr, fpr, 20) )
+        {
+          slot = i;
+          break;
+        }
+    }
+
+  if (slot == -1)
+    { /* Find an unused one or reuse one */
+      for (i=0; i < MAX_CACHE_ENTRIES; i++ )
+        {
+          if ( !the_cache[i].used ) {
+            slot = i;
+            break;
+          }
+          if ( the_cache[i].used < min_used )
+            {
+              min_used = the_cache[i].used;
+              slot = i;
+            }
+        }
+      assert ( slot != -1 );
+    }
+  xfree (the_cache[slot].pw);
+  /* fixme: Allocate to fixed sizes */
+  the_cache[slot].used = 1;
+  memcpy (the_cache[slot].fpr, fpr, 20 );
+  the_cache[slot].pw = gcry_xstrdup ( pw );
+  the_cache[slot].pwlen = strlen ( pw );
+  the_cache[slot].totlen = strlen ( pw );
+}
+
+
+
+static int
+passphrase_dialog ( const byte *fpr, const char *user_string )
+{
+  /* FIXME: call the PIN-ENtry */
+
+  return 0;
+}
+
+
+
+static int
+writen ( int fd, const void *buf, size_t nbytes )
+{
+  size_t nleft = nbytes;
+  ssize_t nwritten;
+  
+  while (nleft > 0)
+    {
+      nwritten = write( fd, buf, nleft );
+      if ( nwritten < 0 )
+        {
+          log_error ( "writen() failed: %s\n", strerror (errno) );
+          return -1;
+        }
+      nleft -= nwritten;
+      buf = (const char*)buf + nwritten;
+    }
+  return 0;
+}
+
+
+static int
+readn ( int fd, void *buf, size_t buflen, size_t *ret_nread )
+{
+  size_t nleft = buflen;
+  int nread;
+  char *p;
+  
+  p = buf;
+  while (nleft > 0 )
+    {
+      nread = read ( fd, buf, nleft );
+      if ( nread < 0 )
+        {
+          log_error ( "read() error: %s\n", strerror (errno) );
+          return -1;
+        }
+      else if (!nread )
+        break; /* EOF */
+        nleft -= nread;
+        buf = (char*)buf + nread;
+    }
+  if (ret_nread )
+    *ret_nread = buflen - nleft;
+  return 0;
+}
+
+
+
+
+static void
+reply_error ( int fd, int x )
+{
+  /*FIXME:*/
+}
+
+static void
+reply ( int fd, int x, const char *data, size_t datalen )
+{
+  /*FIXME:*/
+}
+
+static void
+req_get_version ( int fd, const char *data, size_t datalen )
+{
+  /*FIXME:*/
+}
+
+static void
+req_get_passphrase ( int fd, const char *data, size_t datalen )
+{
+#if 0
+  int slot;
+  const char *pw;
+  size_t pwlen, blocklen;
+
+  if (datalen < 20)
+    {
+      reply_error ( fd, GPGA_PROT_INVALID_DATA );
+      return;
+    }
+
+  slot = open_cached_passphrase ( data );
+  if ( slot == -1 )
+    {
+      int rc;
+      char *string;
+      
+      if ( datalen > 20 ) 
+        {
+          string = xmalloc ( datalen - 20 + 1 );
+          memcpy (string, data+20, datalen-20 );
+          string[datalen-20] = 0;
+        }
+      else
+        {
+          string = xstrdup ("[fingerprint]");
+        }
+      rc = passphrase_dialog ( data, string ); 
+      xfree (string);
+      if (rc) 
+        {
+          reply_error ( fd, rc );
+          return;
+        }
+      slot = open_cached_passphrase ( data );
+      if (slot < 0)
+        BUG ();
+    }
+    
+  pw = read_cached_passphrase ( slot, &pwlen, &blocklen );
+  if (!pw || blocklen < pwlen)
+    BUG ();
+#if 0 /* FIXME: */
+    /* we do a hardcoded reply here to avoid copying of the passphrase
+     * from the cache to a temporary buffer */
+  {
+    byte buf[20]; 
+    
+    u32tobuf ( buf+0, (8+blocklen) );
+    u32tobuf ( buf+4, GPGA_PROT_GOT_PASSPHRASE );
+    u32tobuf ( buf+8, pwlen );
+    writen ( fd, buf, 12 );
+    writen ( fd, pw, blocklen );
+  }
+#endif
+  close_cached_passphrase ( slot );
+#endif
+}
+
+static void
+req_clear_passphrase ( int fd, const char *data, size_t datalen )
+{
+#if 0
+  int slot;
+  
+  if ( datalen < 20 )
+    {
+      reply_error ( fd, GPGA_PROT_INVALID_DATA );
+      return;
+    }
+
+  slot = open_cached_passphrase ( data );
+  if ( slot == -1 ) 
+    {
+      reply_error ( fd, GPGA_PROT_NO_PASSPHRASE );
+      return;
+    }
+         
+  clear_cached_passphrase ( slot );
+  close_cached_passphrase ( slot );
+  reply_error (fd, GPGA_PROT_OKAY );
+#endif
+}
+
+static void
+req_shutdown ( int fd, const char *data, size_t datalen )
+{
+  shut_me_down = 1;
+/*    reply ( fd, GPGA_PROT_OKAY, "", 0 ); */
+}
+
+
+static void
+req_flush ( int fd, const char *data, size_t datalen )
+{
+  int i;
+  
+  /* FIXME: when using multiple connections we need to cope with locking */
+  for (i=0; i < MAX_CACHE_ENTRIES; i++ )
+    {
+      if ( the_cache[i].used ) {
+        xfree ( the_cache[i].pw );
+        the_cache[i].pw = NULL;
+        the_cache[i].used = 0;
+      }
+    }
+/*    reply ( fd, GPGA_PROT_OKAY, "", 0 ); */
+}
+
+
+static void
+process_request ( int fd )
+{
+#if 0
+  byte buf[3000]; /* Below is a hardcoded max. length check */
+  byte *data;
+  size_t n, nread;    
+  
+    /* Check the magic and the protocol number */
+  if ( readn ( fd, buf, 12, &nread ) )
+    goto read_failure;
+  if ( nread != 12 || memcmp ( buf, "GPGA\0\0\0\x01", 8 ) ) {
+    reply_error ( fd, GPGA_PROT_PROTOCOL_ERROR );
+    return;
+  }
+  n = buftou32 ( buf + 8 ); /* length of following packet */
+  if ( n < 4 || n > 2048 ) {
+    reply_error ( fd, GPGA_PROT_INVALID_DATA );
+    return;
+  }
+  /* read the request packet */
+  if ( readn ( fd, buf, n, &nread ) )
+    goto read_failure;
+  if ( nread != n ) {
+    reply_error ( fd, GPGA_PROT_PROTOCOL_ERROR );
+    return;
+  }
+  /* dispatch the request */
+  n -= 4;
+  data = buf+4;
+  switch ( buftou32 ( buf ) ) {
+  case GPGA_PROT_GET_VERSION: 
+    req_get_version ( fd, data, n );
+    break;
+  case GPGA_PROT_GET_PASSPHRASE:
+    req_get_passphrase (fd, data, n);
+    break;
+  case GPGA_PROT_CLEAR_PASSPHRASE:
+    req_clear_passphrase (fd, data, n ); 
+    break;
+  case GPGA_PROT_SHUTDOWN:
+    req_shutdown (fd, data, n );
+    break;
+  case GPGA_PROT_FLUSH:
+    req_flush (fd, data, n );
+    break;
+
+  default:
+    reply_error ( fd, GPGA_PROT_INVALID_REQUEST );
+    break;
+  }      
+    
+  return;
+
+ read_failure:
+  /* it does not make sense to respond in this case */
+  log_error ( "read failure: %s\n", strerror(errno));
+  return;
+#endif
+}
+
+
+
diff --git a/common/Makefile.am b/common/Makefile.am
new file mode 100644 (file)
index 0000000..3c5e471
--- /dev/null
@@ -0,0 +1,35 @@
+# Makefile for common gnupg modules
+# Copyright (C) 2001 Free Software Foundation, Inc.
+#
+# This file is part of GnuPG.
+#
+# GnuPG is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# GnuPG is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = mkerrors
+#INCLUDES = 
+BUILT_SOURCES = errors.c
+
+noinst_LIBRARIES = libcommon.a
+
+libcommon_a_SOURCES = \
+       util.h i18n.h \
+       errors.c errors.h \
+       maperror.c 
+
+
+errors.c : errors.h mkerrors
+       $(srcdir)/mkerrors < $(srcdir)/errors.h > errors.c
diff --git a/common/README b/common/README
new file mode 100644 (file)
index 0000000..d3927d8
--- /dev/null
@@ -0,0 +1,14 @@
+Stuff used by several modules of GnuPG.  This way we can share error
+codes and serveral other things.
+
+
+These directories use it:
+
+gpg
+sm
+agent
+
+These directories don't use it:
+
+assuan
+kbx
\ No newline at end of file
diff --git a/common/errors.h b/common/errors.h
new file mode 100644 (file)
index 0000000..4f7cb32
--- /dev/null
@@ -0,0 +1,122 @@
+/* errors.h - Globally used error codes
+ *     Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GNUPG_COMMON_ERRORS_H
+#define GNUPG_COMMON_ERRORS_H
+
+#include "util.h"
+
+/* Error numbers */
+enum {
+  GNUPG_EOF = -1,
+  GNUPG_No_Error = 0,
+  GNUPG_General_Error = 1, 
+  GNUPG_Out_Of_Core = 2,
+  GNUPG_Invalid_Value = 3,
+  GNUPG_IO_Error = 4,
+  GNUPG_Resource_Limit = 5,
+  GNUPG_Internal_Error = 6,
+  GNUPG_Bad_Certificate = 7,
+  GNUPG_Bad_Certificate_Path = 8,
+  GNUPG_Missing_Certificate = 9,
+  GNUPG_No_Data = 10,
+  GNUPG_Bad_Signature = 11,
+  GNUPG_Not_Implemented = 12,
+  GNUPG_Conflict = 13,
+  GNUPG_Bug = 14
+};
+
+/* Status codes - fixme: should go into another file */
+enum {
+  STATUS_ENTER,
+  STATUS_LEAVE,
+  STATUS_ABORT,
+  STATUS_GOODSIG,
+  STATUS_BADSIG,
+  STATUS_ERRSIG,
+  STATUS_BADARMOR,
+  STATUS_RSA_OR_IDEA,
+  STATUS_SIGEXPIRED,
+  STATUS_KEYREVOKED,
+  STATUS_TRUST_UNDEFINED,
+  STATUS_TRUST_NEVER,
+  STATUS_TRUST_MARGINAL,
+  STATUS_TRUST_FULLY,
+  STATUS_TRUST_ULTIMATE,
+  
+  STATUS_SHM_INFO,
+  STATUS_SHM_GET,
+  STATUS_SHM_GET_BOOL,
+  STATUS_SHM_GET_HIDDEN,
+  
+  STATUS_NEED_PASSPHRASE,
+  STATUS_VALIDSIG,
+  STATUS_SIG_ID,
+  STATUS_ENC_TO,
+  STATUS_NODATA,
+  STATUS_BAD_PASSPHRASE,
+  STATUS_NO_PUBKEY,
+  STATUS_NO_SECKEY,
+  STATUS_NEED_PASSPHRASE_SYM,
+  STATUS_DECRYPTION_FAILED,
+  STATUS_DECRYPTION_OKAY,
+  STATUS_MISSING_PASSPHRASE,
+  STATUS_GOOD_PASSPHRASE,
+  STATUS_GOODMDC,
+  STATUS_BADMDC,
+  STATUS_ERRMDC,
+  STATUS_IMPORTED,
+  STATUS_IMPORT_RES,
+  STATUS_FILE_START,
+  STATUS_FILE_DONE,
+  STATUS_FILE_ERROR,
+  
+  STATUS_BEGIN_DECRYPTION,
+  STATUS_END_DECRYPTION,
+  STATUS_BEGIN_ENCRYPTION,
+  STATUS_END_ENCRYPTION,
+  
+  STATUS_DELETE_PROBLEM,
+  STATUS_GET_BOOL,
+  STATUS_GET_LINE,
+  STATUS_GET_HIDDEN,
+  STATUS_GOT_IT,
+  STATUS_PROGRESS,
+  STATUS_SIG_CREATED,
+  STATUS_SESSION_KEY,
+  STATUS_NOTATION_NAME,
+  STATUS_NOTATION_DATA,
+  STATUS_POLICY_URL,
+  STATUS_BEGIN_STREAM,
+  STATUS_END_STREAM,
+  STATUS_KEY_CREATED,
+  STATUS_USERID_HIN,
+  STATUS_UNEXPECTED,
+  STATUS_INV_RECP,
+  STATUS_NO_RECP,
+  STATUS_ALREADY_SIGNED,
+};
+
+
+/*-- errors.c (built) --*/
+const char *gnupg_strerror (int err);
+
+
+#endif /*GNUPG_COMMON_ERRORS_H*/
diff --git a/common/i18n.h b/common/i18n.h
new file mode 100644 (file)
index 0000000..0e13dca
--- /dev/null
@@ -0,0 +1,47 @@
+/* i18n.h
+ *     Copyright (C) 1998, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GNUPG_COMMON_I18N_H
+#define GNUPG_COMMON_I18N_H
+
+#ifdef USE_SIMPLE_GETTEXT
+  int set_gettext_file( const char *filename );
+  const char *gettext( const char *msgid );
+# define _(a) gettext (a)
+# define N_(a) (a)
+#else
+# ifdef HAVE_LOCALE_H
+#  include <locale.h>  
+# endif
+# ifdef ENABLE_NLS
+#  include <libintl.h>
+#  define _(a) gettext (a)
+#  ifdef gettext_noop
+#   define N_(a) gettext_noop (a)
+#  else
+#   define N_(a) (a)
+#  endif
+# else
+#  define _(a) (a)
+#  define N_(a) (a)
+# endif
+#endif /*!USE_SIMPLE_GETTEXT*/
+
+#endif /*GNUPG_COMMON_I18N_H*/
diff --git a/common/maperror.c b/common/maperror.c
new file mode 100644 (file)
index 0000000..894e235
--- /dev/null
@@ -0,0 +1,85 @@
+/* maperror.c - Error mapping
+ *     Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include <ksba.h>
+
+#include "util.h"
+#include "errors.h"
+
+
+/* Note: we might want to wrap this in a macro to get our hands on
+   the line and file where the error occired */
+int
+map_ksba_err (int err)
+{
+  switch (err)
+    {
+    case -1:
+    case 0:
+      break;
+      
+    default:
+      err = seterr (General_Error);
+      break;
+    }
+  return err;
+}
+
+
+int 
+map_gcry_err (int err)
+{
+  switch (err)
+    {
+    case -1:
+    case 0:
+      break;
+      
+    default:
+      err = seterr (General_Error);
+      break;
+    }
+  return err;
+}
+
+int 
+map_kbx_err (int err)
+{
+  switch (err)
+    {
+    case -1:
+    case 0:
+      break;
+      
+    default:
+      err = seterr (General_Error);
+      break;
+    }
+  return err;
+}
+
similarity index 86%
rename from sm/mkerrors
rename to common/mkerrors
index 46c28e8..5a1ef33 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
-# mkerrors - Extract error strings from gpgsm.h
-#            and create C source for gpgsm_strerror
+# mkerrors - Extract error strings from errors.h
+#            and create C source for gnupg_strerror
 #      Copyright (C) 2001 Free Software Foundation, Inc.
 #
 # This file is part of GnuPG.
@@ -25,10 +25,10 @@ cat <<EOF
 
 #include <config.h>
 #include <stdio.h>
-#include "gpgsm.h"
+#include "errors.h"
 
 /**
- * gpgsm_strerror:
+ * gnupg_strerror:
  * @err:  Error code 
  * 
  * This function returns a textual representaion of the given
@@ -38,7 +38,7 @@ cat <<EOF
  * Return value: String with the error description.
  **/
 const char *
-gpgsm_strerror (int err)
+gnupg_strerror (int err)
 {
   const char *s;
   static char buf[25];
@@ -48,10 +48,10 @@ gpgsm_strerror (int err)
 EOF
 
 awk '
-/GPGSM_No_Error/  { okay=1 }
+/GNUPG_No_Error/  { okay=1 }
 !okay              {next}
 /}/                { exit 0 }
-/GPGSM_[A-Za-z_]*/ { print_code($1) }
+/GNUPG_[A-Za-z_]*/ { print_code($1) }
 
 
 function print_code( s )
similarity index 83%
rename from sm/util.h
rename to common/util.h
index ffd4a40..478d851 100644 (file)
--- a/sm/util.h
@@ -1,4 +1,4 @@
-/* util.h - Utility functions for GpgSM
+/* util.h - Utility functions for Gnupg
  *     Copyright (C) 2001 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-#ifndef UTIL_H
-#define UTIL_H
+#ifndef GNUPG_COMMON_UTIL_H
+#define GNUPG_COMMON_UTIL_H
 
 #include <gcrypt.h> /* we need this for the memory function protos */
 
-/* to pass the fucntion to libksba we need to cast it */
+/* to pass hash functions to libksba we need to cast it */
 #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
 
-
+/* get all the stuff from jnlib */
 #include "../jnlib/logging.h"
 #include "../jnlib/argparse.h"
 #include "../jnlib/stringhelp.h"
@@ -34,6 +34,7 @@
 #include "../jnlib/strlist.h"
 #include "../jnlib/dotlock.h"
 
+/* handy malloc macros  - use only them */
 #define xtrymalloc(a)    gcry_malloc ((a))
 #define xtrycalloc(a,b)  gcry_calloc ((a),(b))
 #define xtryrealloc(a,b) gcry_realloc ((a),(b))
 #define xrealloc(a,b)    gcry_xrealloc ((a),(b))
 #define xstrdup(a)       gcry_xstrdup ((a))
 
+#define seterr(a)  (GNUPG_ ## a)
 
-#define seterr(a)  (GPGSM_ ## a)
-
-/*-- misc.c --*/
+/*-- maperror.c --*/
 int map_ksba_err (int err);
 int map_gcry_err (int err);
 int map_kbx_err (int err);
 
-#endif /*UTIL_H*/
+
+#endif /*GNUPG_COMMON_UTIL_H*/
 
 
index e8b015b..dcc0730 100644 (file)
@@ -31,7 +31,7 @@
 #include "../jnlib/logging.h"
 #include "../jnlib/argparse.h"
 #include "../jnlib/stringhelp.h"
-#include "i18n.h"
+#include "../common/i18n.h"
 #include "keybox-defs.h"
 
 enum cmd_and_opt_values {
index 67cd8c7..5e26382 100644 (file)
 
 bin_PROGRAMS = gpgsm
 
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
+INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/intl
 LDFLAGS = @LDFLAGS@ 
 #$(LIBGCRYPT_LIBS)
-BUILT_SOURCES = errors.c
 
 gpgsm_SOURCES = \
        gpgsm.c gpgsm.h \
-       util.h misc.c errors.c \
+       misc.c \
        keydb.c keydb.h \
        server.c \
        fingerprint.c \
@@ -41,11 +40,8 @@ gpgsm_SOURCES = \
 
 
 gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a ../kbx/libkeybox.a \
+              ../common/libcommon.a \
               ../../libksba/src/.libs/libksba.a \
               ../../libgcrypt/src/.libs/libgcrypt.so.1 
 
 
-errors.c : gpgsm.h mkerrors
-       $(srcdir)/mkerrors < $(srcdir)/gpgsm.h > errors.c
-
-
index 518acfe..9b98ce8 100644 (file)
@@ -46,7 +46,7 @@ gpgsm_validate_path (KsbaCert cert)
   if (!kh)
     {
       log_error (_("failed to allocated keyDB handle\n"));
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       goto leave;
     }
 
@@ -65,7 +65,7 @@ gpgsm_validate_path (KsbaCert cert)
         {
           if (DBG_X509)
             log_debug ("ERROR: issuer missing\n");
-          rc = GPGSM_Bad_Certificate;
+          rc = GNUPG_Bad_Certificate;
           goto leave;
         }
 
@@ -74,7 +74,7 @@ gpgsm_validate_path (KsbaCert cert)
           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
             {
               log_debug ("selfsigned certificate has a BAD signatures\n");
-              rc = depth? GPGSM_Bad_Certificate_Path : GPGSM_Bad_Certificate;
+              rc = depth? GNUPG_Bad_Certificate_Path : GNUPG_Bad_Certificate;
               goto leave;
             }
           log_debug ("selfsigned certificate is good\n");
@@ -90,7 +90,7 @@ gpgsm_validate_path (KsbaCert cert)
       if (rc)
         {
           log_debug ("failed to find issuer's certificate: rc=%d\n", rc);
-          rc = GPGSM_Missing_Certificate;
+          rc = GNUPG_Missing_Certificate;
           goto leave;
         }
 
@@ -99,7 +99,7 @@ gpgsm_validate_path (KsbaCert cert)
       if (rc)
         {
           log_debug ("failed to get cert: rc=%d\n", rc);
-          rc = GPGSM_General_Error;
+          rc = GNUPG_General_Error;
           goto leave;
         }
 
@@ -109,7 +109,7 @@ gpgsm_validate_path (KsbaCert cert)
       if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
         {
           log_debug ("certificate has a BAD signatures\n");
-          rc = GPGSM_Bad_Certificate_Path;
+          rc = GNUPG_Bad_Certificate_Path;
           goto leave;
         }
       log_debug ("certificate is good\n");
index 2d5448e..b648c88 100644 (file)
@@ -50,7 +50,7 @@ do_encode_md (GCRY_MD_HD md, int algo,  unsigned int nbits,
   if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
     {
       log_error ("No object identifier for algo %d\n", algo);
-      return GPGSM_Internal_Error;
+      return GNUPG_Internal_Error;
     }
 
   len = gcry_md_get_algo_dlen (algo);
@@ -59,7 +59,7 @@ do_encode_md (GCRY_MD_HD md, int algo,  unsigned int nbits,
     {
       log_error ("can't encode a %d bit MD into a %d bits frame\n",
                  (int)(len*8), (int)nbits);
-      return GPGSM_Internal_Error;
+      return GNUPG_Internal_Error;
     }
   
   /* We encode the MD in this way:
@@ -70,7 +70,7 @@ do_encode_md (GCRY_MD_HD md, int algo,  unsigned int nbits,
    */
   frame = xtrymalloc (nframe);
   if (!frame)
-    return GPGSM_Out_Of_Core;
+    return GNUPG_Out_Of_Core;
   n = 0;
   frame[n++] = 0;
   frame[n++] = 1; /* block type */
@@ -114,13 +114,13 @@ gpgsm_check_cert_sig (KsbaCert issuer_cert, KsbaCert cert)
   if (!algo)
     {
       log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
-      return GPGSM_General_Error;
+      return GNUPG_General_Error;
     }
   md = gcry_md_open (algo, 0);
   if (!md)
     {
       log_error ("md_open failed: %s\n", gcry_strerror (-1));
-      return GPGSM_General_Error;
+      return GNUPG_General_Error;
     }
 
   rc = ksba_cert_hash (cert, 1, HASH_FNC, md);
index 518acfe..9b98ce8 100644 (file)
@@ -46,7 +46,7 @@ gpgsm_validate_path (KsbaCert cert)
   if (!kh)
     {
       log_error (_("failed to allocated keyDB handle\n"));
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       goto leave;
     }
 
@@ -65,7 +65,7 @@ gpgsm_validate_path (KsbaCert cert)
         {
           if (DBG_X509)
             log_debug ("ERROR: issuer missing\n");
-          rc = GPGSM_Bad_Certificate;
+          rc = GNUPG_Bad_Certificate;
           goto leave;
         }
 
@@ -74,7 +74,7 @@ gpgsm_validate_path (KsbaCert cert)
           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
             {
               log_debug ("selfsigned certificate has a BAD signatures\n");
-              rc = depth? GPGSM_Bad_Certificate_Path : GPGSM_Bad_Certificate;
+              rc = depth? GNUPG_Bad_Certificate_Path : GNUPG_Bad_Certificate;
               goto leave;
             }
           log_debug ("selfsigned certificate is good\n");
@@ -90,7 +90,7 @@ gpgsm_validate_path (KsbaCert cert)
       if (rc)
         {
           log_debug ("failed to find issuer's certificate: rc=%d\n", rc);
-          rc = GPGSM_Missing_Certificate;
+          rc = GNUPG_Missing_Certificate;
           goto leave;
         }
 
@@ -99,7 +99,7 @@ gpgsm_validate_path (KsbaCert cert)
       if (rc)
         {
           log_debug ("failed to get cert: rc=%d\n", rc);
-          rc = GPGSM_General_Error;
+          rc = GNUPG_General_Error;
           goto leave;
         }
 
@@ -109,7 +109,7 @@ gpgsm_validate_path (KsbaCert cert)
       if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
         {
           log_debug ("certificate has a BAD signatures\n");
-          rc = GPGSM_Bad_Certificate_Path;
+          rc = GNUPG_Bad_Certificate_Path;
           goto leave;
         }
       log_debug ("certificate is good\n");
index a00e11d..f1d4fca 100644 (file)
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-#ifndef GPGSM_H
-#define GPGSM_H
+#ifndef GNUPG_H
+#define GNUPG_H
 
 #include <ksba.h>
-#include "util.h"
-
-/* Error numbers */
-enum {
-  GPGSM_EOF = -1,
-  GPGSM_No_Error = 0,
-  GPGSM_General_Error = 1, 
-  GPGSM_Out_Of_Core = 2,
-  GPGSM_Invalid_Value = 3,
-  GPGSM_IO_Error = 4,
-  GPGSM_Resource_Limit = 5,
-  GPGSM_Internal_Error = 6,
-  GPGSM_Bad_Certificate = 7,
-  GPGSM_Bad_Certificate_Path = 8,
-  GPGSM_Missing_Certificate = 9,
-  GPGSM_No_Data = 10,
-  GPGSM_Bad_Signature = 11,
-  GPGSM_Not_Implemented = 12,
-  GPGSM_Conflict = 13,
-  GPGSM_Bug = 14
-};
-
-/* Status codes (shared with gpg) */
-enum {
-  STATUS_ENTER,
-  STATUS_LEAVE,
-  STATUS_ABORT,
-  STATUS_GOODSIG,
-  STATUS_BADSIG,
-  STATUS_ERRSIG,
-  STATUS_BADARMOR,
-  STATUS_RSA_OR_IDEA,
-  STATUS_SIGEXPIRED,
-  STATUS_KEYREVOKED,
-  STATUS_TRUST_UNDEFINED,
-  STATUS_TRUST_NEVER,
-  STATUS_TRUST_MARGINAL,
-  STATUS_TRUST_FULLY,
-  STATUS_TRUST_ULTIMATE,
-  
-  STATUS_SHM_INFO,
-  STATUS_SHM_GET,
-  STATUS_SHM_GET_BOOL,
-  STATUS_SHM_GET_HIDDEN,
-  
-  STATUS_NEED_PASSPHRASE,
-  STATUS_VALIDSIG,
-  STATUS_SIG_ID,
-  STATUS_ENC_TO,
-  STATUS_NODATA,
-  STATUS_BAD_PASSPHRASE,
-  STATUS_NO_PUBKEY,
-  STATUS_NO_SECKEY,
-  STATUS_NEED_PASSPHRASE_SYM,
-  STATUS_DECRYPTION_FAILED,
-  STATUS_DECRYPTION_OKAY,
-  STATUS_MISSING_PASSPHRASE,
-  STATUS_GOOD_PASSPHRASE,
-  STATUS_GOODMDC,
-  STATUS_BADMDC,
-  STATUS_ERRMDC,
-  STATUS_IMPORTED,
-  STATUS_IMPORT_RES,
-  STATUS_FILE_START,
-  STATUS_FILE_DONE,
-  STATUS_FILE_ERROR,
-  
-  STATUS_BEGIN_DECRYPTION,
-  STATUS_END_DECRYPTION,
-  STATUS_BEGIN_ENCRYPTION,
-  STATUS_END_ENCRYPTION,
-  
-  STATUS_DELETE_PROBLEM,
-  STATUS_GET_BOOL,
-  STATUS_GET_LINE,
-  STATUS_GET_HIDDEN,
-  STATUS_GOT_IT,
-  STATUS_PROGRESS,
-  STATUS_SIG_CREATED,
-  STATUS_SESSION_KEY,
-  STATUS_NOTATION_NAME,
-  STATUS_NOTATION_DATA,
-  STATUS_POLICY_URL,
-  STATUS_BEGIN_STREAM,
-  STATUS_END_STREAM,
-  STATUS_KEY_CREATED,
-  STATUS_USERID_HIN,
-  STATUS_UNEXPECTED,
-  STATUS_INV_RECP,
-  STATUS_NO_RECP,
-  STATUS_ALREADY_SIGNED,
-};
-
+#include "../common/util.h"
+#include "../common/errors.h"
 
 #define MAX_DIGEST_LEN 24 
 
@@ -224,7 +133,7 @@ int gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp);
 
 
 /*-- errors.c (built) --*/
-const char *gpgsm_strerror (int err);
+const char *gnupg_strerror (int err);
 
 
-#endif /*GPGSM_H*/
+#endif /*GNUPG_H*/
index ba21312..fc628a6 100644 (file)
@@ -251,12 +251,12 @@ store_cert (KsbaCert cert)
     }
   rc = keydb_locate_writable (kh, 0);
   if (rc)
-      log_error (_("error finding writable keyDB: %s\n"), gpgsm_strerror (rc));
+      log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc));
 
   rc = keydb_insert_cert (kh, cert);
   if (rc)
     {
-      log_error (_("error storing certificate: %s\n"), gpgsm_strerror (rc));
+      log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc));
     }
   keydb_release (kh);               
 }
index 6ca7a33..b6501fe 100644 (file)
@@ -97,7 +97,7 @@ keydb_add_resource (const char *url, int force, int secret)
       #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
        else if (strchr (resname, ':')) {
            log_error ("invalid key resource URL `%s'\n", url );
-           rc = GPGSM_General_Error;
+           rc = GNUPG_General_Error;
            goto leave;
        }
       #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
@@ -141,7 +141,7 @@ keydb_add_resource (const char *url, int force, int secret)
     switch (rt) {
       case KEYDB_RESOURCE_TYPE_NONE:
        log_error ("unknown type of key resource `%s'\n", url );
-       rc = GPGSM_General_Error;
+       rc = GNUPG_General_Error;
        goto leave;
 
       case KEYDB_RESOURCE_TYPE_KEYBOX:
@@ -205,7 +205,7 @@ keydb_add_resource (const char *url, int force, int secret)
           if (!token)
             ; /* already registered - ignore it */
           else if (used_resources >= MAX_KEYDB_RESOURCES)
-              rc = GPGSM_Resource_Limit;
+              rc = GNUPG_Resource_Limit;
           else 
             {
               all_resources[used_resources].type = rt;
@@ -219,7 +219,7 @@ keydb_add_resource (const char *url, int force, int secret)
 
       default:
        log_error ("resource type of `%s' not supported\n", url);
-       rc = GPGSM_General_Error;
+       rc = GNUPG_General_Error;
        goto leave;
     }
 
@@ -227,7 +227,7 @@ keydb_add_resource (const char *url, int force, int secret)
 
   leave:
     if (rc)
-      log_error ("keyblock resource `%s': %s\n", filename, gpgsm_strerror(rc));
+      log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
     else if (secret)
        any_secret = 1;
     else
@@ -520,7 +520,7 @@ keydb_get_cert (KEYDB_HANDLE hd, KsbaCert *r_cert)
   int rc = 0;
 
   if (!hd)
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
   
   if ( hd->found < 0 || hd->found >= hd->used) 
     return -1; /* nothing found */
@@ -528,7 +528,7 @@ keydb_get_cert (KEYDB_HANDLE hd, KsbaCert *r_cert)
   switch (hd->active[hd->found].type) 
     {
     case KEYDB_RESOURCE_TYPE_NONE:
-      rc = GPGSM_General_Error; /* oops */
+      rc = GNUPG_General_Error; /* oops */
       break;
     case KEYDB_RESOURCE_TYPE_KEYBOX:
       rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
@@ -549,7 +549,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, KsbaCert cert)
   char digest[20];
   
   if (!hd) 
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
 
   if (opt.dry_run)
     return 0;
@@ -559,7 +559,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, KsbaCert cert)
   else if ( hd->current >= 0 && hd->current < hd->used) 
     idx = hd->current;
   else
-    return GPGSM_General_Error;
+    return GNUPG_General_Error;
 
   rc = lock_all (hd);
   if (rc)
@@ -570,7 +570,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, KsbaCert cert)
   switch (hd->active[idx].type) 
     {
     case KEYDB_RESOURCE_TYPE_NONE:
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       break;
     case KEYDB_RESOURCE_TYPE_KEYBOX:
       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
@@ -591,7 +591,7 @@ keydb_update_cert (KEYDB_HANDLE hd, KsbaCert cert)
   char digest[20];
   
   if (!hd)
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
 
   if ( hd->found < 0 || hd->found >= hd->used) 
     return -1; /* nothing found */
@@ -608,7 +608,7 @@ keydb_update_cert (KEYDB_HANDLE hd, KsbaCert cert)
   switch (hd->active[hd->found].type) 
     {
     case KEYDB_RESOURCE_TYPE_NONE:
-      rc = GPGSM_General_Error; /* oops */
+      rc = GNUPG_General_Error; /* oops */
       break;
     case KEYDB_RESOURCE_TYPE_KEYBOX:
       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
@@ -629,7 +629,7 @@ keydb_delete (KEYDB_HANDLE hd)
   int rc = -1;
   
   if (!hd)
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
 
   if ( hd->found < 0 || hd->found >= hd->used) 
     return -1; /* nothing found */
@@ -644,7 +644,7 @@ keydb_delete (KEYDB_HANDLE hd)
   switch (hd->active[hd->found].type)
     {
     case KEYDB_RESOURCE_TYPE_NONE:
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       break;
     case KEYDB_RESOURCE_TYPE_KEYBOX:
       rc = keybox_delete (hd->active[hd->found].u.kr);
@@ -668,7 +668,7 @@ keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
   int rc;
   
   if (!hd)
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
   
   rc = keydb_search_reset (hd); /* this does reset hd->current */
   if (rc)
@@ -728,7 +728,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
   int i, rc = 0;
   
   if (!hd)
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
 
   hd->current = 0; 
   hd->found = -1;
@@ -758,7 +758,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
   int rc = -1;
   
   if (!hd)
-    return GPGSM_Invalid_Value;
+    return GNUPG_Invalid_Value;
 
   while (rc == -1 && hd->current >= 0 && hd->current < hd->used) 
     {
index f1aaf9e..f47a0b7 100644 (file)
@@ -131,13 +131,13 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp)
 
   hd = keydb_new (0);
   if (!hd)
-    rc = GPGSM_General_Error;
+    rc = GNUPG_General_Error;
   else
     rc = keydb_search_first (hd);
   if (rc)
     {
       if (rc != -1)
-        log_error ("keydb_search_first failed: %s\n", gpgsm_strerror (rc) );
+        log_error ("keydb_search_first failed: %s\n", gnupg_strerror (rc) );
       goto leave;
     }
 
@@ -147,7 +147,7 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp)
       rc = keydb_get_cert (hd, &cert);
       if (rc) 
         {
-          log_error ("keydb_get_cert failed: %s\n", gpgsm_strerror (rc));
+          log_error ("keydb_get_cert failed: %s\n", gnupg_strerror (rc));
           goto leave;
         }
       
@@ -175,7 +175,7 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp)
     }
   while (!(rc = keydb_search_next (hd)));
   if (rc && rc != -1)
-    log_error ("keydb_search_next failed: %s\n", gpgsm_strerror (rc));
+    log_error ("keydb_search_next failed: %s\n", gnupg_strerror (rc));
   
  leave:
   ksba_cert_release (cert);
index d3f0aab..3260b90 100644 (file)
--- a/sm/misc.c
+++ b/sm/misc.c
 
 #include <ksba.h>
 
-#include "util.h"
 #include "gpgsm.h"
 
-
-/* Note: we might want to wrap this in a macro to get our hands on
-   the line and file where the error occired */
-int
-map_ksba_err (int err)
-{
-  switch (err)
-    {
-    case -1:
-    case 0:
-      break;
-      
-    default:
-      err = GPGSM_General_Error;
-      break;
-    }
-  return err;
-}
-
-
-int 
-map_gcry_err (int err)
-{
-  switch (err)
-    {
-    case -1:
-    case 0:
-      break;
-      
-    default:
-      err = GPGSM_General_Error;
-      break;
-    }
-  return err;
-}
-
-int 
-map_kbx_err (int err)
-{
-  switch (err)
-    {
-    case -1:
-    case 0:
-      break;
-      
-    default:
-      err = GPGSM_General_Error;
-      break;
-    }
-  return err;
-}
-
-
-
-
-
-
-
index 98e3dbf..f87f1ce 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -136,7 +136,7 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
   if (!kh)
     {
       log_error (_("failed to allocated keyDB handle\n"));
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       goto leave;
     }
 
@@ -238,7 +238,7 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
       if (!algo)
         {
           log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
-          rc = GPGSM_Bug;
+          rc = GNUPG_Bug;
           goto leave;
         }
       gcry_md_enable (data_md, algo);
@@ -261,7 +261,7 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
       if ( !digest || !digest_len)
         {
           log_error ("problem getting the hash of the data\n");
-          rc = GPGSM_Bug;
+          rc = GNUPG_Bug;
           goto leave;
         }
       err = ksba_cms_set_message_digest (cms, signer, digest, digest_len);
index 26bb8cf..b44dd6a 100644 (file)
@@ -109,12 +109,12 @@ store_cert (KsbaCert cert)
     }
   rc = keydb_locate_writable (kh, 0);
   if (rc)
-      log_error (_("error finding writable keyDB: %s\n"), gpgsm_strerror (rc));
+      log_error (_("error finding writable keyDB: %s\n"), gnupg_strerror (rc));
 
   rc = keydb_insert_cert (kh, cert);
   if (rc)
     {
-      log_error (_("error storing certificate: %s\n"), gpgsm_strerror (rc));
+      log_error (_("error storing certificate: %s\n"), gnupg_strerror (rc));
     }
   keydb_release (kh);               
 }
@@ -190,7 +190,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
   if (!kh)
     {
       log_error (_("failed to allocated keyDB handle\n"));
-      rc = GPGSM_General_Error;
+      rc = GNUPG_General_Error;
       goto leave;
     }
 
@@ -264,7 +264,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       if (stopreason == KSBA_SR_BEGIN_DATA)
         {
           log_error ("error: only detached signatures are supportted\n");
-          rc = GPGSM_Not_Implemented;
+          rc = GNUPG_Not_Implemented;
           goto leave;
         }
 
@@ -285,7 +285,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
               if (data_fd == -1)
                 {
                   log_error ("detached signature but no data given\n");
-                  rc = GPGSM_Bad_Signature;
+                  rc = GNUPG_Bad_Signature;
                   goto leave;
                 }
               hash_data (data_fd, data_md);  
@@ -297,7 +297,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
   if (data_fd != -1 && !is_detached)
     {
       log_error ("data given for a non-detached signature");
-      rc = GPGSM_Conflict;
+      rc = GNUPG_Conflict;
       goto leave;
     }
 
@@ -357,14 +357,14 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       if (rc)
         {
           log_debug ("failed to find the certificate: %s\n",
-                     gpgsm_strerror(rc));
+                     gnupg_strerror(rc));
           goto next_signer;
         }
 
       rc = keydb_get_cert (kh, &cert);
       if (rc)
         {
-          log_debug ("failed to get cert: %s\n", gpgsm_strerror (rc));
+          log_debug ("failed to get cert: %s\n", gnupg_strerror (rc));
           goto next_signer;
         }
 
@@ -411,7 +411,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
 
       if (rc)
         {
-          log_error ("invalid signature: %s\n", gpgsm_strerror (rc));
+          log_error ("invalid signature: %s\n", gnupg_strerror (rc));
           gpgsm_status (ctrl, STATUS_BADSIG, NULL);
           goto next_signer;
         }
@@ -433,9 +433,9 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       rc = gpgsm_validate_path (cert);
       if (rc)
         {
-          log_error ("invalid certification path: %s\n", gpgsm_strerror (rc));
-          if (rc == GPGSM_Bad_Certificate_Path
-              || rc == GPGSM_Bad_Certificate)
+          log_error ("invalid certification path: %s\n", gnupg_strerror (rc));
+          if (rc == GNUPG_Bad_Certificate_Path
+              || rc == GNUPG_Bad_Certificate)
             gpgsm_status (ctrl, STATUS_TRUST_NEVER, NULL);
           else
             gpgsm_status (ctrl, STATUS_TRUST_UNDEFINED, NULL);