diff options
Diffstat (limited to 'lib/Lintian/Data/Buildflags/Hardening.pm')
-rw-r--r-- | lib/Lintian/Data/Buildflags/Hardening.pm | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/lib/Lintian/Data/Buildflags/Hardening.pm b/lib/Lintian/Data/Buildflags/Hardening.pm new file mode 100644 index 0000000..75056df --- /dev/null +++ b/lib/Lintian/Data/Buildflags/Hardening.pm @@ -0,0 +1,154 @@ +# -*- perl -*- + +# Copyright (C) 2011-2012 Niels Thykier <niels@thykier.net> +# - Based on a shell script by Raphael Geissert <atomo64@gmail.com> +# Copyright (C) 2021 Felix Lechner +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, 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, see <http://www.gnu.org/licenses/>. + +package Lintian::Data::Buildflags::Hardening; + +use v5.20; +use warnings; +use utf8; + +use Const::Fast; +use List::SomeUtils qw(first_value uniq); +use Unicode::UTF8 qw(decode_utf8); + +use Lintian::Deb822; +use Lintian::IPC::Run3 qw(safe_qx); + +use Moo; +use namespace::clean; + +const my $EMPTY => q{}; +const my $SLASH => q{/}; + +const my $RECOMMENDED_FEATURES => q{recommended_features}; + +with 'Lintian::Data::PreambledJSON'; + +=encoding utf-8 + +=head1 NAME + +Lintian::Data::Buildflags::Hardening -- Lintian API for hardening build flags + +=head1 SYNOPSIS + + use Lintian::Data::Buildflags::Hardening; + +=head1 DESCRIPTION + +Lintian API for hardening build flags. + +=head1 INSTANCE METHODS + +=over 4 + +=item title + +=item location + +=item recommended_features + +=cut + +has title => ( + is => 'rw', + default => 'Hardening Flags from Dpkg' +); + +has location => ( + is => 'rw', + default => 'buildflags/hardening.json' +); + +has recommended_features => ( + is => 'rw', + default => sub { {} }, + coerce => sub { my ($hashref) = @_; return ($hashref // {}); } +); + +=item load + +=cut + +sub load { + my ($self, $search_space, $our_vendor) = @_; + + my @candidates = map { $_ . $SLASH . $self->location } @{$search_space}; + my $path = first_value { -e } @candidates; + + my $recommended_features; + return 0 + unless $self->read_file($path, \$recommended_features); + + $self->recommended_features($recommended_features); + + return 1; +} + +=item refresh + +=cut + +sub refresh { + my ($self, $archive, $basedir) = @_; + + # find all recommended hardening features + local $ENV{LC_ALL} = 'C'; + local $ENV{DEB_BUILD_MAINT_OPTIONS} = 'hardening=+all'; + + my @architectures + = split(/\n/, decode_utf8(safe_qx('dpkg-architecture', '-L'))); + chomp for @architectures; + + my %recommended_features; + for my $architecture (@architectures) { + + local $ENV{DEB_HOST_ARCH} = $architecture; + + my @command = qw{dpkg-buildflags --query-features hardening}; + my $feature_output = decode_utf8(safe_qx(@command)); + + my $deb822 = Lintian::Deb822->new; + my @sections = $deb822->parse_string($feature_output); + + my @enabled = grep { $_->value('Enabled') eq 'yes' } @sections; + my @features = uniq map { $_->value('Feature') } @enabled; + + $recommended_features{$architecture} = [sort @features]; + } + + my $data_path = "$basedir/" . $self->location; + my $status + = $self->write_file($RECOMMENDED_FEATURES, \%recommended_features, + $data_path); + + return $status; +} + +=back + +=cut + +1; + +# Local Variables: +# indent-tabs-mode: nil +# cperl-indent-level: 4 +# End: +# vim: syntax=perl sw=4 sts=4 sr et |