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