summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2017-07-24 16:39:01 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2017-08-08 15:50:25 +0000
commit9f8f351cd45e5dd0219c3177558b497ab10c58e9 (patch)
tree9b5f15183f9e8b09ac6e228f9a38f4f5cc9bb6db
parent1672e2eee058d0fe41ed102ca310a9634d36572f (diff)
downloadostree-9f8f351cd45e5dd0219c3177558b497ab10c58e9.tar.gz
lib: Port gpg verification for remotes to fd-relative
This was the last use of `repo->repodir` internally, and will help finally add `ostree_repo_open_at()`. Closes: #1034 Approved by: jlebon
-rw-r--r--src/libostree/ostree-gpg-verifier.c86
-rw-r--r--src/libostree/ostree-gpg-verifier.h12
-rw-r--r--src/libostree/ostree-repo.c56
3 files changed, 112 insertions, 42 deletions
diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c
index 680c410b..99756e2b 100644
--- a/src/libostree/ostree-gpg-verifier.c
+++ b/src/libostree/ostree-gpg-verifier.c
@@ -40,6 +40,7 @@ struct OstreeGpgVerifier {
GObject parent;
GList *keyrings;
+ GPtrArray *keyring_data;
GPtrArray *key_ascii_files;
};
@@ -53,6 +54,7 @@ ostree_gpg_verifier_finalize (GObject *object)
g_list_free_full (self->keyrings, g_object_unref);
if (self->key_ascii_files)
g_ptr_array_unref (self->key_ascii_files);
+ g_clear_pointer (&self->keyring_data, (GDestroyNotify)g_ptr_array_unref);
G_OBJECT_CLASS (_ostree_gpg_verifier_parent_class)->finalize (object);
}
@@ -71,6 +73,7 @@ _ostree_gpg_verifier_class_init (OstreeGpgVerifierClass *klass)
static void
_ostree_gpg_verifier_init (OstreeGpgVerifier *self)
{
+ self->keyring_data = g_ptr_array_new_with_free_func ((GDestroyNotify)g_bytes_unref);
}
static void
@@ -151,6 +154,17 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
goto out;
}
+ for (guint i = 0; i < self->keyring_data->len; i++)
+ {
+ GBytes *keyringd = self->keyring_data->pdata[i];
+ gsize len;
+ gsize bytes_written;
+ const guint8 *buf = g_bytes_get_data (keyringd, &len);
+ if (!g_output_stream_write_all (target_stream, buf, len, &bytes_written,
+ cancellable, error))
+ goto out;
+ }
+
if (!g_output_stream_close (target_stream, cancellable, error))
goto out;
@@ -253,15 +267,28 @@ out:
return result;
}
+/* Given @path which should contain a GPG keyring file, add it
+ * to the list of trusted keys.
+ */
void
-_ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self,
- GFile *path)
+_ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self,
+ GFile *path)
{
g_return_if_fail (G_IS_FILE (path));
self->keyrings = g_list_append (self->keyrings, g_object_ref (path));
}
+/* Given @keyring which should be the contents of a GPG keyring file, add it to
+ * the list of trusted keys.
+ */
+void
+_ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self,
+ GBytes *keyring)
+{
+ g_ptr_array_add (self->keyring_data, g_bytes_ref (keyring));
+}
+
void
_ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,
const char *path)
@@ -276,32 +303,39 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
GFile *path,
GCancellable *cancellable,
GError **error)
+
{
- gboolean ret = FALSE;
- g_autoptr(GFileEnumerator) enumerator = NULL;
-
- enumerator = g_file_enumerate_children (path, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NONE,
- cancellable, error);
- if (!enumerator)
- goto out;
+ return _ostree_gpg_verifier_add_keyring_dir_at (self, AT_FDCWD,
+ gs_file_get_path_cached (path),
+ cancellable, error);
+}
+
+gboolean
+_ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self,
+ int dfd,
+ const char *path,
+ GCancellable *cancellable,
+ GError **error)
+
+{
+ g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
+ if (!glnx_dirfd_iterator_init_at (dfd, path, FALSE,
+ &dfd_iter, error))
+ return FALSE;
while (TRUE)
{
- GFileInfo *file_info;
- GFile *path;
- const char *name;
+ struct dirent *dent;
- if (!g_file_enumerator_iterate (enumerator, &file_info, &path,
- cancellable, error))
- goto out;
- if (file_info == NULL)
+ if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&dfd_iter, &dent, cancellable, error))
+ return FALSE;
+ if (dent == NULL)
break;
- if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR)
+ if (dent->d_type != DT_REG)
continue;
- name = g_file_info_get_name (file_info);
+ const char *name = dent->d_name;
/* Files with a .gpg suffix are typically keyrings except
* for trustdb.gpg, which is the GPG trust database. */
@@ -315,12 +349,18 @@ _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
if (g_str_equal (name, "secring.gpg"))
continue;
- self->keyrings = g_list_append (self->keyrings, g_object_ref (path));
+ glnx_fd_close int fd = -1;
+ if (!glnx_openat_rdonly (dfd_iter.fd, dent->d_name, TRUE, &fd, error))
+ return FALSE;
+
+ g_autoptr(GBytes) data = glnx_fd_readall_bytes (fd, cancellable, error);
+ if (!data)
+ return FALSE;
+
+ g_ptr_array_add (self->keyring_data, g_steal_pointer (&data));
}
- ret = TRUE;
- out:
- return ret;
+ return TRUE;
}
gboolean
diff --git a/src/libostree/ostree-gpg-verifier.h b/src/libostree/ostree-gpg-verifier.h
index 4156d1bd..7d5a7594 100644
--- a/src/libostree/ostree-gpg-verifier.h
+++ b/src/libostree/ostree-gpg-verifier.h
@@ -55,12 +55,20 @@ gboolean _ostree_gpg_verifier_add_keyring_dir (OstreeGpgVerifier *self,
GCancellable *cancellable,
GError **error);
+gboolean _ostree_gpg_verifier_add_keyring_dir_at (OstreeGpgVerifier *self,
+ int dfd,
+ const char *path,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean _ostree_gpg_verifier_add_global_keyring_dir (OstreeGpgVerifier *self,
GCancellable *cancellable,
GError **error);
-void _ostree_gpg_verifier_add_keyring (OstreeGpgVerifier *self,
- GFile *path);
+void _ostree_gpg_verifier_add_keyring_data (OstreeGpgVerifier *self,
+ GBytes *data);
+void _ostree_gpg_verifier_add_keyring_file (OstreeGpgVerifier *self,
+ GFile *path);
void _ostree_gpg_verifier_add_key_ascii_file (OstreeGpgVerifier *self,
const char *path);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 5d5d871b..7b787760 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -4202,31 +4202,52 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo *self,
/* Special remote for _ostree_repo_gpg_verify_with_metadata() */
static const char *OSTREE_ALL_REMOTES = "__OSTREE_ALL_REMOTES__";
-static GFile *
+/* Look for a keyring for @remote in the repo itself, or in
+ * /etc/ostree/remotes.d.
+ */
+static gboolean
find_keyring (OstreeRepo *self,
OstreeRemote *remote,
- GCancellable *cancellable)
+ GBytes **ret_bytes,
+ GCancellable *cancellable,
+ GError **error)
{
- g_autoptr(GFile) file = g_file_get_child (self->repodir, remote->keyring);
+ glnx_fd_close int fd = -1;
+ if (!ot_openat_ignore_enoent (self->repo_dir_fd, remote->keyring, &fd, error))
+ return FALSE;
- if (g_file_query_exists (file, cancellable))
+ if (fd != -1)
{
- return g_steal_pointer (&file);
+ GBytes *ret = glnx_fd_readall_bytes (fd, cancellable, error);
+ if (!ret)
+ return FALSE;
+ *ret_bytes = ret;
+ return TRUE;
}
g_autoptr(GFile) remotes_d = get_remotes_d_dir (self, NULL);
if (remotes_d)
{
- g_autoptr(GFile) file2 = g_file_get_child (remotes_d, remote->keyring);
+ g_autoptr(GFile) child = g_file_get_child (remotes_d, remote->keyring);
- if (g_file_query_exists (file2, cancellable))
- return g_steal_pointer (&file2);
+ if (!ot_openat_ignore_enoent (AT_FDCWD, gs_file_get_path_cached (child), &fd, error))
+ return FALSE;
+
+ if (fd != -1)
+ {
+ GBytes *ret = glnx_fd_readall_bytes (fd, cancellable, error);
+ if (!ret)
+ return FALSE;
+ *ret_bytes = ret;
+ return TRUE;
+ }
}
if (self->parent_repo)
- return find_keyring (self->parent_repo, remote, cancellable);
+ return find_keyring (self->parent_repo, remote, ret_bytes, cancellable, error);
- return NULL;
+ *ret_bytes = NULL;
+ return TRUE;
}
static OstreeGpgVerifyResult *
@@ -4248,8 +4269,8 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
{
/* Add all available remote keyring files. */
- if (!_ostree_gpg_verifier_add_keyring_dir (verifier, self->repodir,
- cancellable, error))
+ if (!_ostree_gpg_verifier_add_keyring_dir_at (verifier, self->repo_dir_fd, ".",
+ cancellable, error))
return NULL;
}
else if (remote_name != NULL)
@@ -4258,17 +4279,18 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
/* Add the remote's keyring file if it exists. */
OstreeRemote *remote;
- g_autoptr(GFile) file = NULL;
remote = _ostree_repo_get_remote_inherited (self, remote_name, error);
if (remote == NULL)
return NULL;
- file = find_keyring (self, remote, cancellable);
+ g_autoptr(GBytes) keyring_data = NULL;
+ if (!find_keyring (self, remote, &keyring_data, cancellable, error))
+ return NULL;
- if (file != NULL)
+ if (keyring_data != NULL)
{
- _ostree_gpg_verifier_add_keyring (verifier, file);
+ _ostree_gpg_verifier_add_keyring_data (verifier, keyring_data);
add_global_keyring_dir = FALSE;
}
@@ -4297,7 +4319,7 @@ _ostree_repo_gpg_verify_data_internal (OstreeRepo *self,
}
if (extra_keyring != NULL)
{
- _ostree_gpg_verifier_add_keyring (verifier, extra_keyring);
+ _ostree_gpg_verifier_add_keyring_file (verifier, extra_keyring);
}
return _ostree_gpg_verifier_check_signature (verifier,