Blame SOURCES/0002-status-Print-any-GPG-signatures-for-deployments.patch

e5b71e
From 347a5003e0f0fd0e921d20094b871dc39d5f8324 Mon Sep 17 00:00:00 2001
e5b71e
From: Matthew Barnes <mbarnes@redhat.com>
e5b71e
Date: Tue, 7 Apr 2015 13:49:21 -0400
e5b71e
Subject: [PATCH 2/2] status: Print any GPG signatures for deployments
e5b71e
e5b71e
In pretty mode (--pretty), print signatures for each listed deployment.
e5b71e
e5b71e
Otherwise, just print signatures for the booted deployment at the end to
e5b71e
preserve the tabular formatting of the deployment list.
e5b71e
---
e5b71e
 src/app/rpmostree-builtin-status.c | 136 +++++++++++++++++++++++++++++++++++--
e5b71e
 1 file changed, 129 insertions(+), 7 deletions(-)
e5b71e
e5b71e
diff --git a/src/rpmostree-builtin-status.c b/src/rpmostree-builtin-status.c
e5b71e
index 5cd8dde..ed492a8 100644
e5b71e
--- a/src/rpmostree-builtin-status.c
e5b71e
+++ b/src/rpmostree-builtin-status.c
e5b71e
@@ -76,6 +76,37 @@ version_of_commit (OstreeRepo *repo, const char *checksum)
e5b71e
   return NULL;
e5b71e
 }
e5b71e
 
e5b71e
+static gboolean
e5b71e
+deployment_get_gpg_verify (OstreeDeployment *deployment,
e5b71e
+                           OstreeRepo *repo)
e5b71e
+{
e5b71e
+  /* XXX Something like this could be added to the OstreeDeployment
e5b71e
+   *     API in libostree if the OstreeRepo parameter is acceptable. */
e5b71e
+
e5b71e
+  GKeyFile *origin;
e5b71e
+  gs_free char *refspec = NULL;
e5b71e
+  gs_free char *remote = NULL;
e5b71e
+  gboolean gpg_verify = FALSE;
e5b71e
+
e5b71e
+  origin = ostree_deployment_get_origin (deployment);
e5b71e
+
e5b71e
+  if (origin == NULL)
e5b71e
+    goto out;
e5b71e
+
e5b71e
+  refspec = g_key_file_get_string (origin, "origin", "refspec", NULL);
e5b71e
+
e5b71e
+  if (refspec == NULL)
e5b71e
+    goto out;
e5b71e
+
e5b71e
+  if (!ostree_parse_refspec (refspec, &remote, NULL, NULL))
e5b71e
+    goto out;
e5b71e
+
e5b71e
+  (void) ostree_repo_remote_get_gpg_verify (repo, remote, &gpg_verify, NULL);
e5b71e
+
e5b71e
+out:
e5b71e
+  return gpg_verify;
e5b71e
+}
e5b71e
+
e5b71e
 gboolean
e5b71e
 rpmostree_builtin_status (int             argc,
e5b71e
                           char          **argv,
e5b71e
@@ -85,6 +116,7 @@ rpmostree_builtin_status (int             argc,
e5b71e
   gboolean ret = FALSE;
e5b71e
   gs_unref_object GFile *sysroot_path = NULL;
e5b71e
   gs_unref_object OstreeSysroot *sysroot = NULL;
e5b71e
+  gs_unref_object OstreeRepo *repo = NULL;
e5b71e
   gs_unref_ptrarray GPtrArray *deployments = NULL;  // list of all depoyments
e5b71e
   OstreeDeployment *booted_deployment = NULL;   // current booted deployment
e5b71e
   GOptionContext *context = g_option_context_new ("- Get the version of the booted system");
e5b71e
@@ -96,6 +128,7 @@ rpmostree_builtin_status (int             argc,
e5b71e
   guint max_refspec_len = 0; // maximum length of refspec - determined in code
e5b71e
   guint max_version_len = 0; // maximum length of version - determined in code
e5b71e
   guint buffer = 5; // minimum space between end of one entry and new column
e5b71e
+  gs_free char *booted_csum = NULL;
e5b71e
 
e5b71e
   if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, error))
e5b71e
     goto out;
e5b71e
@@ -105,6 +138,9 @@ rpmostree_builtin_status (int             argc,
e5b71e
   if (!ostree_sysroot_load (sysroot, cancellable, error))
e5b71e
     goto out;
e5b71e
 
e5b71e
+  if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
e5b71e
+    goto out;
e5b71e
+
e5b71e
   booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);
e5b71e
   deployments = ostree_sysroot_get_deployments (sysroot);
e5b71e
 
e5b71e
@@ -114,7 +150,6 @@ rpmostree_builtin_status (int             argc,
e5b71e
       /* find max lengths of osname and refspec */
e5b71e
       for (j = 0; j < deployments->len; j++) 
e5b71e
         {
e5b71e
-          gs_unref_object OstreeRepo *repo = NULL;
e5b71e
           const char *csum = ostree_deployment_get_csum (deployments->pdata[j]);
e5b71e
           GKeyFile *origin;
e5b71e
           gs_free char *origin_refspec = NULL;
e5b71e
@@ -134,9 +169,6 @@ rpmostree_builtin_status (int             argc,
e5b71e
             }
e5b71e
           max_refspec_len = MAX (max_refspec_len, strlen (origin_refspec));
e5b71e
 
e5b71e
-          if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
e5b71e
-            goto out;
e5b71e
-
e5b71e
           version_string = version_of_commit (repo, csum);
e5b71e
           if (version_string)
e5b71e
             max_version_len = MAX (max_version_len, strlen (version_string));
e5b71e
@@ -158,7 +190,6 @@ rpmostree_builtin_status (int             argc,
e5b71e
   for (i=0; i<deployments->len; i++)
e5b71e
     {
e5b71e
       gs_unref_variant GVariant *commit = NULL;
e5b71e
-      gs_unref_object OstreeRepo *repo = NULL;
e5b71e
       const char *csum = ostree_deployment_get_csum (deployments->pdata[i]);
e5b71e
       OstreeDeployment *deployment = deployments->pdata[i];
e5b71e
       GKeyFile *origin;
e5b71e
@@ -169,8 +200,6 @@ rpmostree_builtin_status (int             argc,
e5b71e
       gs_free char *version_string = NULL;
e5b71e
 
e5b71e
       /* get commit for timestamp */
e5b71e
-      if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
e5b71e
-        goto out;
e5b71e
       if (!ostree_repo_load_variant (repo,
e5b71e
                                    OSTREE_OBJECT_TYPE_COMMIT,
e5b71e
                                    csum,
e5b71e
@@ -202,6 +231,13 @@ rpmostree_builtin_status (int             argc,
e5b71e
       /* print deployment info column */
e5b71e
       if (!opt_pretty)
e5b71e
         {
e5b71e
+          if (deployment == booted_deployment)
e5b71e
+            {
e5b71e
+              /* Stash this for printing signatures later. */
e5b71e
+              if (deployment_get_gpg_verify (deployment, repo))
e5b71e
+                booted_csum = g_strdup (csum);
e5b71e
+            }
e5b71e
+
e5b71e
           g_print ("%c %-*s",
e5b71e
                    deployment == booted_deployment ? '*' : ' ',
e5b71e
                    max_timestamp_len+buffer, timestamp_string);
e5b71e
@@ -218,8 +254,11 @@ rpmostree_builtin_status (int             argc,
e5b71e
       /* print "pretty" row info */
e5b71e
       else
e5b71e
         {
e5b71e
+          gs_unref_object OstreeGpgVerifyResult *result = NULL;
e5b71e
           guint tab = 11;
e5b71e
           char *title = NULL;
e5b71e
+          GError *local_error = NULL;
e5b71e
+
e5b71e
           if (i==0)
e5b71e
             title = "DEFAULT ON BOOT";
e5b71e
           else if (deployment == booted_deployment ||
e5b71e
@@ -239,10 +278,93 @@ rpmostree_builtin_status (int             argc,
e5b71e
                   tab, "id", tab, csum, ostree_deployment_get_deployserial (deployment),
e5b71e
                   tab, "osname", tab, ostree_deployment_get_osname (deployment),
e5b71e
                   tab, "refspec", tab, origin_refspec);
e5b71e
+
e5b71e
+          if (deployment_get_gpg_verify (deployment, repo))
e5b71e
+            {
e5b71e
+              result = ostree_repo_verify_commit_ext (repo, csum, NULL, NULL,
e5b71e
+                                                      cancellable, &local_error);
e5b71e
+
e5b71e
+              /* NOT_FOUND just means the commit is not signed. */
e5b71e
+              if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
e5b71e
+                {
e5b71e
+                  g_clear_error (&local_error);
e5b71e
+                }
e5b71e
+              else if (local_error != NULL)
e5b71e
+                {
e5b71e
+                  g_propagate_error (error, local_error);
e5b71e
+                  goto out;
e5b71e
+                }
e5b71e
+              else
e5b71e
+                {
e5b71e
+                  GString *sigs_buffer;
e5b71e
+                  guint n_sigs, ii;
e5b71e
+
e5b71e
+                  n_sigs = ostree_gpg_verify_result_count_all (result);
e5b71e
+
e5b71e
+                  sigs_buffer = g_string_sized_new (256);
e5b71e
+
e5b71e
+                  for (ii = 0; ii < n_sigs; ii++)
e5b71e
+                    {
e5b71e
+                      g_string_append_c (sigs_buffer, '\n');
e5b71e
+                      ostree_gpg_verify_result_describe (result, ii, sigs_buffer, "  GPG: ",
e5b71e
+                                                         OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT);
e5b71e
+                    }
e5b71e
+
e5b71e
+                  g_print ("%s", sigs_buffer->str);
e5b71e
+                  g_string_free (sigs_buffer, TRUE);
e5b71e
+                }
e5b71e
+            }
e5b71e
+
e5b71e
           printchar ("=", 60);
e5b71e
         }
e5b71e
     }
e5b71e
 
e5b71e
+  /* Print any signatures for the booted deployment, but only in NON-pretty
e5b71e
+   * mode.  We save this for the end to preserve the tabular formatting for
e5b71e
+   * deployments. */
e5b71e
+  if (booted_csum != NULL)
e5b71e
+    {
e5b71e
+      gs_unref_object OstreeGpgVerifyResult *result = NULL;
e5b71e
+      GError *local_error = NULL;
e5b71e
+
e5b71e
+      result = ostree_repo_verify_commit_ext (repo, booted_csum, NULL, NULL,
e5b71e
+                                              cancellable, &local_error);
e5b71e
+
e5b71e
+      /* NOT_FOUND just means the commit is not signed. */
e5b71e
+      if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
e5b71e
+        {
e5b71e
+          g_clear_error (&local_error);
e5b71e
+        }
e5b71e
+      else if (local_error != NULL)
e5b71e
+        {
e5b71e
+          g_propagate_error (error, local_error);
e5b71e
+          goto out;
e5b71e
+        }
e5b71e
+      else
e5b71e
+        {
e5b71e
+          GString *sigs_buffer;
e5b71e
+          guint n_sigs, ii;
e5b71e
+
e5b71e
+          n_sigs = ostree_gpg_verify_result_count_all (result);
e5b71e
+
e5b71e
+          /* XXX If we ever add internationalization, use ngettext() here. */
e5b71e
+          g_print ("\nGPG: Found %u signature%s on the booted deployment (*):\n",
e5b71e
+                   n_sigs, n_sigs == 1 ? "" : "s");
e5b71e
+
e5b71e
+          sigs_buffer = g_string_sized_new (256);
e5b71e
+
e5b71e
+          for (ii = 0; ii < n_sigs; ii++)
e5b71e
+            {
e5b71e
+              g_string_append_c (sigs_buffer, '\n');
e5b71e
+              ostree_gpg_verify_result_describe (result, ii, sigs_buffer, "  ",
e5b71e
+                                                 OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT);
e5b71e
+            }
e5b71e
+
e5b71e
+          g_print ("%s", sigs_buffer->str);
e5b71e
+          g_string_free (sigs_buffer, TRUE);
e5b71e
+        }
e5b71e
+    }
e5b71e
+
e5b71e
   ret = TRUE;
e5b71e
   out:
e5b71e
   	return ret;
e5b71e
-- 
e5b71e
1.8.3.1
e5b71e