Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify downloaded distributions cryptographically (2nd attempt) #191

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -27,3 +27,4 @@ nytprof.out
tmp
perltidy.LOG
.tiidyall.d
t/gnupg/random_seed
6 changes: 6 additions & 0 deletions bin/pinto
Expand Up @@ -279,6 +279,12 @@ when using a local repository.
Sets the timeout (in seconds) for obtaining a lock on the repository. The default
is 50. This variable only has effect when using a local repository.

=item C<PINTO_GNUPGHOME>

Sets the GNUPGHOME to be used when verifying upstream distribution files using
GnuPG. See the documentation for the C<verify|App::Pinto::Command::verify>
command for the rationale and an example.

=back


Expand Down
5 changes: 5 additions & 0 deletions dist.ini
Expand Up @@ -6,6 +6,11 @@ license = Perl_5
main_module = lib/Pinto.pm
version = 0.09996

[Encoding]
encoding = bytes
filename = t/gnupg/pubring.gpg
filename = t/gnupg/secring.gpg
filename = t/gnupg/trustdb.gpg

[GatherDir] ; everything under top dir
[PruneCruft] ; default stuff to skip
Expand Down
91 changes: 91 additions & 0 deletions etc/update-verifier-pod.pl
@@ -0,0 +1,91 @@
#!/usr/bin/env perl

# Maintenance script to help keep the documentation for the evolving
# --verify-upstream option up to date and consistent across all commands that
# use it.

use strict;
use warnings;

use Path::Class qw(file);

my $data = do { local $/ = undef; <DATA> };

my @puller_commands = qw( add install pull update );

for my $command (@puller_commands) {
my $filename = sprintf('lib/App/Pinto/Command/%s.pm', $command);
my $file = file($filename);
my $content = $file->slurp;

# Replace the --verify-upstream POD with our DATA section
$content =~ s{
^=item\ --verify-upstream .*? $ # start of the verify option
\s+ ^=item .+? $ # skip 1st alternative
\s+ ^=item .+? $ # skip 2nd alternative
.+? # everything in the middle
(?=^=) # the start of the next pod section
}{$data}xms;

$file->spew($content);
};

__DATA__
=item --verify-upstream=[0-5]

=item -Z [0-5]

=item -Z ... -ZZZZZ

!! THIS OPTION IS EXPERIMENTAL !!

Require upstream distribution files to be verified before operating on them.
Repeated use of this argument (up to 5) requires the upstream verification to
be progressively more strict. You can also set the verification level
explicitly, e.g.,

--verify-upstream=3

At level 0, no verification is performed. This may be useful if you need to
override a verification level set that has been set earlier on the command
line.

At level 1, we verify the distributions checksum using the upstream CHECKSUMS
file. This gives you some assurance that the distribution archive has not be
corrupted during transfer. This is a good level to use if your upstream
source is on a different system and you trust the network between your system
and upstream.

At level 2, we also verify the signature on the upstream CHECKSUMS file if it
has one. Warnings about unknown or untrusted PGP keys relating to that file
are printed. This is a good level to use if you do not necessarily trust the
network between your system and upstream (because they do not use HTTPS). At
this level we silently ignore warnings about the PAUSE Batch Signing Key
(450F89EC) being unknown or untrusted, since this key is to sign the CHECKSUMS
files for all CPAN distributions.

At level 3, we also require upstream CHECKSUMS files to be signed. Warnings
about unknown or untrusted PGP keys relating to that file are now considered
fatal. This is a good level to use if you only use upstream sources that sign
there distributions and you actively manage the keys that you trust. At this
level we do not ignore warnings about the PAUSE Batch Signing Key.

At level 4, we also verify the unpacked distribution using the embedded
SIGNATURE file if it exists. Warnings about unknown or untrusted PGP keys
relating to that file are printed. This is a good level to use if you want to
be alerted about distributions that have been signed by authors you have yet
to verify.

At level 5, warnings about unknown or untrusted PGP keys relating to embedded
SIGNATURE files are now considered fatal. This is the level to use if you
actively verify all authors who sign their distributions.

Note that none of these checks are applied to LOCAL distributions, i.e.,
distributions that do not have an upstream CHECKSUMS file.

The impact of this option will largely depend on the your chosen upstream
repositories and state of your current keyring. Consider maintaining
a dedicated keyring/trustdb via the C<PINTO_GNUPGHOME> environment variable.
See the documentation for the L<verify|App::Pinto::Command::verify> command
for the rationale and an example.

59 changes: 59 additions & 0 deletions lib/App/Pinto/Command/add.pm
Expand Up @@ -33,6 +33,7 @@ sub opt_spec {
[ 'stack|s=s' => 'Put packages into this stack' ],
[ 'use-default-message|M' => 'Use the generated message' ],
[ 'with-development-prerequisites|wd' => 'Also pull prereqs for development' ],
[ 'verify-upstream|Z:+' => 'Verify upstream files before use (repeatable)' ],
);
}

Expand Down Expand Up @@ -232,6 +233,64 @@ to work on those distributions, in the event that you need to patch them
in the future. Be aware that most distributions do not actually declare
their development prerequisites.

=item --verify-upstream=[0-5]

=item -Z [0-5]

=item -Z ... -ZZZZZ

!! THIS OPTION IS EXPERIMENTAL !!

Require upstream distribution files to be verified before operating on them.
Repeated use of this argument (up to 5) requires the upstream verification to
be progressively more strict. You can also set the verification level
explicitly, e.g.,

--verify-upstream=3

At level 0, no verification is performed. This may be useful if you need to
override a verification level set that has been set earlier on the command
line.

At level 1, we verify the distributions checksum using the upstream CHECKSUMS
file. This gives you some assurance that the distribution archive has not be
corrupted during transfer. This is a good level to use if your upstream
source is on a different system and you trust the network between your system
and upstream.

At level 2, we also verify the signature on the upstream CHECKSUMS file if it
has one. Warnings about unknown or untrusted PGP keys relating to that file
are printed. This is a good level to use if you do not necessarily trust the
network between your system and upstream (because they do not use HTTPS). At
this level we silently ignore warnings about the PAUSE Batch Signing Key
(450F89EC) being unknown or untrusted, since this key is to sign the CHECKSUMS
files for all CPAN distributions.

At level 3, we also require upstream CHECKSUMS files to be signed. Warnings
about unknown or untrusted PGP keys relating to that file are now considered
fatal. This is a good level to use if you only use upstream sources that sign
there distributions and you actively manage the keys that you trust. At this
level we do not ignore warnings about the PAUSE Batch Signing Key.

At level 4, we also verify the unpacked distribution using the embedded
SIGNATURE file if it exists. Warnings about unknown or untrusted PGP keys
relating to that file are printed. This is a good level to use if you want to
be alerted about distributions that have been signed by authors you have yet
to verify.

At level 5, warnings about unknown or untrusted PGP keys relating to embedded
SIGNATURE files are now considered fatal. This is the level to use if you
actively verify all authors who sign their distributions.

Note that none of these checks are applied to LOCAL distributions, i.e.,
distributions that do not have an upstream CHECKSUMS file.

The impact of this option will largely depend on the your chosen upstream
repositories and state of your current keyring. Consider maintaining
a dedicated keyring/trustdb via the C<PINTO_GNUPGHOME> environment variable.
See the documentation for the L<verify|App::Pinto::Command::verify> command
for the rationale and an example.

=back

=cut
88 changes: 73 additions & 15 deletions lib/App/Pinto/Command/install.pm
Expand Up @@ -19,17 +19,17 @@ sub opt_spec {
my ( $self, $app ) = @_;

return (
[ 'cascade' => 'Always pick latest upstream package' ],
[ 'cpanm-exe|cpanm=s' => 'Path to the cpanm executable' ],
[ 'cpanm-options|o:s%' => 'name=value pairs of cpanm options' ],
[ 'diff-style=s' => 'Set style of diff reports' ],
[ 'local-lib|l=s' => 'install into a local lib directory' ],
[ 'local-lib-contained|L=s' => 'install into a contained local lib directory' ],
[ 'message|m=s' => 'Message to describe the change' ],
[ 'do-pull' => 'pull missing prereqs onto the stack first' ],
[ 'stack|s=s' => 'Install modules from this stack' ],
[ 'use-default-message|M' => 'Use the generated message' ],

[ 'cascade' => 'Always pick latest upstream package' ],
[ 'cpanm-exe|cpanm=s' => 'Path to the cpanm executable' ],
[ 'cpanm-options|o:s%' => 'name=value pairs of cpanm options' ],
[ 'diff-style=s' => 'Set style of diff reports' ],
[ 'local-lib|l=s' => 'install into a local lib directory' ],
[ 'local-lib-contained|L=s' => 'install into a contained local lib directory' ],
[ 'message|m=s' => 'Message to describe the change' ],
[ 'do-pull' => 'pull missing prereqs onto the stack first' ],
[ 'stack|s=s' => 'Install modules from this stack' ],
[ 'use-default-message|M' => 'Use the generated message' ],
[ 'verify-upstream|Z:+' => 'Verify upstream files before use (repeatable)' ],
);
}

Expand Down Expand Up @@ -64,8 +64,8 @@ __END__

=pod

=for stopwords
exe
=for stopwords
exe
cpanm

=head1 SYNOPSIS
Expand All @@ -81,8 +81,8 @@ is just a thin wrapper around L<cpanm> that is wired to fetch
everything from the Pinto repository, rather than a public CPAN
mirror.

If the C<--do-pull> option is given, then all targets and their
prerequisites will be pulled onto the stack before attempting to
If the C<--do-pull> option is given, then all targets and their
prerequisites will be pulled onto the stack before attempting to
install them. If any thing cannot be pulled because it cannot be
found or is blocked by a pin, then the installation will not
proceed.
Expand Down Expand Up @@ -196,6 +196,64 @@ informative log message just based on the command and its arguments. If you
set an explicit message with C<--message>, the C<--use- default-message>
option will be silently ignored.

=item --verify-upstream=[0-5]

=item -Z [0-5]

=item -Z ... -ZZZZZ

!! THIS OPTION IS EXPERIMENTAL !!

Require upstream distribution files to be verified before operating on them.
Repeated use of this argument (up to 5) requires the upstream verification to
be progressively more strict. You can also set the verification level
explicitly, e.g.,

--verify-upstream=3

At level 0, no verification is performed. This may be useful if you need to
override a verification level set that has been set earlier on the command
line.

At level 1, we verify the distributions checksum using the upstream CHECKSUMS
file. This gives you some assurance that the distribution archive has not be
corrupted during transfer. This is a good level to use if your upstream
source is on a different system and you trust the network between your system
and upstream.

At level 2, we also verify the signature on the upstream CHECKSUMS file if it
has one. Warnings about unknown or untrusted PGP keys relating to that file
are printed. This is a good level to use if you do not necessarily trust the
network between your system and upstream (because they do not use HTTPS). At
this level we silently ignore warnings about the PAUSE Batch Signing Key
(450F89EC) being unknown or untrusted, since this key is to sign the CHECKSUMS
files for all CPAN distributions.

At level 3, we also require upstream CHECKSUMS files to be signed. Warnings
about unknown or untrusted PGP keys relating to that file are now considered
fatal. This is a good level to use if you only use upstream sources that sign
there distributions and you actively manage the keys that you trust. At this
level we do not ignore warnings about the PAUSE Batch Signing Key.

At level 4, we also verify the unpacked distribution using the embedded
SIGNATURE file if it exists. Warnings about unknown or untrusted PGP keys
relating to that file are printed. This is a good level to use if you want to
be alerted about distributions that have been signed by authors you have yet
to verify.

At level 5, warnings about unknown or untrusted PGP keys relating to embedded
SIGNATURE files are now considered fatal. This is the level to use if you
actively verify all authors who sign their distributions.

Note that none of these checks are applied to LOCAL distributions, i.e.,
distributions that do not have an upstream CHECKSUMS file.

The impact of this option will largely depend on the your chosen upstream
repositories and state of your current keyring. Consider maintaining
a dedicated keyring/trustdb via the C<PINTO_GNUPGHOME> environment variable.
See the documentation for the L<verify|App::Pinto::Command::verify> command
for the rationale and an example.

=back

=head1 USING cpan OR cpanm DIRECTLY
Expand Down
2 changes: 1 addition & 1 deletion lib/App/Pinto/Command/list.pm
Expand Up @@ -63,7 +63,7 @@ __END__

=head1 SYNOPSIS

pinto --root=REPOSITORY_ROOT list [OPTIONS]
pinto --root=REPOSITORY_ROOT list [STACK] [OPTIONS]

=head1 DESCRIPTION

Expand Down
4 changes: 2 additions & 2 deletions lib/App/Pinto/Command/lock.pm
Expand Up @@ -43,15 +43,15 @@ __END__

=head1 SYNOPSIS

pinto --root=REPOSITORY_ROOT lock [OPTIONS]
pinto --root=REPOSITORY_ROOT lock [STACK] [OPTIONS]

=head1 DESCRIPTION

This command locks a stack so that its packages cannot be changed. It
is typically used with the L<copy|App::Pinto::Command::copy> command
to effectively create a read-only "tag" of a stack.

To unlock a stack, use the L<unlock|App::Pinto::Command::unlock>
To unlock a stack, use the L<unlock|App::Pinto::Command::unlock>
command.

=head1 COMMAND ARGUMENTS
Expand Down