gpg: Add ostree_gpg_verify_result_describe()
Internalizes the signature output of "ostree show" so it can be reused elsewhere.
This commit is contained in:
parent
bc5c9fca26
commit
7956b0a5c5
|
|
@ -174,6 +174,8 @@ ostree_gpg_verify_result_count_valid
|
||||||
ostree_gpg_verify_result_lookup
|
ostree_gpg_verify_result_lookup
|
||||||
ostree_gpg_verify_result_get
|
ostree_gpg_verify_result_get
|
||||||
ostree_gpg_verify_result_get_all
|
ostree_gpg_verify_result_get_all
|
||||||
|
OstreeGpgSignatureFormatFlags
|
||||||
|
ostree_gpg_verify_result_describe
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
OSTREE_GPG_VERIFY_RESULT
|
OSTREE_GPG_VERIFY_RESULT
|
||||||
OSTREE_IS_GPG_VERIFY_RESULT
|
OSTREE_IS_GPG_VERIFY_RESULT
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "libglnx.h"
|
||||||
#include "libgsystem.h"
|
#include "libgsystem.h"
|
||||||
|
|
||||||
#include "ostree-gpg-verify-result-private.h"
|
#include "ostree-gpg-verify-result-private.h"
|
||||||
|
|
@ -451,6 +454,147 @@ ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result,
|
||||||
G_N_ELEMENTS (all_signature_attrs));
|
G_N_ELEMENTS (all_signature_attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ostree_gpg_verify_result_describe:
|
||||||
|
* @result: an #OstreeGpgVerifyResult
|
||||||
|
* @signature_index: which signature to describe
|
||||||
|
* @output_buffer: a #GString to hold the description
|
||||||
|
* @line_prefix: (allow-none): optional line prefix string
|
||||||
|
* @flags: flags to adjust the description format
|
||||||
|
*
|
||||||
|
* Appends a brief, human-readable description of the GPG signature at
|
||||||
|
* @signature_index in @result to the @output_buffer. The description
|
||||||
|
* spans multiple lines. A @line_prefix string, if given, will precede
|
||||||
|
* each line of the description.
|
||||||
|
*
|
||||||
|
* The @flags argument is reserved for future variations to the description
|
||||||
|
* format. Currently must be 0.
|
||||||
|
*
|
||||||
|
* It is a programmer error to request an invalid @signature_index. Use
|
||||||
|
* ostree_gpg_verify_result_count_all() to find the number of signatures in
|
||||||
|
* @result.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result,
|
||||||
|
guint signature_index,
|
||||||
|
GString *output_buffer,
|
||||||
|
const gchar *line_prefix,
|
||||||
|
OstreeGpgSignatureFormatFlags flags)
|
||||||
|
{
|
||||||
|
g_autoptr(GVariant) variant = NULL;
|
||||||
|
g_autoptr(GDateTime) date_time_utc = NULL;
|
||||||
|
g_autoptr(GDateTime) date_time_local = NULL;
|
||||||
|
g_autofree char *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;
|
||||||
|
|
||||||
|
g_return_if_fail (OSTREE_IS_GPG_VERIFY_RESULT (result));
|
||||||
|
g_return_if_fail (output_buffer != NULL);
|
||||||
|
|
||||||
|
/* The default format 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_return_if_fail (variant != NULL);
|
||||||
|
|
||||||
|
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", ×tamp);
|
||||||
|
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");
|
||||||
|
|
||||||
|
if (line_prefix != NULL)
|
||||||
|
g_string_append (output_buffer, line_prefix);
|
||||||
|
|
||||||
|
g_string_append_printf (output_buffer,
|
||||||
|
"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 (line_prefix != NULL)
|
||||||
|
g_string_append (output_buffer, line_prefix);
|
||||||
|
|
||||||
|
if (key_missing)
|
||||||
|
{
|
||||||
|
g_string_append (output_buffer,
|
||||||
|
"Can't check signature: public key not found\n");
|
||||||
|
}
|
||||||
|
else if (valid)
|
||||||
|
{
|
||||||
|
g_string_append_printf (output_buffer,
|
||||||
|
"Good signature from \"%s <%s>\"\n",
|
||||||
|
user_name, user_email);
|
||||||
|
}
|
||||||
|
else if (sig_expired)
|
||||||
|
{
|
||||||
|
g_string_append_printf (output_buffer,
|
||||||
|
"Expired signature from \"%s <%s>\"\n",
|
||||||
|
user_name, user_email);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_string_append_printf (output_buffer,
|
||||||
|
"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 (line_prefix != NULL)
|
||||||
|
g_string_append (output_buffer, line_prefix);
|
||||||
|
|
||||||
|
if (sig_expired)
|
||||||
|
{
|
||||||
|
g_string_append_printf (output_buffer,
|
||||||
|
"Signature expired %s\n",
|
||||||
|
formatted_date_time);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_string_append_printf (output_buffer,
|
||||||
|
"Signature expires %s\n",
|
||||||
|
formatted_date_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_ostree_gpg_error_to_gio_error (gpgme_error_t gpg_error,
|
_ostree_gpg_error_to_gio_error (gpgme_error_t gpg_error,
|
||||||
GError **error)
|
GError **error)
|
||||||
|
|
|
||||||
|
|
@ -100,4 +100,23 @@ GVariant * ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
|
||||||
GVariant * ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result,
|
GVariant * ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result,
|
||||||
guint signature_index);
|
guint signature_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OstreeGpgSignatureFormatFlags:
|
||||||
|
* @OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT:
|
||||||
|
* Use the default output format
|
||||||
|
*
|
||||||
|
* Formatting flags for ostree_gpg_verify_result_describe(). Currently
|
||||||
|
* there's only one possible output format, but this enumeration allows
|
||||||
|
* for future variations.
|
||||||
|
**/
|
||||||
|
typedef enum {
|
||||||
|
OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT = 0
|
||||||
|
} OstreeGpgSignatureFormatFlags;
|
||||||
|
|
||||||
|
void ostree_gpg_verify_result_describe (OstreeGpgVerifyResult *result,
|
||||||
|
guint signature_index,
|
||||||
|
GString *output_buffer,
|
||||||
|
const gchar *line_prefix,
|
||||||
|
OstreeGpgSignatureFormatFlags flags);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
||||||
|
|
@ -148,87 +148,6 @@ do_print_metadata_key (OstreeRepo *repo,
|
||||||
return ret;
|
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_autofree char *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", ×tamp);
|
|
||||||
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
|
static gboolean
|
||||||
print_object (OstreeRepo *repo,
|
print_object (OstreeRepo *repo,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
|
|
@ -266,16 +185,23 @@ print_object (OstreeRepo *repo,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
GString *buffer;
|
||||||
guint n_sigs, ii;
|
guint n_sigs, ii;
|
||||||
|
|
||||||
n_sigs = ostree_gpg_verify_result_count_all (result);
|
n_sigs = ostree_gpg_verify_result_count_all (result);
|
||||||
g_print ("Found %u signature%s:\n", n_sigs, n_sigs == 1 ? "" : "s");
|
g_print ("Found %u signature%s:\n", n_sigs, n_sigs == 1 ? "" : "s");
|
||||||
|
|
||||||
|
buffer = g_string_sized_new (256);
|
||||||
|
|
||||||
for (ii = 0; ii < n_sigs; ii++)
|
for (ii = 0; ii < n_sigs; ii++)
|
||||||
{
|
{
|
||||||
g_print ("\n");
|
g_string_append_c (buffer, '\n');
|
||||||
print_signature (result, ii);
|
ostree_gpg_verify_result_describe (result, ii, buffer, " ",
|
||||||
|
OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_print ("%s", buffer->str);
|
||||||
|
g_string_free (buffer, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue