8004e375295ec58393cbcc1fc1d4d18ea6a186bd
[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, uid))
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               /* Note that this doesn't cache the result of a
1381                  revocation issued by a designated revoker.  This is
1382                  because the pk in question does not carry the revkeys
1383                  as we haven't merged the key and selfsigs.  It is
1384                  questionable whether this matters very much since
1385                  there are very very few designated revoker revocation
1386                  packets out there. */
1387               check_key_signature (keyblock, node, NULL);
1388               sigcount++;
1389             }
1390         }
1391       
1392       /* write the keyblock to the temporary file */
1393       rc = write_keyblock (tmpfp, keyblock);
1394       if (rc)
1395         goto leave;
1396
1397       if ( !(++count % 50) && !opt.quiet)
1398         log_info(_("%lu keys checked so far (%lu signatures)\n"),
1399                  count, sigcount );
1400
1401     } /* end main loop */ 
1402   if (rc == -1)
1403     rc = 0;
1404   if (rc) 
1405     {
1406       log_error ("keyring_search failed: %s\n", g10_errstr(rc));
1407       goto leave;
1408     }
1409   log_info(_("%lu keys checked (%lu signatures)\n"), count, sigcount );
1410   if (tmpfp)
1411     {
1412       if (iobuf_close (tmpfp))
1413         {
1414           log_error ("error closing `%s': %s\n",
1415                      tmpfilename, strerror (errno));
1416           rc = G10ERR_CLOSE_FILE;
1417           goto leave;
1418         }
1419       /* because we have switched resources, we can be sure that
1420        * the original file is closed */
1421       tmpfp = NULL;
1422     }
1423   rc = lastresname? rename_tmp_file (bakfilename, tmpfilename,
1424                                      lastresname, 0) : 0;
1425   m_free (tmpfilename);  tmpfilename = NULL;
1426   m_free (bakfilename);  bakfilename = NULL;
1427
1428  leave:
1429   if (tmpfp)
1430     iobuf_cancel (tmpfp);
1431   m_free (tmpfilename);  
1432   m_free (bakfilename);  
1433   release_kbnode (keyblock);
1434   keyring_lock (hd, 0);
1435   keyring_release (hd);
1436   return rc;
1437 }
1438
1439 \f
1440 /****************
1441  * Perform insert/delete/update operation.
1442  * mode 1 = insert
1443  *      2 = delete
1444  *      3 = update
1445  */
1446 static int
1447 do_copy (int mode, const char *fname, KBNODE root, int secret,
1448          off_t start_offset, unsigned int n_packets )
1449 {
1450     IOBUF fp, newfp;
1451     int rc=0;
1452     char *bakfname = NULL;
1453     char *tmpfname = NULL;
1454
1455     /* Open the source file. Because we do a rname, we have to check the 
1456        permissions of the file */
1457     if (access (fname, W_OK))
1458       return G10ERR_WRITE_FILE;
1459
1460     fp = iobuf_open (fname);
1461     if (mode == 1 && !fp && errno == ENOENT) { 
1462         /* insert mode but file does not exist: create a new file */
1463         KBNODE kbctx, node;
1464         mode_t oldmask;
1465
1466         oldmask=umask(077);
1467         newfp = iobuf_create (fname);
1468         umask(oldmask);
1469         if( !newfp ) {
1470             log_error (_("%s: can't create: %s\n"),
1471                        fname, strerror(errno));
1472             return G10ERR_OPEN_FILE;
1473         }
1474         if( !opt.quiet )
1475             log_info(_("%s: keyring created\n"), fname );
1476
1477         kbctx=NULL;
1478         while ( (node = walk_kbnode( root, &kbctx, 0 )) ) {
1479             if( (rc = build_packet( newfp, node->pkt )) ) {
1480                 log_error("build_packet(%d) failed: %s\n",
1481                             node->pkt->pkttype, g10_errstr(rc) );
1482                 iobuf_cancel(newfp);
1483                 return G10ERR_WRITE_FILE;
1484             }
1485         }
1486         if( iobuf_close(newfp) ) {
1487             log_error ("%s: close failed: %s\n", fname, strerror(errno));
1488             return G10ERR_CLOSE_FILE;
1489         }
1490         return 0; /* ready */
1491     }
1492
1493     if( !fp ) {
1494         log_error ("%s: can't open: %s\n", fname, strerror(errno) );
1495         rc = G10ERR_OPEN_FILE;
1496         goto leave;
1497     }
1498
1499     /* create the new file */
1500     rc = create_tmp_file (fname, &bakfname, &tmpfname, &newfp);
1501     if (rc) {
1502         iobuf_close(fp);
1503         goto leave;
1504     }
1505     if( mode == 1 ) { /* insert */
1506         /* copy everything to the new file */
1507         rc = copy_all_packets (fp, newfp);
1508         if( rc != -1 ) {
1509             log_error("%s: copy to `%s' failed: %s\n",
1510                       fname, tmpfname, g10_errstr(rc) );
1511             iobuf_close(fp);
1512             iobuf_cancel(newfp);
1513             goto leave;
1514         }
1515         rc = 0;
1516     }
1517
1518     if( mode == 2 || mode == 3 ) { /* delete or update */
1519         /* copy first part to the new file */
1520         rc = copy_some_packets( fp, newfp, start_offset );
1521         if( rc ) { /* should never get EOF here */
1522             log_error ("%s: copy to `%s' failed: %s\n",
1523                        fname, tmpfname, g10_errstr(rc) );
1524             iobuf_close(fp);
1525             iobuf_cancel(newfp);
1526             goto leave;
1527         }
1528         /* skip this keyblock */
1529         assert( n_packets );
1530         rc = skip_some_packets( fp, n_packets );
1531         if( rc ) {
1532             log_error("%s: skipping %u packets failed: %s\n",
1533                             fname, n_packets, g10_errstr(rc));
1534             iobuf_close(fp);
1535             iobuf_cancel(newfp);
1536             goto leave;
1537         }
1538     }
1539
1540     if( mode == 1 || mode == 3 ) { /* insert or update */
1541         rc = write_keyblock (newfp, root);
1542         if (rc) {
1543           iobuf_close(fp);
1544           iobuf_cancel(newfp);
1545           goto leave;
1546         }
1547     }
1548
1549     if( mode == 2 || mode == 3 ) { /* delete or update */
1550         /* copy the rest */
1551         rc = copy_all_packets( fp, newfp );
1552         if( rc != -1 ) {
1553             log_error("%s: copy to `%s' failed: %s\n",
1554                       fname, tmpfname, g10_errstr(rc) );
1555             iobuf_close(fp);
1556             iobuf_cancel(newfp);
1557             goto leave;
1558         }
1559         rc = 0;
1560     }
1561
1562     /* close both files */
1563     if( iobuf_close(fp) ) {
1564         log_error("%s: close failed: %s\n", fname, strerror(errno) );
1565         rc = G10ERR_CLOSE_FILE;
1566         goto leave;
1567     }
1568     if( iobuf_close(newfp) ) {
1569         log_error("%s: close failed: %s\n", tmpfname, strerror(errno) );
1570         rc = G10ERR_CLOSE_FILE;
1571         goto leave;
1572     }
1573
1574     rc = rename_tmp_file (bakfname, tmpfname, fname, secret);
1575
1576   leave:
1577     m_free(bakfname);
1578     m_free(tmpfname);
1579     return rc;
1580 }