# [--xsadir xsadir] --xsa xsafile
use strict;
-# Disabled warnings as
-# - if ( @{ $XSA_TO_INDEX_MATCH{$e} } ) throws an error, while
-# if ( defined @{ $XSA_TO_INDEX_MATCH{$e} } ) works but warns
-no warnings 'deprecated';
-no warnings 'experimental';
-
use warnings;
use 5.010;
use Getopt::Long qw(GetOptions);
# PRINT REPORT
my @XSA_LIST;
-my %XSA_TO_INDEX;
+
my %XSA_TO_INDEX_AUX; # Contains *.patch files deemed not important
my %XSA_TO_INDEX_MATCH; # Contains *.patch files matching a version
+my %XSA_MAX_AUX; # Possible matches (not important)
+my %XSA_MAX_MATCH; # Possible matches (important)
+my %XSA_NO_AUX; # Number of matches (not important)
+my %XSA_NO_MATCH; # Number of matches (important)
+
preparedatabyxsa();
printreport();
sub preparedatabyxsa {
my $i;
+ my $e;
@XSA_LIST = uniq ( @XSA );
@XSA_LIST = sort { $a <=> $b } @XSA_LIST;
+
+ # Set number of matches
+ foreach $e (@XSA_LIST) {
+ $XSA_NO_AUX{$e} = 0;
+ $XSA_NO_MATCH{$e} = 0;
+ $XSA_MAX_AUX{$e} = 0;
+ $XSA_MAX_MATCH{$e} = 0;
+ }
for ($i=0; $i <= $#XSA; $i++) {
- push @{ $XSA_TO_INDEX{$XSA[$i]} }, $i;
-
# Check $XSA_PATCH[$i] against @XSA_REGEXFORVERSION
# If there is a match put in %XSA_TO_INDEX_MATCH
# Otherwise in %XSA_TO_INDEX_AUX
if ($XSA_PATCH[$i] =~ /$rx/) {
push @{ $XSA_TO_INDEX_MATCH{$XSA[$i]} }, $i;
+ $XSA_MAX_MATCH{$XSA[$i]}++;
+ if ( !($XSA_IN[$i] eq "in NONE") ) {
+ $XSA_NO_MATCH{$XSA[$i]}++;
+ }
} else {
push @{ $XSA_TO_INDEX_AUX{$XSA[$i]} }, $i;
+ $XSA_MAX_AUX{$XSA[$i]}++;
+ if ( !($XSA_IN[$i] eq "in NONE") ) {
+ $XSA_NO_AUX{$XSA[$i]}++;
+ }
}
}
}
-
sub printreport {
my $e;
my $i;
+ printsection("SUMMARY");
+ printlistheader("Applied XSAs", "BLACK");
+ foreach $e (@XSA_LIST)
+ {
+ printxsasummary($e);
+ }
+ printlistend();
+
+ printseparator();
+ printsection("DETAILS");
foreach $e (@XSA_LIST)
{
printheadline($e);
- if ( defined @{ $XSA_TO_INDEX_MATCH{$e} } ) {
+ if ( $XSA_TO_INDEX_MATCH{$e}) {
printlistheader("Comparisons specific to $VERSION.$MAJOR:",
"BLACK");
foreach $i ( @{ $XSA_TO_INDEX_MATCH{$e} } ) {
printseparator();
}
- if ( defined @{ $XSA_TO_INDEX_AUX{$e} } ) {
+ if ( $XSA_TO_INDEX_AUX{$e} ) {
printlistheader("Other comparisons (can probably be ignored):",
"GRAY");
foreach $i ( @{ $XSA_TO_INDEX_AUX{$e} } ) {
- printxsadetail_byindex($i, "GRAY", $debug);
+ printxsadetail_byindex($i, "LIGHTSALMON", $debug);
+ }
+ printlistend();
+ }
+
+ my $vs = 0;
+ my $res = 0;
+
+ # Calculate which additional text to show
+ if ( ( $XSA_NO_AUX{$e} + $XSA_NO_MATCH{$e} ) == 0 ) {
+ # Show VULNERABLE SYSTEMS
+ $vs = 1;
+ } elsif ( ( $XSA_MAX_MATCH{$e} != 0 ) &&
+ ( $XSA_MAX_MATCH{$e} == $XSA_NO_MATCH{$e} ) ) {
+ # Show nothing
+ } else {
+ # Show VULNERABLE SYSTEMS and RESOLUTION
+ $vs = 1;
+ $res = 1;
+ }
+
+ # Show additional text
+ if ( $vs + $res != 0 ) {
+ printseparator();
+ printlistheader("Excerpt from XSA", "BLACK");
+ if ( $vs ) {
+ printquote( $XSA_VS{$e} );
+ }
+ if ( $res ) {
+ printquote( $XSA_RESVERBATIM{$e} );
}
printlistend();
}
}
}
+sub printsection {
+
+ my $section = shift;
+ if ($HTML) {
+ printf('<a name="%s">', $section);
+ printf('<h2>');
+ printf('%s', $section);
+ printf('</h2>');
+
+ } else {
+ my $i;
+ printf("\n%s\n", $section);
+ for ($i=0; $i< length $section; $i++) {
+ printf("=");
+ }
+ printf("\n\n");
+ }
+}
sub printheadline {
-
+
my $xsa = shift;
if ($HTML) {
printf('<a href="http://xenbits.xenproject.org/xsa/'.
'advisory-%s.html">XSA %s</a>', $xsa, $xsa);
printf('</h3>');
-
+
} else {
printf("XSA %-3s\n", $xsa);
printf("=======\n");
}
}
+sub printxsasummary {
+ my $xsa = shift;
+ my $col = "BLACK";
+ my $desc = "(error: unknown)";
+
+ # Calculate which text/color to use
+ if ( ( $XSA_NO_AUX{$xsa} + $XSA_NO_MATCH{$xsa} ) == 0 ) {
+ $col = "RED";
+ $desc = "No patch found => check";
+ } elsif ( ( $XSA_MAX_MATCH{$xsa} != 0 ) &&
+ ( $XSA_MAX_MATCH{$xsa} == $XSA_NO_MATCH{$xsa} ) ) {
+ $col = "GREEN";
+ $desc = "All patches found (no need to check)";
+ } elsif ( ( $XSA_MAX_MATCH{$xsa} == 0 ) &&
+ ( $XSA_MAX_AUX{$xsa} != 0 ) &&
+ ( $XSA_MAX_AUX{$xsa} == $XSA_NO_AUX{$xsa} ) ){
+ $col = "TOMATO";
+ $desc = "All patches found => check as advisory text ".
+ "may be ambiguous";
+ } else {
+ $col = "TOMATO";
+ $desc = "Some patches not applied => check";
+ }
+
+ # Print XSA number (with link to detail)
+ if ($HTML) {
+ printf(' <li style="color:%s;">', $col);
+ printf('<a href="#%s">XSA %s</a> : %s', $xsa, $xsa, $desc);
+ printf('</li>');
+
+ } else {
+ printf("XSA %-3s: %s", $xsa, $desc);
+ }
+
+ printf("\n");
+}
+
+sub printquote {
+
+ my $text = shift;
+
+ if ($HTML) {
+ printf('<pre>');
+ printf($text);
+ printf('</pre>');
+
+ } else {
+ printf("\n");
+ printf($text);
+ printf("\n\n");
+ }
+}
+
sub printxsadetail_byindex {
my $i = shift;
}
if ($DEBUG != 0) {
printf(' ... <a href="File://%s">DEBUG</a> ', $debug."/".
- $XSA[$i]."[".$i_correct."]");
+ $XSA[$i]."[".$i_correct."]");
}
printf('</li>');
printf("\n");
sub printseparator {
- printf("\n");
+ if ($HTML) {
+ printf("\n");
+ }
}
sub printlistheader {
printf('<ul style="color:%s;"> ', $color);
printf("\n");
} else {
- printf("== %s ==\n", $text);
+ printf("=== %s ===\n", $text);
printf("\n");
}
}