LCOV - code coverage report
Current view: top level - agent - trustlist.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 345 1.7 %
Date: 2015-11-05 17:10:59 Functions: 1 13 7.7 %

          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 <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           1 : initialize_module_trustlist (void)
      82             : {
      83             :   static int initialized;
      84             :   int err;
      85             : 
      86           1 :   if (!initialized)
      87             :     {
      88           1 :       err = npth_mutex_init (&trusttable_lock, NULL);
      89           1 :       if (err)
      90           0 :         log_fatal ("failed to init mutex in %s: %s\n", __FILE__,strerror (err));
      91           1 :       initialized = 1;
      92             :     }
      93           1 : }
      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 (opt.homedir, "trustlist.txt", NULL);
     348           0 :   if ( access (fname, F_OK) )
     349             :     {
     350           0 :       if ( errno == ENOENT )
     351             :         ; /* Silently ignore a non-existing trustfile.  */
     352             :       else
     353             :         {
     354           0 :           err = gpg_error_from_syserror ();
     355           0 :           log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
     356             :         }
     357           0 :       xfree (fname);
     358           0 :       fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
     359           0 :       allow_include = 0;
     360             :     }
     361           0 :   err = read_one_trustfile (fname, allow_include,
     362             :                             &table, &tablesize, &tableidx);
     363           0 :   xfree (fname);
     364             : 
     365           0 :   if (err)
     366             :     {
     367           0 :       xfree (table);
     368           0 :       if (gpg_err_code (err) == GPG_ERR_ENOENT)
     369             :         {
     370             :           /* Take a missing trustlist as an empty one.  */
     371           0 :           clear_trusttable ();
     372           0 :           err = 0;
     373             :         }
     374           0 :       return err;
     375             :     }
     376             : 
     377             :   /* Fixme: we should drop duplicates and sort the table. */
     378           0 :   ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table);
     379           0 :   if (!ti)
     380             :     {
     381           0 :       err = gpg_error_from_syserror ();
     382           0 :       xfree (table);
     383           0 :       return err;
     384             :     }
     385             : 
     386             :   /* Replace the trusttable.  */
     387           0 :   xfree (trusttable);
     388           0 :   trusttable = ti;
     389           0 :   trusttablesize = tableidx;
     390           0 :   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           0 : istrusted_internal (ctrl_t ctrl, const char *fpr, int *r_disabled,
     399             :                     int already_locked)
     400             : {
     401             :   gpg_error_t err;
     402           0 :   int locked = already_locked;
     403             :   trustitem_t *ti;
     404             :   size_t len;
     405             :   unsigned char fprbin[20];
     406             : 
     407           0 :   if (r_disabled)
     408           0 :     *r_disabled = 0;
     409             : 
     410           0 :   if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
     411             :     {
     412           0 :       err = gpg_error (GPG_ERR_INV_VALUE);
     413           0 :       goto leave;
     414             :     }
     415             : 
     416           0 :   if (!already_locked)
     417             :     {
     418           0 :       lock_trusttable ();
     419           0 :       locked = 1;
     420             :     }
     421             : 
     422           0 :   if (!trusttable)
     423             :     {
     424           0 :       err = read_trustfiles ();
     425           0 :       if (err)
     426             :         {
     427           0 :           log_error (_("error reading list of trusted root certificates\n"));
     428           0 :           goto leave;
     429             :         }
     430             :     }
     431             : 
     432           0 :   if (trusttable)
     433             :     {
     434           0 :       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
     435           0 :         if (!memcmp (ti->fpr, fprbin, 20))
     436             :           {
     437           0 :             if (ti->flags.disabled && r_disabled)
     438           0 :               *r_disabled = 1;
     439             : 
     440             :             /* Print status messages only if we have not been called
     441             :                in a locked state.  */
     442           0 :             if (already_locked)
     443             :               ;
     444           0 :             else if (ti->flags.relax)
     445             :               {
     446           0 :                 unlock_trusttable ();
     447           0 :                 locked = 0;
     448           0 :                 err = agent_write_status (ctrl, "TRUSTLISTFLAG", "relax", NULL);
     449             :               }
     450           0 :             else if (ti->flags.cm)
     451             :               {
     452           0 :                 unlock_trusttable ();
     453           0 :                 locked = 0;
     454           0 :                 err = agent_write_status (ctrl, "TRUSTLISTFLAG", "cm", NULL);
     455             :               }
     456             : 
     457           0 :             if (!err)
     458           0 :               err = ti->flags.disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
     459           0 :             goto leave;
     460             :           }
     461             :     }
     462           0 :   err = gpg_error (GPG_ERR_NOT_TRUSTED);
     463             : 
     464             :  leave:
     465           0 :   if (locked && !already_locked)
     466           0 :     unlock_trusttable ();
     467           0 :   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           0 : agent_istrusted (ctrl_t ctrl, const char *fpr, int *r_disabled)
     475             : {
     476           0 :   return istrusted_internal (ctrl, fpr, r_disabled, 0);
     477             : }
     478             : 
     479             : 
     480             : /* Write all trust entries to FP. */
     481             : gpg_error_t
     482           0 : 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           0 :   lock_trusttable ();
     490           0 :   if (!trusttable)
     491             :     {
     492           0 :       err = read_trustfiles ();
     493           0 :       if (err)
     494             :         {
     495           0 :           unlock_trusttable ();
     496           0 :           log_error (_("error reading list of trusted root certificates\n"));
     497           0 :           return err;
     498             :         }
     499             :     }
     500             : 
     501           0 :   if (trusttable)
     502             :     {
     503           0 :       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
     504             :         {
     505           0 :           if (ti->flags.disabled)
     506           0 :             continue;
     507           0 :           bin2hex (ti->fpr, 20, key);
     508           0 :           key[40] = ' ';
     509           0 :           key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*'
     510           0 :                      : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' ');
     511           0 :           key[42] = '\n';
     512           0 :           assuan_send_data (assuan_context, key, 43);
     513           0 :           assuan_send_data (assuan_context, NULL, 0); /* flush */
     514             :         }
     515             :     }
     516             : 
     517           0 :   unlock_trusttable ();
     518           0 :   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           0 : insert_colons (const char *string)
     527             : {
     528             :   char *buffer, *p;
     529           0 :   size_t n = strlen (string);
     530           0 :   size_t nnew = n + (n+1)/2;
     531             : 
     532           0 :   p = buffer = xtrymalloc ( nnew + 1 );
     533           0 :   if (!buffer)
     534           0 :     return NULL;
     535           0 :   while (*string)
     536             :     {
     537           0 :       *p++ = *string++;
     538           0 :       if (*string)
     539             :         {
     540           0 :           *p++ = *string++;
     541           0 :           if (*string)
     542           0 :             *p++ = ':';
     543             :         }
     544             :     }
     545           0 :   *p = 0;
     546           0 :   assert (strlen (buffer) <= nnew);
     547             : 
     548           0 :   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           0 : reformat_name (const char *name, const char *replstring)
     557             : {
     558             :   const char *s;
     559             :   char *newname;
     560             :   char *d;
     561             :   size_t count;
     562           0 :   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           0 :   if (*name != '/')
     567           0 :     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           0 :   for (s=name+1, count=0; *s; s++)
     573           0 :     if (*s == '/')
     574           0 :       count++;
     575           0 :   newname = xtrymalloc (strlen (name) + count*replstringlen + 1);
     576           0 :   if (!newname)
     577           0 :     return NULL;
     578           0 :   for (s=name+1, d=newname; *s; s++)
     579           0 :     if (*s == '/')
     580           0 :       d = stpcpy (d, replstring);
     581             :     else
     582           0 :       *d++ = *s;
     583           0 :   *d = 0;
     584           0 :   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           0 : agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
     596             : {
     597           0 :   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           0 :   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
     612           0 :   if ( access (fname, W_OK) && errno != ENOENT)
     613             :     {
     614           0 :       xfree (fname);
     615           0 :       return gpg_error (GPG_ERR_EPERM);
     616             :     }
     617           0 :   xfree (fname);
     618             : 
     619           0 :   if (!agent_istrusted (ctrl, fpr, &is_disabled))
     620             :     {
     621           0 :       return 0; /* We already got this fingerprint.  Silently return
     622             :                    success. */
     623             :     }
     624             : 
     625             :   /* This feature must explicitly been enabled. */
     626           0 :   if (!opt.allow_mark_trusted)
     627           0 :     return gpg_error (GPG_ERR_NOT_SUPPORTED);
     628             : 
     629           0 :   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           0 :       return gpg_error (GPG_ERR_NOT_TRUSTED);
     636             :     }
     637             : 
     638             : 
     639             :   /* Insert a new one. */
     640           0 :   nameformatted = reformat_name (name, "%0A   ");
     641           0 :   if (!nameformatted)
     642           0 :     return gpg_error_from_syserror ();
     643             : 
     644             :   /* First a general question whether this is trusted.  */
     645           0 :   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           0 :   if (!desc)
     659             :     {
     660           0 :       xfree (nameformatted);
     661           0 :       return out_of_core ();
     662             :     }
     663           0 :   err = agent_get_confirmation (ctrl, desc, L_("Yes"), L_("No"), 1);
     664           0 :   xfree (desc);
     665           0 :   if (!err)
     666           0 :     yes_i_trust = 1;
     667           0 :   else if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED)
     668           0 :     yes_i_trust = 0;
     669             :   else
     670             :     {
     671           0 :       xfree (nameformatted);
     672           0 :       return err;
     673             :     }
     674             : 
     675             : 
     676           0 :   fprformatted = insert_colons (fpr);
     677           0 :   if (!fprformatted)
     678             :     {
     679           0 :       xfree (nameformatted);
     680           0 :       return out_of_core ();
     681             :     }
     682             : 
     683             :   /* If the user trusts this certificate he has to verify the
     684             :      fingerprint of course.  */
     685           0 :   if (yes_i_trust)
     686             :     {
     687           0 :       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           0 :       if (!desc)
     702             :         {
     703           0 :           xfree (fprformatted);
     704           0 :           xfree (nameformatted);
     705           0 :           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           0 :       err = agent_get_confirmation (ctrl, desc, L_("Correct"), L_("Wrong"), 1);
     712           0 :       xfree (desc);
     713           0 :       if (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED)
     714           0 :         yes_i_trust = 0;
     715           0 :       else if (err)
     716             :         {
     717           0 :           xfree (fprformatted);
     718           0 :           xfree (nameformatted);
     719           0 :           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           0 :   lock_trusttable ();
     727           0 :   clear_trusttable ();
     728           0 :   if (!istrusted_internal (ctrl, fpr, &is_disabled, 1) || is_disabled)
     729             :     {
     730           0 :       unlock_trusttable ();
     731           0 :       xfree (fprformatted);
     732           0 :       xfree (nameformatted);
     733           0 :       return is_disabled? gpg_error (GPG_ERR_NOT_TRUSTED) : 0;
     734             :     }
     735             : 
     736           0 :   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
     737           0 :   if ( access (fname, F_OK) && errno == ENOENT)
     738             :     {
     739           0 :       fp = es_fopen (fname, "wx,mode=-rw-r");
     740           0 :       if (!fp)
     741             :         {
     742           0 :           err = gpg_error_from_syserror ();
     743           0 :           log_error ("can't create '%s': %s\n", fname, gpg_strerror (err));
     744           0 :           xfree (fname);
     745           0 :           unlock_trusttable ();
     746           0 :           xfree (fprformatted);
     747           0 :           xfree (nameformatted);
     748           0 :           return err;
     749             :         }
     750           0 :       es_fputs (headerblurb, fp);
     751           0 :       es_fclose (fp);
     752             :     }
     753           0 :   fp = es_fopen (fname, "a+,mode=-rw-r");
     754           0 :   if (!fp)
     755             :     {
     756           0 :       err = gpg_error_from_syserror ();
     757           0 :       log_error ("can't open '%s': %s\n", fname, gpg_strerror (err));
     758           0 :       xfree (fname);
     759           0 :       unlock_trusttable ();
     760           0 :       xfree (fprformatted);
     761           0 :       xfree (nameformatted);
     762           0 :       return err;
     763             :     }
     764             : 
     765             :   /* Append the key. */
     766           0 :   es_fputs ("\n# ", fp);
     767           0 :   xfree (nameformatted);
     768           0 :   nameformatted = reformat_name (name, "\n# ");
     769           0 :   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           0 :       es_write_sanitized (fp, name, strlen (name), NULL, NULL);
     774             :     }
     775             :   else
     776           0 :     es_fputs (nameformatted, fp);
     777           0 :   es_fprintf (fp, "\n%s%s %c%s\n", yes_i_trust?"":"!", fprformatted, flag,
     778             :               flag == 'S'? " relax":"");
     779           0 :   if (es_ferror (fp))
     780           0 :     err = gpg_error_from_syserror ();
     781             : 
     782           0 :   if (es_fclose (fp))
     783           0 :     err = gpg_error_from_syserror ();
     784             : 
     785           0 :   clear_trusttable ();
     786           0 :   xfree (fname);
     787           0 :   unlock_trusttable ();
     788           0 :   xfree (fprformatted);
     789           0 :   xfree (nameformatted);
     790           0 :   if (!err)
     791           0 :     bump_key_eventcounter ();
     792           0 :   return err;
     793             : }
     794             : 
     795             : 
     796             : /* This function may be called to force reloading of the
     797             :    trustlist.  */
     798             : void
     799           0 : 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           0 :   lock_trusttable ();
     804           0 :   clear_trusttable ();
     805           0 :   unlock_trusttable ();
     806           0 :   bump_key_eventcounter ();
     807           0 : }

Generated by: LCOV version 1.11