Coverage Report

Created: 2022-12-08 06:10

/src/gnupg/g10/tdbdump.c
Line
Count
Source (jump to first uncovered line)
1
/* tdbdump.c
2
 * Copyright (C) 1998, 1999, 2000, 2001 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 3 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, see <https://www.gnu.org/licenses/>.
18
 */
19
20
#include <config.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <errno.h>
25
#include <ctype.h>
26
#include <sys/types.h>
27
#include <sys/stat.h>
28
#include <fcntl.h>
29
#include <unistd.h>
30
31
#include "gpg.h"
32
#include "../common/status.h"
33
#include "../common/iobuf.h"
34
#include "keydb.h"
35
#include "../common/util.h"
36
#include "trustdb.h"
37
#include "options.h"
38
#include "packet.h"
39
#include "main.h"
40
#include "../common/i18n.h"
41
#include "tdbio.h"
42
43
44
0
#define HEXTOBIN(x) ( (x) >= '0' && (x) <= '9' ? ((x)-'0') : \
45
0
          (x) >= 'A' && (x) <= 'F' ? ((x)-'A'+10) : ((x)-'a'+10))
46
47
48
/*
49
 * Write a record; die on error.
50
 */
51
static void
52
write_record (ctrl_t ctrl, TRUSTREC *rec)
53
0
{
54
0
    int rc = tdbio_write_record (ctrl, rec);
55
0
    if( !rc )
56
0
  return;
57
0
    log_error(_("trust record %lu, type %d: write failed: %s\n"),
58
0
          rec->recnum, rec->rectype, gpg_strerror (rc) );
59
0
    tdbio_invalid();
60
0
}
61
62
63
/*
64
 * Dump the entire trustdb to FP or only the entries of one key.
65
 */
66
void
67
list_trustdb (ctrl_t ctrl, estream_t fp, const char *username)
68
0
{
69
0
  TRUSTREC rec;
70
71
0
  (void)username;
72
73
0
  init_trustdb (ctrl, 0);
74
  /* For now we ignore the user ID. */
75
0
  if (1)
76
0
    {
77
0
      ulong recnum;
78
0
      int i;
79
80
0
      es_fprintf (fp, "TrustDB: %s\n", tdbio_get_dbname ());
81
0
      for (i = 9 + strlen (tdbio_get_dbname()); i > 0; i-- )
82
0
        es_fputc ('-', fp);
83
0
      es_putc ('\n', fp);
84
0
      for (recnum=0; !tdbio_read_record (recnum, &rec, 0); recnum++)
85
0
        tdbio_dump_record (&rec, fp);
86
0
    }
87
0
}
88
89
90
91
92
93
/****************
94
 * Print a list of all defined owner trust value.
95
 */
96
void
97
export_ownertrust (ctrl_t ctrl)
98
0
{
99
0
  TRUSTREC rec;
100
0
  ulong recnum;
101
0
  int i;
102
0
  byte *p;
103
104
0
  init_trustdb (ctrl, 0);
105
0
  es_printf (_("# List of assigned trustvalues, created %s\n"
106
0
               "# (Use \"gpg --import-ownertrust\" to restore them)\n"),
107
0
             asctimestamp( make_timestamp() ) );
108
0
  for (recnum=0; !tdbio_read_record (recnum, &rec, 0); recnum++ )
109
0
    {
110
0
      if (rec.rectype == RECTYPE_TRUST)
111
0
        {
112
          /* Skip records with no ownertrust set or those with trust
113
           * set via --trusted-key.  */
114
0
          if (!rec.r.trust.ownertrust || (rec.r.trust.flags & 1))
115
0
            continue;
116
0
          p = rec.r.trust.fingerprint;
117
0
          for (i=0; i < 20; i++, p++ )
118
0
            es_printf("%02X", *p );
119
0
          es_printf (":%u:\n", (unsigned int)rec.r.trust.ownertrust );
120
0
  }
121
0
    }
122
0
}
123
124
125
void
126
import_ownertrust (ctrl_t ctrl, const char *fname )
127
0
{
128
0
    estream_t fp;
129
0
    int is_stdin=0;
130
0
    char line[256];
131
0
    char *p;
132
0
    size_t n, fprlen;
133
0
    unsigned int otrust;
134
0
    byte fpr[MAX_FINGERPRINT_LEN];
135
0
    int any = 0;
136
0
    int rc;
137
138
0
    init_trustdb (ctrl, 0);
139
0
    if( iobuf_is_pipe_filename (fname) ) {
140
0
  fp = es_stdin;
141
0
  fname = "[stdin]";
142
0
  is_stdin = 1;
143
0
    }
144
0
    else if( !(fp = es_fopen( fname, "r" )) ) {
145
0
  log_error ( _("can't open '%s': %s\n"), fname, strerror(errno) );
146
0
  return;
147
0
    }
148
149
0
    if (is_secured_file (es_fileno (fp)))
150
0
      {
151
0
        es_fclose (fp);
152
0
        gpg_err_set_errno (EPERM);
153
0
  log_error (_("can't open '%s': %s\n"), fname, strerror(errno) );
154
0
  return;
155
0
      }
156
157
0
    while (es_fgets (line, DIM(line)-1, fp)) {
158
0
  TRUSTREC rec;
159
160
0
  if( !*line || *line == '#' )
161
0
      continue;
162
0
  n = strlen(line);
163
0
  if( line[n-1] != '\n' ) {
164
0
      log_error (_("error in '%s': %s\n"), fname, _("line too long") );
165
      /* ... or last line does not have a LF */
166
0
      break; /* can't continue */
167
0
  }
168
0
  for(p = line; *p && *p != ':' ; p++ )
169
0
      if( !hexdigitp(p) )
170
0
    break;
171
0
  if( *p != ':' ) {
172
0
      log_error (_("error in '%s': %s\n"), fname, _("colon missing") );
173
0
      continue;
174
0
  }
175
0
  fprlen = p - line;
176
0
  if( fprlen != 32 && fprlen != 40 && fprlen != 64) {
177
0
      log_error (_("error in '%s': %s\n"),
178
0
                       fname, _("invalid fingerprint") );
179
0
      continue;
180
0
  }
181
0
  if( sscanf(p, ":%u:", &otrust ) != 1 ) {
182
0
      log_error (_("error in '%s': %s\n"),
183
0
                       fname, _("ownertrust value missing"));
184
0
      continue;
185
0
  }
186
0
  if( !otrust )
187
0
      continue; /* no otrust defined - no need to update or insert */
188
  /* Convert the ascii fingerprint to binary */
189
0
  for(p=line, fprlen=0;
190
0
            fprlen < MAX_FINGERPRINT_LEN && *p != ':';
191
0
            p += 2 )
192
0
          fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
193
0
  while (fprlen < MAX_FINGERPRINT_LEN)
194
0
      fpr[fprlen++] = 0;
195
196
0
  rc = tdbio_search_trust_byfpr (ctrl, fpr, &rec);
197
0
  if( !rc ) { /* found: update */
198
0
      if (rec.r.trust.ownertrust != otrust)
199
0
              {
200
0
                if (!opt.quiet)
201
0
                  {
202
0
                    if( rec.r.trust.ownertrust )
203
0
                      log_info("changing ownertrust from %u to %u\n",
204
0
                               rec.r.trust.ownertrust, otrust );
205
0
                    else
206
0
                      log_info("setting ownertrust to %u\n", otrust );
207
0
                  }
208
0
                rec.r.trust.ownertrust = otrust;
209
0
                rec.r.trust.flags &= ~(rec.r.trust.flags & 1);
210
0
                write_record (ctrl, &rec);
211
0
                any = 1;
212
0
              }
213
0
  }
214
0
  else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) { /* insert */
215
0
            if (!opt.quiet)
216
0
              log_info("inserting ownertrust of %u\n", otrust );
217
0
            memset (&rec, 0, sizeof rec);
218
0
            rec.recnum = tdbio_new_recnum (ctrl);
219
0
            rec.rectype = RECTYPE_TRUST;
220
0
            memcpy (rec.r.trust.fingerprint, fpr, 20);
221
0
            rec.r.trust.ownertrust = otrust;
222
0
            write_record (ctrl, &rec);
223
0
            any = 1;
224
0
  }
225
0
  else /* error */
226
0
      log_error (_("error finding trust record in '%s': %s\n"),
227
0
                       fname, gpg_strerror (rc));
228
0
    }
229
0
    if (es_ferror (fp))
230
0
  log_error ( _("read error in '%s': %s\n"), fname, strerror(errno) );
231
0
    if (!is_stdin)
232
0
  es_fclose (fp);
233
234
0
    if (any)
235
0
      {
236
0
        revalidation_mark (ctrl);
237
0
        rc = tdbio_sync ();
238
0
        if (rc)
239
0
          log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) );
240
0
      }
241
242
0
}