~ubuntu-branches/ubuntu/jaunty/gnupg2/jaunty-security

« back to all changes in this revision

Viewing changes to agent/trustlist.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* trustlist.c - Maintain the list of trusted keys
2
 
 *      Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
2
 * Copyright (C) 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
3
3
 *
4
4
 * This file is part of GnuPG.
5
5
 *
6
6
 * GnuPG is free software; you can redistribute it and/or modify
7
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
 
8
 * the Free Software Foundation; either version 3 of the License, or
9
9
 * (at your option) any later version.
10
10
 *
11
11
 * GnuPG is distributed in the hope that it will be useful,
14
14
 * GNU General Public License for more details.
15
15
 *
16
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
18
 */
20
19
 
21
20
#include <config.h>
27
26
#include <assert.h>
28
27
#include <unistd.h>
29
28
#include <sys/stat.h>
 
29
#include <pth.h>
30
30
 
31
31
#include "agent.h"
32
32
#include <assuan.h> /* fixme: need a way to avoid assuan calls here */
33
33
#include "i18n.h"
34
34
 
 
35
 
 
36
/* A structure to store the information from the trust file. */
 
37
struct trustitem_s
 
38
{
 
39
  struct
 
40
  {
 
41
    int for_pgp:1;        /* Set by '*' or 'P' as first flag. */
 
42
    int for_smime:1;      /* Set by '*' or 'S' as first flag. */
 
43
    int relax:1;          /* Relax checking of root certificate
 
44
                             constraints. */
 
45
    int cm:1;             /* Use chain model for validation. */
 
46
  } flags;
 
47
  unsigned char fpr[20];  /* The binary fingerprint. */
 
48
};
 
49
typedef struct trustitem_s trustitem_t;
 
50
 
 
51
/* Malloced table and its allocated size with all trust items. */
 
52
static trustitem_t *trusttable; 
 
53
static size_t trusttablesize; 
 
54
/* A mutex used to protect the table. */
 
55
static pth_mutex_t trusttable_lock;
 
56
 
 
57
 
 
58
 
35
59
static const char headerblurb[] =
36
60
"# This is the list of trusted keys.  Comment lines, like this one, as\n"
37
 
"# well as empty lines are ignored. The entire file may be integrity\n"
38
 
"# protected by the use of a MAC, so changing the file does not make\n"
39
 
"# sense without the knowledge of the MAC key.  Lines do have a length\n"
40
 
"# limit but this is not serious limitation as the format of the\n"
41
 
"# entries is fixed and checked by gpg-agent: A non-comment line starts\n"
42
 
"# with optional white spaces, followed by the SHA-1 fingerpint in hex,\n"
43
 
"# optionally followed by a flag character which my either be 'P', 'S'\n"
44
 
"# or '*'. Additional data, delimited by white space, is ignored.\n"
45
 
"#\n"
46
 
"# NOTE: You should give the gpg-agent a HUP after editing this file.\n"
 
61
"# well as empty lines are ignored.  Lines have a length limit but this\n"
 
62
"# is not serious limitation as the format of the entries is fixed and\n"
 
63
"# checked by gpg-agent.  A non-comment line starts with optional white\n"
 
64
"# space, followed by the SHA-1 fingerpint in hex, optionally followed\n"
 
65
"# by a flag character which my either be 'P', 'S' or '*'.  You should\n"
 
66
"# give the gpg-agent a HUP after editing this file.\n"
 
67
"\n\n"
 
68
"# Include the default trust list\n"
 
69
"include-default\n"
47
70
"\n";
48
71
 
49
72
 
50
 
static FILE *trustfp;
51
 
static int   trustfp_used; /* Counter to track usage of TRUSTFP. */
52
 
static int   reload_trustlist_pending;
53
 
 
54
 
 
55
 
static int
56
 
open_list (int append)
57
 
{
58
 
  char *fname;
59
 
 
60
 
  fname = make_filename (opt.homedir, "trustlist.txt", NULL);
61
 
  trustfp = fopen (fname, append? "a+":"r");
62
 
  if (!trustfp && errno == ENOENT)
63
 
    {
64
 
      trustfp = fopen (fname, "wx");
65
 
      if (!trustfp)
66
 
        {
67
 
          gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
68
 
          log_error ("can't create `%s': %s\n", fname, strerror (errno));
69
 
          xfree (fname);
70
 
          return tmperr;
71
 
        }
72
 
      fputs (headerblurb, trustfp);
73
 
      fclose (trustfp);
74
 
      trustfp = fopen (fname, append? "a+":"r");
75
 
    }
76
 
 
77
 
  if (!trustfp)
78
 
    {
79
 
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
80
 
      log_error ("can't open `%s': %s\n", fname, strerror (errno));
81
 
      xfree (fname);
82
 
      return tmperr;
83
 
    }
84
 
 
85
 
  /*FIXME: check the MAC */
86
 
 
87
 
  return 0;
88
 
}
89
 
 
90
 
 
91
 
 
92
 
/* Read the trustlist and return entry by entry.  KEY must point to a
93
 
   buffer of at least 41 characters. KEYFLAG does return either 'P',
94
 
   'S' or '*'.
95
 
 
96
 
   Reading a valid entry return 0, EOF returns -1 any other error
97
 
   returns the appropriate error code. */
98
 
static int
99
 
read_list (char *key, int *keyflag)
100
 
{
101
 
  int rc;
102
 
  int c, i, j;
 
73
/* This function must be called once to initialize this module.  This
 
74
   has to be done before a second thread is spawned.  We can't do the
 
75
   static initialization because Pth emulation code might not be able
 
76
   to do a static init; in particular, it is not possible for W32. */
 
77
void
 
78
initialize_module_trustlist (void)
 
79
{
 
80
  static int initialized;
 
81
 
 
82
  if (!initialized)
 
83
    {
 
84
      if (!pth_mutex_init (&trusttable_lock))
 
85
        log_fatal ("error initializing mutex: %s\n", strerror (errno));
 
86
      initialized = 1;
 
87
    }
 
88
}
 
89
 
 
90
 
 
91
 
 
92
 
 
93
static void
 
94
lock_trusttable (void)
 
95
{
 
96
  if (!pth_mutex_acquire (&trusttable_lock, 0, NULL))
 
97
    log_fatal ("failed to acquire mutex in %s\n", __FILE__);
 
98
}
 
99
 
 
100
static void
 
101
unlock_trusttable (void)
 
102
{
 
103
  if (!pth_mutex_release (&trusttable_lock))
 
104
    log_fatal ("failed to release mutex in %s\n", __FILE__);
 
105
}
 
106
 
 
107
 
 
108
 
 
109
static gpg_error_t
 
110
read_one_trustfile (const char *fname, int allow_include,
 
111
                    trustitem_t **addr_of_table, 
 
112
                    size_t *addr_of_tablesize,
 
113
                    int *addr_of_tableidx)
 
114
{
 
115
  gpg_error_t err = 0;
 
116
  FILE *fp;
 
117
  int n, c;
103
118
  char *p, line[256];
104
 
  
105
 
  if (!trustfp)
 
119
  trustitem_t *table, *ti;
 
120
  int tableidx;
 
121
  size_t tablesize;
 
122
  int lnr = 0;
 
123
 
 
124
  table = *addr_of_table;
 
125
  tablesize = *addr_of_tablesize;
 
126
  tableidx = *addr_of_tableidx;
 
127
 
 
128
  fp = fopen (fname, "r");
 
129
  if (!fp)
106
130
    {
107
 
      rc = open_list (0);
108
 
      if (rc)
109
 
        return rc;
 
131
      err = gpg_error_from_syserror ();
 
132
      log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
 
133
      goto leave;
110
134
    }
111
135
 
112
 
  do
 
136
  while (fgets (line, DIM(line)-1, fp))
113
137
    {
114
 
      if (!fgets (line, DIM(line)-1, trustfp) )
115
 
        {
116
 
          if (feof (trustfp))
117
 
            return -1;
118
 
          return gpg_error (gpg_err_code_from_errno (errno));
119
 
        }
 
138
      lnr++;
120
139
      
121
140
      if (!*line || line[strlen(line)-1] != '\n')
122
141
        {
123
 
          /* eat until end of line */
124
 
          while ( (c=getc (trustfp)) != EOF && c != '\n')
 
142
          /* Eat until end of line. */
 
143
          while ( (c=getc (fp)) != EOF && c != '\n')
125
144
            ;
126
 
          return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
127
 
                                 : GPG_ERR_INCOMPLETE_LINE);
 
145
          err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
 
146
                           : GPG_ERR_INCOMPLETE_LINE);
 
147
          log_error (_("file `%s', line %d: %s\n"),
 
148
                     fname, lnr, gpg_strerror (err));
 
149
          continue;
128
150
        }
 
151
      line[strlen(line)-1] = 0; /* Chop the LF. */
129
152
      
130
153
      /* Allow for empty lines and spaces */
131
154
      for (p=line; spacep (p); p++)
132
155
        ;
133
 
    }
134
 
  while (!*p || *p == '\n' || *p == '#');
 
156
      if (!*p || *p == '#')
 
157
        continue;
135
158
  
136
 
  for (i=j=0; (p[i] == ':' || hexdigitp (p+i)) && j < 40; i++)
137
 
    if ( p[i] != ':' )
138
 
      key[j++] = p[i] >= 'a'? (p[i] & 0xdf): p[i];
139
 
  key[j] = 0;
140
 
  if (j!=40 || !(spacep (p+i) || p[i] == '\n'))
141
 
    {
142
 
      log_error ("invalid formatted fingerprint in trustlist\n");
143
 
      return gpg_error (GPG_ERR_BAD_DATA);
144
 
    }
145
 
  assert (p[i]);
146
 
  if (p[i] == '\n')
147
 
    *keyflag = '*';
148
 
  else 
149
 
    {
150
 
      i++;
151
 
      if ( p[i] == 'P' || p[i] == 'p')
152
 
        *keyflag = 'P';
153
 
      else if ( p[i] == 'S' || p[i] == 's')
154
 
        *keyflag = 'S';
155
 
      else if ( p[i] == '*')
156
 
        *keyflag = '*';
157
 
      else
158
 
        {
159
 
          log_error ("invalid keyflag in trustlist\n");
160
 
          return gpg_error (GPG_ERR_BAD_DATA);
161
 
        }
162
 
      i++;
163
 
      if ( !(spacep (p+i) || p[i] == '\n'))
164
 
        {
165
 
          log_error ("invalid keyflag in trustlist\n");
166
 
          return gpg_error (GPG_ERR_BAD_DATA);
167
 
        }
168
 
    }
169
 
 
 
159
      if (!strncmp (p, "include-default", 15)
 
160
          && (!p[15] || spacep (p+15)))
 
161
        {
 
162
          char *etcname;
 
163
          gpg_error_t err2;
 
164
 
 
165
          if (!allow_include)
 
166
            {
 
167
              log_error (_("statement \"%s\" ignored in `%s', line %d\n"),
 
168
                         "include-default", fname, lnr);
 
169
              continue;
 
170
            }
 
171
          /* fixme: Should check for trailing garbage.  */
 
172
 
 
173
          etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
 
174
          if ( !strcmp (etcname, fname) ) /* Same file. */
 
175
            log_info (_("statement \"%s\" ignored in `%s', line %d\n"),
 
176
                      "include-default", fname, lnr);
 
177
          else if ( access (etcname, F_OK) && errno == ENOENT )
 
178
            {
 
179
              /* A non existent system trustlist is not an error.
 
180
                 Just print a note. */
 
181
              log_info (_("system trustlist `%s' not available\n"), etcname);
 
182
            }
 
183
          else
 
184
            {
 
185
              err2 = read_one_trustfile (etcname, 0,
 
186
                                         &table, &tablesize, &tableidx);
 
187
              if (err2)
 
188
                err = err2;
 
189
            }
 
190
          xfree (etcname);
 
191
          
 
192
          continue;
 
193
        }
 
194
 
 
195
      if (tableidx == tablesize)  /* Need more space. */
 
196
        {
 
197
          trustitem_t *tmp;
 
198
          size_t tmplen;
 
199
          
 
200
          tmplen = tablesize + 20;
 
201
          tmp = xtryrealloc (table, tmplen * sizeof *table);
 
202
          if (!tmp)
 
203
            {
 
204
              err = gpg_error_from_syserror ();
 
205
              goto leave;
 
206
            }
 
207
          table = tmp;
 
208
          tablesize = tmplen;
 
209
        }
 
210
 
 
211
      ti = table + tableidx;
 
212
 
 
213
      n = hexcolon2bin (p, ti->fpr, 20);
 
214
      if (n < 0)
 
215
        {
 
216
          log_error (_("bad fingerprint in `%s', line %d\n"), fname, lnr);
 
217
          err = gpg_error (GPG_ERR_BAD_DATA); 
 
218
          continue;
 
219
        }
 
220
      p += n;
 
221
      for (; spacep (p); p++)
 
222
        ;
 
223
      
 
224
      memset (&ti->flags, 0, sizeof ti->flags);
 
225
      /* Process the first flag which needs to be the first for
 
226
         backward compatibility. */
 
227
      if (!*p || *p == '*' )
 
228
        {
 
229
          ti->flags.for_smime = 1;
 
230
          ti->flags.for_pgp = 1;
 
231
        }
 
232
      else if ( *p == 'P' || *p == 'p')
 
233
        {
 
234
          ti->flags.for_pgp = 1;
 
235
        }
 
236
      else if ( *p == 'S' || *p == 's')
 
237
        {
 
238
          ti->flags.for_smime = 1;
 
239
        }
 
240
      else
 
241
        {
 
242
          log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
 
243
          err = gpg_error (GPG_ERR_BAD_DATA);
 
244
          continue;
 
245
        }
 
246
      p++;
 
247
      if ( *p && !spacep (p) )
 
248
        {
 
249
          log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
 
250
          err = gpg_error (GPG_ERR_BAD_DATA);
 
251
          continue;
 
252
        }
 
253
 
 
254
      /* Now check for more key-value pairs of the form NAME[=VALUE]. */
 
255
      while (*p)
 
256
        {
 
257
          for (; spacep (p); p++)
 
258
            ;
 
259
          if (!*p)
 
260
            break;
 
261
          n = strcspn (p, "= \t");
 
262
          if (p[n] == '=')
 
263
            {
 
264
              log_error ("assigning a value to a flag is not yet supported; "
 
265
                         "in `%s', line %d\n", fname, lnr);
 
266
              err = gpg_error (GPG_ERR_BAD_DATA);
 
267
              p++;
 
268
            }
 
269
          else if (n == 5 && !memcmp (p, "relax", 5))
 
270
            ti->flags.relax = 1;
 
271
          else if (n == 2 && !memcmp (p, "cm", 2))
 
272
            ti->flags.cm = 1;
 
273
          else
 
274
            log_error ("flag `%.*s' in `%s', line %d ignored\n",
 
275
                       n, p, fname, lnr);
 
276
          p += n;
 
277
        }
 
278
      tableidx++;
 
279
    }
 
280
  if ( !err && !feof (fp) )
 
281
    {
 
282
      err = gpg_error_from_syserror ();
 
283
      log_error (_("error reading `%s', line %d: %s\n"),
 
284
                 fname, lnr, gpg_strerror (err));
 
285
    }
 
286
 
 
287
 leave:
 
288
  if (fp)
 
289
    fclose (fp);
 
290
  *addr_of_table = table;
 
291
  *addr_of_tablesize = tablesize;
 
292
  *addr_of_tableidx = tableidx;
 
293
  return err;
 
294
}
 
295
 
 
296
 
 
297
/* Read the trust files and update the global table on success.  */
 
298
static gpg_error_t
 
299
read_trustfiles (void)
 
300
{
 
301
  gpg_error_t err;
 
302
  trustitem_t *table, *ti;
 
303
  int tableidx;
 
304
  size_t tablesize;
 
305
  char *fname;
 
306
  int allow_include = 1;
 
307
 
 
308
  tablesize = 20;
 
309
  table = xtrycalloc (tablesize, sizeof *table);
 
310
  if (!table)
 
311
    return gpg_error_from_syserror ();
 
312
  tableidx = 0;
 
313
 
 
314
  fname = make_filename (opt.homedir, "trustlist.txt", NULL);
 
315
  if ( access (fname, F_OK) )
 
316
    {
 
317
      if ( errno == ENOENT )
 
318
        ; /* Silently ignore a non-existing trustfile.  */
 
319
      else
 
320
        {
 
321
          err = gpg_error_from_syserror ();
 
322
          log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
 
323
        }
 
324
      xfree (fname);
 
325
      fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
 
326
      allow_include = 0;
 
327
    }
 
328
  err = read_one_trustfile (fname, allow_include,
 
329
                            &table, &tablesize, &tableidx);
 
330
  xfree (fname);
 
331
 
 
332
  if (err)
 
333
    {
 
334
      xfree (table);
 
335
      if (gpg_err_code (err) == GPG_ERR_ENOENT)
 
336
        {
 
337
          /* Take a missing trustlist as an empty one.  */
 
338
          lock_trusttable ();
 
339
          xfree (trusttable);
 
340
          trusttable = NULL;
 
341
          trusttablesize = 0;
 
342
          unlock_trusttable ();
 
343
          err = 0;
 
344
        }
 
345
      return err;
 
346
    }
 
347
 
 
348
  /* Fixme: we should drop duplicates and sort the table. */
 
349
  ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table);
 
350
  if (!ti)
 
351
    {
 
352
      xfree (table);
 
353
      return err;
 
354
    }
 
355
 
 
356
  lock_trusttable ();
 
357
  xfree (trusttable);
 
358
  trusttable = table;
 
359
  trusttablesize = tableidx;
 
360
  unlock_trusttable ();
170
361
  return 0;
171
362
}
172
363
 
 
364
 
 
365
 
173
366
/* Check whether the given fpr is in our trustdb.  We expect FPR to be
174
367
   an all uppercase hexstring of 40 characters. */
175
 
int 
176
 
agent_istrusted (const char *fpr)
 
368
gpg_error_t 
 
369
agent_istrusted (ctrl_t ctrl, const char *fpr)
177
370
{
178
 
  int rc;
179
 
  static char key[41];
180
 
  int keyflag;
181
 
 
182
 
  trustfp_used++;
183
 
  if (trustfp)
184
 
    rewind (trustfp);
185
 
  while (!(rc=read_list (key, &keyflag)))
 
371
  gpg_error_t err;
 
372
  trustitem_t *ti;
 
373
  size_t len;
 
374
  unsigned char fprbin[20];
 
375
 
 
376
  if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
 
377
    return gpg_error (GPG_ERR_INV_VALUE);
 
378
 
 
379
  if (!trusttable)
186
380
    {
187
 
      if (!strcmp (key, fpr))
 
381
      err = read_trustfiles ();
 
382
      if (err)
188
383
        {
189
 
          trustfp_used--;
190
 
          return 0;
 
384
          log_error (_("error reading list of trusted root certificates\n"));
 
385
          return err;
191
386
        }
192
387
    }
193
 
  if (rc != -1)
 
388
 
 
389
  if (trusttable)
194
390
    {
195
 
      /* Error in the trustdb - close it to give the user a chance for
196
 
         correction */
197
 
      if (trustfp)
198
 
        fclose (trustfp);
199
 
      trustfp = NULL;
 
391
      for (ti=trusttable, len = trusttablesize; len; ti++, len--)
 
392
        if (!memcmp (ti->fpr, fprbin, 20))
 
393
          {
 
394
            if (ti->flags.relax)
 
395
              {
 
396
                err = agent_write_status (ctrl,
 
397
                                          "TRUSTLISTFLAG", "relax", 
 
398
                                          NULL);
 
399
                if (err)
 
400
                  return err;
 
401
              }
 
402
            else if (ti->flags.cm)
 
403
              {
 
404
                err = agent_write_status (ctrl,
 
405
                                          "TRUSTLISTFLAG", "cm", 
 
406
                                          NULL);
 
407
                if (err)
 
408
                  return err;
 
409
              }
 
410
            return 0; /* Trusted. */
 
411
          }
200
412
    }
201
 
  trustfp_used--;
202
 
  return rc;
 
413
  return gpg_error (GPG_ERR_NOT_TRUSTED);
203
414
}
204
415
 
205
416
 
206
417
/* Write all trust entries to FP. */
207
 
int 
 
418
gpg_error_t 
208
419
agent_listtrusted (void *assuan_context)
209
420
{
210
 
  int rc;
211
 
  static char key[51];
212
 
  int keyflag;
213
 
 
214
 
  trustfp_used++;
215
 
  if (trustfp)
216
 
    rewind (trustfp);
217
 
  while (!(rc=read_list (key, &keyflag)))
218
 
    {
219
 
      key[40] = ' ';
220
 
      key[41] = keyflag;
221
 
      key[42] = '\n';
222
 
      assuan_send_data (assuan_context, key, 43);
223
 
      assuan_send_data (assuan_context, NULL, 0); /* flush */
224
 
    } 
225
 
  if (rc == -1)
226
 
    rc = 0;
227
 
  if (rc)
228
 
    {
229
 
      /* Error in the trustdb - close it to give the user a chance for
230
 
         correction */
231
 
      if (trustfp)
232
 
        fclose (trustfp);
233
 
      trustfp = NULL;
234
 
    }
235
 
  trustfp_used--;
236
 
  return rc;
 
421
  trustitem_t *ti;
 
422
  char key[51];
 
423
  gpg_error_t err;
 
424
  size_t len;
 
425
 
 
426
  if (!trusttable)
 
427
    {
 
428
      err = read_trustfiles ();
 
429
      if (err)
 
430
        {
 
431
          log_error (_("error reading list of trusted root certificates\n"));
 
432
          return err;
 
433
        }
 
434
    }
 
435
 
 
436
  if (trusttable)
 
437
    {
 
438
      /* We need to lock the table because the scheduler may interrupt
 
439
         assuan_send_data and an other thread may then re-read the table. */
 
440
      lock_trusttable ();
 
441
      for (ti=trusttable, len = trusttablesize; len; ti++, len--)
 
442
        {
 
443
          bin2hex (ti->fpr, 20, key);
 
444
          key[40] = ' ';
 
445
          key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*'
 
446
                     : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' ');
 
447
          key[42] = '\n';
 
448
          assuan_send_data (assuan_context, key, 43);
 
449
          assuan_send_data (assuan_context, NULL, 0); /* flush */
 
450
        }
 
451
      unlock_trusttable ();
 
452
    }
 
453
 
 
454
  return 0;
 
455
}
 
456
 
 
457
 
 
458
/* Create a copy of string with colons inserted after each two bytes.
 
459
   Caller needs to release the string.  In case of a memory failure,
 
460
   NULL is returned.  */
 
461
static char *
 
462
insert_colons (const char *string)
 
463
{
 
464
  char *buffer, *p;
 
465
  size_t n = strlen (string);
 
466
 
 
467
  p = buffer = xtrymalloc ( n + (n+2)/3 + 1 );
 
468
  if (!buffer)
 
469
    return NULL;
 
470
  while (*string)
 
471
    {
 
472
      *p++ = *string++;
 
473
      if (*string)
 
474
        {
 
475
          *p++ = *string++;
 
476
          if (*string)
 
477
            *p++ = ':';
 
478
        }
 
479
    }
 
480
  *p = 0;
 
481
 
 
482
  return buffer;
237
483
}
238
484
 
239
485
 
240
486
/* Insert the given fpr into our trustdb.  We expect FPR to be an all
241
487
   uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
242
 
   This function does first check whether that key has alreay been put
 
488
   This function does first check whether that key has already been put
243
489
   into the trustdb and returns success in this case.  Before a FPR
244
 
   actually gets inserted, the user is asked by means of the pin-entry
245
 
   whether this is actual wants he want to do.
246
 
*/
247
 
int 
248
 
agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag)
 
490
   actually gets inserted, the user is asked by means of the Pinentry
 
491
   whether this is actual wants he want to do.  */
 
492
gpg_error_t
 
493
agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
249
494
{
250
 
  int rc;
251
 
  static char key[41];
252
 
  int keyflag;
 
495
  gpg_error_t err = 0;
253
496
  char *desc;
254
497
  char *fname;
 
498
  FILE *fp;
 
499
  char *fprformatted;
 
500
 
255
501
 
256
502
  /* Check whether we are at all allowed to modify the trustlist.
257
503
     This is useful so that the trustlist may be a symlink to a global
258
504
     trustlist with only admin priviliges to modify it.  Of course
259
505
     this is not a secure way of denying access, but it avoids the
260
 
     usual clicking on an Okay buttun thing most users are used to. */
 
506
     usual clicking on an Okay button most users are used to. */
261
507
  fname = make_filename (opt.homedir, "trustlist.txt", NULL);
262
 
  rc = access (fname, W_OK);
263
 
  if (rc && errno != ENOENT)
 
508
  if ( access (fname, W_OK) && errno != ENOENT)
264
509
    {
265
510
      xfree (fname);
266
511
      return gpg_error (GPG_ERR_EPERM);
267
512
    }    
268
513
  xfree (fname);
269
514
 
270
 
  trustfp_used++;
271
 
  if (trustfp)
272
 
    rewind (trustfp);
273
 
  while (!(rc=read_list (key, &keyflag)))
274
 
    {
275
 
      if (!strcmp (key, fpr))
276
 
        return 0;
277
 
    }
278
 
  if (trustfp)
279
 
    fclose (trustfp);
280
 
  trustfp = NULL;
281
 
  if (rc != -1)
282
 
    {
283
 
      trustfp_used--;
284
 
      return rc;   /* Error in the trustlist. */
 
515
  if (!agent_istrusted (ctrl, fpr))
 
516
    {
 
517
      return 0; /* We already got this fingerprint.  Silently return
 
518
                   success. */
285
519
    }
286
520
 
287
521
  /* This feature must explicitly been enabled. */
288
522
  if (!opt.allow_mark_trusted)
289
 
    {
290
 
      trustfp_used--;
291
 
      return gpg_error (GPG_ERR_NOT_SUPPORTED);
292
 
    }
 
523
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
293
524
 
294
525
  /* Insert a new one. */
 
526
  fprformatted = insert_colons (fpr);
 
527
  if (!fprformatted)
 
528
    return out_of_core ();
295
529
  if (asprintf (&desc,
296
530
                /* TRANSLATORS: This prompt is shown by the Pinentry
297
531
                   and has one special property: A "%%0A" is used by
301
535
                   plain % sign, you need to encode it as "%%25".  The
302
536
                   second "%s" gets replaced by a hexdecimal
303
537
                   fingerprint string whereas the first one receives
304
 
                   the name as store in the certificate. */
 
538
                   the name as stored in the certificate. */
305
539
                _("Please verify that the certificate identified as:%%0A"
306
540
                  "  \"%s\"%%0A"
307
541
                  "has the fingerprint:%%0A"
308
 
                  "  %s"), name, fpr) < 0 )
 
542
                  "  %s"), name, fprformatted) < 0 )
309
543
    {
310
 
      trustfp_used--;
 
544
      xfree (fprformatted);
311
545
      return out_of_core ();
312
546
    }
313
547
 
314
548
  /* TRANSLATORS: "Correct" is the label of a button and intended to
315
549
     be hit if the fingerprint matches the one of the CA.  The other
316
550
     button is "the default "Cancel" of the Pinentry. */
317
 
  rc = agent_get_confirmation (ctrl, desc, _("Correct"), NULL);
 
551
  err = agent_get_confirmation (ctrl, desc, _("Correct"), NULL);
318
552
  free (desc);
319
 
  if (rc)
 
553
  /* If the user did not confirmed this, we return cancel here so that
 
554
     gpgsm may stop asking further questions.  We won't do this for
 
555
     the second question of course. */
 
556
  if (err)
320
557
    {
321
 
      trustfp_used--;
322
 
      return rc;
 
558
      xfree (fprformatted);
 
559
      return (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED ? 
 
560
              gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED) : err);
323
561
    }
324
562
 
 
563
 
 
564
 
325
565
  if (asprintf (&desc,
326
566
                /* TRANSLATORS: This prompt is shown by the Pinentry
327
567
                   and has one special property: A "%%0A" is used by
336
576
                  "to correctly certify user certificates?"),
337
577
                name) < 0 )
338
578
    {
339
 
      trustfp_used--;
 
579
      xfree (fprformatted);
340
580
      return out_of_core ();
341
581
    }
342
 
  rc = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"));
 
582
 
 
583
  err = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"));
343
584
  free (desc);
344
 
  if (rc)
345
 
    {
346
 
      trustfp_used--;
347
 
      return rc;
348
 
    }
349
 
 
350
 
  /* Now check again to avoid duplicates.  Also open in append mode now. */
351
 
  rc = open_list (1);
352
 
  if (rc)
353
 
    {
354
 
      trustfp_used--;
355
 
      return rc;
356
 
    }
357
 
  rewind (trustfp);
358
 
  while (!(rc=read_list (key, &keyflag)))
359
 
    {
360
 
      if (!strcmp (key, fpr))
 
585
  if (err)
 
586
    {
 
587
      xfree (fprformatted);
 
588
      return err;
 
589
    }
 
590
 
 
591
  /* Now check again to avoid duplicates.  We take the lock to make
 
592
     sure that nobody else plays with our file.  Frankly we don't work
 
593
     with the trusttable but using this lock is just fine for our
 
594
     purpose.  */
 
595
  lock_trusttable ();
 
596
  if (!agent_istrusted (ctrl, fpr))
 
597
    {
 
598
      unlock_trusttable ();
 
599
      xfree (fprformatted);
 
600
      return 0; 
 
601
    }
 
602
 
 
603
 
 
604
  fname = make_filename (opt.homedir, "trustlist.txt", NULL);
 
605
  if ( access (fname, F_OK) && errno == ENOENT)
 
606
    {
 
607
      fp = fopen (fname, "wx"); /* Warning: "x" is a GNU extension. */
 
608
      if (!fp)
361
609
        {
362
 
          trustfp_used--;
363
 
          return 0;
 
610
          err = gpg_error_from_syserror ();
 
611
          log_error ("can't create `%s': %s\n", fname, gpg_strerror (err));
 
612
          xfree (fname);
 
613
          unlock_trusttable ();
 
614
          xfree (fprformatted);
 
615
          return err;
364
616
        }
 
617
      fputs (headerblurb, fp);
 
618
      fclose (fp);
365
619
    }
366
 
  if (rc != -1)
 
620
  fp = fopen (fname, "a+");
 
621
  if (!fp)
367
622
    {
368
 
      if (trustfp)
369
 
        fclose (trustfp);
370
 
      trustfp = NULL;
371
 
      trustfp_used--;
372
 
      return rc;   /* Error in the trustlist. */
 
623
      err = gpg_error_from_syserror ();
 
624
      log_error ("can't open `%s': %s\n", fname, gpg_strerror (err));
 
625
      xfree (fname);
 
626
      unlock_trusttable ();
 
627
      xfree (fprformatted);
 
628
      return err;
373
629
    }
374
 
  rc = 0;
375
630
 
376
631
  /* Append the key. */
377
 
  fflush (trustfp);
378
 
  fputs ("\n# ", trustfp);
379
 
  print_sanitized_string (trustfp, name, 0);
380
 
  fprintf (trustfp, "\n%s %c\n", fpr, flag);
381
 
  if (ferror (trustfp))
382
 
    rc = gpg_error (gpg_err_code_from_errno (errno));
 
632
  fputs ("\n# ", fp);
 
633
  print_sanitized_string (fp, name, 0);
 
634
  fprintf (fp, "\n%s %c\n", fprformatted, flag);
 
635
  if (ferror (fp))
 
636
    err = gpg_error_from_syserror ();
383
637
  
384
 
  /* close because we are in append mode */
385
 
  if (fclose (trustfp))
386
 
    rc = gpg_error (gpg_err_code_from_errno (errno));
387
 
  trustfp = NULL;
388
 
  trustfp_used--;
389
 
  return rc;
390
 
}
391
 
 
392
 
 
393
 
void
394
 
agent_trustlist_housekeeping (void)
395
 
{
396
 
  if (reload_trustlist_pending && !trustfp_used)
397
 
    {
398
 
      if (trustfp)
399
 
        {
400
 
          fclose (trustfp);
401
 
          trustfp = NULL;
402
 
        }
403
 
      reload_trustlist_pending = 0;
404
 
    }
405
 
}
406
 
 
407
 
 
408
 
/* Not all editors are editing files in place, thus a changes
409
 
   trustlist.txt won't be recognozed if we keep the file descriptor
410
 
   open. This function may be used to explicitly close that file
411
 
   descriptor, which will force a reopen in turn. */
 
638
  if (fclose (fp))
 
639
    err = gpg_error_from_syserror ();
 
640
 
 
641
  if (!err)
 
642
    agent_reload_trustlist ();
 
643
  xfree (fname);
 
644
  unlock_trusttable ();
 
645
  xfree (fprformatted);
 
646
  return err;
 
647
}
 
648
 
 
649
 
 
650
/* This function may be called to force reloading of the
 
651
   trustlist.  */
412
652
void
413
653
agent_reload_trustlist (void)
414
654
{
415
 
  reload_trustlist_pending = 1;
416
 
  agent_trustlist_housekeeping ();
 
655
  /* All we need to do is to delete the trusttable.  At the next
 
656
     access it will get re-read. */
 
657
  lock_trusttable ();
 
658
  xfree (trusttable);
 
659
  trusttable = NULL;
 
660
  trusttablesize = 0;
 
661
  unlock_trusttable ();
 
662
  bump_key_eventcounter ();
417
663
}