2006-04-14 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / keydb.c
blobb64f38cbc26fdc7e91925cfbac0e401da58507dd
1 /* keydb.c - key database dispatcher
2 * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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
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>
31 #include "gpg.h"
32 #include "util.h"
33 #include "options.h"
34 #include "main.h" /*try_make_homedir ()*/
35 #include "packet.h"
36 #include "keyring.h"
37 #include "keydb.h"
38 #include "i18n.h"
40 static int active_handles;
42 typedef enum {
43 KEYDB_RESOURCE_TYPE_NONE = 0,
44 KEYDB_RESOURCE_TYPE_KEYRING
45 } KeydbResourceType;
46 #define MAX_KEYDB_RESOURCES 40
48 struct resource_item {
49 KeydbResourceType type;
50 union {
51 KEYRING_HANDLE kr;
52 } u;
53 void *token;
54 int secret;
57 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
58 static int used_resources;
59 static void *primary_keyring=NULL;
61 struct keydb_handle {
62 int locked;
63 int found;
64 int current;
65 int used; /* items in active */
66 struct resource_item active[MAX_KEYDB_RESOURCES];
70 static int lock_all (KEYDB_HANDLE hd);
71 static void unlock_all (KEYDB_HANDLE hd);
75 * Register a resource (which currently may only be a keyring file).
76 * The first keyring which is added by this function is
77 * created if it does not exist.
78 * Note: this function may be called before secure memory is
79 * available.
80 * Flag 1 == force
81 * Flag 2 == default
83 int
84 keydb_add_resource (const char *url, int flags, int secret)
86 static int any_secret, any_public;
87 const char *resname = url;
88 iobuf_t iobuf = NULL;
89 char *filename = NULL;
90 int force=(flags&1);
91 int rc = 0;
92 KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
93 void *token;
95 /* Do we have an URL?
96 * gnupg-ring:filename := this is a plain keyring
97 * filename := See what is is, but create as plain keyring.
99 if (strlen (resname) > 11) {
100 if (!strncmp( resname, "gnupg-ring:", 11) ) {
101 rt = KEYDB_RESOURCE_TYPE_KEYRING;
102 resname += 11;
104 #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
105 else if (strchr (resname, ':')) {
106 log_error ("invalid key resource URL `%s'\n", url );
107 rc = GPG_ERR_GENERAL;
108 goto leave;
110 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
113 if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
114 if (strchr(resname, DIRSEP_C) )
115 filename = make_filename (resname, NULL);
116 else
117 filename = make_filename (opt.homedir, resname, NULL);
119 else
120 filename = xstrdup (resname);
122 if (!force)
123 force = secret? !any_secret : !any_public;
125 /* see whether we can determine the filetype */
126 if (rt == KEYDB_RESOURCE_TYPE_NONE) {
127 FILE *fp = fopen( filename, "rb" );
129 if (fp) {
130 u32 magic;
132 if (fread( &magic, 4, 1, fp) == 1 ) {
133 if (magic == 0x13579ace || magic == 0xce9a5713)
134 ; /* GDBM magic - no more support */
135 else
136 rt = KEYDB_RESOURCE_TYPE_KEYRING;
138 else /* maybe empty: assume ring */
139 rt = KEYDB_RESOURCE_TYPE_KEYRING;
140 fclose( fp );
142 else /* no file yet: create ring */
143 rt = KEYDB_RESOURCE_TYPE_KEYRING;
146 switch (rt) {
147 case KEYDB_RESOURCE_TYPE_NONE:
148 log_error ("unknown type of key resource `%s'\n", url );
149 rc = GPG_ERR_GENERAL;
150 goto leave;
152 case KEYDB_RESOURCE_TYPE_KEYRING:
153 if (access(filename, F_OK))
154 { /* file does not exist */
155 mode_t oldmask;
156 char *last_slash_in_filename;
158 if (!force)
160 rc = gpg_error_from_errno (errno);
161 goto leave;
164 last_slash_in_filename = strrchr (filename, DIRSEP_C);
165 *last_slash_in_filename = 0;
166 if (access(filename, F_OK))
167 { /* On the first time we try to create the default
168 homedir and check again. */
169 static int tried;
171 if (!tried)
173 tried = 1;
174 try_make_homedir (filename);
176 if (access (filename, F_OK))
178 rc = gpg_error_from_errno (errno);
179 *last_slash_in_filename = DIRSEP_C;
180 goto leave;
183 *last_slash_in_filename = DIRSEP_C;
185 oldmask=umask(077);
186 iobuf = iobuf_create (filename);
187 umask(oldmask);
188 if (!iobuf)
190 log_error ( _("error creating keyring `%s': %s\n"),
191 filename, strerror(errno));
192 rc = gpg_error_from_errno (errno);
193 goto leave;
196 if (!opt.quiet)
197 log_info (_("keyring `%s' created\n"), filename);
198 iobuf_close (iobuf);
199 iobuf = NULL;
200 /* must invalidate that ugly cache */
201 iobuf_ioctl (NULL, 2, 0, (char*)filename);
202 } /* end file creation */
204 if(keyring_register_filename (filename, secret, &token))
206 if (used_resources >= MAX_KEYDB_RESOURCES)
207 rc = GPG_ERR_RESOURCE_LIMIT;
208 else
210 if(flags&2)
211 primary_keyring=token;
212 all_resources[used_resources].type = rt;
213 all_resources[used_resources].u.kr = NULL; /* Not used here */
214 all_resources[used_resources].token = token;
215 all_resources[used_resources].secret = secret;
216 used_resources++;
219 else
221 /* This keyring was already registered, so ignore it.
222 However, we can still mark it as primary even if it was
223 already registered. */
224 if(flags&2)
225 primary_keyring=token;
227 break;
229 default:
230 log_error ("resource type of `%s' not supported\n", url);
231 rc = GPG_ERR_GENERAL;
232 goto leave;
235 /* fixme: check directory permissions and print a warning */
237 leave:
238 if (rc)
239 log_error ("keyblock resource `%s': %s\n", filename, gpg_strerror (rc));
240 else if (secret)
241 any_secret = 1;
242 else
243 any_public = 1;
244 xfree (filename);
245 return rc;
251 KEYDB_HANDLE
252 keydb_new (int secret)
254 KEYDB_HANDLE hd;
255 int i, j;
257 hd = xcalloc (1,sizeof *hd);
258 hd->found = -1;
260 assert (used_resources <= MAX_KEYDB_RESOURCES);
261 for (i=j=0; i < used_resources; i++)
263 if (!all_resources[i].secret != !secret)
264 continue;
265 switch (all_resources[i].type)
267 case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
268 break;
269 case KEYDB_RESOURCE_TYPE_KEYRING:
270 hd->active[j].type = all_resources[i].type;
271 hd->active[j].token = all_resources[i].token;
272 hd->active[j].secret = all_resources[i].secret;
273 hd->active[j].u.kr = keyring_new (all_resources[i].token, secret);
274 if (!hd->active[j].u.kr) {
275 xfree (hd);
276 return NULL; /* fixme: release all previously allocated handles*/
278 j++;
279 break;
282 hd->used = j;
284 active_handles++;
285 return hd;
288 void
289 keydb_release (KEYDB_HANDLE hd)
291 int i;
293 if (!hd)
294 return;
295 assert (active_handles > 0);
296 active_handles--;
298 unlock_all (hd);
299 for (i=0; i < hd->used; i++) {
300 switch (hd->active[i].type) {
301 case KEYDB_RESOURCE_TYPE_NONE:
302 break;
303 case KEYDB_RESOURCE_TYPE_KEYRING:
304 keyring_release (hd->active[i].u.kr);
305 break;
309 xfree (hd);
314 * Return the name of the current resource. This is function first
315 * looks for the last found found, then for the current search
316 * position, and last returns the first available resource. The
317 * returned string is only valid as long as the handle exists. This
318 * function does only return NULL if no handle is specified, in all
319 * other error cases an empty string is returned.
321 const char *
322 keydb_get_resource_name (KEYDB_HANDLE hd)
324 int idx;
325 const char *s = NULL;
327 if (!hd)
328 return NULL;
330 if ( hd->found >= 0 && hd->found < hd->used)
331 idx = hd->found;
332 else if ( hd->current >= 0 && hd->current < hd->used)
333 idx = hd->current;
334 else
335 idx = 0;
337 switch (hd->active[idx].type) {
338 case KEYDB_RESOURCE_TYPE_NONE:
339 s = NULL;
340 break;
341 case KEYDB_RESOURCE_TYPE_KEYRING:
342 s = keyring_get_resource_name (hd->active[idx].u.kr);
343 break;
346 return s? s: "";
351 static int
352 lock_all (KEYDB_HANDLE hd)
354 int i, rc = 0;
356 for (i=0; !rc && i < hd->used; i++) {
357 switch (hd->active[i].type) {
358 case KEYDB_RESOURCE_TYPE_NONE:
359 break;
360 case KEYDB_RESOURCE_TYPE_KEYRING:
361 rc = keyring_lock (hd->active[i].u.kr, 1);
362 break;
366 if (rc) {
367 /* revert the already set locks */
368 for (i--; i >= 0; i--) {
369 switch (hd->active[i].type) {
370 case KEYDB_RESOURCE_TYPE_NONE:
371 break;
372 case KEYDB_RESOURCE_TYPE_KEYRING:
373 keyring_lock (hd->active[i].u.kr, 0);
374 break;
378 else
379 hd->locked = 1;
381 return rc;
384 static void
385 unlock_all (KEYDB_HANDLE hd)
387 int i;
389 if (!hd->locked)
390 return;
392 for (i=hd->used-1; i >= 0; i--) {
393 switch (hd->active[i].type) {
394 case KEYDB_RESOURCE_TYPE_NONE:
395 break;
396 case KEYDB_RESOURCE_TYPE_KEYRING:
397 keyring_lock (hd->active[i].u.kr, 0);
398 break;
401 hd->locked = 0;
406 * Return the last found keyring. Caller must free it.
407 * The returned keyblock has the kbode flag bit 0 set for the node with
408 * the public key used to locate the keyblock or flag bit 1 set for
409 * the user ID node.
412 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
414 int rc = 0;
416 if (!hd)
417 return GPG_ERR_INV_ARG;
419 if ( hd->found < 0 || hd->found >= hd->used)
420 return -1; /* nothing found */
422 switch (hd->active[hd->found].type) {
423 case KEYDB_RESOURCE_TYPE_NONE:
424 rc = GPG_ERR_GENERAL; /* oops */
425 break;
426 case KEYDB_RESOURCE_TYPE_KEYRING:
427 rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
428 break;
431 return rc;
435 * update the current keyblock with KB
438 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
440 int rc = 0;
442 if (!hd)
443 return GPG_ERR_INV_ARG;
445 if ( hd->found < 0 || hd->found >= hd->used)
446 return -1; /* nothing found */
448 if( opt.dry_run )
449 return 0;
451 rc = lock_all (hd);
452 if (rc)
453 return rc;
455 switch (hd->active[hd->found].type) {
456 case KEYDB_RESOURCE_TYPE_NONE:
457 rc = GPG_ERR_GENERAL; /* oops */
458 break;
459 case KEYDB_RESOURCE_TYPE_KEYRING:
460 rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
461 break;
464 unlock_all (hd);
465 return rc;
470 * Insert a new KB into one of the resources.
473 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
475 int rc = -1;
476 int idx;
478 if (!hd)
479 return GPG_ERR_INV_ARG;
481 if( opt.dry_run )
482 return 0;
484 if ( hd->found >= 0 && hd->found < hd->used)
485 idx = hd->found;
486 else if ( hd->current >= 0 && hd->current < hd->used)
487 idx = hd->current;
488 else
489 return GPG_ERR_GENERAL;
491 rc = lock_all (hd);
492 if (rc)
493 return rc;
495 switch (hd->active[idx].type) {
496 case KEYDB_RESOURCE_TYPE_NONE:
497 rc = GPG_ERR_GENERAL; /* oops */
498 break;
499 case KEYDB_RESOURCE_TYPE_KEYRING:
500 rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
501 break;
504 unlock_all (hd);
505 return rc;
510 * The current keyblock will be deleted.
513 keydb_delete_keyblock (KEYDB_HANDLE hd)
515 int rc = -1;
517 if (!hd)
518 return GPG_ERR_INV_ARG;
520 if ( hd->found < 0 || hd->found >= hd->used)
521 return -1; /* nothing found */
523 if( opt.dry_run )
524 return 0;
526 rc = lock_all (hd);
527 if (rc)
528 return rc;
530 switch (hd->active[hd->found].type) {
531 case KEYDB_RESOURCE_TYPE_NONE:
532 rc = GPG_ERR_GENERAL; /* oops */
533 break;
534 case KEYDB_RESOURCE_TYPE_KEYRING:
535 rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
536 break;
539 unlock_all (hd);
540 return rc;
545 * Locate the default writable key resource, so that the next
546 * operation (which is only relevant for inserts) will be done on this
547 * resource.
550 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
552 int rc;
554 if (!hd)
555 return GPG_ERR_INV_ARG;
557 rc = keydb_search_reset (hd); /* this does reset hd->current */
558 if (rc)
559 return rc;
561 /* If we have a primary set, try that one first */
562 if(primary_keyring)
564 for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
566 if(hd->active[hd->current].token==primary_keyring)
568 if(keyring_is_writable (hd->active[hd->current].token))
569 return 0;
570 else
571 break;
575 rc = keydb_search_reset (hd); /* this does reset hd->current */
576 if (rc)
577 return rc;
580 for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
582 switch (hd->active[hd->current].type)
584 case KEYDB_RESOURCE_TYPE_NONE:
585 BUG();
586 break;
587 case KEYDB_RESOURCE_TYPE_KEYRING:
588 if (keyring_is_writable (hd->active[hd->current].token))
589 return 0; /* found (hd->current is set to it) */
590 break;
594 return -1;
598 * Rebuild the caches of all key resources.
600 void
601 keydb_rebuild_caches (void)
603 int i, rc;
605 for (i=0; i < used_resources; i++)
607 if (all_resources[i].secret)
608 continue;
609 switch (all_resources[i].type)
611 case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
612 break;
613 case KEYDB_RESOURCE_TYPE_KEYRING:
614 rc = keyring_rebuild_cache (all_resources[i].token);
615 if (rc)
616 log_error (_("failed to rebuild keyring cache: %s\n"),
617 gpg_strerror (rc));
618 break;
626 * Start the next search on this handle right at the beginning
628 int
629 keydb_search_reset (KEYDB_HANDLE hd)
631 int i, rc = 0;
633 if (!hd)
634 return GPG_ERR_INV_ARG;
636 hd->current = 0;
637 hd->found = -1;
638 /* and reset all resources */
639 for (i=0; !rc && i < hd->used; i++) {
640 switch (hd->active[i].type) {
641 case KEYDB_RESOURCE_TYPE_NONE:
642 break;
643 case KEYDB_RESOURCE_TYPE_KEYRING:
644 rc = keyring_search_reset (hd->active[i].u.kr);
645 break;
648 return rc;
653 * Search through all keydb resources, starting at the current position,
654 * for a keyblock which contains one of the keys described in the DESC array.
656 int
657 keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
658 size_t ndesc, size_t *descindex)
660 int rc = -1;
662 if (!hd)
663 return GPG_ERR_INV_ARG;
665 while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
666 switch (hd->active[hd->current].type) {
667 case KEYDB_RESOURCE_TYPE_NONE:
668 BUG(); /* we should never see it here */
669 break;
670 case KEYDB_RESOURCE_TYPE_KEYRING:
671 rc = keyring_search (hd->active[hd->current].u.kr, desc,
672 ndesc, descindex);
673 break;
675 if (rc == -1) /* EOF -> switch to next resource */
676 hd->current++;
677 else if (!rc)
678 hd->found = hd->current;
681 return rc;
685 keydb_search_first (KEYDB_HANDLE hd)
687 KEYDB_SEARCH_DESC desc;
689 memset (&desc, 0, sizeof desc);
690 desc.mode = KEYDB_SEARCH_MODE_FIRST;
691 return keydb_search (hd, &desc, 1);
695 keydb_search_next (KEYDB_HANDLE hd)
697 KEYDB_SEARCH_DESC desc;
699 memset (&desc, 0, sizeof desc);
700 desc.mode = KEYDB_SEARCH_MODE_NEXT;
701 return keydb_search (hd, &desc, 1);
705 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
707 KEYDB_SEARCH_DESC desc;
709 memset (&desc, 0, sizeof desc);
710 desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
711 desc.u.kid[0] = kid[0];
712 desc.u.kid[1] = kid[1];
713 return keydb_search (hd, &desc, 1);
717 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
719 KEYDB_SEARCH_DESC desc;
721 memset (&desc, 0, sizeof desc);
722 desc.mode = KEYDB_SEARCH_MODE_FPR;
723 memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
724 return keydb_search (hd, &desc, 1);