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