CSAF

 view release on metacpan or  search on metacpan

lib/CSAF/Downloader.pm  view on Meta::CPAN

package CSAF::Downloader;

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

use CSAF::Options::Downloader;
use CSAF::Util qw(file_read gpg_verify);
use CSAF;

use Cpanel::JSON::XS;
use File::Basename;
use File::Path            qw(make_path);
use File::Spec::Functions qw(catfile);
use LWP::UserAgent;
use Parallel::ForkManager;
use URI::URL;

lib/CSAF/Downloader.pm  view on Meta::CPAN

        }

    }

    if ($self->options->signature_check) {

        if (-e "$csaf_file.asc") {

            $log->info("Check signature of CSAF document");

            my $result = gpg_verify(signed => "$csaf_file.asc", file => $csaf_file);

            if ($result->{exit_code} == 0) {
                $log->info("Signature check OK");
                $log->trace($result->{status});
            }
            else {
                $log->error("Signature check FAILED");
                $log->trace($result->{status});
                Carp::croak "Signature check FAILED for '$csaf_file'";
            }

lib/CSAF/Options/Writer.pm  view on Meta::CPAN

with 'CSAF::Util::Options';

use constant TRUE  => !!1;
use constant FALSE => !!0;

has update_index   => (is => 'rw', default => TRUE);
has update_changes => (is => 'rw', default => TRUE);

has create_sha256_integrity => (is => 'rw', default => TRUE);
has create_sha512_integrity => (is => 'rw', default => TRUE);
has create_gpg_signature    => (is => 'rw', default => FALSE);

has gpg_passphrase => (is => 'rw');
has gpg_key        => (is => 'rw');

1;

__END__

=encoding utf-8

=head1 NAME

CSAF::Options::Writer - CSAF::Writer configurator

=head1 SYNOPSIS

    use CSAF::Options::Writer;
    my $options = CSAF::Options::Writer->new( );

    $options->configure(
        create_sha256_integrity => 0,
        create_gpg_signature    => 1,
        update_index            => 1,
        update_changes          => 1
    );

    if (my $passphrase = get_passphrase_from_stdin) {
        $options->gpg_passphrase($passphrase);
    }


=head1 DESCRIPTION

L<CSAF::Options::Writer> is a configurator of L<CSAF::Writer>.


=head2 METHODS

lib/CSAF/Options/Writer.pm  view on Meta::CPAN

Create and update the C<changes.csv> file (default C<TRUE>).

=item create_sha256_integrity

Create SHA256 integrity file C<*.sha256> for the provided CSAF document (default C<TRUE>).

=item create_sha512_integrity

Create SHA512 integrity file C<*.sha512> for the provided CSAF document (default C<TRUE>).

=item create_gpg_signature

Sign the CSAF document with GPG and create signature file C<*.sha256> (default C<FALSE>).

=item gpg_key

Specify the default GPG key.

=item gpg_passphrase

Specify the passphrase for the provided GPG key.

=back


=head1 SUPPORT

=head2 Bugs / Feature Requests

lib/CSAF/Util.pm  view on Meta::CPAN

use IO::Handle;
use List::Util qw(first);
use Time::Piece;

use Exporter 'import';

our @EXPORT_OK = (qw[
    schema_cache_path resources_path tt_templates_path
    parse_datetime tracking_id_to_well_filename
    collect_product_ids file_read file_write product_in_group_exists
    list_cves gpg_sign gpg_verify log_formatter uniq
]);

my %LOG_LEVELS = (
    0 => 'EMERGENCY',
    1 => 'ALERT',
    2 => 'CRITICAL',
    3 => 'ERROR',
    4 => 'WARNING',
    5 => 'NOTICE',
    6 => 'INFO',

lib/CSAF/Util.pm  view on Meta::CPAN

        open($fh, '>', $file) or Carp::croak "Can't open file: $!";
    }

    $fh->autoflush(1);

    print $fh $content;
    close($fh);

}

sub gpg_get_result_from_handles {

    my %handle = @_;

    my %result = ();
    my $error  = undef;

    foreach (qw[stdout stderr logger status]) {

        $result{$_} = do { local $/ = undef; readline $handle{$_} };
        delete $result{$_} unless $result{$_} && $result{$_} =~ /\S/s;

lib/CSAF/Util.pm  view on Meta::CPAN

    }

    Carp::carp $error if $error;

    $result{exit_code} = ($? >> 8);

    return \%result;

}

sub gpg_verify {

    my %args = (signed => undef, file => undef, @_);

    my %handle = (
        stdin  => IO::Handle->new,
        stdout => IO::Handle->new,
        stderr => IO::Handle->new,
        logger => IO::Handle->new,
        status => IO::Handle->new
    );

lib/CSAF/Util.pm  view on Meta::CPAN


    $gnupg->options->hash_init(meta_interactive => 0);

    my $pid = $gnupg->wrap_call(
        commands     => ['--verify'],
        command_args => [$args{signed}, $args{file}],
        handles      => GnuPG::Handles->new(%handle)
    );
    waitpid $pid, 0;

    return gpg_get_result_from_handles(%handle);

}

sub gpg_sign {

    my %args = (passphrase => undef, plaintext => undef, key => undef, recipients => [], @_);

    my %handle = (
        stdin  => IO::Handle->new,
        stdout => IO::Handle->new,
        stderr => IO::Handle->new,
        logger => IO::Handle->new,
        status => IO::Handle->new
    );

lib/CSAF/Util.pm  view on Meta::CPAN


    $gnupg->passphrase($args{passphrase});

    my $pid = $gnupg->detach_sign(handles => GnuPG::Handles->new(%handle));

    print {$handle{stdin}} ($args{plaintext});
    close $handle{stdin};

    waitpid $pid, 0;

    return gpg_get_result_from_handles(%handle);

}

sub log_formatter {

    my ($category, $level, $format, @params) = @_;

    @params = map { ref $_ ? Dumper($_) : $_ } @params;

    my $message = sprintf($format, @params);

lib/CSAF/Writer.pm  view on Meta::CPAN

package CSAF::Writer;

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

use Carp;
use CSAF::Util qw(tracking_id_to_well_filename file_write gpg_sign);
use CSAF::Options::Writer;
use Digest::SHA           qw(sha256_hex sha512_hex);
use File::Basename        qw(basename dirname);
use File::Path            qw(make_path);
use File::Spec::Functions qw(catfile);
use Tie::File;

use Moo;
extends 'CSAF::Base';
with 'CSAF::Util::Log';

lib/CSAF/Writer.pm  view on Meta::CPAN

    my $csaf_document_path = catfile($csaf_file_year, $csaf_filename);

    if (DEBUG) {
        $self->log->debug("Destination directory : $csaf_directory");
        $self->log->debug("CSAF document         : $csaf_filename");
        $self->log->debug("CSAF document path    : $json_file_path");
        $self->log->debug("index.txt path        : $index_file_path");
        $self->log->debug("changes.csv path      : $changes_file_path");
        $self->log->debug("SHA256 file path      : $json_file_path.sha256") if $self->options->create_sha256_integrity;
        $self->log->debug("SHA512 file path      : $json_file_path.sha512") if $self->options->create_sha512_integrity;
        $self->log->debug("Signature file path   : $json_file_path.asc")    if $self->options->create_gpg_signature;
    }

    make_path(dirname($json_file_path));

    $self->log->info("Save $csaf_id document ($csaf_filename)");

    file_write($json_file_path, $csaf_json);

    if ($self->options->create_sha256_integrity) {
        $self->log->info("Create SHA256 integrity file ($csaf_filename.sha256)");
        file_write("$json_file_path.sha256", sprintf("%s  %s\n", sha256_hex($csaf_json), $csaf_filename));
    }

    if ($self->options->create_sha512_integrity) {
        $self->log->info("Create SHA512 integrity file ($csaf_filename.sha512)");
        file_write("$json_file_path.sha512", sprintf("%s  %s\n", sha512_hex($csaf_json), $csaf_filename));
    }

    if ($self->options->create_gpg_signature) {

        $self->log->info("Sign CSAF document with GPG and create signature file ($csaf_filename.asc)");

        my $result = gpg_sign(
            key        => $self->options->gpg_key,
            passphrase => $self->options->gpg_passphrase,
            plaintext  => $csaf_json
        );

        DEBUG and $self->log->debug($_) for (split("\n", $result->{status}));

        if ($result->{exit_code} == 0) {
            file_write("$json_file_path.asc", $result->{stdout});
        }
        else {
            $self->log->error($result->{logger});

lib/CSAF/Writer.pm  view on Meta::CPAN

=head1 SYNOPSIS

    use CSAF::Writer;

    my $writer = CSAF::Writer->new(
        csaf      => $csaf,
        directory => '/var/www/html/advisories/csaf'
    );

    $writer->options->configure(
        create_gpg_signature => 1
        gpg_key              => '0123456789',
        gpg_passphrase       => 'MY_C00L_Passphrase!'
    );

    if ($writer->write) {
        say "CSAF document created";
    }



=head1 DESCRIPTION

lib/CSAF/Writer.pm  view on Meta::CPAN


    $writer->write('/var/www/html/advisories/csaf');


=item $writer->options

Change the default options for L<CSAF::Options::Writer> configurator.

    $writer->options->configure(
        create_sha256_integrity => 0,
        create_gpg_signature    => 1,
        update_index            => 1,
        update_changes          => 1
    );

    if (my $passphrase = get_passphrase_from_stdin) {
        $writer->options->gpg_passphrase($passphrase);
    }

=back


=head1 SUPPORT

=head2 Bugs / Feature Requests

Please report any bugs or feature requests through the issue tracker



( run in 0.809 second using v1.01-cache-2.11-cpan-df04353d9ac )