Skip to content

Commit

Permalink
Merge branch 'openSUSE:master' into zVM-fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
azouhr authored Feb 8, 2023
2 parents 4bb87c7 + fdc0d54 commit c4b0f27
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 37 deletions.
7 changes: 6 additions & 1 deletion Build/Rpm.pm
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,7 @@ sub parse {
###########################################################################

my %rpmstag = (
"SIGMD5" => 261,
"SIGTAG_SIZE" => 1000, # Header+Payload size in bytes. */
"SIGTAG_PGP" => 1002, # RSA signature over Header+Payload
"SIGTAG_MD5" => 1004, # MD5 hash over Header+Payload
Expand All @@ -973,9 +974,12 @@ my %rpmstag = (
"SUMMARY" => 1004,
"DESCRIPTION" => 1005,
"BUILDTIME" => 1006,
"VENDOR" => 1011,
"LICENSE" => 1014,
"ARCH" => 1022,
"OLDFILENAMES" => 1027,
"FILEMODES" => 1030,
"FILEDIGESTS" => 1035,
"SOURCERPM" => 1044,
"PROVIDENAME" => 1047,
"REQUIREFLAGS" => 1048,
Expand Down Expand Up @@ -1006,7 +1010,8 @@ my %rpmstag = (
"OLDENHANCESNAME" => 1159,
"OLDENHANCESVERSION" => 1160,
"OLDENHANCESFLAGS" => 1161,
"RECOMMENDNAME" => 5046,
"FILEDIGESTALGO" => 5011,
"RECOMMENDNAME" => 5046,
"RECOMMENDVERSION" => 5047,
"RECOMMENDFLAGS" => 5048,
"SUGGESTNAME" => 5049,
Expand Down
1 change: 1 addition & 0 deletions build-recipe-kiwi
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ perform_product_bundle() {
mv "$i" $BUILD_ROOT/$TOPDIR/KIWI/.
test -n "$milestone" && echo "$milestone" > $BUILD_ROOT/$TOPDIR/OTHER/${i%.iso}.milestone ;;
*.packages) mv $i $BUILD_ROOT/$TOPDIR/OTHER/. ;;
*.sbom.json) mv $i $BUILD_ROOT/$TOPDIR/OTHER/. ;;
*.report)
mv $i $BUILD_ROOT/$TOPDIR/OTHER/.
test -n "$milestone" && echo "$milestone" > $BUILD_ROOT/$TOPDIR/OTHER/${i%.report}.milestone
Expand Down
8 changes: 8 additions & 0 deletions dist/build.changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
-------------------------------------------------------------------
Wed Feb 8 11:54:16 UTC 2023 - Adrian Schröter <[email protected]>

- SPDX SBOM generation for container and product builds
- Revert & Redo "Better filetype detection for temp changes files"
- Fix typo in glibc hwcaps supplements
- Implement lua string macros

-------------------------------------------------------------------
Mon Jan 2 08:09:43 UTC 2023 - Adrian Schröter <[email protected]>

Expand Down
115 changes: 79 additions & 36 deletions generate_spdx_sbom
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ BEGIN {
use strict;

use Data::Dumper;
use File::Find;
use File::Temp;

use Digest::SHA;
Expand Down Expand Up @@ -267,7 +268,19 @@ sub gen_filelist {
return \@files;
}

sub read_pkgs {
sub read_rpm {
my ($rpm) = @_;
my %r = Build::Rpm::rpmq($rpm, qw{NAME VERSION RELEASE EPOCH ARCH LICENSE SOURCERPM DISTURL FILENAMES VENDOR FILEMODES FILEDIGESTS FILEDIGESTALGO SIGMD5});
delete $r{$_} for qw{BASENAMES DIRNAMES DIRINDEXES}; # save mem
for (qw{NAME VERSION RELEASE EPOCH ARCH LICENSE SOURCERPM DISTURL VENDOR FILEDIGESTALGO SIGMD5}) {
next unless $r{$_};
die("bad rpm entry for $_\n") unless ref($r{$_}) eq 'ARRAY' && @{$r{$_}} == 1;
$r{$_} = $r{$_}->[0];
}
return \%r;
}

sub read_pkgs_rpmdb {
my ($rpmhdrs) = @_;
my $fd;
open($fd, '<', $rpmhdrs) || die("$rpmhdrs: $!\n");
Expand All @@ -278,24 +291,24 @@ sub read_pkgs {
my ($il, $dl) = unpack('@8NN', $hdr);
die("bad rpm header\n") unless $il && $dl;
die("bad rpm header\n") unless read($fd, $hdr, $il * 16 + $dl, 16) == $il * 16 + $dl;
my %r = Build::Rpm::rpmq([ $hdr ], qw{NAME VERSION RELEASE EPOCH ARCH LICENSE SOURCERPM DISTURL FILENAMES 1011 1030 1035 5011 261});
delete $r{$_} for qw{BASENAMES DIRNAMES DIRINDEXES};
$r{'VENDOR'} = delete $r{'1011'} if $r{'1011'};
$r{'FILEDIGESTALGO'} = delete $r{'5011'} if $r{'5011'};
$r{'FILEMODES'} = delete $r{'1030'} if $r{'1030'};
$r{'FILEDIGESTS'} = delete $r{'1035'} if $r{'1035'};
for (qw{NAME VERSION RELEASE EPOCH ARCH LICENSE SOURCERPM DISTURL VENDOR FILEDIGESTALGO 261}) {
next unless $r{$_};
die("bad rpm entry for $_\n") unless ref($r{$_}) eq 'ARRAY' && @{$r{$_}} == 1;
$r{$_} = $r{$_}->[0];
}
push @rpms, \%r;
push @rpms, read_rpm([ $hdr ]);
}
close($fd);
@rpms = sort {$a->{'NAME'} cmp $b->{'NAME'} || $a->{'VERSION'} cmp $b->{'VERSION'} || $a->{'RELEASE'} cmp $b->{'RELEASE'}} @rpms;
return \@rpms;
}

sub read_pkgs_from_product_directory {
my ($dir) = @_;
my @rpms;
my $addrpmfile = sub {
my $fn = $File::Find::name;
push @rpms, read_rpm($fn) if $fn =~ /\.rpm$/;
};
find($addrpmfile, $dir);
return \@rpms;
}

sub read_dist {
my ($dir) = @_;
my %dist;
Expand All @@ -316,50 +329,77 @@ sub read_dist {
}
close($fd);
}
return \%dist;
return %dist ? \%dist : undef;
}

sub gen_purl_rpm {
my ($p, $dist) = @_;
my ($p, $distro) = @_;

my $vr = $p->{'VERSION'};
$vr = "$vr-$p->{'RELEASE'}" if defined $p->{'RELEASE'};
my $dist_id = $dist->{'id'};
my $dist_str = $dist_id;
$dist_str .= "-$dist->{'version_id'}" if defined($dist->{'version_id'}) && $dist->{'version_id'} ne '';
$dist_str .= "-$dist->{'build_id'}" if defined($dist->{'build_id'}) && $dist->{'build_id'} ne '';
my $purlurl = "pkg:".urlencode("rpm/$dist_id/$p->{'NAME'}\@$vr").'?';
my $vendor = lc($p->{'VENDOR'});
$vendor =~ s/obs:\/\///; # third party OBS builds
$vendor =~ s/\ .*//; # eg. SUSE LLC...
$vendor =~ s/\/?$/\//;
my $purlurl = "pkg:".urlencode("rpm/$vendor$p->{'NAME'}\@$vr").'?';
$purlurl .= '&epoch='.urlencode($p->{'EPOCH'}) if $p->{'EPOCH'};
$purlurl .= '&arch='.urlencode($p->{'ARCH'}) if $p->{'ARCH'};
$purlurl .= '&upstream='.urlencode($p->{'SOURCERPM'}) if $p->{'SOURCERPM'};
$purlurl .= '&distro='.urlencode($dist_str) if $dist_str;
$purlurl .= '&distro='.urlencode($distro) if $distro;
$purlurl =~ s/\?\&/\?/;
$purlurl =~ s/\?$//;
return $purlurl;
}

my $wrap_intoto;

if (@ARGV && $ARGV[0] eq '--intoto') {
$wrap_intoto = 1;
shift @ARGV;
my $isproduct;
my $distro;

while (@ARGV && $ARGV[0] =~ /^-/) {
my $opt = shift @ARGV;
if ($opt eq '--distro') {
$distro = shift @ARGV;
} elsif ($opt eq '--intoto') {
$wrap_intoto = 1;
} elsif ($opt eq '--product') {
$isproduct = 1;
} else {
last if $opt eq '--';
die("unknown option: $opt\n");
}
}

my $containertar = $ARGV[0];
die("usage: generate_spdx_sbom [--disto NAME] [--intoto] [--product] PRODUCT_DIRECTORY|CONTAINER_TAR\n") unless @ARGV == 1;
my $toprocess = $ARGV[0];

my $tmpdir = File::Temp::tempdir( CLEANUP => 1 );
#my $tmpdir = File::Temp::tempdir();

my $unpackdir = unpack_container($tmpdir, $containertar);
dump_rpmdb($unpackdir, "$tmpdir/rpmdb");
my $files;
my $pkgs;
my $dist;
if ($isproduct) {
# product case
#$files = gen_filelist($toprocess);
$pkgs = read_pkgs_from_product_directory($toprocess);
} else {
# container tar case
my $unpackdir = unpack_container($tmpdir, $toprocess);
dump_rpmdb($unpackdir, "$tmpdir/rpmdb");

my $files = gen_filelist($unpackdir);
my $pkgs = read_pkgs("$tmpdir/rpmdb");
my $dist = read_dist($unpackdir);
$files = gen_filelist($unpackdir);
$pkgs = read_pkgs_rpmdb("$tmpdir/rpmdb");
$dist = read_dist($unpackdir);
}

my $subjectname = $containertar;
my $subjectname = $toprocess;
$subjectname =~ s/.*\///;

if (!$distro && $dist) {
$distro = $dist->{'id'};
$distro .= "-$dist->{'version_id'}" if defined($dist->{'version_id'}) && $dist->{'version_id'} ne '';
$distro .= "-$dist->{'build_id'}" if defined($dist->{'build_id'}) && $dist->{'build_id'} ne '';
}

my $spdx = {
'spdxVersion' => 'SPDX-2.3',
'dataLicense' => 'CC0-1.0',
Expand Down Expand Up @@ -395,11 +435,11 @@ for my $p (@$pkgs) {
$spdxpkg->{'licenseDeclared'} = $license;
}
$spdxpkg->{'copyrightText'} = 'NOASSERTION';
my $purlurl = gen_purl_rpm($p, $dist);
my $purlurl = gen_purl_rpm($p, $distro);
my @xref;
push @xref, { 'referenceCategory' => 'PACKAGE-MANAGER', 'referenceType' => 'purl', 'referenceLocator', $purlurl } if $purlurl;
$spdxpkg->{'externalRefs'} = \@xref if @xref;
$p->{'spdx_id'} = "SPDXRef-Package-$p->{'NAME'}-".unpack('H*', $p->{'261'});
$p->{'spdx_id'} = "SPDXRef-Package-$p->{'NAME'}-".unpack('H*', $p->{'SIGMD5'});
$p->{'spdx_id'} =~ s/[^a-zA-Z0-9\.\-]/-/g;
$spdxpkg->{'SPDXID'} = $p->{'spdx_id'};
push @{$spdx->{'packages'}}, $spdxpkg;
Expand Down Expand Up @@ -455,10 +495,13 @@ $uuid = join('-', unpack("H8H4H4H4H12", $uuid));
$spdx->{'documentNamespace'} = 'http://open-build-service.org/spdx/'.urlencode($subjectname).'-'.$uuid;

if ($wrap_intoto) {
my $subject = { 'name' => $subjectname };
# no digest for products as it might be a directory. And an iso file would change the checksum later while signing.
$subject->{'digest'} = { 'sha256' => sha256file($toprocess) } unless $isproduct;
my $intoto = {
'_type' => 'https://in-toto.io/Statement/v0.1',
'subject' => [ $subject ],
'predicateType' => 'https://spdx.dev/Document',
'subject' => [ { 'name' => $subjectname , 'digest' => { 'sha256' => sha256file($containertar) } } ],
'predicate' => $spdx,
};
print Build::SimpleJSON::unparse($intoto, 'template' => $intoto_json_template, 'keepspecial' => 1)."\n";
Expand Down

0 comments on commit c4b0f27

Please sign in to comment.