X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=g10%2Ftofu.c;h=39457a5012f99784b2bcd17fed8ac8e49e498994;hb=ac0fdba6400c9810df9da850cb859f04b471dffe;hp=fc03c5a7dc8ca19d46e6a1e55a08f9eef5fd46c0;hpb=cc96fc5f4a3d4199d5b410859ea1a58d6bcc0385;p=gnupg2.git diff --git a/g10/tofu.c b/g10/tofu.c index fc03c5a..39457a5 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -2304,9 +2304,18 @@ build_conflict_set (tofu_dbs_t dbs, /* Return the effective policy for the binding - * (email has already been normalized) and any conflict information in - * *CONFLICT_SETP, if CONFLICT_SETP is not NULL. Returns - * _tofu_GET_POLICY_ERROR if an error occurs. */ + * (email has already been normalized). Returns + * _tofu_GET_POLICY_ERROR if an error occurs. Returns any conflict + * information in *CONFLICT_SETP if CONFLICT_SETP is not NULL and the + * returned policy is TOFU_POLICY_ASK (consequently, if there is a + * conflict, but the user set the policy to good *CONFLICT_SETP will + * empty). Note: as per build_conflict_set, which is used to build + * the conflict information, the conflict information includes the + * current user id as the first element of the linked list. + * + * This function registers the binding in the bindings table if it has + * not yet been registered. + */ static enum tofu_policy get_policy (tofu_dbs_t dbs, PKT_public_key *pk, const char *fingerprint, const char *user_id, const char *email, @@ -2677,6 +2686,23 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, && _tofu_GET_TRUST_ERROR != TRUST_FULLY && _tofu_GET_TRUST_ERROR != TRUST_ULTIMATE); + begin_transaction (ctrl, 0); + in_transaction = 1; + + /* We need to call get_policy even if the key is ultimately trusted + * to make sure the binding has been registered. */ + policy = get_policy (dbs, pk, fingerprint, user_id, email, + &conflict_set, now); + + if (policy == TOFU_POLICY_ASK) + /* The conflict set should always contain at least one element: + * the current key. */ + log_assert (conflict_set); + else + /* If the policy is not TOFU_POLICY_ASK, then conflict_set will be + * NULL. */ + log_assert (! conflict_set); + /* If the key is ultimately trusted, there is nothing to do. */ { u32 kid[2]; @@ -2690,11 +2716,6 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, } } - begin_transaction (ctrl, 0); - in_transaction = 1; - - policy = get_policy (dbs, pk, fingerprint, user_id, email, - &conflict_set, now); if (policy == TOFU_POLICY_AUTO) { policy = opt.tofu_default_policy; @@ -2703,6 +2724,14 @@ get_trust (ctrl_t ctrl, PKT_public_key *pk, " auto (default: %s).\n", fingerprint, email, tofu_policy_str (opt.tofu_default_policy)); + + if (policy == TOFU_POLICY_ASK) + /* The default policy is ASK, but there is no conflict (policy + * was 'auto'). In this case, we need to make sure the + * conflict set includes at least the current user id. */ + { + add_to_strlist (&conflict_set, fingerprint); + } } switch (policy) { @@ -2976,7 +3005,8 @@ show_statistics (tofu_dbs_t dbs, /* Get the signature stats. */ rc = gpgsql_exec_printf (dbs->db, strings_collect_cb, &strlist, &err, - "select count (*), min (signatures.time), max (signatures.time)\n" + "select count (*), coalesce (min (signatures.time), 0),\n" + " coalesce (max (signatures.time), 0)\n" " from signatures\n" " left join bindings on signatures.binding = bindings.oid\n" " where fingerprint = %Q and email = %Q;", @@ -3029,7 +3059,8 @@ show_statistics (tofu_dbs_t dbs, /* Get the encryption stats. */ rc = gpgsql_exec_printf (dbs->db, strings_collect_cb, &strlist, &err, - "select count (*), min (encryptions.time), max (encryptions.time)\n" + "select count (*), coalesce (min (encryptions.time), 0),\n" + " coalesce (max (encryptions.time), 0)\n" " from encryptions\n" " left join bindings on encryptions.binding = bindings.oid\n" " where fingerprint = %Q and email = %Q;", @@ -3694,6 +3725,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, int bindings = 0; int bindings_valid = 0; int need_warning = 0; + int had_conflict = 0; dbs = opendbs (ctrl); if (! dbs) @@ -3762,6 +3794,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, * key. */ log_assert (conflict_set); + had_conflict = 1; for (iter = conflict_set; iter; iter = iter->next) show_statistics (dbs, iter->d, email, TOFU_POLICY_ASK, NULL, 1, now); @@ -3794,7 +3827,7 @@ tofu_get_validity (ctrl_t ctrl, PKT_public_key *pk, strlist_t user_id_list, xfree (email); } - if (need_warning) + if (need_warning && ! had_conflict) show_warning (fingerprint, user_id_list); die: