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