Skip to content

Commit

Permalink
Added "csaf-validator" utility and improved validation
Browse files Browse the repository at this point in the history
  • Loading branch information
giterlizzi committed Mar 8, 2024
1 parent 60ffdac commit c485cf9
Show file tree
Hide file tree
Showing 83 changed files with 2,046 additions and 1,717 deletions.
5 changes: 5 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
bin/csaf-validator
Changes
INSTALL.md
lib/App/CSAF/Validator.pm
lib/CSAF.pm
lib/CSAF/Base.pm
lib/CSAF/Builder.pm
Expand Down Expand Up @@ -69,6 +71,8 @@ lib/CSAF/Type/Tracking.pm
lib/CSAF/Type/Vulnerabilities.pm
lib/CSAF/Type/Vulnerability.pm
lib/CSAF/Util.pm
lib/CSAF/Util/CVSS.pm
lib/CSAF/Util/CWE.pm
lib/CSAF/Util/List.pm
lib/CSAF/Validator.pm
lib/CSAF/Validator/Base.pm
Expand Down Expand Up @@ -132,6 +136,7 @@ t/examples/rhsa-2019_1862.json
t/examples/rhsa-2021_5186.json
t/examples/rhsa-2021_5217.json
t/examples/rhsa-2022_0011.json
t/kwalitee.t
t/lib/Test/CSAF.pm
t/manifest.t
t/official-testcases/informative/oasis_csaf_tc-csaf_2_0-2021-6-3-01-01.json
Expand Down
3 changes: 2 additions & 1 deletion Makefile.PL
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use strict;
use warnings;

use ExtUtils::MakeMaker;

WriteMakefile(
Expand All @@ -10,7 +11,7 @@ WriteMakefile(
VERSION_FROM => 'lib/CSAF.pm',
ABSTRACT_FROM => 'lib/CSAF.pm',
LICENSE => 'artistic_2',
EXE_FILES => [],
EXE_FILES => ['bin/csaf-validator'],
MIN_PERL_VERSION => 5.010,
PL_FILES => {},
CONFIGURE_REQUIRES => {'ExtUtils::MakeMaker' => '0'},
Expand Down
53 changes: 53 additions & 0 deletions bin/csaf-validator
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use App::CSAF::Validator;

exit App::CSAF::Validator->run(@ARGV) unless caller();

1;

__END__
=encoding utf-8
=head1 NAME
csaf-validator - CSAF Validator
=head1 SYNOPSIS
csaf-validator --file PATH
csaf-validator [--help|--man|-v]
Options:
-f, --file PATH CSAF document path
--help Brief help message
--man Full documentation
-v Print version
=head1 DESCRIPTION
C<csaf-validator> CSAF Validator
=head1 EXAMPLES
$ csaf-validator -f csaf-document.json
[error] /document/tracking/revision_history: Sorted Revision History (6.1.14 - mandatory)
[error] /document/tracking/version: Detected newer revision of document (6.1.16 - mandatory)
$ cat csaf-document.json | csaf-validator
[error] /product_tree/branches/0/branches/0/branches/name: Version Range in Product Version (6.1.31 - mandatory)
=head1 AUTHOR
L<Giuseppe Di Terlizzi|https://metacpan.org/author/gdt>
=head1 COPYRIGHT AND LICENSE
Copyright © 2023-2024 L<Giuseppe Di Terlizzi|https://metacpan.org/author/gdt>
You may use and distribute this module according to the same terms
that Perl is distributed under.
99 changes: 99 additions & 0 deletions lib/App/CSAF/Validator.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package App::CSAF::Validator;

use 5.010001;
use strict;
use warnings;
use utf8;

use Getopt::Long qw( GetOptionsFromArray :config gnu_compat );
use Pod::Usage;
use Carp;

use CSAF;
use CSAF::Parser;

our $VERSION = $CSAF::VERSION;

sub cli_error {
my ($error) = @_;
$error =~ s/ at .* line \d+.*//;
print STDERR "ERROR: $error\n";
}

sub run {

my ($class, @args) = @_;

my %options = ();

delete $ENV{CSAF_DEBUG};

GetOptionsFromArray(
\@args, \%options, qw(
file|f=s
help|h
man
v
)
) or pod2usage(-verbose => 0);

pod2usage(-exitstatus => 0, -verbose => 2) if defined $options{man};
pod2usage(-exitstatus => 0, -verbose => 0) if defined $options{help};

if (defined $options{v}) {

(my $progname = $0) =~ s/.*\///;

say <<"VERSION";
$progname version $CSAF::VERSION
Copyright 2023-2024, Giuseppe Di Terlizzi <gdt\@cpan.org>
This program is part of the CSAF distribution and is free software;
you can redistribute it and/or modify it under the same terms as Perl itself.
Complete documentation for $progname can be found using 'man $progname'
or on the internet at <https://metacpan.org/dist/CSAF>.
VERSION

return 0;

}

my $csaf_parser_options = {};

# Detect input from STDIN
if (-p STDIN || -f STDIN) {
$csaf_parser_options->{content} = do { local $/; <STDIN> };
}

if (defined $options{file}) {
$csaf_parser_options->{file} = $options{file};
}

if (%{$csaf_parser_options}) {

my $csaf = eval { CSAF::Parser->new(%{$csaf_parser_options})->parse };

if ($@) {
cli_error($@);
return 255;
}

if (my @errors = $csaf->validate) {
say STDERR $_ for (@errors);
return 1;
}

say STDERR "CSAF Document valid";
return 0;

}

pod2usage(-verbose => 0);
return 0;

}

1;
45 changes: 34 additions & 11 deletions lib/CSAF.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package CSAF;
use 5.010001;
use strict;
use warnings;
use utf8;

use CSAF::Builder;
use CSAF::Writer;
Expand All @@ -13,17 +14,14 @@ use CSAF::Document;

use overload '""' => \&to_string, fallback => 1;

our $VERSION = '0.12';
our $VERSION = '0.13';

our $CACHE = {};

sub new {

my $class = shift;

$CACHE = {}; # Reset Cache

my $self = {_ => CSAF::Document->new};
my $self = {_ => CSAF::Document->new};

return bless $self, $class;

Expand All @@ -50,6 +48,10 @@ sub render { shift->renderer->render(@_) }
sub to_string { shift->renderer->render }
sub TO_JSON { shift->builder->TO_JSON }

sub DESTROY {
$CACHE = {}; # Reset Cache
}

1;

__END__
Expand All @@ -66,24 +68,45 @@ CSAF - Common Security Advisory Framework
$csaf->document->title('Base CSAF Document');
$csaf->document->category('csaf_security_advisory');
$csaf->document->publisher(category => 'vendor', name => 'CSAF', namespace => 'https://csaf.io');
$csaf->document->publisher(
category => 'vendor',
name => 'CSAF',
namespace => 'https://csaf.io'
);
my $tracking = $csaf->document->tracking(
id => 'CSAF:2023-001',
id => 'CSAF:2024-001',
status => 'final',
version => '1.0.0',
initial_release_date => 'now',
current_release_date => 'now'
);
$tracking->revision_history->add(date => 'now', summary => 'First release', number => '1');
$tracking->revision_history->add(
date => 'now',
summary => 'First release',
number => '1'
);
my @errors = $csaf->validate;
if (@errors) {
say $_ for (@errors);
Carp::croak "Validation errors";
}
$csaf->writer(directory => '/var/www/html/csaf')->write;
=head1 DESCRIPTION
The Common Security Advisory Framework (CSAF) Version 2.0 is the definitive reference for the language which supports
creation, update, and interoperable exchange of security advisories as structured information on products,
vulnerabilities and the status of impact and remediation among interested parties.
The Common Security Advisory Framework (CSAF) Version 2.0 is the definitive
reference for the language which supports creation, update, and interoperable
exchange of security advisories as structured information on products,
vulnerabilities and the status of impact and remediation among interested
parties.
L<https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html>
=head2 CSAF PROPERTIES
Expand Down
1 change: 1 addition & 0 deletions lib/CSAF/Base.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package CSAF::Base;
use 5.010001;
use strict;
use warnings;
use utf8;

use Carp;
use Moo;
Expand Down
1 change: 1 addition & 0 deletions lib/CSAF/Builder.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package CSAF::Builder;
use 5.010001;
use strict;
use warnings;
use utf8;

use Carp;

Expand Down
1 change: 1 addition & 0 deletions lib/CSAF/Document.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package CSAF::Document;
use 5.010001;
use strict;
use warnings;
use utf8;

use CSAF::Type::Document;
use CSAF::Type::ProductTree;
Expand Down
Loading

0 comments on commit c485cf9

Please sign in to comment.