mirror of
https://github.com/ostreedev/ostree.git
synced 2025-03-16 10:50:43 +03:00
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_get
|
||||
ostree_gpg_verify_result_get_all
|
||||
OstreeGpgSignatureFormatFlags
|
||||
ostree_gpg_verify_result_describe
|
||||
<SUBSECTION Standard>
|
||||
OSTREE_GPG_VERIFY_RESULT
|
||||
OSTREE_IS_GPG_VERIFY_RESULT
|
||||
|
@ -20,6 +20,9 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libglnx.h"
|
||||
#include "libgsystem.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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
_ostree_gpg_error_to_gio_error (gpgme_error_t gpg_error,
|
||||
GError **error)
|
||||
|
@ -100,4 +100,23 @@ GVariant * ostree_gpg_verify_result_get (OstreeGpgVerifyResult *result,
|
||||
GVariant * ostree_gpg_verify_result_get_all (OstreeGpgVerifyResult *result,
|
||||
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
|
||||
|
@ -148,87 +148,6 @@ 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_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
|
||||
print_object (OstreeRepo *repo,
|
||||
OstreeObjectType objtype,
|
||||
@ -266,16 +185,23 @@ print_object (OstreeRepo *repo,
|
||||
}
|
||||
else
|
||||
{
|
||||
GString *buffer;
|
||||
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");
|
||||
|
||||
buffer = g_string_sized_new (256);
|
||||
|
||||
for (ii = 0; ii < n_sigs; ii++)
|
||||
{
|
||||
g_print ("\n");
|
||||
print_signature (result, ii);
|
||||
g_string_append_c (buffer, '\n');
|
||||
ostree_gpg_verify_result_describe (result, ii, buffer, " ",
|
||||
OSTREE_GPG_SIGNATURE_FORMAT_DEFAULT);
|
||||
}
|
||||
|
||||
g_print ("%s", buffer->str);
|
||||
g_string_free (buffer, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user