Line | Count | Source |
1 | | /* keydb.c - key database dispatcher |
2 | | * Copyright (C) 2001-2013 Free Software Foundation, Inc. |
3 | | * Copyright (C) 2001-2015 Werner Koch |
4 | | * Copyright (C) 2019,2024 g10 Code GmbH |
5 | | * |
6 | | * This file is part of GnuPG. |
7 | | * |
8 | | * GnuPG is free software; you can redistribute it and/or modify |
9 | | * it under the terms of the GNU General Public License as published by |
10 | | * the Free Software Foundation; either version 3 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * GnuPG is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
20 | | * SPDX-License-Identifier: GPL-3.0-or-later |
21 | | */ |
22 | | |
23 | | #include <config.h> |
24 | | #include <stdio.h> |
25 | | #include <stdlib.h> |
26 | | #include <string.h> |
27 | | #include <errno.h> |
28 | | #include <sys/types.h> |
29 | | #include <sys/stat.h> |
30 | | #include <unistd.h> |
31 | | |
32 | | #include "gpg.h" |
33 | | #include "../common/util.h" |
34 | | #include "../common/sysutils.h" |
35 | | #include "options.h" |
36 | | #include "main.h" /*try_make_homedir ()*/ |
37 | | #include "packet.h" |
38 | | #include "keyring.h" |
39 | | #include "../kbx/keybox.h" |
40 | | #include "keydb.h" |
41 | | #include "../common/i18n.h" |
42 | | #include "../common/comopt.h" |
43 | | |
44 | | #include "keydb-private.h" /* For struct keydb_handle_s */ |
45 | | |
46 | | static int active_handles; |
47 | | |
48 | | |
49 | | static struct resource_item all_resources[MAX_KEYDB_RESOURCES]; |
50 | | static int used_resources; |
51 | | |
52 | | /* A pointer used to check for the primary key database by comparing |
53 | | to the struct resource_item's TOKEN. */ |
54 | | static void *primary_keydb; |
55 | | |
56 | | /* Whether we have successfully registered any resource. */ |
57 | | static int any_registered; |
58 | | |
59 | | /* Looking up keys is expensive. To hide the cost, we cache whether |
60 | | keys exist in the key database. Then, if we know a key does not |
61 | | exist, we don't have to spend time looking it up. This |
62 | | particularly helps the --list-sigs and --check-sigs commands. |
63 | | |
64 | | The cache stores the results in a hash using separate chaining. |
65 | | Concretely: we use the LSB of the keyid to index the hash table and |
66 | | each bucket consists of a linked list of entries. An entry |
67 | | consists of the 64-bit key id. If a key id is not in the cache, |
68 | | then we don't know whether it is in the DB or not. |
69 | | |
70 | | To simplify the cache consistency protocol, we simply flush the |
71 | | whole cache whenever a key is inserted or updated. */ |
72 | | |
73 | 31.8k | #define KID_NOT_FOUND_CACHE_BUCKETS 256 |
74 | | static struct kid_not_found_cache_bucket * |
75 | | kid_not_found_cache[KID_NOT_FOUND_CACHE_BUCKETS]; |
76 | | |
77 | | struct kid_not_found_cache_bucket |
78 | | { |
79 | | struct kid_not_found_cache_bucket *next; |
80 | | u32 kid[2]; |
81 | | }; |
82 | | |
83 | | struct |
84 | | { |
85 | | unsigned int count; /* The current number of entries in the hash table. */ |
86 | | unsigned int peak; /* The peak of COUNT. */ |
87 | | unsigned int flushes; /* The number of flushes. */ |
88 | | } kid_not_found_stats; |
89 | | |
90 | | struct |
91 | | { |
92 | | unsigned int handles; /* Number of handles created. */ |
93 | | unsigned int locks; /* Number of locks taken. */ |
94 | | unsigned int parse_keyblocks; /* Number of parse_keyblock_image calls. */ |
95 | | unsigned int get_keyblocks; /* Number of keydb_get_keyblock calls. */ |
96 | | unsigned int build_keyblocks; /* Number of build_keyblock_image calls. */ |
97 | | unsigned int update_keyblocks;/* Number of update_keyblock calls. */ |
98 | | unsigned int insert_keyblocks;/* Number of update_keyblock calls. */ |
99 | | unsigned int delete_keyblocks;/* Number of delete_keyblock calls. */ |
100 | | unsigned int search_resets; /* Number of keydb_search_reset calls. */ |
101 | | unsigned int found; /* Number of successful keydb_search calls. */ |
102 | | unsigned int found_cached; /* Ditto but from the cache. */ |
103 | | unsigned int notfound; /* Number of failed keydb_search calls. */ |
104 | | unsigned int notfound_cached; /* Ditto but from the cache. */ |
105 | | } keydb_stats; |
106 | | |
107 | | |
108 | | static int lock_all (KEYDB_HANDLE hd); |
109 | | static void unlock_all (KEYDB_HANDLE hd); |
110 | | |
111 | | |
112 | | /* Check whether the keyid KID is in key id is definitely not in the |
113 | | database. |
114 | | |
115 | | Returns: |
116 | | |
117 | | 0 - Indeterminate: the key id is not in the cache; we don't know |
118 | | whether the key is in the database or not. If you want a |
119 | | definitive answer, you'll need to perform a lookup. |
120 | | |
121 | | 1 - There is definitely no key with this key id in the database. |
122 | | We searched for a key with this key id previously, but we |
123 | | didn't find it in the database. */ |
124 | | static int |
125 | | kid_not_found_p (u32 *kid) |
126 | 31.5k | { |
127 | 31.5k | struct kid_not_found_cache_bucket *k; |
128 | | |
129 | 161k | for (k = kid_not_found_cache[kid[0] % KID_NOT_FOUND_CACHE_BUCKETS]; k; k = k->next) |
130 | 161k | if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) |
131 | 31.3k | { |
132 | 31.3k | if (DBG_CACHE) |
133 | 31.3k | log_debug ("keydb: kid_not_found_p (%08lx%08lx) => not in DB\n", |
134 | 0 | (ulong)kid[0], (ulong)kid[1]); |
135 | 31.3k | return 1; |
136 | 31.3k | } |
137 | | |
138 | 145 | if (DBG_CACHE) |
139 | 145 | log_debug ("keydb: kid_not_found_p (%08lx%08lx) => indeterminate\n", |
140 | 0 | (ulong)kid[0], (ulong)kid[1]); |
141 | 145 | return 0; |
142 | 31.5k | } |
143 | | |
144 | | |
145 | | /* Insert the keyid KID into the kid_not_found_cache. FOUND is whether |
146 | | the key is in the key database or not. |
147 | | |
148 | | Note this function does not check whether the key id is already in |
149 | | the cache. As such, kid_not_found_p() should be called first. */ |
150 | | static void |
151 | | kid_not_found_insert (u32 *kid) |
152 | 145 | { |
153 | 145 | struct kid_not_found_cache_bucket *k; |
154 | | |
155 | 145 | if (DBG_CACHE) |
156 | 145 | log_debug ("keydb: kid_not_found_insert (%08lx%08lx)\n", |
157 | 0 | (ulong)kid[0], (ulong)kid[1]); |
158 | 145 | k = xmalloc (sizeof *k); |
159 | 145 | k->kid[0] = kid[0]; |
160 | 145 | k->kid[1] = kid[1]; |
161 | 145 | k->next = kid_not_found_cache[kid[0] % KID_NOT_FOUND_CACHE_BUCKETS]; |
162 | 145 | kid_not_found_cache[kid[0] % KID_NOT_FOUND_CACHE_BUCKETS] = k; |
163 | 145 | kid_not_found_stats.count++; |
164 | 145 | } |
165 | | |
166 | | |
167 | | /* Flush the kid not found cache. */ |
168 | | static void |
169 | | kid_not_found_flush (void) |
170 | 0 | { |
171 | 0 | struct kid_not_found_cache_bucket *k, *knext; |
172 | 0 | int i; |
173 | |
|
174 | 0 | if (DBG_CACHE) |
175 | 0 | log_debug ("keydb: kid_not_found_flush\n"); |
176 | |
|
177 | 0 | if (!kid_not_found_stats.count) |
178 | 0 | return; |
179 | | |
180 | 0 | for (i=0; i < DIM(kid_not_found_cache); i++) |
181 | 0 | { |
182 | 0 | for (k = kid_not_found_cache[i]; k; k = knext) |
183 | 0 | { |
184 | 0 | knext = k->next; |
185 | 0 | xfree (k); |
186 | 0 | } |
187 | 0 | kid_not_found_cache[i] = NULL; |
188 | 0 | } |
189 | 0 | if (kid_not_found_stats.count > kid_not_found_stats.peak) |
190 | 0 | kid_not_found_stats.peak = kid_not_found_stats.count; |
191 | 0 | kid_not_found_stats.count = 0; |
192 | 0 | kid_not_found_stats.flushes++; |
193 | 0 | } |
194 | | |
195 | | |
196 | | static void |
197 | | keyblock_cache_clear (struct keydb_handle_s *hd) |
198 | 81.5k | { |
199 | 81.5k | hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY; |
200 | 81.5k | iobuf_close (hd->keyblock_cache.iobuf); |
201 | 81.5k | hd->keyblock_cache.iobuf = NULL; |
202 | 81.5k | hd->keyblock_cache.resource = -1; |
203 | 81.5k | hd->keyblock_cache.offset = -1; |
204 | 81.5k | } |
205 | | |
206 | | |
207 | | /* Handle the creation of a keyring or a keybox if it does not yet |
208 | | exist. Take into account that other processes might have the |
209 | | keyring/keybox already locked. This lock check does not work if |
210 | | the directory itself is not yet available. If IS_BOX is true the |
211 | | filename is expected to refer to a keybox. If FORCE_CREATE is true |
212 | | the keyring or keybox will be created. |
213 | | |
214 | | Return 0 if it is okay to access the specified file. */ |
215 | | static gpg_error_t |
216 | | maybe_create_keyring_or_box (char *filename, int is_box, int force_create) |
217 | 1 | { |
218 | 1 | gpg_err_code_t ec; |
219 | 1 | dotlock_t lockhd = NULL; |
220 | 1 | IOBUF iobuf; |
221 | 1 | int rc; |
222 | 1 | mode_t oldmask; |
223 | 1 | char *last_slash_in_filename; |
224 | 1 | char *bak_fname = NULL; |
225 | 1 | char *tmp_fname = NULL; |
226 | 1 | int save_slash; |
227 | | |
228 | | /* A quick test whether the filename already exists. */ |
229 | 1 | if (!gnupg_access (filename, F_OK)) |
230 | 0 | return !gnupg_access (filename, R_OK)? 0 : gpg_error (GPG_ERR_EACCES); |
231 | | |
232 | | /* If we don't want to create a new file at all, there is no need to |
233 | | go any further - bail out right here. */ |
234 | 1 | if (!force_create) |
235 | 0 | return gpg_error (GPG_ERR_ENOENT); |
236 | | |
237 | | /* First of all we try to create the home directory. Note, that we |
238 | | don't do any locking here because any sane application of gpg |
239 | | would create the home directory by itself and not rely on gpg's |
240 | | tricky auto-creation which is anyway only done for certain home |
241 | | directory name pattern. */ |
242 | 1 | last_slash_in_filename = strrchr (filename, DIRSEP_C); |
243 | | #if HAVE_W32_SYSTEM |
244 | | { |
245 | | /* Windows may either have a slash or a backslash. Take care of it. */ |
246 | | char *p = strrchr (filename, '/'); |
247 | | if (!last_slash_in_filename || p > last_slash_in_filename) |
248 | | last_slash_in_filename = p; |
249 | | } |
250 | | #endif /*HAVE_W32_SYSTEM*/ |
251 | 1 | if (!last_slash_in_filename) |
252 | 0 | return gpg_error (GPG_ERR_ENOENT); /* No slash at all - should |
253 | | not happen though. */ |
254 | 1 | save_slash = *last_slash_in_filename; |
255 | 1 | *last_slash_in_filename = 0; |
256 | 1 | if (gnupg_access(filename, F_OK)) |
257 | 0 | { |
258 | 0 | static int tried; |
259 | |
|
260 | 0 | if (!tried) |
261 | 0 | { |
262 | 0 | tried = 1; |
263 | 0 | try_make_homedir (filename); |
264 | 0 | } |
265 | 0 | if ((ec = gnupg_access (filename, F_OK))) |
266 | 0 | { |
267 | 0 | rc = gpg_error (ec); |
268 | 0 | *last_slash_in_filename = save_slash; |
269 | 0 | goto leave; |
270 | 0 | } |
271 | | |
272 | 0 | *last_slash_in_filename = save_slash; |
273 | |
|
274 | 0 | if (!opt.use_keyboxd |
275 | 0 | && !parse_comopt (GNUPG_MODULE_NAME_GPG, 0) |
276 | 0 | && comopt.use_keyboxd) |
277 | 0 | { |
278 | | /* The above try_make_homedir created a new default hoemdir |
279 | | * and also wrote a new common.conf. Thus we now see that |
280 | | * use-keyboxd has been set. Let's set this option and |
281 | | * return a dedicated error code. */ |
282 | 0 | opt.use_keyboxd = comopt.use_keyboxd; |
283 | 0 | rc = gpg_error (GPG_ERR_TRUE); |
284 | 0 | goto leave; |
285 | 0 | } |
286 | 0 | } |
287 | 1 | else |
288 | 1 | *last_slash_in_filename = save_slash; |
289 | | |
290 | | /* To avoid races with other instances of gpg trying to create or |
291 | | update the keyring (it is removed during an update for a short |
292 | | time), we do the next stuff in a locked state. */ |
293 | 1 | lockhd = dotlock_create (filename, 0); |
294 | 1 | if (!lockhd) |
295 | 0 | { |
296 | 0 | rc = gpg_error_from_syserror (); |
297 | | /* A reason for this to fail is that the directory is not |
298 | | writable. However, this whole locking stuff does not make |
299 | | sense if this is the case. An empty non-writable directory |
300 | | with no keyring is not really useful at all. */ |
301 | 0 | if (opt.verbose) |
302 | 0 | log_info ("can't allocate lock for '%s': %s\n", |
303 | 0 | filename, gpg_strerror (rc)); |
304 | |
|
305 | 0 | if (!force_create) |
306 | 0 | return gpg_error (GPG_ERR_ENOENT); /* Won't happen. */ |
307 | 0 | else |
308 | 0 | return rc; |
309 | 0 | } |
310 | | |
311 | 1 | if ( dotlock_take (lockhd, -1) ) |
312 | 0 | { |
313 | 0 | rc = gpg_error_from_syserror (); |
314 | | /* This is something bad. Probably a stale lockfile. */ |
315 | 0 | log_info ("can't lock '%s': %s\n", filename, gpg_strerror (rc)); |
316 | 0 | goto leave; |
317 | 0 | } |
318 | | |
319 | | /* Now the real test while we are locked. */ |
320 | | |
321 | | /* Gpg either uses pubring.gpg or pubring.kbx and thus different |
322 | | * lock files. Now, when one gpg process is updating a pubring.gpg |
323 | | * and thus holding the corresponding lock, a second gpg process may |
324 | | * get to here at the time between the two rename operation used by |
325 | | * the first process to update pubring.gpg. The lock taken above |
326 | | * may not protect the second process if it tries to create a |
327 | | * pubring.kbx file which would be protected by a different lock |
328 | | * file. |
329 | | * |
330 | | * We can detect this case by checking that the two temporary files |
331 | | * used by the update code exist at the same time. In that case we |
332 | | * do not create a new file but act as if FORCE_CREATE has not been |
333 | | * given. Obviously there is a race between our two checks but the |
334 | | * worst thing is that we won't create a new file, which is better |
335 | | * than to accidentally creating one. */ |
336 | 1 | rc = keybox_tmp_names (filename, is_box, &bak_fname, &tmp_fname); |
337 | 1 | if (rc) |
338 | 0 | goto leave; |
339 | | |
340 | 1 | if (!gnupg_access (filename, F_OK)) |
341 | 0 | { |
342 | 0 | rc = 0; /* Okay, we may access the file now. */ |
343 | 0 | goto leave; |
344 | 0 | } |
345 | 1 | if (!gnupg_access (bak_fname, F_OK) && !gnupg_access (tmp_fname, F_OK)) |
346 | 0 | { |
347 | | /* Very likely another process is updating a pubring.gpg and we |
348 | | should not create a pubring.kbx. */ |
349 | 0 | rc = gpg_error (GPG_ERR_ENOENT); |
350 | 0 | goto leave; |
351 | 0 | } |
352 | | |
353 | | |
354 | | /* The file does not yet exist, create it now. */ |
355 | 1 | oldmask = umask (077); |
356 | 1 | if (is_secured_filename (filename)) |
357 | 0 | { |
358 | 0 | iobuf = NULL; |
359 | 0 | gpg_err_set_errno (EPERM); |
360 | 0 | } |
361 | 1 | else |
362 | 1 | iobuf = iobuf_create (filename, 0); |
363 | 1 | umask (oldmask); |
364 | 1 | if (!iobuf) |
365 | 0 | { |
366 | 0 | rc = gpg_error_from_syserror (); |
367 | 0 | if (is_box) |
368 | 0 | log_error (_("error creating keybox '%s': %s\n"), |
369 | 0 | filename, gpg_strerror (rc)); |
370 | 0 | else |
371 | 0 | log_error (_("error creating keyring '%s': %s\n"), |
372 | 0 | filename, gpg_strerror (rc)); |
373 | 0 | goto leave; |
374 | 0 | } |
375 | | |
376 | 1 | iobuf_close (iobuf); |
377 | | /* Must invalidate that ugly cache */ |
378 | 1 | iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, filename); |
379 | | |
380 | | /* Make sure that at least one record is in a new keybox file, so |
381 | | that the detection magic will work the next time it is used. */ |
382 | 1 | if (is_box) |
383 | 1 | { |
384 | 1 | estream_t fp = es_fopen (filename, "wb"); |
385 | 1 | if (!fp) |
386 | 0 | rc = gpg_error_from_syserror (); |
387 | 1 | else |
388 | 1 | { |
389 | 1 | rc = _keybox_write_header_blob (fp, 1); |
390 | 1 | es_fclose (fp); |
391 | 1 | } |
392 | 1 | if (rc) |
393 | 0 | { |
394 | 0 | if (is_box) |
395 | 0 | log_error (_("error creating keybox '%s': %s\n"), |
396 | 0 | filename, gpg_strerror (rc)); |
397 | 0 | else |
398 | 0 | log_error (_("error creating keyring '%s': %s\n"), |
399 | 0 | filename, gpg_strerror (rc)); |
400 | 0 | goto leave; |
401 | 0 | } |
402 | 1 | } |
403 | | |
404 | 1 | if (!opt.quiet) |
405 | 1 | { |
406 | 1 | if (is_box) |
407 | 1 | log_info (_("keybox '%s' created\n"), filename); |
408 | 0 | else |
409 | 1 | log_info (_("keyring '%s' created\n"), filename); |
410 | 1 | } |
411 | | |
412 | 1 | rc = 0; |
413 | | |
414 | 1 | leave: |
415 | 1 | if (lockhd) |
416 | 1 | { |
417 | 1 | dotlock_release (lockhd); |
418 | 1 | dotlock_destroy (lockhd); |
419 | 1 | } |
420 | 1 | xfree (bak_fname); |
421 | 1 | xfree (tmp_fname); |
422 | 1 | return rc; |
423 | 1 | } |
424 | | |
425 | | |
426 | | /* Helper for keydb_add_resource. Opens FILENAME to figure out the |
427 | | resource type. |
428 | | |
429 | | Returns the specified file's likely type. If the file does not |
430 | | exist, returns KEYDB_RESOURCE_TYPE_NONE and sets *R_FOUND to 0. |
431 | | Otherwise, tries to figure out the file's type. This is either |
432 | | KEYDB_RESOURCE_TYPE_KEYBOX, KEYDB_RESOURCE_TYPE_KEYRING or |
433 | | KEYDB_RESOURCE_TYPE_KEYNONE. If the file is a keybox and it has |
434 | | the OpenPGP flag set, then R_OPENPGP is also set. */ |
435 | | static KeydbResourceType |
436 | | rt_from_file (const char *filename, int *r_found, int *r_openpgp) |
437 | 2 | { |
438 | 2 | u32 magic; |
439 | 2 | unsigned char verbuf[4]; |
440 | 2 | estream_t fp; |
441 | 2 | KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; |
442 | | |
443 | 2 | *r_found = *r_openpgp = 0; |
444 | 2 | fp = es_fopen (filename, "rb"); |
445 | 2 | if (fp) |
446 | 0 | { |
447 | 0 | *r_found = 1; |
448 | |
|
449 | 0 | if (es_fread (&magic, 4, 1, fp) == 1 ) |
450 | 0 | { |
451 | 0 | if (magic == 0x13579ace || magic == 0xce9a5713) |
452 | 0 | ; /* GDBM magic - not anymore supported. */ |
453 | 0 | else if (es_fread (&verbuf, 4, 1, fp) == 1 |
454 | 0 | && verbuf[0] == 1 |
455 | 0 | && es_fread (&magic, 4, 1, fp) == 1 |
456 | 0 | && !memcmp (&magic, "KBXf", 4)) |
457 | 0 | { |
458 | 0 | if ((verbuf[3] & 0x02)) |
459 | 0 | *r_openpgp = 1; |
460 | 0 | rt = KEYDB_RESOURCE_TYPE_KEYBOX; |
461 | 0 | } |
462 | 0 | else |
463 | 0 | rt = KEYDB_RESOURCE_TYPE_KEYRING; |
464 | 0 | } |
465 | 0 | else /* Maybe empty: assume keyring. */ |
466 | 0 | rt = KEYDB_RESOURCE_TYPE_KEYRING; |
467 | |
|
468 | 0 | es_fclose (fp); |
469 | 0 | } |
470 | | |
471 | 2 | return rt; |
472 | 2 | } |
473 | | |
474 | | char * |
475 | | keydb_search_desc_dump (struct keydb_search_desc *desc) |
476 | 0 | { |
477 | 0 | char b[MAX_FORMATTED_FINGERPRINT_LEN + 1]; |
478 | 0 | char fpr[2 * MAX_FINGERPRINT_LEN + 1]; |
479 | |
|
480 | | #if MAX_FINGERPRINT_LEN < UBID_LEN || MAX_FINGERPRINT_LEN < KEYGRIP_LEN |
481 | | #error MAX_FINGERPRINT_LEN is shorter than KEYGRIP or UBID length. |
482 | | #endif |
483 | |
|
484 | 0 | switch (desc->mode) |
485 | 0 | { |
486 | 0 | case KEYDB_SEARCH_MODE_EXACT: |
487 | 0 | return xasprintf ("EXACT: '%s'", desc->u.name); |
488 | 0 | case KEYDB_SEARCH_MODE_SUBSTR: |
489 | 0 | return xasprintf ("SUBSTR: '%s'", desc->u.name); |
490 | 0 | case KEYDB_SEARCH_MODE_MAIL: |
491 | 0 | return xasprintf ("MAIL: '%s'", desc->u.name); |
492 | 0 | case KEYDB_SEARCH_MODE_MAILSUB: |
493 | 0 | return xasprintf ("MAILSUB: '%s'", desc->u.name); |
494 | 0 | case KEYDB_SEARCH_MODE_MAILEND: |
495 | 0 | return xasprintf ("MAILEND: '%s'", desc->u.name); |
496 | 0 | case KEYDB_SEARCH_MODE_WORDS: |
497 | 0 | return xasprintf ("WORDS: '%s'", desc->u.name); |
498 | 0 | case KEYDB_SEARCH_MODE_SHORT_KID: |
499 | 0 | return xasprintf ("SHORT_KID: '%s'", |
500 | 0 | format_keyid (desc->u.kid, KF_SHORT, b, sizeof (b))); |
501 | 0 | case KEYDB_SEARCH_MODE_LONG_KID: |
502 | 0 | return xasprintf ("LONG_KID: '%s'", |
503 | 0 | format_keyid (desc->u.kid, KF_LONG, b, sizeof (b))); |
504 | 0 | case KEYDB_SEARCH_MODE_FPR: |
505 | 0 | bin2hex (desc->u.fpr, desc->fprlen, fpr); |
506 | 0 | return xasprintf ("FPR%02d: '%s'", desc->fprlen, |
507 | 0 | format_hexfingerprint (fpr, b, sizeof (b))); |
508 | 0 | case KEYDB_SEARCH_MODE_ISSUER: |
509 | 0 | return xasprintf ("ISSUER: '%s'", desc->u.name); |
510 | 0 | case KEYDB_SEARCH_MODE_ISSUER_SN: |
511 | 0 | return xasprintf ("ISSUER_SN: '#%.*s/%s'", |
512 | 0 | (int)desc->snlen,desc->sn, desc->u.name); |
513 | 0 | case KEYDB_SEARCH_MODE_SN: |
514 | 0 | return xasprintf ("SN: '%.*s'", |
515 | 0 | (int)desc->snlen, desc->sn); |
516 | 0 | case KEYDB_SEARCH_MODE_SUBJECT: |
517 | 0 | return xasprintf ("SUBJECT: '%s'", desc->u.name); |
518 | 0 | case KEYDB_SEARCH_MODE_KEYGRIP: |
519 | 0 | bin2hex (desc[0].u.grip, KEYGRIP_LEN, fpr); |
520 | 0 | return xasprintf ("KEYGRIP: %s", fpr); |
521 | 0 | case KEYDB_SEARCH_MODE_UBID: |
522 | 0 | bin2hex (desc[0].u.ubid, UBID_LEN, fpr); |
523 | 0 | return xasprintf ("UBID: %s", fpr); |
524 | 0 | case KEYDB_SEARCH_MODE_FIRST: |
525 | 0 | return xasprintf ("FIRST"); |
526 | 0 | case KEYDB_SEARCH_MODE_NEXT: |
527 | 0 | return xasprintf ("NEXT"); |
528 | 0 | default: |
529 | 0 | return xasprintf ("Bad search mode (%d)", desc->mode); |
530 | 0 | } |
531 | 0 | } |
532 | | |
533 | | |
534 | | |
535 | | /* Register a resource (keyring or keybox). The first keyring or |
536 | | * keybox that is added using this function is created if it does not |
537 | | * already exist and the KEYDB_RESOURCE_FLAG_READONLY is not set. |
538 | | * |
539 | | * FLAGS are a combination of the KEYDB_RESOURCE_FLAG_* constants. |
540 | | * |
541 | | * URL must have the following form: |
542 | | * |
543 | | * gnupg-ring:filename = plain keyring |
544 | | * gnupg-kbx:filename = keybox file |
545 | | * filename = check file's type (create as a plain keyring) |
546 | | * |
547 | | * Note: on systems with drive letters (Windows) invalid URLs (i.e., |
548 | | * those with an unrecognized part before the ':' such as "c:\...") |
549 | | * will silently be treated as bare filenames. On other systems, such |
550 | | * URLs will cause this function to return GPG_ERR_GENERAL. |
551 | | * |
552 | | * If KEYDB_RESOURCE_FLAG_DEFAULT is set, the resource is a keyring |
553 | | * and the file ends in ".gpg", then this function also checks if a |
554 | | * file with the same name, but the extension ".kbx" exists, is a |
555 | | * keybox and the OpenPGP flag is set. If so, this function opens |
556 | | * that resource instead. |
557 | | * |
558 | | * If the file is not found, KEYDB_RESOURCE_FLAG_GPGVDEF is set and |
559 | | * the URL ends in ".kbx", then this function will try opening the |
560 | | * same URL, but with the extension ".gpg". If that file is a keybox |
561 | | * with the OpenPGP flag set or it is a keyring, then we use that |
562 | | * instead. |
563 | | * |
564 | | * If the file is not found, KEYDB_RESOURCE_FLAG_DEFAULT is set, the |
565 | | * file should be created and the file's extension is ".gpg" then we |
566 | | * replace the extension with ".kbx". |
567 | | * |
568 | | * If the KEYDB_RESOURCE_FLAG_PRIMARY is set and the resource is a |
569 | | * keyring (not a keybox), then this resource is considered the |
570 | | * primary resource. This is used by keydb_locate_writable(). If |
571 | | * another primary keyring is set, then that keyring is considered the |
572 | | * primary. |
573 | | * |
574 | | * If KEYDB_RESOURCE_FLAG_READONLY is set and the resource is a |
575 | | * keyring (not a keybox), then the keyring is marked as read only and |
576 | | * operations just as keyring_insert_keyblock will return |
577 | | * GPG_ERR_ACCESS. |
578 | | */ |
579 | | gpg_error_t |
580 | | keydb_add_resource (const char *url, unsigned int flags) |
581 | 1 | { |
582 | | /* The file named by the URL (i.e., without the prototype). */ |
583 | 1 | const char *resname = url; |
584 | | |
585 | 1 | char *filename = NULL; |
586 | 1 | int create; |
587 | 1 | int read_only = !!(flags&KEYDB_RESOURCE_FLAG_READONLY); |
588 | 1 | int is_default = !!(flags&KEYDB_RESOURCE_FLAG_DEFAULT); |
589 | 1 | int is_gpgvdef = !!(flags&KEYDB_RESOURCE_FLAG_GPGVDEF); |
590 | 1 | gpg_error_t err = 0; |
591 | 1 | KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; |
592 | 1 | void *token; |
593 | | |
594 | | /* Create the resource if it is the first registered one. */ |
595 | 1 | create = (!read_only && !any_registered); |
596 | | |
597 | 1 | if (strlen (resname) > 11 && !strncmp( resname, "gnupg-ring:", 11) ) |
598 | 0 | { |
599 | 0 | rt = KEYDB_RESOURCE_TYPE_KEYRING; |
600 | 0 | resname += 11; |
601 | 0 | } |
602 | 1 | else if (strlen (resname) > 10 && !strncmp (resname, "gnupg-kbx:", 10) ) |
603 | 0 | { |
604 | 0 | rt = KEYDB_RESOURCE_TYPE_KEYBOX; |
605 | 0 | resname += 10; |
606 | 0 | } |
607 | 1 | #if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__) |
608 | 1 | else if (strchr (resname, ':')) |
609 | 0 | { |
610 | 0 | log_error ("invalid key resource URL '%s'\n", url ); |
611 | 0 | err = gpg_error (GPG_ERR_GENERAL); |
612 | 0 | goto leave; |
613 | 0 | } |
614 | 1 | #endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */ |
615 | | |
616 | 1 | if (*resname != DIRSEP_C |
617 | | #ifdef HAVE_W32_SYSTEM |
618 | | && *resname != '/' /* Fixme: does not handle drive letters. */ |
619 | | #endif |
620 | 1 | ) |
621 | 1 | { |
622 | | /* Do tilde expansion etc. */ |
623 | 1 | if (strchr (resname, DIRSEP_C) |
624 | | #ifdef HAVE_W32_SYSTEM |
625 | | || strchr (resname, '/') /* Windows also accepts this. */ |
626 | | #endif |
627 | 1 | ) |
628 | 0 | filename = make_filename (resname, NULL); |
629 | 1 | else |
630 | 1 | filename = make_filename (gnupg_homedir (), resname, NULL); |
631 | 1 | } |
632 | 0 | else |
633 | 0 | filename = xstrdup (resname); |
634 | | |
635 | | /* See whether we can determine the filetype. */ |
636 | 1 | if (rt == KEYDB_RESOURCE_TYPE_NONE) |
637 | 1 | { |
638 | 1 | int found, openpgp_flag; |
639 | 1 | int pass = 0; |
640 | 1 | size_t filenamelen; |
641 | | |
642 | 2 | check_again: |
643 | 2 | filenamelen = strlen (filename); |
644 | 2 | rt = rt_from_file (filename, &found, &openpgp_flag); |
645 | 2 | if (found) |
646 | 0 | { |
647 | | /* The file exists and we have the resource type in RT. |
648 | | |
649 | | Now let us check whether in addition to the "pubring.gpg" |
650 | | a "pubring.kbx with openpgp keys exists. This is so that |
651 | | GPG 2.1 will use an existing "pubring.kbx" by default iff |
652 | | that file has been created or used by 2.1. This check is |
653 | | needed because after creation or use of the kbx file with |
654 | | 2.1 an older version of gpg may have created a new |
655 | | pubring.gpg for its own use. */ |
656 | 0 | if (!pass && is_default && rt == KEYDB_RESOURCE_TYPE_KEYRING |
657 | 0 | && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg")) |
658 | 0 | { |
659 | 0 | strcpy (filename+filenamelen-4, ".kbx"); |
660 | 0 | if ((rt_from_file (filename, &found, &openpgp_flag) |
661 | 0 | == KEYDB_RESOURCE_TYPE_KEYBOX) && found && openpgp_flag) |
662 | 0 | rt = KEYDB_RESOURCE_TYPE_KEYBOX; |
663 | 0 | else /* Restore filename */ |
664 | 0 | strcpy (filename+filenamelen-4, ".gpg"); |
665 | 0 | } |
666 | 0 | } |
667 | 2 | else if (!pass && is_gpgvdef |
668 | 0 | && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".kbx")) |
669 | 0 | { |
670 | | /* Not found but gpgv's default "trustedkeys.kbx" file has |
671 | | been requested. We did not found it so now check whether |
672 | | a "trustedkeys.gpg" file exists and use that instead. */ |
673 | 0 | KeydbResourceType rttmp; |
674 | |
|
675 | 0 | strcpy (filename+filenamelen-4, ".gpg"); |
676 | 0 | rttmp = rt_from_file (filename, &found, &openpgp_flag); |
677 | 0 | if (found |
678 | 0 | && ((rttmp == KEYDB_RESOURCE_TYPE_KEYBOX && openpgp_flag) |
679 | 0 | || (rttmp == KEYDB_RESOURCE_TYPE_KEYRING))) |
680 | 0 | rt = rttmp; |
681 | 0 | else /* Restore filename */ |
682 | 0 | strcpy (filename+filenamelen-4, ".kbx"); |
683 | 0 | } |
684 | 2 | else if (!pass |
685 | 1 | && is_default && create |
686 | 1 | && filenamelen > 4 && !strcmp (filename+filenamelen-4, ".gpg")) |
687 | 1 | { |
688 | | /* The file does not exist, the default resource has been |
689 | | requested, the file shall be created, and the file has a |
690 | | ".gpg" suffix. Change the suffix to ".kbx" and try once |
691 | | more. This way we achieve that we open an existing |
692 | | ".gpg" keyring, but create a new keybox file with an |
693 | | ".kbx" suffix. */ |
694 | 1 | strcpy (filename+filenamelen-4, ".kbx"); |
695 | 1 | pass++; |
696 | 1 | goto check_again; |
697 | 1 | } |
698 | 1 | else /* No file yet: create keybox. */ |
699 | 1 | rt = KEYDB_RESOURCE_TYPE_KEYBOX; |
700 | 2 | } |
701 | | |
702 | 1 | switch (rt) |
703 | 1 | { |
704 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
705 | 0 | log_error ("unknown type of key resource '%s'\n", url ); |
706 | 0 | err = gpg_error (GPG_ERR_GENERAL); |
707 | 0 | goto leave; |
708 | | |
709 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
710 | 0 | err = maybe_create_keyring_or_box (filename, 0, create); |
711 | 0 | if (err) |
712 | 0 | goto leave; |
713 | | |
714 | 0 | if (keyring_register_filename (filename, read_only, &token)) |
715 | 0 | { |
716 | 0 | if (used_resources >= MAX_KEYDB_RESOURCES) |
717 | 0 | err = gpg_error (GPG_ERR_RESOURCE_LIMIT); |
718 | 0 | else |
719 | 0 | { |
720 | 0 | if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) |
721 | 0 | primary_keydb = token; |
722 | 0 | all_resources[used_resources].type = rt; |
723 | 0 | all_resources[used_resources].u.kr = NULL; /* Not used here */ |
724 | 0 | all_resources[used_resources].token = token; |
725 | 0 | used_resources++; |
726 | 0 | } |
727 | 0 | } |
728 | 0 | else |
729 | 0 | { |
730 | | /* This keyring was already registered, so ignore it. |
731 | | However, we can still mark it as primary even if it was |
732 | | already registered. */ |
733 | 0 | if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) |
734 | 0 | primary_keydb = token; |
735 | 0 | } |
736 | 0 | break; |
737 | | |
738 | 1 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
739 | 1 | { |
740 | 1 | err = maybe_create_keyring_or_box (filename, 1, create); |
741 | 1 | if (err) |
742 | 0 | goto leave; |
743 | | |
744 | 1 | err = keybox_register_file (filename, 0, &token); |
745 | 1 | if (!err) |
746 | 1 | { |
747 | 1 | if (used_resources >= MAX_KEYDB_RESOURCES) |
748 | 0 | err = gpg_error (GPG_ERR_RESOURCE_LIMIT); |
749 | 1 | else |
750 | 1 | { |
751 | 1 | if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) |
752 | 0 | primary_keydb = token; |
753 | 1 | all_resources[used_resources].type = rt; |
754 | 1 | all_resources[used_resources].u.kb = NULL; /* Not used here */ |
755 | 1 | all_resources[used_resources].token = token; |
756 | | |
757 | 1 | if (!(flags & KEYDB_RESOURCE_FLAG_READONLY)) |
758 | | /* Do a compress run if needed and no other user is |
759 | | * currently using the keybox. */ |
760 | 1 | keybox_compress_when_no_other_users (token, 1); |
761 | 1 | used_resources++; |
762 | 1 | } |
763 | 1 | } |
764 | 0 | else if (gpg_err_code (err) == GPG_ERR_EEXIST) |
765 | 0 | { |
766 | | /* Already registered. We will mark it as the primary key |
767 | | if requested. */ |
768 | 0 | if ((flags & KEYDB_RESOURCE_FLAG_PRIMARY)) |
769 | 0 | primary_keydb = token; |
770 | 0 | } |
771 | 1 | } |
772 | 0 | break; |
773 | | |
774 | 0 | default: |
775 | 0 | log_error ("resource type of '%s' not supported\n", url); |
776 | 0 | err = gpg_error (GPG_ERR_GENERAL); |
777 | 0 | goto leave; |
778 | 1 | } |
779 | | |
780 | | /* fixme: check directory permissions and print a warning */ |
781 | | |
782 | 1 | leave: |
783 | 1 | if (err) |
784 | 0 | { |
785 | 0 | if (gpg_err_code (err) != GPG_ERR_TRUE) |
786 | 0 | { |
787 | 0 | log_error (_("keyblock resource '%s': %s\n"), |
788 | 0 | filename, gpg_strerror (err)); |
789 | 0 | write_status_error ("add_keyblock_resource", err); |
790 | 0 | } |
791 | 0 | } |
792 | 1 | else |
793 | 1 | any_registered = 1; |
794 | 1 | xfree (filename); |
795 | 1 | return err; |
796 | 1 | } |
797 | | |
798 | | |
799 | | void |
800 | | keydb_dump_stats (void) |
801 | 0 | { |
802 | 0 | log_info ("keydb: handles=%u locks=%u parse=%u get=%u\n", |
803 | 0 | keydb_stats.handles, |
804 | 0 | keydb_stats.locks, |
805 | 0 | keydb_stats.parse_keyblocks, |
806 | 0 | keydb_stats.get_keyblocks); |
807 | 0 | log_info (" build=%u update=%u insert=%u delete=%u\n", |
808 | 0 | keydb_stats.build_keyblocks, |
809 | 0 | keydb_stats.update_keyblocks, |
810 | 0 | keydb_stats.insert_keyblocks, |
811 | 0 | keydb_stats.delete_keyblocks); |
812 | 0 | log_info (" reset=%u found=%u not=%u cache=%u not=%u\n", |
813 | 0 | keydb_stats.search_resets, |
814 | 0 | keydb_stats.found, |
815 | 0 | keydb_stats.notfound, |
816 | 0 | keydb_stats.found_cached, |
817 | 0 | keydb_stats.notfound_cached); |
818 | 0 | log_info ("kid_not_found_cache: count=%u peak=%u flushes=%u\n", |
819 | 0 | kid_not_found_stats.count, |
820 | 0 | kid_not_found_stats.peak, |
821 | 0 | kid_not_found_stats.flushes); |
822 | 0 | } |
823 | | |
824 | | |
825 | | /* keydb_new diverts to here in non-keyboxd mode. HD is just the |
826 | | * calloced structure with the handle type initialized. */ |
827 | | gpg_error_t |
828 | | internal_keydb_init (KEYDB_HANDLE hd) |
829 | 25.3k | { |
830 | 25.3k | gpg_error_t err = 0; |
831 | 25.3k | int i, j; |
832 | 25.3k | int die = 0; |
833 | 25.3k | int reterrno; |
834 | | |
835 | 25.3k | log_assert (!hd->use_keyboxd); |
836 | 25.3k | hd->found = -1; |
837 | 25.3k | hd->saved_found = -1; |
838 | 25.3k | hd->is_reset = 1; |
839 | | |
840 | 25.3k | log_assert (used_resources <= MAX_KEYDB_RESOURCES); |
841 | 50.7k | for (i=j=0; ! die && i < used_resources; i++) |
842 | 25.3k | { |
843 | 25.3k | switch (all_resources[i].type) |
844 | 25.3k | { |
845 | 0 | case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ |
846 | 0 | break; |
847 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
848 | 0 | hd->active[j].type = all_resources[i].type; |
849 | 0 | hd->active[j].token = all_resources[i].token; |
850 | 0 | hd->active[j].u.kr = keyring_new (all_resources[i].token); |
851 | 0 | if (!hd->active[j].u.kr) |
852 | 0 | { |
853 | 0 | reterrno = errno; |
854 | 0 | die = 1; |
855 | 0 | } |
856 | 0 | j++; |
857 | 0 | break; |
858 | 25.3k | case KEYDB_RESOURCE_TYPE_KEYBOX: |
859 | 25.3k | hd->active[j].type = all_resources[i].type; |
860 | 25.3k | hd->active[j].token = all_resources[i].token; |
861 | 25.3k | hd->active[j].u.kb = keybox_new_openpgp (all_resources[i].token, 0); |
862 | 25.3k | if (!hd->active[j].u.kb) |
863 | 0 | { |
864 | 0 | reterrno = errno; |
865 | 0 | die = 1; |
866 | 0 | } |
867 | 25.3k | j++; |
868 | 25.3k | break; |
869 | 25.3k | } |
870 | 25.3k | } |
871 | 25.3k | hd->used = j; |
872 | | |
873 | 25.3k | active_handles++; |
874 | 25.3k | keydb_stats.handles++; |
875 | | |
876 | 25.3k | if (die) |
877 | 0 | err = gpg_error_from_errno (reterrno); |
878 | | |
879 | 25.3k | return err; |
880 | 25.3k | } |
881 | | |
882 | | |
883 | | /* Free all non-keyboxd resources owned by the database handle. |
884 | | * keydb_release diverts to here. */ |
885 | | void |
886 | | internal_keydb_deinit (KEYDB_HANDLE hd) |
887 | 25.3k | { |
888 | 25.3k | int i; |
889 | | |
890 | 25.3k | log_assert (!hd->use_keyboxd); |
891 | | |
892 | 25.3k | log_assert (active_handles > 0); |
893 | 25.3k | active_handles--; |
894 | | |
895 | 25.3k | hd->keep_lock = 0; |
896 | 25.3k | unlock_all (hd); |
897 | 50.7k | for (i=0; i < hd->used; i++) |
898 | 25.3k | { |
899 | 25.3k | switch (hd->active[i].type) |
900 | 25.3k | { |
901 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
902 | 0 | break; |
903 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
904 | 0 | keyring_release (hd->active[i].u.kr); |
905 | 0 | break; |
906 | 25.3k | case KEYDB_RESOURCE_TYPE_KEYBOX: |
907 | 25.3k | keybox_release (hd->active[i].u.kb); |
908 | 25.3k | break; |
909 | 25.3k | } |
910 | 25.3k | } |
911 | | |
912 | 25.3k | keyblock_cache_clear (hd); |
913 | 25.3k | } |
914 | | |
915 | | |
916 | | /* Take a lock on the files immediately and not only during insert or |
917 | | * update. This lock is released with keydb_release. */ |
918 | | static gpg_error_t |
919 | | internal_keydb_lock (KEYDB_HANDLE hd) |
920 | 0 | { |
921 | 0 | gpg_error_t err; |
922 | |
|
923 | 0 | log_assert (!hd->use_keyboxd); |
924 | | |
925 | 0 | err = lock_all (hd); |
926 | 0 | if (!err) |
927 | 0 | hd->keep_lock = 1; |
928 | |
|
929 | 0 | return err; |
930 | 0 | } |
931 | | |
932 | | |
933 | | /* Take a lock if we are not using the keyboxd. */ |
934 | | gpg_error_t |
935 | | keydb_lock (KEYDB_HANDLE hd) |
936 | 0 | { |
937 | 0 | if (!hd) |
938 | 0 | return gpg_error (GPG_ERR_INV_ARG); |
939 | | |
940 | 0 | if (!hd->use_keyboxd) |
941 | 0 | return internal_keydb_lock (hd); |
942 | | |
943 | 0 | return 0; |
944 | 0 | } |
945 | | |
946 | | |
947 | | /* Set a flag on the handle to suppress use of cached results. This |
948 | | * is required for updating a keyring and for key listings. Fixme: |
949 | | * Using a new parameter for keydb_new might be a better solution. */ |
950 | | void |
951 | | keydb_disable_caching (KEYDB_HANDLE hd) |
952 | 0 | { |
953 | 0 | if (hd && !hd->use_keyboxd) |
954 | 0 | hd->no_caching = 1; |
955 | 0 | } |
956 | | |
957 | | |
958 | | /* Return the file name of the resource in which the current search |
959 | | * result was found or, if there is no search result, the filename of |
960 | | * the current resource (i.e., the resource that the file position |
961 | | * points to). Note: the filename is not necessarily the URL used to |
962 | | * open it! |
963 | | * |
964 | | * This function only returns NULL if no handle is specified, in all |
965 | | * other error cases an empty string is returned. */ |
966 | | const char * |
967 | | keydb_get_resource_name (KEYDB_HANDLE hd) |
968 | 0 | { |
969 | 0 | int idx; |
970 | 0 | const char *s = NULL; |
971 | |
|
972 | 0 | if (!hd) |
973 | 0 | return NULL; |
974 | | |
975 | 0 | if (hd->use_keyboxd) |
976 | 0 | return "[keyboxd]"; |
977 | | |
978 | 0 | if ( hd->found >= 0 && hd->found < hd->used) |
979 | 0 | idx = hd->found; |
980 | 0 | else if ( hd->current >= 0 && hd->current < hd->used) |
981 | 0 | idx = hd->current; |
982 | 0 | else |
983 | 0 | idx = 0; |
984 | |
|
985 | 0 | switch (hd->active[idx].type) |
986 | 0 | { |
987 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
988 | 0 | s = NULL; |
989 | 0 | break; |
990 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
991 | 0 | s = keyring_get_resource_name (hd->active[idx].u.kr); |
992 | 0 | break; |
993 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
994 | 0 | s = keybox_get_resource_name (hd->active[idx].u.kb); |
995 | 0 | break; |
996 | 0 | } |
997 | | |
998 | 0 | return s? s: ""; |
999 | 0 | } |
1000 | | |
1001 | | |
1002 | | |
1003 | | static int |
1004 | | lock_all (KEYDB_HANDLE hd) |
1005 | 0 | { |
1006 | 0 | int i, rc = 0; |
1007 | | |
1008 | | /* Fixme: This locking scheme may lead to a deadlock if the resources |
1009 | | are not added in the same order by all processes. We are |
1010 | | currently only allowing one resource so it is not a problem. |
1011 | | [Oops: Who claimed the latter] |
1012 | | |
1013 | | To fix this we need to use a lock file to protect lock_all. */ |
1014 | |
|
1015 | 0 | if (hd->keep_lock) |
1016 | 0 | return 0; |
1017 | | |
1018 | 0 | for (i=0; !rc && i < hd->used; i++) |
1019 | 0 | { |
1020 | 0 | switch (hd->active[i].type) |
1021 | 0 | { |
1022 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1023 | 0 | break; |
1024 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1025 | 0 | rc = keyring_lock (hd->active[i].u.kr, 1); |
1026 | 0 | break; |
1027 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1028 | 0 | rc = keybox_lock (hd->active[i].u.kb, 1, -1); |
1029 | 0 | break; |
1030 | 0 | } |
1031 | 0 | } |
1032 | | |
1033 | 0 | if (rc) |
1034 | 0 | { |
1035 | | /* Revert the already taken locks. */ |
1036 | 0 | for (i--; i >= 0; i--) |
1037 | 0 | { |
1038 | 0 | switch (hd->active[i].type) |
1039 | 0 | { |
1040 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1041 | 0 | break; |
1042 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1043 | 0 | keyring_lock (hd->active[i].u.kr, 0); |
1044 | 0 | break; |
1045 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1046 | 0 | keybox_lock (hd->active[i].u.kb, 0, 0); |
1047 | 0 | break; |
1048 | 0 | } |
1049 | 0 | } |
1050 | 0 | } |
1051 | 0 | else |
1052 | 0 | { |
1053 | 0 | hd->locked = 1; |
1054 | 0 | keydb_stats.locks++; |
1055 | 0 | } |
1056 | | |
1057 | 0 | return rc; |
1058 | 0 | } |
1059 | | |
1060 | | |
1061 | | static void |
1062 | | do_fp_close (KEYDB_HANDLE hd) |
1063 | 25.3k | { |
1064 | 25.3k | int i; |
1065 | | |
1066 | 50.7k | for (i=0; i < hd->used; i++) |
1067 | 25.3k | { |
1068 | 25.3k | switch (hd->active[i].type) |
1069 | 25.3k | { |
1070 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1071 | 0 | break; |
1072 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1073 | 0 | keyring_fp_close (hd->active[i].u.kr); |
1074 | 0 | break; |
1075 | 25.3k | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1076 | 25.3k | keybox_fp_close (hd->active[i].u.kb); |
1077 | 25.3k | break; |
1078 | 25.3k | } |
1079 | 25.3k | } |
1080 | 25.3k | } |
1081 | | |
1082 | | static void |
1083 | | unlock_all (KEYDB_HANDLE hd) |
1084 | 25.3k | { |
1085 | 25.3k | int i; |
1086 | | |
1087 | 25.3k | do_fp_close (hd); |
1088 | | |
1089 | 25.3k | if (!hd->locked) |
1090 | 25.3k | return; |
1091 | | |
1092 | 0 | for (i=hd->used-1; i >= 0; i--) |
1093 | 0 | { |
1094 | 0 | switch (hd->active[i].type) |
1095 | 0 | { |
1096 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1097 | 0 | break; |
1098 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1099 | 0 | keyring_lock (hd->active[i].u.kr, 0); |
1100 | 0 | break; |
1101 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1102 | 0 | keybox_lock (hd->active[i].u.kb, 0, 0); |
1103 | 0 | break; |
1104 | 0 | } |
1105 | 0 | } |
1106 | 0 | hd->locked = 0; |
1107 | 0 | } |
1108 | | |
1109 | | |
1110 | | |
1111 | | /* Save the last found state and invalidate the current selection |
1112 | | * (i.e., the entry selected by keydb_search() is invalidated and |
1113 | | * something like keydb_get_keyblock() will return an error). This |
1114 | | * does not change the file position. This makes it possible to do |
1115 | | * something like: |
1116 | | * |
1117 | | * keydb_search (hd, ...); // Result 1. |
1118 | | * keydb_push_found_state (hd); |
1119 | | * keydb_search_reset (hd); |
1120 | | * keydb_search (hd, ...); // Result 2. |
1121 | | * keydb_pop_found_state (hd); |
1122 | | * keydb_get_keyblock (hd, ...); // -> Result 1. |
1123 | | * |
1124 | | * Note: it is only possible to save a single save state at a time. |
1125 | | * In other words, the save stack only has room for a single |
1126 | | * instance of the state. */ |
1127 | | /* FIXME(keyboxd): This function is used only at one place - see how |
1128 | | * we can avoid it. */ |
1129 | | void |
1130 | | keydb_push_found_state (KEYDB_HANDLE hd) |
1131 | 0 | { |
1132 | 0 | if (!hd) |
1133 | 0 | return; |
1134 | | |
1135 | 0 | if (hd->found < 0 || hd->found >= hd->used) |
1136 | 0 | { |
1137 | 0 | hd->saved_found = -1; |
1138 | 0 | return; |
1139 | 0 | } |
1140 | | |
1141 | 0 | switch (hd->active[hd->found].type) |
1142 | 0 | { |
1143 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1144 | 0 | break; |
1145 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1146 | 0 | keyring_push_found_state (hd->active[hd->found].u.kr); |
1147 | 0 | break; |
1148 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1149 | 0 | keybox_push_found_state (hd->active[hd->found].u.kb); |
1150 | 0 | break; |
1151 | 0 | } |
1152 | | |
1153 | 0 | hd->saved_found = hd->found; |
1154 | 0 | hd->found = -1; |
1155 | 0 | } |
1156 | | |
1157 | | |
1158 | | /* Restore the previous save state. If the saved state is NULL or |
1159 | | invalid, this is a NOP. */ |
1160 | | /* FIXME(keyboxd): This function is used only at one place - see how |
1161 | | * we can avoid it. */ |
1162 | | void |
1163 | | keydb_pop_found_state (KEYDB_HANDLE hd) |
1164 | 0 | { |
1165 | 0 | if (!hd) |
1166 | 0 | return; |
1167 | | |
1168 | 0 | hd->found = hd->saved_found; |
1169 | 0 | hd->saved_found = -1; |
1170 | 0 | if (hd->found < 0 || hd->found >= hd->used) |
1171 | 0 | return; |
1172 | | |
1173 | 0 | switch (hd->active[hd->found].type) |
1174 | 0 | { |
1175 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1176 | 0 | break; |
1177 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1178 | 0 | keyring_pop_found_state (hd->active[hd->found].u.kr); |
1179 | 0 | break; |
1180 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1181 | 0 | keybox_pop_found_state (hd->active[hd->found].u.kb); |
1182 | 0 | break; |
1183 | 0 | } |
1184 | 0 | } |
1185 | | |
1186 | | |
1187 | | |
1188 | | /* Parse the keyblock in IOBUF and return at R_KEYBLOCK. PK_NO gives |
1189 | | * the index of the public (sub)key which matched the search criteria; |
1190 | | * the primary key is 1, the first subkey 2, 0 means unknown. UID_NO |
1191 | | * is the same for user-ids as search criteria; 1 is the first |
1192 | | * user-id, 0 means unknown. */ |
1193 | | gpg_error_t |
1194 | | keydb_parse_keyblock (iobuf_t iobuf, int pk_no, int uid_no, |
1195 | | kbnode_t *r_keyblock) |
1196 | 0 | { |
1197 | 0 | gpg_error_t err; |
1198 | 0 | struct parse_packet_ctx_s parsectx; |
1199 | 0 | PACKET *pkt; |
1200 | 0 | kbnode_t keyblock = NULL; |
1201 | 0 | kbnode_t node, *tail; |
1202 | 0 | int in_cert, save_mode; |
1203 | 0 | int pk_count, uid_count; |
1204 | |
|
1205 | 0 | *r_keyblock = NULL; |
1206 | |
|
1207 | 0 | pkt = xtrymalloc (sizeof *pkt); |
1208 | 0 | if (!pkt) |
1209 | 0 | return gpg_error_from_syserror (); |
1210 | 0 | init_packet (pkt); |
1211 | 0 | init_parse_packet (&parsectx, iobuf); |
1212 | 0 | save_mode = set_packet_list_mode (0); |
1213 | 0 | in_cert = 0; |
1214 | 0 | tail = NULL; |
1215 | 0 | pk_count = uid_count = 0; |
1216 | 0 | while ((err = parse_packet (&parsectx, pkt)) != -1) |
1217 | 0 | { |
1218 | 0 | if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET) |
1219 | 0 | { |
1220 | 0 | free_packet (pkt, &parsectx); |
1221 | 0 | init_packet (pkt); |
1222 | 0 | continue; |
1223 | 0 | } |
1224 | 0 | if (err) |
1225 | 0 | { |
1226 | 0 | es_fflush (es_stdout); |
1227 | 0 | log_error ("parse_keyblock_image: read error: %s\n", |
1228 | 0 | gpg_strerror (err)); |
1229 | 0 | if (gpg_err_code (err) == GPG_ERR_INV_PACKET) |
1230 | 0 | { |
1231 | 0 | free_packet (pkt, &parsectx); |
1232 | 0 | init_packet (pkt); |
1233 | 0 | continue; |
1234 | 0 | } |
1235 | 0 | err = gpg_error (GPG_ERR_INV_KEYRING); |
1236 | 0 | break; |
1237 | 0 | } |
1238 | | |
1239 | | /* Filter allowed packets. */ |
1240 | 0 | switch (pkt->pkttype) |
1241 | 0 | { |
1242 | 0 | case PKT_PUBLIC_KEY: |
1243 | 0 | case PKT_PUBLIC_SUBKEY: |
1244 | 0 | case PKT_SECRET_KEY: |
1245 | 0 | case PKT_SECRET_SUBKEY: |
1246 | 0 | case PKT_USER_ID: |
1247 | 0 | case PKT_ATTRIBUTE: |
1248 | 0 | case PKT_SIGNATURE: |
1249 | 0 | case PKT_RING_TRUST: |
1250 | 0 | break; /* Allowed per RFC. */ |
1251 | | |
1252 | 0 | default: |
1253 | 0 | log_info ("skipped packet of type %d in keybox\n", (int)pkt->pkttype); |
1254 | 0 | free_packet(pkt, &parsectx); |
1255 | 0 | init_packet(pkt); |
1256 | 0 | continue; |
1257 | 0 | } |
1258 | | |
1259 | | /* Other sanity checks. */ |
1260 | 0 | if (!in_cert && pkt->pkttype != PKT_PUBLIC_KEY) |
1261 | 0 | { |
1262 | 0 | log_error ("parse_keyblock_image: first packet in a keybox blob " |
1263 | 0 | "is not a public key packet\n"); |
1264 | 0 | err = gpg_error (GPG_ERR_INV_KEYRING); |
1265 | 0 | break; |
1266 | 0 | } |
1267 | 0 | if (in_cert && (pkt->pkttype == PKT_PUBLIC_KEY |
1268 | 0 | || pkt->pkttype == PKT_SECRET_KEY)) |
1269 | 0 | { |
1270 | 0 | log_error ("parse_keyblock_image: " |
1271 | 0 | "multiple keyblocks in a keybox blob\n"); |
1272 | 0 | err = gpg_error (GPG_ERR_INV_KEYRING); |
1273 | 0 | break; |
1274 | 0 | } |
1275 | 0 | in_cert = 1; |
1276 | |
|
1277 | 0 | node = new_kbnode (pkt); |
1278 | |
|
1279 | 0 | switch (pkt->pkttype) |
1280 | 0 | { |
1281 | 0 | case PKT_PUBLIC_KEY: |
1282 | 0 | case PKT_PUBLIC_SUBKEY: |
1283 | 0 | case PKT_SECRET_KEY: |
1284 | 0 | case PKT_SECRET_SUBKEY: |
1285 | 0 | if (++pk_count == pk_no) |
1286 | 0 | node->flag |= 1; |
1287 | 0 | break; |
1288 | | |
1289 | 0 | case PKT_USER_ID: |
1290 | 0 | if (++uid_count == uid_no) |
1291 | 0 | node->flag |= 2; |
1292 | 0 | break; |
1293 | | |
1294 | 0 | default: |
1295 | 0 | break; |
1296 | 0 | } |
1297 | | |
1298 | 0 | if (!keyblock) |
1299 | 0 | keyblock = node; |
1300 | 0 | else |
1301 | 0 | *tail = node; |
1302 | 0 | tail = &node->next; |
1303 | 0 | pkt = xtrymalloc (sizeof *pkt); |
1304 | 0 | if (!pkt) |
1305 | 0 | { |
1306 | 0 | err = gpg_error_from_syserror (); |
1307 | 0 | break; |
1308 | 0 | } |
1309 | 0 | init_packet (pkt); |
1310 | 0 | } |
1311 | 0 | set_packet_list_mode (save_mode); |
1312 | |
|
1313 | 0 | if (err == -1 && keyblock) |
1314 | 0 | err = 0; /* Got the entire keyblock. */ |
1315 | |
|
1316 | 0 | if (err) |
1317 | 0 | release_kbnode (keyblock); |
1318 | 0 | else |
1319 | 0 | { |
1320 | 0 | *r_keyblock = keyblock; |
1321 | 0 | keydb_stats.parse_keyblocks++; |
1322 | 0 | } |
1323 | 0 | free_packet (pkt, &parsectx); |
1324 | 0 | deinit_parse_packet (&parsectx); |
1325 | 0 | xfree (pkt); |
1326 | 0 | return err; |
1327 | 0 | } |
1328 | | |
1329 | | |
1330 | | /* Return the keyblock last found by keydb_search() in *RET_KB. |
1331 | | * keydb_get_keyblock divert to here in the non-keyboxd mode. |
1332 | | * |
1333 | | * On success, the function returns 0 and the caller must free *RET_KB |
1334 | | * using release_kbnode(). Otherwise, the function returns an error |
1335 | | * code. |
1336 | | * |
1337 | | * The returned keyblock has the kbnode flag bit 0 set for the node |
1338 | | * with the public key used to locate the keyblock or flag bit 1 set |
1339 | | * for the user ID node. */ |
1340 | | gpg_error_t |
1341 | | internal_keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb) |
1342 | 0 | { |
1343 | 0 | gpg_error_t err = 0; |
1344 | |
|
1345 | 0 | log_assert (!hd->use_keyboxd); |
1346 | | |
1347 | 0 | if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED) |
1348 | 0 | { |
1349 | 0 | err = iobuf_seek (hd->keyblock_cache.iobuf, 0); |
1350 | 0 | if (err) |
1351 | 0 | { |
1352 | 0 | log_error ("keydb_get_keyblock: failed to rewind iobuf for cache\n"); |
1353 | 0 | keyblock_cache_clear (hd); |
1354 | 0 | } |
1355 | 0 | else |
1356 | 0 | { |
1357 | 0 | err = keydb_parse_keyblock (hd->keyblock_cache.iobuf, |
1358 | 0 | hd->keyblock_cache.pk_no, |
1359 | 0 | hd->keyblock_cache.uid_no, |
1360 | 0 | ret_kb); |
1361 | 0 | if (err) |
1362 | 0 | keyblock_cache_clear (hd); |
1363 | 0 | if (DBG_CLOCK) |
1364 | 0 | log_clock ("%s leave (cached mode)", __func__); |
1365 | 0 | return err; |
1366 | 0 | } |
1367 | 0 | } |
1368 | | |
1369 | 0 | if (hd->found < 0 || hd->found >= hd->used) |
1370 | 0 | return gpg_error (GPG_ERR_VALUE_NOT_FOUND); |
1371 | | |
1372 | 0 | switch (hd->active[hd->found].type) |
1373 | 0 | { |
1374 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1375 | 0 | err = gpg_error (GPG_ERR_GENERAL); /* oops */ |
1376 | 0 | break; |
1377 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1378 | 0 | err = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb); |
1379 | 0 | break; |
1380 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1381 | 0 | { |
1382 | 0 | iobuf_t iobuf; |
1383 | 0 | int pk_no, uid_no; |
1384 | |
|
1385 | 0 | err = keybox_get_keyblock (hd->active[hd->found].u.kb, |
1386 | 0 | &iobuf, &pk_no, &uid_no); |
1387 | 0 | if (!err) |
1388 | 0 | { |
1389 | 0 | err = keydb_parse_keyblock (iobuf, pk_no, uid_no, ret_kb); |
1390 | 0 | if (!err && hd->keyblock_cache.state == KEYBLOCK_CACHE_PREPARED) |
1391 | 0 | { |
1392 | 0 | hd->keyblock_cache.state = KEYBLOCK_CACHE_FILLED; |
1393 | 0 | hd->keyblock_cache.iobuf = iobuf; |
1394 | 0 | hd->keyblock_cache.pk_no = pk_no; |
1395 | 0 | hd->keyblock_cache.uid_no = uid_no; |
1396 | 0 | } |
1397 | 0 | else |
1398 | 0 | { |
1399 | 0 | iobuf_close (iobuf); |
1400 | 0 | } |
1401 | 0 | } |
1402 | 0 | } |
1403 | 0 | break; |
1404 | 0 | } |
1405 | | |
1406 | 0 | if (hd->keyblock_cache.state != KEYBLOCK_CACHE_FILLED) |
1407 | 0 | keyblock_cache_clear (hd); |
1408 | |
|
1409 | 0 | if (!err) |
1410 | 0 | keydb_stats.get_keyblocks++; |
1411 | |
|
1412 | 0 | return err; |
1413 | 0 | } |
1414 | | |
1415 | | |
1416 | | /* Update the keyblock KB (i.e., extract the fingerprint and find the |
1417 | | * corresponding keyblock in the keyring). |
1418 | | * keydb_update_keyblock diverts to here in the non-keyboxd mode. |
1419 | | * |
1420 | | * This doesn't do anything if --dry-run was specified. |
1421 | | * |
1422 | | * Returns 0 on success. Otherwise, it returns an error code. Note: |
1423 | | * if there isn't a keyblock in the keyring corresponding to KB, then |
1424 | | * this function returns GPG_ERR_VALUE_NOT_FOUND. |
1425 | | * |
1426 | | * This function selects the matching record and modifies the current |
1427 | | * file position to point to the record just after the selected entry. |
1428 | | * Thus, if you do a subsequent search using HD, you should first do a |
1429 | | * keydb_search_reset. Further, if the selected record is important, |
1430 | | * you should use keydb_push_found_state and keydb_pop_found_state to |
1431 | | * save and restore it. */ |
1432 | | gpg_error_t |
1433 | | internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb) |
1434 | 0 | { |
1435 | 0 | gpg_error_t err; |
1436 | 0 | PKT_public_key *pk; |
1437 | 0 | KEYDB_SEARCH_DESC desc; |
1438 | 0 | size_t len; |
1439 | |
|
1440 | 0 | log_assert (!hd->use_keyboxd); |
1441 | | |
1442 | 0 | if (!hd->locked) |
1443 | 0 | return gpg_error (GPG_ERR_NOT_LOCKED); |
1444 | | |
1445 | 0 | pk = kb->pkt->pkt.public_key; |
1446 | |
|
1447 | 0 | kid_not_found_flush (); |
1448 | 0 | keyblock_cache_clear (hd); |
1449 | |
|
1450 | 0 | if (opt.dry_run) |
1451 | 0 | return 0; |
1452 | | |
1453 | | #ifdef USE_TOFU |
1454 | | tofu_notice_key_changed (ctrl, kb); |
1455 | | #else |
1456 | 0 | (void)ctrl; |
1457 | 0 | #endif |
1458 | |
|
1459 | 0 | memset (&desc, 0, sizeof (desc)); |
1460 | 0 | fingerprint_from_pk (pk, desc.u.fpr, &len); |
1461 | 0 | if (len == 20 || len == 32) |
1462 | 0 | { |
1463 | 0 | desc.mode = KEYDB_SEARCH_MODE_FPR; |
1464 | 0 | desc.fprlen = len; |
1465 | 0 | } |
1466 | 0 | else |
1467 | 0 | log_bug ("%s: Unsupported key length: %zu\n", __func__, len); |
1468 | | |
1469 | 0 | keydb_search_reset (hd); |
1470 | 0 | err = keydb_search (hd, &desc, 1, NULL); |
1471 | 0 | if (err) |
1472 | 0 | return gpg_error (GPG_ERR_VALUE_NOT_FOUND); |
1473 | 0 | log_assert (hd->found >= 0 && hd->found < hd->used); |
1474 | | |
1475 | 0 | switch (hd->active[hd->found].type) |
1476 | 0 | { |
1477 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1478 | 0 | err = gpg_error (GPG_ERR_GENERAL); /* oops */ |
1479 | 0 | break; |
1480 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1481 | 0 | err = keyring_update_keyblock (hd->active[hd->found].u.kr, kb); |
1482 | 0 | break; |
1483 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1484 | 0 | { |
1485 | 0 | iobuf_t iobuf; |
1486 | |
|
1487 | 0 | err = build_keyblock_image (kb, &iobuf); |
1488 | 0 | if (!err) |
1489 | 0 | { |
1490 | 0 | keydb_stats.build_keyblocks++; |
1491 | 0 | err = keybox_update_keyblock (hd->active[hd->found].u.kb, |
1492 | 0 | iobuf_get_temp_buffer (iobuf), |
1493 | 0 | iobuf_get_temp_length (iobuf)); |
1494 | 0 | iobuf_close (iobuf); |
1495 | 0 | } |
1496 | 0 | } |
1497 | 0 | break; |
1498 | 0 | } |
1499 | | |
1500 | 0 | if (!err) |
1501 | 0 | keydb_stats.update_keyblocks++; |
1502 | 0 | return err; |
1503 | 0 | } |
1504 | | |
1505 | | |
1506 | | /* Insert a keyblock into one of the underlying keyrings or keyboxes. |
1507 | | * keydb_insert_keyblock diverts to here in the non-keyboxd mode. |
1508 | | * |
1509 | | * Be default, the keyring / keybox from which the last search result |
1510 | | * came is used. If there was no previous search result (or |
1511 | | * keydb_search_reset was called), then the keyring / keybox where the |
1512 | | * next search would start is used (i.e., the current file position). |
1513 | | * |
1514 | | * Note: this doesn't do anything if --dry-run was specified. |
1515 | | * |
1516 | | * Returns 0 on success. Otherwise, it returns an error code. */ |
1517 | | gpg_error_t |
1518 | | internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb) |
1519 | 0 | { |
1520 | 0 | gpg_error_t err = 0; |
1521 | 0 | int idx; |
1522 | |
|
1523 | 0 | log_assert (!hd->use_keyboxd); |
1524 | | |
1525 | 0 | if (!hd->locked) |
1526 | 0 | return gpg_error (GPG_ERR_NOT_LOCKED); |
1527 | | |
1528 | 0 | kid_not_found_flush (); |
1529 | 0 | keyblock_cache_clear (hd); |
1530 | |
|
1531 | 0 | if (opt.dry_run) |
1532 | 0 | return 0; |
1533 | | |
1534 | 0 | if (hd->found >= 0 && hd->found < hd->used) |
1535 | 0 | idx = hd->found; |
1536 | 0 | else if (hd->current >= 0 && hd->current < hd->used) |
1537 | 0 | idx = hd->current; |
1538 | 0 | else |
1539 | 0 | return gpg_error (GPG_ERR_GENERAL); |
1540 | | |
1541 | 0 | switch (hd->active[idx].type) |
1542 | 0 | { |
1543 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1544 | 0 | err = gpg_error (GPG_ERR_GENERAL); /* oops */ |
1545 | 0 | break; |
1546 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1547 | 0 | err = keyring_insert_keyblock (hd->active[idx].u.kr, kb); |
1548 | 0 | break; |
1549 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1550 | 0 | { /* We need to turn our kbnode_t list of packets into a proper |
1551 | | keyblock first. This is required by the OpenPGP key parser |
1552 | | included in the keybox code. Eventually we can change this |
1553 | | kludge to have the caller pass the image. */ |
1554 | 0 | iobuf_t iobuf; |
1555 | |
|
1556 | 0 | err = build_keyblock_image (kb, &iobuf); |
1557 | 0 | if (!err) |
1558 | 0 | { |
1559 | 0 | keydb_stats.build_keyblocks++; |
1560 | 0 | err = keybox_insert_keyblock (hd->active[idx].u.kb, |
1561 | 0 | iobuf_get_temp_buffer (iobuf), |
1562 | 0 | iobuf_get_temp_length (iobuf)); |
1563 | 0 | iobuf_close (iobuf); |
1564 | 0 | } |
1565 | 0 | } |
1566 | 0 | break; |
1567 | 0 | } |
1568 | | |
1569 | 0 | if (!err) |
1570 | 0 | keydb_stats.insert_keyblocks++; |
1571 | 0 | return err; |
1572 | 0 | } |
1573 | | |
1574 | | |
1575 | | /* Delete the currently selected keyblock. If you haven't done a |
1576 | | * search yet on this database handle (or called keydb_search_reset), |
1577 | | * then this will return an error. |
1578 | | * |
1579 | | * Returns 0 on success or an error code, if an error occurs. */ |
1580 | | gpg_error_t |
1581 | | internal_keydb_delete_keyblock (KEYDB_HANDLE hd) |
1582 | 0 | { |
1583 | 0 | gpg_error_t err = 0; |
1584 | |
|
1585 | 0 | log_assert (!hd->use_keyboxd); |
1586 | | |
1587 | 0 | if (!hd->locked) |
1588 | 0 | return gpg_error (GPG_ERR_NOT_LOCKED); |
1589 | | |
1590 | 0 | kid_not_found_flush (); |
1591 | 0 | keyblock_cache_clear (hd); |
1592 | |
|
1593 | 0 | if (hd->found < 0 || hd->found >= hd->used) |
1594 | 0 | return gpg_error (GPG_ERR_VALUE_NOT_FOUND); |
1595 | | |
1596 | 0 | if (opt.dry_run) |
1597 | 0 | return 0; |
1598 | | |
1599 | 0 | switch (hd->active[hd->found].type) |
1600 | 0 | { |
1601 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1602 | 0 | err = gpg_error (GPG_ERR_GENERAL); |
1603 | 0 | break; |
1604 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1605 | 0 | err = keyring_delete_keyblock (hd->active[hd->found].u.kr); |
1606 | 0 | break; |
1607 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1608 | 0 | err = keybox_delete (hd->active[hd->found].u.kb); |
1609 | 0 | break; |
1610 | 0 | } |
1611 | | |
1612 | 0 | if (!err) |
1613 | 0 | keydb_stats.delete_keyblocks++; |
1614 | 0 | return err; |
1615 | 0 | } |
1616 | | |
1617 | | |
1618 | | |
1619 | | /* A database may consists of multiple keyrings / key boxes. This |
1620 | | * sets the "file position" to the start of the first keyring / key |
1621 | | * box that is writable (i.e., doesn't have the read-only flag set). |
1622 | | * |
1623 | | * This first tries the primary keyring (the last keyring (not |
1624 | | * keybox!) added using keydb_add_resource() and with |
1625 | | * KEYDB_RESOURCE_FLAG_PRIMARY set). If that is not writable, then it |
1626 | | * tries the keyrings / keyboxes in the order in which they were |
1627 | | * added. */ |
1628 | | gpg_error_t |
1629 | | keydb_locate_writable (KEYDB_HANDLE hd) |
1630 | 0 | { |
1631 | 0 | gpg_error_t rc; |
1632 | |
|
1633 | 0 | if (!hd) |
1634 | 0 | return GPG_ERR_INV_ARG; |
1635 | | |
1636 | 0 | if (hd->use_keyboxd) |
1637 | 0 | return 0; /* No need for this here. */ |
1638 | | |
1639 | 0 | rc = keydb_search_reset (hd); /* this does reset hd->current */ |
1640 | 0 | if (rc) |
1641 | 0 | return rc; |
1642 | | |
1643 | | /* If we have a primary set, try that one first */ |
1644 | 0 | if (primary_keydb) |
1645 | 0 | { |
1646 | 0 | for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) |
1647 | 0 | { |
1648 | 0 | if(hd->active[hd->current].token == primary_keydb) |
1649 | 0 | { |
1650 | 0 | if(keyring_is_writable (hd->active[hd->current].token)) |
1651 | 0 | return 0; |
1652 | 0 | else |
1653 | 0 | break; |
1654 | 0 | } |
1655 | 0 | } |
1656 | | |
1657 | 0 | rc = keydb_search_reset (hd); /* this does reset hd->current */ |
1658 | 0 | if (rc) |
1659 | 0 | return rc; |
1660 | 0 | } |
1661 | | |
1662 | 0 | for ( ; hd->current >= 0 && hd->current < hd->used; hd->current++) |
1663 | 0 | { |
1664 | 0 | switch (hd->active[hd->current].type) |
1665 | 0 | { |
1666 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1667 | 0 | BUG(); |
1668 | 0 | break; |
1669 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1670 | 0 | if (keyring_is_writable (hd->active[hd->current].token)) |
1671 | 0 | return 0; /* found (hd->current is set to it) */ |
1672 | 0 | break; |
1673 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1674 | 0 | if (keybox_is_writable (hd->active[hd->current].token)) |
1675 | 0 | return 0; /* found (hd->current is set to it) */ |
1676 | 0 | break; |
1677 | 0 | } |
1678 | 0 | } |
1679 | | |
1680 | 0 | return gpg_error (GPG_ERR_NOT_FOUND); |
1681 | 0 | } |
1682 | | |
1683 | | |
1684 | | /* Rebuild the on-disk caches of all key resources. */ |
1685 | | void |
1686 | | keydb_rebuild_caches (ctrl_t ctrl, int noisy) |
1687 | 0 | { |
1688 | 0 | int i, rc; |
1689 | |
|
1690 | 0 | if (opt.use_keyboxd) |
1691 | 0 | return; /* No need for this here. */ |
1692 | | |
1693 | 0 | for (i=0; i < used_resources; i++) |
1694 | 0 | { |
1695 | 0 | if (!keyring_is_writable (all_resources[i].token)) |
1696 | 0 | continue; |
1697 | 0 | switch (all_resources[i].type) |
1698 | 0 | { |
1699 | 0 | case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ |
1700 | 0 | break; |
1701 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1702 | 0 | rc = keyring_rebuild_cache (ctrl, all_resources[i].token,noisy); |
1703 | 0 | if (rc) |
1704 | 0 | log_error (_("failed to rebuild keyring cache: %s\n"), |
1705 | 0 | gpg_strerror (rc)); |
1706 | 0 | break; |
1707 | 0 | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1708 | | /* N/A. */ |
1709 | 0 | break; |
1710 | 0 | } |
1711 | 0 | } |
1712 | 0 | } |
1713 | | |
1714 | | |
1715 | | /* Return the number of skipped blocks (because they were too large to |
1716 | | read from a keybox) since the last search reset. */ |
1717 | | unsigned long |
1718 | | keydb_get_skipped_counter (KEYDB_HANDLE hd) |
1719 | 0 | { |
1720 | | /*FIXME(keyboxd): Do we need this? */ |
1721 | 0 | return hd && !hd->use_keyboxd? hd->skipped_long_blobs : 0; |
1722 | 0 | } |
1723 | | |
1724 | | |
1725 | | /* Clears the current search result and resets the handle's position |
1726 | | * so that the next search starts at the beginning of the database |
1727 | | * (the start of the first resource). |
1728 | | * keydb_search_reset diverts to here in the non-keyboxd mode. |
1729 | | * |
1730 | | * Returns 0 on success and an error code if an error occurred. |
1731 | | * (Currently, this function always returns 0 if HD is valid.) */ |
1732 | | gpg_error_t |
1733 | | internal_keydb_search_reset (KEYDB_HANDLE hd) |
1734 | 31.1k | { |
1735 | 31.1k | gpg_error_t rc = 0; |
1736 | 31.1k | int i; |
1737 | | |
1738 | 31.1k | log_assert (!hd->use_keyboxd); |
1739 | | |
1740 | 31.1k | keyblock_cache_clear (hd); |
1741 | | |
1742 | 31.1k | hd->skipped_long_blobs = 0; |
1743 | 31.1k | hd->current = 0; |
1744 | 31.1k | hd->found = -1; |
1745 | | /* Now reset all resources. */ |
1746 | 62.2k | for (i=0; !rc && i < hd->used; i++) |
1747 | 31.1k | { |
1748 | 31.1k | switch (hd->active[i].type) |
1749 | 31.1k | { |
1750 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1751 | 0 | break; |
1752 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1753 | 0 | rc = keyring_search_reset (hd->active[i].u.kr); |
1754 | 0 | break; |
1755 | 31.1k | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1756 | 31.1k | rc = keybox_search_reset (hd->active[i].u.kb); |
1757 | 31.1k | break; |
1758 | 31.1k | } |
1759 | 31.1k | } |
1760 | 31.1k | hd->is_reset = 1; |
1761 | 31.1k | if (!rc) |
1762 | 31.1k | keydb_stats.search_resets++; |
1763 | 31.1k | return rc; |
1764 | 31.1k | } |
1765 | | |
1766 | | |
1767 | | /* Search the database for keys matching the search description. If |
1768 | | * the DB contains any legacy keys, these are silently ignored. |
1769 | | * keydb_search diverts to here in the non-keyboxd mode. |
1770 | | * |
1771 | | * DESC is an array of search terms with NDESC entries. The search |
1772 | | * terms are or'd together. That is, the next entry in the DB that |
1773 | | * matches any of the descriptions will be returned. |
1774 | | * |
1775 | | * Note: this function resumes searching where the last search left |
1776 | | * off (i.e., at the current file position). If you want to search |
1777 | | * from the start of the database, then you need to first call |
1778 | | * keydb_search_reset(). |
1779 | | * |
1780 | | * If no key matches the search description, returns |
1781 | | * GPG_ERR_NOT_FOUND. If there was a match, returns 0. If an error |
1782 | | * occurred, returns an error code. |
1783 | | * |
1784 | | * The returned key is considered to be selected and the raw data can, |
1785 | | * for instance, be returned by calling keydb_get_keyblock(). */ |
1786 | | gpg_error_t |
1787 | | internal_keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, |
1788 | | size_t ndesc, size_t *descindex) |
1789 | 56.4k | { |
1790 | 56.4k | gpg_error_t rc; |
1791 | 56.4k | int was_reset = hd->is_reset; |
1792 | | /* If an entry is already in the cache, then don't add it again. */ |
1793 | 56.4k | int already_in_cache = 0; |
1794 | 56.4k | int fprlen; |
1795 | | |
1796 | 56.4k | log_assert (!hd->use_keyboxd); |
1797 | | |
1798 | 56.4k | if (!any_registered) |
1799 | 0 | { |
1800 | 0 | write_status_error ("keydb_search", gpg_error (GPG_ERR_KEYRING_OPEN)); |
1801 | 0 | return gpg_error (GPG_ERR_NOT_FOUND); |
1802 | 0 | } |
1803 | | |
1804 | 56.4k | if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID |
1805 | 31.5k | && (already_in_cache = kid_not_found_p (desc[0].u.kid)) == 1 ) |
1806 | 31.3k | { |
1807 | 31.3k | if (DBG_CLOCK) |
1808 | 31.3k | log_clock ("%s leave (not found, cached)", __func__); |
1809 | 31.3k | keydb_stats.notfound_cached++; |
1810 | 31.3k | return gpg_error (GPG_ERR_NOT_FOUND); |
1811 | 31.3k | } |
1812 | | |
1813 | | /* NB: If one of the exact search modes below is used in a loop to |
1814 | | walk over all keys (with the same fingerprint) the caching must |
1815 | | have been disabled for the handle. */ |
1816 | 25.1k | if (desc[0].mode == KEYDB_SEARCH_MODE_FPR) |
1817 | 0 | fprlen = desc[0].fprlen; |
1818 | 25.1k | else |
1819 | 25.1k | fprlen = 0; |
1820 | | |
1821 | 25.1k | if (!hd->no_caching |
1822 | 25.1k | && ndesc == 1 |
1823 | 25.1k | && fprlen |
1824 | 0 | && hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED |
1825 | 0 | && hd->keyblock_cache.fprlen == fprlen |
1826 | 0 | && !memcmp (hd->keyblock_cache.fpr, desc[0].u.fpr, fprlen) |
1827 | | /* Make sure the current file position occurs before the cached |
1828 | | result to avoid an infinite loop. */ |
1829 | 0 | && (hd->current < hd->keyblock_cache.resource |
1830 | 0 | || (hd->current == hd->keyblock_cache.resource |
1831 | 0 | && (keybox_offset (hd->active[hd->current].u.kb) |
1832 | 0 | <= hd->keyblock_cache.offset)))) |
1833 | 0 | { |
1834 | | /* (DESCINDEX is already set). */ |
1835 | 0 | if (DBG_CLOCK) |
1836 | 0 | log_clock ("%s leave (cached)", __func__); |
1837 | |
|
1838 | 0 | hd->current = hd->keyblock_cache.resource; |
1839 | | /* HD->KEYBLOCK_CACHE.OFFSET is the last byte in the record. |
1840 | | Seek just beyond that. */ |
1841 | 0 | keybox_seek (hd->active[hd->current].u.kb, hd->keyblock_cache.offset + 1); |
1842 | 0 | keydb_stats.found_cached++; |
1843 | 0 | return 0; |
1844 | 0 | } |
1845 | | |
1846 | 25.1k | rc = -1; |
1847 | 50.2k | while ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) |
1848 | 50.2k | && hd->current >= 0 && hd->current < hd->used) |
1849 | 25.1k | { |
1850 | 25.1k | if (DBG_KEYDB) |
1851 | 25.1k | log_debug ("%s: searching %s (resource %d of %d)\n", |
1852 | 0 | __func__, |
1853 | 0 | hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYRING |
1854 | 0 | ? "keyring" |
1855 | 0 | : (hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX |
1856 | 0 | ? "keybox" : "unknown type"), |
1857 | 0 | hd->current, hd->used); |
1858 | | |
1859 | 25.1k | switch (hd->active[hd->current].type) |
1860 | 25.1k | { |
1861 | 0 | case KEYDB_RESOURCE_TYPE_NONE: |
1862 | 0 | BUG(); /* we should never see it here */ |
1863 | 0 | break; |
1864 | 0 | case KEYDB_RESOURCE_TYPE_KEYRING: |
1865 | 0 | rc = keyring_search (hd->active[hd->current].u.kr, desc, |
1866 | 0 | ndesc, descindex, 1); |
1867 | 0 | break; |
1868 | 25.1k | case KEYDB_RESOURCE_TYPE_KEYBOX: |
1869 | 25.1k | do |
1870 | 25.1k | rc = keybox_search (hd->active[hd->current].u.kb, desc, |
1871 | 25.1k | ndesc, KEYBOX_BLOBTYPE_PGP, |
1872 | 25.1k | descindex, &hd->skipped_long_blobs); |
1873 | 25.1k | while (rc == GPG_ERR_LEGACY_KEY); |
1874 | 25.1k | break; |
1875 | 25.1k | } |
1876 | | |
1877 | 25.1k | if (DBG_KEYDB) |
1878 | 25.1k | log_debug ("%s: searched %s (resource %d of %d) => %s\n", |
1879 | 0 | __func__, |
1880 | 0 | hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYRING |
1881 | 0 | ? "keyring" |
1882 | 0 | : (hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX |
1883 | 0 | ? "keybox" : "unknown type"), |
1884 | 0 | hd->current, hd->used, |
1885 | 0 | rc == -1 ? "EOF" : gpg_strerror (rc)); |
1886 | | |
1887 | 25.1k | if (rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) |
1888 | 25.1k | { |
1889 | | /* EOF -> switch to next resource */ |
1890 | 25.1k | hd->current++; |
1891 | 25.1k | } |
1892 | 0 | else if (!rc) |
1893 | 0 | hd->found = hd->current; |
1894 | 25.1k | } |
1895 | 25.1k | hd->is_reset = 0; |
1896 | | |
1897 | 25.1k | rc = ((rc == -1 || gpg_err_code (rc) == GPG_ERR_EOF) |
1898 | 25.1k | ? gpg_error (GPG_ERR_NOT_FOUND) |
1899 | 25.1k | : rc); |
1900 | | |
1901 | 25.1k | keyblock_cache_clear (hd); |
1902 | 25.1k | if (!hd->no_caching |
1903 | 25.1k | && !rc |
1904 | 0 | && ndesc == 1 |
1905 | 0 | && fprlen |
1906 | 0 | && hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX) |
1907 | 0 | { |
1908 | 0 | hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED; |
1909 | 0 | hd->keyblock_cache.resource = hd->current; |
1910 | | /* The current offset is at the start of the next record. Since |
1911 | | a record is at least 1 byte, we just use offset - 1, which is |
1912 | | within the record. */ |
1913 | 0 | hd->keyblock_cache.offset |
1914 | 0 | = keybox_offset (hd->active[hd->current].u.kb) - 1; |
1915 | 0 | memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, fprlen); |
1916 | 0 | hd->keyblock_cache.fprlen = fprlen; |
1917 | 0 | } |
1918 | | |
1919 | 25.1k | if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND |
1920 | 25.1k | && ndesc == 1 |
1921 | 25.1k | && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID |
1922 | 145 | && was_reset |
1923 | 145 | && !already_in_cache) |
1924 | 145 | kid_not_found_insert (desc[0].u.kid); |
1925 | | |
1926 | 25.1k | if (!rc) |
1927 | 0 | keydb_stats.found++; |
1928 | 25.1k | else |
1929 | 25.1k | keydb_stats.notfound++; |
1930 | 25.1k | return rc; |
1931 | 25.1k | } |
1932 | | |
1933 | | |
1934 | | /* Return the first non-legacy key in the database. |
1935 | | * |
1936 | | * If you want the very first key in the database, you can directly |
1937 | | * call keydb_search with the search description |
1938 | | * KEYDB_SEARCH_MODE_FIRST. */ |
1939 | | gpg_error_t |
1940 | | keydb_search_first (KEYDB_HANDLE hd) |
1941 | 1 | { |
1942 | 1 | gpg_error_t err; |
1943 | 1 | KEYDB_SEARCH_DESC desc; |
1944 | | |
1945 | 1 | err = keydb_search_reset (hd); |
1946 | 1 | if (err) |
1947 | 0 | return err; |
1948 | | |
1949 | 1 | memset (&desc, 0, sizeof desc); |
1950 | 1 | desc.mode = KEYDB_SEARCH_MODE_FIRST; |
1951 | 1 | return keydb_search (hd, &desc, 1, NULL); |
1952 | 1 | } |
1953 | | |
1954 | | |
1955 | | /* Return the next key (not the next matching key!). |
1956 | | * |
1957 | | * Unlike calling keydb_search with KEYDB_SEARCH_MODE_NEXT, this |
1958 | | * function silently skips legacy keys. */ |
1959 | | gpg_error_t |
1960 | | keydb_search_next (KEYDB_HANDLE hd) |
1961 | 0 | { |
1962 | 0 | KEYDB_SEARCH_DESC desc; |
1963 | |
|
1964 | 0 | memset (&desc, 0, sizeof desc); |
1965 | 0 | desc.mode = KEYDB_SEARCH_MODE_NEXT; |
1966 | 0 | return keydb_search (hd, &desc, 1, NULL); |
1967 | 0 | } |
1968 | | |
1969 | | |
1970 | | /* This is a convenience function for searching for keys with a long |
1971 | | * key id. |
1972 | | * |
1973 | | * Note: this function resumes searching where the last search left |
1974 | | * off. If you want to search the whole database, then you need to |
1975 | | * first call keydb_search_reset(). */ |
1976 | | gpg_error_t |
1977 | | keydb_search_kid (KEYDB_HANDLE hd, u32 *kid) |
1978 | 271 | { |
1979 | 271 | KEYDB_SEARCH_DESC desc; |
1980 | | |
1981 | 271 | memset (&desc, 0, sizeof desc); |
1982 | 271 | desc.mode = KEYDB_SEARCH_MODE_LONG_KID; |
1983 | 271 | desc.u.kid[0] = kid[0]; |
1984 | 271 | desc.u.kid[1] = kid[1]; |
1985 | 271 | return keydb_search (hd, &desc, 1, NULL); |
1986 | 271 | } |
1987 | | |
1988 | | |
1989 | | /* This is a convenience function for searching for keys with a long |
1990 | | * (20 byte) fingerprint. |
1991 | | * |
1992 | | * Note: this function resumes searching where the last search left |
1993 | | * off. If you want to search the whole database, then you need to |
1994 | | * first call keydb_search_reset(). */ |
1995 | | gpg_error_t |
1996 | | keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr, size_t fprlen) |
1997 | 0 | { |
1998 | 0 | KEYDB_SEARCH_DESC desc; |
1999 | |
|
2000 | 0 | memset (&desc, 0, sizeof desc); |
2001 | 0 | desc.mode = KEYDB_SEARCH_MODE_FPR; |
2002 | 0 | memcpy (desc.u.fpr, fpr, fprlen); |
2003 | 0 | desc.fprlen = fprlen; |
2004 | | return keydb_search (hd, &desc, 1, NULL); |
2005 | 0 | } |