diff -Nru linux-signed-4.15.0/debian/changelog linux-signed-4.15.0/debian/changelog --- linux-signed-4.15.0/debian/changelog 2018-04-04 13:29:20.000000000 +0000 +++ linux-signed-4.15.0/debian/changelog 2018-04-21 22:32:56.000000000 +0000 @@ -1,3 +1,60 @@ +linux-signed (4.15.0-19.20) bionic; urgency=medium + + * Master version: 4.15.0-19.20 + + -- Seth Forshee Sat, 21 Apr 2018 17:32:56 -0500 + +linux-signed (4.15.0-18.19+signed2) bionic; urgency=medium + + * Fix dbgsym package handling to work for the case where we have a + bumped linux-signed version number. + + -- Steve Langasek Sat, 21 Apr 2018 00:38:57 -0700 + +linux-signed (4.15.0-18.19+signed1) bionic; urgency=medium + + * Fix the dbgsym packages to be correctly named as .ddeb instead of .deb + so they are published to the right archive. + + -- Steve Langasek Sat, 21 Apr 2018 04:57:38 +0000 + +linux-signed (4.15.0-18.19) bionic; urgency=medium + + * Master version: 4.15.0-18.19 + + * signing: only install a signed kernel (LP: #1764794) + - switch to raw-signing tarball form + - make control.stub master for packages built + - [Config] tone down the output verbosity + - switch to producing linux-image directly + - propogate control information from -unsigned package + - pull control files in from linux-unsigned + - resync control files with master + - introduce meta packages for the debug package + - fix names of substvars files + - propogate Recommends: and Provides: from unsigned package + - fix Section: control records + - do not produce lowlatency dbgsym package for ppc64el + - move dbgsym packages to bottom of control file + - ensure we apt-cache show against the exact version + + * [18.04 FEAT] Sign POWER host/NV kernels (LP: #1696154) + - add Opal signing support and enable for ppc64el + + -- Andy Whitcroft Fri, 20 Apr 2018 13:29:23 +0100 + +linux-signed (4.15.0-17.18) bionic; urgency=medium + + * Master version: 4.15.0-17.18 + + -- Seth Forshee Mon, 16 Apr 2018 15:07:48 -0500 + +linux-signed (4.15.0-16.17) bionic; urgency=medium + + * Master version: 4.15.0-16.17 + + -- Thadeu Lima de Souza Cascardo Fri, 13 Apr 2018 15:19:17 -0300 + linux-signed (4.15.0-15.16) bionic; urgency=medium * Master version: 4.15.0-15.16 diff -Nru linux-signed-4.15.0/debian/control linux-signed-4.15.0/debian/control --- linux-signed-4.15.0/debian/control 2018-04-04 13:29:20.000000000 +0000 +++ linux-signed-4.15.0/debian/control 2018-04-21 22:32:56.000000000 +0000 @@ -1,34 +1,62 @@ Source: linux-signed -Section: utils +Section: kernel Priority: optional Maintainer: Canonical Kernel Team -Build-Depends: debhelper (>= 9), lsb-release, python3, python3-apt, sbsigntool, linux-image-4.15.0-15-generic (>= 4.15.0-15.16), linux-image-4.15.0-15-lowlatency (>= 4.15.0-15.16), +Build-Depends: + debhelper (>= 9), + lsb-release, + python3, + python3-apt, + sbsigntool [amd64], + linux-libc-dev (>= 4.15.0-19.20), Standards-Version: 3.9.4 -Package: linux-signed-image-4.15.0-15-generic -Architecture: linux-amd64 -Depends: ${misc:Depends}, sbsigntool, linux-image-4.15.0-15-generic (= 4.15.0-15.16) -Built-Using: linux (= ${linux:Version}) +Package: linux-image-4.15.0-19-generic +Architecture: amd64 ppc64el +Depends: ${unsigned:Depends} +Recommends: ${unsigned:Recommends} +Suggests: ${unsigned:Suggests} +Conflicts: ${unsigned:Conflicts} +Provides: ${unsigned:Provides} +Built-Using: linux (= 4.15.0-19.20) Description: Signed kernel image generic A kernel image for generic. This version of it is signed with - Canonical's UEFI signing key. + Canonical's UEFI/Opal signing key. -Package: linux-signed-image-4.15.0-15-lowlatency -Architecture: linux-amd64 -Depends: ${misc:Depends}, sbsigntool, linux-image-4.15.0-15-lowlatency (= 4.15.0-15.16) -Built-Using: linux (= ${linux:Version}) +Package: linux-image-4.15.0-19-lowlatency +Architecture: amd64 +Depends: ${unsigned:Depends} +Recommends: ${unsigned:Recommends} +Suggests: ${unsigned:Suggests} +Conflicts: ${unsigned:Conflicts} +Provides: ${unsigned:Provides} +Built-Using: linux (= 4.15.0-19.20) Description: Signed kernel image lowlatency A kernel image for lowlatency. This version of it is signed with Canonical's UEFI signing key. -Package: kernel-signed-image-4.15.0-15-generic-di +Package: kernel-signed-image-4.15.0-19-generic-di Package-Type: udeb Section: debian-installer Priority: extra Provides: kernel-signed-image -Architecture: linux-amd64 -Built-Using: linux (= ${linux:Version}) +Architecture: amd64 ppc64el +Built-Using: linux (= 4.15.0-19.20) Description: Signed kernel image generic for the Debian installer A kernel image for generic. This version of it is signed with Canonical's UEFI signing key. It is intended for the Debian installer, it does _not_ provide a usable kernel for your full Debian system. + +Package: linux-image-4.15.0-19-generic-dbgsym +Section: devel +Architecture: amd64 ppc64el +Depends: linux-image-unsigned-4.15.0-19-generic-dbgsym +Description: Signed kernel image generic + A link to the debugging symbols for the generic signed kernel. + +Package: linux-image-4.15.0-19-lowlatency-dbgsym +Section: devel +Architecture: amd64 +Depends: linux-image-unsigned-4.15.0-19-lowlatency-dbgsym +Description: Signed kernel image lowlatency + A link to the debugging symbols for the lowlatency signed kernel. diff -Nru linux-signed-4.15.0/debian/control-scripts.stub linux-signed-4.15.0/debian/control-scripts.stub --- linux-signed-4.15.0/debian/control-scripts.stub 2017-12-06 14:08:34.000000000 +0000 +++ linux-signed-4.15.0/debian/control-scripts.stub 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -#!/bin/sh -e - -kernel='KERNEL' - -case "$0-$1" in -*.postinst-configure) - rm -f /boot/$kernel.efi.signed - cp /boot/$kernel /boot/$kernel.efi.signed - sbattach --attach /usr/lib/linux/$kernel.efi.signature /boot/$kernel.efi.signed - - if which update-grub >/dev/null 2>&1; then - update-grub || true - fi - ;; -*.postrm-remove) - rm -f /boot/$kernel.efi.signed - - if which update-grub >/dev/null 2>&1; then - update-grub || true - fi - ;; -esac - -#DEBHELPER# - -exit 0 diff -Nru linux-signed-4.15.0/debian/control.stub linux-signed-4.15.0/debian/control.stub --- linux-signed-4.15.0/debian/control.stub 2017-12-06 14:08:34.000000000 +0000 +++ linux-signed-4.15.0/debian/control.stub 2018-04-21 21:21:25.000000000 +0000 @@ -1,6 +1,62 @@ Source: linux-signed -Section: utils +Section: kernel Priority: optional Maintainer: Canonical Kernel Team -Build-Depends: debhelper (>= 9), lsb-release, python3, python3-apt, sbsigntool, BINARIES +Build-Depends: + debhelper (>= 9), + lsb-release, + python3, + python3-apt, + sbsigntool [amd64], + linux-libc-dev (>= VERSION), Standards-Version: 3.9.4 + +Package: linux-image-ABI-generic +Architecture: amd64 ppc64el +Depends: ${unsigned:Depends} +Recommends: ${unsigned:Recommends} +Suggests: ${unsigned:Suggests} +Conflicts: ${unsigned:Conflicts} +Provides: ${unsigned:Provides} +Built-Using: linux (= VERSION) +Description: Signed kernel image generic + A kernel image for generic. This version of it is signed with + Canonical's UEFI/Opal signing key. + +Package: linux-image-ABI-lowlatency +Architecture: amd64 +Depends: ${unsigned:Depends} +Recommends: ${unsigned:Recommends} +Suggests: ${unsigned:Suggests} +Conflicts: ${unsigned:Conflicts} +Provides: ${unsigned:Provides} +Built-Using: linux (= VERSION) +Description: Signed kernel image lowlatency + A kernel image for lowlatency. This version of it is signed with + Canonical's UEFI signing key. + +Package: kernel-signed-image-ABI-generic-di +Package-Type: udeb +Section: debian-installer +Priority: extra +Provides: kernel-signed-image +Architecture: amd64 ppc64el +Built-Using: linux (= VERSION) +Description: Signed kernel image generic for the Debian installer + A kernel image for generic. This version of it is signed with + Canonical's UEFI signing key. It is intended for the Debian installer, + it does _not_ provide a usable kernel for your full Debian system. + +Package: linux-image-ABI-generic-dbgsym +Section: devel +Architecture: amd64 ppc64el +Depends: linux-image-unsigned-ABI-generic-dbgsym +Description: Signed kernel image generic + A link to the debugging symbols for the generic signed kernel. + +Package: linux-image-ABI-lowlatency-dbgsym +Section: devel +Architecture: amd64 +Depends: linux-image-unsigned-ABI-lowlatency-dbgsym +Description: Signed kernel image lowlatency + A link to the debugging symbols for the lowlatency signed kernel. diff -Nru linux-signed-4.15.0/debian/flavour.stub linux-signed-4.15.0/debian/flavour.stub --- linux-signed-4.15.0/debian/flavour.stub 2017-12-06 14:08:34.000000000 +0000 +++ linux-signed-4.15.0/debian/flavour.stub 1970-01-01 00:00:00.000000000 +0000 @@ -1,8 +0,0 @@ - -Package: linux-signed-image-ABI-FLAVOUR -Architecture: linux-amd64 -Depends: ${misc:Depends}, sbsigntool, linux-image-ABI-FLAVOUR (= VERSION) -Built-Using: linux (= ${linux:Version}) -Description: Signed kernel image FLAVOUR - A kernel image for FLAVOUR. This version of it is signed with - Canonical's UEFI signing key. diff -Nru linux-signed-4.15.0/debian/flavour-udeb.stub linux-signed-4.15.0/debian/flavour-udeb.stub --- linux-signed-4.15.0/debian/flavour-udeb.stub 2017-12-06 14:08:34.000000000 +0000 +++ linux-signed-4.15.0/debian/flavour-udeb.stub 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ - -Package: kernel-signed-image-ABI-FLAVOUR-di -Package-Type: udeb -Section: debian-installer -Priority: extra -Provides: kernel-signed-image -Architecture: linux-amd64 -Built-Using: linux (= ${linux:Version}) -Description: Signed kernel image FLAVOUR for the Debian installer - A kernel image for FLAVOUR. This version of it is signed with - Canonical's UEFI signing key. It is intended for the Debian installer, - it does _not_ provide a usable kernel for your full Debian system. diff -Nru linux-signed-4.15.0/debian/rules linux-signed-4.15.0/debian/rules --- linux-signed-4.15.0/debian/rules 2017-12-06 14:08:34.000000000 +0000 +++ linux-signed-4.15.0/debian/rules 2018-04-21 22:32:31.000000000 +0000 @@ -1,45 +1,31 @@ #! /usr/bin/make -f -export DH_VERBOSE := 1 +##export DH_VERBOSE := 1 #VERSION := $(shell LC_ALL=C dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2) +DEB_HOST_ARCH = $(shell dpkg-architecture -qDEB_HOST_ARCH) # Work out the source package name and version. We assume the source package # is the name of this package with -signed stripped. The version is identical # to this package less any rebuild suffic (+signedN). src_package := $(shell LC_ALL=C dpkg-parsechangelog | grep ^Source: | cut -d ' ' -f 2 | sed -e 's/-signed//') -src_version = $(shell LC_ALL=C dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2 | sed -e 's/+signed[0-9]*.*//') +src_fullversion = $(shell LC_ALL=C dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2) +src_version = $(shell echo $(src_fullversion) | sed -e 's/+signed[0-9]*.*//') src_abi = $(shell echo "$(src_version)" | sed -ne 's/\([0-9]*\.[0-9]*\.[0-9]*\-[0-9]*\)\..*/\1/p') -# Flavours in the master package. -# NOTE: flavours must be a superset of udeb_flavours. -flavours = generic lowlatency -udeb_flavours = generic - -flavour_first = $(firstword $(flavours)) -binaries = $(foreach flavour,$(flavours),linux-image-$(src_abi)-$(flavour) \(>= $(src_version)\), ) - # We build our control file. This has to be done before dh runs otherwise # we have no binary files and we will not run the appropriate targets. pre-clean: - { \ - cat debian/control.stub; \ - for flavour in $(flavours); do \ - sed debian/control \ + sed debian/control \ -e "s/ABI/$(src_abi)/g" \ - -e "s/BINARIES/$(binaries)/g" \ -e "s/VERSION/$(src_version)/g" - rm -f version flavours *.signed \ - debian/linux-signed-image-*.install \ - debian/linux-signed-image-*.postinst \ - debian/linux-signed-image-*.postrm + rm -rf ./$(src_version) UNSIGNED SIGNED + rm -f debian/linux-image-*.install \ + debian/linux-image-*.preinst \ + debian/linux-image-*.prerm \ + debian/linux-image-*.postinst \ + debian/linux-image-*.postrm + rm -f debian/kernel-signed-image-*.install PHONY: pre-clean @@ -49,34 +35,60 @@ dh $@ override_dh_auto_build: - ./download-signed "linux-image-$(src_abi)-$(flavour_first)" \ - "$(src_version)" "$(src_package)" - for flavour in $(flavours); do \ - sbattach --detach vmlinuz-$(src_abi)-$$flavour.efi.signature \ - vmlinuz-$(src_abi)-$$flavour.efi.signed; \ - done + ./download-signed "linux-libc-dev" "$(src_version)" "$(src_package)" + #./download-unsigned "$(DEB_HOST_ARCH)" "$(src_version)" + mkdir SIGNED + ( \ + cd "$(src_version)" || exit 1; \ + for s in *.efi.signed; do \ + [ ! -f "$$s" ] && continue; \ + base=$$(echo "$$s" | sed -e 's/.efi.signed//'); \ + ln "$$s" "../SIGNED/$$base"; \ + done; \ + for s in *.opal.sig; do \ + [ ! -f "$$s" ] && continue; \ + base=$$(echo "$$s" | sed -e 's/.opal.sig//'); \ + cat "$$base.opal" "$$s" >"../SIGNED/$$base";\ + done \ + ) override_dh_auto_install: - for flavour in $(flavours); do \ - echo "vmlinuz-$(src_abi)-$$flavour.efi.signature usr/lib/linux" \ - >"debian/linux-signed-image-$(src_abi)-$$flavour.install"; \ - done - for flavour in $(udeb_flavours); do \ - echo "vmlinuz-$(src_abi)-$$flavour.efi.signed boot" \ - >"debian/kernel-signed-image-$(src_abi)-$$flavour-di.install"; \ + for signed in "SIGNED"/*; do \ + flavour=$$(echo "$$signed" | sed -e "s@.*-$(src_abi)-@@"); \ + instfile=$$(echo "$$signed" | sed -e "s@[^/]*/@@" \ + -e "s@-$(src_abi)-.*@@"); \ + verflav="$(src_abi)-$$flavour"; \ + \ + package="kernel-signed-image-$$verflav-di"; \ + echo "$$package: adding $$signed"; \ + echo "$$signed boot" >>"debian/$$package.install"; \ + \ + package="linux-image-$$verflav"; \ + echo "$$package: adding $$signed"; \ + echo "$$signed boot" >>"debian/$$package.install"; \ + \ + ./generate-depends linux-image-unsigned-$$verflav $(src_version) \ + linux-image-$$verflav \ + >>"debian/linux-image-$$verflav.substvars"; \ + \ + for which in postinst postrm preinst prerm; do \ + template="debian/templates/image.$$which.in"; \ + script="debian/$$package.$$which"; \ + sed -e "s/@abiname@/$(src_abi)/g" \ + -e "s/@localversion@/-$$flavour/g" \ + -e "s/@image-stem@/$$instfile/g" \ + <"$$template" >"$$script"; \ + done; \ + echo "interest linux-update-$(src_abi)-$$flavour" \ + >"debian/$$package.triggers"; \ done dh_install -override_dh_installdeb: - for flavour in $(flavours); do \ - sed debian/linux-signed-image-$(src_abi)-$$flavour.postinst; \ - cp debian/linux-signed-image-$(src_abi)-$$flavour.postinst \ - debian/linux-signed-image-$(src_abi)-$$flavour.postrm; \ +override_dh_builddeb: + dh_builddeb + for pkg in $$(dh_listpackages); do \ + case $$pkg in *dbgsym) ;; *) continue ;; esac; \ + mv ../$${pkg}_$(src_fullversion)_$(DEB_HOST_ARCH).deb \ + ../$${pkg}_$(src_fullversion)_$(DEB_HOST_ARCH).ddeb; \ + sed -i "/^$${pkg}_/s/\.deb /.ddeb /" debian/files; \ done - dh_installdeb - -override_dh_gencontrol: - dh_gencontrol -- -Vlinux:Version=$(shell cat version) - diff -Nru linux-signed-4.15.0/debian/templates/image.postinst.in linux-signed-4.15.0/debian/templates/image.postinst.in --- linux-signed-4.15.0/debian/templates/image.postinst.in 1970-01-01 00:00:00.000000000 +0000 +++ linux-signed-4.15.0/debian/templates/image.postinst.in 2018-04-20 16:22:24.000000000 +0000 @@ -0,0 +1,62 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +# +# When we install linux-image we have to run kernel postinst.d support to +# generate the initramfs, create links etc. Should it have an associated +# linux-image-extra package and we install that we also need to run kernel +# postinst.d, to regenerate the initramfs. If we are installing both at the +# same time, we necessarily trigger kernel postinst.d twice. As this includes +# rebuilding the initramfs and reconfiguring the boot loader this is very time +# consuming. +# +# Similarly for removal when we remove the linux-image-extra package we need to +# run kernel postinst.d handling in order to pare down the initramfs to +# linux-image contents only. When we remove the linux-image need to remove the +# now redundant initramfs. If we are removing both at the same time, then +# we will rebuilt the initramfs and then immediatly remove it. +# +# Switches to using a trigger against the linux-image package for all +# postinst.d and postrm.d handling. On installation postinst.d gets triggered +# twice once by linux-image and once by linux-image-extra. As triggers are +# non-cumulative we will only run this processing once. When removing both +# packages we will trigger postinst.d from linux-image-extra and then in +# linux-image postrm.d we effectivly ignore the pending trigger and simply run +# the postrm.d. This prevents us from rebuilding the initramfs. +# +if [ "$1" = triggered ]; then + trigger=/usr/lib/linux/triggers/$version + if [ -f "$trigger" ]; then + sh "$trigger" + rm -f "$trigger" + fi + exit 0 +fi + +if [ "$1" != configure ]; then + exit 0 +fi + +depmod $version + +if [ -f /lib/modules/$version/.fresh-install ]; then + change=install +else + change=upgrade +fi +linux-update-symlinks $change $version $image_path +rm -f /lib/modules/$version/.fresh-install + +if [ -d /etc/kernel/postinst.d ]; then + mkdir -p /usr/lib/linux/triggers + cat - >/usr/lib/linux/triggers/$version </dev/null; then + linux-update-symlinks remove $version $image_path +fi + +if [ -d /etc/kernel/postrm.d ]; then + # We cannot trigger ourselves as at the end of this we will no longer + # exist and can no longer respond to the trigger. The trigger would + # then become lost. Therefore we clear any pending trigger and apply + # postrm directly. + if [ -f /usr/lib/linux/triggers/$version ]; then + echo "$0 ... removing pending trigger" + rm -f /usr/lib/linux/triggers/$version + rmdir --ignore-fail-on-non-empty /usr/lib/linux/triggers + fi + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/postrm.d +fi + +if [ "$1" = purge ]; then + for extra_file in modules.dep modules.isapnpmap modules.pcimap \ + modules.usbmap modules.parportmap \ + modules.generic_string modules.ieee1394map \ + modules.ieee1394map modules.pnpbiosmap \ + modules.alias modules.ccwmap modules.inputmap \ + modules.symbols modules.ofmap \ + modules.seriomap modules.\*.bin \ + modules.softdep modules.devname; do + eval rm -f /lib/modules/$version/$extra_file + done + rmdir /lib/modules/$version || true +fi + +exit 0 diff -Nru linux-signed-4.15.0/debian/templates/image.preinst.in linux-signed-4.15.0/debian/templates/image.preinst.in --- linux-signed-4.15.0/debian/templates/image.preinst.in 1970-01-01 00:00:00.000000000 +0000 +++ linux-signed-4.15.0/debian/templates/image.preinst.in 2018-04-20 16:22:24.000000000 +0000 @@ -0,0 +1,22 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" = abort-upgrade ]; then + exit 0 +fi + +if [ "$1" = install ]; then + # Create a flag file for postinst + mkdir -p /lib/modules/$version + touch /lib/modules/$version/.fresh-install +fi + +if [ -d /etc/kernel/preinst.d ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/preinst.d +fi + +exit 0 diff -Nru linux-signed-4.15.0/debian/templates/image.prerm.in linux-signed-4.15.0/debian/templates/image.prerm.in --- linux-signed-4.15.0/debian/templates/image.prerm.in 1970-01-01 00:00:00.000000000 +0000 +++ linux-signed-4.15.0/debian/templates/image.prerm.in 2018-04-20 16:22:24.000000000 +0000 @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +version=@abiname@@localversion@ +image_path=/boot/@image-stem@-$version + +if [ "$1" != remove ]; then + exit 0 +fi + +linux-check-removal $version + +if [ -d /etc/kernel/prerm.d ]; then + DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \ + --arg=$image_path /etc/kernel/prerm.d +fi + +exit 0 diff -Nru linux-signed-4.15.0/download-signed linux-signed-4.15.0/download-signed --- linux-signed-4.15.0/download-signed 2017-12-06 14:08:34.000000000 +0000 +++ linux-signed-4.15.0/download-signed 2018-04-20 16:22:24.000000000 +0000 @@ -1,97 +1,165 @@ #! /usr/bin/python3 -import sys +import hashlib +import os import re import shutil -from urllib.parse import urlparse, urlunparse -from urllib.error import HTTPError +import sys +import tarfile from urllib import request +from urllib.error import HTTPError +from urllib.parse import ( + urlparse, + urlunparse, + ) import apt from aptsources.distro import get_distro +# package_name: package containing the objects we signed +# package_version: package version containing the objects we signed +# src_package: source package name in dists (package_name, package_version, src_package) = sys.argv[1:] -# Find the package in the available archive repositories. Use a _binary_ -# package name and version to locate the appropriate archive. Then use the -# URI there to look for and find the appropriate binary. -cache = apt.Cache() - -package = None -for version in cache[package_name].versions: - if version.version == package_version: - package = version - break - -if not package: - raise KeyError("{0}: package version not found".format(package_name)) - - -pool_parsed = urlparse(package.uri) -distro = get_distro().codename -#distro = 'quantal' -package_dir = "/main/uefi/%s-%s/%s/" % ( - src_package, package.architecture, package_version) - -# Prepare the master url stem and pull out any username/password. If present -# replace the default opener with one which offers that password. -dists_parsed_master = list(pool_parsed) -if '@' in dists_parsed_master[1]: - (username_password, host) = pool_parsed[1].split('@', 1) - (username, password) = username_password.split(':', 1) - - dists_parsed_master[1] = host - - # Work out the authentication domain. - domain_parsed = [ dists_parsed_master[0], dists_parsed_master[1], '/', None, None, None ] - auth_uri = urlunparse(domain_parsed) - # create a password manager - password_mgr = request.HTTPPasswordMgrWithDefaultRealm() +class SignedDownloader: + """Download a block of signed information from dists. - # Add the username and password. - # If we knew the realm, we could use it instead of None. - password_mgr.add_password(None, auth_uri, username, password) - - handler = request.HTTPBasicAuthHandler(password_mgr) - - # create "opener" (OpenerDirector instance) - opener = request.build_opener(handler) - - # Now all calls to urllib.request.urlopen use our opener. - request.install_opener(opener) - - -def download(base): - for pocket in ('-proposed', '-updates', '-security', '', '-backports'): - dists_parsed = list(dists_parsed_master) - dists_parsed[2] = re.sub(r"/pool/.*", "/dists/" + distro + \ - pocket + package_dir + base, dists_parsed[2]) + Find a block of signed information as published in dists/*/signed + and download the contents. Use the contained checksum files to + identify the members and to validate them once downloaded. + """ + + def __init__(self, package_name, package_version, src_package): + self.package_name = package_name + self.package_version = package_version + self.src_package = src_package + + # Find the package in the available archive repositories. Use a _binary_ + # package name and version to locate the appropriate archive. Then use the + # URI there to look for and find the appropriate binary. + cache = apt.Cache() + + self.package = None + for version in cache[package_name].versions: + if version.version == self.package_version: + self.package = version + break + + if not self.package: + raise KeyError("{0}: package version not found".format(self.package_name)) + + origin = self.package.origins[0] + pool_parsed = urlparse(self.package.uri) + self.package_dir = "%s/%s/%s/%s-%s/%s/" % ( + origin.archive, origin.component, 'signed', + self.src_package, self.package.architecture, self.package_version) + + # Prepare the master url stem and pull out any username/password. If present + # replace the default opener with one which offers that password. + dists_parsed_master = list(pool_parsed) + if '@' in dists_parsed_master[1]: + (username_password, host) = pool_parsed[1].split('@', 1) + (username, password) = username_password.split(':', 1) + + dists_parsed_master[1] = host + + # Work out the authentication domain. + domain_parsed = [ dists_parsed_master[0], dists_parsed_master[1], '/', None, None, None ] + auth_uri = urlunparse(domain_parsed) + + # create a password manager + password_mgr = request.HTTPPasswordMgrWithDefaultRealm() + + # Add the username and password. + # If we knew the realm, we could use it instead of None. + password_mgr.add_password(None, auth_uri, username, password) + + handler = request.HTTPBasicAuthHandler(password_mgr) + + # create "opener" (OpenerDirector instance) + opener = request.build_opener(handler) + + # Now all calls to urllib.request.urlopen use our opener. + request.install_opener(opener) + + self.dists_parsed = dists_parsed_master + + def download_one(self, member, filename, hash_factory=None): + directory = os.path.dirname(filename) + if not os.path.exists(directory): + os.makedirs(directory) + + dists_parsed = list(self.dists_parsed) + dists_parsed[2] = re.sub(r"/pool/.*", "/dists/" + self.package_dir + \ + member, dists_parsed[2]) dists_uri = urlunparse(dists_parsed) print("Downloading %s ... " % dists_uri, end='') + sys.stdout.flush() try: - with request.urlopen(dists_uri) as dists, open(base, "wb") as out: - shutil.copyfileobj(dists, out) + with request.urlopen(dists_uri) as dists, open(filename, "wb") as out: + hashobj = None + if hash_factory: + hashobj = hash_factory() + for chunk in iter(lambda: dists.read(256 * 1024), b''): + if hashobj: + hashobj.update(chunk) + out.write(chunk) + checksum = True + if hashobj: + checksum = hashobj.hexdigest() except HTTPError as e: if e.code == 404: print("not found") - continue - raise + else: + raise else: print("found") - return True - return False - -for base in "flavours", "version": - if not download(base): - print('download-signed: {0}: not found'.format(base)) - sys.exit(1) - -with open("flavours") as fd: - for line in fd: - filename = line.rstrip() - filename += '.signed' - if not download(filename): - print('download-signed: {0}: not found'.format(filename)) + return checksum + return None + + def download(self, base): + """Download an entire signed result from dists.""" + + # Download the checksums and use that to download the contents. + sums = 'SHA256SUMS' + sums_local = os.path.join(base, self.package_version, sums) + if not self.download_one(sums, sums_local): + print('download-signed: {0}: not found'.format(sums)) sys.exit(1) + + # Read the checksum file and download the files it mentions. + here = os.path.abspath(base) + with open(sums_local) as sfd: + for line in sfd: + line = line.strip() + (checksum_expected, member) = (line[0:64], line[66:]) + filename = os.path.abspath(os.path.join(base, self.package_version, member)) + if not filename.startswith(here): + print('download-signed: {0}: member outside output directory'.format(member)) + sys.exit(1) + + # Download and checksum this member. + checksum_actual = self.download_one(member, filename, hashlib.sha256) + if checksum_expected != checksum_actual: + print('download-signed: {0}: member checksum invalid'.format(member)) + sys.exit(1) + + # If this is a tarball result then extract it. + here = os.path.abspath(os.path.join(base, self.package_version)) + tarball_filename = os.path.join(base, self.package_version, 'signed.tar.gz') + if os.path.exists(tarball_filename): + with tarfile.open(tarball_filename) as tarball: + for tarinfo in tarball: + fullname = os.path.abspath(os.path.join(base, tarinfo.name)) + if not filename.startswith(here): + print('download-signed: {0}: tarball member outside output directory'.format(member)) + sys.exit(1) + for tarinfo in tarball: + print('Extracting {0} ...'.format(tarinfo.name)) + tarball.extract(tarinfo, base) + + +downloader = SignedDownloader(package_name, package_version, src_package) +downloader.download('.') diff -Nru linux-signed-4.15.0/download-unsigned linux-signed-4.15.0/download-unsigned --- linux-signed-4.15.0/download-unsigned 1970-01-01 00:00:00.000000000 +0000 +++ linux-signed-4.15.0/download-unsigned 2018-04-20 16:22:24.000000000 +0000 @@ -0,0 +1,17 @@ +#!/bin/bash + +arch="$1" +version="$2" + +unsigned=$(awk ' + /^Package: linux-image-/ { package=$2; next } + /^Package:/ { package=""; next } + /^Architecture:.* '"$arch"'( |$)/ { print package } + ' /$from/"