From 754b1c463034a634a678d8efc76c27fd46aad9b9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 21 May 2016 12:26:44 +0200 Subject: [PATCH] gpg: Store the Tofu meta handle for databases in CTRL. * g10/gpg.h (struct tofu_dbs_s, tofu_dbs_t): New declarations. (struct server_control_s): Add field tofu.dbs. * g10/tofu.c (struct dbs): Rename to tofu_dbs_s. Replace all users by by tofu_dbs_t. (opendbs): Add arg CTRL. Cache the DBS in CTRL. (closedbs): Rename to tofu_closedbs and make global. Add arg CTRL. (tofu_register): Add arg CTRL. Change all callers. Do not call closedbs. (tofu_get_validity): Ditto. (tofu_set_policy): Ditto. (tofu_get_policy): Ditto. (tofu_set_policy_by_keyid): Add arg CTRL. * g10/gpg.c (gpg_deinit_default_ctrl): Call tofu_closedbs. Signed-off-by: Werner Koch --- g10/gpg.c | 3 +- g10/gpg.h | 10 +++++++ g10/gpgv.c | 3 +- g10/keyedit.c | 2 +- g10/keylist.c | 2 +- g10/test-stubs.c | 3 +- g10/tofu.c | 73 +++++++++++++++++++++++++----------------------- g10/tofu.h | 17 +++++++---- g10/trustdb.c | 4 +-- 9 files changed, 70 insertions(+), 47 deletions(-) diff --git a/g10/gpg.c b/g10/gpg.c index 3e0ae3f4f..f901bbd11 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2046,6 +2046,7 @@ gpg_init_default_ctrl (ctrl_t ctrl) static void gpg_deinit_default_ctrl (ctrl_t ctrl) { + tofu_closedbs (ctrl); gpg_dirmngr_deinit_session_data (ctrl); } @@ -4586,7 +4587,7 @@ main (int argc, char **argv) } merge_keys_and_selfsig (kb); - if (tofu_set_policy (kb, policy)) + if (tofu_set_policy (ctrl, kb, policy)) g10_exit (1); } diff --git a/g10/gpg.h b/g10/gpg.h index 5cd836697..c0f0a2dea 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -63,6 +63,10 @@ typedef struct dirmngr_local_s *dirmngr_local_t; typedef struct kbnode_struct *KBNODE; typedef struct kbnode_struct *kbnode_t; +/* TOFU database meta object. */ +struct tofu_dbs_s; +typedef struct tofu_dbs_s *tofu_dbs_t; + /* Session control object. This object is passed to most functions to convey the status of a session. Note that the defaults are set by @@ -74,6 +78,12 @@ struct server_control_s /* Local data for call-dirmngr.c */ dirmngr_local_t dirmngr_local; + + /* Local data for tofu.c */ + struct { + tofu_dbs_t dbs; + } tofu; + }; diff --git a/g10/gpgv.c b/g10/gpgv.c index ea26659f1..f1e994bff 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -645,9 +645,10 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, } gpg_error_t -tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, +tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id, enum tofu_policy *policy) { + (void)ctrl; (void)pk; (void)user_id; (void)policy; diff --git a/g10/keyedit.c b/g10/keyedit.c index c7288b2da..c78f8a3b5 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3485,7 +3485,7 @@ show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock) { #ifdef USE_TOFU enum tofu_policy policy; - if (! tofu_get_policy (primary, uid, &policy) + if (! tofu_get_policy (ctrl, primary, uid, &policy) && policy != TOFU_POLICY_NONE) es_fprintf (fp, "%s", tofu_policy_str (policy)); #endif /*USE_TOFU*/ diff --git a/g10/keylist.c b/g10/keylist.c index 763edac21..cbde0bb72 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -1545,7 +1545,7 @@ list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock, { #ifdef USE_TOFU enum tofu_policy policy; - if (! tofu_get_policy (pk, uid, &policy) + if (! tofu_get_policy (ctrl, pk, uid, &policy) && policy != TOFU_POLICY_NONE) es_fprintf (es_stdout, "%s", tofu_policy_str (policy)); #endif /*USE_TOFU*/ diff --git a/g10/test-stubs.c b/g10/test-stubs.c index 177f35acd..cfaa72c02 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -456,9 +456,10 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, } gpg_error_t -tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, +tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id, enum tofu_policy *policy) { + (void)ctrl; (void)pk; (void)user_id; (void)policy; diff --git a/g10/tofu.c b/g10/tofu.c index b73ad938b..314c76bbd 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -782,7 +782,8 @@ opendb (char *filename, enum db_type type) return db; } -struct dbs +/* Definition of the Tofu dabase meta handle. */ +struct tofu_dbs_s { struct db *db; }; @@ -814,7 +815,7 @@ link_db (struct db **head, struct db *db) TYPE must be either DB_MAIL or DB_KEY. In the combined format, the combined DB is always returned. */ static struct db * -getdb (struct dbs *dbs, const char *name, enum db_type type) +getdb (tofu_dbs_t dbs, const char *name, enum db_type type) { struct db *t = NULL; char *name_sanitized = NULL; @@ -980,9 +981,12 @@ closedb (struct db *db) /* Create a new DB meta-handle. Returns NULL on error. */ /* FIXME: Change to return an error code for better reporting by the caller. */ -static struct dbs * -opendbs (void) +static tofu_dbs_t +opendbs (ctrl_t ctrl) { + if (ctrl->tofu.dbs) + return ctrl->tofu.dbs; + if (opt.tofu_db_format == TOFU_DB_AUTO) { char *filename = make_filename (opt.homedir, "tofu.db", NULL); @@ -1045,13 +1049,20 @@ opendbs (void) } } - return xmalloc_clear (sizeof (struct dbs)); + ctrl->tofu.dbs = xmalloc_clear (sizeof (struct tofu_dbs_s)); + return ctrl->tofu.dbs; } + /* Release all of the resources associated with a DB meta-handle. */ -static void -closedbs (struct dbs *dbs) +void +tofu_closedbs (ctrl_t ctrl) { + tofu_dbs_t dbs = ctrl->tofu.dbs; + + if (!dbs) + return; /* Not initialized. */ + if (dbs->db) { struct db *old_head = db_cache; @@ -1103,7 +1114,8 @@ closedbs (struct dbs *dbs) } } - xfree (dbs); + xfree (ctrl->tofu.dbs); + ctrl->tofu.dbs = NULL; #if DEBUG_TOFU_CACHE log_debug ("Queries: %d (prepares saved: %d)\n", @@ -1142,7 +1154,7 @@ get_single_long_cb2 (void *cookie, int argc, char **argv, char **azColName, If SHOW_OLD is set, the binding's old policy is displayed. */ static gpg_error_t -record_binding (struct dbs *dbs, const char *fingerprint, const char *email, +record_binding (tofu_dbs_t dbs, const char *fingerprint, const char *email, const char *user_id, enum tofu_policy policy, int show_old) { char *fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); @@ -1485,7 +1497,7 @@ time_ago_scale (signed long t) if CONFLICT is not NULL. Returns _tofu_GET_POLICY_ERROR if an error occurs. */ static enum tofu_policy -get_policy (struct dbs *dbs, const char *fingerprint, const char *email, +get_policy (tofu_dbs_t dbs, const char *fingerprint, const char *email, char **conflict) { struct db *db; @@ -1598,7 +1610,7 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email, conflicting binding's policy to TOFU_POLICY_ASK. In either case, we return TRUST_UNDEFINED. */ static enum tofu_policy -get_trust (struct dbs *dbs, const char *fingerprint, const char *email, +get_trust (tofu_dbs_t dbs, const char *fingerprint, const char *email, const char *user_id, int may_ask) { char *fingerprint_pp; @@ -2405,7 +2417,7 @@ write_stats_status (long messages, enum tofu_policy policy, } static void -show_statistics (struct dbs *dbs, const char *fingerprint, +show_statistics (tofu_dbs_t dbs, const char *fingerprint, const char *email, const char *user_id, const char *sig_exclude) { @@ -2646,11 +2658,11 @@ email_from_user_id (const char *user_id) This function returns the binding's trust level on return. If an error occurs, this function returns TRUST_UNKNOWN. */ int -tofu_register (PKT_public_key *pk, const char *user_id, +tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, const byte *sig_digest_bin, int sig_digest_bin_len, time_t sig_time, const char *origin, int may_ask) { - struct dbs *dbs; + tofu_dbs_t dbs; struct db *db; char *fingerprint = NULL; char *fingerprint_pp = NULL; @@ -2664,7 +2676,7 @@ tofu_register (PKT_public_key *pk, const char *user_id, sig_digest = make_radix64_string (sig_digest_bin, sig_digest_bin_len); - dbs = opendbs (); + dbs = opendbs (ctrl); if (! dbs) { log_error (_("error opening TOFU database: %s\n"), @@ -2806,8 +2818,6 @@ tofu_register (PKT_public_key *pk, const char *user_id, xfree (email); xfree (fingerprint_pp); xfree (fingerprint); - if (dbs) - closedbs (dbs); xfree (sig_digest); return trust_level; @@ -2887,15 +2897,15 @@ tofu_wot_trust_combine (int tofu_base, int wot_base) Returns TRUST_UNDEFINED if an error occurs. */ int -tofu_get_validity (PKT_public_key *pk, const char *user_id, +tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, int may_ask) { - struct dbs *dbs; + tofu_dbs_t dbs; char *fingerprint = NULL; char *email = NULL; int trust_level = TRUST_UNDEFINED; - dbs = opendbs (); + dbs = opendbs (ctrl); if (! dbs) { log_error (_("error opening TOFU database: %s\n"), @@ -2925,9 +2935,6 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id, die: xfree (email); xfree (fingerprint); - if (dbs) - closedbs (dbs); - return trust_level; } @@ -2939,16 +2946,16 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id, Returns 0 on success and an error code otherwise. */ gpg_error_t -tofu_set_policy (kbnode_t kb, enum tofu_policy policy) +tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy) { - struct dbs *dbs; + tofu_dbs_t dbs; PKT_public_key *pk; char *fingerprint = NULL; log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY); pk = kb->pkt->pkt.public_key; - dbs = opendbs (); + dbs = opendbs (ctrl); if (! dbs) { log_error (_("error opening TOFU database: %s\n"), @@ -2987,8 +2994,6 @@ tofu_set_policy (kbnode_t kb, enum tofu_policy policy) } xfree (fingerprint); - closedbs (dbs); - return 0; } @@ -3000,13 +3005,13 @@ tofu_set_policy (kbnode_t kb, enum tofu_policy policy) Returns 0 on success and an error code otherwise. */ gpg_error_t -tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy) +tofu_set_policy_by_keyid (ctrl_t ctrl, u32 *keyid, enum tofu_policy policy) { kbnode_t keyblock = get_pubkeyblock (keyid); if (! keyblock) return gpg_error (GPG_ERR_NO_PUBKEY); - return tofu_set_policy (keyblock, policy); + return tofu_set_policy (ctrl, keyblock, policy); } /* Return the TOFU policy for the specified binding in *POLICY. If no @@ -3017,10 +3022,10 @@ tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy) Returns 0 on success and an error code otherwise. */ gpg_error_t -tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, +tofu_get_policy (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *user_id, enum tofu_policy *policy) { - struct dbs *dbs; + tofu_dbs_t dbs; char *fingerprint; char *email; @@ -3028,7 +3033,7 @@ tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, log_assert (pk->main_keyid[0] == pk->keyid[0] && pk->main_keyid[1] == pk->keyid[1]); - dbs = opendbs (); + dbs = opendbs (ctrl); if (! dbs) { log_error (_("error opening TOFU database: %s\n"), @@ -3044,8 +3049,6 @@ tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, xfree (email); xfree (fingerprint); - closedbs (dbs); - if (*policy == _tofu_GET_POLICY_ERROR) return gpg_error (GPG_ERR_GENERAL); return 0; diff --git a/g10/tofu.h b/g10/tofu.h index 7ee10839b..d3448b92f 100644 --- a/g10/tofu.h +++ b/g10/tofu.h @@ -63,6 +63,7 @@ enum tofu_policy _tofu_GET_POLICY_ERROR = 100 }; + /* Return a string representation of a trust policy. Returns "???" if POLICY is not valid. */ const char *tofu_policy_str (enum tofu_policy policy); @@ -78,7 +79,7 @@ int tofu_policy_to_trust_level (enum tofu_policy policy); interact with the user in the case of a conflict or if the binding's policy is ask. This function returns the binding's trust level. If an error occurs, it returns TRUST_UNKNOWN. */ -int tofu_register (PKT_public_key *pk, const char *user_id, +int tofu_register (ctrl_t ctrl, PKT_public_key *pk, const char *user_id, const byte *sigs_digest, int sigs_digest_len, time_t sig_time, const char *origin, int may_ask); @@ -91,18 +92,21 @@ int tofu_wot_trust_combine (int tofu, int wot); . If MAY_ASK is 1, then this function may interact with the user. If not, TRUST_UNKNOWN is returned. If an error occurs, TRUST_UNDEFINED is returned. */ -int tofu_get_validity (PKT_public_key *pk, const char *user_id, int may_ask); +int tofu_get_validity (ctrl_t ctrl, + PKT_public_key *pk, const char *user_id, int may_ask); /* Set the policy for all non-revoked user ids in the keyblock KB to POLICY. */ -gpg_error_t tofu_set_policy (kbnode_t kb, enum tofu_policy policy); +gpg_error_t tofu_set_policy (ctrl_t ctrl, kbnode_t kb, enum tofu_policy policy); /* Set the TOFU policy for all non-revoked users in the key with the key id KEYID to POLICY. */ -gpg_error_t tofu_set_policy_by_keyid (u32 *keyid, enum tofu_policy policy); +gpg_error_t tofu_set_policy_by_keyid (ctrl_t ctrl, + u32 *keyid, enum tofu_policy policy); /* Return the TOFU policy for the specified binding in *POLICY. */ -gpg_error_t tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, +gpg_error_t tofu_get_policy (ctrl_t ctrl, + PKT_public_key *pk, PKT_user_id *user_id, enum tofu_policy *policy); /* When doing a lot of DB activities (in particular, when listing @@ -111,4 +115,7 @@ gpg_error_t tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, void tofu_begin_batch_update (void); void tofu_end_batch_update (void); +/* Release all of the resources associated with a DB meta-handle. */ +void tofu_closedbs (ctrl_t ctrl); + #endif /*G10_TOFU_H*/ diff --git a/g10/trustdb.c b/g10/trustdb.c index e5f7121dd..527a23d2f 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1065,12 +1065,12 @@ tdb_get_validity_core (ctrl_t ctrl, user_ids ++; if (sig) - tl = tofu_register (main_pk, user_id->name, + tl = tofu_register (ctrl, main_pk, user_id->name, sig->digest, sig->digest_len, sig->timestamp, "unknown", may_ask); else - tl = tofu_get_validity (main_pk, user_id->name, may_ask); + tl = tofu_get_validity (ctrl, main_pk, user_id->name, may_ask); if (tl == TRUST_EXPIRED) user_ids_expired ++;