LCOV - code coverage report
Current view: top level - g10 - keyring.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 450 811 55.5 %
Date: 2016-09-12 13:01:59 Functions: 22 28 78.6 %

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

Generated by: LCOV version 1.11