[ostree] show: Print a blurb for each signature on a commit



commit e48fd5e6bbc3a19549fa59f2cc8291ca4e3e2bcb
Author: Matthew Barnes <mbarnes redhat com>
Date:   Sun Mar 15 15:41:03 2015 -0400

    show: Print a blurb for each signature on a commit
    
    Roughly mimics the output of "gpg --verify".

 src/ostree/ot-builtin-show.c |  114 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 114 insertions(+), 0 deletions(-)
---
diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c
index d094974..4eb52f3 100644
--- a/src/ostree/ot-builtin-show.c
+++ b/src/ostree/ot-builtin-show.c
@@ -148,6 +148,87 @@ do_print_metadata_key (OstreeRepo     *repo,
   return ret;
 }
 
+static void
+print_signature (OstreeGpgVerifyResult *result,
+                 guint signature_index)
+{
+  g_autoptr(GVariant) variant = NULL;
+  g_autoptr(GDateTime) date_time_utc = NULL;
+  g_autoptr(GDateTime) date_time_local = NULL;
+  g_autoptr(gchar) formatted_date_time = NULL;
+  gint64 timestamp;
+  gint64 exp_timestamp;
+  const char *fingerprint;
+  const char *pubkey_algo;
+  const char *user_name;
+  const char *user_email;
+  const char *key_id;
+  gboolean valid;
+  gboolean sig_expired;
+  gboolean key_missing;
+  gsize len;
+
+  /* This function roughly mimics the verify output generated by
+   * check_sig_and_print() in gnupg/g10/mainproc.c, though obviously
+   * greatly simplified. */
+
+  variant = ostree_gpg_verify_result_get_all (result, signature_index);
+
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_VALID,
+                       "b", &valid);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_SIG_EXPIRED,
+                       "b", &sig_expired);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_KEY_MISSING,
+                       "b", &key_missing);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_FINGERPRINT,
+                       "&s", &fingerprint);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_TIMESTAMP,
+                       "x", &timestamp);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_EXP_TIMESTAMP,
+                       "x", &exp_timestamp);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_PUBKEY_ALGO_NAME,
+                       "&s", &pubkey_algo);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_NAME,
+                       "&s", &user_name);
+  g_variant_get_child (variant, OSTREE_GPG_SIGNATURE_ATTR_USER_EMAIL,
+                       "&s", &user_email);
+
+  len = strlen (fingerprint);
+  key_id = (len > 16) ? fingerprint + len - 16 : fingerprint;
+
+  date_time_utc = g_date_time_new_from_unix_utc (timestamp);
+  date_time_local = g_date_time_to_local (date_time_utc);
+  formatted_date_time = g_date_time_format (date_time_local, "%c");
+
+  g_print ("  Signature made %s using %s key ID %s\n",
+           formatted_date_time, pubkey_algo, key_id);
+
+  g_clear_pointer (&date_time_utc, g_date_time_unref);
+  g_clear_pointer (&date_time_local, g_date_time_unref);
+  g_clear_pointer (&formatted_date_time, g_free);
+
+  if (key_missing)
+    g_print ("  Can't check signature: public key not found\n");
+  else if (valid)
+    g_print ("  Good signature from \"%s <%s>\"\n", user_name, user_email);
+  else if (sig_expired)
+    g_print ("  Expired signature from \"%s <%s>\"\n", user_name, user_email);
+  else
+    g_print ("  BAD signature from \"%s <%s>\"\n", user_name, user_email);
+
+  if (exp_timestamp > 0)
+    {
+      date_time_utc = g_date_time_new_from_unix_utc (exp_timestamp);
+      date_time_local = g_date_time_to_local (date_time_utc);
+      formatted_date_time = g_date_time_format (date_time_local, "%c");
+
+      if (sig_expired)
+        g_print ("  Signature expired %s\n", formatted_date_time);
+      else
+        g_print ("  Signature expires %s\n", formatted_date_time);
+    }
+}
+
 static gboolean
 print_object (OstreeRepo          *repo,
               OstreeObjectType     objtype,
@@ -165,6 +246,39 @@ print_object (OstreeRepo          *repo,
     flags |= OSTREE_DUMP_RAW;
   ot_dump_object (objtype, checksum, variant, flags);
 
+  if (objtype == OSTREE_OBJECT_TYPE_COMMIT)
+    {
+      gs_unref_object OstreeGpgVerifyResult *result = NULL;
+      GError *local_error = NULL;
+
+      result = ostree_repo_verify_commit_ext (repo, checksum,
+                                              NULL, NULL, NULL,
+                                              &local_error);
+
+      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+        {
+          g_clear_error (&local_error);
+        }
+      else if (local_error != NULL)
+        {
+          g_propagate_error (error, local_error);
+          goto out;
+        }
+      else
+        {
+          guint n_sigs, ii;
+
+          n_sigs = ostree_gpg_verify_result_count_all (result);
+          g_print ("Found %u signature%s:\n", n_sigs, n_sigs == 1 ? "" : "s");
+
+          for (ii = 0; ii < n_sigs; ii++)
+            {
+              g_print ("\n");
+              print_signature (result, ii);
+            }
+        }
+    }
+
   ret = TRUE;
 out:
   return ret;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]