--- /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 !";
+ }