telephonyserver/etelserverandcore/Documentation/platsec/GenerateCapabilityList.pl
branchopencode
changeset 32 58332560b319
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserver/etelserverandcore/Documentation/platsec/GenerateCapabilityList.pl	Wed Jun 02 16:33:50 2010 +0100
@@ -0,0 +1,577 @@
+# Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+# Script to generate API Policing data structures from CSV file
+# Usage:
+# cvs files as input:  GenerateCapabilityList.pl caps.csv  [caps2.csv] [caps3.csv] ...
+# excel file as input:  GenerateCapabilityList.pl caps.xls etel|phbksync|c32
+# output - file with extension out added to the name of the first argument
+# use strict;
+# 
+#
+
+my $dest_file_ext = ".out";
+
+# following hash maps second input parameter to list of spreadsheets in the execel file to be processed
+my %inputParms =
+	(
+	"etel" => "etel etelmm etelpckt etelsat etelcdma customapi",
+	"phbksync" => "phbksync",
+	"c32" => "c32",
+	);
+
+my $capsColumnName = "Final Capabilities";
+my $ipcValueColumnName = "New IPC Number";
+
+my @spreadSheets = ();
+
+# All valid capabilities
+my %Capabilities =
+	(
+	"TCB" => 1,
+	"CommDD" => 1,
+	"PowerMgmt" => 1,
+	"MultimediaDD" => 1,
+	"ReadDeviceData" => 1,
+	"WriteDeviceData" => 1,
+	"DRM" => 1,
+	"TrustedUI" => 1,
+	"ProtServ" => 1,
+	"DiskAdmin" => 1,
+	"NetworkControl" => 1,
+	"AllFiles" => 1,
+	"SwEvent" => 1,
+	"NetworkServices" => 1,
+	"LocalServices" => 1,
+	"ReadUserData" => 1,
+	"WriteUserData" => 1,
+	"Location" => 1
+	);
+
+sub validate_capabilities
+	{
+	my ($caps) = @_;
+	no warnings;  # silence spurious -w undef complaints
+	if (@$caps eq 0)
+		{
+		return 0;
+		}
+
+	$cap = $caps->[0];
+
+	if ((@$caps == 1) and (($cap =~ /KCapabilityNone/)
+	    or ($cap =~ /None/) or ($cap =~ /CustomCheckStart/)
+	    or ($cap =~ /CustomCheckEnd/) or ($cap =~ /CustomCheckSingle/)))
+		{
+		if($cap =~ /KCapabilityNone/)
+			{
+			$cap=substr( $caps->[$0], 11 );
+			$caps->[$0]=$cap;
+			}
+
+		return 1; # magic "capabilities"
+		}
+
+	for ($i = 0; $i < @$caps; $i++)
+		{
+		if($caps->[$i] =~ /^KCapability/)# old csv format
+			{
+			$cap=substr( $caps->[$i], 11 );
+			$caps->[$i]=$cap;
+			#printf "\n KCapability found: $cap";
+			}
+		else
+			{
+			$cap=$caps->[$i];
+			}
+
+		#printf "\n ->$cap<-";
+
+		if($Capabilities{$cap} ne 1)
+			{
+			return 0;
+			}
+		}
+
+	return 1;
+	}
+
+my %ipc_table = ();
+my $count = 0;
+my $ipc_num = 0;
+my $numOfFiles = @ARGV;
+my $inputMode = "";
+my %policies = ();
+
+# parse arguments in order to figure out type of input files
+if ($numOfFiles  > 0)
+	{
+	$source_file = $ARGV[0];
+
+	foreach $i (0 .. $#ARGV)
+		{
+		if ($inputMode eq "") # first argument
+			{
+			if ($ARGV[$i] =~ /$\.csv/)
+				{
+				$inputMode = "csv";
+				}
+			elsif ($ARGV[$i] =~ /$\.xls/) # excel
+				{
+				$inputMode = "excel";
+				}
+			else
+				{
+				die " Unexpected argument  $ARGV[$i] !\n";
+				}
+			}
+		else  # verify consistency of follow-up arguments
+			{
+			if (($inputMode eq "csv") and !($ARGV[$i] =~ /$\.csv/) )
+				{
+				die " Unexpected mixed arguments inputMode: $inputMode file:$ARGV[$i] \n";
+				}
+			elsif (($inputMode eq "excel") and ($i > 1))
+				{
+				die " Unexpected arguments $ARGV[$i] \n";
+				}
+			elsif (($inputMode eq "excel") and ($i eq 1))
+				{
+				if($inputParms{$ARGV[$i]} ne "")
+					{
+					@spreadSheets= split('\s+' ,$inputParms{$ARGV[$i]});
+					}
+				else
+					{
+					die "Sheet not supported: $ARGV[$i]";
+					}
+				}
+			}
+		} # foreach argument in command line
+
+	if (($inputMode eq "excel") and ($#ARGV == 0))
+		{
+		die "\nArgument missing - name of the server!\n";
+		}
+
+	if ($inputMode eq "csv") # process input csv files
+		{ # TODO - Fix hashing into %policies (currently, this script is broken when used with csv becauase of this)
+		my $nameOfInputFile = "";
+		while (<ARGV>)
+			{
+			if ($ARGV ne $nameOfInputFile)
+				{
+				$nameOfInputFile=$ARGV;
+				print "\nProcessing $nameOfInputFile";
+				}
+
+			if (/(.*),([0-9]+),(.*)$/)
+				{
+				$count++;
+				m/(.*),([0-9]+),(.*)$/;
+
+				$ipc_num = $2;
+				$capability = $3;
+				$capability =~ s/,(.*)//;
+
+				$capability =~ s/^\s+//;
+				$capability =~ s/\s+$//; # remove leading & trailing white spaces
+
+				if($ipc_table{$ipc_num} ne "")
+					{
+					print "\nWarning - ipc $ipc_num is already defined with capability $ipc_table{$ipc_num} - $capability to be assigned .";
+					}
+				else
+					{
+					my @capsArray = sort split('\s+', $capability);
+
+					if (validate_capabilities(\@capsArray ) != 1)
+						{
+						die "Capabilities are not valid for IPC #$ipc_num ! ";
+						}
+
+					my $sortedCaps="";
+					for (my $i = 0; $i < scalar @capsArray; $i++)
+						{
+						$sortedCaps=$sortedCaps." $capsArray[$i]";
+						}
+
+					$ipc_table{$ipc_num} = $sortedCaps;
+					#print "\nipc $ipc_num is capability $ipc_table{$ipc_num} !";
+					}
+				}
+			}
+		$ipc_num++;
+		} # csv files, processed
+
+	elsif ($inputMode eq "excel") # process input excel file - set of sheets defined by second parameter
+		{
+		use Win32::OLE;
+		# Establish MS Excel Access
+		eval {$main::excel= Win32::OLE->GetActiveObject('Excel.Application')};
+
+		die "Excel is not installed" if $@;
+
+		unless (defined $main::excel)
+			{
+			$main::excel = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;})
+			  or die "Cant start Excel";
+			}
+		print "Excel access established\n";
+
+		$main::excel->{DisplayAlerts} = 0; # turn off pesky alerts
+
+		# Open Our Capability Book & Spreadsheet
+		$main::excelbook = $main::excel->Workbooks->Open({FileName => $source_file, ReadOnly=>1})
+		  or die "Can't open $source_file";
+		print "Excel spreadsheet $source_file opened\n";
+
+		#################################
+		for $spreadSheet (@spreadSheets)
+			{
+			print "\n\nProcessing sheet $spreadSheet\n";
+			$main::excelsheet = $main::excelbook->Worksheets($spreadSheet)
+			  or die "Can't open sheet $spreadSheet";
+
+			$main::excelsheet->Activate();
+			my $numRows = $main::excelsheet->UsedRange->Rows->{Count};
+			my $numColumns = $main::excelsheet->UsedRange->Columns->{Count};
+
+			my $IpcCol = 0;
+			my $CapsCol = 0;
+
+			for (my $col = 1; ($col <= $numColumns) and (($IpcCol == 0) or ($CapsCol == 0)); $col++)
+				{
+				$nameOfCol = $main::excelsheet->Cells(1,$col)->{'Value'};
+
+				if ($nameOfCol =~ /$ipcValueColumnName/)
+					{
+					$IpcCol = $col;
+					}
+				elsif ($nameOfCol =~ /$capsColumnName/)
+					{
+					$CapsCol = $col;
+					}
+				} # end finding out relevant columns
+
+			for (my $row = 2; ($row <= $numRows); $row++) # Start at row = 2 because anything above is header.
+				{
+				$ipc_num = $main::excelsheet->Cells($row,$IpcCol)->{'Value'};
+				#printf "\n row: $row - ipc: $ipc_num";
+				if($ipc_num ne "")
+					{
+					$capability = $main::excelsheet->Cells($row,$CapsCol)->{'Value'};
+					$capability =~ s/,(.*)//;
+
+					$capability =~ s/^\s+//;
+					$capability =~ s/\s+$//; # remove leading & trailing white spaces
+
+					if($ipc_table{$ipc_num} ne "")
+						{
+						print "\nWarning - ipc $ipc_num is already defined with capability $ipc_table{$ipc_num} - $capability to be assigned.";
+						}
+					else
+						{
+						my @capsArray = sort { $a cmp $b } split('\s+', $capability);
+
+						if (validate_capabilities(\@capsArray ) != 1)
+							{
+							die "Capabilities are not valid for IPC #$ipc_num!";
+							}
+						my $sortedCaps = "";
+						foreach my $seperateCap (@capsArray)
+							{ # TODO - remove leading white space
+							$sortedCaps .= " $seperateCap";
+							}
+						$ipc_table{$ipc_num} = $sortedCaps;
+
+						if (!($sortedCaps =~ /CustomCheck/)) # Create a policy entry for each new combination of caps
+							{ # TODO move this down to where ranges are generated
+							if ($policies{$sortedCaps})
+								{
+								$policies{$sortedCaps}++; # TODO no need to increment number.
+								}
+							else
+								{
+								$policies{$sortedCaps} = 1;
+								}
+							}
+						}
+
+					$ipc_num++;
+					}
+				} # end for all rows
+
+			$main::excelsheet->Close();
+			} # end for workSheets
+
+		#################################
+		$main::excel->ActiveWorkbook->Close(0);
+		$main::excel->Quit();
+		} # excel spreadsheet
+	else
+		{
+		die "$source_file is neither csv nor xls file !";
+		}
+
+	# at this point following hash is generated, where $ipc_table{k} is unique, but not sorted yet
+	#    ipc1     caps1
+	#    ipc2     caps2
+	#    ...
+	#    ipcn     capsn
+	@ipcs = sort {$a <=> $b} keys %ipc_table;
+
+	if(@ipcs == 0)
+		{
+		die "\n There are no ipcs defined!\n";
+		}
+
+	# generate hash that contains ranges of ipcs with same capability :
+	# ipc1   count1
+	# ipc2   count2
+	# ...
+	# ipcm   count m
+
+	# number of ranges is less or ( in the worst case) equal to number of input ipcs
+	# ipcs are sorted in incremental order
+
+	open(OUTPUT, ">$source_file$dest_file_ext")
+	  or die "Can't create output file: $!";
+
+	# generate ranges
+	my @range_sizes = ();
+	my @range_starts = ();
+
+	my $customCheckOn = 0;
+	$count = -1; # initial count of ipcs in the range
+
+	# prepare for start
+	push @range_starts, $ipcs[0];
+	my $caps = $ipc_table{$ipcs[0]};
+	$prev_caps = $caps;
+	$prev_ipc = $ipcs[0]-1;
+
+	for $ipc (@ipcs)
+		{
+		$caps = $ipc_table{$ipc};
+		$count++;
+
+		# enforce pairs CustomCheckStart/CustomCheckEnd
+		if(($customCheckOn == 1) and !($caps =~ /CustomCheckEnd/))
+			{
+			die "Inconsistent use of CustomCheckEnd at ipc #$ipc \n";
+			}
+
+		if ($caps =~ /CustomCheckStart/ and $customCheckOn == 1)
+			{
+			die "Inconsistent use of CustomCheck at ipc #$ipc; CustomCheckStart already at previous IPC\n";
+			}
+		elsif ($caps =~ /CustomCheckEnd/ and $customCheckOn == 0)
+			{
+			die "Inconsistent use of CustomCheck at ipc #$ipc; CustomCheckEnd without a start\n";
+			}
+		elsif ($caps =~ /CustomCheckStart/)
+			{
+			$customCheckOn = 1;
+			if ($ipc ne $ipcs[0])  # custom range is not the first
+				{
+				push (@range_sizes, $count); # complete previous range
+				# start new range
+				push (@range_starts, $ipc);
+				}
+
+			$prev_ipc = $ipc;
+			$prev_caps = $caps;
+			$count = 0;
+			next;
+			}
+		elsif( $caps =~ /CustomCheckEnd/)
+			{
+			$customCheckOn = 0;
+			$count = $ipc-$prev_ipc;
+
+			if($count == 0)
+				{
+				$count = 1;
+				}
+
+			$prev_ipc = $ipc;
+			next;
+			}
+
+		# end of the range if caps differ of non-sequental ipcs
+		if (($caps ne $prev_caps) or ($prev_ipc ne ($ipc-1)))
+			{
+			push (@range_sizes, $count);
+
+			# start new range
+			push (@range_starts, $ipc);
+			$count = 0;
+			}
+
+		# continue to iterate through range
+		$prev_ipc = $ipc;
+		$prev_caps = $caps;
+		} # for all IPCs
+
+	$count++;
+	push @range_sizes, $count;
+
+	# now generate output c++ structures
+
+	$range_id = 0;
+	$curr_ipc = $ipcs[0];
+	$range_start = $curr_ipc;
+	print OUTPUT "\n\nconst TInt iRanges[] = \n\t{\n";
+
+	$startRange=0;
+	$numOfRanges=0;
+	$i=0;
+	$lastIpc= $range_starts[(scalar @range_starts)-1];
+
+	for $startIpcs (@range_starts)
+		{
+		if($startRange != $startIpcs)
+			{
+			$endRange = $startIpcs-1;
+			print OUTPUT "\t$startRange,\t\t//range is $startRange-$endRange inclusive\n";
+			$numOfRanges++;
+			}
+
+		$endRange = $startIpcs + $range_sizes[$i]-1;
+
+		if($endRange != $startIpcs)
+			{
+			print OUTPUT "\t$startIpcs,\t\t//range is $startIpcs-$endRange inclusive\n";
+			}
+		else
+			{
+			if( ($customCheckOn == 1) and ($lastIpc eq $startIpcs ))
+				{
+				print OUTPUT "\t$startIpcs,\t\t//range is $startIpcs-KMaxTInt\n";
+				}
+			else
+				{
+				print OUTPUT "\t$startIpcs,\t\t//range is $startIpcs\n";
+				}
+			}
+		$numOfRanges++;
+		$startRange = $endRange + 1;
+		$i++;
+		} # for each range of IPCs
+
+	if(!($customCheckOn == 1))
+		{
+		print OUTPUT "\t$startRange,\t\t//range is $startRange-KMaxTInt inclusive\n";
+		$numOfRanges++;
+		}
+	print OUTPUT "\t};\n";
+
+	print OUTPUT "\nconst TUint iRangeCount = $numOfRanges;\n";
+
+	# Number the policies in the order they will be placed in the server's const static array
+	my $ii = 0;
+	# Sort the policies table for later printing into an array
+	foreach (sort keys %policies)
+		{
+		# Ensure array indicies are given correctly to all policies.
+		$policies{$_} = $ii++;
+		}
+
+	print OUTPUT "\n\nconst TUint8 iElementsIndex[] = \n\t{\n";
+	$startRange=0;
+	$i=0;
+
+	for $startIpc (@range_starts)
+		{
+		if($startRange != $startIpc)
+			{
+			$endRange = $startIpc-1;
+			print OUTPUT "\tCPolicyServer::ENotSupported,\n"; # range not covered by API policing
+			$numOfRanges++;
+			}
+
+		if(($ipc_table{$startIpc} =~ /CustomCheckSingle/))
+			{
+			print OUTPUT "\tCPolicyServer::ECustomCheck,\n"; # range to be custom checked
+			}
+		elsif(!($ipc_table{$startIpc} =~ /CustomCheck/))
+			{
+			print OUTPUT "\t$policies{$ipc_table{$startIpc}},\n";
+			}
+		else
+			{
+			print OUTPUT "\tCPolicyServer::ECustomCheck,\n"; # range to be custom checked
+			}
+
+		$endRange = $startIpc + $range_sizes[$i]-1;
+		$startRange=$endRange+1;
+		$i++;
+		} # For each range print link to policy table
+
+	if( !($customCheckOn == 1) )
+		{
+		print OUTPUT "\tCPolicyServer::ENotSupported,\n";  # last range - up to KIntMax
+		}
+	print OUTPUT "\t};\n";
+
+	print OUTPUT "\n\nconst CPolicyServer::TPolicyElement iElements[] = \n\t{\n";
+	$startRange = 0;
+	$currentRange = 0;
+	$range_id = 0;
+
+	foreach (sort keys %policies)
+		{
+		my @capsArray = split ('\s+', $_);
+		my $numberCaps=scalar @capsArray-1;
+
+		print OUTPUT "\t{ _INIT_SECURITY_POLICY_C$numberCaps( ";
+		for (my $i = 1; $i < $numberCaps; $i++) # Should start at zero, but would need to change lines 283-286 first; i.e. get rid of space at beginning of $capsArray[i].
+			{
+			if($capsArray[$i] =~ /None/)
+				{
+				print OUTPUT "ECapability_$capsArray[$i], ";
+				}
+			else
+				{
+				print OUTPUT "ECapability$capsArray[$i], ";
+				}
+			} # foreach capability, output a security caps flag
+
+		if($capsArray[$numberCaps] =~ /None/)
+			{
+			print OUTPUT "ECapability_$capsArray[$numberCaps])";
+			}
+		else
+			{
+			print OUTPUT "ECapability$capsArray[$numberCaps])";
+			}
+
+		print OUTPUT ", CPolicyServer::EFailClient},\n";
+		}
+
+	print OUTPUT "\t};\n";
+
+	print OUTPUT "\n\nconst CPolicyServer::TPolicy iPolicy = \n\t{\n";
+	print OUTPUT "\tCPolicyServer::EAlwaysPass,\n";
+	print OUTPUT "\tiRangeCount,\n";
+	print OUTPUT "\tiRanges,\n";
+	print OUTPUT "\tiElementsIndex,\n";
+	print OUTPUT "\tiElements\n";
+	print OUTPUT "\t};\n";
+	close(OUTPUT);
+	}
+else
+	{
+	die "Bad arguments !";
+	}