
use twtools;

package polupdate;


######################################################################
# One time module initialization goes in here...
#
BEGIN 
{
	# This is the root directory we will be integrity checking
	#
	$root1 = "$twtools::twcwd/$twtools::twrootdir/polupdate-test-1";
	$root2 = "$twtools::twcwd/$twtools::twrootdir/polupdate-test-2";
	$root3 = "$twtools::twcwd/$twtools::twrootdir/polupdate-test-3";

	# Here are the names of the report files this test will create
	#
	$report1 = "$twtools::twcwd/$twtools::twrootdir/report/polupdate-1.twr";
	$report2 = "$twtools::twcwd/$twtools::twrootdir/report/polupdate-2.twr";
	$report3 = "$twtools::twcwd/$twtools::twrootdir/report/polupdate-3.twr";
	$report4 = "$twtools::twcwd/$twtools::twrootdir/report/polupdate-4.twr";
}

######################################################################
# PolicyFileString -- return the policy text as a string
#
sub PolicyFileString
{
	return <<POLICY_END;	
	# Policy file generated by polupdate test
	#
	$root1 -> \$(ReadOnly) +M -ab; #read only plus MD5 minus atime & blocks
	$root2 -> \$(ReadOnly) +M -ab; #read only plus MD5 minus atime & blocks
	
POLICY_END

}

######################################################################
# PolicyFileStringNew -- return the policy text as a string
#
sub PolicyFileStringNew
{
	return <<POLICY_END;	
	# Policy file generated by polupdate test
	#
	$root1 -> \$(ReadOnly) +S -ab; #read only plus SHA1 minus atime & blocks
	$root3 -> \$(ReadOnly) +S -ab; #read only plus SHA1 minus atime & blocks
	
POLICY_END

}

######################################################################
# CreateFile -- create a file with the specified contents
#   
# input:  path     -- *absolute* path to the file
#         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 by absolute path
#   
sub RemoveFile
{
	my ($path) = @_;
	
	if( -e $path )
	{
		system( "rm -f $path" );
	}
	
	$? && die "Remove file failed for $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 $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 ( "$root1/sub" );        
	CreateFile( "$root1/sub/hello.txt", "hello world one" );

	CreateDir ( "$root2/sub" );        
	CreateFile( "$root2/sub/hello.txt", "hello world two" );

	CreateDir ( "$root3/sub" );        
	CreateFile( "$root3/sub/hello.txt", "hello world three" );

	# Initialize the database
	#
	twtools::InitializeDatabase();
}

######################################################################
# RunBasicTest -- performs a rudimentary UpdateDatabase test
# 
sub RunBasicTest
{
       twtools::logStatus("*** Beginning polupdate.basic test\n");
	printf("%-30s", "-- polupdate.basic test");

	PrepareForTest();

	twtools::WritePolicyFile( PolicyFileStringNew() );
	if( ! twtools::UpdatePolicy() )
        {
            twtools::logStatus("FAILED -- update policy returned nonzero\n");
            return 0;
        }
 
	# do another IC and make sure there are no violations
	#
	twtools::RunIntegrityCheck();

	($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() );
	
	if( $n != 0 )
	{
	    twtools::logStatus("FAILED -- violations after update\n");
	    return 0;
	}
	
	++$twtools::twpassedtests;
	print "PASSED\n";
	return 1;
}

######################################################################
# RunSecureModeTest -- performs a rudimentary UpdateDatabase test
# 
sub RunSecureModeTest
{
       twtools::logStatus("*** Beginning polupdate.secure_mode test\n");
	printf("%-30s", "-- polupdate.secure_mode test");

	PrepareForTest();

	twtools::WritePolicyFile( PolicyFileStringNew() );
	if( ! twtools::UpdatePolicy({ secure_mode => "high" } ))
        {
            twtools::logStatus("FAILED -- update policy returned nonzero\n");
            return 0;
        }

	# do another IC and make sure there are no violations
	#
	twtools::RunIntegrityCheck();

	($n, $a, $r, $c) = twtools::AnalyzeReport( twtools::RunReport() );
	
	if( $n != 0 )
	{
	    twtools::logStatus("FAILED -- violations after update\n");
	    return 0;
	}
	
	++$twtools::twpassedtests;
	print "PASSED\n";
	return 1;
}


######################################################################
#
# Initialize the test
#

sub initialize 
{
    # Make the policy file
    #
    twtools::GeneratePolicyFile( PolicyFileString() );
    return 1;
}


######################################################################
#
# Run the test.
#
sub run 
{
    eval {
	RunBasicTest();
    } or do {
        my $e = $@;
	twtools::logStatus("Exception in Polupdate RunBasicTest: $e\n");
	++$twtools::twfailedtests;
	print "*FAILED*\n";
    };

    # bump the total test count since this file's a twofer
    ++$twtools::twtotaltests;

    eval {
	RunSecureModeTest();
    } or do {
        my $e = $@;
	twtools::logStatus("Exception in Polupdate RunSecureModeTest: $e\n");
	++$twtools::twfailedtests;
	print "*FAILED*\n";
    };
}

sub cleanup
{
	# remove all of the files we were integrity checking...
	#
	system( "rm -rf $root1/*" );
	system( "rm -rf $root2/*" );
	system( "rm -rf $root3/*" );
	$? && print "WARNING: polupdate 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;

