On Tue, Sep 01, 2015 at 06:54:12AM +0200, Johannes Schauer wrote:
> any extra repositories are written to
> /etc/apt/sources.list.d/sbuild-build-depends-archive.list inside the
> chroot. This path is also stored in the configuration key 'Dummy
> archive list file' and you can see the function 'cleanup_apt_archive'
> removes the file pointed to by that key.

Ah! That explains that. Thanks for that, Perl's not my first language, I
was trying to keep my focus on the small parts I thought I'd be using, I
totally missed that.

> I only just read the man page of apt-key, and maybe something similar
> to the sources.list can be done with keys too, by just dumping them
> into /etc/apt/trusted.gpg.d/sbuild-build-depends-archive.gpg (or
> similar) and then removing just that file in the end.

Good call. Updated patch attached.

> 
> I imagine it would be more difficult to use "apt-key del" to clean up
> because running that command requires you to know the key ID(s).
> 
> cheers, josch

Cheers,
  Paul
From 55717aa86c7c85fad1cad4025755a27ea8ef02eb Mon Sep 17 00:00:00 2001
From: Paul Tagliamonte <[email protected]>
Date: Wed, 2 Sep 2015 10:41:05 -0400
Subject: [PATCH] Add --extra-repository-key flag for extra apt keys

This will allow users to specify which OpenPGP key should be added
to the trusted keys inside the chroot. This is particularly useful
if the target --extra-repository is not signed with a key that's
trusted by the base chroot.
---
 lib/Sbuild/Conf.pm         |  6 +++++
 lib/Sbuild/Options.pm      |  3 +++
 lib/Sbuild/ResolverBase.pm | 58 ++++++++++++++++++++++++++++++++++++++++++++++
 man/sbuild.1.in            | 20 ++++++++++++++--
 4 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/lib/Sbuild/Conf.pm b/lib/Sbuild/Conf.pm
index 763ecaa..ffce72f 100644
--- a/lib/Sbuild/Conf.pm
+++ b/lib/Sbuild/Conf.pm
@@ -1069,6 +1069,12 @@ sub setup ($) {
 	    DEFAULT => [],
 	    HELP => 'Additional per-build packages available as build dependencies.  Do not set by hand.'
 	},
+	'EXTRA_REPOSITORY_KEYS'				=> {
+	    TYPE => 'ARRAY:STRING',
+	    GROUP => '__INTERNAL',
+	    DEFAULT => [],
+	    HELP => 'Additional per-build apt repository keys.  Do not set by hand.'
+	},
 	'EXTRA_REPOSITORIES'				=> {
 	    TYPE => 'ARRAY:STRING',
 	    GROUP => '__INTERNAL',
diff --git a/lib/Sbuild/Options.pm b/lib/Sbuild/Options.pm
index 587acad..b47b3f5 100644
--- a/lib/Sbuild/Options.pm
+++ b/lib/Sbuild/Options.pm
@@ -313,6 +313,9 @@ sub set_options {
 			"extra-repository=s" => sub {
 			   push(@{$self->get_conf('EXTRA_REPOSITORIES')}, $_[1]);
 		       },
+			"extra-repository-key=s" => sub {
+			   push(@{$self->get_conf('EXTRA_REPOSITORY_KEYS')}, $_[1]);
+		       },
 			"build-path=s" => sub {
 			   $self->set_conf('BUILD_PATH', $_[1]);
 			},
diff --git a/lib/Sbuild/ResolverBase.pm b/lib/Sbuild/ResolverBase.pm
index 5d85f60..5eae24f 100644
--- a/lib/Sbuild/ResolverBase.pm
+++ b/lib/Sbuild/ResolverBase.pm
@@ -67,6 +67,9 @@ sub new {
         '/etc/apt/sources.list.d/sbuild-build-depends-archive.list';
     $self->set('Dummy archive list file', $dummy_archive_list_file);
 
+    my $dummy_archive_key_file = $session->get('Location') .
+        '/etc/apt/trusted.gpg.d/sbuild-build-depends-archive.gpg';
+    $self->set('Dummy archive key file', $dummy_archive_key_file);
 
     return $self;
 }
@@ -1000,6 +1003,54 @@ EOF
         }
     }
 
+    # Now, we'll add in any provided OpenPGP keys into the archive, so that
+    # builds can (optionally) trust an external key for the duration of the
+    # build.
+    if (@{$self->get_conf('EXTRA_REPOSITORY_KEYS')}) {
+        my $dummy_archive_key_file = $self->get('Dummy archive key file');
+        my ($tmpfh, $tmpfilename) = tempfile(DIR => $session->get('Location') . "/tmp");
+        # Right, so, in order to copy the keys into the chroot (since we may have
+        # a bunch of them), we'll open up a tempfile, and write *all* of the
+        # given keys to the tempfile. After we're clear, we'll move that file
+        # into the correct location by importing the .asc into a .gpg file.
+
+        for my $repokey (@{$self->get_conf('EXTRA_REPOSITORY_KEYS')}) {
+            debug("Adding archive key: $repokey\n");
+            if (!-f $repokey) {
+                $self->log("Failed to add archive key '${repokey}' - it doesn't exist!\n");
+                $self->cleanup_apt_archive();
+                return 0;
+            }
+            copy($repokey, $tmpfh);
+            print $tmpfh "\n";
+        }
+        close($tmpfh);
+
+        # Now that we've concat'd all the keys into the chroot, we're going
+        # to use GPG to import the keys into a single keyring. We've stubbed
+        # out the secret ring and home to ensure we don't store anything
+        # except for the public keyring.
+
+		my $tmpgpghome = tempdir('extra-repository-keys' . '-XXXXXX',
+			   DIR => $session->get('Location') . "/tmp");
+
+        my @gpg_command = ('gpg', '--import', '--no-default-keyring',
+                           '--homedir', $session->strip_chroot_path($tmpgpghome),
+                           '--secret-keyring', '/dev/null',
+                           '--keyring', $session->strip_chroot_path($dummy_archive_key_file),
+                           $session->strip_chroot_path($tmpfilename));
+
+        $session->run_command(
+            { COMMAND => \@gpg_command,
+              USER => 'root',
+              PRIORITY => 0});
+        if ($?) {
+            $self->log("Failed to import archive keys to the trusted keyring");
+            $self->cleanup_apt_archive();
+            return 0;
+        }
+    }
+
     # Write a list file for the dummy archive if one not create yet.
     if (! -f $dummy_archive_list_file) {
         my ($tmpfh, $tmpfilename) = tempfile(DIR => $session->get('Location') . "/tmp");
@@ -1067,6 +1118,13 @@ sub cleanup_apt_archive {
 	  USER => 'root',
 	  DIR => '/',
 	  PRIORITY => 0});
+
+    $session->run_command(
+	{ COMMAND => ['rm', '-f', $session->strip_chroot_path($self->get('Dummy archive key file'))],
+	  USER => 'root',
+	  DIR => '/',
+	  PRIORITY => 0});
+
     $self->set('Dummy package path', undef);
     $self->set('Dummy archive directory', undef);
     $self->set('Dummy Release file', undef);
diff --git a/man/sbuild.1.in b/man/sbuild.1.in
index e5d1e4a..39cae07 100644
--- a/man/sbuild.1.in
+++ b/man/sbuild.1.in
@@ -80,6 +80,7 @@ sbuild \- build debian packages from source
 .RB [ \-\-resolve\-alternatives \[or] \-\-no\-resolve\-alternatives ]
 .RB [ \-\-extra\-package=\fIpackage.deb\fP ]
 .RB [ \-\-extra\-repository=\fIspec\fP ]
+.RB [ \-\-extra\-repository\-key=\fIfile.asc\fP ]
 .RB [ \-\-build\-path=\fIstring\fP ]
 .RB [ PACKAGE [ .dsc ]]
 .SH DESCRIPTION
@@ -450,8 +451,23 @@ file. For instance, you might use
 .hy
 to allow packages in the experimental distribution to fulfill
 build-dependencies. Note that the build chroot must already trust the
-key of this repository (see
-.BR apt-secure (8)).
+key of this repository or a key must be given with the
+.nh
+.B \-\-extra\-repository-key
+.hy
+flag. (see
+.BR apt-secure (8))
+.TP
+.BR \-\-extra\-repository-key=\fIfile.asc\fP
+Add \fIfile.asc\fP to the list of trusted keys inside the chroot. The key is
+read from the filename given, and added using
+.BR apt-key (8).
+This flag is particularly useful if the target in
+.nh
+.B --extra-repository
+.hy
+is not signed
+with a key that's trusted by the base chroot.
 .TP
 .BR \-\-build\-path=\fIstring\fP
 By default the package is built in a path of the following format /build/packagename-XXXXXX/packagename-version/ where XXXXXX is a random ascii string. This option allows one to specify a custom path where the package is built inside the chroot. Notice that the sbuild user in the chroot must have permissions to create the path. Common writable locations are subdirectories of /tmp or /build. The buildpath must be an empty directory because the last component of the path will be removed after the build is finished. If you are running multiple sbuild instances with the same build path in parallel for the same package, make sure that your build path is not in a directory commonly mounted by all sbuild instances (like /tmp or /home). In that case, use for example /build instead. Otherwise, your builds will probably fail or contain wrong content.
-- 
2.5.0

Attachment: signature.asc
Description: Digital signature

Reply via email to