eb94ef3634cc3e568af4b23f139a1f6ba4602613
[gnupg.git] / g10 / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2002 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 "util.h"
32 #include "options.h"
33 #include "main.h" /*try_make_homedir ()*/
34 #include "packet.h"
35 #include "keyring.h"
36 #include "keydb.h" 
37 #include "i18n.h"
38
39 static int active_handles;
40
41 typedef enum {
42     KEYDB_RESOURCE_TYPE_NONE = 0,
43     KEYDB_RESOURCE_TYPE_KEYRING
44 } KeydbResourceType;
45 #define MAX_KEYDB_RESOURCES 20
46
47 struct resource_item {
48   KeydbResourceType type;
49   union {
50     KEYRING_HANDLE kr;
51   } u;
52   void *token;
53   int secret;
54 };
55
56 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
57 static int used_resources;
58
59 struct keydb_handle {
60   int locked;
61   int found;
62   int current;
63   int used; /* items in active */
64   struct resource_item active[MAX_KEYDB_RESOURCES];
65 };
66
67
68 static int lock_all (KEYDB_HANDLE hd);
69 static void unlock_all (KEYDB_HANDLE hd);
70
71
72 /*
73  * Register a resource (which currently may only be a keyring file).
74  * The first keyring which is added by this function is
75  * created if it does not exist.
76  * Note: this function may be called before secure memory is
77  * available.
78  */
79 int
80 keydb_add_resource (const char *url, int force, int secret)
81 {
82     static int any_secret, any_public;
83     const char *resname = url;
84     IOBUF iobuf = NULL;
85     char *filename = NULL;
86     int rc = 0;
87     KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
88     void *token;
89
90     /* Do we have an URL?
91      *  gnupg-ring:filename  := this is a plain keyring
92      *  filename := See what is is, but create as plain keyring.
93      */
94     if (strlen (resname) > 11) {
95         if (!strncmp( resname, "gnupg-ring:", 11) ) {
96             rt = KEYDB_RESOURCE_TYPE_KEYRING;
97             resname += 11;
98         }
99       #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
100         else if (strchr (resname, ':')) {
101             log_error ("invalid key resource URL `%s'\n", url );
102             rc = G10ERR_GENERAL;
103             goto leave;
104         }
105       #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
106     }
107
108     if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
109         if (strchr(resname, DIRSEP_C) )
110             filename = make_filename (resname, NULL);
111         else
112             filename = make_filename (opt.homedir, resname, NULL);
113     }
114     else
115         filename = m_strdup (resname);
116
117     if (!force)
118         force = secret? !any_secret : !any_public;
119
120     /* see whether we can determine the filetype */
121     if (rt == KEYDB_RESOURCE_TYPE_NONE) {
122         FILE *fp = fopen( filename, "rb" );
123
124         if (fp) {
125             u32 magic;
126
127             if (fread( &magic, 4, 1, fp) == 1 ) {
128                 if (magic == 0x13579ace || magic == 0xce9a5713)
129                     ; /* GDBM magic - no more support */
130                 else
131                     rt = KEYDB_RESOURCE_TYPE_KEYRING;
132             }
133             else /* maybe empty: assume ring */
134                 rt = KEYDB_RESOURCE_TYPE_KEYRING;
135             fclose( fp );
136         }
137         else /* no file yet: create ring */
138             rt = KEYDB_RESOURCE_TYPE_KEYRING;
139     }
140
141     switch (rt) {
142       case KEYDB_RESOURCE_TYPE_NONE:
143         log_error ("unknown type of key resource `%s'\n", url );
144         rc = G10ERR_GENERAL;
145         goto leave;
146
147       case KEYDB_RESOURCE_TYPE_KEYRING:
148         if (access(filename, F_OK))
149           { /* file does not exist */
150             char *last_slash_in_filename;
151
152             if (!force) 
153               {
154                 rc = G10ERR_OPEN_FILE;
155                 goto leave;
156               }
157
158             last_slash_in_filename = strrchr (filename, DIRSEP_C);
159             *last_slash_in_filename = 0;
160             if (access(filename, F_OK))
161               { /* on the first time we try to create the default
162                    homedir and in this case the process will be
163                    terminated, so that on the next invocation it can
164                    read the options file in on startup */
165                 try_make_homedir (filename);
166                 rc = G10ERR_OPEN_FILE;
167                 *last_slash_in_filename = DIRSEP_C;
168                 goto leave;
169               }
170             *last_slash_in_filename = DIRSEP_C;
171
172             iobuf = iobuf_create (filename);
173             if (!iobuf) 
174               {
175                 log_error ( _("error creating keyring `%s': %s\n"),
176                             filename, strerror(errno));
177                 rc = G10ERR_OPEN_FILE;
178                 goto leave;
179               }
180
181 #ifndef HAVE_DOSISH_SYSTEM
182             if (secret && !opt.preserve_permissions) 
183               {
184                 if (chmod (filename, S_IRUSR | S_IWUSR) ) 
185                   {
186                     log_error (_("changing permission of "
187                                  " `%s' failed: %s\n"),
188                                filename, strerror(errno) );
189                     rc = G10ERR_WRITE_FILE;
190                     goto leave;
191                   }
192               }
193 #endif
194             if (!opt.quiet)
195               log_info (_("keyring `%s' created\n"), filename);
196             iobuf_close (iobuf);
197             iobuf = NULL;
198             /* must invalidate that ugly cache */
199             iobuf_ioctl (NULL, 2, 0, (char*)filename);
200           } /* end file creation */
201
202         token = keyring_register_filename (filename, secret);
203         if (!token)
204           ; /* already registered - ignore it */
205         else if (used_resources >= MAX_KEYDB_RESOURCES)
206           rc = G10ERR_RESOURCE_LIMIT;
207         else 
208           {
209             all_resources[used_resources].type = rt;
210             all_resources[used_resources].u.kr = NULL; /* Not used here */
211             all_resources[used_resources].token = token;
212             all_resources[used_resources].secret = secret;
213             used_resources++;
214           }
215         break;
216
217       default:
218         log_error ("resource type of `%s' not supported\n", url);
219         rc = G10ERR_GENERAL;
220         goto leave;
221     }
222
223     /* fixme: check directory permissions and print a warning */
224
225   leave:
226     if (rc)
227         log_error ("keyblock resource `%s': %s\n", filename, g10_errstr(rc));
228     else if (secret)
229         any_secret = 1;
230     else
231         any_public = 1;
232     m_free (filename);
233     return rc;
234 }
235
236
237
238
239 KEYDB_HANDLE
240 keydb_new (int secret)
241 {
242   KEYDB_HANDLE hd;
243   int i, j;
244   
245   hd = m_alloc_clear (sizeof *hd);
246   hd->found = -1;
247   
248   assert (used_resources <= MAX_KEYDB_RESOURCES);
249   for (i=j=0; i < used_resources; i++)
250     {
251       if (!all_resources[i].secret != !secret)
252         continue;
253       switch (all_resources[i].type)
254         {
255         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
256           break;
257         case KEYDB_RESOURCE_TYPE_KEYRING:
258           hd->active[j].type   = all_resources[i].type;
259           hd->active[j].token  = all_resources[i].token;
260           hd->active[j].secret = all_resources[i].secret;
261           hd->active[j].u.kr = keyring_new (all_resources[i].token, secret);
262           if (!hd->active[j].u.kr) {
263             m_free (hd);
264             return NULL; /* fixme: release all previously allocated handles*/
265           }
266           j++;
267           break;
268         }
269     }
270   hd->used = j;
271   
272   active_handles++;
273   return hd;
274 }
275
276 void 
277 keydb_release (KEYDB_HANDLE hd)
278 {
279     int i;
280
281     if (!hd)
282         return;
283     assert (active_handles > 0);
284     active_handles--;
285
286     unlock_all (hd);
287     for (i=0; i < hd->used; i++) {
288         switch (hd->active[i].type) {
289           case KEYDB_RESOURCE_TYPE_NONE:
290             break;
291           case KEYDB_RESOURCE_TYPE_KEYRING:
292             keyring_release (hd->active[i].u.kr);
293             break;
294         }
295     }
296
297     m_free (hd);
298 }
299
300
301 /*
302  * Return the name of the current resource.  This is function first
303  * looks for the last found found, then for the current search
304  * position, and last returns the first available resource.  The
305  * returned string is only valid as long as the handle exists.  This
306  * function does only return NULL if no handle is specified, in all
307  * other error cases an empty string is returned.
308  */
309 const char *
310 keydb_get_resource_name (KEYDB_HANDLE hd)
311 {
312     int idx;
313     const char *s = NULL;
314
315     if (!hd) 
316         return NULL;
317
318     if ( hd->found >= 0 && hd->found < hd->used) 
319         idx = hd->found;
320     else if ( hd->current >= 0 && hd->current < hd->used) 
321         idx = hd->current;
322     else
323         idx = 0;
324
325     switch (hd->active[idx].type) {
326       case KEYDB_RESOURCE_TYPE_NONE:
327         s = NULL; 
328         break;
329       case KEYDB_RESOURCE_TYPE_KEYRING:
330         s = keyring_get_resource_name (hd->active[idx].u.kr);
331         break;
332     }
333
334     return s? s: "";
335 }
336
337
338
339 static int 
340 lock_all (KEYDB_HANDLE hd)
341 {
342     int i, rc = 0;
343
344     for (i=0; !rc && i < hd->used; i++) {
345         switch (hd->active[i].type) {
346           case KEYDB_RESOURCE_TYPE_NONE:
347             break;
348           case KEYDB_RESOURCE_TYPE_KEYRING:
349             rc = keyring_lock (hd->active[i].u.kr, 1);
350             break;
351         }
352     }
353
354     if (rc) {
355         /* revert the already set locks */
356         for (i--; i >= 0; i--) {
357             switch (hd->active[i].type) {
358               case KEYDB_RESOURCE_TYPE_NONE:
359                 break;
360               case KEYDB_RESOURCE_TYPE_KEYRING:
361                 keyring_lock (hd->active[i].u.kr, 0);
362                 break;
363             }
364         }
365     }
366     else
367         hd->locked = 1;
368
369     return rc;
370 }
371
372 static void
373 unlock_all (KEYDB_HANDLE hd)
374 {
375     int i;
376
377     if (!hd->locked)
378         return;
379
380     for (i=hd->used-1; i >= 0; i--) {
381         switch (hd->active[i].type) {
382           case KEYDB_RESOURCE_TYPE_NONE:
383             break;
384           case KEYDB_RESOURCE_TYPE_KEYRING:
385             keyring_lock (hd->active[i].u.kr, 0);
386             break;
387         }
388     }
389     hd->locked = 0;
390 }
391
392
393 /*
394  * Return the last found keyring.  Caller must free it.
395  * The returned keyblock has the kbode flag bit 0 set for the node with
396  * the public key used to locate the keyblock or flag bit 1 set for 
397  * the user ID node.
398  */
399 int
400 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
401 {
402     int rc = 0;
403
404     if (!hd)
405         return G10ERR_INV_ARG;
406
407     if ( hd->found < 0 || hd->found >= hd->used) 
408         return -1; /* nothing found */
409
410     switch (hd->active[hd->found].type) {
411       case KEYDB_RESOURCE_TYPE_NONE:
412         rc = G10ERR_GENERAL; /* oops */
413         break;
414       case KEYDB_RESOURCE_TYPE_KEYRING:
415         rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
416         break;
417     }
418
419     return rc;
420 }
421
422 /* 
423  * update the current keyblock with KB
424  */
425 int
426 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
427 {
428     int rc = 0;
429
430     if (!hd)
431         return G10ERR_INV_ARG;
432
433     if ( hd->found < 0 || hd->found >= hd->used) 
434         return -1; /* nothing found */
435
436     if( opt.dry_run )
437         return 0;
438
439     rc = lock_all (hd);
440     if (rc)
441         return rc;
442
443     switch (hd->active[hd->found].type) {
444       case KEYDB_RESOURCE_TYPE_NONE:
445         rc = G10ERR_GENERAL; /* oops */
446         break;
447       case KEYDB_RESOURCE_TYPE_KEYRING:
448         rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
449         break;
450     }
451
452     unlock_all (hd);
453     return rc;
454 }
455
456
457 /* 
458  * Insert a new KB into one of the resources. 
459  */
460 int
461 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
462 {
463     int rc = -1;
464     int idx;
465
466     if (!hd) 
467         return G10ERR_INV_ARG;
468
469     if( opt.dry_run )
470         return 0;
471
472     if ( hd->found >= 0 && hd->found < hd->used) 
473         idx = hd->found;
474     else if ( hd->current >= 0 && hd->current < hd->used) 
475         idx = hd->current;
476     else
477         return G10ERR_GENERAL;
478
479     rc = lock_all (hd);
480     if (rc)
481         return rc;
482
483     switch (hd->active[idx].type) {
484       case KEYDB_RESOURCE_TYPE_NONE:
485         rc = G10ERR_GENERAL; /* oops */
486         break;
487       case KEYDB_RESOURCE_TYPE_KEYRING:
488         rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
489         break;
490     }
491
492     unlock_all (hd);
493     return rc;
494 }
495
496
497 /* 
498  * The current keyblock will be deleted.
499  */
500 int
501 keydb_delete_keyblock (KEYDB_HANDLE hd)
502 {
503     int rc = -1;
504
505     if (!hd)
506         return G10ERR_INV_ARG;
507
508     if ( hd->found < 0 || hd->found >= hd->used) 
509         return -1; /* nothing found */
510
511     if( opt.dry_run )
512         return 0;
513
514     rc = lock_all (hd);
515     if (rc)
516         return rc;
517
518     switch (hd->active[hd->found].type) {
519       case KEYDB_RESOURCE_TYPE_NONE:
520         rc = G10ERR_GENERAL; /* oops */
521         break;
522       case KEYDB_RESOURCE_TYPE_KEYRING:
523         rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
524         break;
525     }
526
527     unlock_all (hd);
528     return rc;
529 }
530
531 \f
532 /*
533  * Locate the default writable key resource, so that the next
534  * operation (which is only relevant for inserts) will be done on this
535  * resource.  
536  */
537 int
538 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
539 {
540   int rc;
541   
542   if (!hd)
543     return G10ERR_INV_ARG;
544   
545   rc = keydb_search_reset (hd); /* this does reset hd->current */
546   if (rc)
547     return rc;
548
549   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) 
550     {
551       switch (hd->active[hd->current].type) 
552         {
553         case KEYDB_RESOURCE_TYPE_NONE:
554           BUG();
555           break;
556         case KEYDB_RESOURCE_TYPE_KEYRING:
557           if (keyring_is_writable (hd->active[hd->current].token))
558             return 0; /* found (hd->current is set to it) */
559           break;
560         }
561     }
562   
563   return -1;
564 }
565
566 /*
567  * Rebuild the caches of all key resources.
568  */
569 void
570 keydb_rebuild_caches (void)
571 {
572   int i, rc;
573   
574   for (i=0; i < used_resources; i++)
575     {
576       if (all_resources[i].secret)
577         continue;
578       switch (all_resources[i].type)
579         {
580         case KEYDB_RESOURCE_TYPE_NONE: /* ignore */
581           break;
582         case KEYDB_RESOURCE_TYPE_KEYRING:
583           rc = keyring_rebuild_cache (all_resources[i].token);
584           if (rc)
585             log_error (_("failed to rebuild keyring cache: %s\n"),
586                        g10_errstr (rc));
587           break;
588         }
589     }
590 }
591
592
593
594 /* 
595  * Start the next search on this handle right at the beginning
596  */
597 int 
598 keydb_search_reset (KEYDB_HANDLE hd)
599 {
600     int i, rc = 0;
601
602     if (!hd)
603         return G10ERR_INV_ARG;
604
605     hd->current = 0; 
606     hd->found = -1;
607     /* and reset all resources */
608     for (i=0; !rc && i < hd->used; i++) {
609         switch (hd->active[i].type) {
610           case KEYDB_RESOURCE_TYPE_NONE:
611             break;
612           case KEYDB_RESOURCE_TYPE_KEYRING:
613             rc = keyring_search_reset (hd->active[i].u.kr);
614             break;
615         }
616     }
617     return rc; 
618 }
619
620
621 /* 
622  * Search through all keydb resources, starting at the current position,
623  * for a keyblock which contains one of the keys described in the DESC array.
624  */
625 int 
626 keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
627 {
628     int rc = -1;
629
630     if (!hd)
631         return G10ERR_INV_ARG;
632
633     while (rc == -1 && hd->current >= 0 && hd->current < hd->used) {
634         switch (hd->active[hd->current].type) {
635           case KEYDB_RESOURCE_TYPE_NONE:
636             BUG(); /* we should never see it here */
637             break;
638           case KEYDB_RESOURCE_TYPE_KEYRING:
639             rc = keyring_search (hd->active[hd->current].u.kr, desc, ndesc);
640             break;
641         }
642         if (rc == -1) /* EOF -> switch to next resource */
643             hd->current++; 
644         else if (!rc)
645             hd->found = hd->current;
646     }
647
648     return rc; 
649 }
650
651
652 int
653 keydb_search_first (KEYDB_HANDLE hd)
654 {
655     KEYDB_SEARCH_DESC desc;
656
657     memset (&desc, 0, sizeof desc);
658     desc.mode = KEYDB_SEARCH_MODE_FIRST;
659     return keydb_search (hd, &desc, 1);
660 }
661
662 int
663 keydb_search_next (KEYDB_HANDLE hd)
664 {
665     KEYDB_SEARCH_DESC desc;
666
667     memset (&desc, 0, sizeof desc);
668     desc.mode = KEYDB_SEARCH_MODE_NEXT;
669     return keydb_search (hd, &desc, 1);
670 }
671
672 int
673 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
674 {
675     KEYDB_SEARCH_DESC desc;
676
677     memset (&desc, 0, sizeof desc);
678     desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
679     desc.u.kid[0] = kid[0];
680     desc.u.kid[1] = kid[1];
681     return keydb_search (hd, &desc, 1);
682 }
683
684 int
685 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
686 {
687     KEYDB_SEARCH_DESC desc;
688
689     memset (&desc, 0, sizeof desc);
690     desc.mode = KEYDB_SEARCH_MODE_FPR;
691     memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
692     return keydb_search (hd, &desc, 1);
693 }
694
695
696