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