#!/usr/bin/perl
#
# Copyright 2004-2013 SPARTA, Inc.  All rights reserved.  See the COPYING
# file distributed with this software for details
#
#
# This script performs several tests of the DNSSEC-Tools keyrec module.
# A test keyrec file is created and parsed.  Various operations are run
# on these data, and their results printed to the screen.
#
# The following interfaces are tested:
#	keyrec_setval()
#	keyrec_fullrec()
#	keyrec_recval()
#	* keyrec_newkeyrec()
#	keyrec_keyfields()
#	keyrec_zonefields()
#	* keyrec_add()
#		keyrec_discard()
#		keyrec_init()
#		keyrec_read()
#		keyrec_write()
#
# The keyrec_add() and keyrec_setval() tests save the modified file to disk.
# The last four interfaces are tested by the keyrec_add() test.
#
# These are simple tests in that the results are displayed to the screen
# and the tester is left the responsibility of ensuring that all worked
# as expected.  Automatic testing would be great, and it may come RSN.
# Interfaces marked with an asterisk above have tests that automatically
# check for success or failure.
#

use strict;

use Net::DNS::SEC::Tools::keyrec;

create_keyrecfile();

my $keyrecs;					# Keyrec file data.
my $krf = "portrigh.keyrec";			# Keyrec file to use.

$keyrecs = keyrec_read($krf);
# print "keyrecs - $keyrecs\n";

test_fielders();

test_keyrec_fullrec();

test_keyrec_newkeyrec();

test_keyrec_recval();

test_keyrec_setval();

test_keyrec_add();

exit 0;

#############################################################

sub test_fielders
{
	my @fields;

	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_keyfields()\n\n";

	@fields = keyrec_keyfields();
	print "\tvalid key fields:\n";
	foreach my $kf (sort(@fields))
	{
		print "\t\t$kf\n";
	}

	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_zonefields()\n\n";

	@fields = keyrec_zonefields();
	print "\tvalid zone fields:\n";
	foreach my $kf (sort(@fields))
	{
		print "\t\t$kf\n";
	}
}

#############################################################

sub test_keyrec_fullrec
{
	my @krnames = keyrec_names();
	my $nind = @krnames;

	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_fullrec()\n\n";

	for(my $ind=0;$ind<$nind;$ind++)
	{
		print "$ind:  $krnames[$ind]\n";
		my $val = keyrec_fullrec($krnames[$ind]);
		my %sval = %$val;
		foreach my $k (sort(keys(%sval)))
		{
			print "\t<$k>\t<$sval{$k}>\n";
		}
		print "\n";
	}
}

#############################################################

sub test_keyrec_newkeyrec
{
	my $kn1	 = "nkr_1";		# Test keyrec name.
	my $kn2	 = "nkr_2";		# Test keyrec name.
	my $kn3	 = "nkr_3";		# Test keyrec name.
	my $errs = 0;			# Error count.

	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_newkeyrec()\n\n";

	if(keyrec_newkeyrec($kn1,"zone") < 0)
	{
		print "\tunable to create new zone keyrec $kn1\n";
		$errs++;
	}

	if(keyrec_newkeyrec($kn2,"key") < 0)
	{
		print "\tunable to create new key keyrec $kn2\n";
		$errs++;
	}

	if(keyrec_newkeyrec($kn3,"badtype") == 0)
	{
		print "\table to create new bad-type keyrec $kn3\n";
		$errs++;
	}

	if($errs == 0)
	{
		print "\n\tall keyrec_newkeyrec() tests passed\n";
	}
	else
	{
		print "\n\tonly " . (3 - $errs) . " keyrec_newkeyrec() tests passed\n";
	}

	print "\n";
}

#############################################################

sub test_keyrec_recval
{
	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_recval()\n\n";

	getit("portrigh.com","zonefile");
	getit("portrigh.com","kskpath");
	getit("portrigh.com","endtime");
	getit("Kportrigh.com.+005+26000","zonename");
	getit("Kportrigh.com.+005+26000","algorithm");
	getit("Kportrigh.com.+005+52000","zonename");
	getit("Kportrigh.com.+005+52000","random");
	getit("Kportrigh.com.+005+88888","zonename");
	print "\n";
}

#############################################################

sub test_keyrec_setval
{
	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_setval()\n\n";

	# keyrec_dump_hash();	print "\n";
	# keyrec_dump_array();		print "\n";

	keyrec_setval("key","Kportrigh.com.+005+12345","keyrec_type","ksk");
	keyrec_setval("zone","portrigh.com","zonefile","db.portrigh.com");
	keyrec_setval("zone","portrigh.com","endtime","+8888000");
	keyrec_setval("zone","portrigh.com","kskpath","keys.ksk/Kportrigh.com.+005+44000");
	keyrec_setval("zone","portrigh.com","zskpath","keys.zsk/Kportrigh.com.+005+88000");
	keyrec_setval("zone","portrigh.com","endtime","+8888888");

	# keyrec_dump_array();		print "\n";
	# keyrec_dump_hash();	print "\n";

	keyrec_write();
}

#############################################################

sub test_keyrec_add
{
	my %fields;				# Fields for new keyrecs.
	my $kr;					# Keyrec reference.
	my %names;				# New keyrec name hash.

	print "\n-----------------------------------------------------\n\n";
	print "testing keyrec_add()\n\n";

	keyrec_discard();
	$keyrecs = keyrec_read($krf);

	#
	# Build a set of three keyrecs and add them to the keyrec table.
	#
	%fields = ();
	$fields{'zonefile'} = "db.harp.portrigh.com";
	$fields{'kskkey'} = "Kharp.portrigh.com.+005+12345";
	$fields{'zskkey'} = "Kharp.portrigh.com.+005+23456";
	$fields{'endtime'} = "+2598000";
	$fields{'keyrec_signsecs'} = "1101183759";
	$fields{'keyrec_signdate'} = "Tue Nov 23 04:22:39 2004-2006";
	keyrec_add("zone","harp.portrigh.com",\%fields);

	%fields = ();
	$fields{'zonename'} = "harp.portrigh.com";
	$fields{'keyrec_type'} = "ksk";
	$fields{'ksklength'} = "1024";
	$fields{'algorithm'} = "rsasha1";
	$fields{'random'} = "-r /dev/urandom";
	$fields{'keyrec_gensecs'} = "1101183759";
	$fields{'keyrec_gendate'} = "Tue Nov 23 04:22:39 2004-2006";
	keyrec_add("key","Kharp.portrigh.com.+005+12345",\%fields);

	%fields = ();
	$fields{'zonename'} = "harp.portrigh.com";
	$fields{'keyrec_type'} = "zsk";
	$fields{'zsklength'} = "512";
	$fields{'algorithm'} = "rsasha1";
	$fields{'random'} = "-r /dev/urandom";
	$fields{'keyrec_gensecs'} = "1101183759";
	$fields{'keyrec_gendate'} = "Tue Nov 23 04:22:39 2004-2006";
	keyrec_add("key","Kharp.portrigh.com.+005+23456",\%fields);


	#
	# Write the new keyrec file, dump all our data, and then re-read
	# the file.
	#
	keyrec_write();
	keyrec_init();
	$keyrecs = keyrec_read($krf);

	#
	# Build a table of keyrec names (as created above.)  If the hash value
	# is 1, then we're expecting a keyrec_fullrec() on the hash key to
	# succeed.  If the value is 0, we're expecting it to fail.
	#
	%names = (
		 	"harp.portrigh.com"		=> 1,
		 	"Kharp.portrigh.com.+005+12345"	=> 1,
		 	"Kharp.portrigh.com.+005+23456"	=> 1,
		 	"dummy.keyname.value"		=> 0,
		 );

	#
	# Go through the list of keyrec names and ensure that our newly
	# created keyrecs exist, and that our dummy keyrec doesn't exist.
	#
	foreach my $kn (keys(%names))
	{
		my $expected = $names{$kn};
		$kr = keyrec_fullrec($kn);

		if(defined($kr))
		{
			if($expected)
			{
				print "\tsuccess:  keyrec_add($kn) worked\n";
			}
			else
			{
				print "\tfailure:  key $kn should not exist\n";
			}
		}
		else
		{
			if($expected)
			{
				print "\tfailure:  key $kn should exist\n";
			}
			else
			{
				print "\tsuccess:  $kn invalid, as expected\n";
			}
		}
	}
}

############################################################################

sub getit
{
	my $p1 = shift;
	my $p2 = shift;
	my $val = keyrec_recval($p1,$p2);

	if($val eq "")
	{
		print "$p1/$p2 - empty\n";
	}
	elsif(!defined($val))
	{
		print "$p1/$p2 - not defined\n";
	}
	else
	{
		print "$p1/$p2 - <$val>\n";
	}
}

############################################################################
#
# These data are in the portrigh.keyrec file used in this test.

sub create_keyrecfile
{
	open(KRF,"> portrigh.keyrec");
	print KRF <<EOF;
#
# key management database
#

zone "portrigh.com"
	zonefile	"db.portrigh.com"
	kskkey		"Kportrigh.com.+005+26000.key"
	kskpath		"./Kportrigh.com.+005+26000.key"
	zskkey		"Kportrigh.com.+005+52000.key"
	zskpath		"./Kportrigh.com.+005+52000.key"
	endtime		"+2592000"		# good for 30 days
	keyrec_signsecs	"1101183759"
	keyrec_signdate	"Tue Nov 23 04:22:39 2004-2006"

key "Kportrigh.com.+005+26000"
	zonename	"portrigh.com"
	keyrec_type	"ksk"
	algorithm	"rsasha1"
	ksklength	"1024"
	random		"-r /dev/urandom"
	keyrec_gensecs	"1101183759"
	keyrec_gendate	"Tue Nov 23 04:22:39 2004-2006"

key "Kportrigh.com.+005+52000"
	zonename	"portrigh.com"
	keyrec_type	"zsk"
	algorithm	"rsasha1"
	zsklength	"512"
	random		"-r /dev/urandom"
	keyrec_gensecs	"1101183759"
	keyrec_gendate	"Tue Nov 23 04:22:39 2004-2006"
EOF

	close(KRF);
}
