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