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