(pk_sign): Fix last change.
[gnupg.git] / g10 / keydb.c
1 /* keydb.c - key database dispatcher
2  * Copyright (C) 2001, 2002, 2003 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 "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"
39
40 static int active_handles;
41
42 typedef enum {
43     KEYDB_RESOURCE_TYPE_NONE = 0,
44     KEYDB_RESOURCE_TYPE_KEYRING
45 } KeydbResourceType;
46 #define MAX_KEYDB_RESOURCES 40
47
48 struct resource_item {
49   KeydbResourceType type;
50   union {
51     KEYRING_HANDLE kr;
52   } u;
53   void *token;
54   int secret;
55 };
56
57 static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
58 static int used_resources;
59 static void *primary_keyring=NULL;
60
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];
67 };
68
69
70 static int lock_all (KEYDB_HANDLE hd);
71 static void unlock_all (KEYDB_HANDLE hd);
72
73
74 /*
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
82  */
83 int
84 keydb_add_resource (const char *url, int flags, int secret)
85 {
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;
94
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.
98      */
99     if (strlen (resname) > 11) {
100         if (!strncmp( resname, "gnupg-ring:", 11) ) {
101             rt = KEYDB_RESOURCE_TYPE_KEYRING;
102             resname += 11;
103         }
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;
109         }
110 #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
111     }
112
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);
118     }
119     else
120         filename = xstrdup (resname);
121
122     if (!force)
123         force = secret? !any_secret : !any_public;
124
125     /* see whether we can determine the filetype */
126     if (rt == KEYDB_RESOURCE_TYPE_NONE) {
127         FILE *fp = fopen( filename, "rb" );
128
129         if (fp) {
130             u32 magic;
131
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;
137             }
138             else /* maybe empty: assume ring */
139                 rt = KEYDB_RESOURCE_TYPE_KEYRING;
140             fclose( fp );
141         }
142         else /* no file yet: create ring */
143             rt = KEYDB_RESOURCE_TYPE_KEYRING;
144     }
145
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;
151
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;
157
158             if (!force) 
159               {
160                 rc = gpg_error_from_errno (errno);
161                 goto leave;
162               }
163
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;
170                 
171                 if (!tried)
172                   {
173                     tried = 1;
174                     try_make_homedir (filename);
175                   }
176                 if (access (filename, F_OK))
177                   {
178                     rc = gpg_error_from_errno (errno);
179                     *last_slash_in_filename = DIRSEP_C;
180                     goto leave;
181                   }
182               }
183             *last_slash_in_filename = DIRSEP_C;
184
185             oldmask=umask(077);
186             iobuf = iobuf_create (filename);
187             umask(oldmask);
188             if (!iobuf) 
189               {
190                 log_error ( _("error creating keyring `%s': %s\n"),
191                             filename, strerror(errno));
192                 rc = gpg_error_from_errno (errno);
193                 goto leave;
194               }
195
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 */
203
204         if(keyring_register_filename (filename, secret, &token))
205           {
206             if (used_resources >= MAX_KEYDB_RESOURCES)
207               rc = GPG_ERR_RESOURCE_LIMIT;
208             else 
209               {
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++;
217               }
218           }
219         else
220           {
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;
226           }
227         break;
228
229       default:
230         log_error ("resource type of `%s' not supported\n", url);
231         rc = GPG_ERR_GENERAL;
232         goto leave;
233     }
234
235     /* fixme: check directory permissions and print a warning */
236
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;
246 }
247
248
249
250
251 KEYDB_HANDLE
252 keydb_new (int secret)
253 {
254   KEYDB_HANDLE hd;
255   int i, j;
256   
257   hd = xcalloc (1,sizeof *hd);
258   hd->found = -1;
259   
260   assert (used_resources <= MAX_KEYDB_RESOURCES);
261   for (i=j=0; i < used_resources; i++)
262     {
263       if (!all_resources[i].secret != !secret)
264         continue;
265       switch (all_resources[i].type)
266         {
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*/
277           }
278           j++;
279           break;
280         }
281     }
282   hd->used = j;
283   
284   active_handles++;
285   return hd;
286 }
287
288 void 
289 keydb_release (KEYDB_HANDLE hd)
290 {
291     int i;
292
293     if (!hd)
294         return;
295     assert (active_handles > 0);
296     active_handles--;
297
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;
306         }
307     }
308
309     xfree (hd);
310 }
311
312
313 /*
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.
320  */
321 const char *
322 keydb_get_resource_name (KEYDB_HANDLE hd)
323 {
324     int idx;
325     const char *s = NULL;
326
327     if (!hd) 
328         return NULL;
329
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;
336
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;
344     }
345
346     return s? s: "";
347 }
348
349
350
351 static int 
352 lock_all (KEYDB_HANDLE hd)
353 {
354     int i, rc = 0;
355
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;
363         }
364     }
365
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;
375             }
376         }
377     }
378     else
379         hd->locked = 1;
380
381     return rc;
382 }
383
384 static void
385 unlock_all (KEYDB_HANDLE hd)
386 {
387     int i;
388
389     if (!hd->locked)
390         return;
391
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;
399         }
400     }
401     hd->locked = 0;
402 }
403
404
405 /*
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.
410  */
411 int
412 keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
413 {
414     int rc = 0;
415
416     if (!hd)
417         return GPG_ERR_INV_ARG;
418
419     if ( hd->found < 0 || hd->found >= hd->used) 
420         return -1; /* nothing found */
421
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;
429     }
430
431     return rc;
432 }
433
434 /* 
435  * update the current keyblock with KB
436  */
437 int
438 keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
439 {
440     int rc = 0;
441
442     if (!hd)
443         return GPG_ERR_INV_ARG;
444
445     if ( hd->found < 0 || hd->found >= hd->used) 
446         return -1; /* nothing found */
447
448     if( opt.dry_run )
449         return 0;
450
451     rc = lock_all (hd);
452     if (rc)
453         return rc;
454
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;
462     }
463
464     unlock_all (hd);
465     return rc;
466 }
467
468
469 /* 
470  * Insert a new KB into one of the resources. 
471  */
472 int
473 keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
474 {
475     int rc = -1;
476     int idx;
477
478     if (!hd) 
479         return GPG_ERR_INV_ARG;
480
481     if( opt.dry_run )
482         return 0;
483
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;
490
491     rc = lock_all (hd);
492     if (rc)
493         return rc;
494
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;
502     }
503
504     unlock_all (hd);
505     return rc;
506 }
507
508
509 /* 
510  * The current keyblock will be deleted.
511  */
512 int
513 keydb_delete_keyblock (KEYDB_HANDLE hd)
514 {
515     int rc = -1;
516
517     if (!hd)
518         return GPG_ERR_INV_ARG;
519
520     if ( hd->found < 0 || hd->found >= hd->used) 
521         return -1; /* nothing found */
522
523     if( opt.dry_run )
524         return 0;
525
526     rc = lock_all (hd);
527     if (rc)
528         return rc;
529
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;
537     }
538
539     unlock_all (hd);
540     return rc;
541 }
542
543 \f
544 /*
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.  
548  */
549 int
550 keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
551 {
552   int rc;
553   
554   if (!hd)
555     return GPG_ERR_INV_ARG;
556   
557   rc = keydb_search_reset (hd); /* this does reset hd->current */
558   if (rc)
559     return rc;
560
561   /* If we have a primary set, try that one first */
562   if(primary_keyring)
563     {
564       for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++)
565         {
566           if(hd->active[hd->current].token==primary_keyring)
567             {
568               if(keyring_is_writable (hd->active[hd->current].token))
569                 return 0;
570               else
571                 break;
572             }
573         }
574
575       rc = keydb_search_reset (hd); /* this does reset hd->current */
576       if (rc)
577         return rc;
578     }
579
580   for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) 
581     {
582       switch (hd->active[hd->current].type) 
583         {
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;
591         }
592     }
593   
594   return -1;
595 }
596
597 /*
598  * Rebuild the caches of all key resources.
599  */
600 void
601 keydb_rebuild_caches (void)
602 {
603   int i, rc;
604   
605   for (i=0; i < used_resources; i++)
606     {
607       if (all_resources[i].secret)
608         continue;
609       switch (all_resources[i].type)
610         {
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;
619         }
620     }
621 }
622
623
624
625 /* 
626  * Start the next search on this handle right at the beginning
627  */
628 int 
629 keydb_search_reset (KEYDB_HANDLE hd)
630 {
631     int i, rc = 0;
632
633     if (!hd)
634         return GPG_ERR_INV_ARG;
635
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;
646         }
647     }
648     return rc; 
649 }
650
651
652 /* 
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.
655  */
656 int 
657 keydb_search2 (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
658                size_t ndesc, size_t *descindex)
659 {
660     int rc = -1;
661
662     if (!hd)
663         return GPG_ERR_INV_ARG;
664
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;
674         }
675         if (rc == -1) /* EOF -> switch to next resource */
676             hd->current++; 
677         else if (!rc)
678             hd->found = hd->current;
679     }
680
681     return rc; 
682 }
683
684 int
685 keydb_search_first (KEYDB_HANDLE hd)
686 {
687     KEYDB_SEARCH_DESC desc;
688
689     memset (&desc, 0, sizeof desc);
690     desc.mode = KEYDB_SEARCH_MODE_FIRST;
691     return keydb_search (hd, &desc, 1);
692 }
693
694 int
695 keydb_search_next (KEYDB_HANDLE hd)
696 {
697     KEYDB_SEARCH_DESC desc;
698
699     memset (&desc, 0, sizeof desc);
700     desc.mode = KEYDB_SEARCH_MODE_NEXT;
701     return keydb_search (hd, &desc, 1);
702 }
703
704 int
705 keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
706 {
707     KEYDB_SEARCH_DESC desc;
708
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);
714 }
715
716 int
717 keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
718 {
719     KEYDB_SEARCH_DESC desc;
720
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);
725 }