chiark / gitweb /
gpg: Make sure the conflict set includes the current key.
[gnupg2.git] / g10 / tofu.c
index fc03c5a7dc8ca19d46e6a1e55a08f9eef5fd46c0..39457a5012f99784b2bcd17fed8ac8e49e498994 100644 (file)
@@ -2304,9 +2304,18 @@ build_conflict_set (tofu_dbs_t dbs,
 
 
 /* Return the effective policy for the binding <FINGERPRINT, EMAIL>
- * (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: