use twtools; package integritycheck; ###################################################################### # One time module initialization goes in here... # BEGIN { $description = "integrity check test"; # This is the root directory we will be integrity checking # $root = "$twtools::twcwd/$twtools::twrootdir/ic-test-a"; $root2 = "$twtools::twcwd/$twtools::twrootdir/ic-test-b"; # Here are the names of the report files this test will create # $report1 = "$twtools::twcwd/$twtools::twrootdir/report/ic-1.twr"; $report2 = "$twtools::twcwd/$twtools::twrootdir/report/dbupdate-2.twr"; $report3 = "$twtools::twcwd/$twtools::twrootdir/report/dbupdate-3.twr"; $report4 = "$twtools::twcwd/$twtools::twrootdir/report/dbupdate-4.twr"; } ###################################################################### # PolicyFileString -- return the policy text as a string # sub PolicyFileString { return < \$(ReadOnly)+S; #read only plus SHA-1 } (rulename="RuleB", severity=200, emailto="elvis@mars") { $root2 -> \$(ReadOnly)+S; #read only plus SHA-1 } POLICY_END } ###################################################################### # CreateFile -- create a file with the specified contents # # input: path -- path to the file; relative to $root # contents -- string to put in the file # sub CreateFile { my ($path, $contents) = @_; system( "echo $contents > $path" ); $? && die "Create file failed for $path\n"; } ###################################################################### # RemoveFile -- removes the named file # sub RemoveFile { my ($path) = @_; if( -e "$path" ) { system( "rm -f $path" ); } $? && die "Remove file failed for $root/$path\n"; } ###################################################################### # CreateDir -- create a directory # sub CreateDir { my($dir) = @_; # NOTE: mkdir fails if it is already a directory! # if( ! -d "$dir" ) { system( "rm -f $dir" ); system( "mkdir -p $dir" ); $? && die "Mkdir failed for $root/$dir\n"; } } ###################################################################### # MoveFile -- move a file from one place to another # NOTE: file names are relative to $root # # input: old_name -- name of file to move # new_name -- where it should be moved to # sub MoveFile { my($old, $new) = @_; system( "mv $old $new" ); $? && die "mv $old $new failed!\n"; } ###################################################################### # PrintDatabase # sub PrintDatabase { system( "$twtools::twrootdir/bin/twprint -m d -c $twtools::twrootdir/tw.cfg" ); } ###################################################################### # PrintReport # sub PrintReport { my ($report) = @_; system( "$twtools::twrootdir/bin/twprint -m r -c $twtools::twrootdir/tw.cfg -r $report" ); } ###################################################################### # PrepareForTest -- creates the files that each test will be # integrity checking and initializes the database. # sub PrepareForTest { # make sure we are cleaned up... # cleanup(); # Make the files we will be using... # CreateDir ( "$root"); CreateDir ( "$root/subdir" ); CreateFile( "$root/subdir/modify.txt", "hello world" ); CreateFile( "$root/copy-src.txt", "asdf" ); CreateDir ( "$root2"); CreateFile( "$root2/deleteme.txt", "goodbye cruel world" ); # Initialize the database # twtools::InitializeDatabase(); } ###################################################################### # # Run the test. # sub run { my $twpassed = 1; twtools::logStatus("*** Beginning integrity check test\n"); printf("%-30s", "-- $description"); PrepareForTest(); # make some violations... # MoveFile ( "$root/copy-src.txt", "$root/copy-dest.txt" ); CreateFile( "$root/subdir/modify.txt", "bark bark bark" ); RemoveFile( "$root2/deleteme.txt"); ####################################################### # First run a full IC # twtools::RunIntegrityCheck(); # Make sure we got 6 violations: 3 mod, 1 add, 2 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 6) || ($a != 1) || ($r != 2) || ($c != 3) ) { twtools::logStatus("Full IC failed: $n $a $r $c\n"); $twpassed = 0; } # TODO: Make RunReport+AnalyzeReport play nice with signed report files ####################################################### # Do it again, but sign it this time. # #twtools::RunIntegrityCheck({trailing-opts => "-E -P $twtools::twlocalpass"}); # Make sure we got 6 violations: 3 mod, 1 add, 2 rm. # #my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); #if( ($n != 6) || ($a != 1) || ($r != 2) || ($c != 3) ) #{ # twtools::logStatus("Full IC with signing failed: $n $a $r $c\n"); # $twpassed = 0; #} ####################################################### # Now run 'just' the FS section, aka the whole policy # RemoveFile("$reportloc"); twtools::RunIntegrityCheck(trailing-opts => "-x FS"); # Make sure we got 6 violations: 3 mod, 1 add, 2 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 6) || ($a != 1) || ($r != 2) || ($c != 3) ) { twtools::logStatus("IC with FS section failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Now run a check ignoring the SHA attribute, should still return same changes # RemoveFile("$reportloc"); twtools::RunIntegrityCheck(trailing-opts => "-i S"); # Make sure we got 6 violations: 3 mod, 1 add, 2 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 6) || ($a != 1) || ($r != 2) || ($c != 3) ) { twtools::logStatus("IC with FS section failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Now just run RuleA # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "-R RuleA"}); # Make sure we got 4 violations this time: 2 mod, 1 add, 1 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 4) || ($a != 1) || ($r != 1) || ($c != 2) ) { twtools::logStatus("IC of Rule A failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Now run severity level 200, meaning RuleB # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "-l 200"}); # Make sure we got 2 violations this time: 1 mod, 0 add, 1 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 2) || ($a != 0) || ($r != 1) || ($c != 1) ) { twtools::logStatus("IC of severity 200+ failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Now run severity level "high", also meaning RuleB # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "-l high"}); # Make sure we got 2 violations this time: 1 mod, 0 add, 1 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 2) || ($a != 0) || ($r != 1) || ($c != 1) ) { twtools::logStatus("IC of severity 'high' failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Now run against one object, modify.txt # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "$root/subdir/modify.txt"}); # Make sure we got 1 violation this time: 1 mod, 0 add, 0 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 1) || ($a != 0) || ($r != 0) || ($c != 1) ) { twtools::logStatus("IC of single object modify.txt failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Run a few full check w/ email reporting, all the valid levels # (we're configured to pipe to cat as a fake mailprogram) # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "-M -t 0"}); twtools::RunIntegrityCheck({trailing-opts => "-M -t 1"}); twtools::RunIntegrityCheck({trailing-opts => "-M -t 2"}); twtools::RunIntegrityCheck({trailing-opts => "-M -t 3"}); twtools::RunIntegrityCheck({trailing-opts => "-M -t 4"}); # Make sure we got 6 violations: 3 mod, 1 add, 2 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 6) || ($a != 1) || ($r != 2) || ($c != 3) ) { twtools::logStatus("Full IC failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Now run an interactive IC with cat as a fake editor, so DB gets auto updated. # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "-I -V cat -P $twtools::twlocalpass"}); # Make sure we got 1 violation this time: 1 mod, 0 add, 0 rm. # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 6) || ($a != 1) || ($r != 2) || ($c != 3) ) { twtools::logStatus("Interactive IC failed: $n $a $r $c\n"); $twpassed = 0; } ####################################################### # Finally run another full IC to verify db was updated # + also exercise the verbose & hex output options since we don't elsewhere. # RemoveFile("$reportloc"); twtools::RunIntegrityCheck({trailing-opts => "-v -h"}); # Make sure we got no violations this time # my ($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() ); if( ($n != 0) || ($a != 0) || ($r != 0) || ($c != 0) ) { twtools::logStatus("IC after interactive IC failed: $n $a $r $c\n"); $twpassed = 0; } ######################################################### # # See if the tests all succeeded... # if ($twpassed) { ++$twtools::twpassedtests; print "PASSED\n"; return 1; } else { ++$twtools::twfailedtests; print "*FAILED*\n"; return 0; } } ###################################################################### # # Initialize the test # sub initialize { # Make the policy file # twtools::GeneratePolicyFile( PolicyFileString() ); return 1; } sub cleanup { # remove all of the files we were integrity checking... # system( "rm -rf $root/*" ); system( "rm -rf $root2/*" ); $? && print "WARNING: IC cleanup failed.\n"; # remove the report files we created... # system( "rm -f $report1" ) if (-e $report1); system( "rm -r $report2" ) if (-e $report2); system( "rm -r $report3" ) if (-e $report3); system( "rm -r $report4" ) if (-e $report4); } ###################################################################### # One time module cleanup goes in here... # END { } 1;