Line data Source code
1 : /* trustlist.c - Maintain the list of trusted keys
2 : * Copyright (C) 2002, 2004, 2006, 2007, 2009,
3 : * 2012 Free Software Foundation, Inc.
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 <errno.h>
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <string.h>
26 : #include <ctype.h>
27 : #include <assert.h>
28 : #include <unistd.h>
29 : #include <sys/stat.h>
30 : #include <npth.h>
31 :
32 : #include "agent.h"
33 : #include <assuan.h> /* fixme: need a way to avoid assuan calls here */
34 : #include "i18n.h"
35 :
36 :
37 : /* A structure to store the information from the trust file. */
38 : struct trustitem_s
39 : {
40 : struct
41 : {
42 : int disabled:1; /* This entry is disabled. */
43 : int for_pgp:1; /* Set by '*' or 'P' as first flag. */
44 : int for_smime:1; /* Set by '*' or 'S' as first flag. */
45 : int relax:1; /* Relax checking of root certificate
46 : constraints. */
47 : int cm:1; /* Use chain model for validation. */
48 : } flags;
49 : unsigned char fpr[20]; /* The binary fingerprint. */
50 : };
51 : typedef struct trustitem_s trustitem_t;
52 :
53 : /* Malloced table and its allocated size with all trust items. */
54 : static trustitem_t *trusttable;
55 : static size_t trusttablesize;
56 : /* A mutex used to protect the table. */
57 : static npth_mutex_t trusttable_lock;
58 :
59 :
60 : static const char headerblurb[] =
61 : "# This is the list of trusted keys. Comment lines, like this one, as\n"
62 : "# well as empty lines are ignored. Lines have a length limit but this\n"
63 : "# is not a serious limitation as the format of the entries is fixed and\n"
64 : "# checked by gpg-agent. A non-comment line starts with optional white\n"
65 : "# space, followed by the SHA-1 fingerpint in hex, followed by a flag\n"
66 : "# which may be one of 'P', 'S' or '*' and optionally followed by a list of\n"
67 : "# other flags. The fingerprint may be prefixed with a '!' to mark the\n"
68 : "# key as not trusted. You should give the gpg-agent a HUP or run the\n"
69 : "# command \"gpgconf --reload gpg-agent\" after changing this file.\n"
70 : "\n\n"
71 : "# Include the default trust list\n"
72 : "include-default\n"
73 : "\n";
74 :
75 :
76 : /* This function must be called once to initialize this module. This
77 : has to be done before a second thread is spawned. We can't do the
78 : static initialization because Pth emulation code might not be able
79 : to do a static init; in particular, it is not possible for W32. */
80 : void
81 50 : initialize_module_trustlist (void)
82 : {
83 : static int initialized;
84 : int err;
85 :
86 50 : if (!initialized)
87 : {
88 50 : err = npth_mutex_init (&trusttable_lock, NULL);
89 50 : if (err)
90 0 : log_fatal ("failed to init mutex in %s: %s\n", __FILE__,strerror (err));
91 50 : initialized = 1;
92 : }
93 50 : }
94 :
95 :
96 :
97 :
98 : static void
99 0 : lock_trusttable (void)
100 : {
101 : int err;
102 :
103 0 : err = npth_mutex_lock (&trusttable_lock);
104 0 : if (err)
105 0 : log_fatal ("failed to acquire mutex in %s: %s\n", __FILE__, strerror (err));
106 0 : }
107 :
108 :
109 : static void
110 0 : unlock_trusttable (void)
111 : {
112 : int err;
113 :
114 0 : err = npth_mutex_unlock (&trusttable_lock);
115 0 : if (err)
116 0 : log_fatal ("failed to release mutex in %s: %s\n", __FILE__, strerror (err));
117 0 : }
118 :
119 :
120 : /* Clear the trusttable. The caller needs to make sure that the
121 : trusttable is locked. */
122 : static inline void
123 0 : clear_trusttable (void)
124 : {
125 0 : xfree (trusttable);
126 0 : trusttable = NULL;
127 0 : trusttablesize = 0;
128 0 : }
129 :
130 :
131 : static gpg_error_t
132 0 : read_one_trustfile (const char *fname, int allow_include,
133 : trustitem_t **addr_of_table,
134 : size_t *addr_of_tablesize,
135 : int *addr_of_tableidx)
136 : {
137 0 : gpg_error_t err = 0;
138 : estream_t fp;
139 : int n, c;
140 : char *p, line[256];
141 : trustitem_t *table, *ti;
142 : int tableidx;
143 : size_t tablesize;
144 0 : int lnr = 0;
145 :
146 0 : table = *addr_of_table;
147 0 : tablesize = *addr_of_tablesize;
148 0 : tableidx = *addr_of_tableidx;
149 :
150 0 : fp = es_fopen (fname, "r");
151 0 : if (!fp)
152 : {
153 0 : err = gpg_error_from_syserror ();
154 0 : log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
155 0 : goto leave;
156 : }
157 :
158 0 : while (es_fgets (line, DIM(line)-1, fp))
159 : {
160 0 : lnr++;
161 :
162 0 : n = strlen (line);
163 0 : if (!n || line[n-1] != '\n')
164 : {
165 : /* Eat until end of line. */
166 0 : while ( (c=es_getc (fp)) != EOF && c != '\n')
167 : ;
168 0 : err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
169 : : GPG_ERR_INCOMPLETE_LINE);
170 0 : log_error (_("file '%s', line %d: %s\n"),
171 : fname, lnr, gpg_strerror (err));
172 0 : continue;
173 : }
174 0 : line[--n] = 0; /* Chop the LF. */
175 0 : if (n && line[n-1] == '\r')
176 0 : line[--n] = 0; /* Chop an optional CR. */
177 :
178 : /* Allow for empty lines and spaces */
179 0 : for (p=line; spacep (p); p++)
180 : ;
181 0 : if (!*p || *p == '#')
182 0 : continue;
183 :
184 0 : if (!strncmp (p, "include-default", 15)
185 0 : && (!p[15] || spacep (p+15)))
186 : {
187 : char *etcname;
188 : gpg_error_t err2;
189 :
190 0 : if (!allow_include)
191 : {
192 0 : log_error (_("statement \"%s\" ignored in '%s', line %d\n"),
193 : "include-default", fname, lnr);
194 0 : continue;
195 : }
196 : /* fixme: Should check for trailing garbage. */
197 :
198 0 : etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
199 0 : if ( !strcmp (etcname, fname) ) /* Same file. */
200 0 : log_info (_("statement \"%s\" ignored in '%s', line %d\n"),
201 : "include-default", fname, lnr);
202 0 : else if ( access (etcname, F_OK) && errno == ENOENT )
203 : {
204 : /* A non existent system trustlist is not an error.
205 : Just print a note. */
206 0 : log_info (_("system trustlist '%s' not available\n"), etcname);
207 : }
208 : else
209 : {
210 0 : err2 = read_one_trustfile (etcname, 0,
211 : &table, &tablesize, &tableidx);
212 0 : if (err2)
213 0 : err = err2;
214 : }
215 0 : xfree (etcname);
216 :
217 0 : continue;
218 : }
219 :
220 0 : if (tableidx == tablesize) /* Need more space. */
221 : {
222 : trustitem_t *tmp;
223 : size_t tmplen;
224 :
225 0 : tmplen = tablesize + 20;
226 0 : tmp = xtryrealloc (table, tmplen * sizeof *table);
227 0 : if (!tmp)
228 : {
229 0 : err = gpg_error_from_syserror ();
230 0 : goto leave;
231 : }
232 0 : table = tmp;
233 0 : tablesize = tmplen;
234 : }
235 :
236 0 : ti = table + tableidx;
237 :
238 0 : memset (&ti->flags, 0, sizeof ti->flags);
239 0 : if (*p == '!')
240 : {
241 0 : ti->flags.disabled = 1;
242 0 : p++;
243 0 : while (spacep (p))
244 0 : p++;
245 : }
246 :
247 0 : n = hexcolon2bin (p, ti->fpr, 20);
248 0 : if (n < 0)
249 : {
250 0 : log_error (_("bad fingerprint in '%s', line %d\n"), fname, lnr);
251 0 : err = gpg_error (GPG_ERR_BAD_DATA);
252 0 : continue;
253 : }
254 0 : p += n;
255 0 : for (; spacep (p); p++)
256 : ;
257 :
258 : /* Process the first flag which needs to be the first for
259 : backward compatibility. */
260 0 : if (!*p || *p == '*' )
261 : {
262 0 : ti->flags.for_smime = 1;
263 0 : ti->flags.for_pgp = 1;
264 : }
265 0 : else if ( *p == 'P' || *p == 'p')
266 : {
267 0 : ti->flags.for_pgp = 1;
268 : }
269 0 : else if ( *p == 'S' || *p == 's')
270 : {
271 0 : ti->flags.for_smime = 1;
272 : }
273 : else
274 : {
275 0 : log_error (_("invalid keyflag in '%s', line %d\n"), fname, lnr);
276 0 : err = gpg_error (GPG_ERR_BAD_DATA);
277 0 : continue;
278 : }
279 0 : p++;
280 0 : if ( *p && !spacep (p) )
281 : {
282 0 : log_error (_("invalid keyflag in '%s', line %d\n"), fname, lnr);
283 0 : err = gpg_error (GPG_ERR_BAD_DATA);
284 0 : continue;
285 : }
286 :
287 : /* Now check for more key-value pairs of the form NAME[=VALUE]. */
288 0 : while (*p)
289 : {
290 0 : for (; spacep (p); p++)
291 : ;
292 0 : if (!*p)
293 0 : break;
294 0 : n = strcspn (p, "= \t");
295 0 : if (p[n] == '=')
296 : {
297 0 : log_error ("assigning a value to a flag is not yet supported; "
298 : "in '%s', line %d\n", fname, lnr);
299 0 : err = gpg_error (GPG_ERR_BAD_DATA);
300 0 : p++;
301 : }
302 0 : else if (n == 5 && !memcmp (p, "relax", 5))
303 0 : ti->flags.relax = 1;
304 0 : else if (n == 2 && !memcmp (p, "cm", 2))
305 0 : ti->flags.cm = 1;
306 : else
307 0 : log_error ("flag '%.*s' in '%s', line %d ignored\n",
308 : n, p, fname, lnr);
309 0 : p += n;
310 : }
311 0 : tableidx++;
312 : }
313 0 : if ( !err && !es_feof (fp) )
314 : {
315 0 : err = gpg_error_from_syserror ();
316 0 : log_error (_("error reading '%s', line %d: %s\n"),
317 : fname, lnr, gpg_strerror (err));
318 : }
319 :
320 : leave:
321 0 : es_fclose (fp);
322 0 : *addr_of_table = table;
323 0 : *addr_of_tablesize = tablesize;
324 0 : *addr_of_tableidx = tableidx;
325 0 : return err;
326 : }
327 :
328 :
329 : /* Read the trust files and update the global table on success. The
330 : trusttable is assumed to be locked. */
331 : static gpg_error_t
332 0 : read_trustfiles (void)
333 : {
334 : gpg_error_t err;
335 : trustitem_t *table, *ti;
336 : int tableidx;
337 : size_t tablesize;
338 : char *fname;
339 0 : int allow_include = 1;
340 :
341 0 : tablesize = 20;
342 0 : table = xtrycalloc (tablesize, sizeof *table);
343 0 : if (!table)
344 0 : return gpg_error_from_syserror ();
345 0 : tableidx = 0;
346 :
347 0 : fname = make_filename_try (gnupg_homedir (), "trustlist.txt", NULL);
348 0 : if (!fname)
349 : {
350 0 : err = gpg_error_from_syserror ();
351 0 : xfree (table);
352 0 : return err;
353 : }
354 :
355 0 : if ( access (fname, F_OK) )
356 : {
357 0 : if ( errno == ENOENT )
358 : ; /* Silently ignore a non-existing trustfile. */
359 : else
360 : {
361 0 : err = gpg_error_from_syserror ();
362 0 : log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
363 : }
364 0 : xfree (fname);
365 0 : fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
366 0 : allow_include = 0;
367 : }
368 0 : err = read_one_trustfile (fname, allow_include,
369 : &table, &tablesize, &tableidx);
370 0 : xfree (fname);
371 :
372 0 : if (err)
373 : {
374 0 : xfree (table);
375 0 : if (gpg_err_code (err) == GPG_ERR_ENOENT)
376 : {
377 : /* Take a missing trustlist as an empty one. */
378 0 : clear_trusttable ();
379 0 : err = 0;
380 : }
381 0 : return err;
382 : }
383 :
384 : /* Fixme: we should drop duplicates and sort the table. */
385 0 : ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table);
386 0 : if (!ti)
387 : {
388 0 : err = gpg_error_from_syserror ();
389 0 : xfree (table);
390 0 : return err;
391 : }
392 :
393 : /* Replace the trusttable. */
394 0 : xfree (trusttable);
395 0 : trusttable = ti;
396 0 : trusttablesize = tableidx;
397 0 : return 0;
398 : }
399 :
400 :
401 : /* Check whether the given fpr is in our trustdb. We expect FPR to be
402 : an all uppercase hexstring of 40 characters. If ALREADY_LOCKED is
403 : true the function assumes that the trusttable is already locked. */
404 : static gpg_error_t
405 0 : istrusted_internal (ctrl_t ctrl, const char *fpr, int *r_disabled,
406 : int already_locked)
407 : {
408 0 : gpg_error_t err = 0;
409 0 : int locked = already_locked;
410 : trustitem_t *ti;
411 : size_t len;
412 : unsigned char fprbin[20];
413 :
414 0 : if (r_disabled)
415 0 : *r_disabled = 0;
416 :
417 0 : if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
418 : {
419 0 : err = gpg_error (GPG_ERR_INV_VALUE);
420 0 : goto leave;
421 : }
422 :
423 0 : if (!already_locked)
424 : {
425 0 : lock_trusttable ();
426 0 : locked = 1;
427 : }
428 :
429 0 : if (!trusttable)
430 : {
431 0 : err = read_trustfiles ();
432 0 : if (err)
433 : {
434 0 : log_error (_("error reading list of trusted root certificates\n"));
435 0 : goto leave;
436 : }
437 : }
438 :
439 0 : if (trusttable)
440 : {
441 0 : for (ti=trusttable, len = trusttablesize; len; ti++, len--)
442 0 : if (!memcmp (ti->fpr, fprbin, 20))
443 : {
444 0 : if (ti->flags.disabled && r_disabled)
445 0 : *r_disabled = 1;
446 :
447 : /* Print status messages only if we have not been called
448 : in a locked state. */
449 0 : if (already_locked)
450 : ;
451 0 : else if (ti->flags.relax)
452 : {
453 0 : unlock_trusttable ();
454 0 : locked = 0;
455 0 : err = agent_write_status (ctrl, "TRUSTLISTFLAG", "relax", NULL);
456 : }
457 0 : else if (ti->flags.cm)
458 : {
459 0 : unlock_trusttable ();
460 0 : locked = 0;
461 0 : err = agent_write_status (ctrl, "TRUSTLISTFLAG", "cm", NULL);
462 : }
463 :
464 0 : if (!err)
465 0 : err = ti->flags.disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
466 0 : goto leave;
467 : }
468 : }
469 0 : err = gpg_error (GPG_ERR_NOT_TRUSTED);
470 :
471 : leave:
472 0 : if (locked && !already_locked)
473 0 : unlock_trusttable ();
474 0 : return err;
475 : }
476 :
477 :
478 : /* Check whether the given fpr is in our trustdb. We expect FPR to be
479 : an all uppercase hexstring of 40 characters. */
480 : gpg_error_t
481 0 : agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
482 : {
483 0 : return istrusted_internal (ctrl, fpr, r_disabled, 0);
484 : }
485 :
486 :
487 : /* Write all trust entries to FP. */
488 : gpg_error_t
489 0 : agent_listtrusted (void *assuan_context)
490 : {
491 : trustitem_t *ti;
492 : char key[51];
493 : gpg_error_t err;
494 : size_t len;
495 :
496 0 : lock_trusttable ();
497 0 : if (!trusttable)
498 : {
499 0 : err = read_trustfiles ();
500 0 : if (err)
501 : {
502 0 : unlock_trusttable ();
503 0 : log_error (_("error reading list of trusted root certificates\n"));
504 0 : return err;
505 : }
506 : }
507 :
508 0 : if (trusttable)
509 : {
510 0 : for (ti=trusttable, len = trusttablesize; len; ti++, len--)
511 : {
512 0 : if (ti->flags.disabled)
513 0 : continue;
514 0 : bin2hex (ti->fpr, 20, key);
515 0 : key[40] = ' ';
516 0 : key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*'
517 0 : : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' ');
518 0 : key[42] = '\n';
519 0 : assuan_send_data (assuan_context, key, 43);
520 0 : assuan_send_data (assuan_context, NULL, 0); /* flush */
521 : }
522 : }
523 :
524 0 : unlock_trusttable ();
525 0 : return 0;
526 : }
527 :
528 :
529 : /* Create a copy of string with colons inserted after each two bytes.
530 : Caller needs to release the string. In case of a memory failure,
531 : NULL is returned. */
532 : static char *
533 0 : insert_colons (const char *string)
534 : {
535 : char *buffer, *p;
536 0 : size_t n = strlen (string);
537 0 : size_t nnew = n + (n+1)/2;
538 :
539 0 : p = buffer = xtrymalloc ( nnew + 1 );
540 0 : if (!buffer)
541 0 : return NULL;
542 0 : while (*string)
543 : {
544 0 : *p++ = *string++;
545 0 : if (*string)
546 : {
547 0 : *p++ = *string++;
548 0 : if (*string)
549 0 : *p++ = ':';
550 : }
551 : }
552 0 : *p = 0;
553 0 : assert (strlen (buffer) <= nnew);
554 :
555 0 : return buffer;
556 : }
557 :
558 :
559 : /* To pretty print DNs in the Pinentry, we replace slashes by
560 : REPLSTRING. The caller needs to free the returned string. NULL is
561 : returned on error with ERRNO set. */
562 : static char *
563 0 : reformat_name (const char *name, const char *replstring)
564 : {
565 : const char *s;
566 : char *newname;
567 : char *d;
568 : size_t count;
569 0 : size_t replstringlen = strlen (replstring);
570 :
571 : /* If the name does not start with a slash it is not a preformatted
572 : DN and thus we don't bother to reformat it. */
573 0 : if (*name != '/')
574 0 : return xtrystrdup (name);
575 :
576 : /* Count the names. Note that a slash contained in a DN part is
577 : expected to be C style escaped and thus the slashes we see here
578 : are the actual part delimiters. */
579 0 : for (s=name+1, count=0; *s; s++)
580 0 : if (*s == '/')
581 0 : count++;
582 0 : newname = xtrymalloc (strlen (name) + count*replstringlen + 1);
583 0 : if (!newname)
584 0 : return NULL;
585 0 : for (s=name+1, d=newname; *s; s++)
586 0 : if (*s == '/')
587 0 : d = stpcpy (d, replstring);
588 : else
589 0 : *d++ = *s;
590 0 : *d = 0;
591 0 : return newname;
592 : }
593 :
594 :
595 : /* Insert the given fpr into our trustdb. We expect FPR to be an all
596 : uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
597 : This function does first check whether that key has already been
598 : put into the trustdb and returns success in this case. Before a
599 : FPR actually gets inserted, the user is asked by means of the
600 : Pinentry whether this is actual what he wants to do. */
601 : gpg_error_t
602 0 : agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
603 : {
604 0 : gpg_error_t err = 0;
605 : char *desc;
606 : char *fname;
607 : estream_t fp;
608 : char *fprformatted;
609 : char *nameformatted;
610 : int is_disabled;
611 : int yes_i_trust;
612 :
613 : /* Check whether we are at all allowed to modify the trustlist.
614 : This is useful so that the trustlist may be a symlink to a global
615 : trustlist with only admin priviliges to modify it. Of course
616 : this is not a secure way of denying access, but it avoids the
617 : usual clicking on an Okay button most users are used to. */
618 0 : fname = make_filename_try (gnupg_homedir (), "trustlist.txt", NULL);
619 0 : if (!fname)
620 0 : return gpg_error_from_syserror ();
621 :
622 0 : if ( access (fname, W_OK) && errno != ENOENT)
623 : {
624 0 : xfree (fname);
625 0 : return gpg_error (GPG_ERR_EPERM);
626 : }
627 0 : xfree (fname);
628 :
629 0 : if (!agent_istrusted (ctrl, fpr, &is_disabled))
630 : {
631 0 : return 0; /* We already got this fingerprint. Silently return
632 : success. */
633 : }
634 :
635 : /* This feature must explicitly been enabled. */
636 0 : if (!opt.allow_mark_trusted)
637 0 : return gpg_error (GPG_ERR_NOT_SUPPORTED);
638 :
639 0 : if (is_disabled)
640 : {
641 : /* There is an disabled entry in the trustlist. Return an error
642 : so that the user won't be asked again for that one. Changing
643 : this flag with the integrated marktrusted feature is and will
644 : not be made possible. */
645 0 : return gpg_error (GPG_ERR_NOT_TRUSTED);
646 : }
647 :
648 :
649 : /* Insert a new one. */
650 0 : nameformatted = reformat_name (name, "%0A ");
651 0 : if (!nameformatted)
652 0 : return gpg_error_from_syserror ();
653 :
654 : /* First a general question whether this is trusted. */
655 0 : desc = xtryasprintf (
656 : /* TRANSLATORS: This prompt is shown by the Pinentry
657 : and has one special property: A "%%0A" is used by
658 : Pinentry to insert a line break. The double
659 : percent sign is actually needed because it is also
660 : a printf format string. If you need to insert a
661 : plain % sign, you need to encode it as "%%25". The
662 : "%s" gets replaced by the name as stored in the
663 : certificate. */
664 : L_("Do you ultimately trust%%0A"
665 : " \"%s\"%%0A"
666 : "to correctly certify user certificates?"),
667 : nameformatted);
668 0 : if (!desc)
669 : {
670 0 : xfree (nameformatted);
671 0 : return out_of_core ();
672 : }
673 0 : err = agent_get_confirmation (ctrl, desc, L_("Yes"), L_("No"), 1);
674 0 : xfree (desc);
675 0 : if (!err)
676 0 : yes_i_trust = 1;
677 0 : else if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED)
678 0 : yes_i_trust = 0;
679 : else
680 : {
681 0 : xfree (nameformatted);
682 0 : return err;
683 : }
684 :
685 :
686 0 : fprformatted = insert_colons (fpr);
687 0 : if (!fprformatted)
688 : {
689 0 : xfree (nameformatted);
690 0 : return out_of_core ();
691 : }
692 :
693 : /* If the user trusts this certificate he has to verify the
694 : fingerprint of course. */
695 0 : if (yes_i_trust)
696 : {
697 0 : desc = xtryasprintf
698 : (
699 : /* TRANSLATORS: This prompt is shown by the Pinentry and has
700 : one special property: A "%%0A" is used by Pinentry to
701 : insert a line break. The double percent sign is actually
702 : needed because it is also a printf format string. If you
703 : need to insert a plain % sign, you need to encode it as
704 : "%%25". The second "%s" gets replaced by a hexdecimal
705 : fingerprint string whereas the first one receives the name
706 : as stored in the certificate. */
707 : L_("Please verify that the certificate identified as:%%0A"
708 : " \"%s\"%%0A"
709 : "has the fingerprint:%%0A"
710 : " %s"), nameformatted, fprformatted);
711 0 : if (!desc)
712 : {
713 0 : xfree (fprformatted);
714 0 : xfree (nameformatted);
715 0 : return out_of_core ();
716 : }
717 :
718 : /* TRANSLATORS: "Correct" is the label of a button and intended
719 : to be hit if the fingerprint matches the one of the CA. The
720 : other button is "the default "Cancel" of the Pinentry. */
721 0 : err = agent_get_confirmation (ctrl, desc, L_("Correct"), L_("Wrong"), 1);
722 0 : xfree (desc);
723 0 : if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED)
724 0 : yes_i_trust = 0;
725 0 : else if (err)
726 : {
727 0 : xfree (fprformatted);
728 0 : xfree (nameformatted);
729 0 : return err;
730 : }
731 : }
732 :
733 :
734 : /* Now check again to avoid duplicates. We take the lock to make
735 : sure that nobody else plays with our file and force a reread. */
736 0 : lock_trusttable ();
737 0 : clear_trusttable ();
738 0 : if (!istrusted_internal (ctrl, fpr, &is_disabled, 1) || is_disabled)
739 : {
740 0 : unlock_trusttable ();
741 0 : xfree (fprformatted);
742 0 : xfree (nameformatted);
743 0 : return is_disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
744 : }
745 :
746 0 : fname = make_filename_try (gnupg_homedir (), "trustlist.txt", NULL);
747 0 : if (!fname)
748 : {
749 0 : err = gpg_error_from_syserror ();
750 0 : unlock_trusttable ();
751 0 : xfree (fprformatted);
752 0 : xfree (nameformatted);
753 0 : return err;
754 : }
755 0 : if ( access (fname, F_OK) && errno == ENOENT)
756 : {
757 0 : fp = es_fopen (fname, "wx,mode=-rw-r");
758 0 : if (!fp)
759 : {
760 0 : err = gpg_error_from_syserror ();
761 0 : log_error ("can't create '%s': %s\n", fname, gpg_strerror (err));
762 0 : xfree (fname);
763 0 : unlock_trusttable ();
764 0 : xfree (fprformatted);
765 0 : xfree (nameformatted);
766 0 : return err;
767 : }
768 0 : es_fputs (headerblurb, fp);
769 0 : es_fclose (fp);
770 : }
771 0 : fp = es_fopen (fname, "a+,mode=-rw-r");
772 0 : if (!fp)
773 : {
774 0 : err = gpg_error_from_syserror ();
775 0 : log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
776 0 : xfree (fname);
777 0 : unlock_trusttable ();
778 0 : xfree (fprformatted);
779 0 : xfree (nameformatted);
780 0 : return err;
781 : }
782 :
783 : /* Append the key. */
784 0 : es_fputs ("\n# ", fp);
785 0 : xfree (nameformatted);
786 0 : nameformatted = reformat_name (name, "\n# ");
787 0 : if (!nameformatted || strchr (name, '\n'))
788 : {
789 : /* Note that there should never be a LF in NAME but we better
790 : play safe and print a sanitized version in this case. */
791 0 : es_write_sanitized (fp, name, strlen (name), NULL, NULL);
792 : }
793 : else
794 0 : es_fputs (nameformatted, fp);
795 0 : es_fprintf (fp, "\n%s%s %c%s\n", yes_i_trust?"":"!", fprformatted, flag,
796 : flag == 'S'? " relax":"");
797 0 : if (es_ferror (fp))
798 0 : err = gpg_error_from_syserror ();
799 :
800 0 : if (es_fclose (fp))
801 0 : err = gpg_error_from_syserror ();
802 :
803 0 : clear_trusttable ();
804 0 : xfree (fname);
805 0 : unlock_trusttable ();
806 0 : xfree (fprformatted);
807 0 : xfree (nameformatted);
808 0 : if (!err)
809 0 : bump_key_eventcounter ();
810 0 : return err;
811 : }
812 :
813 :
814 : /* This function may be called to force reloading of the
815 : trustlist. */
816 : void
817 0 : agent_reload_trustlist (void)
818 : {
819 : /* All we need to do is to delete the trusttable. At the next
820 : access it will get re-read. */
821 0 : lock_trusttable ();
822 0 : clear_trusttable ();
823 0 : unlock_trusttable ();
824 0 : bump_key_eventcounter ();
825 0 : }
|