On 2/18/13 2:48 PM, Brian Millett wrote:
On Sat, 16 Feb 2013 13:35:41 -0500
Shawn Wells <shawn.d.wells@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.

Well.... It's a complete hack, until we can think of a clever/appropriate/scalable/non-sucky way to get the variable names into the fix content.

[root@localhost RHEL6]# time transforms/combinefixes.sh input/fixes/bash/

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

So I rewrote it in perl which took:

[root@localhost RHEL6]# time transforms/combinefixes.pl input/fixes/bash/

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

Hah, this is hilarious. Thank you for cleaning up my bilge quality bash script!

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

__BEGIN__ parseFix.pl

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'};
It seems like this would really be only needed a few developers end, to breakup your pre-existing scripts, vs something that should get dropped into the project.

__BEGIN__ combinefixes.pl

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;
Running this locally:

$ make content
$ oscap xccdf eval --profile stig-rhel6-server --results /tmp/results.xml --cpe-dict output/ssg-rhel6-cpe-dictionary.xml output/ssg-rhel6-xccdf.xml
$ oscap xccdf generate fix --result-id xccdf_org.open-scap_testresult_stig-rhel6-server /tmp/results.xml >>/tmp/fixscript.sh
$ cat /tmp/fixscript.sh
# OpenSCAP fix generator output for benchmark: DRAFT Guide to the Secure Configuration of Red Hat Enterprise Linux 6

# generated: 2013-02-19T01:37:13-05:00

Something appears to be off.... will look at this more tomorrow (err, later today?). Changed Makefile to run the pl script:
        ./$(TRANS)/combinefixes.pl $(IN)/fixes/bash/ $(OUT)/bash-remediations.xml