From 74c4068b9da7f2dff16a8ee2605d3350a6a782f6 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Thu, 2 Feb 2017 15:41:29 -0500 Subject: [PATCH] core: Do GPG verification before importing While reading a recent conversation about GPG checking at treecompose time, I had a sudden thought - were we actually doing verification client side? Turned out, we aren't. That happens as part of `dnf_transaction_commit()` which we don't use. That function verifies every package at one go, but for us I think it's better to do it before "importing". We shouldn't have untrusted bits that we've unpacked (they might have suid binaries, for one thing). This is an embarassing problem, but it's worth emphasizing that everyone should be retrieving repodata at a minimum over TLS, which sets a baseline. On RHEL, we already do pinned TLS, and there are discussions about extending that elsewhere. --- libdnf | 2 +- src/libpriv/rpmostree-core.c | 12 +++++++++++- tests/common/libvm.sh | 16 ++++++++++++++++ tests/vmcheck/test-layering-gpg.sh | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100755 tests/vmcheck/test-layering-gpg.sh diff --git a/src/libpriv/rpmostree-core.c b/src/libpriv/rpmostree-core.c index 2daaa48..0b4a3ab 100644 --- a/src/libpriv/rpmostree-core.c +++ b/src/libpriv/rpmostree-core.c @@ -1152,18 +1152,25 @@ import_one_package (RpmOstreeContext *self, g_autofree char *ostree_commit = NULL; glnx_unref_object RpmOstreeUnpacker *unpacker = NULL; g_autofree char *pkg_path; + DnfRepo *pkg_repo; int flags = 0; + pkg_repo = dnf_package_get_repo (pkg); + if (pkg_is_local (pkg)) pkg_path = g_strdup (dnf_package_get_filename (pkg)); else { const char *pkg_location = dnf_package_get_location (pkg); pkg_path = - g_build_filename (dnf_repo_get_location (dnf_package_get_repo (pkg)), + g_build_filename (dnf_repo_get_location (pkg_repo), "packages", glnx_basename (pkg_location), NULL); } + /* Verify signatures if enabled */ + if (!dnf_transaction_gpgcheck_package (dnf_context_get_transaction (hifctx), pkg, error)) + goto out; + flags = RPMOSTREE_UNPACKER_FLAGS_OSTREE_CONVENTION; if (self->unprivileged) flags |= RPMOSTREE_UNPACKER_FLAGS_UNPRIVILEGED; @@ -1220,6 +1227,9 @@ rpmostree_context_import (RpmOstreeContext *self, g_return_val_if_fail (get_pkgcache_repo (self) != NULL, FALSE); + if (!dnf_transaction_import_keys (dnf_context_get_transaction (hifctx), error)) + goto out; + { glnx_unref_object DnfState *hifstate = dnf_state_new (); dnf_state_set_number_steps (hifstate, install->packages_to_import->len); diff --git a/tests/common/libvm.sh b/tests/common/libvm.sh index 3b7cb35..bbbcba2 100644 --- a/tests/common/libvm.sh +++ b/tests/common/libvm.sh @@ -51,6 +51,11 @@ vm_cmd() { $SSH "$@" } +# Delete anything which we might change between runs +vm_clean_caches() { + vm_cmd rm /ostree/repo/extensions/rpmostree/pkgcache/refs/heads/* -rf +} + # run rpm-ostree in vm # - $@ args vm_rpmostree() { @@ -68,6 +73,7 @@ vm_send() { # copy the test repo to the vm vm_send_test_repo() { + gpgcheck=${1:-0} vm_cmd rm -rf /tmp/vmcheck vm_send /tmp/vmcheck ${commondir}/compose/yum/repo @@ -77,6 +83,16 @@ name=test-repo baseurl=file:///tmp/vmcheck/repo EOF + if [ $gpgcheck -eq 1 ]; then + cat >> vmcheck.repo <> vmcheck.repo + fi + vm_send /etc/yum.repos.d vmcheck.repo } diff --git a/tests/vmcheck/test-layering-gpg.sh b/tests/vmcheck/test-layering-gpg.sh new file mode 100755 index 0000000..6b66a79 --- /dev/null +++ b/tests/vmcheck/test-layering-gpg.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Copyright (C) 2017 Red Hat, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +set -e + +. ${commondir}/libtest.sh +. ${commondir}/libvm.sh + +set -x + +vm_send_test_repo 1 +vm_clean_caches + +# make sure the package is not already layered +vm_assert_layered_pkg foo absent + +if vm_rpmostree pkg-add foo-1.0 2>err.txt; then + assert_not_reached "Installed unsigned package" +fi +assert_file_has_content err.txt 'package not signed: foo' +echo "ok failed to install unsigned package" -- 2.9.3