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