speedo: Improve speedo Makefile.
[gnupg.git] / g10 / keyring.c
1 /* keyring.c - keyring file handling
2  * Copyright (C) 2001, 2004, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29
30 #include "gpg.h"
31 #include "util.h"
32 #include "keyring.h"
33 #include "packet.h"
34 #include "keydb.h"
35 #include "options.h"
36 #include "main.h" /*for check_key_signature()*/
37 #include "i18n.h"
38
39 /* off_item is a funny named for an object used to keep track of known
40  * keys.  The idea was to use the offset to seek to the known keyblock, but
41  * this is not possible if more than one process is using the keyring.
42  */
43 struct off_item {
44   struct off_item *next;
45   u32 kid[2];
46   /*off_t off;*/
47 };
48
49 typedef struct off_item **OffsetHashTable;
50
51
52 typedef struct keyring_name *KR_NAME;
53 struct keyring_name
54 {
55   struct keyring_name *next;
56   int read_only;
57   dotlock_t lockhd;
58   int is_locked;
59   int did_full_scan;
60   char fname[1];
61 };
62 typedef struct keyring_name const * CONST_KR_NAME;
63
64 static KR_NAME kr_names;
65 static int active_handles;
66
67 static OffsetHashTable kr_offtbl;
68 static int kr_offtbl_ready;
69
70
71 struct keyring_handle
72 {
73   CONST_KR_NAME resource;
74   struct {
75     CONST_KR_NAME kr;
76     IOBUF iobuf;
77     int eof;
78     int error;
79   } current;
80   struct {
81     CONST_KR_NAME kr;
82     off_t offset;
83     size_t pk_no;
84     size_t uid_no;
85     unsigned int n_packets; /*used for delete and update*/
86   } found;
87   struct {
88     char *name;
89     char *pattern;
90   } word_match;
91 };
92
93
94
95 static int do_copy (int mode, const char *fname, KBNODE root,
96                     off_t start_offset, unsigned int n_packets );
97
98
99 \f
100 static struct off_item *
101 new_offset_item (void)
102 {
103   struct off_item *k;
104
105   k = xmalloc_clear (sizeof *k);
106   return k;
107 }
108
109 #if 0
110 static void
111 release_offset_items (struct off_item *k)
112 {
113   struct off_item *k2;
114
115   for (; k; k = k2)
116     {
117       k2 = k->next;
118       xfree (k);
119     }
120 }
121 #endif
122
123 static OffsetHashTable
124 new_offset_hash_table (void)
125 {
126   struct off_item **tbl;
127
128   tbl = xmalloc_clear (2048 * sizeof *tbl);
129   return tbl;
130 }
131
132 #if 0
133 static void
134 release_offset_hash_table (OffsetHashTable tbl)
135 {
136   int i;
137
138   if (!tbl)
139     return;
140   for (i=0; i < 2048; i++)
141     release_offset_items (tbl[i]);
142   xfree (tbl);
143 }
144 #endif
145
146 static struct off_item *
147 lookup_offset_hash_table (OffsetHashTable tbl, u32 *kid)
148 {
149   struct off_item *k;
150
151   for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next)
152     if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
153       return k;
154   return NULL;
155 }
156
157 static void
158 update_offset_hash_table (OffsetHashTable tbl, u32 *kid, off_t off)
159 {
160   struct off_item *k;
161
162   (void)off;
163
164   for (k = tbl[(kid[1] & 0x07ff)]; k; k = k->next)
165     {
166       if (k->kid[0] == kid[0] && k->kid[1] == kid[1])
167         {
168           /*k->off = off;*/
169           return;
170         }
171     }
172
173   k = new_offset_item ();
174   k->kid[0] = kid[0];
175   k->kid[1] = kid[1];
176   /*k->off = off;*/
177   k->next = tbl[(kid[1] & 0x07ff)];
178   tbl[(kid[1] & 0x07ff)] = k;
179 }
180
181 static void
182 update_offset_hash_table_from_kb (OffsetHashTable tbl, KBNODE node, off_t off)
183 {
184   for (; node; node = node->next)
185     {
186       if (node->pkt->pkttype == PKT_PUBLIC_KEY
187           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
188         {
189           u32 aki[2];
190           keyid_from_pk (node->pkt->pkt.public_key, aki);
191           update_offset_hash_table (tbl, aki, off);
192         }
193     }
194 }
195
196 /*
197  * Register a filename for plain keyring files.  ptr is set to a
198  * pointer to be used to create a handles etc, or the already-issued
199  * pointer if it has already been registered.  The function returns 1
200  * if a new keyring was registered.
201 */
202 int
203 keyring_register_filename (const char *fname, int read_only, void **ptr)
204 {
205     KR_NAME kr;
206
207     if (active_handles)
208         BUG (); /* We don't allow that */
209
210     for (kr=kr_names; kr; kr = kr->next)
211       {
212         if (same_file_p (kr->fname, fname))
213           {
214             /* Already registered. */
215             if (read_only)
216               kr->read_only = 1;
217             *ptr=kr;
218             return 0;
219           }
220       }
221
222     kr = xmalloc (sizeof *kr + strlen (fname));
223     strcpy (kr->fname, fname);
224     kr->read_only = read_only;
225     kr->lockhd = NULL;
226     kr->is_locked = 0;
227     kr->did_full_scan = 0;
228     /* keep a list of all issued pointers */
229     kr->next = kr_names;
230     kr_names = kr;
231
232     /* create the offset table the first time a function here is used */
233     if (!kr_offtbl)
234       kr_offtbl = new_offset_hash_table ();
235
236     *ptr=kr;
237
238     return 1;
239 }
240
241 int
242 keyring_is_writable (void *token)
243 {
244   KR_NAME r = token;
245
246   return r? (r->read_only || !access (r->fname, W_OK)) : 0;
247 }
248
249
250 \f
251 /* Create a new handle for the resource associated with TOKEN.
252
253    The returned handle must be released using keyring_release (). */
254 KEYRING_HANDLE
255 keyring_new (void *token)
256 {
257   KEYRING_HANDLE hd;
258   KR_NAME resource = token;
259
260   assert (resource);
261
262   hd = xmalloc_clear (sizeof *hd);
263   hd->resource = resource;
264   active_handles++;
265   return hd;
266 }
267
268 void
269 keyring_release (KEYRING_HANDLE hd)
270 {
271     if (!hd)
272         return;
273     assert (active_handles > 0);
274     active_handles--;
275     xfree (hd->word_match.name);
276     xfree (hd->word_match.pattern);
277     iobuf_close (hd->current.iobuf);
278     xfree (hd);
279 }
280
281
282 const char *
283 keyring_get_resource_name (KEYRING_HANDLE hd)
284 {
285     if (!hd || !hd->resource)
286       return NULL;
287     return hd->resource->fname;
288 }
289
290
291 /*
292  * Lock the keyring with the given handle, or unlock if YES is false.
293  * We ignore the handle and lock all registered files.
294  */
295 int
296 keyring_lock (KEYRING_HANDLE hd, int yes)
297 {
298     KR_NAME kr;
299     int rc = 0;
300
301     (void)hd;
302
303     if (yes) {
304         /* first make sure the lock handles are created */
305         for (kr=kr_names; kr; kr = kr->next) {
306             if (!keyring_is_writable(kr))
307                 continue;
308             if (!kr->lockhd) {
309                 kr->lockhd = dotlock_create (kr->fname, 0);
310                 if (!kr->lockhd) {
311                     log_info ("can't allocate lock for '%s'\n", kr->fname );
312                     rc = G10ERR_GENERAL;
313                 }
314             }
315         }
316         if (rc)
317             return rc;
318
319         /* and now set the locks */
320         for (kr=kr_names; kr; kr = kr->next) {
321             if (!keyring_is_writable(kr))
322                 continue;
323             if (kr->is_locked)
324                 ;
325             else if (dotlock_take (kr->lockhd, -1) ) {
326                 log_info ("can't lock '%s'\n", kr->fname );
327                 rc = G10ERR_GENERAL;
328             }
329             else
330                 kr->is_locked = 1;
331         }
332     }
333
334     if (rc || !yes) {
335         for (kr=kr_names; kr; kr = kr->next) {
336             if (!keyring_is_writable(kr))
337                 continue;
338             if (!kr->is_locked)
339                 ;
340             else if (dotlock_release (kr->lockhd))
341                 log_info ("can't unlock '%s'\n", kr->fname );
342             else
343                 kr->is_locked = 0;
344         }
345     }
346
347     return rc;
348 }
349
350
351 \f
352 /*
353  * Return the last found keyring.  Caller must free it.
354  * The returned keyblock has the kbode flag bit 0 set for the node with
355  * the public key used to locate the keyblock or flag bit 1 set for
356  * the user ID node.
357  */
358 int
359 keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb)
360 {
361     PACKET *pkt;
362     int rc;
363     KBNODE keyblock = NULL, node, lastnode;
364     IOBUF a;
365     int in_cert = 0;
366     int pk_no = 0;
367     int uid_no = 0;
368     int save_mode;
369
370     if (ret_kb)
371         *ret_kb = NULL;
372
373     if (!hd->found.kr)
374         return -1; /* no successful search */
375
376     a = iobuf_open (hd->found.kr->fname);
377     if (!a)
378       {
379         log_error(_("can't open '%s'\n"), hd->found.kr->fname);
380         return G10ERR_KEYRING_OPEN;
381       }
382
383     if (iobuf_seek (a, hd->found.offset) ) {
384         log_error ("can't seek '%s'\n", hd->found.kr->fname);
385         iobuf_close(a);
386         return G10ERR_KEYRING_OPEN;
387     }
388
389     pkt = xmalloc (sizeof *pkt);
390     init_packet (pkt);
391     hd->found.n_packets = 0;;
392     lastnode = NULL;
393     save_mode = set_packet_list_mode(0);
394     while ((rc=parse_packet (a, pkt)) != -1) {
395         hd->found.n_packets++;
396         if (rc == G10ERR_UNKNOWN_PACKET) {
397             free_packet (pkt);
398             init_packet (pkt);
399             continue;
400         }
401         if (rc) {
402             log_error ("keyring_get_keyblock: read error: %s\n",
403                        g10_errstr(rc) );
404             rc = G10ERR_INV_KEYRING;
405             break;
406         }
407         if (pkt->pkttype == PKT_COMPRESSED) {
408             log_error ("skipped compressed packet in keyring\n");
409             free_packet(pkt);
410             init_packet(pkt);
411             continue;
412         }
413
414         if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY
415                         || pkt->pkttype == PKT_SECRET_KEY)) {
416             hd->found.n_packets--; /* fix counter */
417             break; /* ready */
418         }
419
420         in_cert = 1;
421         if (pkt->pkttype == PKT_RING_TRUST)
422           {
423             /*(this code is duplicated after the loop)*/
424             if ( lastnode
425                  && lastnode->pkt->pkttype == PKT_SIGNATURE
426                  && (pkt->pkt.ring_trust->sigcache & 1) ) {
427                 /* This is a ring trust packet with a checked signature
428                  * status cache following directly a signature paket.
429                  * Set the cache status into that signature packet.  */
430                 PKT_signature *sig = lastnode->pkt->pkt.signature;
431
432                 sig->flags.checked = 1;
433                 sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
434             }
435             /* Reset LASTNODE, so that we set the cache status only from
436              * the ring trust packet immediately following a signature. */
437             lastnode = NULL;
438             free_packet(pkt);
439             init_packet(pkt);
440             continue;
441           }
442
443
444         node = lastnode = new_kbnode (pkt);
445         if (!keyblock)
446           keyblock = node;
447         else
448           add_kbnode (keyblock, node);
449         switch (pkt->pkttype)
450           {
451           case PKT_PUBLIC_KEY:
452           case PKT_PUBLIC_SUBKEY:
453           case PKT_SECRET_KEY:
454           case PKT_SECRET_SUBKEY:
455             if (++pk_no == hd->found.pk_no)
456               node->flag |= 1;
457             break;
458
459           case PKT_USER_ID:
460             if (++uid_no == hd->found.uid_no)
461               node->flag |= 2;
462             break;
463
464           default:
465             break;
466           }
467
468         pkt = xmalloc (sizeof *pkt);
469         init_packet(pkt);
470     }
471     set_packet_list_mode(save_mode);
472
473     if (rc == -1 && keyblock)
474         rc = 0; /* got the entire keyblock */
475
476     if (rc || !ret_kb)
477         release_kbnode (keyblock);
478     else {
479         /*(duplicated form the loop body)*/
480         if ( pkt && pkt->pkttype == PKT_RING_TRUST
481              && lastnode
482              && lastnode->pkt->pkttype == PKT_SIGNATURE
483              && (pkt->pkt.ring_trust->sigcache & 1) ) {
484             PKT_signature *sig = lastnode->pkt->pkt.signature;
485             sig->flags.checked = 1;
486             sig->flags.valid = !!(pkt->pkt.ring_trust->sigcache & 2);
487         }
488         *ret_kb = keyblock;
489     }
490     free_packet (pkt);
491     xfree (pkt);
492     iobuf_close(a);
493
494     /* Make sure that future search operations fail immediately when
495      * we know that we are working on a invalid keyring
496      */
497     if (rc == G10ERR_INV_KEYRING)
498         hd->current.error = rc;
499
500     return rc;
501 }
502
503 int
504 keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb)
505 {
506     int rc;
507
508     if (!hd->found.kr)
509         return -1; /* no successful prior search */
510
511     if (hd->found.kr->read_only)
512       return gpg_error (GPG_ERR_EACCES);
513
514     if (!hd->found.n_packets) {
515         /* need to know the number of packets - do a dummy get_keyblock*/
516         rc = keyring_get_keyblock (hd, NULL);
517         if (rc) {
518             log_error ("re-reading keyblock failed: %s\n", g10_errstr (rc));
519             return rc;
520         }
521         if (!hd->found.n_packets)
522             BUG ();
523     }
524
525     /* The open iobuf isn't needed anymore and in fact is a problem when
526        it comes to renaming the keyring files on some operating systems,
527        so close it here */
528     iobuf_close(hd->current.iobuf);
529     hd->current.iobuf = NULL;
530
531     /* do the update */
532     rc = do_copy (3, hd->found.kr->fname, kb,
533                   hd->found.offset, hd->found.n_packets );
534     if (!rc) {
535       if (kr_offtbl)
536         {
537           update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
538         }
539       /* better reset the found info */
540       hd->found.kr = NULL;
541       hd->found.offset = 0;
542     }
543     return rc;
544 }
545
546 int
547 keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb)
548 {
549     int rc;
550     const char *fname;
551
552     if (!hd)
553         fname = NULL;
554     else if (hd->found.kr)
555       {
556         fname = hd->found.kr->fname;
557         if (hd->found.kr->read_only)
558           return gpg_error (GPG_ERR_EACCES);
559       }
560     else if (hd->current.kr)
561       {
562         fname = hd->current.kr->fname;
563         if (hd->current.kr->read_only)
564           return gpg_error (GPG_ERR_EACCES);
565       }
566     else
567         fname = hd->resource? hd->resource->fname:NULL;
568
569     if (!fname)
570         return G10ERR_GENERAL;
571
572     /* Close this one otherwise we will lose the position for
573      * a next search.  Fixme: it would be better to adjust the position
574      * after the write opertions.
575      */
576     iobuf_close (hd->current.iobuf);
577     hd->current.iobuf = NULL;
578
579     /* do the insert */
580     rc = do_copy (1, fname, kb, 0, 0 );
581     if (!rc && kr_offtbl)
582       {
583         update_offset_hash_table_from_kb (kr_offtbl, kb, 0);
584       }
585
586     return rc;
587 }
588
589
590 int
591 keyring_delete_keyblock (KEYRING_HANDLE hd)
592 {
593     int rc;
594
595     if (!hd->found.kr)
596         return -1; /* no successful prior search */
597
598     if (hd->found.kr->read_only)
599       return gpg_error (GPG_ERR_EACCES);
600
601     if (!hd->found.n_packets) {
602         /* need to know the number of packets - do a dummy get_keyblock*/
603         rc = keyring_get_keyblock (hd, NULL);
604         if (rc) {
605             log_error ("re-reading keyblock failed: %s\n", g10_errstr (rc));
606             return rc;
607         }
608         if (!hd->found.n_packets)
609             BUG ();
610     }
611
612     /* close this one otherwise we will lose the position for
613      * a next search.  Fixme: it would be better to adjust the position
614      * after the write opertions.
615      */
616     iobuf_close (hd->current.iobuf);
617     hd->current.iobuf = NULL;
618
619     /* do the delete */
620     rc = do_copy (2, hd->found.kr->fname, NULL,
621                   hd->found.offset, hd->found.n_packets );
622     if (!rc) {
623         /* better reset the found info */
624         hd->found.kr = NULL;
625         hd->found.offset = 0;
626         /* Delete is a rare operations, so we don't remove the keys
627          * from the offset table */
628     }
629     return rc;
630 }
631
632
633 \f
634 /*
635  * Start the next search on this handle right at the beginning
636  */
637 int
638 keyring_search_reset (KEYRING_HANDLE hd)
639 {
640     assert (hd);
641
642     hd->current.kr = NULL;
643     iobuf_close (hd->current.iobuf);
644     hd->current.iobuf = NULL;
645     hd->current.eof = 0;
646     hd->current.error = 0;
647
648     hd->found.kr = NULL;
649     hd->found.offset = 0;
650     return 0;
651 }
652
653
654 static int
655 prepare_search (KEYRING_HANDLE hd)
656 {
657     if (hd->current.error)
658         return hd->current.error; /* still in error state */
659
660     if (hd->current.kr && !hd->current.eof) {
661         if ( !hd->current.iobuf )
662             return G10ERR_GENERAL; /* position invalid after a modify */
663         return 0; /* okay */
664     }
665
666     if (!hd->current.kr && hd->current.eof)
667         return -1; /* still EOF */
668
669     if (!hd->current.kr) { /* start search with first keyring */
670         hd->current.kr = hd->resource;
671         if (!hd->current.kr) {
672             hd->current.eof = 1;
673             return -1; /* keyring not available */
674         }
675         assert (!hd->current.iobuf);
676     }
677     else { /* EOF */
678         iobuf_close (hd->current.iobuf);
679         hd->current.iobuf = NULL;
680         hd->current.kr = NULL;
681         hd->current.eof = 1;
682         return -1;
683     }
684
685     hd->current.eof = 0;
686     hd->current.iobuf = iobuf_open (hd->current.kr->fname);
687     if (!hd->current.iobuf)
688       {
689         hd->current.error = gpg_error_from_syserror ();
690         log_error(_("can't open '%s'\n"), hd->current.kr->fname );
691         return hd->current.error;
692       }
693
694     return 0;
695 }
696
697 \f
698 /* A map of the all characters valid used for word_match()
699  * Valid characters are in in this table converted to uppercase.
700  * because the upper 128 bytes have special meaning, we assume
701  * that they are all valid.
702  * Note: We must use numerical values here in case that this program
703  * will be converted to those little blue HAL9000s with their strange
704  * EBCDIC character set (user ids are UTF-8).
705  * wk 2000-04-13: Hmmm, does this really make sense, given the fact that
706  * we can run gpg now on a S/390 running GNU/Linux, where the code
707  * translation is done by the device drivers?
708  */
709 static const byte word_match_chars[256] = {
710   /* 00 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711   /* 08 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712   /* 10 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713   /* 18 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714   /* 20 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715   /* 28 */  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716   /* 30 */  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
717   /* 38 */  0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718   /* 40 */  0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
719   /* 48 */  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
720   /* 50 */  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
721   /* 58 */  0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
722   /* 60 */  0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
723   /* 68 */  0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
724   /* 70 */  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
725   /* 78 */  0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
726   /* 80 */  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
727   /* 88 */  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
728   /* 90 */  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
729   /* 98 */  0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
730   /* a0 */  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
731   /* a8 */  0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
732   /* b0 */  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
733   /* b8 */  0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
734   /* c0 */  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
735   /* c8 */  0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
736   /* d0 */  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
737   /* d8 */  0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
738   /* e0 */  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
739   /* e8 */  0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
740   /* f0 */  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
741   /* f8 */  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
742 };
743
744 /****************
745  * Do a word match (original user id starts with a '+').
746  * The pattern is already tokenized to a more suitable format:
747  * There are only the real words in it delimited by one space
748  * and all converted to uppercase.
749  *
750  * Returns: 0 if all words match.
751  *
752  * Note: This algorithm is a straightforward one and not very
753  *       fast.  It works for UTF-8 strings.  The uidlen should
754  *       be removed but due to the fact that old versions of
755  *       pgp don't use UTF-8 we still use the length; this should
756  *       be fixed in parse-packet (and replace \0 by some special
757  *       UTF-8 encoding)
758  */
759 static int
760 word_match( const byte *uid, size_t uidlen, const byte *pattern )
761 {
762     size_t wlen, n;
763     const byte *p;
764     const byte *s;
765
766     for( s=pattern; *s; ) {
767         do {
768             /* skip leading delimiters */
769             while( uidlen && !word_match_chars[*uid] )
770                 uid++, uidlen--;
771             /* get length of the word */
772             n = uidlen; p = uid;
773             while( n && word_match_chars[*p] )
774                 p++, n--;
775             wlen = p - uid;
776             /* and compare against the current word from pattern */
777             for(n=0, p=uid; n < wlen && s[n] != ' ' && s[n] ; n++, p++ ) {
778                 if( word_match_chars[*p] != s[n] )
779                     break;
780             }
781             if( n == wlen && (s[n] == ' ' || !s[n]) )
782                 break; /* found */
783             uid += wlen;
784             uidlen -= wlen;
785         } while( uidlen );
786         if( !uidlen )
787             return -1; /* not found */
788
789         /* advance to next word in pattern */
790         for(; *s != ' ' && *s ; s++ )
791             ;
792         if( *s )
793             s++ ;
794     }
795     return 0; /* found */
796 }
797
798 /****************
799  * prepare word word_match; that is parse the name and
800  * build the pattern.
801  * caller has to free the returned pattern
802  */
803 static char*
804 prepare_word_match (const byte *name)
805 {
806     byte *pattern, *p;
807     int c;
808
809     /* the original length is always enough for the pattern */
810     p = pattern = xmalloc(strlen(name)+1);
811     do {
812         /* skip leading delimiters */
813         while( *name && !word_match_chars[*name] )
814             name++;
815         /* copy as long as we don't have a delimiter and convert
816          * to uppercase.
817          * fixme: how can we handle utf8 uppercasing */
818         for( ; *name &&  (c=word_match_chars[*name]); name++ )
819             *p++ = c;
820         *p++ = ' '; /* append pattern delimiter */
821     } while( *name );
822     p[-1] = 0; /* replace last pattern delimiter by EOS */
823
824     return pattern;
825 }
826
827
828
829
830 static int
831 compare_name (int mode, const char *name, const char *uid, size_t uidlen)
832 {
833     int i;
834     const char *s, *se;
835
836     if (mode == KEYDB_SEARCH_MODE_EXACT) {
837         for (i=0; name[i] && uidlen; i++, uidlen--)
838             if (uid[i] != name[i])
839                 break;
840         if (!uidlen && !name[i])
841             return 0; /* found */
842     }
843     else if (mode == KEYDB_SEARCH_MODE_SUBSTR) {
844         if (ascii_memistr( uid, uidlen, name ))
845             return 0;
846     }
847     else if (   mode == KEYDB_SEARCH_MODE_MAIL
848              || mode == KEYDB_SEARCH_MODE_MAILSUB
849              || mode == KEYDB_SEARCH_MODE_MAILEND) {
850         for (i=0, s= uid; i < uidlen && *s != '<'; s++, i++)
851             ;
852         if (i < uidlen)  {
853             /* skip opening delim and one char and look for the closing one*/
854             s++; i++;
855             for (se=s+1, i++; i < uidlen && *se != '>'; se++, i++)
856                 ;
857             if (i < uidlen) {
858                 i = se - s;
859                 if (mode == KEYDB_SEARCH_MODE_MAIL) {
860                     if( strlen(name)-2 == i
861                         && !ascii_memcasecmp( s, name+1, i) )
862                         return 0;
863                 }
864                 else if (mode == KEYDB_SEARCH_MODE_MAILSUB) {
865                     if( ascii_memistr( s, i, name ) )
866                         return 0;
867                 }
868                 else { /* email from end */
869                     /* nyi */
870                 }
871             }
872         }
873     }
874     else if (mode == KEYDB_SEARCH_MODE_WORDS)
875         return word_match (uid, uidlen, name);
876     else
877         BUG();
878
879     return -1; /* not found */
880 }
881
882 \f
883 /*
884  * Search through the keyring(s), starting at the current position,
885  * for a keyblock which contains one of the keys described in the DESC array.
886  */
887 int
888 keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
889                 size_t ndesc, size_t *descindex)
890 {
891   int rc;
892   PACKET pkt;
893   int save_mode;
894   off_t offset, main_offset;
895   size_t n;
896   int need_uid, need_words, need_keyid, need_fpr, any_skip;
897   int pk_no, uid_no;
898   int initial_skip;
899   int use_offtbl;
900   PKT_user_id *uid = NULL;
901   PKT_public_key *pk = NULL;
902   u32 aki[2];
903
904   /* figure out what information we need */
905   need_uid = need_words = need_keyid = need_fpr = any_skip = 0;
906   for (n=0; n < ndesc; n++)
907     {
908       switch (desc[n].mode)
909         {
910         case KEYDB_SEARCH_MODE_EXACT:
911         case KEYDB_SEARCH_MODE_SUBSTR:
912         case KEYDB_SEARCH_MODE_MAIL:
913         case KEYDB_SEARCH_MODE_MAILSUB:
914         case KEYDB_SEARCH_MODE_MAILEND:
915           need_uid = 1;
916           break;
917         case KEYDB_SEARCH_MODE_WORDS:
918           need_uid = 1;
919           need_words = 1;
920           break;
921         case KEYDB_SEARCH_MODE_SHORT_KID:
922         case KEYDB_SEARCH_MODE_LONG_KID:
923           need_keyid = 1;
924           break;
925         case KEYDB_SEARCH_MODE_FPR16:
926         case KEYDB_SEARCH_MODE_FPR20:
927         case KEYDB_SEARCH_MODE_FPR:
928           need_fpr = 1;
929           break;
930         case KEYDB_SEARCH_MODE_FIRST:
931           /* always restart the search in this mode */
932           keyring_search_reset (hd);
933           break;
934         default: break;
935         }
936       if (desc[n].skipfnc)
937         {
938           any_skip = 1;
939           need_keyid = 1;
940         }
941     }
942
943   rc = prepare_search (hd);
944   if (rc)
945     return rc;
946
947   use_offtbl = !!kr_offtbl;
948   if (!use_offtbl)
949     ;
950   else if (!kr_offtbl_ready)
951     need_keyid = 1;
952   else if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID)
953     {
954       struct off_item *oi;
955
956       oi = lookup_offset_hash_table (kr_offtbl, desc[0].u.kid);
957       if (!oi)
958         { /* We know that we don't have this key */
959           hd->found.kr = NULL;
960           hd->current.eof = 1;
961           return -1;
962         }
963       /* We could now create a positive search status and return.
964        * However the problem is that another instance of gpg may
965        * have changed the keyring so that the offsets are not valid
966        * anymore - therefore we don't do it
967        */
968     }
969
970   if (need_words)
971     {
972       const char *name = NULL;
973
974       log_debug ("word search mode does not yet work\n");
975       /* FIXME: here is a long standing bug in our function and in addition we
976          just use the first search description */
977       for (n=0; n < ndesc && !name; n++)
978         {
979           if (desc[n].mode == KEYDB_SEARCH_MODE_WORDS)
980             name = desc[n].u.name;
981         }
982       assert (name);
983       if ( !hd->word_match.name || strcmp (hd->word_match.name, name) )
984         {
985           /* name changed */
986           xfree (hd->word_match.name);
987           xfree (hd->word_match.pattern);
988           hd->word_match.name = xstrdup (name);
989           hd->word_match.pattern = prepare_word_match (name);
990         }
991       /*  name = hd->word_match.pattern; */
992     }
993
994   init_packet(&pkt);
995   save_mode = set_packet_list_mode(0);
996
997   hd->found.kr = NULL;
998   main_offset = 0;
999   pk_no = uid_no = 0;
1000   initial_skip = 1; /* skip until we see the start of a keyblock */
1001   while (!(rc=search_packet (hd->current.iobuf, &pkt, &offset, need_uid)))
1002     {
1003       byte afp[MAX_FINGERPRINT_LEN];
1004       size_t an;
1005
1006       if (pkt.pkttype == PKT_PUBLIC_KEY  || pkt.pkttype == PKT_SECRET_KEY)
1007         {
1008           main_offset = offset;
1009           pk_no = uid_no = 0;
1010           initial_skip = 0;
1011         }
1012       if (initial_skip)
1013         {
1014           free_packet (&pkt);
1015           continue;
1016         }
1017
1018       pk = NULL;
1019       uid = NULL;
1020       if (   pkt.pkttype == PKT_PUBLIC_KEY
1021              || pkt.pkttype == PKT_PUBLIC_SUBKEY
1022              || pkt.pkttype == PKT_SECRET_KEY
1023              || pkt.pkttype == PKT_SECRET_SUBKEY)
1024         {
1025           pk = pkt.pkt.public_key;
1026           ++pk_no;
1027
1028           if (need_fpr) {
1029             fingerprint_from_pk (pk, afp, &an);
1030             while (an < 20) /* fill up to 20 bytes */
1031               afp[an++] = 0;
1032           }
1033           if (need_keyid)
1034             keyid_from_pk (pk, aki);
1035
1036           if (use_offtbl && !kr_offtbl_ready)
1037             update_offset_hash_table (kr_offtbl, aki, main_offset);
1038         }
1039       else if (pkt.pkttype == PKT_USER_ID)
1040         {
1041           uid = pkt.pkt.user_id;
1042           ++uid_no;
1043         }
1044
1045       for (n=0; n < ndesc; n++)
1046         {
1047           switch (desc[n].mode) {
1048           case KEYDB_SEARCH_MODE_NONE:
1049             BUG ();
1050             break;
1051           case KEYDB_SEARCH_MODE_EXACT:
1052           case KEYDB_SEARCH_MODE_SUBSTR:
1053           case KEYDB_SEARCH_MODE_MAIL:
1054           case KEYDB_SEARCH_MODE_MAILSUB:
1055           case KEYDB_SEARCH_MODE_MAILEND:
1056           case KEYDB_SEARCH_MODE_WORDS:
1057             if ( uid && !compare_name (desc[n].mode,
1058                                        desc[n].u.name,
1059                                        uid->name, uid->len))
1060               goto found;
1061             break;
1062
1063           case KEYDB_SEARCH_MODE_SHORT_KID:
1064             if (pk && desc[n].u.kid[1] == aki[1])
1065               goto found;
1066             break;
1067           case KEYDB_SEARCH_MODE_LONG_KID:
1068             if (pk && desc[n].u.kid[0] == aki[0]
1069                 && desc[n].u.kid[1] == aki[1])
1070               goto found;
1071             break;
1072           case KEYDB_SEARCH_MODE_FPR16:
1073             if (pk && !memcmp (desc[n].u.fpr, afp, 16))
1074               goto found;
1075             break;
1076           case KEYDB_SEARCH_MODE_FPR20:
1077           case KEYDB_SEARCH_MODE_FPR:
1078             if (pk && !memcmp (desc[n].u.fpr, afp, 20))
1079               goto found;
1080             break;
1081           case KEYDB_SEARCH_MODE_FIRST:
1082             if (pk)
1083               goto found;
1084             break;
1085           case KEYDB_SEARCH_MODE_NEXT:
1086             if (pk)
1087               goto found;
1088             break;
1089           default:
1090             rc = G10ERR_INV_ARG;
1091             goto found;
1092           }
1093         }
1094       free_packet (&pkt);
1095       continue;
1096     found:
1097       /* Record which desc we matched on.  Note this value is only
1098          meaningful if this function returns with no errors. */
1099       if(descindex)
1100         *descindex=n;
1101       for (n=any_skip?0:ndesc; n < ndesc; n++)
1102         {
1103           if (desc[n].skipfnc
1104               && desc[n].skipfnc (desc[n].skipfncvalue, aki, uid))
1105             break;
1106         }
1107       if (n == ndesc)
1108         goto real_found;
1109       free_packet (&pkt);
1110     }
1111  real_found:
1112   if (!rc)
1113     {
1114       hd->found.offset = main_offset;
1115       hd->found.kr = hd->current.kr;
1116       hd->found.pk_no = pk? pk_no : 0;
1117       hd->found.uid_no = uid? uid_no : 0;
1118     }
1119   else if (rc == -1)
1120     {
1121       hd->current.eof = 1;
1122       /* if we scanned all keyrings, we are sure that
1123        * all known key IDs are in our offtbl, mark that. */
1124       if (use_offtbl && !kr_offtbl_ready)
1125         {
1126           KR_NAME kr;
1127
1128           /* First set the did_full_scan flag for this keyring.  */
1129           for (kr=kr_names; kr; kr = kr->next)
1130             {
1131               if (hd->resource == kr)
1132                 {
1133                   kr->did_full_scan = 1;
1134                   break;
1135                 }
1136             }
1137           /* Then check whether all flags are set and if so, mark the
1138              offtbl ready */
1139           for (kr=kr_names; kr; kr = kr->next)
1140             {
1141               if (!kr->did_full_scan)
1142                 break;
1143             }
1144           if (!kr)
1145             kr_offtbl_ready = 1;
1146         }
1147     }
1148   else
1149     hd->current.error = rc;
1150
1151   free_packet(&pkt);
1152   set_packet_list_mode(save_mode);
1153   return rc;
1154 }
1155
1156
1157 static int
1158 create_tmp_file (const char *template,
1159                  char **r_bakfname, char **r_tmpfname, IOBUF *r_fp)
1160 {
1161   char *bakfname, *tmpfname;
1162   mode_t oldmask;
1163
1164   *r_bakfname = NULL;
1165   *r_tmpfname = NULL;
1166
1167 # ifdef USE_ONLY_8DOT3
1168   /* Here is another Windoze bug?:
1169    * you cant rename("pubring.gpg.tmp", "pubring.gpg");
1170    * but        rename("pubring.gpg.tmp", "pubring.aaa");
1171    * works.  So we replace .gpg by .bak or .tmp
1172    */
1173   if (strlen (template) > 4
1174       && !strcmp (template+strlen(template)-4, EXTSEP_S GPGEXT_GPG) )
1175     {
1176       bakfname = xmalloc (strlen (template) + 1);
1177       strcpy (bakfname, template);
1178       strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak");
1179
1180       tmpfname = xmalloc (strlen( template ) + 1 );
1181       strcpy (tmpfname,template);
1182       strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp");
1183     }
1184     else
1185       { /* file does not end with gpg; hmmm */
1186         bakfname = xmalloc (strlen( template ) + 5);
1187         strcpy (stpcpy(bakfname, template), EXTSEP_S "bak");
1188
1189         tmpfname = xmalloc (strlen( template ) + 5);
1190         strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp");
1191     }
1192 # else /* Posix file names */
1193     bakfname = xmalloc (strlen( template ) + 2);
1194     strcpy (stpcpy (bakfname,template),"~");
1195
1196     tmpfname = xmalloc (strlen( template ) + 5);
1197     strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp");
1198 # endif /* Posix filename */
1199
1200     /* Create the temp file with limited access.  Note that the umask
1201        call is not anymore needed because iobuf_create now takes care
1202        of it.  However, it does not harm and thus we keep it.  */
1203     oldmask=umask(077);
1204     if (is_secured_filename (tmpfname))
1205       {
1206         *r_fp = NULL;
1207         gpg_err_set_errno (EPERM);
1208       }
1209     else
1210       *r_fp = iobuf_create (tmpfname, 1);
1211     umask(oldmask);
1212     if (!*r_fp)
1213       {
1214         int rc = gpg_error_from_syserror ();
1215         log_error(_("can't create '%s': %s\n"), tmpfname, strerror(errno) );
1216         xfree (tmpfname);
1217         xfree (bakfname);
1218         return rc;
1219       }
1220
1221     *r_bakfname = bakfname;
1222     *r_tmpfname = tmpfname;
1223     return 0;
1224 }
1225
1226
1227 static int
1228 rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname)
1229 {
1230   int rc = 0;
1231
1232   /* Invalidate close caches.  */
1233   if (iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)tmpfname ))
1234     {
1235       rc = gpg_error_from_syserror ();
1236       goto fail;
1237     }
1238   iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)bakfname );
1239   iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname );
1240
1241   /* First make a backup file. */
1242 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1243   gnupg_remove (bakfname);
1244 #endif
1245   if (rename (fname, bakfname) )
1246     {
1247       rc = gpg_error_from_syserror ();
1248       log_error ("renaming '%s' to '%s' failed: %s\n",
1249                  fname, bakfname, strerror(errno) );
1250       return rc;
1251     }
1252
1253   /* then rename the file */
1254 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
1255   gnupg_remove( fname );
1256 #endif
1257   if (rename (tmpfname, fname) )
1258     {
1259       rc = gpg_error_from_syserror ();
1260       log_error (_("renaming '%s' to '%s' failed: %s\n"),
1261                  tmpfname, fname, strerror(errno) );
1262       register_secured_file (fname);
1263       goto fail;
1264     }
1265
1266   /* Now make sure the file has the same permissions as the original */
1267
1268 #ifndef HAVE_DOSISH_SYSTEM
1269   {
1270     struct stat statbuf;
1271
1272     statbuf.st_mode=S_IRUSR | S_IWUSR;
1273
1274     if (!stat (bakfname, &statbuf) && !chmod (fname, statbuf.st_mode))
1275       ;
1276     else
1277       log_error ("WARNING: unable to restore permissions to '%s': %s",
1278                  fname, strerror(errno));
1279   }
1280 #endif
1281
1282   return 0;
1283
1284  fail:
1285   return rc;
1286 }
1287
1288
1289 static int
1290 write_keyblock (IOBUF fp, KBNODE keyblock)
1291 {
1292   KBNODE kbctx = NULL, node;
1293   int rc;
1294
1295   while ( (node = walk_kbnode (keyblock, &kbctx, 0)) )
1296     {
1297       if (node->pkt->pkttype == PKT_RING_TRUST)
1298         continue; /* we write it later on our own */
1299
1300       if ( (rc = build_packet (fp, node->pkt) ))
1301         {
1302           log_error ("build_packet(%d) failed: %s\n",
1303                      node->pkt->pkttype, g10_errstr(rc) );
1304           return rc;
1305         }
1306       if (node->pkt->pkttype == PKT_SIGNATURE)
1307         { /* always write a signature cache packet */
1308           PKT_signature *sig = node->pkt->pkt.signature;
1309           unsigned int cacheval = 0;
1310
1311           if (sig->flags.checked)
1312             {
1313               cacheval |= 1;
1314               if (sig->flags.valid)
1315                 cacheval |= 2;
1316             }
1317           iobuf_put (fp, 0xb0); /* old style packet 12, 1 byte len*/
1318           iobuf_put (fp, 2);    /* 2 bytes */
1319           iobuf_put (fp, 0);    /* unused */
1320           if (iobuf_put (fp, cacheval))
1321             {
1322               rc = gpg_error_from_syserror ();
1323               log_error ("writing sigcache packet failed\n");
1324               return rc;
1325             }
1326         }
1327     }
1328   return 0;
1329 }
1330
1331 /*
1332  * Walk over all public keyrings, check the signatures and replace the
1333  * keyring with a new one where the signature cache is then updated.
1334  * This is only done for the public keyrings.
1335  */
1336 int
1337 keyring_rebuild_cache (void *token,int noisy)
1338 {
1339   KEYRING_HANDLE hd;
1340   KEYDB_SEARCH_DESC desc;
1341   KBNODE keyblock = NULL, node;
1342   const char *lastresname = NULL, *resname;
1343   IOBUF tmpfp = NULL;
1344   char *tmpfilename = NULL;
1345   char *bakfilename = NULL;
1346   int rc;
1347   ulong count = 0, sigcount = 0;
1348
1349   hd = keyring_new (token);
1350   memset (&desc, 0, sizeof desc);
1351   desc.mode = KEYDB_SEARCH_MODE_FIRST;
1352
1353   rc=keyring_lock (hd, 1);
1354   if(rc)
1355     goto leave;
1356
1357   while ( !(rc = keyring_search (hd, &desc, 1, NULL)) )
1358     {
1359       desc.mode = KEYDB_SEARCH_MODE_NEXT;
1360       resname = keyring_get_resource_name (hd);
1361       if (lastresname != resname )
1362         { /* we have switched to a new keyring - commit changes */
1363           if (tmpfp)
1364             {
1365               if (iobuf_close (tmpfp))
1366                 {
1367                   rc = gpg_error_from_syserror ();
1368                   log_error ("error closing '%s': %s\n",
1369                              tmpfilename, strerror (errno));
1370                   goto leave;
1371                 }
1372               /* because we have switched resources, we can be sure that
1373                * the original file is closed */
1374               tmpfp = NULL;
1375             }
1376           rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
1377                                              lastresname) : 0;
1378           xfree (tmpfilename);  tmpfilename = NULL;
1379           xfree (bakfilename);  bakfilename = NULL;
1380           if (rc)
1381             goto leave;
1382           lastresname = resname;
1383           if (noisy && !opt.quiet)
1384             log_info (_("caching keyring '%s'\n"), resname);
1385           rc = create_tmp_file (resname, &bakfilename, &tmpfilename, &tmpfp);
1386           if (rc)
1387             goto leave;
1388         }
1389
1390       release_kbnode (keyblock);
1391       rc = keyring_get_keyblock (hd, &keyblock);
1392       if (rc)
1393         {
1394           log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc));
1395           goto leave;
1396         }
1397       if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
1398         {
1399           /* We had a few reports about corrupted keyrings; if we have
1400              been called directly from the command line we delete such
1401              a keyblock instead of bailing out.  */
1402           log_error ("unexpected keyblock found (pkttype=%d)%s\n",
1403                      keyblock->pkt->pkttype, noisy? " - deleted":"");
1404           if (noisy)
1405             continue;
1406           log_info ("Hint: backup your keys and try running '%s'\n",
1407                     "gpg --rebuild-keydb-caches");
1408           rc = gpg_error (GPG_ERR_INV_KEYRING);
1409           goto leave;
1410         }
1411
1412       /* check all signature to set the signature's cache flags */
1413       for (node=keyblock; node; node=node->next)
1414         {
1415           /* Note that this doesn't cache the result of a revocation
1416              issued by a designated revoker.  This is because the pk
1417              in question does not carry the revkeys as we haven't
1418              merged the key and selfsigs.  It is questionable whether
1419              this matters very much since there are very very few
1420              designated revoker revocation packets out there. */
1421
1422           if (node->pkt->pkttype == PKT_SIGNATURE)
1423             {
1424               PKT_signature *sig=node->pkt->pkt.signature;
1425
1426               if(!opt.no_sig_cache && sig->flags.checked && sig->flags.valid
1427                  && (openpgp_md_test_algo(sig->digest_algo)
1428                      || openpgp_pk_test_algo(sig->pubkey_algo)))
1429                 sig->flags.checked=sig->flags.valid=0;
1430               else
1431                 check_key_signature (keyblock, node, NULL);
1432
1433               sigcount++;
1434             }
1435         }
1436
1437       /* write the keyblock to the temporary file */
1438       rc = write_keyblock (tmpfp, keyblock);
1439       if (rc)
1440         goto leave;
1441
1442       if ( !(++count % 50) && noisy && !opt.quiet)
1443         log_info(_("%lu keys cached so far (%lu signatures)\n"),
1444                  count, sigcount );
1445
1446     } /* end main loop */
1447   if (rc == -1)
1448     rc = 0;
1449   if (rc)
1450     {
1451       log_error ("keyring_search failed: %s\n", g10_errstr(rc));
1452       goto leave;
1453     }
1454   if(noisy || opt.verbose)
1455     log_info(_("%lu keys cached (%lu signatures)\n"), count, sigcount );
1456   if (tmpfp)
1457     {
1458       if (iobuf_close (tmpfp))
1459         {
1460           rc = gpg_error_from_syserror ();
1461           log_error ("error closing '%s': %s\n",
1462                      tmpfilename, strerror (errno));
1463           goto leave;
1464         }
1465       /* because we have switched resources, we can be sure that
1466        * the original file is closed */
1467       tmpfp = NULL;
1468     }
1469   rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
1470                                      lastresname) : 0;
1471   xfree (tmpfilename);  tmpfilename = NULL;
1472   xfree (bakfilename);  bakfilename = NULL;
1473
1474  leave:
1475   if (tmpfp)
1476     iobuf_cancel (tmpfp);
1477   xfree (tmpfilename);
1478   xfree (bakfilename);
1479   release_kbnode (keyblock);
1480   keyring_lock (hd, 0);
1481   keyring_release (hd);
1482   return rc;
1483 }
1484
1485 \f
1486 /****************
1487  * Perform insert/delete/update operation.
1488  * mode 1 = insert
1489  *      2 = delete
1490  *      3 = update
1491  */
1492 static int
1493 do_copy (int mode, const char *fname, KBNODE root,
1494          off_t start_offset, unsigned int n_packets )
1495 {
1496     IOBUF fp, newfp;
1497     int rc=0;
1498     char *bakfname = NULL;
1499     char *tmpfname = NULL;
1500
1501     /* Open the source file. Because we do a rename, we have to check the
1502        permissions of the file */
1503     if (access (fname, W_OK))
1504       return gpg_error_from_syserror ();
1505
1506     fp = iobuf_open (fname);
1507     if (mode == 1 && !fp && errno == ENOENT) {
1508         /* insert mode but file does not exist: create a new file */
1509         KBNODE kbctx, node;
1510         mode_t oldmask;
1511
1512         oldmask=umask(077);
1513         if (is_secured_filename (fname)) {
1514             newfp = NULL;
1515             gpg_err_set_errno (EPERM);
1516         }
1517         else
1518             newfp = iobuf_create (fname, 1);
1519         umask(oldmask);
1520         if( !newfp )
1521           {
1522             rc = gpg_error_from_syserror ();
1523             log_error (_("can't create '%s': %s\n"), fname, strerror(errno));
1524             return rc;
1525           }
1526         if( !opt.quiet )
1527             log_info(_("%s: keyring created\n"), fname );
1528
1529         kbctx=NULL;
1530         while ( (node = walk_kbnode( root, &kbctx, 0 )) ) {
1531             if( (rc = build_packet( newfp, node->pkt )) ) {
1532                 log_error("build_packet(%d) failed: %s\n",
1533                             node->pkt->pkttype, g10_errstr(rc) );
1534                 iobuf_cancel(newfp);
1535                 return rc;
1536             }
1537         }
1538         if( iobuf_close(newfp) ) {
1539             rc = gpg_error_from_syserror ();
1540             log_error ("%s: close failed: %s\n", fname, strerror(errno));
1541             return rc;
1542         }
1543         return 0; /* ready */
1544     }
1545
1546     if( !fp )
1547       {
1548         rc = gpg_error_from_syserror ();
1549         log_error(_("can't open '%s': %s\n"), fname, strerror(errno) );
1550         goto leave;
1551       }
1552
1553     /* Create the new file.  */
1554     rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
1555     if (rc) {
1556         iobuf_close(fp);
1557         goto leave;
1558     }
1559
1560     if( mode == 1 ) { /* insert */
1561         /* copy everything to the new file */
1562         rc = copy_all_packets (fp, newfp);
1563         if( rc != -1 ) {
1564             log_error("%s: copy to '%s' failed: %s\n",
1565                       fname, tmpfname, g10_errstr(rc) );
1566             iobuf_close(fp);
1567             iobuf_cancel(newfp);
1568             goto leave;
1569         }
1570         rc = 0;
1571     }
1572
1573     if( mode == 2 || mode == 3 ) { /* delete or update */
1574         /* copy first part to the new file */
1575         rc = copy_some_packets( fp, newfp, start_offset );
1576         if( rc ) { /* should never get EOF here */
1577             log_error ("%s: copy to '%s' failed: %s\n",
1578                        fname, tmpfname, g10_errstr(rc) );
1579             iobuf_close(fp);
1580             iobuf_cancel(newfp);
1581             goto leave;
1582         }
1583         /* skip this keyblock */
1584         assert( n_packets );
1585         rc = skip_some_packets( fp, n_packets );
1586         if( rc ) {
1587             log_error("%s: skipping %u packets failed: %s\n",
1588                             fname, n_packets, g10_errstr(rc));
1589             iobuf_close(fp);
1590             iobuf_cancel(newfp);
1591             goto leave;
1592         }
1593     }
1594
1595     if( mode == 1 || mode == 3 ) { /* insert or update */
1596         rc = write_keyblock (newfp, root);
1597         if (rc) {
1598           iobuf_close(fp);
1599           iobuf_cancel(newfp);
1600           goto leave;
1601         }
1602     }
1603
1604     if( mode == 2 || mode == 3 ) { /* delete or update */
1605         /* copy the rest */
1606         rc = copy_all_packets( fp, newfp );
1607         if( rc != -1 ) {
1608             log_error("%s: copy to '%s' failed: %s\n",
1609                       fname, tmpfname, g10_errstr(rc) );
1610             iobuf_close(fp);
1611             iobuf_cancel(newfp);
1612             goto leave;
1613         }
1614         rc = 0;
1615     }
1616
1617     /* close both files */
1618     if( iobuf_close(fp) ) {
1619         rc = gpg_error_from_syserror ();
1620         log_error("%s: close failed: %s\n", fname, strerror(errno) );
1621         goto leave;
1622     }
1623     if( iobuf_close(newfp) ) {
1624         rc = gpg_error_from_syserror ();
1625         log_error("%s: close failed: %s\n", tmpfname, strerror(errno) );
1626         goto leave;
1627     }
1628
1629     rc = rename_tmp_file (bakfname, tmpfname, fname);
1630
1631   leave:
1632     xfree(bakfname);
1633     xfree(tmpfname);
1634     return rc;
1635 }