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
27 #include <sys/types.h>
34 #include "main.h" /*try_make_homedir ()*/
40 static int active_handles
;
43 KEYDB_RESOURCE_TYPE_NONE
= 0,
44 KEYDB_RESOURCE_TYPE_KEYRING
46 #define MAX_KEYDB_RESOURCES 40
48 struct resource_item
{
49 KeydbResourceType type
;
57 static struct resource_item all_resources
[MAX_KEYDB_RESOURCES
];
58 static int used_resources
;
59 static void *primary_keyring
=NULL
;
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
84 keydb_add_resource (const char *url
, int flags
, int secret
)
86 static int any_secret
, any_public
;
87 const char *resname
= url
;
89 char *filename
= NULL
;
92 KeydbResourceType rt
= KEYDB_RESOURCE_TYPE_NONE
;
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
;
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
;
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
);
117 filename
= make_filename (opt
.homedir
, resname
, NULL
);
120 filename
= xstrdup (resname
);
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" );
132 if (fread( &magic
, 4, 1, fp
) == 1 ) {
133 if (magic
== 0x13579ace || magic
== 0xce9a5713)
134 ; /* GDBM magic - no more support */
136 rt
= KEYDB_RESOURCE_TYPE_KEYRING
;
138 else /* maybe empty: assume ring */
139 rt
= KEYDB_RESOURCE_TYPE_KEYRING
;
142 else /* no file yet: create ring */
143 rt
= KEYDB_RESOURCE_TYPE_KEYRING
;
147 case KEYDB_RESOURCE_TYPE_NONE
:
148 log_error ("unknown type of key resource `%s'\n", url
);
149 rc
= GPG_ERR_GENERAL
;
152 case KEYDB_RESOURCE_TYPE_KEYRING
:
153 if (access(filename
, F_OK
))
154 { /* file does not exist */
156 char *last_slash_in_filename
;
160 rc
= gpg_error_from_errno (errno
);
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. */
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
;
183 *last_slash_in_filename
= DIRSEP_C
;
186 iobuf
= iobuf_create (filename
);
190 log_error ( _("error creating keyring `%s': %s\n"),
191 filename
, strerror(errno
));
192 rc
= gpg_error_from_errno (errno
);
197 log_info (_("keyring `%s' created\n"), filename
);
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
;
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
;
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. */
225 primary_keyring
=token
;
230 log_error ("resource type of `%s' not supported\n", url
);
231 rc
= GPG_ERR_GENERAL
;
235 /* fixme: check directory permissions and print a warning */
239 log_error ("keyblock resource `%s': %s\n", filename
, gpg_strerror (rc
));
252 keydb_new (int secret
)
257 hd
= xcalloc (1,sizeof *hd
);
260 assert (used_resources
<= MAX_KEYDB_RESOURCES
);
261 for (i
=j
=0; i
< used_resources
; i
++)
263 if (!all_resources
[i
].secret
!= !secret
)
265 switch (all_resources
[i
].type
)
267 case KEYDB_RESOURCE_TYPE_NONE
: /* ignore */
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
) {
276 return NULL
; /* fixme: release all previously allocated handles*/
289 keydb_release (KEYDB_HANDLE hd
)
295 assert (active_handles
> 0);
299 for (i
=0; i
< hd
->used
; i
++) {
300 switch (hd
->active
[i
].type
) {
301 case KEYDB_RESOURCE_TYPE_NONE
:
303 case KEYDB_RESOURCE_TYPE_KEYRING
:
304 keyring_release (hd
->active
[i
].u
.kr
);
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.
322 keydb_get_resource_name (KEYDB_HANDLE hd
)
325 const char *s
= NULL
;
330 if ( hd
->found
>= 0 && hd
->found
< hd
->used
)
332 else if ( hd
->current
>= 0 && hd
->current
< hd
->used
)
337 switch (hd
->active
[idx
].type
) {
338 case KEYDB_RESOURCE_TYPE_NONE
:
341 case KEYDB_RESOURCE_TYPE_KEYRING
:
342 s
= keyring_get_resource_name (hd
->active
[idx
].u
.kr
);
352 lock_all (KEYDB_HANDLE hd
)
356 for (i
=0; !rc
&& i
< hd
->used
; i
++) {
357 switch (hd
->active
[i
].type
) {
358 case KEYDB_RESOURCE_TYPE_NONE
:
360 case KEYDB_RESOURCE_TYPE_KEYRING
:
361 rc
= keyring_lock (hd
->active
[i
].u
.kr
, 1);
367 /* revert the already set locks */
368 for (i
--; i
>= 0; i
--) {
369 switch (hd
->active
[i
].type
) {
370 case KEYDB_RESOURCE_TYPE_NONE
:
372 case KEYDB_RESOURCE_TYPE_KEYRING
:
373 keyring_lock (hd
->active
[i
].u
.kr
, 0);
385 unlock_all (KEYDB_HANDLE hd
)
392 for (i
=hd
->used
-1; i
>= 0; i
--) {
393 switch (hd
->active
[i
].type
) {
394 case KEYDB_RESOURCE_TYPE_NONE
:
396 case KEYDB_RESOURCE_TYPE_KEYRING
:
397 keyring_lock (hd
->active
[i
].u
.kr
, 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
412 keydb_get_keyblock (KEYDB_HANDLE hd
, KBNODE
*ret_kb
)
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 */
426 case KEYDB_RESOURCE_TYPE_KEYRING
:
427 rc
= keyring_get_keyblock (hd
->active
[hd
->found
].u
.kr
, ret_kb
);
435 * update the current keyblock with KB
438 keydb_update_keyblock (KEYDB_HANDLE hd
, KBNODE kb
)
443 return GPG_ERR_INV_ARG
;
445 if ( hd
->found
< 0 || hd
->found
>= hd
->used
)
446 return -1; /* nothing found */
455 switch (hd
->active
[hd
->found
].type
) {
456 case KEYDB_RESOURCE_TYPE_NONE
:
457 rc
= GPG_ERR_GENERAL
; /* oops */
459 case KEYDB_RESOURCE_TYPE_KEYRING
:
460 rc
= keyring_update_keyblock (hd
->active
[hd
->found
].u
.kr
, kb
);
470 * Insert a new KB into one of the resources.
473 keydb_insert_keyblock (KEYDB_HANDLE hd
, KBNODE kb
)
479 return GPG_ERR_INV_ARG
;
484 if ( hd
->found
>= 0 && hd
->found
< hd
->used
)
486 else if ( hd
->current
>= 0 && hd
->current
< hd
->used
)
489 return GPG_ERR_GENERAL
;
495 switch (hd
->active
[idx
].type
) {
496 case KEYDB_RESOURCE_TYPE_NONE
:
497 rc
= GPG_ERR_GENERAL
; /* oops */
499 case KEYDB_RESOURCE_TYPE_KEYRING
:
500 rc
= keyring_insert_keyblock (hd
->active
[idx
].u
.kr
, kb
);
510 * The current keyblock will be deleted.
513 keydb_delete_keyblock (KEYDB_HANDLE hd
)
518 return GPG_ERR_INV_ARG
;
520 if ( hd
->found
< 0 || hd
->found
>= hd
->used
)
521 return -1; /* nothing found */
530 switch (hd
->active
[hd
->found
].type
) {
531 case KEYDB_RESOURCE_TYPE_NONE
:
532 rc
= GPG_ERR_GENERAL
; /* oops */
534 case KEYDB_RESOURCE_TYPE_KEYRING
:
535 rc
= keyring_delete_keyblock (hd
->active
[hd
->found
].u
.kr
);
545 * Locate the default writable key resource, so that the next
546 * operation (which is only relevant for inserts) will be done on this
550 keydb_locate_writable (KEYDB_HANDLE hd
, const char *reserved
)
555 return GPG_ERR_INV_ARG
;
557 rc
= keydb_search_reset (hd
); /* this does reset hd->current */
561 /* If we have a primary set, try that one first */
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
))
575 rc
= keydb_search_reset (hd
); /* this does reset hd->current */
580 for ( ; hd
->current
>= 0 && hd
->current
< hd
->used
; hd
->current
++)
582 switch (hd
->active
[hd
->current
].type
)
584 case KEYDB_RESOURCE_TYPE_NONE
:
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) */
598 * Rebuild the caches of all key resources.
601 keydb_rebuild_caches (void)
605 for (i
=0; i
< used_resources
; i
++)
607 if (all_resources
[i
].secret
)
609 switch (all_resources
[i
].type
)
611 case KEYDB_RESOURCE_TYPE_NONE
: /* ignore */
613 case KEYDB_RESOURCE_TYPE_KEYRING
:
614 rc
= keyring_rebuild_cache (all_resources
[i
].token
);
616 log_error (_("failed to rebuild keyring cache: %s\n"),
626 * Start the next search on this handle right at the beginning
629 keydb_search_reset (KEYDB_HANDLE hd
)
634 return GPG_ERR_INV_ARG
;
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
:
643 case KEYDB_RESOURCE_TYPE_KEYRING
:
644 rc
= keyring_search_reset (hd
->active
[i
].u
.kr
);
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.
657 keydb_search2 (KEYDB_HANDLE hd
, KEYDB_SEARCH_DESC
*desc
,
658 size_t ndesc
, size_t *descindex
)
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 */
670 case KEYDB_RESOURCE_TYPE_KEYRING
:
671 rc
= keyring_search (hd
->active
[hd
->current
].u
.kr
, desc
,
675 if (rc
== -1) /* EOF -> switch to next resource */
678 hd
->found
= hd
->current
;
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);