New "relax" option for trustlist.txt
[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       return err;
317     }
318
319   /* Fixme: we should drop duplicates and sort the table. */
320
321   ti = xtryrealloc (table, tableidx * sizeof *table);
322   if (!ti)
323     {
324       xfree (table);
325       return err;
326     }
327
328   lock_trusttable ();
329   xfree (trusttable);
330   trusttable = table;
331   trusttablesize = tableidx;
332   unlock_trusttable ();
333   return 0;
334 }
335
336
337
338 /* Check whether the given fpr is in our trustdb.  We expect FPR to be
339    an all uppercase hexstring of 40 characters. */
340 gpg_error_t 
341 agent_istrusted (ctrl_t ctrl, const char *fpr)
342 {
343   gpg_error_t err;
344   trustitem_t *ti;
345   size_t len;
346   unsigned char fprbin[20];
347
348   if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
349     return gpg_error (GPG_ERR_INV_VALUE);
350
351   if (!trusttable)
352     {
353       err = read_trustfiles ();
354       if (err)
355         {
356           log_error (_("error reading list of trusted root certificates\n"));
357           return err;
358         }
359     }
360
361   if (trusttable)
362     {
363       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
364         if (!memcmp (ti->fpr, fprbin, 20))
365           {
366             if (ti->flags.relax)
367               {
368                 err = agent_write_status (ctrl,
369                                           "TRUSTLISTFLAG", "relax", 
370                                           NULL);
371                 if (err)
372                   return err;
373               }
374             return 0; /* Trusted. */
375           }
376     }
377   return gpg_error (GPG_ERR_NOT_TRUSTED);
378 }
379
380
381 /* Write all trust entries to FP. */
382 gpg_error_t 
383 agent_listtrusted (void *assuan_context)
384 {
385   trustitem_t *ti;
386   char key[51];
387   gpg_error_t err;
388   size_t len;
389
390   if (!trusttable)
391     {
392       err = read_trustfiles ();
393       if (err)
394         {
395           log_error (_("error reading list of trusted root certificates\n"));
396           return err;
397         }
398     }
399
400   if (trusttable)
401     {
402       /* We need to lock the table because the scheduler may interrupt
403          assuan_send_data and an other thread may then re-read the table. */
404       lock_trusttable ();
405       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
406         {
407           bin2hex (ti->fpr, 20, key);
408           key[40] = ' ';
409           key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*'
410                      : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' ');
411           key[42] = '\n';
412           assuan_send_data (assuan_context, key, 43);
413           assuan_send_data (assuan_context, NULL, 0); /* flush */
414         }
415       unlock_trusttable ();
416     }
417
418   return 0;
419 }
420
421
422 /* Insert the given fpr into our trustdb.  We expect FPR to be an all
423    uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
424    This function does first check whether that key has alreay been put
425    into the trustdb and returns success in this case.  Before a FPR
426    actually gets inserted, the user is asked by means of the pin-entry
427    whether this is actual wants he want to do.
428 */
429 gpg_error_t
430 agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
431 {
432   gpg_error_t err = 0;
433   char *desc;
434   char *fname;
435   FILE *fp;
436
437   /* Check whether we are at all allowed to modify the trustlist.
438      This is useful so that the trustlist may be a symlink to a global
439      trustlist with only admin priviliges to modify it.  Of course
440      this is not a secure way of denying access, but it avoids the
441      usual clicking on an Okay button most users are used to. */
442   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
443   if ( access (fname, W_OK) && errno != ENOENT)
444     {
445       xfree (fname);
446       return gpg_error (GPG_ERR_EPERM);
447     }    
448   xfree (fname);
449
450   if (!agent_istrusted (ctrl, fpr))
451     {
452       return 0; /* We already got this fingerprint.  Silently return
453                    success. */
454     }
455
456   /* This feature must explicitly been enabled. */
457   if (!opt.allow_mark_trusted)
458     return gpg_error (GPG_ERR_NOT_SUPPORTED);
459
460   /* Insert a new one. */
461   if (asprintf (&desc,
462                 /* TRANSLATORS: This prompt is shown by the Pinentry
463                    and has one special property: A "%%0A" is used by
464                    Pinentry to insert a line break.  The double
465                    percent sign is actually needed because it is also
466                    a printf format string.  If you need to insert a
467                    plain % sign, you need to encode it as "%%25".  The
468                    second "%s" gets replaced by a hexdecimal
469                    fingerprint string whereas the first one receives
470                    the name as store in the certificate. */
471                 _("Please verify that the certificate identified as:%%0A"
472                   "  \"%s\"%%0A"
473                   "has the fingerprint:%%0A"
474                   "  %s"), name, fpr) < 0 )
475     return out_of_core ();
476
477   /* TRANSLATORS: "Correct" is the label of a button and intended to
478      be hit if the fingerprint matches the one of the CA.  The other
479      button is "the default "Cancel" of the Pinentry. */
480   err = agent_get_confirmation (ctrl, desc, _("Correct"), NULL);
481   free (desc);
482   if (err)
483     return err;
484
485   if (asprintf (&desc,
486                 /* TRANSLATORS: This prompt is shown by the Pinentry
487                    and has one special property: A "%%0A" is used by
488                    Pinentry to insert a line break.  The double
489                    percent sign is actually needed because it is also
490                    a printf format string.  If you need to insert a
491                    plain % sign, you need to encode it as "%%25".  The
492                    "%s" gets replaced by the name as store in the
493                    certificate. */
494                 _("Do you ultimately trust%%0A"
495                   "  \"%s\"%%0A"
496                   "to correctly certify user certificates?"),
497                 name) < 0 )
498     return out_of_core ();
499
500   err = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"));
501   free (desc);
502   if (err)
503     return err;
504
505   /* Now check again to avoid duplicates.  We take the lock to make
506      sure that nobody else plays with our file.  Frankly we don't work
507      with the trusttable but using this lock is just fine for our
508      purpose.  */
509   lock_trusttable ();
510   if (!agent_istrusted (ctrl, fpr))
511     {
512       unlock_trusttable ();
513       return 0; 
514     }
515
516
517   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
518   if ( access (fname, F_OK) && errno == ENOENT)
519     {
520       fp = fopen (fname, "wx"); /* Warning: "x" is a GNU extension. */
521       if (!fp)
522         {
523           err = gpg_error_from_syserror ();
524           log_error ("can't create `%s': %s\n", fname, gpg_strerror (err));
525           xfree (fname);
526           unlock_trusttable ();
527           return err;
528         }
529       fputs (headerblurb, fp);
530       fclose (fp);
531     }
532   fp = fopen (fname, "a+");
533   if (!fp)
534     {
535       err = gpg_error_from_syserror ();
536       log_error ("can't open `%s': %s\n", fname, gpg_strerror (err));
537       xfree (fname);
538       unlock_trusttable ();
539       return err;
540     }
541
542   /* Append the key. */
543   fputs ("\n# ", fp);
544   print_sanitized_string (fp, name, 0);
545   fprintf (fp, "\n%s %c\n", fpr, flag);
546   if (ferror (fp))
547     err = gpg_error_from_syserror ();
548   
549   if (fclose (fp))
550     err = gpg_error_from_syserror ();
551
552   if (!err)
553     agent_reload_trustlist ();
554   xfree (fname);
555   unlock_trusttable ();
556   return err;
557 }
558
559
560 /* This function may be called to force reloading of the
561    trustlist.  */
562 void
563 agent_reload_trustlist (void)
564 {
565   /* All we need to do is to delete the trusttable.  At the next
566      access it will get re-read. */
567   lock_trusttable ();
568   xfree (trusttable);
569   trusttable = NULL;
570   trusttablesize = 0;
571   unlock_trusttable ();
572 }