File Coverage

blib/lib/urpm/signature.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package urpm::signature;
2              
3              
4 1     1   1666 use strict;
  1         2  
  1         25  
5 1     1   27 use urpm::msg;
  0            
  0            
6             use urpm::media;
7             use urpm::util qw(any basename);
8              
9              
10             =head1 NAME
11              
12             urpm::signature - Package signature routines for urpmi
13              
14             =head1 SYNOPSIS
15              
16             =head1 DESCRIPTION
17              
18             =over
19              
20             =item check($urpm, $sources_install, $sources, %options)
21              
22             Checks a package signature, return a list of error messages
23              
24             Options:
25              
26             =over
27              
28             =item * basename
29              
30             whether to show full file paths or only file names in messages (used by rpmdrake)
31              
32             =item * callback
33              
34             A callback called on package verification (used by rpmdrake in order to update its progressbar)
35              
36             =back
37              
38             =cut
39              
40             sub check {
41             my ($urpm, $sources_install, $sources, %options) = @_;
42             sort(_check($urpm, $sources_install, %options),
43             _check($urpm, $sources, %options));
44             }
45             sub _check {
46             my ($urpm, $sources, %options) = @_;
47             my ($medium, %invalid_sources);
48              
49             foreach my $id (keys %$sources) {
50             my $filepath = $sources->{$id};
51             $filepath !~ /\.spec$/ or next;
52              
53             $urpm->{debug} and $urpm->{debug}("verifying signature of $filepath");
54             #- rpmlib is doing strftime %c, and so the string comes from the current encoding
55             #- (URPM::bind_rpm_textdomain_codeset() doesn't help here)
56             #- so we have to transform...
57             my $verif = urpm::msg::from_locale_encoding(URPM::verify_signature($filepath, $urpm->{urpmi_root}));
58              
59             if ($verif =~ /NOT OK/) {
60             $verif =~ s/\n//g;
61             $invalid_sources{$filepath} = N("Invalid signature (%s)", $verif);
62             } else {
63             unless ($medium && urpm::media::is_valid_medium($medium) &&
64             $medium->{start} <= $id && $id <= $medium->{end})
65             {
66             $medium = undef;
67             foreach (@{$urpm->{media}}) {
68             urpm::media::is_valid_medium($_) && $_->{start} <= $id && $id <= $_->{end}
69             and $medium = $_, last;
70             }
71             }
72             #- no medium found for this rpm ?
73             if (!$medium) {
74             if ($verif =~ /OK \(\(none\)\)/) {
75             $verif =~ s/\n//g;
76             $urpm->{info}(N("SECURITY: The following package is _NOT_ signed (%s): %s", $verif, $filepath));
77             }
78             next;
79             }
80             #- check whether verify-rpm is specifically disabled for this medium
81             if (defined $medium->{'verify-rpm'} && !$medium->{'verify-rpm'}) {
82             $urpm->{info}(N("SECURITY: NOT checking package \"%s\" (due to configuration)", $filepath));
83             next;
84             }
85              
86             my $key_ids = $medium->{'key-ids'} || $urpm->{options}{'key-ids'};
87             #- check that the key ids of the medium match the key ids of the package.
88             if ($key_ids) {
89             my $valid_ids = 0;
90             my $invalid_ids = 0;
91              
92             foreach my $key_id ($verif =~ /(?:key id \w{8}|#)(\w+)/gi) {
93             if (any { hex($_) == hex($key_id) } split /[,\s]+/, $key_ids) {
94             ++$valid_ids;
95             } else {
96             ++$invalid_ids;
97             }
98             }
99              
100             if ($invalid_ids) {
101             $invalid_sources{$filepath} = N("Invalid Key ID (%s)", $verif);
102             } elsif (!$valid_ids) {
103             $invalid_sources{$filepath} = N("Missing signature (%s)", $verif);
104             }
105             } elsif ($urpm::args::options{usedistrib} && $medium->{virtual}) {
106             $urpm->{info}(N("SECURITY: Medium \"%s\" has no key (%s)!", $medium->{name}, $verif));
107             } else {
108             $invalid_sources{$filepath} = N("Medium without key (%s)", $verif);
109             }
110             #- invoke check signature callback.
111             $options{callback} and $options{callback}->(
112             $urpm, $filepath,
113             id => $id,
114             verif => $verif,
115             why => $invalid_sources{$filepath},
116             );
117             }
118             }
119             map { ($options{basename} ? basename($_) : $_) . ": $invalid_sources{$_}" }
120             keys %invalid_sources;
121             }
122              
123             1;
124              
125              
126             =back
127              
128             =head1 COPYRIGHT
129              
130             Copyright (C) 2005 MandrakeSoft SA
131              
132             Copyright (C) 2005-2010 Mandriva SA
133              
134             Copyright (C) 2011-2017 Mageia
135              
136             =cut