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