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