summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RPM4/lib/RPM4/Sign.pm151
1 files changed, 151 insertions, 0 deletions
diff --git a/RPM4/lib/RPM4/Sign.pm b/RPM4/lib/RPM4/Sign.pm
new file mode 100644
index 0000000..9ed3a24
--- /dev/null
+++ b/RPM4/lib/RPM4/Sign.pm
@@ -0,0 +1,151 @@
+##- the Free Software Foundation; either version 2, or (at your option)
+##- any later version.
+##-
+##- This program is distributed in the hope that it will be useful,
+##- but WITHOUT ANY WARRANTY; without even the implied warranty of
+##- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+##- GNU General Public License for more details.
+##-
+##- You should have received a copy of the GNU General Public License
+##- along with this program; if not, write to the Free Software
+##- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# $Id$
+
+package RPM4::Sign;
+
+use strict;
+use warnings;
+
+use RPM4;
+
+sub new {
+ my ($class, %options) = @_;
+
+ my $Sign;
+ $Sign = {
+ _signature => undef,
+ name => undef,
+ path => undef,
+ checkrpms => 1,
+
+ password_file => undef,
+
+ log => sub {
+ my ($m, @v) = @_;
+ printf STDERR "$m\n", @v;
+ },
+
+ };
+
+ foreach (keys %$Sign) {
+ defined($options{$_}) and $Sign->{$_} = $options{$_};
+ }
+
+ bless($Sign, $class);
+ $Sign->getpubkey();
+ $Sign->getpasswdfile();
+ $Sign;
+}
+
+sub getpasswdfile {
+ my ($self) = @_;
+ $self->{password_file} or return 1;
+ open(my $hpass, "<", $self->{password_file}) or return 0;
+ $self->{passphrase} = <$hpass>;
+ chomp($self->{passphrase});
+ close($hpass);
+ 1;
+}
+
+sub adjustmacro {
+ my ($self) = @_;
+
+ defined($self->{_signature}) and RPM4::add_macro("_signature $self->{_signature}");
+
+ foreach my $macro (qw(_gpg_name _pgp_name)) {
+ RPM4::add_macro("$macro $self->{name}") if (defined($self->{name}));
+ }
+
+ foreach my $macro (qw(_gpg_path _pgp_path)) {
+ RPM4::add_macro("$macro $self->{path}") if (defined($self->{path}));
+ }
+}
+
+sub restoremacro {
+ my ($self) = @_;
+
+ if (defined($self->{_signature})) { RPM4::del_macro('_signature'); }
+
+ if (defined($self->{name})) {
+ RPM4::del_macro('_gpg_name');
+ RPM4::del_macro('_pgp_name');
+ }
+
+ if (defined($self->{path})) {
+ RPM4::del_macro('_gpg_path');
+ RPM4::del_macro('_pgp_path');
+ }
+}
+
+sub getpubkey {
+ my ($self) = @_;
+ $self->adjustmacro();
+ my $gpgcmd;
+ if (RPM4::expand("%_signature") eq "gpg") {
+ $gpgcmd = '%__gpg --homedir %_gpg_path --list-public-keys --with-colons \'%_gpg_name\'';
+ }
+ open(my $hgpg, RPM4::expand($gpgcmd) .'|') or return undef;
+ while (my $l = <$hgpg>) {
+ chomp($l);
+ my @v = split(':', $l);
+ if ($v[0] eq 'pub') {
+ $self->{keyid} = $v[4];
+ last;
+ }
+ }
+ close($hgpg);
+ $self->restoremacro();
+}
+
+sub rpmsign {
+ my ($self, $rpm, $header) = @_;
+ my $need = 1;
+
+ $header or return -1;
+
+ if (RPM4::expand("_signature") || "" eq "gpg") {
+ my $sigid = $header->queryformat("%{SIGGPG:pgpsig}");
+ ($sigid) = $sigid =~ m/Key ID (\S+)/;
+ if ($sigid && lc($sigid) eq lc($self->{keyid} || "")) { $need = 0 }
+ }
+
+ if ($need > 0) {
+ $self->adjustmacro();
+ rpmresign($self->{passphrase}, $rpm) and $need = -1;
+ $self->restoremacro();
+ }
+
+ $need;
+}
+
+sub rpmssign {
+ my ($self, @rpms) = @_;
+
+ RPM4::parserpms(
+ rpms => [ @rpms ],
+ checkrpms => $self->{checkrpms},
+ callback => sub {
+ my (%arg) = @_;
+ defined($arg{header}) or do {
+ $self->{log}->("bad rpm %s", $arg{rpm});
+ return;
+ };
+ my $res = $self->rpmsign($arg{rpm}, $arg{header});
+ if ($res > 0) { $self->{log}->("%s has been resigned", $arg{rpm});
+ } elsif ($res < 0) { $self->{log}->("Can't resign %s", $arg{rpm}); }
+ },
+ );
+}
+
+1;