Package: debhelper Version: 9.20131227ubuntu1 Severity: wishlist Dear Maintainer,
This is a request for adding file signatures in .deb packages and for installing those signatures as 'security.ima' extended attributes at package install time. The existing md5sums file contains the file hash and name for each file included in the package, making it the most logical place for storing file signatures. This patch set defines a new debhelper dh_checksums, based on dh_md5sums, to support additional, larger digests. Depending on the relationship of the build and signing server, the signatures could either be included in the checksums files during the package build process or post build, prior to uploading. Included in this patch set is a sample script that opens the package, extracts the checksums file, includes the file signatures, and inserts the modified checksums file with the file signatures in the deb package. To install the file signatures as 'security.ima' extended attributes, this patch set defines the dh_installfile-sigs debhelper and the postinst-file-sigs autoscript. Although the checksums file should contain signatures for all files, the autoscript currently installs only the signatures for ELF files and scripts, making them "immutable" on systems with IMA-appraisal enabled and configured in enforcing mode. -- System Information: Debian Release: jessie/sid APT prefers trusty-updates APT policy: (500, 'trusty-updates'), (500, 'trusty-security'), (500, 'trusty'), (100, 'trusty-backports') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.2+ (SMP w/2 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages debhelper depends on: ii binutils 2.24-5ubuntu3 ii dh-apparmor 2.8.95~2430-0ubuntu5 ii dpkg 1.17.5ubuntu5.3 ii dpkg-dev 1.17.5ubuntu5.3 ii file 1:5.14-2ubuntu3.1 ii man-db 2.6.7.1-1 ii perl 5.18.2-2ubuntu1 ii po-debconf 1.0.16+nmu2ubuntu1 debhelper recommends no packages. Versions of packages debhelper suggests: ii dh-make 0.63 -- no debconf information
>From d8be569b21899a9be817aba7fd04410ac28cdd3b Mon Sep 17 00:00:00 2001 From: Mimi Zohar <[email protected]> Date: Thu, 7 Aug 2014 08:55:29 -0400 Subject: [PATCH 2/3] Define a new debhelper dh_checksums The new dh_checksums debhelper extends the existing dh_md5sums to support larger file digests (eg. sha256, sha512). The resulting checksums are stored in an algorithm specific filename DEBIAN/<algo sums>. This patch defines a new option "--algo=" to specify the hash algorithm. The default hash algorithm is sha256. Changelog v2: - dh_md5sums is called manually from numerous packages. Do not remove it. Changelog v1: - Based on the mailing list discussion, replace the existing dh_md5sums script with a single debhelper script that supports larger hashes. --- dh | 1 + dh_checksums | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100755 dh_checksums diff --git a/dh b/dh index 4f80f75..f3da70d 100755 --- a/dh +++ b/dh @@ -409,6 +409,7 @@ my @b=qw{ dh_installdeb dh_gencontrol dh_md5sums + dh_checksums dh_builddeb }; $sequences{clean} = [qw{ diff --git a/dh_checksums b/dh_checksums new file mode 100755 index 0000000..8908ebc --- /dev/null +++ b/dh_checksums @@ -0,0 +1,118 @@ +#!/usr/bin/perl -w + +=head1 NAME + +dh_checksums - generate the DEBIAN/<algo sums> file + +=cut + +use strict; +use Cwd; +use Debian::Debhelper::Dh_Lib; + +=head1 SYNOPSIS + +B<dh_checksums> [S<I<debhelper options>>] [B<-x>] [B<-X>I<item>] [B<--include-conffiles>] [B<--alg=>I<algorithm>] + +=head1 DESCRIPTION + +B<dh_checksums> is a debhelper program that is responsible for generating +a checksums file, which lists the hashes of each file in the package. +These files are used by the B<debsums> package. + +All files in F<DEBIAN/> are omitted from the F<checksums> file, as are all +conffiles (unless you use the B<--include-conffiles> switch). + +The checksums file is installed with proper permissions and ownerships. + +=head1 OPTIONS + +=over 4 + +=item B<-x>, B<--include-conffiles> + +Include conffiles in the checksums list. Note that this information is +redundant since it is included elsewhere in Debian packages. + +=item B<-X>I<item>, B<--exclude=>I<item> + +Exclude files that contain I<item> anywhere in their filename from +being listed in the checksums file. + +=item B<--alg=>I<algorithm> + +Used to override the default hash algorithm (sha256). The current set +of valid hash algorithms are: b<md5>, b<sha256>, b<sha512> + +=back + +=cut + +init(options => { + "x" => \$dh{INCLUDE_CONFFILES}, # is -x for some unknown historical reason.. + "include-conffiles" => \$dh{INCLUDE_CONFFILES}, + "alg=s" => \$dh{ALG}, +}); + +if (defined $dh{ALG}) { + my @algorithms = <md5 sha256 sha512>; + use List::MoreUtils 'any'; + $dh{ALG}="sha256" unless any { /$dh{ALG}/ } @algorithms; +} else { + $dh{ALG}="sha256"; +} +my $HASHCMD = $dh{ALG}."sum"; +my $hashsums = $dh{ALG}."sums"; + +foreach my $package (@{$dh{DOPACKAGES}}) { + next if is_udeb($package); + + my $tmp=tmpdir($package); + + if (! -d "$tmp/DEBIAN") { + doit("install","-d","$tmp/DEBIAN"); + } + + # Check if we should exclude conffiles. + my $exclude=""; + if (! $dh{INCLUDE_CONFFILES} && -r "$tmp/DEBIAN/conffiles") { + # Generate exclude regexp. + open (CONFF,"$tmp/DEBIAN/conffiles"); + while (<CONFF>) { + chomp; + s/^\///; + $exclude.="! -path \"./$_\" "; + } + close CONFF; + } + + # See if we should exclude other files. + if (defined($dh{EXCLUDE_FIND}) && $dh{EXCLUDE_FIND} ne '') { + $exclude.="! \\( $dh{EXCLUDE_FIND} \\) "; + } + + my $find="find . -type f $exclude ! -regex './DEBIAN/.*' -printf '%P\\0'"; + complex_doit("(cd $tmp >/dev/null ; $find | LC_ALL=C sort -z | xargs -r0 $HASHCMD > DEBIAN/$hashsums) >/dev/null"); + # If the file's empty, no reason to waste inodes on it. + if (-z "$tmp/DEBIAN/$hashsums") { + doit("rm","-f","$tmp/DEBIAN/$hashsums"); + } + else { + doit("chmod",644,"$tmp/DEBIAN/$hashsums"); + doit("chown","0:0","$tmp/DEBIAN/$hashsums"); + } +} + +=head1 SEE ALSO + +L<debhelper(7)> + +This program is a part of debhelper. + +=head1 AUTHOR + +Joey Hess <[email protected]> + +(Modified by Mimi Zohar <[email protected]> to support other digests) + +=cut -- 1.9.1
>From e2aa0e82dd8cdcffd67587ca8e9904c85eeb57d4 Mon Sep 17 00:00:00 2001 From: Mimi Zohar <[email protected]> Date: Thu, 7 Aug 2014 08:23:25 -0400 Subject: [PATCH 1/3] Define a new debhelper dh_installfile-sigs and postinst autoscript This patch defines a debhelper dh_installfile-sigs and autoscript postinst-file-sigs to install the ELF file and script signatures stored in the checksums file named DEBIAN/<algo sums>. Changelog v1: - Fix postinst script error msg, replacing 'grep' with 'case' statement. --- autoscripts/postinst-file-sigs | 30 +++++++++++++++++++++++++++ dh | 1 + dh_installfile-sigs | 46 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 autoscripts/postinst-file-sigs create mode 100755 dh_installfile-sigs diff --git a/autoscripts/postinst-file-sigs b/autoscripts/postinst-file-sigs new file mode 100644 index 0000000..f0efbfe --- /dev/null +++ b/autoscripts/postinst-file-sigs @@ -0,0 +1,30 @@ +file=$(dpkg-query --control-path #PACKAGE# sha256sums) +if [ ! -e "${file}" ]; then + file=$(dpkg-query --control-path #PACKAGE# sha512sums) +fi + +if [ "$1" = "configure" ]; then + if [ -e "${file}" ]; then + while read -r line; do + sig=$(echo "${line}" | awk '{print $3}') + if [ ! -n "$sig" ]; then + continue; + + fn=$(echo "${line}" | awk '{print $2}') + if [ ! -e "${fn}" ]; then + continue; + fi + + case "$(file --brief $fn)" in + *script*) + setfattr -n 'security.ima' -v 0x$sig ${fn} + ;; + *ELF*) + setfattr -n 'security.ima' -v 0x$sig ${fn} + ;; + esac + done < "${file}" + fi +fi + +exit 0; diff --git a/dh b/dh index f3bd321..4f80f75 100755 --- a/dh +++ b/dh @@ -373,6 +373,7 @@ my @i = qw{ dh_installifupdown dh_installinfo dh_installinit + dh_installfile-sigs dh_installmenu dh_installmime dh_installmodules diff --git a/dh_installfile-sigs b/dh_installfile-sigs new file mode 100755 index 0000000..8a8888b --- /dev/null +++ b/dh_installfile-sigs @@ -0,0 +1,46 @@ +#!/usr/bin/perl -w + +=head1 NAME + +dh_installfile-sigs - install file signatures in the DEBIAN/<algo sums> file as xattrs + +=cut + +use strict; +use Cwd; +use Debian::Debhelper::Dh_Lib; + +=head1 SYNOPSIS + +B<dh_installfile-sigs> + +=head1 DESCRIPTION + +B<dh_installfile-sigs> is a debhelper program that is responsible for automatically +generating the F<postinst> commands needed to install file signatures contained in +the checksums file F<DEBIAN/algo sums>. These commands are inserted into the maintainer +scripts by L<dh_installdeb(1)>. + +=cut + +init(); + +foreach my $package (@{$dh{DOPACKAGES}}) { + + if (! $dh{NOSCRIPTS}) { + autoscript($package,"postinst","postinst-file-sigs","s!#PACKAGE#!$package!g"); + } +} + + +=head1 SEE ALSO + +L<debhelper(7)> + +This program is a part of debhelper. + +=head1 AUTHOR + +Mimi Zohar <[email protected]> + +=cut -- 1.9.1
>From 730d6b2ca37d36ef96e07f9cb21cbcaf4a9ea230 Mon Sep 17 00:00:00 2001 From: Mimi Zohar <[email protected]> Date: Tue, 14 Oct 2014 08:15:21 -0400 Subject: [PATCH 3/3] Include sample script named ima-signhashes.sh This script extracts the checksums file named DEBIAN/<algo sums> from the deb package, appends the file signature using the ima-evm-utils package, and inserts the modified checksums file containing the signatures in the package. (The public key used to sign files should be stored safely.) Changelog v1: - Use the checksums stored in the algorithm specific file (eg. DEBIAN/sha256sums, DEBIAN/sha512sums). --- examples/ima-signhashes.sh | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 examples/ima-signhashes.sh diff --git a/examples/ima-signhashes.sh b/examples/ima-signhashes.sh new file mode 100755 index 0000000..3faf2e0 --- /dev/null +++ b/examples/ima-signhashes.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# +# ima-signhashes.sh - replace the checksums file in the .deb package with +# a version containing the file signatures. The file signatures provide +# file authenticity and provenance. As part of the package install process, +# the file signatures are stored as extended attributes associated with +# the file. IMA-appraisal, if enabled, will appraise file integrity based +# on these file signatures. +# +# Mimi Zohar <[email protected]> + +# format: <debian package pathname> <private key pathname> + +set -e +DEBPACKAGE="${1}" +PRIVKEY="$2" +tmpdir="${DEBPACKAGE}.tmp" + +if [ $# -ne 2 ]; then + echo "$0: <debian package pathname> <private key pathname>" + exit -1 +fi + +if [ ! -f "${DEBPACKAGE}" ]; then + echo ".deb package not found: ${DEBPACKAGE}" + exit -1 +fi + +if [ ! -f "${PRIVKEY}" ]; then + echo "Private key not found: ${PRIVKEY}" + exit -1 +fi + +# extract files from the .deb archive into a temporary directory +if [ -d "${tmpdir}" ]; then + rm -rf "${tmpdir}" + if [ $? -ne 0 ]; then + echo "Deleting directory failed: ${tmpdir}" + exit -1 + fi +fi +mkdir -p "${tmpdir/DEBIAN}" +if [ $? -ne 0 ]; then + echo "Creating directory failed: ${tmpdir}/DEBIAN" + exit -1 +fi + +cd $tmpdir +ar -x "../$DEBPACKAGE" +#ls -lat + +# untar the control file in the DEBIAN subdirectory +if [ ! -f ./control.tar.gz ]; then + echo ".deb package missing 'control.tar.gz' file" + exit -1 +fi +mkdir -p DEBIAN +cd DEBIAN +tar -xvzf ../control.tar.gz +if [ -f ./sha256sums ]; then + # Replace sha256sums with one containing file signatures + cat ./sha256sums | evmctl sign_hash -a sha256 --key "${PRIVKEY}" > sha256sums.sig + if [ $? == 0 ]; then + cp ./sha256sums.sig ./sha256sums + rm ./sha256sums.sig + cat sha256sums + fi +elif [ -f ./sha512sums ]; then + # Replace sha256sums with one containing file signatures + cat ./sha512sums | evmctl sign_hash -a sha512 --key "${PRIVKEY}" > sha512sums.sig + if [ $? == 0 ]; then + cp ./sha512sums.sig ./sha512sums + rm ./sha512sums.sig + fi +else + echo "'control.tar.gz' missing check sums file" + ls -lat + exit -1 +fi + + +# create the control tar containing the new sha256sums with the signatures +tar -cvzf ../control.tar.gz ./* + +# replace the existing compressed tar file in the .deb package +cd .. +ar -r "../$DEBPACKAGE" control.tar.gz -- 1.9.1

