diff --git a/qubesmanager/dsa-4371-update b/qubesmanager/dsa-4371-update new file mode 100644 index 0000000..f00f245 --- /dev/null +++ b/qubesmanager/dsa-4371-update @@ -0,0 +1,131 @@ +#!/bin/bash + +# Log everthing to stdout. +# Use qrexc output only to communicate success/failure +exec {qrexec_output}>&1 +exec 1>&2 + +set -eu -o pipefail + +tmp= + +error() { + printf "Error: $1\n" "${@:2}" + exit +} + +exit_ok() { + printf "Ok: $2\n" "${@:3}" + printf "$1\n" >&$qrexec_output + exit +} + +cleanup() { + if [ -n "$tmp" ]; then + rm -rf "$tmp" + fi +} + +check_apt_version() { + local pkg="$1" + local fixed_version="$2" + if [ -z "$fixed_version" ] || [ -z "$pkg" ]; then + error "Bug: Invalid argument!" + fi + + installed_version="$(dpkg -s $pkg | grep '^Version: ' | cut -d ' ' -f 2)" + if [ -z "$installed_version" ]; then + error "Failed to get apt version." + fi + + rc=0 + dpkg --compare-versions "$installed_version" ge "$fixed_version" || rc=$? + + if [ "$rc" -gt 1 ]; then + error "Bug: Failed to compare versions!" + fi + + return $rc +} + +main() { + if [ ! -e /etc/debian_version ]; then + exit_ok 'changed=no' 'Not a Debian.' + fi + + trap cleanup EXIT + tmp="$(mktemp -d --tmpdir)" + + codename="$(cat /etc/debian_version)" + case "$codename" in + */sid) + # We will treat testing as sid here. This hopefully won't break + # anything ... + codename="sid" + pkg="libapt-pkg5.0" + fixed_version="1.8.0~alpha3.1" + ;; + 8.*) + codename="jessie" + pkg="libapt-pkg4.12" + fixed_version="1.0.9.8.5" + ;; + 9.*) + codename="stretch" + pkg="libapt-pkg5.0" + fixed_version="1.4.9" + ;; + *) + error 'Error: Could not determine Debian release!' + esac + + if check_apt_version "$pkg" "$fixed_version"; then + exit_ok 'changed=no' 'Nothing to do, apt already fixed.' + fi + + : > "$tmp/sources.list" + mkdir "$tmp/sources.list.d" + + # Make sure that any old (maybe bogus) list is removed. + apt-get \ + -o "Acquire::http::AllowRedirect=false" \ + -o "Dir::Etc::SourceList=$tmp/sources.list" \ + -o "Dir::Etc::SourceParts=$tmp/sources.list.d" \ + --list-cleanup \ + update + + printf 'deb http://cdn-fastly.deb.debian.org/debian %s main\n' "$codename" > "$tmp/sources.list" + if [ "$codename" != "sid" ]; then + printf 'deb http://cdn-fastly.deb.debian.org/debian-security %s/updates main\n' "$codename" >> "$tmp/sources.list" + fi + + # Don't fetch Translation and Contents file. We don't need them and we will + # throw them away later anyway. + apt-get \ + -o "Acquire::http::AllowRedirect=false" \ + -o "Acquire::Languages=none" \ + -o "Acquire::IndexTargets::deb::Contents-deb::DefaultEnabled=false" \ + -o "Dir::Etc::SourceList=$tmp/sources.list" \ + -o "Dir::Etc::SourceParts=$tmp/sources.list.d" \ + update + + apt-get \ + -o "Acquire::http::AllowRedirect=false" \ + -o "Dir::Etc::SourceList=$tmp/sources.list" \ + -o "Dir::Etc::SourceParts=$tmp/sources.list.d" \ + --no-remove \ + --only-upgrade \ + -y \ + install "$pkg" + + if ! check_apt_version "$pkg" "$fixed_version"; then + error 'apt version is still not fixed!' + fi + + # Run update again to restore normal package sources. + apt-get update + + exit_ok 'changed=yes' "Done." +} + +main diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py index 1f2ab9d..83720ab 100644 --- a/qubesmanager/qube_manager.py +++ b/qubesmanager/qube_manager.py @@ -277,6 +277,23 @@ class UpdateVMThread(QtCore.QThread): else: if not self.vm.is_running(): self.vm.start() + # apply DSA-4371 + with open('/usr/libexec/qubes-manager/dsa-4371-update', 'rb') \ + as dsa4371update: + stdout, stderr = self.vm.run_service_for_stdio( + "qubes.VMShell", + user="root", + input=dsa4371update.read()) + if stdout == b'changed=yes\n': + subprocess.call(['notify-send', '-i', 'dialog-information', + 'Debian DSA-4371 fix installed in {}'.format( + self.vm.name)]) + elif stdout == b'changed=no\n': + pass + else: + raise exc.QubesException( + "Failed to apply DSA-4371 fix: {}".format( + stderr.decode('ascii'))) self.vm.run_service("qubes.InstallUpdatesGUI",\ user="root", wait=False) except (ChildProcessError, exc.QubesException) as ex: diff --git a/rpm_spec/qmgr.spec.in b/rpm_spec/qmgr.spec.in index 28a0828..65adced 100644 --- a/rpm_spec/qmgr.spec.in +++ b/rpm_spec/qmgr.spec.in @@ -41,6 +41,7 @@ make python_install \ mkdir -p $RPM_BUILD_ROOT/usr/libexec/qubes-manager/ cp qubesmanager/mount_for_backup.sh $RPM_BUILD_ROOT/usr/libexec/qubes-manager/ cp qubesmanager/qvm_about.sh $RPM_BUILD_ROOT/usr/libexec/qubes-manager/ +cp qubesmanager/dsa-4371-update $RPM_BUILD_ROOT/usr/libexec/qubes-manager/ mkdir -p $RPM_BUILD_ROOT/usr/share/applications cp qubes-global-settings.desktop $RPM_BUILD_ROOT/usr/share/applications/ @@ -72,6 +73,7 @@ rm -rf $RPM_BUILD_ROOT /usr/bin/qubes-template-manager /usr/libexec/qubes-manager/mount_for_backup.sh /usr/libexec/qubes-manager/qvm_about.sh +/usr/libexec/qubes-manager/dsa-4371-update %dir %{python3_sitelib}/qubesmanager %{python3_sitelib}/qubesmanager/__pycache__