Moved 1.9 branch to trunk
[gnupg.git] / sm / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #include "gpgsm.h"
33 #include "../kbx/keybox.h"
34 #include "keydb.h" 
35 #include "i18n.h"
36
37 static int active_handles;
38
39 typedef enum {
40     KEYDB_RESOURCE_TYPE_NONE = 0,
41     KEYDB_RESOURCE_TYPE_KEYBOX
42 } KeydbResourceType;
43 #define MAX_KEYDB_RESOURCES 20
44
45 struct resource_item {
46   KeydbResourceType type;
47   union {
48     KEYBOX_HANDLE kr;
49   } u;
50   void *token;
51   int secret;
52   DOTLOCK lockhandle;
53 };
54
55 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
56 static int used_resources;
57
58 struct keydb_handle {
59   int locked;
60   int found;
61   int current;
62   int is_ephemeral;
63   int used; /* items in active */
64   struct resource_item active[MAX_KEYDB_RESOURCES];
65 };
66
67
68 static int lock_all (KEYDB_HANDLE hd);
69 static void unlock_all (KEYDB_HANDLE hd);
70
71
72 /*
73  * Register a resource (which currently may only be a keybox file).
74  * The first keybox which is added by this function is
75  * created if it does not exist.
76  * Note: this function may be called before secure memory is
77  * available.
78  */
79 int
80 keydb_add_resource (const char *url, int force, int secret)
81 {
82   static int any_secret, any_public;
83   const char *resname = url;
84   char *filename = NULL;
85   int rc = 0; 
86   FILE *fp;
87   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
88   const char *created_fname = NULL;
89
90   /* Do we have an URL?
91      gnupg-kbx:filename := this is a plain keybox
92      filename := See what is is, but create as plain keybox.
93   */
94   if (strlen (resname) > 10) 
95     {
96       if (!strncmp (resname, "gnupg-kbx:", 10) )
97         {
98           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
99           resname += 10;
100         }
101 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
102       else if (strchr (resname, ':'))
103         {
104           log_error ("invalid key resource URL `%s'\n", url );
105           rc = gpg_error (GPG_ERR_GENERAL);
106           goto leave;
107         }
108 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
109     }
110
111   if (*resname != DIRSEP_C )
112     { /* do tilde expansion etc */
113       if (strchr(resname, DIRSEP_C) )
114         filename = make_filename (resname, NULL);
115       else
116         filename = make_filename (opt.homedir, resname, NULL);
117     }
118   else
119     filename = xstrdup (resname);
120   
121   if (!force)
122     force = secret? !any_secret : !any_public;
123   
124   /* see whether we can determine the filetype */
125   if (rt == KEYDB_RESOURCE_TYPE_NONE)
126     {
127       FILE *fp2 = fopen( filename, "rb" );
128       
129       if (fp2) {
130         u32 magic;
131         
132         /* FIXME: check for the keybox magic */
133         if (fread( &magic, 4, 1, fp2) == 1 ) 
134           {
135             if (magic == 0x13579ace || magic == 0xce9a5713)
136               ; /* GDBM magic - no more support */
137             else
138               rt = KEYDB_RESOURCE_TYPE_KEYBOX;
139           }
140         else /* maybe empty: assume ring */
141           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
142         fclose (fp2);
143       }
144       else /* no file yet: create ring */
145         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
146     }
147     
148   switch (rt)
149     {
150     case KEYDB_RESOURCE_TYPE_NONE:
151       log_error ("unknown type of key resource `%s'\n", url );
152       rc = gpg_error (GPG_ERR_GENERAL);
153       goto leave;
154       
155     case KEYDB_RESOURCE_TYPE_KEYBOX:
156       fp = fopen (filename, "rb");
157       if (!fp && !force)
158         {
159           rc = gpg_error (gpg_err_code_from_errno (errno));
160           goto leave;
161         }
162       
163       if (!fp)
164         { /* no file */
165 #if 0 /* no autocreate of the homedirectory yet */
166           {
167             char *last_slash_in_filename;
168             
169             last_slash_in_filename = strrchr (filename, DIRSEP_C);
170             *last_slash_in_filename = 0;
171             if (access (filename, F_OK))
172               { /* on the first time we try to create the default
173                    homedir and in this case the process will be
174                    terminated, so that on the next invocation can
175                    read the options file in on startup */
176                 try_make_homedir (filename);
177                 rc = gpg_error (GPG_ERR_FILE_OPEN_ERROR);
178                 *last_slash_in_filename = DIRSEP_C;
179                 goto leave;
180               }
181             *last_slash_in_filename = DIRSEP_C;
182           }
183 #endif
184           fp = fopen (filename, "w");
185           if (!fp)
186             {
187               rc = gpg_error (gpg_err_code_from_errno (errno));
188               log_error (_("error creating keybox `%s': %s\n"),
189                          filename, strerror(errno));
190               if (errno == ENOENT)
191                 log_info (_("you may want to start the gpg-agent first\n"));
192               goto leave;
193             }
194
195           if (!opt.quiet)
196             log_info (_("keybox `%s' created\n"), filename);
197           created_fname = filename;
198         }
199         fclose (fp);
200         fp = NULL;
201         /* now register the file */
202         {
203           
204           void *token = keybox_register_file (filename, secret);
205           if (!token)
206             ; /* already registered - ignore it */
207           else if (used_resources >= MAX_KEYDB_RESOURCES)
208             rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
209           else 
210             {
211               all_resources[used_resources].type = rt;
212               all_resources[used_resources].u.kr = NULL; /* Not used here */
213               all_resources[used_resources].token = token;
214               all_resources[used_resources].secret = secret;
215
216               all_resources[used_resources].lockhandle
217                 = create_dotlock (filename);
218               if (!all_resources[used_resources].lockhandle)
219                 log_fatal ( _("can't create lock for `%s'\n"), filename);
220
221               /* Do a compress run if needed and the file is not locked. */
222               if (!make_dotlock (all_resources[used_resources].lockhandle, 0))
223                 {
224                   KEYBOX_HANDLE kbxhd = keybox_new (token, secret);
225                   
226                   if (kbxhd)
227                     {
228                       keybox_compress (kbxhd);
229                       keybox_release (kbxhd);
230                     }
231                   release_dotlock (all_resources[used_resources].lockhandle);
232                 }
233                   
234               used_resources++;
235             }
236         }
237
238
239         break;
240     default:
241       log_error ("resource type of `%s' not supported\n", url);
242       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
243       goto leave;
244     }
245
246   /* fixme: check directory permissions and print a warning */
247
248  leave:
249   if (rc)
250     log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror(rc));
251   else if (secret)
252     any_secret = 1;
253   else
254     any_public = 1;
255   xfree (filename);
256   return rc;
257 }
258
259
260 KEYDB_HANDLE
261 keydb_new (int secret)
262 {
263   KEYDB_HANDLE hd;
264   int i, j;
265   
266   hd = xcalloc (1, sizeof *hd);
267   hd->found = -1;
268   
269   assert (used_resources <= MAX_KEYDB_RESOURCES);
270   for (i=j=0; i < used_resources; i++)
271     {
272       if (!all_resources[i].secret != !secret)
273         continue;
274       switch (all_resources[i].type)
275         {
276         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
277           break;
278         case KEYDB_RESOURCE_TYPE_KEYBOX:
279           hd->active[j].type   = all_resources[i].type;
280           hd->active[j].token  = all_resources[i].token;
281           hd->active[j].secret = all_resources[i].secret;
282           hd->active[j].lockhandle = all_resources[i].lockhandle;
283           hd->active[j].u.kr = keybox_new (all_resources[i].token, secret);
284           if (!hd->active[j].u.kr) 
285             {
286               xfree (hd);
287               return NULL; /* fixme: release all previously allocated handles*/
288             }
289           j++;
290           break;
291         }
292     }
293   hd->used = j;
294   
295   active_handles++;
296   return hd;
297 }
298
299 void 
300 keydb_release (KEYDB_HANDLE hd)
301 {
302   int i;
303   
304   if (!hd)
305     return;
306   assert (active_handles > 0);
307   active_handles--;
308
309   unlock_all (hd);
310   for (i=0; i < hd->used; i++)
311     {
312       switch (hd->active[i].type) 
313         {
314         case KEYDB_RESOURCE_TYPE_NONE:
315           break;
316         case KEYDB_RESOURCE_TYPE_KEYBOX:
317           keybox_release (hd->active[i].u.kr);
318           break;
319         }
320     }
321
322     xfree (hd);
323 }
324
325
326 /* Return the name of the current resource.  This is function first
327    looks for the last found found, then for the current search
328    position, and last returns the first available resource.  The
329    returned string is only valid as long as the handle exists.  This
330    function does only return NULL if no handle is specified, in all
331    other error cases an empty string is returned.  */
332 const char *
333 keydb_get_resource_name (KEYDB_HANDLE hd)
334 {
335   int idx;
336   const char *s = NULL;
337   
338   if (!hd) 
339     return NULL;
340
341   if ( hd->found >= 0 && hd->found < hd->used) 
342     idx = hd->found;
343   else if ( hd->current >= 0 && hd->current < hd->used) 
344     idx = hd->current;
345   else
346     idx = 0;
347
348   switch (hd->active[idx].type) 
349     {
350     case KEYDB_RESOURCE_TYPE_NONE:
351       s = NULL; 
352       break;
353     case KEYDB_RESOURCE_TYPE_KEYBOX:
354       s = keybox_get_resource_name (hd->active[idx].u.kr);
355       break;
356     }
357   
358   return s? s: "";
359 }
360
361 /* Switch the handle into ephemeral mode and return the orginal value. */
362 int
363 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
364 {
365   int i;
366
367   if (!hd)
368     return 0;
369
370   yes = !!yes;
371   if (hd->is_ephemeral != yes)
372     {
373       for (i=0; i < hd->used; i++)
374         {
375           switch (hd->active[i].type) 
376             {
377             case KEYDB_RESOURCE_TYPE_NONE:
378               break;
379             case KEYDB_RESOURCE_TYPE_KEYBOX:
380               keybox_set_ephemeral (hd->active[i].u.kr, yes);
381               break;
382             }
383         }
384     }
385       
386   i = hd->is_ephemeral;
387   hd->is_ephemeral = yes;
388   return i;
389 }
390
391
392 /* If the keyring has not yet been locked, lock it now.  This
393    operation is required before any update opeations; it is optionaly
394    for an insert operation.  The lock is released with
395    keydb_released. */
396 gpg_error_t
397 keydb_lock (KEYDB_HANDLE hd)
398 {
399   if (!hd)
400     return gpg_error (GPG_ERR_INV_HANDLE);
401   if (hd->locked)
402     return 0; /* Already locked. */
403   return lock_all (hd);
404 }
405
406
407 \f
408 static int 
409 lock_all (KEYDB_HANDLE hd)
410 {
411   int i, rc = 0;
412
413   /* Fixme: This locking scheme may lead to deadlock if the resources
414      are not added in the same order by all processes.  We are
415      currently only allowing one resource so it is not a problem. */
416   for (i=0; i < hd->used; i++) 
417     {
418       switch (hd->active[i].type) 
419         {
420         case KEYDB_RESOURCE_TYPE_NONE:
421           break;
422         case KEYDB_RESOURCE_TYPE_KEYBOX:
423           if (hd->active[i].lockhandle)
424             rc = make_dotlock (hd->active[i].lockhandle, -1);
425           break;
426         }
427       if (rc)
428         break;
429     }
430
431     if (rc) 
432       {
433         /* revert the already set locks */
434         for (i--; i >= 0; i--) 
435           {
436             switch (hd->active[i].type) 
437               {
438               case KEYDB_RESOURCE_TYPE_NONE:
439                 break;
440               case KEYDB_RESOURCE_TYPE_KEYBOX:
441                 if (hd->active[i].lockhandle)
442                   release_dotlock (hd->active[i].lockhandle);
443                 break;
444               }
445           }
446       }
447     else
448       hd->locked = 1;
449
450     /* make_dotlock () does not yet guarantee that errno is set, thus
451        we can't rely on the error reason and will simply use
452        EACCES. */
453     return rc? gpg_error (GPG_ERR_EACCES) : 0;
454 }
455
456 static void
457 unlock_all (KEYDB_HANDLE hd)
458 {
459   int i;
460   
461   if (!hd->locked)
462     return;
463
464   for (i=hd->used-1; i >= 0; i--) 
465     {
466       switch (hd->active[i].type) 
467         {
468         case KEYDB_RESOURCE_TYPE_NONE:
469           break;
470         case KEYDB_RESOURCE_TYPE_KEYBOX:
471           if (hd->active[i].lockhandle)
472             release_dotlock (hd->active[i].lockhandle);
473           break;
474         }
475     }
476   hd->locked = 0;
477 }
478
479 \f
480 #if 0
481 /*
482  * Return the last found keybox.  Caller must free it.
483  * The returned keyblock has the kbode flag bit 0 set for the node with
484  * the public key used to locate the keyblock or flag bit 1 set for 
485  * the user ID node.
486  */
487 int
488 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
489 {
490     int rc = 0;
491
492     if (!hd)
493         return G10ERR_INV_ARG;
494
495     if ( hd->found < 0 || hd->found >= hd->used) 
496         return -1; /* nothing found */
497
498     switch (hd->active[hd->found].type) {
499       case KEYDB_RESOURCE_TYPE_NONE:
500         rc = G10ERR_GENERAL; /* oops */
501         break;
502       case KEYDB_RESOURCE_TYPE_KEYBOX:
503         rc = keybox_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
504         break;
505     }
506
507     return rc;
508 }
509
510 /* 
511  * update the current keyblock with KB
512  */
513 int
514 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
515 {
516     int rc = 0;
517
518     if (!hd)
519         return G10ERR_INV_ARG;
520
521     if ( hd->found < 0 || hd->found >= hd->used) 
522         return -1; /* nothing found */
523
524     if( opt.dry_run )
525         return 0;
526
527     if (!hd->locked)
528       return gpg_error (GPG_ERR_NOT_LOCKED);
529
530     switch (hd->active[hd->found].type) {
531       case KEYDB_RESOURCE_TYPE_NONE:
532         rc = G10ERR_GENERAL; /* oops */
533         break;
534       case KEYDB_RESOURCE_TYPE_KEYBOX:
535         rc = keybox_update_keyblock (hd->active[hd->found].u.kr, kb);
536         break;
537     }
538
539     unlock_all (hd);
540     return rc;
541 }
542
543
544 /* 
545  * Insert a new KB into one of the resources. 
546  */
547 int
548 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
549 {
550     int rc = -1;
551     int idx;
552
553     if (!hd) 
554         return G10ERR_INV_ARG;
555
556     if( opt.dry_run )
557         return 0;
558
559     if ( hd->found >= 0 && hd->found < hd->used) 
560         idx = hd->found;
561     else if ( hd->current >= 0 && hd->current < hd->used) 
562         idx = hd->current;
563     else
564         return G10ERR_GENERAL;
565
566     rc = lock_all (hd);
567     if (rc)
568         return rc;
569
570     switch (hd->active[idx].type) {
571       case KEYDB_RESOURCE_TYPE_NONE:
572         rc = G10ERR_GENERAL; /* oops */
573         break;
574       case KEYDB_RESOURCE_TYPE_KEYBOX:
575         rc = keybox_insert_keyblock (hd->active[idx].u.kr, kb);
576         break;
577     }
578
579     unlock_all (hd);
580     return rc;
581 }
582
583 #endif /*disabled code*/
584
585
586 \f
587 /*
588   Return the last found object.  Caller must free it.  The returned
589   keyblock has the kbode flag bit 0 set for the node with the public
590   key used to locate the keyblock or flag bit 1 set for the user ID
591   node.  */
592 int
593 keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
594 {
595   int rc = 0;
596
597   if (!hd)
598     return gpg_error (GPG_ERR_INV_VALUE);
599   
600   if ( hd->found < 0 || hd->found >= hd->used) 
601     return -1; /* nothing found */
602   
603   switch (hd->active[hd->found].type) 
604     {
605     case KEYDB_RESOURCE_TYPE_NONE:
606       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
607       break;
608     case KEYDB_RESOURCE_TYPE_KEYBOX:
609       rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
610       break;
611     }
612   
613   return rc;
614 }
615
616 /* Return a flag of the last found object. WHICH is the flag requested;
617    it should be one of the KEYBOX_FLAG_ values.  If the operation is
618    successful, the flag value will be stored at the address given by
619    VALUE.  Return 0 on success or an error code. */
620 gpg_error_t
621 keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
622 {
623   int err = 0;
624
625   if (!hd)
626     return gpg_error (GPG_ERR_INV_VALUE);
627   
628   if ( hd->found < 0 || hd->found >= hd->used) 
629     return gpg_error (GPG_ERR_NOTHING_FOUND);
630   
631   switch (hd->active[hd->found].type) 
632     {
633     case KEYDB_RESOURCE_TYPE_NONE:
634       err = gpg_error (GPG_ERR_GENERAL); /* oops */
635       break;
636     case KEYDB_RESOURCE_TYPE_KEYBOX:
637       err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
638       break;
639     }
640   
641   return err;
642 }
643
644 /* Set a flag of the last found object. WHICH is the flag to be set; it
645    should be one of the KEYBOX_FLAG_ values.  If the operation is
646    successful, the flag value will be stored in the keybox.  Note,
647    that some flag values can't be updated and thus may return an
648    error, some other flag values may be masked out before an update.
649    Returns 0 on success or an error code. */
650 gpg_error_t
651 keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
652 {
653   int err = 0;
654
655   if (!hd)
656     return gpg_error (GPG_ERR_INV_VALUE);
657   
658   if ( hd->found < 0 || hd->found >= hd->used) 
659     return gpg_error (GPG_ERR_NOTHING_FOUND);
660   
661   if (!hd->locked)
662     return gpg_error (GPG_ERR_NOT_LOCKED);
663
664   switch (hd->active[hd->found].type) 
665     {
666     case KEYDB_RESOURCE_TYPE_NONE:
667       err = gpg_error (GPG_ERR_GENERAL); /* oops */
668       break;
669     case KEYDB_RESOURCE_TYPE_KEYBOX:
670       err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
671       break;
672     }
673   
674   return err;
675 }
676
677 /* 
678  * Insert a new Certificate into one of the resources. 
679  */
680 int
681 keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
682 {
683   int rc = -1;
684   int idx;
685   unsigned char digest[20];
686   
687   if (!hd) 
688     return gpg_error (GPG_ERR_INV_VALUE);
689
690   if (opt.dry_run)
691     return 0;
692   
693   if ( hd->found >= 0 && hd->found < hd->used) 
694     idx = hd->found;
695   else if ( hd->current >= 0 && hd->current < hd->used) 
696     idx = hd->current;
697   else
698     return gpg_error (GPG_ERR_GENERAL);
699
700   if (!hd->locked)
701     return gpg_error (GPG_ERR_NOT_LOCKED);
702
703   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
704
705   switch (hd->active[idx].type) 
706     {
707     case KEYDB_RESOURCE_TYPE_NONE:
708       rc = gpg_error (GPG_ERR_GENERAL);
709       break;
710     case KEYDB_RESOURCE_TYPE_KEYBOX:
711       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
712       break;
713     }
714   
715   unlock_all (hd);
716   return rc;
717 }
718
719
720
721 /* update the current keyblock with KB */
722 int
723 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
724 {
725   int rc = 0;
726   unsigned char digest[20];
727   
728   if (!hd)
729     return gpg_error (GPG_ERR_INV_VALUE);
730
731   if ( hd->found < 0 || hd->found >= hd->used) 
732     return -1; /* nothing found */
733
734   if (opt.dry_run)
735     return 0;
736
737   rc = lock_all (hd);
738   if (rc)
739     return rc;
740
741   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
742
743   switch (hd->active[hd->found].type) 
744     {
745     case KEYDB_RESOURCE_TYPE_NONE:
746       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
747       break;
748     case KEYDB_RESOURCE_TYPE_KEYBOX:
749       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
750       break;
751     }
752
753   unlock_all (hd);
754   return rc;
755 }
756
757
758 /* 
759  * The current keyblock or cert will be deleted.
760  */
761 int
762 keydb_delete (KEYDB_HANDLE hd, int unlock)
763 {
764   int rc = -1;
765   
766   if (!hd)
767     return gpg_error (GPG_ERR_INV_VALUE);
768
769   if ( hd->found < 0 || hd->found >= hd->used) 
770     return -1; /* nothing found */
771
772   if( opt.dry_run )
773     return 0;
774
775   if (!hd->locked)
776     return gpg_error (GPG_ERR_NOT_LOCKED); 
777
778   switch (hd->active[hd->found].type)
779     {
780     case KEYDB_RESOURCE_TYPE_NONE:
781       rc = gpg_error (GPG_ERR_GENERAL);
782       break;
783     case KEYDB_RESOURCE_TYPE_KEYBOX:
784       rc = keybox_delete (hd->active[hd->found].u.kr);
785       break;
786     }
787
788   if (unlock)
789     unlock_all (hd);
790   return rc;
791 }
792
793
794 \f
795 /*
796  * Locate the default writable key resource, so that the next
797  * operation (which is only relevant for inserts) will be done on this
798  * resource.  
799  */
800 int
801 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
802 {
803   int rc;
804   
805   if (!hd)
806     return gpg_error (GPG_ERR_INV_VALUE);
807   
808   rc = keydb_search_reset (hd); /* this does reset hd->current */
809   if (rc)
810     return rc;
811   
812   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) 
813     {
814       switch (hd->active[hd->current].type) 
815         {
816         case KEYDB_RESOURCE_TYPE_NONE:
817           BUG();
818           break;
819         case KEYDB_RESOURCE_TYPE_KEYBOX:
820           if (keybox_is_writable (hd->active[hd->current].token))
821             return 0; /* found (hd->current is set to it) */
822           break;
823         }
824     }
825   
826   return -1;
827 }
828
829 /*
830  * Rebuild the caches of all key resources.
831  */
832 void
833 keydb_rebuild_caches (void)
834 {
835   int i;
836   
837   for (i=0; i < used_resources; i++)
838     {
839       if (all_resources[i].secret)
840         continue;
841       switch (all_resources[i].type)
842         {
843         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
844           break;
845         case KEYDB_RESOURCE_TYPE_KEYBOX:
846 /*            rc = keybox_rebuild_cache (all_resources[i].token); */
847 /*            if (rc) */
848 /*              log_error (_("failed to rebuild keybox cache: %s\n"), */
849 /*                         g10_errstr (rc)); */
850           break;
851         }
852     }
853 }
854
855
856
857 /* 
858  * Start the next search on this handle right at the beginning
859  */
860 int 
861 keydb_search_reset (KEYDB_HANDLE hd)
862 {
863   int i, rc = 0;
864   
865   if (!hd)
866     return gpg_error (GPG_ERR_INV_VALUE);
867
868   hd->current = 0; 
869   hd->found = -1;
870   /* and reset all resources */
871   for (i=0; !rc && i < hd->used; i++) 
872     {
873       switch (hd->active[i].type) 
874         {
875         case KEYDB_RESOURCE_TYPE_NONE:
876           break;
877         case KEYDB_RESOURCE_TYPE_KEYBOX:
878           rc = keybox_search_reset (hd->active[i].u.kr);
879           break;
880         }
881     }
882   return rc; /* fixme: we need to map error codes or share them with
883                 all modules*/
884 }
885
886 /* 
887  * Search through all keydb resources, starting at the current position,
888  * for a keyblock which contains one of the keys described in the DESC array.
889  */
890 int 
891 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
892 {
893   int rc = -1;
894   
895   if (!hd)
896     return gpg_error (GPG_ERR_INV_VALUE);
897
898   while (rc == -1 && hd->current >= 0 && hd->current < hd->used) 
899     {
900       switch (hd->active[hd->current].type) 
901         {
902         case KEYDB_RESOURCE_TYPE_NONE:
903           BUG(); /* we should never see it here */
904           break;
905         case KEYDB_RESOURCE_TYPE_KEYBOX:
906           rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc);
907           break;
908         }
909       if (rc == -1) /* EOF -> switch to next resource */
910         hd->current++; 
911       else if (!rc)
912         hd->found = hd->current;
913     }
914   
915   return rc; 
916 }
917
918
919 int
920 keydb_search_first (KEYDB_HANDLE hd)
921 {
922   KEYDB_SEARCH_DESC desc;
923   
924   memset (&desc, 0, sizeof desc);
925   desc.mode = KEYDB_SEARCH_MODE_FIRST;
926   return keydb_search (hd, &desc, 1);
927 }
928
929 int
930 keydb_search_next (KEYDB_HANDLE hd)
931 {
932   KEYDB_SEARCH_DESC desc;
933   
934   memset (&desc, 0, sizeof desc);
935   desc.mode = KEYDB_SEARCH_MODE_NEXT;
936   return keydb_search (hd, &desc, 1);
937 }
938
939 int
940 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
941 {
942   KEYDB_SEARCH_DESC desc;
943   
944   memset (&desc, 0, sizeof desc);
945   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
946 /*    desc.u.kid[0] = kid[0]; */
947 /*    desc.u.kid[1] = kid[1]; */
948   return keydb_search (hd, &desc, 1);
949 }
950
951 int
952 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
953 {
954   KEYDB_SEARCH_DESC desc;
955   
956   memset (&desc, 0, sizeof desc);
957   desc.mode = KEYDB_SEARCH_MODE_FPR;
958   memcpy (desc.u.fpr, fpr, 20);
959   return keydb_search (hd, &desc, 1);
960 }
961
962 int
963 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
964 {
965   KEYDB_SEARCH_DESC desc;
966   int rc;
967   
968   memset (&desc, 0, sizeof desc);
969   desc.mode = KEYDB_SEARCH_MODE_ISSUER;
970   desc.u.name = issuer;
971   rc = keydb_search (hd, &desc, 1);
972   return rc;
973 }
974
975 int
976 keydb_search_issuer_sn (KEYDB_HANDLE hd,
977                         const char *issuer, ksba_const_sexp_t serial)
978 {
979   KEYDB_SEARCH_DESC desc;
980   int rc;
981   const unsigned char *s;
982   
983   memset (&desc, 0, sizeof desc);
984   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
985   s = serial;
986   if (*s !='(')
987     return gpg_error (GPG_ERR_INV_VALUE);
988   s++;
989   for (desc.snlen = 0; digitp (s); s++)
990     desc.snlen = 10*desc.snlen + atoi_1 (s);
991   if (*s !=':')
992     return gpg_error (GPG_ERR_INV_VALUE);
993   desc.sn = s+1;
994   desc.u.name = issuer;
995   rc = keydb_search (hd, &desc, 1);
996   return rc;
997 }
998
999 int
1000 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
1001 {
1002   KEYDB_SEARCH_DESC desc;
1003   int rc;
1004   
1005   memset (&desc, 0, sizeof desc);
1006   desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1007   desc.u.name = name;
1008   rc = keydb_search (hd, &desc, 1);
1009   return rc;
1010 }
1011
1012
1013 static int
1014 classify_user_id (const char *name, 
1015                   KEYDB_SEARCH_DESC *desc,
1016                   int *force_exact )
1017 {
1018   const char *s;
1019   int hexprefix = 0;
1020   int hexlength;
1021   int mode = 0;   
1022     
1023   /* clear the structure so that the mode field is set to zero unless
1024    * we set it to the correct value right at the end of this function */
1025   memset (desc, 0, sizeof *desc);
1026   *force_exact = 0;
1027   /* Skip leading spaces.  Fixme: what about trailing white space? */
1028   for(s = name; *s && spacep (s); s++ )
1029     ;
1030
1031   switch (*s) 
1032     {
1033     case 0:  /* empty string is an error */
1034       return 0;
1035
1036     case '.': /* an email address, compare from end */
1037       mode = KEYDB_SEARCH_MODE_MAILEND;
1038       s++;
1039       desc->u.name = s;
1040       break;
1041
1042     case '<': /* an email address */
1043       mode = KEYDB_SEARCH_MODE_MAIL;
1044       s++;
1045       desc->u.name = s;
1046       break;
1047
1048     case '@':  /* part of an email address */
1049       mode = KEYDB_SEARCH_MODE_MAILSUB;
1050       s++;
1051       desc->u.name = s;
1052       break;
1053
1054     case '=':  /* exact compare */
1055       mode = KEYDB_SEARCH_MODE_EXACT;
1056       s++;
1057       desc->u.name = s;
1058       break;
1059
1060     case '*':  /* case insensitive substring search */
1061       mode = KEYDB_SEARCH_MODE_SUBSTR;
1062       s++;
1063       desc->u.name = s;
1064       break;
1065
1066     case '+':  /* compare individual words */
1067       mode = KEYDB_SEARCH_MODE_WORDS;
1068       s++;
1069       desc->u.name = s;
1070       break;
1071
1072     case '/': /* subject's DN */
1073       s++;
1074       if (!*s || spacep (s))
1075         return 0; /* no DN or prefixed with a space */
1076       desc->u.name = s;
1077       mode = KEYDB_SEARCH_MODE_SUBJECT;
1078       break;
1079
1080     case '#':
1081       { 
1082         const char *si;
1083         
1084         s++;
1085         if ( *s == '/')
1086           { /* "#/" indicates an issuer's DN */
1087             s++;
1088             if (!*s || spacep (s))
1089               return 0; /* no DN or prefixed with a space */
1090             desc->u.name = s;
1091             mode = KEYDB_SEARCH_MODE_ISSUER;
1092           }
1093         else 
1094           { /* serialnumber + optional issuer ID */
1095             for (si=s; *si && *si != '/'; si++)
1096               {
1097                 if (!strchr("01234567890abcdefABCDEF", *si))
1098                   return 0; /* invalid digit in serial number*/
1099               }
1100             desc->sn = (const unsigned char*)s;
1101             desc->snlen = -1;
1102             if (!*si)
1103               mode = KEYDB_SEARCH_MODE_SN;
1104             else
1105               {
1106                 s = si+1;
1107                 if (!*s || spacep (s))
1108                   return 0; /* no DN or prefixed with a space */
1109                 desc->u.name = s;
1110                 mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1111               }
1112           }
1113       }
1114       break;
1115
1116     case ':': /*Unified fingerprint */
1117       {  
1118         const char *se, *si;
1119         int i;
1120         
1121         se = strchr (++s,':');
1122         if (!se)
1123           return 0;
1124         for (i=0,si=s; si < se; si++, i++ )
1125           {
1126             if (!strchr("01234567890abcdefABCDEF", *si))
1127               return 0; /* invalid digit */
1128           }
1129         if (i != 32 && i != 40)
1130           return 0; /* invalid length of fpr*/
1131         for (i=0,si=s; si < se; i++, si +=2) 
1132           desc->u.fpr[i] = hextobyte(si);
1133         for (; i < 20; i++)
1134           desc->u.fpr[i]= 0;
1135         s = se + 1;
1136         mode = KEYDB_SEARCH_MODE_FPR;
1137       } 
1138       break;
1139            
1140     default:
1141       if (s[0] == '0' && s[1] == 'x')
1142         {
1143           hexprefix = 1;
1144           s += 2;
1145         }
1146
1147       hexlength = strspn(s, "0123456789abcdefABCDEF");
1148       if (hexlength >= 8 && s[hexlength] =='!')
1149         {
1150           *force_exact = 1;
1151           hexlength++; /* just for the following check */
1152         }
1153       
1154       /* check if a hexadecimal number is terminated by EOS or blank */
1155       if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
1156         {
1157           if (hexprefix) /* a "0x" prefix without correct */
1158             return 0;    /* termination is an error */
1159           /* The first chars looked like a hex number, but really is
1160              not */
1161           hexlength = 0;  
1162         }
1163       
1164       if (*force_exact)
1165         hexlength--; /* remove the bang */
1166
1167       if (hexlength == 8
1168           || (!hexprefix && hexlength == 9 && *s == '0'))
1169         { /* short keyid */
1170           unsigned long kid;
1171           if (hexlength == 9)
1172             s++;
1173           kid = strtoul( s, NULL, 16 );
1174           desc->u.kid[4] = kid >> 24; 
1175           desc->u.kid[5] = kid >> 16; 
1176           desc->u.kid[6] = kid >>  8; 
1177           desc->u.kid[7] = kid; 
1178           mode = KEYDB_SEARCH_MODE_SHORT_KID;
1179         }
1180       else if (hexlength == 16
1181                || (!hexprefix && hexlength == 17 && *s == '0'))
1182         { /* complete keyid */
1183           unsigned long kid0, kid1;
1184           char buf[9];
1185           if (hexlength == 17)
1186             s++;
1187           mem2str(buf, s, 9 );
1188           kid0 = strtoul (buf, NULL, 16);
1189           kid1 = strtoul (s+8, NULL, 16);
1190           desc->u.kid[0] = kid0 >> 24; 
1191           desc->u.kid[1] = kid0 >> 16; 
1192           desc->u.kid[2] = kid0 >>  8; 
1193           desc->u.kid[3] = kid0; 
1194           desc->u.kid[4] = kid1 >> 24; 
1195           desc->u.kid[5] = kid1 >> 16; 
1196           desc->u.kid[6] = kid1 >>  8; 
1197           desc->u.kid[7] = kid1; 
1198           mode = KEYDB_SEARCH_MODE_LONG_KID;
1199         }
1200       else if (hexlength == 32
1201                || (!hexprefix && hexlength == 33 && *s == '0'))
1202         { /* md5 fingerprint */
1203           int i;
1204           if (hexlength == 33)
1205             s++;
1206           memset(desc->u.fpr+16, 0, 4); 
1207           for (i=0; i < 16; i++, s+=2) 
1208             {
1209               int c = hextobyte(s);
1210               if (c == -1)
1211                 return 0;
1212               desc->u.fpr[i] = c;
1213             }
1214           mode = KEYDB_SEARCH_MODE_FPR16;
1215         }
1216       else if (hexlength == 40
1217                || (!hexprefix && hexlength == 41 && *s == '0'))
1218         { /* sha1/rmd160 fingerprint */
1219           int i;
1220           if (hexlength == 41)
1221             s++;
1222           for (i=0; i < 20; i++, s+=2) 
1223             {
1224               int c = hextobyte(s);
1225               if (c == -1)
1226                 return 0;
1227               desc->u.fpr[i] = c;
1228             }
1229           mode = KEYDB_SEARCH_MODE_FPR20;
1230         }
1231       else if (!hexprefix)
1232         { 
1233           /* The fingerprint in an X.509 listing is often delimited by
1234              colons, so we try to single this case out. */
1235           mode = 0;
1236           hexlength = strspn (s, ":0123456789abcdefABCDEF");
1237           if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
1238             {
1239               int i;
1240
1241               for (i=0; i < 20; i++, s += 3) 
1242                 {
1243                   int c = hextobyte(s);
1244                   if (c == -1 || (i < 19 && s[2] != ':'))
1245                     break;
1246                   desc->u.fpr[i] = c;
1247                 }
1248               if (i == 20)
1249                 mode = KEYDB_SEARCH_MODE_FPR20;
1250             }
1251           if (!mode) /* default is substring search */
1252             { 
1253               *force_exact = 0;
1254               desc->u.name = s;
1255               mode = KEYDB_SEARCH_MODE_SUBSTR; 
1256             }
1257         }
1258       else
1259         { /* hex number with a prefix but a wrong length */
1260           return 0;
1261         }
1262     }
1263   
1264   desc->mode = mode;
1265   return mode;
1266 }
1267
1268
1269 int
1270 keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
1271 {
1272   int dummy;
1273   KEYDB_SEARCH_DESC dummy_desc;
1274
1275   if (!desc)
1276     desc = &dummy_desc;
1277
1278   if (!classify_user_id (name, desc, &dummy))
1279     return gpg_error (GPG_ERR_INV_NAME);
1280   return 0;
1281 }
1282
1283 \f
1284 /* Store the certificate in the key DB but make sure that it does not
1285    already exists.  We do this simply by comparing the fingerprint.
1286    If EXISTED is not NULL it will be set to true if the certificate
1287    was already in the DB. */
1288 int
1289 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1290 {
1291   KEYDB_HANDLE kh;
1292   int rc;
1293   unsigned char fpr[20];
1294
1295   if (existed)
1296     *existed = 0;
1297
1298   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1299     {
1300       log_error (_("failed to get the fingerprint\n"));
1301       return gpg_error (GPG_ERR_GENERAL);
1302     }
1303
1304   kh = keydb_new (0);
1305   if (!kh)
1306     {
1307       log_error (_("failed to allocate keyDB handle\n"));
1308       return gpg_error (GPG_ERR_ENOMEM);;
1309     }
1310
1311   if (ephemeral)
1312     keydb_set_ephemeral (kh, 1);
1313   
1314   rc = lock_all (kh);
1315   if (rc)
1316     return rc;
1317
1318   rc = keydb_search_fpr (kh, fpr);
1319   if (rc != -1)
1320     {
1321       keydb_release (kh);
1322       if (!rc)
1323         {
1324           if (existed)
1325             *existed = 1;
1326           return 0; /* okay */
1327         }
1328       log_error (_("problem looking for existing certificate: %s\n"),
1329                  gpg_strerror (rc));
1330       return rc;
1331     }
1332
1333   rc = keydb_locate_writable (kh, 0);
1334   if (rc)
1335     {
1336       log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1337       keydb_release (kh);
1338       return rc;
1339     }
1340
1341   rc = keydb_insert_cert (kh, cert);
1342   if (rc)
1343     {
1344       log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1345       keydb_release (kh);
1346       return rc;
1347     }
1348   keydb_release (kh);               
1349   return 0;
1350 }
1351
1352
1353 /* This is basically keydb_set_flags but it implements a complete
1354    transaction by locating the certificate in the DB and updating the
1355    flags. */
1356 gpg_error_t
1357 keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
1358 {
1359   KEYDB_HANDLE kh;
1360   gpg_error_t err;
1361   unsigned char fpr[20];
1362   unsigned int old_value;
1363
1364   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1365     {
1366       log_error (_("failed to get the fingerprint\n"));
1367       return gpg_error (GPG_ERR_GENERAL);
1368     }
1369
1370   kh = keydb_new (0);
1371   if (!kh)
1372     {
1373       log_error (_("failed to allocate keyDB handle\n"));
1374       return gpg_error (GPG_ERR_ENOMEM);;
1375     }
1376
1377   err = keydb_lock (kh);
1378   if (err)
1379     {
1380       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1381       keydb_release (kh);
1382       return err;
1383     }
1384
1385   err = keydb_search_fpr (kh, fpr);
1386   if (err)
1387     {
1388       log_error (_("problem re-searching certificate: %s\n"),
1389                  gpg_strerror (err));
1390       keydb_release (kh);
1391       return err;
1392     }
1393
1394   err = keydb_get_flags (kh, which, idx, &old_value);
1395   if (err)
1396     {
1397       log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1398       keydb_release (kh);
1399       return err;
1400     }
1401   if (value != old_value)
1402     {
1403       err = keydb_set_flags (kh, which, idx, value);
1404       if (err)
1405         {
1406           log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1407           keydb_release (kh);
1408           return err;
1409         }
1410     }
1411   keydb_release (kh);               
1412   return 0;
1413 }
1414
1415
1416 /* Reset all the certificate flags we have stored with the certificates
1417    for performance reasons. */
1418 void
1419 keydb_clear_some_cert_flags (ctrl_t ctrl, STRLIST names)
1420 {
1421   gpg_error_t err;
1422   KEYDB_HANDLE hd = NULL;
1423   KEYDB_SEARCH_DESC *desc = NULL;
1424   int ndesc;
1425   STRLIST sl;
1426   int rc=0;
1427   unsigned int old_value, value;
1428   
1429   hd = keydb_new (0);
1430   if (!hd)
1431     {
1432       log_error ("keydb_new failed\n");
1433       goto leave;
1434     }
1435
1436   if (!names)
1437     ndesc = 1;
1438   else
1439     {
1440       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1441         ;
1442     }
1443
1444   desc = xtrycalloc (ndesc, sizeof *desc);
1445   if (!ndesc)
1446     {
1447       log_error ("allocating memory failed: %s\n",
1448                  gpg_strerror (OUT_OF_CORE (errno)));
1449       goto leave;
1450     }
1451
1452   if (!names)
1453     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1454   else 
1455     {
1456       for (ndesc=0, sl=names; sl; sl = sl->next) 
1457         {
1458           rc = keydb_classify_name (sl->d, desc+ndesc);
1459           if (rc)
1460             {
1461               log_error ("key `%s' not found: %s\n",
1462                          sl->d, gpg_strerror (rc));
1463               rc = 0;
1464             }
1465           else
1466             ndesc++;
1467         }
1468     }
1469
1470   err = keydb_lock (hd);
1471   if (err)
1472     {
1473       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1474       goto leave;
1475     }
1476
1477   while (!(rc = keydb_search (hd, desc, ndesc)))
1478     {
1479       if (!names) 
1480         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1481
1482       err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1483       if (err)
1484         {
1485           log_error (_("error getting stored flags: %s\n"),
1486                      gpg_strerror (err));
1487           goto leave;
1488         }
1489  
1490       value = (old_value & ~VALIDITY_REVOKED);
1491       if (value != old_value)
1492         {
1493           err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1494           if (err)
1495             {
1496               log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1497               goto leave;
1498             }
1499         }
1500     }
1501   if (rc && rc != -1)
1502     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1503   
1504  leave:
1505   xfree (desc);
1506   keydb_release (hd);
1507 }
1508
1509