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