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