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

Reply via email to