[PATCH] [RFC] Modularized the fix scripts

Brian Millett bmillett at gmail.com
Mon Feb 18 19:48:24 UTC 2013


On Sat, 16 Feb 2013 13:35:41 -0500
Shawn Wells <shawn.d.wells at gmail.com> wrote:

> 

Ok, so your idea is really good.  I've converted my "project" for the company I'm at and 
it works really nice.

I ran into a bit of some issues which I'll
run past you.

My bash-ks.xml is very large, so I wrote a perl script to break it up into
individual files.

[bpm]$ pwd
/home/bpm/src/scap/scap-security-guide/RHEL6/input/fixes/bash

[bpm]$ ls | wc -l
399

So you can see that there are many fixes.  One of the side affects of the perl
script to parse the bash-ks.xml, is that all of the scripts had the &amp; &lt; &gt; changed 
back into & < >.  Which is a nice side affect in that each fix can be ran from the
commandline to test.  But combining them back into  the bash-remediations.xml
left the xml file broken.  Also the combinefixes.sh took a LONG time to run:

[root at localhost RHEL6]# time transforms/combinefixes.sh input/fixes/bash/
output/bash-remediations2.xml

real	4m41.432s
user	0m5.427s
sys	0m53.876s

So I rewrote it in perl which took:

[root at localhost RHEL6]# time transforms/combinefixes.pl input/fixes/bash/
output/bash-remediations.xml

real	0m1.131s
user	0m0.095s
sys	0m0.184s

So here are the perl scripts.  One to break up a large bash-ks.xml file and
one to combinefixes.

__BEGIN__ parseFix.pl
#!/usr/bin/perl

use XML::Simple qw(:strict);
use Data::Dumper;

my $xmlFile = $ARGV[0];
my $xmlDir = $ARGV[1];

my $DEBUG=0;

my $config = XMLin($xmlFile,
                   KeyAttr => { fix => 'rule' },
                   ForceArray => [ 'fix' ]);

#print Dumper($config) if $DEBUG;

my $fixes = $config->{'fix'};

for my $rule (keys %{$fixes}) {
  printf "%s => %s\n", $rule, $fixes->{$rule}->{'content'} if $DEBUG;
  open my $fix, '>', $xmlDir."/". $rule.".sh";
  printf $fix "%s\n", $fixes->{$rule}->{'content'};
}
__END__

__BEGIN__ combinefixes.pl
#!/usr/bin/perl

use Data::Dumper;
use File::Basename;

## First argument: directory with .sh scripts
## Second argument: where to put combined xml file

my $fixDir=$ARGV[0];
my $output=$ARGV[1];

sub encode {
  my($toencode) = @_;
  $toencode =~ s/\&/\&amp;/g;
  $toencode =~ s/>/\&gt;/g;
  $toencode =~ s/</\&lt;/g;
  return $toencode;
}

open my $XML, '>', $output;

print $XML "<fix-group id=\"bash\" system=\"urn:xccdf:fix:script:sh\" xmlns=\"http://checklists.nist.gov/xccdf/1.1\">\n";

opendir(my $dh, $fixDir) || die "can't opendir $fixDir: $!";
@files = grep { !/^\./ && -f "$fixDir/$_" } readdir($dh);
closedir $dh;

for my $fixScript (@files) {
  my $fixName = basename($fixScript,".sh");
  open my $FIX,'<', $fixDir."/".$fixScript;
  my @lines = <$FIX>;
  close $FIX;
  @lines = map { encode($_) } @lines;
  print $XML "<fix rule=\"$fixName\">\n";
  print $XML (@lines);
  print $XML "</fix>\n";
}

print $XML "</fix-group>\n";
close $XML;
__END__

-- 
Brian Millett
"Now, Commander, I'm sure there's more to your story than that."
'Yes.'
           -- [ Cynthia Torqueman and Ivanova, "And Now For A Word"]


More information about the scap-security-guide mailing list