diff options
-rw-r--r-- | urpm.pm | 91 | ||||
-rwxr-xr-x | urpmi | 51 | ||||
-rw-r--r-- | urpmi.spec | 7 | ||||
-rwxr-xr-x | urpmq | 2 |
4 files changed, 103 insertions, 48 deletions
@@ -1128,11 +1128,13 @@ sub update_media { require URPM::Build; require URPM::Signature; - $options{nolock} or $urpm->exlock_urpmi_db; - #- get gpg-pubkey signature. + $options{nopubkey} or $urpm->exlock_rpm_db; $options{nopubkey} or $urpm->{keys} or $urpm->parse_pubkeys(root => $urpm->{root}); + #- lock database if allowed. + $options{nolock} or $urpm->exlock_urpmi_db; + #- examine each medium to see if one of them need to be updated. #- if this is the case and if not forced, try to use a pre-calculated #- hdlist file else build it from rpm files. @@ -1979,6 +1981,7 @@ this could happen if you mounted manually the directory when creating the medium } $options{nolock} or $urpm->unlock_urpmi_db; + $options{nopubkey} or $urpm->unlock_rpm_db; } #- clean params and depslist computation zone. @@ -2565,6 +2568,46 @@ sub download_source_packages { %sources, %error_sources; } +#- safety rpm db locking mechanism +sub exlock_rpm_db { + my ($urpm) = @_; + + #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). + my ($LOCK_EX, $LOCK_NB) = (2, 4); + + #- lock urpmi database, but keep lock to wait for an urpmi.update to finish. + open RPMLOCK_FILE, ">$urpm->{statedir}/.RPMLOCK"; + flock RPMLOCK_FILE, $LOCK_EX|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked")); +} +sub shlock_rpm_db { + my ($urpm) = @_; + + #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). + my ($LOCK_SH, $LOCK_NB) = (1, 4); + + #- create the .LOCK file if needed (and if possible) + unless (-e "$urpm->{statedir}/.RPMLOCK") { + open RPMLOCK_FILE, ">$urpm->{statedir}/.RPMLOCK"; + close RPMLOCK_FILE; + } + #- lock urpmi database, if the LOCK file doesn't exists no share lock. + open RPMLOCK_FILE, "$urpm->{statedir}/.RPMLOCK" or return; + flock RPMLOCK_FILE, $LOCK_SH|$LOCK_NB or $urpm->{fatal}(7, N("urpmi database locked")); +} +sub unlock_rpm_db { + my ($urpm) = @_; + + #- avoid putting a require on Fcntl ':flock' (which is perl and not perl-base). + my $LOCK_UN = 8; + + #- now everything is finished. + system("sync"); + + #- release lock on database. + flock RPMLOCK_FILE, $LOCK_UN; + close RPMLOCK_FILE; +} + sub exlock_urpmi_db { my ($urpm) = @_; @@ -2647,6 +2690,7 @@ sub copy_packages_of_removable_media { } if (-e $dir) { while (my ($i, $url) = each %{$list->[$id]}) { + print STDERR "copying or looking for $i:$url"; chomp $url; my ($filepath, $filename) = $url =~ /^(?:removable[^:]*|file):\/(.*\/([^\/]*))/ or next; if (-r $filepath) { @@ -3167,6 +3211,49 @@ sub translate_why_removed { } @l; } +sub check_sources_signatures { + my ($urpm, $sources_install, $sources, %options) = @_; + my ($medium, %invalid_sources); + + foreach my $id (sort { $a <=> $b } keys %$sources_install, keys %$sources) { + my $verif = URPM::verify_rpm($sources_install->{$id} || $sources->{$id}); + + if ($verif =~ /NOT OK/) { + $invalid_sources{$sources_install->{$id} || $sources->{$id}} = N("Invalid signature (%s)", $verif); + } else { + unless ($medium && $medium->{start} <= $id && $id <= $medium->{end}) { + $medium = undef; + foreach (@{$urpm->{media}}) { + $_->{start} <= $id && $id <= $_->{end} and $medium = $_, last; + } + } + + my $key_ids = $medium && $medium->{'key-ids'} || $urpm->{options}{'key-ids'}; + #- check the key ids of the medium are matching (all) the given key id of the package. + if ($key_ids) { + my $valid_ids = 0; + my $invalid_ids = 0; + + foreach my $key_id ($verif =~ /#(\S+)/g) { + if (grep { hex($_) == hex($key_id) } split /[,\s]+/, $key_ids) { + ++$valid_ids; + } else { + ++$invalid_ids; + } + } + + if ($invalid_ids) { + $invalid_sources{$sources_install->{$id} || $sources->{$id}} = N("Invalid Key ID (%s)", $verif); + } elsif (!$valid_ids) { + $invalid_sources{$sources_install->{$id} || $sources->{$id}} = N("Missing signature (%s)", $verif); + } + } + } + } + + map { $_ . ($options{translate} ? ": $invalid_sources{$_}" : "") } sort keys %invalid_sources; +} + 1; __END__ @@ -323,7 +323,8 @@ unless ($bug) { } $verbose > 0 or $urpm->{log} = sub {}; -$urpm->exlock_urpmi_db; +$urpm->exlock_rpm_db; +$urpm->shlock_urpmi_db; $urpm->configure(nocheck_access => $env || $uid > 0, media => $media, excludemedia => $excludemedia, @@ -582,51 +583,12 @@ foreach my $set (@{$state->{transaction} || []}) { my %transaction_sources_install = %{$urpm->extract_packages_to_install(\%transaction_sources) || {}}; if ($urpm->{options}{'verify-rpm'}) { - my ($medium, %invalid_sources); - - foreach my $id (sort { $a <=> $b } keys %transaction_sources_install, keys %transaction_sources) { - my $verif = URPM::verify_rpm($transaction_sources_install{$id} || $transaction_sources{$id}); - - if ($verif =~ /NOT OK/) { - $invalid_sources{$transaction_sources_install{$id} || - $transaction_sources{$id}} = N("Invalid signature (%s)", $verif); - } else { - unless ($medium && $medium->{start} <= $id && $id <= $medium->{end}) { - $medium = undef; - foreach (@{$urpm->{media}}) { - $_->{start} <= $id && $id <= $_->{end} and $medium = $_, last; - } - } - - my $key_ids = $medium && $medium->{'key-ids'} || $urpm->{options}{'key-ids'}; - #- check the key ids of the medium are matching (all) the given key id of the package. - if ($key_ids) { - my $valid_ids = 0; - my $invalid_ids = 0; - - foreach my $key_id ($verif =~ /#(\S+)/g) { - if (grep { hex($_) == hex($key_id) } split /[,\s]+/, $key_ids) { - ++$valid_ids; - } else { - ++$invalid_ids; - } - } - - if ($invalid_ids) { - $invalid_sources{$transaction_sources_install{$id} || - $transaction_sources{$id}} = N("Invalid Key ID (%s)", $verif); - } elsif (!$valid_ids) { - $invalid_sources{$transaction_sources_install{$id} || - $transaction_sources{$id}} = N("Missing signature (%s)", $verif); - } - } - } - } - - if (%invalid_sources) { + my @bad_signatures = $urpm->check_sources_signatures(\%transaction_sources_install, \%transaction_sources, translate => 1); + + if (@bad_signatures) { my $msg = N("The following packages have bad signatures"); my $msg2 = N("Do you want to continue installation ?"); - my $p = join "\n", map { "$_: $invalid_sources{$_}"} sort { $a cmp $b} keys %invalid_sources; + my $p = join "\n", @bad_signatures; if ($auto) { message("$msg:\n$p\n", 'noX'); exit 1; @@ -788,6 +750,7 @@ if ($nok) { } $urpm->unlock_urpmi_db; +$urpm->unlock_rpm_db; #- try to umount removable device which may have been mounted. $urpm->try_umounting_removables; @@ -2,7 +2,7 @@ Name: urpmi Version: 4.4 -Release: 29mdk +Release: 30mdk License: GPL Source0: %{name}.tar.bz2 Source1: %{name}.logrotate @@ -202,13 +202,16 @@ $urpm->update_media(nolock => 1, nopubkey => 1); %changelog +* Tue Sep 2 2003 François Pons <fpons@mandrakesoft.com> 4.4-30mdk +- improved checking to be safer and smarter. +- added urpm::check_sources_signatures. + * Mon Sep 1 2003 François Pons <fpons@mandrakesoft.com> 4.4-29mdk - fixed @EXPORT of *N to be N only (avoid clashes with rpmdrake or others, and fix #5090) - added urpmi.cfg man page in section 5. - fixed bug 5058. - * Thu Aug 28 2003 François Pons <fpons@mandrakesoft.com> 4.4-28mdk - fixed transaction number restarting at 1 in split mode. - updated C and fr man pages. @@ -174,6 +174,7 @@ if ($query->{env}) { $urpm->{statedir} = $query->{env}; } +$query->{upgrade} && !$query->{env} && !$query->{root} and $urpm->shlock_rpm_db; $urpm->shlock_urpmi_db; $urpm->configure(nocheck_access => 1, noskipping => $query->{nodepslist}, noinstalling => $query->{nodepslist}, nodepslist => $query->{nodepslist}, @@ -400,6 +401,7 @@ if ($query->{list_aliases}) { } } $urpm->unlock_urpmi_db; +$query->{upgrade} && !$query->{env} && !$query->{root} and $urpm->unlock_rpm_db; #- print sub for query. my $query_sub = sub { |