* keydb.c (keydb_add_resource): Create keybox
authorWerner Koch <wk@gnupg.org>
Mon, 26 Nov 2001 13:08:36 +0000 (13:08 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 26 Nov 2001 13:08:36 +0000 (13:08 +0000)
* keylist.c (gpgsm_list_keys): Fixed non-server keylisting.
* server.c (rc_to_assuan_status): New.  Use it for all commands.

sm/ChangeLog
sm/call-agent.c
sm/keydb.c
sm/keylist.c
sm/server.c
sm/sign.c
sm/verify.c

index e69de29..878002c 100644 (file)
@@ -0,0 +1,20 @@
+2001-11-26  Werner Koch  <wk@gnupg.org>
+
+       * keydb.c (keydb_add_resource): Create keybox
+
+       * keylist.c (gpgsm_list_keys): Fixed non-server keylisting.
+
+       * server.c (rc_to_assuan_status): New.  Use it for all commands.
+
+       
+ Copyright 2001 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+       
+
index c440f2b..16cc46f 100644 (file)
@@ -470,16 +470,16 @@ request_reply (const char *line, struct membuf *membuf)
           for (;len && *p != '%'; len--, p++)
             ;
           put_membuf (membuf, buf, p-buf);
-          buf = p;
           if (len>2)
             { /* handle escaping */
               unsigned char tmp[1];
-              buf++;
-              *tmp = xtoi_2 (buf);
-              buf += 2;
+              p++;
+              *tmp = xtoi_2 (p);
+              p += 2;
               len -= 3;
               put_membuf (membuf, tmp, 1);
             }
+          buf = p;
         }
       goto again;
     }
index b6501fe..a5f3f41 100644 (file)
@@ -78,134 +78,130 @@ static void unlock_all (KEYDB_HANDLE hd);
 int
 keydb_add_resource (const char *url, int force, int secret)
 {
-    static int any_secret, any_public;
-    const char *resname = url;
-    char *filename = NULL;
-    int rc = 0; 
-    KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
-/*      const char *created_fname = NULL; */
-
-    /* Do we have an URL?
-     * gnupg-ring:filename  := this is a plain keybox
-     * filename := See what is is, but create as plain keybox.
-     */
-    if (strlen (resname) > 11) {
-       if (!strncmp( resname, "gnupg-kbx:", 10) ) {
-           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-           resname += 11;
+  static int any_secret, any_public;
+  const char *resname = url;
+  char *filename = NULL;
+  int rc = 0; 
+  FILE *fp;
+  KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
+  const char *created_fname = NULL;
+
+  /* Do we have an URL?
+     gnupg-kbx:filename := this is a plain keybox
+     filename := See what is is, but create as plain keybox.
+  */
+  if (strlen (resname) > 10) 
+    {
+      if (!strncmp (resname, "gnupg-kbx:", 10) )
+        {
+          rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+          resname += 10;
        }
-      #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
-       else if (strchr (resname, ':')) {
-           log_error ("invalid key resource URL `%s'\n", url );
-           rc = GNUPG_General_Error;
-           goto leave;
+#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
+      else if (strchr (resname, ':'))
+        {
+          log_error ("invalid key resource URL `%s'\n", url );
+          rc = GNUPG_General_Error;
+          goto leave;
        }
-      #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
+#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
     }
 
-    if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
-       if (strchr(resname, DIRSEP_C) )
-           filename = make_filename (resname, NULL);
-       else
-           filename = make_filename (opt.homedir, resname, NULL);
+  if (*resname != DIRSEP_C )
+    { /* do tilde expansion etc */
+      if (strchr(resname, DIRSEP_C) )
+        filename = make_filename (resname, NULL);
+      else
+        filename = make_filename (opt.homedir, resname, NULL);
     }
-    else
-       filename = xstrdup (resname);
-
-    if (!force)
-       force = secret? !any_secret : !any_public;
-
-    /* see whether we can determine the filetype */
-    if (rt == KEYDB_RESOURCE_TYPE_NONE) {
-       FILE *fp2 = fopen( filename, "rb" );
-
-       if (fp2) {
-           u32 magic;
-
-            /* FIXME: check for the keybox magic */
-           if (fread( &magic, 4, 1, fp2) == 1 ) 
-              {
-               if (magic == 0x13579ace || magic == 0xce9a5713)
-                  ; /* GDBM magic - no more support */
-               else
-                  rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-              }
-           else /* maybe empty: assume ring */
+  else
+    filename = xstrdup (resname);
+  
+  if (!force)
+    force = secret? !any_secret : !any_public;
+  
+  /* see whether we can determine the filetype */
+  if (rt == KEYDB_RESOURCE_TYPE_NONE)
+    {
+      FILE *fp2 = fopen( filename, "rb" );
+      
+      if (fp2) {
+        u32 magic;
+        
+        /* FIXME: check for the keybox magic */
+        if (fread( &magic, 4, 1, fp2) == 1 ) 
+          {
+            if (magic == 0x13579ace || magic == 0xce9a5713)
+              ; /* GDBM magic - no more support */
+            else
               rt = KEYDB_RESOURCE_TYPE_KEYBOX;
-           fclose (fp2);
-       }
-       else /* no file yet: create ring */
+          }
+        else /* maybe empty: assume ring */
           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
+        fclose (fp2);
+      }
+      else /* no file yet: create ring */
+        rt = KEYDB_RESOURCE_TYPE_KEYBOX;
     }
-
-    switch (rt) {
-      case KEYDB_RESOURCE_TYPE_NONE:
-       log_error ("unknown type of key resource `%s'\n", url );
-       rc = GNUPG_General_Error;
-       goto leave;
-
-      case KEYDB_RESOURCE_TYPE_KEYBOX:
-#if 0
-       fp = fopen (filename);
-       if (!iobuf && !force) {
-           rc = G10ERR_OPEN_FILE;
-           goto leave;
-       }
-
-       if (!fp) {
-           char *last_slash_in_filename;
-
-           last_slash_in_filename = strrchr (filename, DIRSEP_C);
-           *last_slash_in_filename = 0;
-
-           if (access(filename, F_OK)) {
-               /* on the first time we try to create the default
+    
+  switch (rt)
+    {
+    case KEYDB_RESOURCE_TYPE_NONE:
+      log_error ("unknown type of key resource `%s'\n", url );
+      rc = GNUPG_General_Error;
+      goto leave;
+      
+    case KEYDB_RESOURCE_TYPE_KEYBOX:
+      fp = fopen (filename, "rb");
+      if (!fp && !force)
+        {
+          rc = GNUPG_File_Open_Error;
+          goto leave;
+        }
+      
+      if (!fp)
+        { /* no file */
+#if 0 /* no autocreate of the homedirectory yet */
+          {
+            char *last_slash_in_filename;
+            
+            last_slash_in_filename = strrchr (filename, DIRSEP_C);
+            *last_slash_in_filename = 0;
+            if (access (filename, F_OK))
+              { /* on the first time we try to create the default
                    homedir and in this case the process will be
-                   terminated, so that on the next invocation it can
+                   terminated, so that on the next invocation can
                    read the options file in on startup */
-               try_make_homedir (filename);
-               rc = G10ERR_OPEN_FILE;
-               *last_slash_in_filename = DIRSEP_C;
-               goto leave;
+                try_make_homedir (filename);
+                rc = GNUPG_File_Open_Error;
+                *last_slash_in_filename = DIRSEP_C;
+                goto leave;
+              }
+            *last_slash_in_filename = DIRSEP_C;
+          }
+#endif
+          fp = fopen (filename, "w");
+          if (!fp)
+            {
+              log_error (_("error creating keybox `%s': %s\n"),
+                         filename, strerror(errno));
+              rc = GNUPG_File_Create_Error;
+              goto leave;
            }
 
-           *last_slash_in_filename = DIRSEP_C;
-
-           iobuf = iobuf_create (filename);
-           if (!iobuf) {
-               log_error ( _("error creating keybox `%s': %s\n"),
-                            filename, strerror(errno));
-               rc = G10ERR_OPEN_FILE;
-               goto leave;
-           }
-           else {
-             #ifndef HAVE_DOSISH_SYSTEM
-               if (secret && !opt.preserve_permissionws) {
-                   if (chmod (filename, S_IRUSR | S_IWUSR) ) {
-                       log_error (_("changing permission of "
-                                     " `%s' failed: %s\n"),
-                                   filename, strerror(errno) );
-                       rc = G10ERR_WRITE_FILE;
-                       goto leave;
-                   }
-               }
-             #endif
-               if (!opt.quiet)
-                    log_info (_("keybox `%s' created\n"), filename);
-                created_fname = filename;
-           }
+          if (!opt.quiet)
+            log_info (_("keybox `%s' created\n"), filename);
+          created_fname = filename;
        }
-       iobuf_close (iobuf);
-       iobuf = NULL;
-        if (created_fname) /* must invalidate that ugly cache */
-            iobuf_ioctl (NULL, 2, 0, (char*)created_fname);
-#endif     
+       fclose (fp);
+       fp = NULL;
+        /* now regsiter the file */
         {
           void *token = keybox_register_file (filename, secret);
           if (!token)
             ; /* already registered - ignore it */
           else if (used_resources >= MAX_KEYDB_RESOURCES)
-              rc = GNUPG_Resource_Limit;
+            rc = GNUPG_Resource_Limit;
           else 
             {
               all_resources[used_resources].type = rt;
@@ -216,29 +212,26 @@ keydb_add_resource (const char *url, int force, int secret)
             }
         }
        break;
-
-      default:
-       log_error ("resource type of `%s' not supported\n", url);
-       rc = GNUPG_General_Error;
-       goto leave;
+    default:
+      log_error ("resource type of `%s' not supported\n", url);
+      rc = GNUPG_Not_Supported;
+      goto leave;
     }
 
-    /* fixme: check directory permissions and print a warning */
+  /* fixme: check directory permissions and print a warning */
 
 leave:
-    if (rc)
-      log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
-    else if (secret)
-       any_secret = 1;
-    else
-       any_public = 1;
-    xfree (filename);
-    return rc;
+ leave:
+  if (rc)
+    log_error ("keyblock resource `%s': %s\n", filename, gnupg_strerror(rc));
+  else if (secret)
+    any_secret = 1;
+  else
+    any_public = 1;
+  xfree (filename);
+  return rc;
 }
 
 
-
-
 KEYDB_HANDLE
 keydb_new (int secret)
 {
index 19bc9dd..98ae8eb 100644 (file)
@@ -168,13 +168,13 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp)
               putc ('\n', fp);
               lastresname = resname;
             }
-          if (ctrl->with_colons)
-            list_cert_colon (cert, fp);
-          else
-            list_cert_colon (cert, fp);
-          ksba_cert_release (cert); 
-          cert = NULL;
-        } 
+        }
+      if (ctrl->with_colons)
+        list_cert_colon (cert, fp);
+      else
+        list_cert_colon (cert, fp);
+      ksba_cert_release (cert); 
+      cert = NULL;
     }
   while (!(rc = keydb_search_next (hd)));
   if (rc && rc != -1)
index e2f7ec0..e835060 100644 (file)
@@ -42,6 +42,45 @@ struct server_local_s {
   int message_fd;
 };
 
+/* Map GNUPG_xxx error codes to Assuan status codes */
+static int
+rc_to_assuan_status (int rc)
+{
+  switch (rc)
+    {
+    case 0: break;
+    case GNUPG_Bad_Certificate:   rc = ASSUAN_Bad_Certificate; break;
+    case GNUPG_Bad_Certificate_Path: rc = ASSUAN_Bad_Certificate_Path; break;
+    case GNUPG_Missing_Certificate: rc = ASSUAN_Missing_Certificate; break;
+    case GNUPG_No_Data:           rc = ASSUAN_No_Data_Available; break;
+    case GNUPG_Bad_Signature:     rc = ASSUAN_Bad_Signature; break;
+    case GNUPG_Not_Implemented:   rc = ASSUAN_Not_Implemented; break;
+    case GNUPG_No_Agent:          rc = ASSUAN_No_Agent; break;
+    case GNUPG_Agent_Error:       rc = ASSUAN_Agent_Error; break;
+    case GNUPG_No_Public_Key:     rc = ASSUAN_No_Public_Key; break;
+    case GNUPG_No_Secret_Key:     rc = ASSUAN_No_Secret_Key; break;
+
+    case GNUPG_Read_Error: 
+    case GNUPG_Write_Error:
+    case GNUPG_IO_Error: 
+      rc = ASSUAN_Server_IO_Error;
+      break;
+    case GNUPG_Out_Of_Core:    
+    case GNUPG_Resource_Limit: 
+      rc = ASSUAN_Server_Resource_Problem;
+      break;
+    case GNUPG_Bug: 
+    case GNUPG_Internal_Error:   
+      rc = ASSUAN_Server_Bug;
+      break;
+    default: 
+      rc = ASSUAN_Server_Fault;
+      break;
+    }
+  return rc;
+}
+
+
 
 
 /*  RECIPIENT <userID>
@@ -116,15 +155,17 @@ cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
 static int 
 cmd_verify (ASSUAN_CONTEXT ctx, char *line)
 {
+  int rc;
   CTRL ctrl = assuan_get_pointer (ctx);
   int fd = assuan_get_input_fd (ctx);
 
   if (fd == -1)
     return set_error (No_Input, NULL);
 
-  gpgsm_verify (assuan_get_pointer (ctx), fd, ctrl->server_local->message_fd);
+  rc = gpgsm_verify (assuan_get_pointer (ctx), fd,
+                     ctrl->server_local->message_fd);
 
-  return 0;
+  return rc_to_assuan_status (rc);
 }
 
 
@@ -139,6 +180,7 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
   int inp_fd, out_fd;
   FILE *out_fp;
   int detached;
+  int rc;
 
   inp_fd = assuan_get_input_fd (ctx);
   if (inp_fd == -1)
@@ -152,10 +194,10 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
   out_fp = fdopen ( dup(out_fd), "w");
   if (!out_fp)
     return set_error (General_Error, "fdopen() failed");
-  gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp);
+  rc = gpgsm_sign (assuan_get_pointer (ctx), inp_fd, detached, out_fp);
   fclose (out_fp);
 
-  return 0;
+  return rc_to_assuan_status (rc);
 }
 
 
@@ -168,14 +210,15 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
 static int 
 cmd_import (ASSUAN_CONTEXT ctx, char *line)
 {
+  int rc;
   int fd = assuan_get_input_fd (ctx);
 
   if (fd == -1)
     return set_error (No_Input, NULL);
 
-  gpgsm_import (assuan_get_pointer (ctx), fd);
+  rc = gpgsm_import (assuan_get_pointer (ctx), fd);
 
-  return 0;
+  return rc_to_assuan_status (rc);
 }
 
 /* MESSAGE FD=<n>
@@ -211,7 +254,8 @@ cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
 
   ctrl->with_colons = 1;
   /* fixme: check that the returned data_fp is not NULL */
-  gpgsm_list_keys (assuan_get_pointer (ctx), NULL, assuan_get_data_fp (ctx));
+  gpgsm_list_keys (assuan_get_pointer (ctx), NULL,
+                        assuan_get_data_fp (ctx));
 
   return 0;
 }
index f87f1ce..a246511 100644 (file)
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -244,16 +244,16 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
       gcry_md_enable (data_md, algo);
     }
 
+  signer = 0;
   if (detached)
-    { /* we hash the data right now so tha we can store the message
-         digest.  ksba_cms_build() takes this as an flag that deatched
+    { /* we hash the data right now so that we can store the message
+         digest.  ksba_cms_build() takes this as an flag that detached
          data is expected. */
       unsigned char *digest;
       size_t digest_len;
       /* Fixme do this for all signers and get the algo to use from
          the signer's certificate - does not make mich sense, bu we
          should do this consistent as we have already done it above */
-      signer = 0;
       algo = GCRY_MD_SHA1; 
       hash_data (data_fd, data_md);
       digest = gcry_md_read (data_md, algo);
@@ -274,7 +274,14 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
         }
     }
 
-
+  err = ksba_cms_set_signing_time (cms, signer, 0 /*now*/);
+  if (err)
+    {
+      log_error ("ksba_cms_set_signing_time failed: %s\n",
+                 ksba_strerror (err));
+      rc = map_ksba_err (err);
+      goto leave;
+    }
 
   do 
     {
index 581cafe..5b3a5a8 100644 (file)
@@ -136,6 +136,28 @@ print_integer (unsigned char *p)
     }
 }
 
+static void
+print_time (time_t t)
+{
+
+  if (!t)
+    log_printf ("none");
+  else if ( t == (time_t)(-1) )
+    log_printf ("error");
+  else
+    {
+      struct tm *tp;
+
+      tp = gmtime (&t);
+      log_printf ("%04d-%02d-%02d %02d:%02d:%02d",
+                  1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+                  tp->tm_hour, tp->tm_min, tp->tm_sec);
+      assert (!tp->tm_isdst);
+    }
+}
+
+
+
 
 static void
 hash_data (int fd, GCRY_MD_HD md)
@@ -316,6 +338,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
     {
       char *issuer = NULL;
       char *sigval = NULL;
+      time_t sigtime;
       unsigned char *serial;
       char *msgdigest = NULL;
       size_t msgdigestlen;
@@ -328,6 +351,17 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
       print_integer (serial);
       log_printf ("\n");
 
+      err = ksba_cms_get_signing_time (cms, signer, &sigtime);
+      if (err)
+        {
+          log_debug ("error getting signing time: %s\n", ksba_strerror (err));
+          sigtime = (time_t)-1;
+        }
+      log_debug ("signer %d - sigtime: ", signer);
+      print_time (sigtime);  
+      log_printf ("\n");
+
+
       err = ksba_cms_get_message_digest (cms, signer,
                                          &msgdigest, &msgdigestlen);
       if (err)