PkgSign.pm (c07cf433) | PkgSign.pm (039cbdaa) |
---|---|
1#! /usr/bin/perl 2# ex:ts=8 sw=4: | 1#! /usr/bin/perl 2# ex:ts=8 sw=4: |
3# $OpenBSD: PkgSign.pm,v 1.17 2019/07/08 10:55:39 espie Exp $ | 3# $OpenBSD: PkgSign.pm,v 1.18 2023/06/13 09:07:17 espie Exp $ |
4# 5# Copyright (c) 2003-2014 Marc Espie <espie@openbsd.org> 6# 7# Permission to use, copy, modify, and distribute this software for any 8# purpose with or without fee is hereby granted, provided that the above 9# copyright notice and this permission notice appear in all copies. 10# 11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 | 4# 5# Copyright (c) 2003-2014 Marc Espie <espie@openbsd.org> 6# 7# Permission to use, copy, modify, and distribute this software for any 8# purpose with or without fee is hereby granted, provided that the above 9# copyright notice and this permission notice appear in all copies. 10# 11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 |
19use strict; 20use warnings; | 19use v5.36; |
21 22use OpenBSD::AddCreateDelete; 23use OpenBSD::Signer; 24 25package OpenBSD::PkgSign::State; 26our @ISA = qw(OpenBSD::CreateSign::State); 27 | 20 21use OpenBSD::AddCreateDelete; 22use OpenBSD::Signer; 23 24package OpenBSD::PkgSign::State; 25our @ISA = qw(OpenBSD::CreateSign::State); 26 |
28sub handle_options | 27sub handle_options($state) |
29{ | 28{ |
30 my $state = shift; 31 | |
32 $state->{extra_stats} = 0; 33 $state->{opt} = { 34 'o' => | 29 $state->{extra_stats} = 0; 30 $state->{opt} = { 31 'o' => |
35 sub { 36 $state->{output_dir} = shift; | 32 sub($opt) { 33 $state->{output_dir} = $opt; |
37 }, 38 'S' => | 34 }, 35 'S' => |
39 sub { 40 $state->{source} = shift; | 36 sub($opt) { 37 $state->{source} = $opt; |
41 }, 42 's' => | 38 }, 39 's' => |
43 sub { 44 push(@{$state->{signature_params}}, shift); | 40 sub($opt) { 41 push(@{$state->{signature_params}}, $opt); |
45 }, 46 'V' => | 42 }, 43 'V' => |
47 sub { | 44 sub() { |
48 $state->{extra_stats}++; 49 }, 50 }; 51 $state->{signature_style} = 'unsigned'; 52 53 $state->SUPER::handle_options('Cij:o:S:s:V', 54 '[-CvV] [-D name[=value]] -s signify2 -s priv', 55 '[-o dir] [-S source] [pkg-name...]'); --- 12 unchanged lines hidden (view full) --- 68 $state->{wantntogo} = $state->{extra_stats}; 69} 70 71package OpenBSD::PkgSign; 72use OpenBSD::Temp; 73use OpenBSD::PackingList; 74use OpenBSD::PackageInfo; 75 | 45 $state->{extra_stats}++; 46 }, 47 }; 48 $state->{signature_style} = 'unsigned'; 49 50 $state->SUPER::handle_options('Cij:o:S:s:V', 51 '[-CvV] [-D name[=value]] -s signify2 -s priv', 52 '[-o dir] [-S source] [pkg-name...]'); --- 12 unchanged lines hidden (view full) --- 65 $state->{wantntogo} = $state->{extra_stats}; 66} 67 68package OpenBSD::PkgSign; 69use OpenBSD::Temp; 70use OpenBSD::PackingList; 71use OpenBSD::PackageInfo; 72 |
76sub sign_existing_package | 73sub sign_existing_package($self, $state, $pkg) |
77{ | 74{ |
78 my ($self, $state, $pkg) = @_; | |
79 my $output = $state->{output_dir}; 80 my $dest = $output.'/'.$pkg->name.".tgz"; 81 if ($state->opt('i')) { 82 if (-f $dest) { 83 return; 84 } 85 } 86 my (undef, $tmp) = OpenBSD::Temp::permanent_file($output, "pkg") or 87 die $state->fatal(OpenBSD::Temp->last_error); 88 $state->{signer}->sign($pkg, $state, $tmp); 89 90 chmod((0666 & ~umask), $tmp); 91 rename($tmp, $dest) or 92 $state->fatal("Can't create final signed package: #1", $!); 93 if ($state->opt('C')) { | 75 my $output = $state->{output_dir}; 76 my $dest = $output.'/'.$pkg->name.".tgz"; 77 if ($state->opt('i')) { 78 if (-f $dest) { 79 return; 80 } 81 } 82 my (undef, $tmp) = OpenBSD::Temp::permanent_file($output, "pkg") or 83 die $state->fatal(OpenBSD::Temp->last_error); 84 $state->{signer}->sign($pkg, $state, $tmp); 85 86 chmod((0666 & ~umask), $tmp); 87 rename($tmp, $dest) or 88 $state->fatal("Can't create final signed package: #1", $!); 89 if ($state->opt('C')) { |
94 $state->system(sub { 95 chdir($output); 96 open(STDOUT, '>>', 'SHA256'); | 90 $state->system( 91 sub() { 92 chdir($output); 93 open(STDOUT, '>>', 'SHA256'); |
97 }, 98 OpenBSD::Paths->sha256, '-b', $pkg->name.".tgz"); 99 } 100} 101 | 94 }, 95 OpenBSD::Paths->sha256, '-b', $pkg->name.".tgz"); 96 } 97} 98 |
102sub sign_list | 99sub sign_list($self, $l, $repo, $maxjobs, $state) |
103{ | 100{ |
104 my ($self, $l, $repo, $maxjobs, $state) = @_; | |
105 $state->{total} = scalar @$l; 106 $maxjobs //= 1; | 101 $state->{total} = scalar @$l; 102 $maxjobs //= 1; |
107 my $code = sub { 108 my $name = shift; | 103 my $code = sub($name) { |
109 my $pkg = $repo->find($name); 110 if (!defined $pkg) { 111 $state->errsay("#1 not found", $name); 112 } else { 113 $self->sign_existing_package($state, $pkg); 114 } 115 }; 116 my $display = $state->verbose ? | 104 my $pkg = $repo->find($name); 105 if (!defined $pkg) { 106 $state->errsay("#1 not found", $name); 107 } else { 108 $self->sign_existing_package($state, $pkg); 109 } 110 }; 111 my $display = $state->verbose ? |
117 sub { 118 $state->progress->set_header("Signed ".shift); | 112 sub($name) { 113 $state->progress->set_header("Signed ".$name); |
119 $state->{done}++; 120 $state->progress->next($state->ntogo); 121 } : | 114 $state->{done}++; 115 $state->progress->next($state->ntogo); 116 } : |
122 sub { | 117 sub($) { |
123 }; 124 if ($maxjobs > 1) { 125 my $jobs = {}; 126 my $n = 0; | 118 }; 119 if ($maxjobs > 1) { 120 my $jobs = {}; 121 my $n = 0; |
127 my $reap_job = sub { | 122 my $reap_job = sub() { |
128 my $pid = wait; 129 if (!defined $jobs->{$pid}) { 130 $state->fatal("Wait returned #1: unknown process", $pid); 131 } 132 if ($? != 0) { 133 $state->fatal("Signature of #1 failed\n", 134 $jobs->{$pid}); 135 } --- 10 unchanged lines hidden (view full) --- 146 $repo->reinitialize; 147 &$code($name); 148 exit(0); 149 } else { 150 $jobs->{$pid} = $name; 151 $n++; 152 } 153 if ($n >= $maxjobs) { | 123 my $pid = wait; 124 if (!defined $jobs->{$pid}) { 125 $state->fatal("Wait returned #1: unknown process", $pid); 126 } 127 if ($? != 0) { 128 $state->fatal("Signature of #1 failed\n", 129 $jobs->{$pid}); 130 } --- 10 unchanged lines hidden (view full) --- 141 $repo->reinitialize; 142 &$code($name); 143 exit(0); 144 } else { 145 $jobs->{$pid} = $name; 146 $n++; 147 } 148 if ($n >= $maxjobs) { |
154 &$reap_job; | 149 &$reap_job(); |
155 } 156 } 157 while ($n != 0) { | 150 } 151 } 152 while ($n != 0) { |
158 &$reap_job; | 153 &$reap_job(); |
159 } 160 } else { 161 for my $name (@$l) { 162 &$code($name); 163 &$display($name); 164 delete $state->{signer}{pubkey}; 165 } 166 } 167 if ($state->opt('C')) { | 154 } 155 } else { 156 for my $name (@$l) { 157 &$code($name); 158 &$display($name); 159 delete $state->{signer}{pubkey}; 160 } 161 } 162 if ($state->opt('C')) { |
168 $state->system(sub { 169 chdir($state->{output_dir}); 170 open(STDOUT, '>', 'SHA256.new'); | 163 $state->system( 164 sub() { 165 chdir($state->{output_dir}); 166 open(STDOUT, '>', 'SHA256.new'); |
171 }, 'sort', 'SHA256'); 172 rename($state->{output_dir}.'/SHA256.new', 173 $state->{output_dir}.'/SHA256'); 174 } 175} 176 | 167 }, 'sort', 'SHA256'); 168 rename($state->{output_dir}.'/SHA256.new', 169 $state->{output_dir}.'/SHA256'); 170 } 171} 172 |
177sub sign_existing_repository | 173sub sign_existing_repository($self, $state, $source) |
178{ | 174{ |
179 my ($self, $state, $source) = @_; | |
180 require OpenBSD::PackageRepository; 181 my $repo = OpenBSD::PackageRepository->new($source, $state); 182 if ($state->{signer}->want_local && !$repo->is_local_file) { 183 $state->fatal("Signing distant source is not supported"); 184 } 185 my @list = sort @{$repo->list}; 186 if (@list == 0) { 187 $state->errsay('Source repository "#1" is empty', $source); 188 } 189 $self->sign_list(\@list, $repo, $state->opt('j'), $state); 190} 191 192 | 175 require OpenBSD::PackageRepository; 176 my $repo = OpenBSD::PackageRepository->new($source, $state); 177 if ($state->{signer}->want_local && !$repo->is_local_file) { 178 $state->fatal("Signing distant source is not supported"); 179 } 180 my @list = sort @{$repo->list}; 181 if (@list == 0) { 182 $state->errsay('Source repository "#1" is empty', $source); 183 } 184 $self->sign_list(\@list, $repo, $state->opt('j'), $state); 185} 186 187 |
193sub parse_and_run | 188sub parse_and_run($self, $cmd) |
194{ | 189{ |
195 my ($self, $cmd) = @_; | |
196 my $state = OpenBSD::PkgSign::State->new($cmd); 197 $state->handle_options; 198 if (!defined $state->{source} && @ARGV == 0) { 199 $state->usage("Nothing to sign"); 200 } 201 if (defined $state->{source}) { 202 $self->sign_existing_repository($state, 203 $state->{source}); 204 } 205 $self->sign_list(\@ARGV, $state->repo, $state->opt('j'), 206 $state); 207 return 0; 208} 209 | 190 my $state = OpenBSD::PkgSign::State->new($cmd); 191 $state->handle_options; 192 if (!defined $state->{source} && @ARGV == 0) { 193 $state->usage("Nothing to sign"); 194 } 195 if (defined $state->{source}) { 196 $self->sign_existing_repository($state, 197 $state->{source}); 198 } 199 $self->sign_list(\@ARGV, $state->repo, $state->opt('j'), 200 $state); 201 return 0; 202} 203 |