Add "gpgkeypath" option to remotes
For Project Atomic, we already have RPM signatures which use files in `/etc/pki/rpm-gpg`. It's convenient to simply bind the OSTree remote configuration to those file paths, rather than having duplicate key data. This does mean that we need to parse the files for verification, so we end up importing them into the verifier's temporary keyring, which is a bit ugly, but it's what other projects do. Closes: https://github.com/ostreedev/ostree/issues/573 Closes: #575 Approved by: giuseppe
This commit is contained in:
1 parent
3cd5e6b41a
commit
f244c70277
6 files changed
+99
-5
No files matched your search
@@ -40,6 +40,7 @@ struct OstreeGpgVerifier {
|
||||
GObject parent;
|
||||
|
||||
GList *keyrings;
|
||||
GPtrArray *key_ascii_files;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (OstreeGpgVerifier, _ostree_gpg_verifier, G_TYPE_OBJECT)
|
||||
@@ -50,6 +51,8 @@ ostree_gpg_verifier_finalize (GObject *object)
|
||||
OstreeGpgVerifier *self = OSTREE_GPG_VERIFIER (object);
|
||||
|
||||
g_list_free_full (self->keyrings, g_object_unref);
|
||||
if (self->key_ascii_files)
|
||||
g_ptr_array_unref (self->key_ascii_files);
|
||||
|
||||
G_OBJECT_CLASS (_ostree_gpg_verifier_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -98,6 +101,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
||||
OstreeGpgVerifyResult *result = NULL;
|
||||
gboolean success = FALSE;
|
||||
GList *link;
|
||||
int armor;
|
||||
|
||||
/* GPGME has no API for using multiple keyrings (aka, gpg --keyring),
|
||||
* so we concatenate all the keyring files into one pubring.gpg in a
|
||||
@@ -149,6 +153,44 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
||||
if (!g_output_stream_close (target_stream, cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* Save the previous armor value - we need it on for importing ASCII keys */
|
||||
armor = gpgme_get_armor (result->context);
|
||||
gpgme_set_armor (result->context, 1);
|
||||
|
||||
/* Now, use the API to import ASCII-armored keys */
|
||||
if (self->key_ascii_files)
|
||||
{
|
||||
for (guint i = 0; i < self->key_ascii_files->len; i++)
|
||||
{
|
||||
const char *path = self->key_ascii_files->pdata[i];
|
||||
glnx_fd_close int fd = -1;
|
||||
ot_auto_gpgme_data gpgme_data_t kdata = NULL;
|
||||
|
||||
fd = openat (AT_FDCWD, path, O_RDONLY | O_CLOEXEC) ;
|
||||
if (fd < 0)
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "Opening %s", path);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gpg_error = gpgme_data_new_from_fd (&kdata, fd);
|
||||
if (gpg_error != GPG_ERR_NO_ERROR)
|
||||
{
|
||||
ot_gpgme_error_to_gio_error (gpg_error, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gpg_error = gpgme_op_import (result->context, kdata);
|
||||
if (gpg_error != GPG_ERR_NO_ERROR)
|
||||
{
|
||||
ot_gpgme_error_to_gio_error (gpg_error, error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gpgme_set_armor (result->context, armor);
|
||||
|
||||
/* Both the signed data and signature GBytes instances will outlive the
|
||||
* gpgme_data_t structs, so we can safely reuse the GBytes memory buffer
|
||||
* directly and avoid a copy. */
|
||||
@@ -225,6 +267,15 @@ _ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self,
|
||||
self->keyrings = g_list_append (self->keyrings, g_object_ref (path));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,
|
||||
const char *path)
|
||||
{
|
||||
if (!self->key_ascii_files)
|
||||
self->key_ascii_files = g_ptr_array_new_with_free_func (g_free);
|
||||
g_ptr_array_add (self->key_ascii_files, g_strdup (path));
|
||||
}
|
||||
|
||||
gboolean
|
||||
_ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
|
||||
GFile *path,
|
||||
|
||||
@@ -62,4 +62,7 @@ gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *s
|
||||
void _ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self,
|
||||
GFile *path);
|
||||
|
||||
void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,
|
||||
const char *path);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -4282,6 +4282,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
|
||||
}
|
||||
else if (remote_name != NULL)
|
||||
{
|
||||
g_autofree char *gpgkeypath = NULL;
|
||||
/* Add the remote's keyring file if it exists. */
|
||||
|
||||
OstreeRemote *remote;
|
||||
@@ -4299,6 +4300,13 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
|
||||
add_global_keyring_dir = FALSE;
|
||||
}
|
||||
|
||||
if (!ot_keyfile_get_value_with_default (remote->options, remote->group, "gpgkeypath", NULL,
|
||||
&gpgkeypath, error))
|
||||
return NULL;
|
||||
|
||||
if (gpgkeypath)
|
||||
_ostree_gpg_verifier_add_key_ascii_file (verifier, gpgkeypath);
|
||||
|
||||
ost_remote_unref (remote);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user