sm: Create homedir and lock empty keybox creation.
[gnupg.git] / sm / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
3  * Copyright (C) 2014 g10 Code GmbH
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
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_t 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 saved_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 static void
73 try_make_homedir (const char *fname)
74 {
75   const char *defhome = standard_homedir ();
76
77   /* Create the directory only if the supplied directory name is the
78      same as the default one.  This way we avoid to create arbitrary
79      directories when a non-default home directory is used.  To cope
80      with HOME, we do compare only the suffix if we see that the
81      default homedir does start with a tilde.  */
82   if ( opt.dry_run || opt.no_homedir_creation )
83     return;
84
85   if (
86 #ifdef HAVE_W32_SYSTEM
87       ( !compare_filenames (fname, defhome) )
88 #else
89       ( *defhome == '~'
90         && (strlen(fname) >= strlen (defhome+1)
91             && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
92       || (*defhome != '~'  && !compare_filenames( fname, defhome ) )
93 #endif
94       )
95     {
96       if (gnupg_mkdir (fname, "-rwx"))
97         log_info (_("can't create directory '%s': %s\n"),
98                   fname, strerror(errno) );
99       else if (!opt.quiet )
100         log_info (_("directory '%s' created\n"), fname);
101     }
102 }
103
104
105 /* Handle the creation of a keybox if it does not yet exist.  Take
106    into acount that other processes might have the keybox already
107    locked.  This lock check does not work if the directory itself is
108    not yet available.  If R_CREATED is not NULL it will be set to true
109    if the function created a new keybox.  */
110 static int
111 maybe_create_keybox (char *filename, int force, int *r_created)
112 {
113   dotlock_t lockhd = NULL;
114   FILE *fp;
115   int rc;
116   mode_t oldmask;
117   char *last_slash_in_filename;
118   int save_slash;
119
120   if (r_created)
121     *r_created = 0;
122
123   /* A quick test whether the filename already exists. */
124   if (!access (filename, F_OK))
125     return 0;
126
127   /* If we don't want to create a new file at all, there is no need to
128      go any further - bail out right here.  */
129   if (!force)
130     return gpg_error (GPG_ERR_ENOENT);
131
132   /* First of all we try to create the home directory.  Note, that we
133      don't do any locking here because any sane application of gpg
134      would create the home directory by itself and not rely on gpg's
135      tricky auto-creation which is anyway only done for some home
136      directory name patterns. */
137   last_slash_in_filename = strrchr (filename, DIRSEP_C);
138 #if HAVE_W32_SYSTEM
139   {
140     /* Windows may either have a slash or a backslash.  Take care of it.  */
141     char *p = strrchr (filename, '/');
142     if (!last_slash_in_filename || p > last_slash_in_filename)
143       last_slash_in_filename = p;
144   }
145 #endif /*HAVE_W32_SYSTEM*/
146   if (!last_slash_in_filename)
147     return gpg_error (GPG_ERR_ENOENT);  /* No slash at all - should
148                                            not happen though.  */
149   save_slash = *last_slash_in_filename;
150   *last_slash_in_filename = 0;
151   if (access(filename, F_OK))
152     {
153       static int tried;
154
155       if (!tried)
156         {
157           tried = 1;
158           try_make_homedir (filename);
159         }
160       if (access (filename, F_OK))
161         {
162           rc = gpg_error_from_syserror ();
163           *last_slash_in_filename = save_slash;
164           goto leave;
165         }
166     }
167   *last_slash_in_filename = save_slash;
168
169   /* To avoid races with other instances of gpg trying to create or
170      update the keybox (it is removed during an update for a short
171      time), we do the next stuff in a locked state. */
172   lockhd = dotlock_create (filename, 0);
173   if (!lockhd)
174     {
175       /* A reason for this to fail is that the directory is not
176          writable. However, this whole locking stuff does not make
177          sense if this is the case. An empty non-writable directory
178          with no keyring is not really useful at all. */
179       if (opt.verbose)
180         log_info ("can't allocate lock for '%s'\n", filename );
181
182       if (!force)
183         return gpg_error (GPG_ERR_ENOENT);
184       else
185         return gpg_error (GPG_ERR_GENERAL);
186     }
187
188   if ( dotlock_take (lockhd, -1) )
189     {
190       /* This is something bad.  Probably a stale lockfile.  */
191       log_info ("can't lock '%s'\n", filename);
192       rc = gpg_error (GPG_ERR_GENERAL);
193       goto leave;
194     }
195
196   /* Now the real test while we are locked. */
197   if (!access(filename, F_OK))
198     {
199       rc = 0;  /* Okay, we may access the file now.  */
200       goto leave;
201     }
202
203   /* The file does not yet exist, create it now. */
204   oldmask = umask (077);
205   fp = fopen (filename, "w");
206   if (!fp)
207     {
208       rc = gpg_error_from_syserror ();
209       umask (oldmask);
210       log_error (_("error creating keybox '%s': %s\n"),
211                  filename, gpg_strerror (rc));
212       goto leave;
213     }
214   umask (oldmask);
215
216   if (!opt.quiet)
217     log_info (_("keybox '%s' created\n"), filename);
218   if (r_created)
219     *r_created = 1;
220
221   fclose (fp);
222   rc = 0;
223
224  leave:
225   if (lockhd)
226     {
227       dotlock_release (lockhd);
228       dotlock_destroy (lockhd);
229     }
230   return rc;
231 }
232
233
234 /*
235  * Register a resource (which currently may only be a keybox file).
236  * The first keybox which is added by this function is created if it
237  * does not exist.  If AUTO_CREATED is not NULL it will be set to true
238  * if the function has created a new keybox.
239  */
240 int
241 keydb_add_resource (const char *url, int force, int secret, int *auto_created)
242 {
243   static int any_secret, any_public;
244   const char *resname = url;
245   char *filename = NULL;
246   int rc = 0;
247   KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
248
249   if (auto_created)
250     *auto_created = 0;
251
252   /* Do we have an URL?
253      gnupg-kbx:filename := this is a plain keybox
254      filename := See what is is, but create as plain keybox.
255   */
256   if (strlen (resname) > 10)
257     {
258       if (!strncmp (resname, "gnupg-kbx:", 10) )
259         {
260           rt = KEYDB_RESOURCE_TYPE_KEYBOX;
261           resname += 10;
262         }
263 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
264       else if (strchr (resname, ':'))
265         {
266           log_error ("invalid key resource URL '%s'\n", url );
267           rc = gpg_error (GPG_ERR_GENERAL);
268           goto leave;
269         }
270 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
271     }
272
273   if (*resname != DIRSEP_C )
274     { /* do tilde expansion etc */
275       if (strchr(resname, DIRSEP_C) )
276         filename = make_filename (resname, NULL);
277       else
278         filename = make_filename (opt.homedir, resname, NULL);
279     }
280   else
281     filename = xstrdup (resname);
282
283   if (!force)
284     force = secret? !any_secret : !any_public;
285
286   /* see whether we can determine the filetype */
287   if (rt == KEYDB_RESOURCE_TYPE_NONE)
288     {
289       FILE *fp = fopen( filename, "rb" );
290
291       if (fp)
292         {
293           u32 magic;
294
295           /* FIXME: check for the keybox magic */
296           if (fread (&magic, 4, 1, fp) == 1 )
297             {
298               if (magic == 0x13579ace || magic == 0xce9a5713)
299                 ; /* GDBM magic - no more support */
300               else
301                 rt = KEYDB_RESOURCE_TYPE_KEYBOX;
302             }
303           else /* maybe empty: assume keybox */
304             rt = KEYDB_RESOURCE_TYPE_KEYBOX;
305           fclose (fp);
306         }
307       else /* no file yet: create keybox */
308         rt = KEYDB_RESOURCE_TYPE_KEYBOX;
309     }
310
311   switch (rt)
312     {
313     case KEYDB_RESOURCE_TYPE_NONE:
314       log_error ("unknown type of key resource '%s'\n", url );
315       rc = gpg_error (GPG_ERR_GENERAL);
316       goto leave;
317
318     case KEYDB_RESOURCE_TYPE_KEYBOX:
319       rc = maybe_create_keybox (filename, force, auto_created);
320       if (rc)
321         goto leave;
322       /* Now register the file */
323       {
324         void *token = keybox_register_file (filename, secret);
325         if (!token)
326           ; /* already registered - ignore it */
327         else if (used_resources >= MAX_KEYDB_RESOURCES)
328           rc = gpg_error (GPG_ERR_RESOURCE_LIMIT);
329         else
330           {
331             all_resources[used_resources].type = rt;
332             all_resources[used_resources].u.kr = NULL; /* Not used here */
333             all_resources[used_resources].token = token;
334             all_resources[used_resources].secret = secret;
335
336             all_resources[used_resources].lockhandle
337               = dotlock_create (filename, 0);
338             if (!all_resources[used_resources].lockhandle)
339               log_fatal ( _("can't create lock for '%s'\n"), filename);
340
341             /* Do a compress run if needed and the file is not locked. */
342             if (!dotlock_take (all_resources[used_resources].lockhandle, 0))
343               {
344                 KEYBOX_HANDLE kbxhd = keybox_new (token, secret);
345
346                 if (kbxhd)
347                   {
348                     keybox_compress (kbxhd);
349                     keybox_release (kbxhd);
350                   }
351                 dotlock_release (all_resources[used_resources].lockhandle);
352               }
353
354             used_resources++;
355           }
356       }
357       break;
358
359     default:
360       log_error ("resource type of '%s' not supported\n", url);
361       rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
362       goto leave;
363     }
364
365   /* fixme: check directory permissions and print a warning */
366
367  leave:
368   if (rc)
369     log_error ("keyblock resource '%s': %s\n", filename, gpg_strerror(rc));
370   else if (secret)
371     any_secret = 1;
372   else
373     any_public = 1;
374   xfree (filename);
375   return rc;
376 }
377
378
379 KEYDB_HANDLE
380 keydb_new (int secret)
381 {
382   KEYDB_HANDLE hd;
383   int i, j;
384
385   hd = xcalloc (1, sizeof *hd);
386   hd->found = -1;
387   hd->saved_found = -1;
388
389   assert (used_resources <= MAX_KEYDB_RESOURCES);
390   for (i=j=0; i < used_resources; i++)
391     {
392       if (!all_resources[i].secret != !secret)
393         continue;
394       switch (all_resources[i].type)
395         {
396         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
397           break;
398         case KEYDB_RESOURCE_TYPE_KEYBOX:
399           hd->active[j].type   = all_resources[i].type;
400           hd->active[j].token  = all_resources[i].token;
401           hd->active[j].secret = all_resources[i].secret;
402           hd->active[j].lockhandle = all_resources[i].lockhandle;
403           hd->active[j].u.kr = keybox_new (all_resources[i].token, secret);
404           if (!hd->active[j].u.kr)
405             {
406               xfree (hd);
407               return NULL; /* fixme: release all previously allocated handles*/
408             }
409           j++;
410           break;
411         }
412     }
413   hd->used = j;
414
415   active_handles++;
416   return hd;
417 }
418
419 void
420 keydb_release (KEYDB_HANDLE hd)
421 {
422   int i;
423
424   if (!hd)
425     return;
426   assert (active_handles > 0);
427   active_handles--;
428
429   unlock_all (hd);
430   for (i=0; i < hd->used; i++)
431     {
432       switch (hd->active[i].type)
433         {
434         case KEYDB_RESOURCE_TYPE_NONE:
435           break;
436         case KEYDB_RESOURCE_TYPE_KEYBOX:
437           keybox_release (hd->active[i].u.kr);
438           break;
439         }
440     }
441
442     xfree (hd);
443 }
444
445
446 /* Return the name of the current resource.  This is function first
447    looks for the last found found, then for the current search
448    position, and last returns the first available resource.  The
449    returned string is only valid as long as the handle exists.  This
450    function does only return NULL if no handle is specified, in all
451    other error cases an empty string is returned.  */
452 const char *
453 keydb_get_resource_name (KEYDB_HANDLE hd)
454 {
455   int idx;
456   const char *s = NULL;
457
458   if (!hd)
459     return NULL;
460
461   if ( hd->found >= 0 && hd->found < hd->used)
462     idx = hd->found;
463   else if ( hd->current >= 0 && hd->current < hd->used)
464     idx = hd->current;
465   else
466     idx = 0;
467
468   switch (hd->active[idx].type)
469     {
470     case KEYDB_RESOURCE_TYPE_NONE:
471       s = NULL;
472       break;
473     case KEYDB_RESOURCE_TYPE_KEYBOX:
474       s = keybox_get_resource_name (hd->active[idx].u.kr);
475       break;
476     }
477
478   return s? s: "";
479 }
480
481 /* Switch the handle into ephemeral mode and return the orginal value. */
482 int
483 keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
484 {
485   int i;
486
487   if (!hd)
488     return 0;
489
490   yes = !!yes;
491   if (hd->is_ephemeral != yes)
492     {
493       for (i=0; i < hd->used; i++)
494         {
495           switch (hd->active[i].type)
496             {
497             case KEYDB_RESOURCE_TYPE_NONE:
498               break;
499             case KEYDB_RESOURCE_TYPE_KEYBOX:
500               keybox_set_ephemeral (hd->active[i].u.kr, yes);
501               break;
502             }
503         }
504     }
505
506   i = hd->is_ephemeral;
507   hd->is_ephemeral = yes;
508   return i;
509 }
510
511
512 /* If the keyring has not yet been locked, lock it now.  This
513    operation is required before any update operation; it is optional
514    for an insert operation.  The lock is released with
515    keydb_released. */
516 gpg_error_t
517 keydb_lock (KEYDB_HANDLE hd)
518 {
519   if (!hd)
520     return gpg_error (GPG_ERR_INV_HANDLE);
521   if (hd->locked)
522     return 0; /* Already locked. */
523   return lock_all (hd);
524 }
525
526
527 \f
528 static int
529 lock_all (KEYDB_HANDLE hd)
530 {
531   int i, rc = 0;
532
533   /* Fixme: This locking scheme may lead to deadlock if the resources
534      are not added in the same order by all processes.  We are
535      currently only allowing one resource so it is not a problem. */
536   for (i=0; i < hd->used; i++)
537     {
538       switch (hd->active[i].type)
539         {
540         case KEYDB_RESOURCE_TYPE_NONE:
541           break;
542         case KEYDB_RESOURCE_TYPE_KEYBOX:
543           if (hd->active[i].lockhandle)
544             rc = dotlock_take (hd->active[i].lockhandle, -1);
545           break;
546         }
547       if (rc)
548         break;
549     }
550
551     if (rc)
552       {
553         /* revert the already set locks */
554         for (i--; i >= 0; i--)
555           {
556             switch (hd->active[i].type)
557               {
558               case KEYDB_RESOURCE_TYPE_NONE:
559                 break;
560               case KEYDB_RESOURCE_TYPE_KEYBOX:
561                 if (hd->active[i].lockhandle)
562                   dotlock_release (hd->active[i].lockhandle);
563                 break;
564               }
565           }
566       }
567     else
568       hd->locked = 1;
569
570     /* make_dotlock () does not yet guarantee that errno is set, thus
571        we can't rely on the error reason and will simply use
572        EACCES. */
573     return rc? gpg_error (GPG_ERR_EACCES) : 0;
574 }
575
576 static void
577 unlock_all (KEYDB_HANDLE hd)
578 {
579   int i;
580
581   if (!hd->locked)
582     return;
583
584   for (i=hd->used-1; i >= 0; i--)
585     {
586       switch (hd->active[i].type)
587         {
588         case KEYDB_RESOURCE_TYPE_NONE:
589           break;
590         case KEYDB_RESOURCE_TYPE_KEYBOX:
591           if (hd->active[i].lockhandle)
592             dotlock_release (hd->active[i].lockhandle);
593           break;
594         }
595     }
596   hd->locked = 0;
597 }
598
599
600 \f
601 /* Push the last found state if any.  */
602 void
603 keydb_push_found_state (KEYDB_HANDLE hd)
604 {
605   if (!hd)
606     return;
607
608   if (hd->found < 0 || hd->found >= hd->used)
609     {
610       hd->saved_found = -1;
611       return;
612     }
613
614   switch (hd->active[hd->found].type)
615     {
616     case KEYDB_RESOURCE_TYPE_NONE:
617       break;
618     case KEYDB_RESOURCE_TYPE_KEYBOX:
619       keybox_push_found_state (hd->active[hd->found].u.kr);
620       break;
621     }
622
623   hd->saved_found = hd->found;
624   hd->found = -1;
625 }
626
627
628 /* Pop the last found state.  */
629 void
630 keydb_pop_found_state (KEYDB_HANDLE hd)
631 {
632   if (!hd)
633     return;
634
635   hd->found = hd->saved_found;
636   hd->saved_found = -1;
637   if (hd->found < 0 || hd->found >= hd->used)
638     return;
639
640   switch (hd->active[hd->found].type)
641     {
642     case KEYDB_RESOURCE_TYPE_NONE:
643       break;
644     case KEYDB_RESOURCE_TYPE_KEYBOX:
645       keybox_pop_found_state (hd->active[hd->found].u.kr);
646       break;
647     }
648 }
649
650
651 \f
652 /*
653   Return the last found object.  Caller must free it.  The returned
654   keyblock has the kbode flag bit 0 set for the node with the public
655   key used to locate the keyblock or flag bit 1 set for the user ID
656   node.  */
657 int
658 keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
659 {
660   int rc = 0;
661
662   if (!hd)
663     return gpg_error (GPG_ERR_INV_VALUE);
664
665   if ( hd->found < 0 || hd->found >= hd->used)
666     return -1; /* nothing found */
667
668   switch (hd->active[hd->found].type)
669     {
670     case KEYDB_RESOURCE_TYPE_NONE:
671       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
672       break;
673     case KEYDB_RESOURCE_TYPE_KEYBOX:
674       rc = keybox_get_cert (hd->active[hd->found].u.kr, r_cert);
675       break;
676     }
677
678   return rc;
679 }
680
681 /* Return a flag of the last found object. WHICH is the flag requested;
682    it should be one of the KEYBOX_FLAG_ values.  If the operation is
683    successful, the flag value will be stored at the address given by
684    VALUE.  Return 0 on success or an error code. */
685 gpg_error_t
686 keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
687 {
688   int err = 0;
689
690   if (!hd)
691     return gpg_error (GPG_ERR_INV_VALUE);
692
693   if ( hd->found < 0 || hd->found >= hd->used)
694     return gpg_error (GPG_ERR_NOTHING_FOUND);
695
696   switch (hd->active[hd->found].type)
697     {
698     case KEYDB_RESOURCE_TYPE_NONE:
699       err = gpg_error (GPG_ERR_GENERAL); /* oops */
700       break;
701     case KEYDB_RESOURCE_TYPE_KEYBOX:
702       err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
703       break;
704     }
705
706   return err;
707 }
708
709 /* Set a flag of the last found object. WHICH is the flag to be set; it
710    should be one of the KEYBOX_FLAG_ values.  If the operation is
711    successful, the flag value will be stored in the keybox.  Note,
712    that some flag values can't be updated and thus may return an
713    error, some other flag values may be masked out before an update.
714    Returns 0 on success or an error code. */
715 gpg_error_t
716 keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
717 {
718   int err = 0;
719
720   if (!hd)
721     return gpg_error (GPG_ERR_INV_VALUE);
722
723   if ( hd->found < 0 || hd->found >= hd->used)
724     return gpg_error (GPG_ERR_NOTHING_FOUND);
725
726   if (!hd->locked)
727     return gpg_error (GPG_ERR_NOT_LOCKED);
728
729   switch (hd->active[hd->found].type)
730     {
731     case KEYDB_RESOURCE_TYPE_NONE:
732       err = gpg_error (GPG_ERR_GENERAL); /* oops */
733       break;
734     case KEYDB_RESOURCE_TYPE_KEYBOX:
735       err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
736       break;
737     }
738
739   return err;
740 }
741
742 /*
743  * Insert a new Certificate into one of the resources.
744  */
745 int
746 keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
747 {
748   int rc = -1;
749   int idx;
750   unsigned char digest[20];
751
752   if (!hd)
753     return gpg_error (GPG_ERR_INV_VALUE);
754
755   if (opt.dry_run)
756     return 0;
757
758   if ( hd->found >= 0 && hd->found < hd->used)
759     idx = hd->found;
760   else if ( hd->current >= 0 && hd->current < hd->used)
761     idx = hd->current;
762   else
763     return gpg_error (GPG_ERR_GENERAL);
764
765   if (!hd->locked)
766     return gpg_error (GPG_ERR_NOT_LOCKED);
767
768   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
769
770   switch (hd->active[idx].type)
771     {
772     case KEYDB_RESOURCE_TYPE_NONE:
773       rc = gpg_error (GPG_ERR_GENERAL);
774       break;
775     case KEYDB_RESOURCE_TYPE_KEYBOX:
776       rc = keybox_insert_cert (hd->active[idx].u.kr, cert, digest);
777       break;
778     }
779
780   unlock_all (hd);
781   return rc;
782 }
783
784
785
786 /* Update the current keyblock with KB.  */
787 int
788 keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
789 {
790   int rc = 0;
791   unsigned char digest[20];
792
793   if (!hd)
794     return gpg_error (GPG_ERR_INV_VALUE);
795
796   if ( hd->found < 0 || hd->found >= hd->used)
797     return -1; /* nothing found */
798
799   if (opt.dry_run)
800     return 0;
801
802   rc = lock_all (hd);
803   if (rc)
804     return rc;
805
806   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
807
808   switch (hd->active[hd->found].type)
809     {
810     case KEYDB_RESOURCE_TYPE_NONE:
811       rc = gpg_error (GPG_ERR_GENERAL); /* oops */
812       break;
813     case KEYDB_RESOURCE_TYPE_KEYBOX:
814       rc = keybox_update_cert (hd->active[hd->found].u.kr, cert, digest);
815       break;
816     }
817
818   unlock_all (hd);
819   return rc;
820 }
821
822
823 /*
824  * The current keyblock or cert will be deleted.
825  */
826 int
827 keydb_delete (KEYDB_HANDLE hd, int unlock)
828 {
829   int rc = -1;
830
831   if (!hd)
832     return gpg_error (GPG_ERR_INV_VALUE);
833
834   if ( hd->found < 0 || hd->found >= hd->used)
835     return -1; /* nothing found */
836
837   if( opt.dry_run )
838     return 0;
839
840   if (!hd->locked)
841     return gpg_error (GPG_ERR_NOT_LOCKED);
842
843   switch (hd->active[hd->found].type)
844     {
845     case KEYDB_RESOURCE_TYPE_NONE:
846       rc = gpg_error (GPG_ERR_GENERAL);
847       break;
848     case KEYDB_RESOURCE_TYPE_KEYBOX:
849       rc = keybox_delete (hd->active[hd->found].u.kr);
850       break;
851     }
852
853   if (unlock)
854     unlock_all (hd);
855   return rc;
856 }
857
858
859 \f
860 /*
861  * Locate the default writable key resource, so that the next
862  * operation (which is only relevant for inserts) will be done on this
863  * resource.
864  */
865 int
866 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
867 {
868   int rc;
869
870   (void)reserved;
871
872   if (!hd)
873     return gpg_error (GPG_ERR_INV_VALUE);
874
875   rc = keydb_search_reset (hd); /* this does reset hd->current */
876   if (rc)
877     return rc;
878
879   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
880     {
881       switch (hd->active[hd->current].type)
882         {
883         case KEYDB_RESOURCE_TYPE_NONE:
884           BUG();
885           break;
886         case KEYDB_RESOURCE_TYPE_KEYBOX:
887           if (keybox_is_writable (hd->active[hd->current].token))
888             return 0; /* found (hd->current is set to it) */
889           break;
890         }
891     }
892
893   return -1;
894 }
895
896 /*
897  * Rebuild the caches of all key resources.
898  */
899 void
900 keydb_rebuild_caches (void)
901 {
902   int i;
903
904   for (i=0; i < used_resources; i++)
905     {
906       if (all_resources[i].secret)
907         continue;
908       switch (all_resources[i].type)
909         {
910         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
911           break;
912         case KEYDB_RESOURCE_TYPE_KEYBOX:
913 /*            rc = keybox_rebuild_cache (all_resources[i].token); */
914 /*            if (rc) */
915 /*              log_error (_("failed to rebuild keybox cache: %s\n"), */
916 /*                         g10_errstr (rc)); */
917           break;
918         }
919     }
920 }
921
922
923
924 /*
925  * Start the next search on this handle right at the beginning
926  */
927 int
928 keydb_search_reset (KEYDB_HANDLE hd)
929 {
930   int i, rc = 0;
931
932   if (!hd)
933     return gpg_error (GPG_ERR_INV_VALUE);
934
935   hd->current = 0;
936   hd->found = -1;
937   /* and reset all resources */
938   for (i=0; !rc && i < hd->used; i++)
939     {
940       switch (hd->active[i].type)
941         {
942         case KEYDB_RESOURCE_TYPE_NONE:
943           break;
944         case KEYDB_RESOURCE_TYPE_KEYBOX:
945           rc = keybox_search_reset (hd->active[i].u.kr);
946           break;
947         }
948     }
949   return rc; /* fixme: we need to map error codes or share them with
950                 all modules*/
951 }
952
953 /*
954  * Search through all keydb resources, starting at the current position,
955  * for a keyblock which contains one of the keys described in the DESC array.
956  */
957 int
958 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
959 {
960   int rc = -1;
961
962   if (!hd)
963     return gpg_error (GPG_ERR_INV_VALUE);
964
965   while (rc == -1 && hd->current >= 0 && hd->current < hd->used)
966     {
967       switch (hd->active[hd->current].type)
968         {
969         case KEYDB_RESOURCE_TYPE_NONE:
970           BUG(); /* we should never see it here */
971           break;
972         case KEYDB_RESOURCE_TYPE_KEYBOX:
973           rc = keybox_search (hd->active[hd->current].u.kr, desc, ndesc, NULL);
974           break;
975         }
976       if (rc == -1) /* EOF -> switch to next resource */
977         hd->current++;
978       else if (!rc)
979         hd->found = hd->current;
980     }
981
982   return rc;
983 }
984
985
986 int
987 keydb_search_first (KEYDB_HANDLE hd)
988 {
989   KEYDB_SEARCH_DESC desc;
990
991   memset (&desc, 0, sizeof desc);
992   desc.mode = KEYDB_SEARCH_MODE_FIRST;
993   return keydb_search (hd, &desc, 1);
994 }
995
996 int
997 keydb_search_next (KEYDB_HANDLE hd)
998 {
999   KEYDB_SEARCH_DESC desc;
1000
1001   memset (&desc, 0, sizeof desc);
1002   desc.mode = KEYDB_SEARCH_MODE_NEXT;
1003   return keydb_search (hd, &desc, 1);
1004 }
1005
1006 int
1007 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
1008 {
1009   KEYDB_SEARCH_DESC desc;
1010
1011   (void)kid;
1012
1013   memset (&desc, 0, sizeof desc);
1014   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
1015   desc.u.kid[0] = kid[0];
1016   desc.u.kid[1] = kid[1];
1017   return keydb_search (hd, &desc, 1);
1018 }
1019
1020 int
1021 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
1022 {
1023   KEYDB_SEARCH_DESC desc;
1024
1025   memset (&desc, 0, sizeof desc);
1026   desc.mode = KEYDB_SEARCH_MODE_FPR;
1027   memcpy (desc.u.fpr, fpr, 20);
1028   return keydb_search (hd, &desc, 1);
1029 }
1030
1031 int
1032 keydb_search_issuer (KEYDB_HANDLE hd, const char *issuer)
1033 {
1034   KEYDB_SEARCH_DESC desc;
1035   int rc;
1036
1037   memset (&desc, 0, sizeof desc);
1038   desc.mode = KEYDB_SEARCH_MODE_ISSUER;
1039   desc.u.name = issuer;
1040   rc = keydb_search (hd, &desc, 1);
1041   return rc;
1042 }
1043
1044 int
1045 keydb_search_issuer_sn (KEYDB_HANDLE hd,
1046                         const char *issuer, ksba_const_sexp_t serial)
1047 {
1048   KEYDB_SEARCH_DESC desc;
1049   int rc;
1050   const unsigned char *s;
1051
1052   memset (&desc, 0, sizeof desc);
1053   desc.mode = KEYDB_SEARCH_MODE_ISSUER_SN;
1054   s = serial;
1055   if (*s !='(')
1056     return gpg_error (GPG_ERR_INV_VALUE);
1057   s++;
1058   for (desc.snlen = 0; digitp (s); s++)
1059     desc.snlen = 10*desc.snlen + atoi_1 (s);
1060   if (*s !=':')
1061     return gpg_error (GPG_ERR_INV_VALUE);
1062   desc.sn = s+1;
1063   desc.u.name = issuer;
1064   rc = keydb_search (hd, &desc, 1);
1065   return rc;
1066 }
1067
1068 int
1069 keydb_search_subject (KEYDB_HANDLE hd, const char *name)
1070 {
1071   KEYDB_SEARCH_DESC desc;
1072   int rc;
1073
1074   memset (&desc, 0, sizeof desc);
1075   desc.mode = KEYDB_SEARCH_MODE_SUBJECT;
1076   desc.u.name = name;
1077   rc = keydb_search (hd, &desc, 1);
1078   return rc;
1079 }
1080
1081
1082 \f
1083 /* Store the certificate in the key DB but make sure that it does not
1084    already exists.  We do this simply by comparing the fingerprint.
1085    If EXISTED is not NULL it will be set to true if the certificate
1086    was already in the DB. */
1087 int
1088 keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
1089 {
1090   KEYDB_HANDLE kh;
1091   int rc;
1092   unsigned char fpr[20];
1093
1094   if (existed)
1095     *existed = 0;
1096
1097   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1098     {
1099       log_error (_("failed to get the fingerprint\n"));
1100       return gpg_error (GPG_ERR_GENERAL);
1101     }
1102
1103   kh = keydb_new (0);
1104   if (!kh)
1105     {
1106       log_error (_("failed to allocate keyDB handle\n"));
1107       return gpg_error (GPG_ERR_ENOMEM);;
1108     }
1109
1110   if (ephemeral)
1111     keydb_set_ephemeral (kh, 1);
1112
1113   rc = lock_all (kh);
1114   if (rc)
1115     return rc;
1116
1117   rc = keydb_search_fpr (kh, fpr);
1118   if (rc != -1)
1119     {
1120       keydb_release (kh);
1121       if (!rc)
1122         {
1123           if (existed)
1124             *existed = 1;
1125           return 0; /* okay */
1126         }
1127       log_error (_("problem looking for existing certificate: %s\n"),
1128                  gpg_strerror (rc));
1129       return rc;
1130     }
1131
1132   rc = keydb_locate_writable (kh, 0);
1133   if (rc)
1134     {
1135       log_error (_("error finding writable keyDB: %s\n"), gpg_strerror (rc));
1136       keydb_release (kh);
1137       return rc;
1138     }
1139
1140   rc = keydb_insert_cert (kh, cert);
1141   if (rc)
1142     {
1143       log_error (_("error storing certificate: %s\n"), gpg_strerror (rc));
1144       keydb_release (kh);
1145       return rc;
1146     }
1147   keydb_release (kh);
1148   return 0;
1149 }
1150
1151
1152 /* This is basically keydb_set_flags but it implements a complete
1153    transaction by locating the certificate in the DB and updating the
1154    flags. */
1155 gpg_error_t
1156 keydb_set_cert_flags (ksba_cert_t cert, int ephemeral,
1157                       int which, int idx,
1158                       unsigned int mask, unsigned int value)
1159 {
1160   KEYDB_HANDLE kh;
1161   gpg_error_t err;
1162   unsigned char fpr[20];
1163   unsigned int old_value;
1164
1165   if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
1166     {
1167       log_error (_("failed to get the fingerprint\n"));
1168       return gpg_error (GPG_ERR_GENERAL);
1169     }
1170
1171   kh = keydb_new (0);
1172   if (!kh)
1173     {
1174       log_error (_("failed to allocate keyDB handle\n"));
1175       return gpg_error (GPG_ERR_ENOMEM);;
1176     }
1177
1178   if (ephemeral)
1179     keydb_set_ephemeral (kh, 1);
1180
1181   err = keydb_lock (kh);
1182   if (err)
1183     {
1184       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1185       keydb_release (kh);
1186       return err;
1187     }
1188
1189   err = keydb_search_fpr (kh, fpr);
1190   if (err)
1191     {
1192       if (err == -1)
1193         err = gpg_error (GPG_ERR_NOT_FOUND);
1194       else
1195         log_error (_("problem re-searching certificate: %s\n"),
1196                    gpg_strerror (err));
1197       keydb_release (kh);
1198       return err;
1199     }
1200
1201   err = keydb_get_flags (kh, which, idx, &old_value);
1202   if (err)
1203     {
1204       log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
1205       keydb_release (kh);
1206       return err;
1207     }
1208
1209   value = ((old_value & ~mask) | (value & mask));
1210
1211   if (value != old_value)
1212     {
1213       err = keydb_set_flags (kh, which, idx, value);
1214       if (err)
1215         {
1216           log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1217           keydb_release (kh);
1218           return err;
1219         }
1220     }
1221
1222   keydb_release (kh);
1223   return 0;
1224 }
1225
1226
1227 /* Reset all the certificate flags we have stored with the certificates
1228    for performance reasons. */
1229 void
1230 keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
1231 {
1232   gpg_error_t err;
1233   KEYDB_HANDLE hd = NULL;
1234   KEYDB_SEARCH_DESC *desc = NULL;
1235   int ndesc;
1236   strlist_t sl;
1237   int rc=0;
1238   unsigned int old_value, value;
1239
1240   (void)ctrl;
1241
1242   hd = keydb_new (0);
1243   if (!hd)
1244     {
1245       log_error ("keydb_new failed\n");
1246       goto leave;
1247     }
1248
1249   if (!names)
1250     ndesc = 1;
1251   else
1252     {
1253       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1254         ;
1255     }
1256
1257   desc = xtrycalloc (ndesc, sizeof *desc);
1258   if (!ndesc)
1259     {
1260       log_error ("allocating memory failed: %s\n",
1261                  gpg_strerror (out_of_core ()));
1262       goto leave;
1263     }
1264
1265   if (!names)
1266     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1267   else
1268     {
1269       for (ndesc=0, sl=names; sl; sl = sl->next)
1270         {
1271           rc = classify_user_id (sl->d, desc+ndesc, 0);
1272           if (rc)
1273             {
1274               log_error ("key '%s' not found: %s\n",
1275                          sl->d, gpg_strerror (rc));
1276               rc = 0;
1277             }
1278           else
1279             ndesc++;
1280         }
1281     }
1282
1283   err = keydb_lock (hd);
1284   if (err)
1285     {
1286       log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
1287       goto leave;
1288     }
1289
1290   while (!(rc = keydb_search (hd, desc, ndesc)))
1291     {
1292       if (!names)
1293         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1294
1295       err = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &old_value);
1296       if (err)
1297         {
1298           log_error (_("error getting stored flags: %s\n"),
1299                      gpg_strerror (err));
1300           goto leave;
1301         }
1302
1303       value = (old_value & ~VALIDITY_REVOKED);
1304       if (value != old_value)
1305         {
1306           err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
1307           if (err)
1308             {
1309               log_error (_("error storing flags: %s\n"), gpg_strerror (err));
1310               goto leave;
1311             }
1312         }
1313     }
1314   if (rc && rc != -1)
1315     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1316
1317  leave:
1318   xfree (desc);
1319   keydb_release (hd);
1320 }