b5bafa9cbcb2dfe2ef7e1a16f38a16848909f1b8
[gnupg.git] / agent / trustlist.c
1 /* trustlist.c - Maintain the list of trusted keys
2  *      Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <assert.h>
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <pth.h>
32
33 #include "agent.h"
34 #include <assuan.h> /* fixme: need a way to avoid assuan calls here */
35 #include "i18n.h"
36
37
38 /* A structure to store the information from the trust file. */
39 struct trustitem_s
40 {
41   struct
42   {
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   } flags;
48   unsigned char fpr[20];  /* The binary fingerprint. */
49 };
50 typedef struct trustitem_s trustitem_t;
51
52 /* Malloced table and its allocated size with all trust items. */
53 static trustitem_t *trusttable; 
54 static size_t trusttablesize; 
55 /* A mutex used to protect the table. */
56 static pth_mutex_t trusttable_lock = PTH_MUTEX_INIT;
57
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 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, optionally followed\n"
66 "# by a flag character which my either be 'P', 'S' or '*'.  You should\n"
67 "# give the gpg-agent a HUP after editing this file.\n"
68 "\n\n"
69 "# Include the default trust list\n"
70 "include-default\n"
71 "\n";
72
73
74
75 \f
76 static void
77 lock_trusttable (void)
78 {
79   if (!pth_mutex_acquire (&trusttable_lock, 0, NULL))
80     log_fatal ("failed to acquire mutex in %s\n", __FILE__);
81 }
82
83 static void
84 unlock_trusttable (void)
85 {
86   if (!pth_mutex_release (&trusttable_lock))
87     log_fatal ("failed to release mutex in %s\n", __FILE__);
88 }
89
90
91
92 static gpg_error_t
93 read_one_trustfile (const char *fname, int allow_include,
94                     trustitem_t **addr_of_table, 
95                     size_t *addr_of_tablesize,
96                     int *addr_of_tableidx)
97 {
98   gpg_error_t err = 0;
99   FILE *fp;
100   int n, c;
101   char *p, line[256];
102   trustitem_t *table, *ti;
103   int tableidx;
104   size_t tablesize;
105   int lnr = 0;
106
107   table = *addr_of_table;
108   tablesize = *addr_of_tablesize;
109   tableidx = *addr_of_tableidx;
110
111   fp = fopen (fname, "r");
112   if (!fp)
113     {
114       err = gpg_error_from_syserror ();
115       log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
116       goto leave;
117     }
118
119   while (fgets (line, DIM(line)-1, fp))
120     {
121       lnr++;
122       
123       if (!*line || line[strlen(line)-1] != '\n')
124         {
125           /* Eat until end of line. */
126           while ( (c=getc (fp)) != EOF && c != '\n')
127             ;
128           err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
129                            : GPG_ERR_INCOMPLETE_LINE);
130           log_error (_("file `%s', line %d: %s\n"),
131                      fname, lnr, gpg_strerror (err));
132           continue;
133         }
134       line[strlen(line)-1] = 0; /* Chop the LF. */
135       
136       /* Allow for empty lines and spaces */
137       for (p=line; spacep (p); p++)
138         ;
139       if (!*p || *p == '#')
140         continue;
141   
142       if (!strncmp (p, "include-default", 15)
143           && (!p[15] || spacep (p+15)))
144         {
145           char *etcname;
146           gpg_error_t err2;
147
148           if (!allow_include)
149             {
150               log_error (_("statement \"%s\" ignored in `%s', line %d\n"),
151                          "include-default", fname, lnr);
152               continue;
153             }
154           /* fixme: Should check for trailing garbage.  */
155
156           etcname = make_filename (GNUPG_SYSCONFDIR, "trustlist.txt", NULL);
157           if ( !strcmp (etcname, fname) ) /* Same file. */
158             log_info (_("statement \"%s\" ignored in `%s', line %d\n"),
159                       "include-default", fname, lnr);
160           else if ( access (etcname, F_OK) && errno == ENOENT )
161             {
162               /* A non existent system trustlist is not an error.
163                  Just print a note. */
164               log_info (_("system trustlist `%s' not available\n"), etcname);
165             }
166           else
167             {
168               err2 = read_one_trustfile (etcname, 0,
169                                          &table, &tablesize, &tableidx);
170               if (err2)
171                 err = err2;
172             }
173           xfree (etcname);
174           
175           continue;
176         }
177
178       if (tableidx == tablesize)  /* Need more space. */
179         {
180           trustitem_t *tmp;
181           size_t tmplen;
182           
183           tmplen = tablesize + 20;
184           tmp = xtryrealloc (table, tmplen * sizeof *table);
185           if (!tmp)
186             {
187               err = gpg_error_from_syserror ();
188               goto leave;
189             }
190           table = tmp;
191           tablesize = tmplen;
192         }
193
194       ti = table + tableidx;
195
196       n = hexcolon2bin (p, ti->fpr, 20);
197       if (n < 0)
198         {
199           log_error (_("bad fingerprint in `%s', line %d\n"), fname, lnr);
200           err = gpg_error (GPG_ERR_BAD_DATA); 
201           continue;
202         }
203       p += n;
204       for (; spacep (p); p++)
205         ;
206       
207       memset (&ti->flags, 0, sizeof ti->flags);
208       /* Process the first flag which needs to be the first for
209          backward compatibility. */
210       if (!*p || *p == '*' )
211         {
212           ti->flags.for_smime = 1;
213           ti->flags.for_pgp = 1;
214         }
215       else if ( *p == 'P' || *p == 'p')
216         {
217           ti->flags.for_pgp = 1;
218         }
219       else if ( *p == 'S' || *p == 's')
220         {
221           ti->flags.for_smime = 1;
222         }
223       else
224         {
225           log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
226           err = gpg_error (GPG_ERR_BAD_DATA);
227           continue;
228         }
229       p++;
230       if ( *p && !spacep (p) )
231         {
232           log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
233           err = gpg_error (GPG_ERR_BAD_DATA);
234           continue;
235         }
236
237       /* Now check for more key-value pairs of the form NAME[=VALUE]. */
238       while (*p)
239         {
240           for (; spacep (p); p++)
241             ;
242           if (!*p)
243             break;
244           n = strcspn (p, "= \t");
245           if (p[n] == '=')
246             {
247               log_error ("assigning a value to a flag is not yet supported; "
248                          "in `%s', line %d\n", fname, lnr);
249               err = gpg_error (GPG_ERR_BAD_DATA);
250               p++;
251             }
252           else if (n == 5 && !memcmp (p, "relax", 5))
253             ti->flags.relax = 1;
254           else
255             log_error ("flag `%.*s' in `%s', line %d ignored\n",
256                        n, p, fname, lnr);
257           p += n;
258         }
259       tableidx++;
260     }
261   if ( !err && !feof (fp) )
262     {
263       err = gpg_error_from_syserror ();
264       log_error (_("error reading `%s', line %d: %s\n"),
265                  fname, lnr, gpg_strerror (err));
266     }
267
268  leave:
269   if (fp)
270     fclose (fp);
271   *addr_of_table = table;
272   *addr_of_tablesize = tablesize;
273   *addr_of_tableidx = tableidx;
274   return err;
275 }
276
277
278 /* Read the trust files and update the global table on success.  */
279 static gpg_error_t
280 read_trustfiles (void)
281 {
282   gpg_error_t err;
283   trustitem_t *table, *ti;
284   int tableidx;
285   size_t tablesize;
286   char *fname;
287   int allow_include = 1;
288
289   tablesize = 20;
290   table = xtrycalloc (tablesize, sizeof *table);
291   if (!table)
292     return gpg_error_from_syserror ();
293   tableidx = 0;
294
295   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
296   if ( access (fname, F_OK) )
297     {
298       if ( errno == ENOENT )
299         ; /* Silently ignore a non-existing trustfile.  */
300       else
301         {
302           err = gpg_error_from_syserror ();
303           log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
304         }
305       xfree (fname);
306       fname = make_filename (GNUPG_SYSCONFDIR, "trustlist.txt", NULL);
307       allow_include = 0;
308     }
309   err = read_one_trustfile (fname, allow_include,
310                             &table, &tablesize, &tableidx);
311   xfree (fname);
312
313   if (err)
314     {
315       xfree (table);
316       if (gpg_err_code (err) == GPG_ERR_ENOENT)
317         {
318           /* Take a missing trustlist as an empty one.  */
319           lock_trusttable ();
320           xfree (trusttable);
321           trusttable = NULL;
322           trusttablesize = 0;
323           unlock_trusttable ();
324           err = 0;
325         }
326       return err;
327     }
328
329   /* Fixme: we should drop duplicates and sort the table. */
330   ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table);
331   if (!ti)
332     {
333       xfree (table);
334       return err;
335     }
336
337   lock_trusttable ();
338   xfree (trusttable);
339   trusttable = table;
340   trusttablesize = tableidx;
341   unlock_trusttable ();
342   return 0;
343 }
344
345
346
347 /* Check whether the given fpr is in our trustdb.  We expect FPR to be
348    an all uppercase hexstring of 40 characters. */
349 gpg_error_t 
350 agent_istrusted (ctrl_t ctrl, const char *fpr)
351 {
352   gpg_error_t err;
353   trustitem_t *ti;
354   size_t len;
355   unsigned char fprbin[20];
356
357   if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
358     return gpg_error (GPG_ERR_INV_VALUE);
359
360   if (!trusttable)
361     {
362       err = read_trustfiles ();
363       if (err)
364         {
365           log_error (_("error reading list of trusted root certificates\n"));
366           return err;
367         }
368     }
369
370   if (trusttable)
371     {
372       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
373         if (!memcmp (ti->fpr, fprbin, 20))
374           {
375             if (ti->flags.relax)
376               {
377                 err = agent_write_status (ctrl,
378                                           "TRUSTLISTFLAG", "relax", 
379                                           NULL);
380                 if (err)
381                   return err;
382               }
383             return 0; /* Trusted. */
384           }
385     }
386   return gpg_error (GPG_ERR_NOT_TRUSTED);
387 }
388
389
390 /* Write all trust entries to FP. */
391 gpg_error_t 
392 agent_listtrusted (void *assuan_context)
393 {
394   trustitem_t *ti;
395   char key[51];
396   gpg_error_t err;
397   size_t len;
398
399   if (!trusttable)
400     {
401       err = read_trustfiles ();
402       if (err)
403         {
404           log_error (_("error reading list of trusted root certificates\n"));
405           return err;
406         }
407     }
408
409   if (trusttable)
410     {
411       /* We need to lock the table because the scheduler may interrupt
412          assuan_send_data and an other thread may then re-read the table. */
413       lock_trusttable ();
414       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
415         {
416           bin2hex (ti->fpr, 20, key);
417           key[40] = ' ';
418           key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*'
419                      : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' ');
420           key[42] = '\n';
421           assuan_send_data (assuan_context, key, 43);
422           assuan_send_data (assuan_context, NULL, 0); /* flush */
423         }
424       unlock_trusttable ();
425     }
426
427   return 0;
428 }
429
430
431 /* Insert the given fpr into our trustdb.  We expect FPR to be an all
432    uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
433    This function does first check whether that key has alreay been put
434    into the trustdb and returns success in this case.  Before a FPR
435    actually gets inserted, the user is asked by means of the pin-entry
436    whether this is actual wants he want to do.
437 */
438 gpg_error_t
439 agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
440 {
441   gpg_error_t err = 0;
442   char *desc;
443   char *fname;
444   FILE *fp;
445
446   /* Check whether we are at all allowed to modify the trustlist.
447      This is useful so that the trustlist may be a symlink to a global
448      trustlist with only admin priviliges to modify it.  Of course
449      this is not a secure way of denying access, but it avoids the
450      usual clicking on an Okay button most users are used to. */
451   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
452   if ( access (fname, W_OK) && errno != ENOENT)
453     {
454       xfree (fname);
455       return gpg_error (GPG_ERR_EPERM);
456     }    
457   xfree (fname);
458
459   if (!agent_istrusted (ctrl, fpr))
460     {
461       return 0; /* We already got this fingerprint.  Silently return
462                    success. */
463     }
464
465   /* This feature must explicitly been enabled. */
466   if (!opt.allow_mark_trusted)
467     return gpg_error (GPG_ERR_NOT_SUPPORTED);
468
469   /* Insert a new one. */
470   if (asprintf (&desc,
471                 /* TRANSLATORS: This prompt is shown by the Pinentry
472                    and has one special property: A "%%0A" is used by
473                    Pinentry to insert a line break.  The double
474                    percent sign is actually needed because it is also
475                    a printf format string.  If you need to insert a
476                    plain % sign, you need to encode it as "%%25".  The
477                    second "%s" gets replaced by a hexdecimal
478                    fingerprint string whereas the first one receives
479                    the name as store in the certificate. */
480                 _("Please verify that the certificate identified as:%%0A"
481                   "  \"%s\"%%0A"
482                   "has the fingerprint:%%0A"
483                   "  %s"), name, fpr) < 0 )
484     return out_of_core ();
485
486   /* TRANSLATORS: "Correct" is the label of a button and intended to
487      be hit if the fingerprint matches the one of the CA.  The other
488      button is "the default "Cancel" of the Pinentry. */
489   err = agent_get_confirmation (ctrl, desc, _("Correct"), NULL);
490   free (desc);
491   /* If the user did not confirmed this, we return cancel here so that
492      gpgsm may stop asking further questions.  We won't do this for
493      the second question of course. */
494   if (err)
495     return (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED ? 
496             gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED) : err);
497
498
499
500   if (asprintf (&desc,
501                 /* TRANSLATORS: This prompt is shown by the Pinentry
502                    and has one special property: A "%%0A" is used by
503                    Pinentry to insert a line break.  The double
504                    percent sign is actually needed because it is also
505                    a printf format string.  If you need to insert a
506                    plain % sign, you need to encode it as "%%25".  The
507                    "%s" gets replaced by the name as store in the
508                    certificate. */
509                 _("Do you ultimately trust%%0A"
510                   "  \"%s\"%%0A"
511                   "to correctly certify user certificates?"),
512                 name) < 0 )
513     return out_of_core ();
514
515   err = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"));
516   free (desc);
517   if (err)
518     return err;
519
520   /* Now check again to avoid duplicates.  We take the lock to make
521      sure that nobody else plays with our file.  Frankly we don't work
522      with the trusttable but using this lock is just fine for our
523      purpose.  */
524   lock_trusttable ();
525   if (!agent_istrusted (ctrl, fpr))
526     {
527       unlock_trusttable ();
528       return 0; 
529     }
530
531
532   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
533   if ( access (fname, F_OK) && errno == ENOENT)
534     {
535       fp = fopen (fname, "wx"); /* Warning: "x" is a GNU extension. */
536       if (!fp)
537         {
538           err = gpg_error_from_syserror ();
539           log_error ("can't create `%s': %s\n", fname, gpg_strerror (err));
540           xfree (fname);
541           unlock_trusttable ();
542           return err;
543         }
544       fputs (headerblurb, fp);
545       fclose (fp);
546     }
547   fp = fopen (fname, "a+");
548   if (!fp)
549     {
550       err = gpg_error_from_syserror ();
551       log_error ("can't open `%s': %s\n", fname, gpg_strerror (err));
552       xfree (fname);
553       unlock_trusttable ();
554       return err;
555     }
556
557   /* Append the key. */
558   fputs ("\n# ", fp);
559   print_sanitized_string (fp, name, 0);
560   fprintf (fp, "\n%s %c\n", fpr, flag);
561   if (ferror (fp))
562     err = gpg_error_from_syserror ();
563   
564   if (fclose (fp))
565     err = gpg_error_from_syserror ();
566
567   if (!err)
568     agent_reload_trustlist ();
569   xfree (fname);
570   unlock_trusttable ();
571   return err;
572 }
573
574
575 /* This function may be called to force reloading of the
576    trustlist.  */
577 void
578 agent_reload_trustlist (void)
579 {
580   /* All we need to do is to delete the trusttable.  At the next
581      access it will get re-read. */
582   lock_trusttable ();
583   xfree (trusttable);
584   trusttable = NULL;
585   trusttablesize = 0;
586   unlock_trusttable ();
587   bump_key_eventcounter ();
588 }