mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-03 22:56:33 +02:00
Merge branch 'STABLE-BRANCH-2-2' into master
This commit is contained in:
commit
d4dc4245bf
36 changed files with 516 additions and 135 deletions
|
@ -289,6 +289,23 @@ start_agent (ctrl_t ctrl, int flag_for_card)
|
|||
}
|
||||
}
|
||||
|
||||
/* Pass on the request origin. */
|
||||
if (opt.request_origin)
|
||||
{
|
||||
char *tmp = xasprintf ("OPTION pretend-request-origin=%s",
|
||||
str_request_origin (opt.request_origin));
|
||||
rc = assuan_transact (agent_ctx, tmp,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
xfree (tmp);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("setting request origin '%s' failed: %s\n",
|
||||
str_request_origin (opt.request_origin),
|
||||
gpg_strerror (rc));
|
||||
write_status_error ("set_request_origin", rc);
|
||||
}
|
||||
}
|
||||
|
||||
/* In DE_VS mode under Windows we require that the JENT RNG
|
||||
* is active. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
|
@ -591,6 +608,8 @@ learn_status_cb (void *opaque, const char *line)
|
|||
parm->extcap.ki = abool;
|
||||
else if (!strcmp (p, "aac"))
|
||||
parm->extcap.aac = abool;
|
||||
else if (!strcmp (p, "kdf"))
|
||||
parm->extcap.kdf = abool;
|
||||
else if (!strcmp (p, "si"))
|
||||
parm->status_indicator = strtoul (p2, NULL, 10);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ struct agent_card_info_s
|
|||
struct {
|
||||
unsigned int ki:1; /* Key import available. */
|
||||
unsigned int aac:1; /* Algorithm attributes are changeable. */
|
||||
unsigned int kdf:1; /* KDF object to support PIN hashing available. */
|
||||
} extcap;
|
||||
unsigned int status_indicator;
|
||||
};
|
||||
|
|
132
g10/card-util.c
132
g10/card-util.c
|
@ -659,7 +659,7 @@ current_card_status (ctrl_t ctrl, estream_t fp,
|
|||
|
||||
/* Print all available information for specific card with SERIALNO.
|
||||
Print all available information for current card when SERIALNO is NULL.
|
||||
Or print llfor all cards when SERIALNO is "all". */
|
||||
Or print for all cards when SERIALNO is "all". */
|
||||
void
|
||||
card_status (ctrl_t ctrl, estream_t fp, const char *serialno)
|
||||
{
|
||||
|
@ -1797,6 +1797,7 @@ factory_reset (void)
|
|||
scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
|
||||
scd apdu 00 e6 00 00
|
||||
scd apdu 00 44 00 00
|
||||
scd reset
|
||||
/echo Card has been reset to factory defaults
|
||||
|
||||
but tries to find out something about the card first.
|
||||
|
@ -1809,7 +1810,7 @@ factory_reset (void)
|
|||
else if (err)
|
||||
{
|
||||
log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
|
||||
return;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!termstate)
|
||||
|
@ -1859,10 +1860,16 @@ factory_reset (void)
|
|||
command because there is no machinery in scdaemon to catch
|
||||
the verify command and ask for the PIN when the "APDU"
|
||||
command is used. */
|
||||
/* Here, the length of dummy wrong PIN is 32-byte, also
|
||||
supporting authentication with KDF DO. */
|
||||
for (i=0; i < 4; i++)
|
||||
send_apdu ("00200081084040404040404040", "VERIFY", 0xffff);
|
||||
send_apdu ("0020008120"
|
||||
"40404040404040404040404040404040"
|
||||
"40404040404040404040404040404040", "VERIFY", 0xffff);
|
||||
for (i=0; i < 4; i++)
|
||||
send_apdu ("00200083084040404040404040", "VERIFY", 0xffff);
|
||||
send_apdu ("0020008320"
|
||||
"40404040404040404040404040404040"
|
||||
"40404040404040404040404040404040", "VERIFY", 0xffff);
|
||||
|
||||
/* Send terminate datafile command. */
|
||||
err = send_apdu ("00e60000", "TERMINATE DF", 0x6985);
|
||||
|
@ -1878,8 +1885,16 @@ factory_reset (void)
|
|||
|
||||
/* Finally we reset the card reader once more. */
|
||||
err = send_apdu (NULL, "RESET", 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* Then, connect the card again. */
|
||||
if (!err)
|
||||
{
|
||||
char *serialno0;
|
||||
|
||||
err = agent_scd_serialno (&serialno0, NULL);
|
||||
if (!err)
|
||||
xfree (serialno0);
|
||||
}
|
||||
|
||||
leave:
|
||||
xfree (answer);
|
||||
|
@ -1887,6 +1902,104 @@ factory_reset (void)
|
|||
}
|
||||
|
||||
|
||||
#define USER_PIN_DEFAULT "123456"
|
||||
#define ADMIN_PIN_DEFAULT "12345678"
|
||||
#define KDF_DATA_LENGTH 110
|
||||
|
||||
/* Generate KDF data. */
|
||||
static gpg_error_t
|
||||
gen_kdf_data (unsigned char *data)
|
||||
{
|
||||
const unsigned char h0[] = { 0x81, 0x01, 0x03,
|
||||
0x82, 0x01, 0x08,
|
||||
0x83, 0x04 };
|
||||
const unsigned char h1[] = { 0x84, 0x08 };
|
||||
const unsigned char h2[] = { 0x85, 0x08 };
|
||||
const unsigned char h3[] = { 0x86, 0x08 };
|
||||
const unsigned char h4[] = { 0x87, 0x20 };
|
||||
const unsigned char h5[] = { 0x88, 0x20 };
|
||||
unsigned char *p, *salt_user, *salt_admin;
|
||||
unsigned char s2k_char;
|
||||
unsigned int iterations;
|
||||
unsigned char count_4byte[4];
|
||||
gpg_error_t err = 0;
|
||||
|
||||
p = data;
|
||||
|
||||
s2k_char = encode_s2k_iterations (0);
|
||||
iterations = S2K_DECODE_COUNT (s2k_char);
|
||||
count_4byte[0] = (iterations >> 24) & 0xff;
|
||||
count_4byte[1] = (iterations >> 16) & 0xff;
|
||||
count_4byte[2] = (iterations >> 8) & 0xff;
|
||||
count_4byte[3] = (iterations & 0xff);
|
||||
|
||||
memcpy (p, h0, sizeof h0);
|
||||
p += sizeof h0;
|
||||
memcpy (p, count_4byte, sizeof count_4byte);
|
||||
p += sizeof count_4byte;
|
||||
memcpy (p, h1, sizeof h1);
|
||||
salt_user = (p += sizeof h1);
|
||||
gcry_randomize (p, 8, GCRY_STRONG_RANDOM);
|
||||
p += 8;
|
||||
memcpy (p, h2, sizeof h2);
|
||||
p += sizeof h2;
|
||||
gcry_randomize (p, 8, GCRY_STRONG_RANDOM);
|
||||
p += 8;
|
||||
memcpy (p, h3, sizeof h3);
|
||||
salt_admin = (p += sizeof h3);
|
||||
gcry_randomize (p, 8, GCRY_STRONG_RANDOM);
|
||||
p += 8;
|
||||
memcpy (p, h4, sizeof h4);
|
||||
p += sizeof h4;
|
||||
err = gcry_kdf_derive (USER_PIN_DEFAULT, strlen (USER_PIN_DEFAULT),
|
||||
GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256,
|
||||
salt_user, 8, iterations, 32, p);
|
||||
p += 32;
|
||||
if (!err)
|
||||
{
|
||||
memcpy (p, h5, sizeof h5);
|
||||
p += sizeof h5;
|
||||
err = gcry_kdf_derive (ADMIN_PIN_DEFAULT, strlen (ADMIN_PIN_DEFAULT),
|
||||
GCRY_KDF_ITERSALTED_S2K, DIGEST_ALGO_SHA256,
|
||||
salt_admin, 8, iterations, 32, p);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Setup KDF data object which is used for PIN authentication. */
|
||||
static void
|
||||
kdf_setup (void)
|
||||
{
|
||||
struct agent_card_info_s info;
|
||||
gpg_error_t err;
|
||||
unsigned char kdf_data[KDF_DATA_LENGTH];
|
||||
|
||||
memset (&info, 0, sizeof info);
|
||||
|
||||
err = agent_scd_getattr ("EXTCAP", &info);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error getting card info: %s\n"), gpg_strerror (err));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info.extcap.kdf)
|
||||
{
|
||||
log_error (_("This command is not supported by this card\n"));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!(err = gen_kdf_data (kdf_data))
|
||||
&& !(err = agent_scd_setattr ("KDF", kdf_data, KDF_DATA_LENGTH, NULL)))
|
||||
err = agent_scd_getattr ("KDF", &info);
|
||||
|
||||
if (err)
|
||||
log_error (_("error for setup KDF: %s\n"), gpg_strerror (err));
|
||||
|
||||
leave:
|
||||
agent_release_card_info (&info);
|
||||
}
|
||||
|
||||
/* Data used by the command parser. This needs to be outside of the
|
||||
function scope to allow readline based command completion. */
|
||||
|
@ -1896,7 +2009,7 @@ enum cmdids
|
|||
cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
|
||||
cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
|
||||
cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
|
||||
cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET,
|
||||
cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET, cmdKDFSETUP,
|
||||
cmdINVCMD
|
||||
};
|
||||
|
||||
|
@ -1930,6 +2043,7 @@ static struct
|
|||
{ "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")},
|
||||
{ "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
|
||||
{ "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
|
||||
{ "kdf-setup", cmdKDFSETUP, 1, N_("setup KDF for PIN authentication")},
|
||||
/* Note, that we do not announce these command yet. */
|
||||
{ "privatedo", cmdPRIVATEDO, 0, NULL },
|
||||
{ "readcert", cmdREADCERT, 0, NULL },
|
||||
|
@ -2213,6 +2327,10 @@ card_edit (ctrl_t ctrl, strlist_t commands)
|
|||
factory_reset ();
|
||||
break;
|
||||
|
||||
case cmdKDFSETUP:
|
||||
kdf_setup ();
|
||||
break;
|
||||
|
||||
case cmdQUIT:
|
||||
goto leave;
|
||||
|
||||
|
|
|
@ -428,6 +428,7 @@ enum cmd_and_opt_values
|
|||
oDisableSignerUID,
|
||||
oSender,
|
||||
oKeyOrigin,
|
||||
oRequestOrigin,
|
||||
|
||||
oNoop
|
||||
};
|
||||
|
@ -719,6 +720,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||
ARGPARSE_s_s (oPassphraseFile, "passphrase-file", "@"),
|
||||
ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
|
||||
ARGPARSE_s_s (oPinentryMode, "pinentry-mode", "@"),
|
||||
ARGPARSE_s_s (oRequestOrigin, "request-origin", "@"),
|
||||
ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
|
||||
ARGPARSE_s_s (oCommandFile, "command-file", "@"),
|
||||
ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
|
||||
|
@ -3158,6 +3160,12 @@ main (int argc, char **argv)
|
|||
log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
|
||||
break;
|
||||
|
||||
case oRequestOrigin:
|
||||
opt.request_origin = parse_request_origin (pargs.r.ret_str);
|
||||
if (opt.request_origin == -1)
|
||||
log_error (_("invalid request origin '%s'\n"), pargs.r.ret_str);
|
||||
break;
|
||||
|
||||
case oCommandFD:
|
||||
opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
|
||||
if (! gnupg_fd_valid (opt.command_fd))
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
correct value and may be of advantage if we ever have to do
|
||||
special things. */
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
|
||||
#ifdef GPG_ERR_SOURCE_DEFAULT
|
||||
#error GPG_ERR_SOURCE_DEFAULT already defined
|
||||
#endif
|
||||
|
|
|
@ -1134,8 +1134,10 @@ change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
|
|||
if (err)
|
||||
goto leave;
|
||||
|
||||
/* Note that when using --dry-run we don't change the
|
||||
* passphrase but merely verify the current passphrase. */
|
||||
desc = gpg_format_keydesc (ctrl, pk, FORMAT_KEYDESC_NORMAL, 1);
|
||||
err = agent_passwd (ctrl, hexgrip, desc, 0,
|
||||
err = agent_passwd (ctrl, hexgrip, desc, !!opt.dry_run,
|
||||
&cache_nonce, &passwd_nonce);
|
||||
xfree (desc);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <time.h>
|
||||
#include <process.h>
|
||||
#ifdef HAVE_WINSOCK2_H
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
|
|
@ -278,6 +278,7 @@ struct
|
|||
|
||||
int passphrase_repeat;
|
||||
int pinentry_mode;
|
||||
int request_origin;
|
||||
|
||||
int unwrap_encryption;
|
||||
int only_sign_text_ids;
|
||||
|
|
|
@ -971,10 +971,10 @@ skip_packet (IOBUF inp, int pkttype, unsigned long pktlen, int partial)
|
|||
}
|
||||
|
||||
|
||||
/* Read PKTLEN bytes form INP and return them in a newly allocated
|
||||
buffer. In case of an error (including reading fewer than PKTLEN
|
||||
bytes from INP before EOF is returned), NULL is returned and an
|
||||
error message is logged. */
|
||||
/* Read PKTLEN bytes from INP and return them in a newly allocated
|
||||
* buffer. In case of an error (including reading fewer than PKTLEN
|
||||
* bytes from INP before EOF is returned), NULL is returned and an
|
||||
* error message is logged. */
|
||||
static void *
|
||||
read_rest (IOBUF inp, size_t pktlen)
|
||||
{
|
||||
|
@ -1741,6 +1741,8 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype,
|
|||
}
|
||||
if (buflen < n)
|
||||
goto too_short;
|
||||
if (!buflen)
|
||||
goto no_type_byte;
|
||||
type = *buffer;
|
||||
if (type & 0x80)
|
||||
{
|
||||
|
@ -1815,6 +1817,13 @@ enum_sig_subpkt (const subpktarea_t * pktbuf, sigsubpkttype_t reqtype,
|
|||
if (start)
|
||||
*start = -1;
|
||||
return NULL;
|
||||
|
||||
no_type_byte:
|
||||
if (opt.verbose)
|
||||
log_info ("type octet missing in subpacket\n");
|
||||
if (start)
|
||||
*start = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ import_ownertrust (ctrl_t ctrl, const char *fname )
|
|||
while (fprlen < MAX_FINGERPRINT_LEN)
|
||||
fpr[fprlen++] = 0;
|
||||
|
||||
rc = tdbio_search_trust_byfpr (fpr, &rec);
|
||||
rc = tdbio_search_trust_byfpr (ctrl, fpr, &rec);
|
||||
if( !rc ) { /* found: update */
|
||||
if (rec.r.trust.ownertrust != otrust)
|
||||
{
|
||||
|
|
110
g10/tdbio.c
110
g10/tdbio.c
|
@ -105,16 +105,17 @@ struct cmp_xdir_struct
|
|||
/* The name of the trustdb file. */
|
||||
static char *db_name;
|
||||
|
||||
/* The handle for locking the trustdb file and a flag to record
|
||||
whether a lock has been taken. */
|
||||
/* The handle for locking the trustdb file and a counter to record how
|
||||
* often this lock has been taken. That counter is required becuase
|
||||
* dotlock does not implemen recursive locks. */
|
||||
static dotlock_t lockhandle;
|
||||
static int is_locked;
|
||||
static unsigned int is_locked;
|
||||
|
||||
/* The file descriptor of the trustdb. */
|
||||
static int db_fd = -1;
|
||||
|
||||
/* A flag indicating that a transaction is active. */
|
||||
static int in_transaction;
|
||||
/* static int in_transaction; Not yet used. */
|
||||
|
||||
|
||||
|
||||
|
@ -125,7 +126,7 @@ static void create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type);
|
|||
|
||||
/*
|
||||
* Take a lock on the trustdb file name. I a lock file can't be
|
||||
* created the function terminates the process. Excvept for a
|
||||
* created the function terminates the process. Except for a
|
||||
* different return code the function does nothing if the lock has
|
||||
* already been taken.
|
||||
*
|
||||
|
@ -135,6 +136,8 @@ static void create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type);
|
|||
static int
|
||||
take_write_lock (void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!lockhandle)
|
||||
lockhandle = dotlock_create (db_name, 0);
|
||||
if (!lockhandle)
|
||||
|
@ -144,12 +147,16 @@ take_write_lock (void)
|
|||
{
|
||||
if (dotlock_take (lockhandle, -1) )
|
||||
log_fatal ( _("can't lock '%s'\n"), db_name );
|
||||
else
|
||||
is_locked = 1;
|
||||
return 0;
|
||||
rc = 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
rc = 1;
|
||||
|
||||
if (opt.lock_once)
|
||||
is_locked = 1;
|
||||
else
|
||||
is_locked++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,10 +167,22 @@ take_write_lock (void)
|
|||
static void
|
||||
release_write_lock (void)
|
||||
{
|
||||
if (!opt.lock_once)
|
||||
if (!dotlock_release (lockhandle))
|
||||
is_locked = 0;
|
||||
if (opt.lock_once)
|
||||
return; /* Don't care; here IS_LOCKED is fixed to 1. */
|
||||
|
||||
if (!is_locked)
|
||||
{
|
||||
log_error ("Ooops, tdbio:release_write_lock with no lock held\n");
|
||||
return;
|
||||
}
|
||||
if (--is_locked)
|
||||
return;
|
||||
|
||||
if (dotlock_release (lockhandle))
|
||||
log_error ("Oops, tdbio:release_write_locked failed\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************
|
||||
************* record cache **********
|
||||
|
@ -329,6 +348,7 @@ put_record_into_cache (ulong recno, const char *data)
|
|||
}
|
||||
|
||||
/* No clean entries: We have to flush some dirty entries. */
|
||||
#if 0 /* Transactions are not yet used. */
|
||||
if (in_transaction)
|
||||
{
|
||||
/* But we can't do this while in a transaction. Thus we
|
||||
|
@ -352,6 +372,7 @@ put_record_into_cache (ulong recno, const char *data)
|
|||
log_info (_("trustdb transaction too large\n"));
|
||||
return GPG_ERR_RESOURCE_LIMIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dirty_count)
|
||||
{
|
||||
|
@ -418,8 +439,10 @@ tdbio_sync()
|
|||
|
||||
if( db_fd == -1 )
|
||||
open_db();
|
||||
#if 0 /* Transactions are not yet used. */
|
||||
if( in_transaction )
|
||||
log_bug("tdbio: syncing while in transaction\n");
|
||||
#endif
|
||||
|
||||
if( !cache_is_dirty )
|
||||
return 0;
|
||||
|
@ -560,7 +583,7 @@ tdbio_update_version_record (ctrl_t ctrl)
|
|||
|
||||
/*
|
||||
* Create and write the trustdb version record.
|
||||
*
|
||||
* This is called with the writelock activ.
|
||||
* Returns: 0 on success or an error code.
|
||||
*/
|
||||
static int
|
||||
|
@ -951,10 +974,12 @@ tdbio_write_nextcheck (ctrl_t ctrl, ulong stamp)
|
|||
* Return: record number
|
||||
*/
|
||||
static ulong
|
||||
get_trusthashrec(void)
|
||||
get_trusthashrec (ctrl_t ctrl)
|
||||
{
|
||||
static ulong trusthashtbl; /* Record number of the trust hashtable. */
|
||||
|
||||
(void)ctrl;
|
||||
|
||||
if (!trusthashtbl)
|
||||
{
|
||||
TRUSTREC vr;
|
||||
|
@ -965,6 +990,20 @@ get_trusthashrec(void)
|
|||
log_fatal (_("%s: error reading version record: %s\n"),
|
||||
db_name, gpg_strerror (rc) );
|
||||
|
||||
if (!vr.r.ver.trusthashtbl)
|
||||
{
|
||||
/* Oops: the trustdb is corrupt because the hashtable is
|
||||
* always created along with the version record. However,
|
||||
* if something went initially wrong it may happen that
|
||||
* there is just the version record. We try to fix it here.
|
||||
* If we can't do that we return 0 - this is the version
|
||||
* record and thus the actual read will detect the mismatch
|
||||
* and bail out. Note that create_hashtable updates VR. */
|
||||
take_write_lock ();
|
||||
if (lseek (db_fd, 0, SEEK_END) == TRUST_RECORD_LEN)
|
||||
create_hashtable (ctrl, &vr, 0);
|
||||
release_write_lock ();
|
||||
}
|
||||
trusthashtbl = vr.r.ver.trusthashtbl;
|
||||
}
|
||||
|
||||
|
@ -1269,6 +1308,13 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen,
|
|||
int msb;
|
||||
int level = 0;
|
||||
|
||||
if (!table)
|
||||
{
|
||||
rc = gpg_error (GPG_ERR_INV_RECORD);
|
||||
log_error("lookup_hashtable failed: %s\n", "request for record 0");
|
||||
return rc;
|
||||
}
|
||||
|
||||
hashrec = table;
|
||||
next_level:
|
||||
msb = key[level];
|
||||
|
@ -1358,7 +1404,7 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen,
|
|||
static int
|
||||
update_trusthashtbl (ctrl_t ctrl, TRUSTREC *tr)
|
||||
{
|
||||
return upd_hashtable (ctrl, get_trusthashrec (),
|
||||
return upd_hashtable (ctrl, get_trusthashrec (ctrl),
|
||||
tr->r.trust.fingerprint, 20, tr->recnum);
|
||||
}
|
||||
|
||||
|
@ -1441,7 +1487,7 @@ tdbio_dump_record (TRUSTREC *rec, estream_t fp)
|
|||
* EXPECTED is not 0 reading any other record type will return an
|
||||
* error.
|
||||
*
|
||||
* Return: 0 on success, -1 on EOF, or an error code.
|
||||
* Return: 0 on success or an error code.
|
||||
*/
|
||||
int
|
||||
tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
|
||||
|
@ -1466,7 +1512,7 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
|
|||
n = read (db_fd, readbuf, TRUST_RECORD_LEN);
|
||||
if (!n)
|
||||
{
|
||||
return -1; /* eof */
|
||||
return gpg_error (GPG_ERR_EOF);
|
||||
}
|
||||
else if (n != TRUST_RECORD_LEN)
|
||||
{
|
||||
|
@ -1700,7 +1746,7 @@ tdbio_delete_record (ctrl_t ctrl, ulong recnum)
|
|||
;
|
||||
else if (rec.rectype == RECTYPE_TRUST)
|
||||
{
|
||||
rc = drop_from_hashtable (ctrl, get_trusthashrec(),
|
||||
rc = drop_from_hashtable (ctrl, get_trusthashrec (ctrl),
|
||||
rec.r.trust.fingerprint, 20, rec.recnum);
|
||||
}
|
||||
|
||||
|
@ -1746,20 +1792,14 @@ tdbio_new_recnum (ctrl_t ctrl)
|
|||
recnum = vr.r.ver.firstfree;
|
||||
rc = tdbio_read_record (recnum, &rec, RECTYPE_FREE);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("%s: error reading free record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
log_fatal (_("%s: error reading free record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
/* Update dir record. */
|
||||
vr.r.ver.firstfree = rec.r.free.next;
|
||||
rc = tdbio_write_record (ctrl, &vr);
|
||||
if (rc)
|
||||
{
|
||||
log_error (_("%s: error writing dir record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
log_fatal (_("%s: error writing dir record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
/* Zero out the new record. */
|
||||
memset (&rec, 0, sizeof rec);
|
||||
rec.rectype = 0; /* Mark as unused record (actually already done
|
||||
|
@ -1776,7 +1816,7 @@ tdbio_new_recnum (ctrl_t ctrl)
|
|||
if (offset == (off_t)(-1))
|
||||
log_fatal ("trustdb: lseek to end failed: %s\n", strerror (errno));
|
||||
recnum = offset / TRUST_RECORD_LEN;
|
||||
log_assert (recnum); /* this is will never be the first record */
|
||||
log_assert (recnum); /* This will never be the first record */
|
||||
/* We must write a record, so that the next call to this
|
||||
* function returns another recnum. */
|
||||
memset (&rec, 0, sizeof rec);
|
||||
|
@ -1798,13 +1838,13 @@ tdbio_new_recnum (ctrl_t ctrl)
|
|||
{
|
||||
rc = gpg_error_from_syserror ();
|
||||
log_error (_("trustdb rec %lu: write failed (n=%d): %s\n"),
|
||||
recnum, n, strerror (errno));
|
||||
recnum, n, gpg_strerror (rc));
|
||||
}
|
||||
}
|
||||
|
||||
if (rc)
|
||||
log_fatal (_("%s: failed to append a record: %s\n"),
|
||||
db_name, gpg_strerror (rc));
|
||||
db_name, gpg_strerror (rc));
|
||||
}
|
||||
|
||||
return recnum ;
|
||||
|
@ -1828,12 +1868,12 @@ cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec )
|
|||
* Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
|
||||
*/
|
||||
gpg_error_t
|
||||
tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec)
|
||||
tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint, TRUSTREC *rec)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Locate the trust record using the hash table */
|
||||
rc = lookup_hashtable (get_trusthashrec(), fingerprint, 20,
|
||||
rc = lookup_hashtable (get_trusthashrec (ctrl), fingerprint, 20,
|
||||
cmp_trec_fpr, fingerprint, rec );
|
||||
return rc;
|
||||
}
|
||||
|
@ -1846,7 +1886,7 @@ tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec)
|
|||
* Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
|
||||
*/
|
||||
gpg_error_t
|
||||
tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
|
||||
tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec)
|
||||
{
|
||||
byte fingerprint[MAX_FINGERPRINT_LEN];
|
||||
size_t fingerlen;
|
||||
|
@ -1854,7 +1894,7 @@ tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
|
|||
fingerprint_from_pk( pk, fingerprint, &fingerlen );
|
||||
for (; fingerlen < 20; fingerlen++)
|
||||
fingerprint[fingerlen] = 0;
|
||||
return tdbio_search_trust_byfpr (fingerprint, rec);
|
||||
return tdbio_search_trust_byfpr (ctrl, fingerprint, rec);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -110,8 +110,10 @@ int tdbio_end_transaction(void);
|
|||
int tdbio_cancel_transaction(void);
|
||||
int tdbio_delete_record (ctrl_t ctrl, ulong recnum);
|
||||
ulong tdbio_new_recnum (ctrl_t ctrl);
|
||||
gpg_error_t tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec);
|
||||
gpg_error_t tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec);
|
||||
gpg_error_t tdbio_search_trust_byfpr (ctrl_t ctrl, const byte *fingerprint,
|
||||
TRUSTREC *rec);
|
||||
gpg_error_t tdbio_search_trust_bypk (ctrl_t ctrl, PKT_public_key *pk,
|
||||
TRUSTREC *rec);
|
||||
|
||||
void tdbio_how_to_fix (void);
|
||||
void tdbio_invalid(void);
|
||||
|
|
|
@ -649,7 +649,7 @@ read_trust_record (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec)
|
|||
int rc;
|
||||
|
||||
init_trustdb (ctrl, 0);
|
||||
rc = tdbio_search_trust_bypk (pk, rec);
|
||||
rc = tdbio_search_trust_bypk (ctrl, pk, rec);
|
||||
if (rc)
|
||||
{
|
||||
if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue