--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/networksecurity/ipsec/ipsecpol/src/ipsecpolmanhandler.cpp Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,2163 @@
+// 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:
+// IPSecPolicyManagerHandler.cpp - IPSec Policy Manager Handler
+//
+
+#include <es_sock.h>
+#include <in_sock.h>
+#include <es_ini.h>
+
+#include "ipsecpolmanhandler.h"
+#include "algorithmconf.h"
+#include "ipsecpolmanserver.h"
+#include "ipsecpolmansession.h"
+#include "ipsecpolapi.h"
+#include "ipsecpol.h"
+#include "log_ipsecpol.H"
+#include "ipsecpolparser.h"
+#include "secpolreader.h"
+
+#define FIRST_ARGUMENT 0
+#define SECOND_ARGUMENT 1
+#define THIRD_ARGUMENT 2
+#define FOURTH_ARGUMENT 3
+
+//
+// Create IPSecPolicyManagerHandler object
+//
+CIPSecPolicyManagerHandler*
+CIPSecPolicyManagerHandler::NewL(CIPSecPolicyManagerServer*)
+ {
+ LOG(Log::Printf(_L("Constructing IPSecPolManHandler\n")));
+
+ CIPSecPolicyManagerHandler* self =
+ new (ELeave) CIPSecPolicyManagerHandler();
+
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+//
+// Phase 2 constructor
+//
+void
+CIPSecPolicyManagerHandler::ConstructL()
+ {
+ User::LeaveIfError(iFs.Connect());
+ User::LeaveIfError(iSS.Connect());
+
+ iActivePolicyList = new (ELeave) CActivePolicyList(1);
+
+ iIsPreloadNeeded = EFalse;
+
+ iPreloadPolicyHandle.iHandle = 0;
+
+
+#ifdef TESTFLAG
+
+ iStringBuf = NULL;
+
+#endif
+
+ ReadAlgorithmsFileL();
+ iSelectorInfoArray = new (ELeave) CArrayFixFlat<TIpsecSelectorInfo> (2);
+
+ }
+
+//
+// Destructor
+//
+CIPSecPolicyManagerHandler::~CIPSecPolicyManagerHandler()
+ {
+ LOG(Log::Printf(_L("Destructing IPSecPolManHandler\n")));
+
+ // Unload the autoload policy if the load method is Preload,
+ if (iPreloadPolicyHandle.iHandle > 0)
+ {
+ TRAPD(leaveCode,
+ UnloadPolicyByHandleL(iPreloadPolicyHandle.iHandle, NULL));
+
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("Unload autoload policy failed\n")));
+ }
+ }
+
+ // Corrected code
+ if (iActivePolicyList)
+ {
+ // Deletes all the items in the list
+ for (TInt i = iActivePolicyList->Count() - 1; i >= 0; i--)
+ {
+
+ if ( iActivePolicyList->At(i) != NULL )
+ {
+ // Unloads still active policies
+ TRAPD(leaveCode,
+ UnloadPolicyByHandleL(iActivePolicyList->At(i)->iPolicyHandle.iHandle, NULL));
+
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("Unload autoload policy failed\n")));
+ }
+
+ }
+ }
+
+ delete iActivePolicyList;
+ iActivePolicyList = NULL;
+ }
+
+ delete iSecpolReader6;
+ iSecpolReader6 = NULL;
+
+ delete iLastConflictInfo;
+ iLastConflictInfo = NULL;
+
+ delete iLastParsingErrorInfo;
+ iLastParsingErrorInfo = NULL;
+
+ delete iAlgorithmsHBufC8;
+ iAlgorithmsHBufC8 = NULL;
+
+ delete iPreloadPolicy;
+ iPreloadPolicy = NULL;
+
+ delete iBeforeManualLoadPolicy;
+ iBeforeManualLoadPolicy = NULL;
+
+ delete iAfterManualLoadPolicy;
+ iAfterManualLoadPolicy = NULL;
+
+ delete iBeforeScopedLoadPolicy;
+ iBeforeScopedLoadPolicy = NULL;
+
+ delete iAfterScopedLoadPolicy;
+ iAfterScopedLoadPolicy = NULL;
+
+#ifdef TESTFLAG
+
+ delete iStringBuf;
+ iStringBuf = NULL;
+
+#endif
+
+ // Release scoped autoload policy array
+ for (TInt i = iScopedAutoloadPolicyPairs.Count() - 1; i >= 0; i--)
+ {
+ delete iScopedAutoloadPolicyPairs[i];
+ iScopedAutoloadPolicyPairs.Remove(i);
+ }
+
+ // Close array to avoid memory leaks
+ iScopedAutoloadPolicyPairs.Close();
+
+ ReleaseResources();
+
+ iFs.Close();
+ iSS.Close();
+
+ delete iSelectorInfoArray;
+ iSelectorInfoArray = NULL;
+ }
+
+//
+// Release resources allocated for a call
+//
+void
+CIPSecPolicyManagerHandler::ReleaseResources()
+ {
+ delete iPieceData;
+ iPieceData = NULL;
+
+ delete iPieceData2;
+ iPieceData2 = NULL;
+
+ delete iSAInfo;
+ iSAInfo = NULL;
+
+ delete iSelectorInfo;
+ iSelectorInfo = NULL;
+
+ delete iPolicyHBufC8;
+ iPolicyHBufC8 = NULL;
+
+ delete iPolBfr;
+ iPolBfr = NULL;
+
+#ifdef TESTFLAG
+
+ delete iHandles;
+ iHandles = NULL;
+
+#endif
+
+ if (iSecpolSocketOpen)
+ {
+ iSecpolSocketOpen = EFalse;
+ iSock.Close();
+ }
+
+ if (iAlgorithmsFileOpen)
+ {
+ iAlgorithmsFileOpen = EFalse;
+ iAlgFile.Close();
+ }
+ }
+
+//
+// ErrorHandling - Leave is trapped by server's RunError()
+//
+void
+CIPSecPolicyManagerHandler::ErrorHandlingL(
+ TInt aMainCode,
+ TInt aDetailCode)
+ {
+ LOG(Log::Printf(_L("ErrorHandling: main status: %d detail status: %d\n"),
+ aMainCode, aDetailCode));
+#ifndef __FLOG_ACTIVE
+ (void)aDetailCode;
+#endif
+
+ User::Leave(aMainCode);
+ }
+
+//
+//
+// ProcessLoadPolicy - Process a LoadPolicy request issued
+// by IPSecPolicyManApi
+//
+//
+TInt
+CIPSecPolicyManagerHandler::ProcessLoadPolicyL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* /* aIPSecPolicyManagerSession */,
+ TPolicyType aPolType)
+ {
+ // Retrieve arguments
+
+ // (1): Policy data buffer length
+ TInt policyDataLth = aMsg.GetDesLengthL(FIRST_ARGUMENT);
+
+ // (2): Policy data buffer contents
+ delete iPolicyHBufC8;
+ iPolicyHBufC8 = NULL;
+ iPolicyHBufC8 = HBufC8::NewL(policyDataLth);
+ TPtr8 policyDataDesc(iPolicyHBufC8->Des());
+ aMsg.ReadL(FIRST_ARGUMENT, policyDataDesc);
+
+ // (3): Zone info (optional)
+ TZoneInfoSet zoneInfoSet;
+ if (aMsg.GetDesLength(THIRD_ARGUMENT) <= 0)
+ {
+ zoneInfoSet = KDefaultZoneInfo;
+ iFunction = 0;
+ }
+ else
+ {
+ iFunction = aMsg.Int3();
+ TPckg<TZoneInfoSet>pckgZoneInfoSet(zoneInfoSet);
+ aMsg.ReadL(THIRD_ARGUMENT, pckgZoneInfoSet);
+ }
+ iVPNNetId = 0;
+ if (zoneInfoSet.iSelectorZone.iScope != KScopeNone)
+ {
+ iVPNNetId = zoneInfoSet.iSelectorZone.iId;
+ }
+ iGwNetId = 0;
+ if (zoneInfoSet.iEndPointZone.iScope != KScopeNone)
+ {
+ iGwNetId = zoneInfoSet.iEndPointZone.iId;
+ }
+ LOG(Log::Printf(_L("LoadPolicy request VPN NetId: %d GW NetId: %d\n"),
+ iVPNNetId, iGwNetId));
+
+
+ // Parse the policy file from string format to the ipsecpolparser
+ // class object format
+ ParseCurrentPolicyL();
+
+ // Calculate the Bypass/Drop mode of parsed policy
+ TInt policyBypassDropMode(KDropMode);
+ CSecurityPolicy* policy = iPieceData->Policies();
+ policyBypassDropMode = CalculatePolicyBypassDropMode(*policy);
+
+ // Check if we have a direct Bypass-everything-else Vs Drop-everything-else conflict between the active policy and
+ // the one that is attempted to be loaded. If so, return with error
+
+ TInt activepolicyBypassDropMode;
+ //coverity[var_compare_op]
+ //intentional null comparision if there is no policylist do nothing.
+ if (iActivePolicyList && iActivePolicyList->Count())
+ {
+ //coverity[var_compare_op]
+ // It is ok to compare with the first active policy. Every subsequent policy would have been compared against the first one
+ activepolicyBypassDropMode = iActivePolicyList->At(0)->iBypassOrDropMode;
+ if((policyBypassDropMode == KDropMode && (( activepolicyBypassDropMode & KInboundBypass) || (activepolicyBypassDropMode & KOutboundBypass))) ||
+ (((policyBypassDropMode & KInboundBypass) || (policyBypassDropMode & KOutboundBypass)) && activepolicyBypassDropMode == KDropMode ))
+ {
+ ErrorHandlingL (ESelectorConflict,0);
+ }
+ }
+
+ // Add VPNNetId to CPolicySelector and GwNetId to CSecpolBundleItem objects
+ UpdateSelectorsAndTunnels();
+
+ // Check if the IP addresses in the selectors of current policy
+ // file overlaps with the selectors of the policies in the active
+ // policy list. Overlapping is allowed when the scope IDs differ
+ // or all parameters in the selectors and corresponding SA
+ // match exactly.
+ CheckSelectorConflictsL();
+
+ // Modify the SA names to avoid conflicts caused by equal names
+ // in different policies
+ MakeUniqueSANamesL();
+
+ // Convert object format policy pieces to string format
+ // and do the operations defined by the API flags
+ ConvertFromObjectsToStringWithSectionsL(iFunction,
+ policyBypassDropMode);
+
+ // Store current policy entry to active policy list
+ StorePolicyToActiveListL(aPolType, policyBypassDropMode);
+ LOG(Log::Printf(_L("LoadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // Return the current policy file handle to the API user
+ ReturnPolicyFileHandleL(aMsg);
+
+ // An API call completed
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+//
+// ProcessLoadPoliciesL - Process a LoadPolicy request issued
+// by IPSecPolicyManApi. This method considers autoload policies as well
+//
+//
+TInt
+CIPSecPolicyManagerHandler::ProcessLoadPoliciesL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* aSession)
+ {
+ // Read scope information
+ TBool scopedLoad = EFalse;
+ TInt preLoadHandle(0);
+ TInt postLoadHandle(0);
+ TInt parentPolicyHandle(0);
+ TInt leaveCode(0);
+
+ TZoneInfoSet zoneInfoSet;
+ if (aMsg.GetDesLength(THIRD_ARGUMENT) <= 0) // Use default zoneInfo
+ {
+ zoneInfoSet = KDefaultZoneInfo;
+
+ // Processing flags
+ iFunction = 0;
+ }
+ else
+ {
+ scopedLoad = ETrue;
+ iFunction = aMsg.Int3();
+ TPckg<TZoneInfoSet>pckgZoneInfoSet(zoneInfoSet);
+ aMsg.ReadL(THIRD_ARGUMENT, pckgZoneInfoSet);
+ }
+ iVPNNetId = 0;
+ if (zoneInfoSet.iSelectorZone.iScope != KScopeNone)
+ {
+ iVPNNetId = zoneInfoSet.iSelectorZone.iId;
+ }
+ iGwNetId = 0;
+ if (zoneInfoSet.iEndPointZone.iScope != KScopeNone)
+ {
+ iGwNetId = zoneInfoSet.iEndPointZone.iId;
+ }
+
+ LOG(Log::Printf(_L("LoadPolicy request VPN NetId: %d GW NetId: %d\n"),
+ iVPNNetId, iGwNetId));
+
+ if (scopedLoad)
+ {
+ // Load BeforescopedLoadPolicies before
+ if (iBeforeScopedLoadPolicy->Size() != 0)
+ {
+ TRAP(leaveCode,
+ AutoloadPoliciesL(zoneInfoSet,
+ iBeforeScopedLoadPolicy,
+ EAutoloadBeforeScopedLoad));
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"),
+ aMsg.Int0()));
+ }
+ else
+ {
+ preLoadHandle = iCurrentPolicyHandle.iHandle;
+ }
+ }
+
+ // Load the policy itself
+ ProcessLoadPolicyL(aMsg, aSession, EScopedManualLoad);
+ parentPolicyHandle = iCurrentPolicyHandle.iHandle;
+
+ // Load BeforescopedLoadPolicies before
+ if (iAfterScopedLoadPolicy->Size() != 0 )
+ {
+ TRAP(leaveCode,
+ AutoloadPoliciesL(zoneInfoSet,
+ iAfterScopedLoadPolicy,
+ EAutoloadAfterScopedLoad));
+
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"),
+ aMsg.Int0()));
+ }
+ else
+ {
+ postLoadHandle = iCurrentPolicyHandle.iHandle;
+ }
+ }
+
+ if (parentPolicyHandle != 0
+ && (preLoadHandle != 0 || postLoadHandle != 0))
+ {
+ // Add the policy hadle pair to an 'unload list'
+ AddScopedAutoloadPolicyPairL(preLoadHandle,
+ postLoadHandle,
+ parentPolicyHandle);
+ }
+ }
+ else
+ {
+ // In case of manual load
+ if (iManualAutoloadHandlePair.iManualPreloadHandle.iHandle == 0
+ && iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle == 0)
+ {
+ // Load BeforescopedLoadPolicies before
+ if (iBeforeManualLoadPolicy->Size() != 0)
+ {
+ TRAP(leaveCode,
+ AutoloadPoliciesL(zoneInfoSet,
+ iBeforeManualLoadPolicy,
+ EAutoloadBeforeManualLoad));
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"),
+ aMsg.Int0() ));
+ }
+ else
+ {
+ iManualAutoloadHandlePair.iManualPreloadHandle.iHandle =
+ iCurrentPolicyHandle.iHandle;
+ }
+ }
+
+ // Load the policy itself
+ ProcessLoadPolicyL(aMsg, aSession, EManualLoad);
+
+ // Load AfterManualLoadPolicies
+ if (iAfterManualLoadPolicy->Size() != 0)
+ {
+ TRAP(leaveCode,
+ AutoloadPoliciesL(zoneInfoSet,
+ iAfterManualLoadPolicy,
+ EAutoloadAfterManualLoad));
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("Autoload failed for parent policy: %d\n"),
+ aMsg.Int0() ));
+ }
+ else
+ {
+ iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle =
+ iCurrentPolicyHandle.iHandle;
+ }
+ }
+ }
+ else
+ {
+ // Load the policy itself
+ ProcessLoadPolicyL(aMsg, aSession, EManualLoad);
+ }
+
+ }
+
+ return KErrNone;
+ }
+
+//
+//
+// ProcessActivatePolicy - Process an ActivatePolicy request issued
+// by IPSecPolicyManApi
+//
+//
+TInt
+CIPSecPolicyManagerHandler::ProcessActivatePolicyL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession)
+ {
+ // Store the parameters to this object
+ iSession = aIPSecPolicyManagerSession;
+ iCurrentPolicyHandle.iHandle = aMsg.Int0();
+
+ LOG(Log::Printf(_L("ActivatePolicy request, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // Search from the active policy list the policy corresponding
+ // to the current policy handle and activate it
+ TInt ret = SearchPolicyFromListAndActivate();
+ if (ret != KErrNone)
+ {
+ ErrorHandlingL(ret, 0 );
+ }
+
+ // Parse all active policy files from string format
+ // to IPSecPolParser class object formats
+ ParseAllPolicyFilesL();
+
+ // Calculate the combined policy Bypass/Drop mode
+ CalculateCombinedPolicyBypassDropMode();
+
+ // Delete all pure Inbound/Ooutbound selectors
+ DeleteExtraInboundOutboundSelectors();
+
+ // Update the policy selectors by building a comparison word
+ // and setting a sequence number. IpsecPolParser uses them.
+ SortSelectors();
+
+ // Convert object format policy pieces to string format.
+ // This format is used by IPSec protocol component.
+ ConvertFromObjectsToStringWithoutSectionsL();
+
+ // Add an Inbound/outbound selector pair to the end of string format
+ // policy file. This occurs only when the bypass mode is defined.
+ TInt err = AddInboundOutboundSelectorPair();
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+
+ // Send the algorithms table and the string format policy file to
+ // IPSec protocol component using Secpol socket
+ SendAlgorithmsAndPolicyToIPSecL(_L("secpol6"));
+
+ LOG(Log::Printf(_L("ActivatePolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // An API call completed
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+//
+// ProcessActivateAutoloadPolicy - Process an ActivatePolicy request issued
+// by IPSecPolicyManApi
+//
+//
+TInt
+CIPSecPolicyManagerHandler::ProcessActivateAutoloadPolicyL(
+ const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession)
+ {
+ // Store the parameters to this object
+ iSession = aIPSecPolicyManagerSession;
+
+ LOG(Log::Printf(_L("ActivateAutoloadPolicy request, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // Search from the active policy list the policy corresponding
+ // to the current policy handle and activate it
+ TInt ret = SearchPolicyFromListAndActivate();
+ if (ret != KErrNone)
+ {
+ ErrorHandlingL(ret, 0 );
+ }
+
+ // Parse all active policy files from string format
+ // to IPSecPolParser class object formats
+ ParseAllPolicyFilesL();
+
+ // Calculate the combined policy Bypass/Drop mode
+ CalculateCombinedPolicyBypassDropMode();
+
+ // Delete all pure Inbound/Ooutbound selectors
+ DeleteExtraInboundOutboundSelectors();
+
+ // Update the policy selectors by building a comparison word
+ // and setting a sequence number. IpsecPolParser uses them.
+ SortSelectors();
+
+ // Convert object format policy pieces to string format.
+ // This format is used by IPSec protocol component.
+ ConvertFromObjectsToStringWithoutSectionsL();
+
+ // Add an Inbound/outbound selector pair to the end of string format
+ // policy file. This occurs only when the bypass mode is defined.
+ TInt err = AddInboundOutboundSelectorPair();
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+
+ // Send the algorithms table and the string format policy file to
+ // IPSec protocol component using Secpol socket
+ SendAlgorithmsAndPolicyToIPSecL(_L("secpol6"));
+
+ LOG(Log::Printf(_L("ActivateAutoloadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // An API call completed
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+
+//
+// Process UnloadPolicy - Process an UnloadPolicy request issued
+// by IPSecPolicyManApi
+//
+TInt
+CIPSecPolicyManagerHandler::ProcessUnloadPolicyL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession)
+ {
+ // Store the parameters to this object
+ iSession = aIPSecPolicyManagerSession;
+
+ iCurrentPolicyHandle.iHandle = aMsg.Int0();
+ LOG(Log::Printf(_L("UnloadPolicy request, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // Search from the active policy list the policy corresponding
+ // to the current policy handle and delete it
+ TInt ret = DeletePolicyFromList();
+ if (ret != KErrNone)
+ {
+ ErrorHandlingL(ret, 0 );
+ }
+
+ // Send BypassAll file to the IPSec protocol component if
+ // the deleted policy was the last one
+ if (iActivePolicyList->Count() == 0)
+ {
+ SendNullFileToIPSecL(_L("secpol6"));
+ LOG(Log::Printf(_L("Last policy deleted\n")));
+ LOG(Log::Printf(_L("UnLoadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // An API call completed
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+ // Parse all active policy files from string format
+ // to IPSecPolParser class object formats
+ ParseAllPolicyFilesL();
+
+ // Calculate whether it's drop or bypass mode to be used
+ CalculateCombinedPolicyBypassDropMode();
+
+ // Delete pure Inbound/Outbound selectors
+ DeleteExtraInboundOutboundSelectors();
+
+ // Update the policy selectors by building a comparison word
+ // and setting a sequence number
+ SortSelectors();
+
+ // Convert object format policy pieces to string format.
+ // This format is used by IPSec protocol component.
+ ConvertFromObjectsToStringWithoutSectionsL();
+
+ // Add an Inbound/outbound selector pair to the end of string format
+ // policy file. This occurs only when the bypass mode is defined.
+ TInt err = AddInboundOutboundSelectorPair();
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+
+ // Send the algorithms table and the string format policy file to
+ // IPSec protocol component using Secpol socket
+ SendAlgorithmsAndPolicyToIPSecL(_L("secpol6"));
+
+ // An API call completed
+ LOG(Log::Printf(_L("UnloadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+// Convert the object format policy pieces to string format
+// and do the operations defined by the function code.
+// Section Data, for example, [POLICY], is included
+//
+void
+CIPSecPolicyManagerHandler::ConvertFromObjectsToStringWithSectionsL(
+ TInt aFunction,
+ TInt aBypassDropMode)
+ {
+ // Constant for adding Mip4 bypass selectors to the policy
+ // TODO:
+ // This constant should be defined in Policy Manager API
+ // header files
+ const TInt KAddMip4BypassSelectors = (1 << 3);
+
+ // Allocate a buffer for string format policy
+ delete iPolBfr;
+ iPolBfr = NULL;
+ iPolBfr = HBufC8::NewL(KPolicyBufferSizeIncrement);
+
+ // Convert and write policy data to a policy buffer
+ TInt err = TIpSecParser::Write(iPieceData, iPolBfr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+
+ // Check if given policy contains 'drop_everything_else' rule
+ // and add IKE, DHCP and MIPv4 bypass selectors if necessary
+ if (aBypassDropMode == KDropMode)
+ {
+ // Allow plain IKE negotiation packets. Write the bypass
+ // selectors to the end of selector list, but they will
+ // later be sorted to the beginning of selectors.
+ if (aFunction & KAddIkeBypassSelectors)
+ {
+ TInt err = WriteTunnelModeIkeNegotiationStringsL(iPolBfr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+
+ err = WriteTransportModeIkeNegotiationStrings(iPolBfr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+ }
+
+ // Allow plain DHCP negotiation packets. Write bypass mode
+ // selectors for DHCP ports (67, 68) to the end of selector list.
+ if (aFunction & KAddDhcpBypassSelectors)
+ {
+ TInt err = BuildDhcpProtocolString(iPolBfr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+ }
+
+ // Allow plain MIPv4 (Mobile IP v4) packets. Write bypass mode
+ // selectors for MIPv4 to the end of selector list.
+ if (aFunction & KAddMip4BypassSelectors)
+ {
+ TInt err = BuildMip4BypassSelectors(iPolBfr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+ }
+ }
+ }
+
+//
+// Convert object format policy pieces to string format.
+// Section Data is not included
+//
+void
+CIPSecPolicyManagerHandler::ConvertFromObjectsToStringWithoutSectionsL()
+ {
+ // Allocate a buffer for string format policy
+ delete iPolBfr;
+ iPolBfr = NULL;
+ iPolBfr = HBufC8::NewL(KPolicyBufferSizeIncrement);
+
+ // Convert and write policy data to a policy buffer
+ TInt err = TPolicyParser::Write(iPieceData->Policies(), iPolBfr, ETrue);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+ }
+
+//
+// Store a policy entry to the policy list
+//
+void
+CIPSecPolicyManagerHandler::StorePolicyToActiveListL(
+ TPolicyType aPolType,
+ TInt aBypassOrDropMode)
+ {
+ // Take the next policy file handle
+ iNextPolicyHandle.iHandle++;
+ iCurrentPolicyHandle.iHandle = iNextPolicyHandle.iHandle;
+
+ // Update an active policy entry
+ TActivePolicyListEntry* entry = new (ELeave) TActivePolicyListEntry;
+ CleanupStack::PushL(entry);
+ entry->iActiveState = EFalse;
+ entry->iBypassOrDropMode = aBypassOrDropMode;
+ entry->iPolicyHandle.iHandle = iCurrentPolicyHandle.iHandle;
+ entry->iPolicyBuf = iPolBfr;
+ entry->iPolicyType = aPolType;
+ iPolBfr = NULL;
+ CleanupStack::PushL(entry->iPolicyBuf);
+
+ // Store a new entry to active policy list
+ iActivePolicyList->AppendL(entry);
+ CleanupStack::Pop(2);
+ }
+
+//
+// Parse all active policy files from string format
+// to IPSecPolParser class object format
+//
+void
+CIPSecPolicyManagerHandler::ParseAllPolicyFilesL()
+ {
+ delete iPieceData;
+ iPieceData = NULL;
+ iPieceData = new (ELeave) CIpSecurityPiece;
+ iPieceData->ConstructL();
+
+ for (TInt i = 0; i < iActivePolicyList->Count(); i++)
+ {
+ // Check if policy activated
+ if (iActivePolicyList->At(i)->iActiveState == EFalse)
+ {
+ continue;
+ }
+
+ // Store policy to IPSecPolParser
+ HBufC8* policyHBufC8 = iActivePolicyList->At(i)->iPolicyBuf;
+
+ // Copy policy to 16bit buffer
+ TPtr8 ptr8(policyHBufC8->Des());
+ TInt length = ptr8.Length();
+ HBufC *policyDataHBufC16 = HBufC::NewL(length);
+ CleanupStack::PushL(policyDataHBufC16);
+ TPtr ptr(policyDataHBufC16->Des());
+
+ // Parse policy into binary object format
+ ptr.Copy(ptr8);
+ TIpSecParser parser(ptr);
+ TInt err = parser.ParseAndIgnoreIKEL(iPieceData);
+
+ // Delete policyDataHBufC16;
+ CleanupStack::PopAndDestroy();
+
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(EParsingError, err);
+ }
+ }
+ }
+
+//
+// Sort the selectors in the following sequence:
+// -- Port 500 or 4500 is defined for selector
+// -- Port 67 or 68 is defined
+// -- All other selectors are in original order
+//
+void
+CIPSecPolicyManagerHandler::SortSelectors()
+ {
+ CSecurityPolicy* sp = iPieceData->Policies();
+ CSelectorList* selectorList = sp->SelectorList();
+ BuildComparisonWord(selectorList);
+ SetSequenceNumbers(selectorList);
+ }
+
+//
+// Send the algorithms file and string format policy file to
+// IPSec protocol component using Secpol socket
+//
+void
+CIPSecPolicyManagerHandler::SendAlgorithmsAndPolicyToIPSecL(
+ const TDesC &aSocket)
+ {
+ TInt err(KErrNone);
+ TInt algSize(0), polSize(0), sendBuf(0), octetSize(0);
+
+ TInetAddr addr;
+ TRequestStatus stat;
+
+ // Open Secpol socket
+ err = iSock.Open(iSS, aSocket);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(EOpenSocketError, err);
+ }
+ iSecpolSocketOpen = ETrue;
+
+ // Bind to socket
+ addr.SetAddress(KInetAddrNone);
+ addr.SetPort(0);
+ err = iSock.Bind(addr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(EBindSocketError, err);
+ }
+ iSock.LocalName(addr);
+
+
+ // Get algorithm table size and police file size
+ if (iAlgorithmsHBufC8 != NULL)
+ {
+ algSize = iAlgorithmsHBufC8->Length();
+ }
+ polSize = iPolBfr->Des().Length();
+
+ // Allocate a buffer for the algorithms data and policy data
+ HBufC8 *buf = HBufC8::NewLC(algSize + polSize); // Both files
+ TPtr8 algPtr((TUint8 *)buf->Ptr(), algSize, algSize);
+ TPtr8 polPtr((TUint8 *)buf->Ptr() + algSize, polSize, polSize);
+
+ if (iAlgorithmsHBufC8 != NULL)
+ {
+ algPtr.Copy(*iAlgorithmsHBufC8);
+ }
+
+ // Store the policy buffer data after algorithm data
+ // and free the policy buffer
+ polPtr.Copy(iPolBfr->Des());
+ delete iPolBfr;
+ iPolBfr = NULL;
+
+ // Currently, the policy loading requires the policy data in a
+ // single contiguous buffer. If the socket buffer is less than
+ // policy file length, then increase the buffer size!
+
+ // *2 because _UNICODE
+ octetSize = 2 * (algSize + polSize);
+ sendBuf = -1;
+ err = iSock.GetOpt(KSOSendBuf, KSOLSocket, sendBuf);
+ if (sendBuf < octetSize)
+ {
+ err = iSock.SetOpt(KSOSendBuf, KSOLSocket, octetSize);
+ }
+ if (err != KErrNone)
+ {
+ // The buffer holding the 8-bit data in the file
+ CleanupStack::PopAndDestroy();
+ ErrorHandlingL(ESecpolSocketSetOptError, err);
+ }
+
+ // Set buffer address
+ HBufC *data = HBufC::NewL(algSize + polSize);
+ TPtr ptr16(data->Des());
+ TPtrC8 ptr((TUint8 *)buf->Ptr(), algSize + polSize);
+
+ // For debug
+ ptr16.Copy(ptr);
+
+#ifdef TESTFLAG
+
+ // TODO: Copy the concatenated string for testing purposes
+ delete iStringBuf;
+ iStringBuf = HBufC::NewL(algSize + polSize);
+ *iStringBuf = *data;
+
+#endif
+
+ // The buffer holding the 8-bit data in the file
+ CleanupStack::PopAndDestroy();
+
+ CleanupStack::PushL(data);
+ ptr.Set((TUint8 *)ptr16.Ptr(), ptr16.Size());
+
+ // Write the data over socket to IPSec protocol component
+ iSock.Write(ptr, stat);
+ User::WaitForRequest(stat);
+
+ // The buffer holding the data in the file
+ CleanupStack::PopAndDestroy();
+ if (stat.Int() != KErrNone)
+ {
+ ErrorHandlingL(EWriteSocketError, stat.Int());
+ }
+ iSock.Close();
+ iSecpolSocketOpen = EFalse;
+
+ // Start the SecpolReader object that reads the log messages
+ // sent by IPSec protocol component
+ if (!iSecpolReader6)
+ {
+ iSecpolReader6 = new (ELeave) CSecpolReader(this);
+ err = iSecpolReader6->Construct(_L("secpol6"));
+ if (err != KErrNone)
+ {
+ delete iSecpolReader6;
+ iSecpolReader6 = NULL;
+ ErrorHandlingL(ESecpolReaderError, err);
+ }
+ }
+ }
+
+//
+// Send a "Bypass All" policy to the IPSec protocol component using Secpol
+// socket. It indicates that IPSec accepts all packets.
+//
+void
+CIPSecPolicyManagerHandler::SendNullFileToIPSecL(const TDesC &aSocket)
+ {
+ TInt err(KErrNone);
+ TInetAddr addr;
+ TRequestStatus stat;
+ TInt algSize(0), polSize(0);
+
+ _LIT8 (KBypassAllString, " inbound = {}\n outbound = {}\n");
+ // Open Secpol socket
+ err = iSock.Open(iSS, aSocket);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(EOpenSocketError, err);
+ }
+ iSecpolSocketOpen = ETrue;
+
+ // Bind to socket
+ addr.SetAddress(KInetAddrNone);
+ addr.SetPort(0);
+ err = iSock.Bind(addr);
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(EBindSocketError, err);
+ }
+ iSock.LocalName(addr);
+
+ polSize = KBypassAllString().Length();
+ if (iAlgorithmsHBufC8 != NULL)
+ {
+ algSize = iAlgorithmsHBufC8->Des().Length();
+ }
+
+ // Both files
+ HBufC8* buf = HBufC8::NewLC(algSize + polSize);
+ TPtr8 algPtr((TUint8 *)buf->Ptr(), algSize, algSize);
+ TPtr8 polPtr((TUint8 *)buf->Ptr() + algSize, polSize, polSize);
+
+ if (iAlgorithmsHBufC8 != NULL)
+ {
+ algPtr.Copy(*iAlgorithmsHBufC8);
+ }
+
+ // Store the policy buffer data after algorithm data
+ // and free the policy buffer
+ polPtr.Copy(KBypassAllString);
+
+ // Allocate a buffer for the KBypassAllString
+ HBufC* data = HBufC::NewL(algSize + polSize);
+ TPtr ptr16(data->Des());
+ TPtrC8 ptr((TUint8 *)buf->Ptr(), algSize + polSize);
+
+ // For debug
+ ptr16.Copy(ptr);
+
+ // The buffer holding the 8-bit data in the file
+ CleanupStack::PopAndDestroy();
+
+ CleanupStack::PushL(data);
+ ptr.Set((TUint8 *)ptr16.Ptr(), ptr16.Size());
+
+ // Write the BypassAllString over socket to IPSec protocol component
+ iSock.Write(ptr, stat);
+ User::WaitForRequest(stat);
+
+ // The buffer holding the data in the file
+ CleanupStack::PopAndDestroy();
+ iSock.Close();
+ iSecpolSocketOpen = EFalse;
+ }
+
+//
+// Search from the active policy list the policy corresponding
+// to the current policy handle and delete it
+//
+TInt
+CIPSecPolicyManagerHandler::DeletePolicyFromList()
+ {
+ TInt count(iActivePolicyList->Count());
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iActivePolicyList->At(i)->iPolicyHandle.iHandle ==
+ iCurrentPolicyHandle.iHandle)
+ {
+ delete iActivePolicyList->At(i)->iPolicyBuf;
+ iActivePolicyList->At(i)->iPolicyBuf = NULL;
+ delete iActivePolicyList->At(i);
+ iActivePolicyList->Delete(i);
+ return KErrNone;
+ }
+ }
+ return (EUnknownPolicyHandle);
+ }
+
+//
+// Search from the active policy list the policy corresponding
+// to the current policy handle
+//
+TInt
+CIPSecPolicyManagerHandler::SearchPolicyFromListAndActivate()
+ {
+ TInt count(iActivePolicyList->Count());
+ for (TInt i = 0; i < count; i++)
+ {
+ if (iActivePolicyList->At(i)->iPolicyHandle.iHandle ==
+ iCurrentPolicyHandle.iHandle)
+ {
+ iActivePolicyList->At(i)->iActiveState = ETrue;
+ return KErrNone;
+ }
+ }
+ return (EUnknownPolicyHandle);
+ }
+
+//
+// Return the new Policy File Handle to the API user
+//
+void
+CIPSecPolicyManagerHandler::ReturnPolicyFileHandleL(
+ const RMessage2& aMsg)
+ {
+ TPckg<TPolicyHandle> pckgPolicyHandle(iCurrentPolicyHandle);
+ aMsg.WriteL(SECOND_ARGUMENT, pckgPolicyHandle);
+ }
+
+//
+// An API call completed
+//
+void
+CIPSecPolicyManagerHandler::ApiCallCompleted()
+ {
+ ReleaseResources();
+ }
+
+//
+// Read the autoload configuration data
+//
+void
+CIPSecPolicyManagerHandler::ReadAutoloadConfigDataL()
+ {
+ TBool findVar(EFalse);
+ TInt leaveCode(KErrNone);
+ TBuf<32> loadIndexBuf;
+
+ iPreloadPolicy = HBufC8::NewL(1);
+ iBeforeManualLoadPolicy = HBufC8::NewL(1);
+ iAfterManualLoadPolicy = HBufC8::NewL(1);
+ iBeforeScopedLoadPolicy = HBufC8::NewL(1);
+ iAfterScopedLoadPolicy = HBufC8::NewL(1);
+
+ // Open ini file
+ CESockIniData* preloadIniFile = NULL;
+
+ TRAP(leaveCode, preloadIniFile = CESockIniData::NewL(KPreloadFileName));
+ if (leaveCode != KErrNone)
+ {
+ return;
+ }
+
+ CleanupStack::PushL(preloadIniFile);
+
+ TPtrC fileName(NULL, 0);
+ TPtrC loadFlag(NULL, 0);
+
+ TInt index(0);
+ _LIT(KAutoloadEntry, "Autoload%d");
+
+ loadIndexBuf.Format(KAutoloadEntry, index);
+ while (preloadIniFile->FindVar(loadIndexBuf, KLoadFlag, loadFlag))
+ {
+ findVar = preloadIniFile->FindVar(loadIndexBuf, KFileName, fileName);
+ // If there is no such configuration information, no autoload takes place
+ if (!findVar)
+ {
+ goto forward;
+ }
+ findVar = preloadIniFile->FindVar(loadIndexBuf, KLoadFlag, loadFlag);
+ if (!findVar || (loadFlag == KAutoloadNone))
+ {
+ goto forward;
+ }
+
+ // Check the values of the autoload flag and read & store autoload
+ // policy file accordingly
+ if (loadFlag == KAutoloadPreload)
+ {
+ ReadNextAutoloadPolicyL(iPreloadPolicy, fileName);
+ iIsPreloadNeeded = ETrue;
+ }
+ if (loadFlag == KAutoloadBeforeManualLoad)
+ {
+ ReadNextAutoloadPolicyL(iBeforeManualLoadPolicy, fileName);
+ }
+ if (loadFlag == KAutoloadAfterManualLoad)
+ {
+ ReadNextAutoloadPolicyL(iAfterManualLoadPolicy, fileName);
+ }
+ if (loadFlag == KAutoloadBeforeScopedLoad)
+ {
+ ReadNextAutoloadPolicyL(iBeforeScopedLoadPolicy, fileName);
+ }
+ if (loadFlag == KAutoloadAfterScopedLoad)
+ {
+ ReadNextAutoloadPolicyL(iAfterScopedLoadPolicy, fileName);
+ }
+
+ forward:
+ index++;
+ loadIndexBuf.Format(KAutoloadEntry, index);
+ }
+
+ // Ini file closed
+ CleanupStack::PopAndDestroy(preloadIniFile);
+ }
+
+//
+// read the next autoload policy file
+//
+void
+CIPSecPolicyManagerHandler::ReadNextAutoloadPolicyL(
+ HBufC8*& aAutoloadPolicyBuffer,
+ TPtrC& aPolicyFileName)
+ {
+ RFile fileAutoload;
+ CleanupClosePushL(fileAutoload);
+ TInt err = fileAutoload.Open(iFs, aPolicyFileName, EFileRead);
+
+ if (err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(); // fileAutoload
+ return ;
+ }
+
+ TInt polSize;
+ err = fileAutoload.Size(polSize);
+
+ if (err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(); // fileAutoload
+ return ;
+ }
+
+ // Read current policy size
+ TInt currentPolSize = aAutoloadPolicyBuffer->Length();
+
+ // Create temporary buffer that will concatenate policies and push
+ // it to cleanup stack
+ HBufC8* tempFileBuf = HBufC8::NewLC(currentPolSize + polSize + 1);
+
+ // Store current policies to temp buf
+ *tempFileBuf = *aAutoloadPolicyBuffer;
+ TPtr8 policyPtr8((TUint8*)tempFileBuf->Ptr() + currentPolSize,
+ polSize,
+ polSize);
+
+ // Read new autoload polici data to the same temp buffer
+ err = fileAutoload.Read(policyPtr8);
+ if (err != KErrNone)
+ {
+ CleanupStack::PopAndDestroy(2); // tempFileBuf,fileAutoload
+ return ;
+ }
+
+ // Delete old policy buffer
+ delete aAutoloadPolicyBuffer;
+ aAutoloadPolicyBuffer = NULL;
+
+ // Create new policy buffer
+ aAutoloadPolicyBuffer = HBufC8::NewL(currentPolSize + polSize + 1);
+ TPtr8 policyBuf(aAutoloadPolicyBuffer->Des());
+
+ // Copy contents of concatenated buffer to new policy buffer
+ policyBuf.Copy( (TUint8*)tempFileBuf->Ptr() , currentPolSize + polSize);
+ policyBuf.ZeroTerminate();
+
+ // Delete temporary buffer and close policy file
+ CleanupStack::PopAndDestroy(2);
+ }
+
+//
+// Set the flag determining the autoload policy status
+//
+void
+CIPSecPolicyManagerHandler::SetAutoloadPolicyActive(
+ TBool aIsAutoloadPolicyActive)
+ {
+ iIsAutoloadPolicyActive = aIsAutoloadPolicyActive;
+ }
+
+//
+// Check is there is an active autoload policy
+//
+TBool
+CIPSecPolicyManagerHandler::IsAutoloadPolicyActive()
+ {
+ return iIsAutoloadPolicyActive;
+ }
+
+//
+// Perform the autoload for policies
+//
+void
+CIPSecPolicyManagerHandler::AutoloadPoliciesL(
+ const TZoneInfoSet& aZoneInfoSet,
+ HBufC8* aPolicyBuffer,
+ TAutoloadFlags aAutoloadType)
+ {
+ // Zone Info
+ iVPNNetId = 0;
+ if (aZoneInfoSet.iSelectorZone.iScope != KScopeNone)
+ {
+ iVPNNetId = aZoneInfoSet.iSelectorZone.iId;
+ }
+ iGwNetId = 0;
+ if (aZoneInfoSet.iEndPointZone.iScope != KScopeNone)
+ {
+ iGwNetId = aZoneInfoSet.iEndPointZone.iId;
+ }
+
+ LOG(Log::Printf(_L("LoadPolicy request VPN NetId: %d GW NetId: %d\n"),
+ iVPNNetId, iGwNetId));
+
+ // Autoload policies are loaded into a separate descriptor
+ if (aAutoloadType == EAutoloadPreload)
+ {
+ delete iPolicyHBufC8;
+ iPolicyHBufC8 = NULL;
+ iPolicyHBufC8 = HBufC8::NewL(iPreloadPolicy->Length());
+ TPtr8 autoloadPolicyDataDesc(iPolicyHBufC8->Des());
+ autoloadPolicyDataDesc.Copy(iPreloadPolicy->Des());
+ }
+ else
+ {
+ delete iPolicyHBufC8;
+ iPolicyHBufC8 = NULL;
+ iPolicyHBufC8 = HBufC8::NewL(aPolicyBuffer->Length());
+ TPtr8 autoloadPolicyDataDesc(iPolicyHBufC8->Des());
+ autoloadPolicyDataDesc.Copy(aPolicyBuffer->Des());
+ }
+
+ // Parse the policy file from string format to binary object format
+ ParseCurrentPolicyL();
+
+ // Calculate the Bypass/Drop mode of parsed policy
+ TInt policyBypassDropMode(KDropMode);
+ CSecurityPolicy* policy = iPieceData->Policies();
+ policyBypassDropMode = CalculatePolicyBypassDropMode(*policy);
+
+ // Add VPNNetId to CPolicySelector and GwNetId to CSecpolBundleItem objects
+ UpdateSelectorsAndTunnels();
+
+ // Check if the IP addresses in the selectors of current policy
+ // file overlaps with the selectors of the policies in the active
+ // policy list. Overlapping is allowed when the scope IDs differ
+ // or all parameters in the selectors and corresponding SA
+ // match exactly.
+ CheckSelectorConflictsL();
+
+ // Modify the SA names to avoid conflicts caused by equal names
+ // in different policies
+ MakeUniqueSANamesL();
+
+ // Convert object format policy pieces to string format
+ // and do the operations defined by the API flags
+ ConvertFromObjectsToStringWithSectionsL(iFunction,
+ policyBypassDropMode);
+
+ // Store current policy entry to active policy list
+ StorePolicyToActiveListL(EAutoload, policyBypassDropMode);
+ LOG(Log::Printf(_L("LoadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // An API call completed
+ ApiCallCompleted();
+
+ if (SearchPolicyFromListAndActivate() == KErrNone)
+ {
+ SetAutoloadPolicyActive(ETrue);
+ }
+ else
+ {
+ LOG(Log::Printf(_L("LoadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+ }
+ }
+
+//
+// Store the preload policy handle
+//
+void
+CIPSecPolicyManagerHandler::StorePreloadPolicyHandle()
+ {
+ iPreloadPolicyHandle.iHandle = iCurrentPolicyHandle.iHandle;
+
+ // Delete preload buffer because it's not needed anymore
+ delete iPreloadPolicy;
+ iPreloadPolicy = NULL;
+ }
+
+//
+// Find the associated autoload policy for a certain policy
+//
+CAutoloadListItem*
+CIPSecPolicyManagerHandler::FindScopedAutoloadPolicyPair(
+ TUint32 aParentPolicyHandle)
+ {
+ for (TInt i = 0; i < iScopedAutoloadPolicyPairs.Count(); i++)
+ {
+ if (iScopedAutoloadPolicyPairs[i]->GetParentPolicyHandle()
+ == aParentPolicyHandle)
+ {
+ return iScopedAutoloadPolicyPairs[i];
+ }
+ }
+
+ return NULL;
+ }
+
+//
+// Add the associated autoload policy pair for a certain policy
+//
+void
+CIPSecPolicyManagerHandler::AddScopedAutoloadPolicyPairL(
+ TUint32 aPreloadPolicyHandle,
+ TUint32 aPostloadPolicyHandle,
+ TUint32 aParentPolicyHandle)
+ {
+ CAutoloadListItem* autoloadListItem =
+ CAutoloadListItem::NewL(aPreloadPolicyHandle,
+ aPostloadPolicyHandle,
+ aParentPolicyHandle);
+
+ if (autoloadListItem != NULL)
+ {
+ iScopedAutoloadPolicyPairs.Append(autoloadListItem);
+ }
+ }
+
+//
+// Delete the associated autoload policy pair for a certain policy
+//
+void
+CIPSecPolicyManagerHandler::DeleteScopedAutoloadPolicyPair(
+ TUint32 aParentPolicyHandle)
+ {
+ for (TInt i = 0; i < iScopedAutoloadPolicyPairs.Count(); i++)
+ {
+ if (iScopedAutoloadPolicyPairs[i]->GetParentPolicyHandle()
+ == aParentPolicyHandle)
+ {
+ delete iScopedAutoloadPolicyPairs[i];
+ iScopedAutoloadPolicyPairs.Remove(i);
+ }
+ }
+ }
+
+//
+// read the algorithmsfile contents
+//
+void
+CIPSecPolicyManagerHandler::ReadAlgorithmsFileL()
+ {
+ RFile algFile;
+ TInt algSize(0);
+ CleanupClosePushL(algFile);
+ TInt err = algFile.Open(iFs, KAlgorithmFile, EFileRead);
+
+ delete iAlgorithmsHBufC8;
+ iAlgorithmsHBufC8 = NULL;
+
+ if (err == KErrNone)
+ {
+ err = algFile.Size(algSize);
+ iAlgorithmsHBufC8 = HBufC8::NewL(algSize);
+ TPtr8 algorithmsPtr8(iAlgorithmsHBufC8->Des());
+ algFile.Read(algorithmsPtr8);
+ }
+ else
+ {
+ algSize = KAlgorithmConf().Length();
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+ algSize += KNewAlgorithmConf().Length();
+#endif // SYMBIAN_IPSEC_VOIP_SUPPORT
+ iAlgorithmsHBufC8 = HBufC8::NewL(algSize);
+ TPtr8 algorithmsPtr8(iAlgorithmsHBufC8->Des());
+ algorithmsPtr8.Copy(KAlgorithmConf);
+#ifdef SYMBIAN_IPSEC_VOIP_SUPPORT
+ algorithmsPtr8.Append(KNewAlgorithmConf);
+#endif // SYMBIAN_IPSEC_VOIP_SUPPORT
+ }
+
+ CleanupStack::PopAndDestroy();
+ }
+
+TBool
+CIPSecPolicyManagerHandler::IsLastManualLoadPolicy(TUint32 aPolicyHandle)
+ {
+ for (TInt i = 0; i < iActivePolicyList->Count(); i++)
+ {
+ // If there are other manual load policies
+ if ((iActivePolicyList->At(i)->iPolicyType == EManualLoad) &&
+ iActivePolicyList->At(i)->iPolicyHandle.iHandle != aPolicyHandle)
+ {
+ return EFalse;
+ }
+ }
+ return ETrue;
+ }
+
+//
+// Process UnloadPolicy - Process an UnloadPolicy for the autoload policies
+// The policy is identified by the policy handle passed on as a parameter
+//
+TInt
+CIPSecPolicyManagerHandler::UnloadPolicyByHandleL(
+ TUint32 aPolicyHandle,
+ const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession)
+ {
+ // Store the parameters to this object
+ iSession = aIPSecPolicyManagerSession;
+ iCurrentPolicyHandle.iHandle = aPolicyHandle;
+ LOG(Log::Printf(_L("UnloadPolicy request, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // Search from the active policy list the policy corresponding
+ // to the current policy handle and delete it
+ TInt ret = DeletePolicyFromList();
+ if (ret != KErrNone)
+ {
+ ErrorHandlingL(ret, 0 );
+ }
+
+ // Send BypassAll file to the IPSec protocol component if
+ // the deleted policy was the last one
+ if (iActivePolicyList->Count() == 0)
+ {
+ SendNullFileToIPSecL(_L("secpol6"));
+ LOG(Log::Printf(_L("Last policy deleted\n")));
+ LOG(Log::Printf(_L("UnLoadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+
+ // An API call completed
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+ // Parse all active policy files from string format
+ // to IPSecPolParser class object formats
+ ParseAllPolicyFilesL();
+
+ // Calculate whether it's drop or bypass mode to be used
+ CalculateCombinedPolicyBypassDropMode();
+
+ // Delete all INBOUND/OUTBOUND selector pairs
+ DeleteExtraInboundOutboundSelectors();
+
+ // Update the policy selectors by building a comparison word
+ // and setting a sequence number
+ SortSelectors();
+
+ // Convert object format policy pieces to string format.
+ // This format is used by IPSec protocol component.
+ ConvertFromObjectsToStringWithoutSectionsL();
+
+ // Add an Inbound/outbound selector pair to the end of string format
+ // policy file. This occurs only when the bypass mode is defined.
+ TInt err = AddInboundOutboundSelectorPair();
+ if (err != KErrNone)
+ {
+ ErrorHandlingL(ENoMemory, err);
+ }
+
+ // Send the algorithms table and the string format policy file to
+ // IPSec protocol component using Secpol socket
+ SendAlgorithmsAndPolicyToIPSecL(_L("secpol6"));
+
+ // An API call completed
+ LOG(Log::Printf(_L("UnloadPolicy request completed OK, handle: %d\n"),
+ iCurrentPolicyHandle.iHandle));
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+// Process UnloadPolicy - Process an UnloadPolicy considering the autoload
+// policies. The policy is identified by the policy handle passed on in the
+// IPC message
+//
+TInt
+CIPSecPolicyManagerHandler::ProcessUnloadPoliciesL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* aIPSecPolicyManagerSession)
+ {
+ TInt err(KErrNone);
+ TInt preloadHandle(0), postLoadHandle(0);
+ TInt leaveCode(KErrNone);
+
+ // Find the autoload policy paired with this parent policy and unload it
+ CAutoloadListItem* autoLoadItem = FindScopedAutoloadPolicyPair(aMsg.Int0());
+
+ if (autoLoadItem != NULL)
+ {
+ err = ProcessUnloadPolicyL(aMsg, aIPSecPolicyManagerSession);
+
+ preloadHandle = autoLoadItem->GetPreloadPolicyHandle();
+ if (preloadHandle > 0)
+ {
+ TRAP(leaveCode, UnloadPolicyByHandleL(preloadHandle,
+ aIPSecPolicyManagerSession));
+
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"),
+ preloadHandle));
+ }
+ }
+
+ postLoadHandle = autoLoadItem->GetPostloadPolicyHandle();
+ if (postLoadHandle > 0)
+ {
+ TRAP(leaveCode, UnloadPolicyByHandleL(postLoadHandle,
+ aIPSecPolicyManagerSession));
+
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"),
+ postLoadHandle));
+ }
+ }
+
+ DeleteScopedAutoloadPolicyPair(aMsg.Int0());
+ }
+ else
+ {
+ // If this is the last unload for manual policies
+ if (IsLastManualLoadPolicy(aMsg.Int0()))
+ {
+ if (iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle != 0 )
+ {
+ TRAP(leaveCode,
+ UnloadPolicyByHandleL(iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle,
+ aIPSecPolicyManagerSession));
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"),
+ iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle));
+ }
+ iManualAutoloadHandlePair.iManualPostLoadHandle.iHandle = 0;
+ }
+
+ err = ProcessUnloadPolicyL(aMsg, aIPSecPolicyManagerSession);
+ if (iManualAutoloadHandlePair.iManualPreloadHandle.iHandle != 0 )
+ {
+ TRAP(leaveCode,
+ UnloadPolicyByHandleL(iManualAutoloadHandlePair.iManualPreloadHandle.iHandle,
+ aIPSecPolicyManagerSession));
+ if (leaveCode != KErrNone)
+ {
+ LOG(Log::Printf(_L("UnloadAutoloadPolicy failed for handle: %d\n"),
+ iManualAutoloadHandlePair.iManualPreloadHandle.iHandle));
+ }
+
+ iManualAutoloadHandlePair.iManualPreloadHandle.iHandle = 0;
+ }
+ }
+ else
+ {
+ err = ProcessUnloadPolicyL(aMsg, aIPSecPolicyManagerSession);
+ }
+ }
+
+ return err;
+ }
+
+//
+// GetIPSecSAInfo - Search a selector object and correponding SAs
+// and return the SA info data. The parameters in message
+// object are:
+// -- TIpsecSelectorInfo. Contains parameters used to
+// search the rigth selector object
+// -- TIpsecSaSpec in which the SA Info is to be
+// returned
+//
+//
+TInt
+CIPSecPolicyManagerHandler::GetIPSecSAInfoL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* /*aIPSecPolicyManagerSession*/)
+ {
+ LOG(Log::Printf(_L("MatchSelector (GetIPsecSaInfo) request\n")));
+
+ // Allocate buffer for TIpsecSelectorInfo object and read the object
+ // data from the client
+ delete iSelectorInfo;
+ iSelectorInfo = NULL;
+ iSelectorInfo = new(ELeave) TIpsecSelectorInfo;
+ TPckg<TIpsecSelectorInfo>pckgSelectorInfo(*iSelectorInfo);
+ aMsg.ReadL(FIRST_ARGUMENT , pckgSelectorInfo);
+
+ // Allocate buffer for TIPSecSAInfo object
+ delete iSAInfo;
+ iSAInfo = NULL;
+ iSAInfo = new(ELeave) TIpsecSaSpec;
+ TPckg<TIpsecSaSpec>pckgSaSpec(*iSAInfo);
+ iPckgSAInfo = &pckgSaSpec;
+
+ // Parse all active policy files from string format to IPSecPolParser
+ // class object format
+ ParseAllPolicyFilesL();
+ if (iActivePolicyList->Count() == 0)
+ {
+ ErrorHandlingL(ENoSelectorFound, 0);
+ }
+
+ // Find selector object that corresponds to the parameters
+ // in TIPSecSelectorInfo object
+ CPolicySelector* policySelector = FindMatchingSelector();
+ if (policySelector == NULL)
+ {
+ ErrorHandlingL(ENoSelectorFound, 0);
+ }
+
+ // Fill the TIPSecSAInfo object with the data of an SA
+ // (TSecurityAssocSpec)
+ FillSAInfoObject(policySelector, iSelectorInfo->iSaIndex);
+
+ // Write the SAInfo block to the client's address space
+ TPckg<TIpsecSaSpec> pckgSAInfoWrite(*iSAInfo);
+ aMsg.WriteL(SECOND_ARGUMENT, pckgSAInfoWrite);
+
+ // An API call completed
+ LOG(Log::Printf(_L("MatchSelector request completed OK\n")));
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+// GetLastConflictInfo (GetDebugInfo) - Returns information about
+// the policy that caused policy activation to fail.
+// ARG 0 = aDebugInfo buffer in API
+// ARG 1 = aInfoFlags
+// KConflictingPolicyInfo - Get the last conflict Info data
+// KParsingErrorInfo - Get the last parsing error data
+//
+//
+TInt
+CIPSecPolicyManagerHandler::GetLastConflictInfoL(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* /*aIPSecPolicyManagerSession*/)
+ {
+ TUint flags = aMsg.Int1();
+
+ //
+ // Check what info the API user is getting
+ //
+ HBufC8* infoBfr = NULL;
+ if (flags & KConflictingPolicyInfo)
+ {
+ infoBfr = iLastConflictInfo;
+ LOG(Log::Printf(_L("GetDebugInfo request, conflicting info requested\n")));
+ }
+ else if (flags & KParsingErrorInfo)
+ {
+ infoBfr = iLastParsingErrorInfo;
+ LOG(Log::Printf(_L("GetDebugInfo request, parsing error info requested\n")));
+ }
+
+ if (infoBfr != NULL)
+ {
+ // Copy info data to 16 bit buffer
+ TPtr8 ptr8(infoBfr->Des());
+ TInt length(ptr8.Length());
+
+ HBufC16* infoBfr16 = HBufC16::NewL(length + 1);
+ CleanupStack::PushL(infoBfr16);
+ TPtr16 ptr(infoBfr16->Des());
+ ptr.FillZ();
+ ptr.Copy(ptr8);
+ ptr.ZeroTerminate();
+
+ // Write the info buffer content to the client's address space
+ LOG(Log::Printf(_L("GetDebugInfo returned: %S\n"), &ptr));
+ aMsg.WriteL(FIRST_ARGUMENT, *infoBfr16);
+
+ // Release 16-bit info buffer
+ CleanupStack::PopAndDestroy(1);
+ }
+ else
+ {
+ ErrorHandlingL(ENoConflictInfoFound, 0);
+ }
+
+ // An API call completed
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+// Convert the policy content to object format using IPSecPolParser
+//
+//
+void
+CIPSecPolicyManagerHandler::ParseCurrentPolicyL()
+ {
+ delete iPieceData;
+ iPieceData = NULL;
+ iPieceData = new (ELeave) CIpSecurityPiece;
+ iPieceData->ConstructL();
+
+ // Copy policy to 16-bit buffer
+ TPtr8 ptr8(iPolicyHBufC8->Des());
+ TInt length = ptr8.Length();
+ HBufC *policyDataHBufC16 = HBufC::NewL(length + 1);
+ CleanupStack::PushL(policyDataHBufC16);
+ TPtr ptr(policyDataHBufC16->Des());
+ ptr.FillZ();
+ ptr.Copy(ptr8);
+ ptr.ZeroTerminate();
+
+ // Parse policy from string format into binary object format
+ TIpSecParser parser(ptr);
+ TInt err = parser.ParseAndIgnoreIKEL(iPieceData);
+ CleanupStack::PopAndDestroy();
+
+ // If parsing error, allocate a buffer and read the last error
+ // string from the ipsecpolparser. The API user will use the
+ // GetDebugInfo method to get the string (method is named as
+ // GetLastConflictInfo here).
+ if (err != KErrNone)
+ {
+ delete iLastParsingErrorInfo;
+ iLastParsingErrorInfo = NULL;
+
+ // The same size as used in ipsecpolparser
+ iLastParsingErrorInfo = HBufC8::NewL(200);
+ iLastParsingErrorInfo->Des().Copy(iPieceData->iErrorInfo);
+ ErrorHandlingL(EParsingError, err);
+ }
+ }
+
+//
+// CIPSecPolicyManagerHandler::UpdateSelectorsAndTunnels()
+//
+// Include VPNNetId to CPolicySelectors and GwNetId to CSecpolBundleItem
+// objects
+//
+//
+void
+CIPSecPolicyManagerHandler::UpdateSelectorsAndTunnels()
+ {
+ // If VPN Network ID is set, store it to policy selectors
+ if (iVPNNetId)
+ {
+ CSecurityPolicy* sp = iPieceData->Policies();
+ CSelectorList* selectorList = sp->SelectorList();
+ TInt count = selectorList->Count();
+
+ // Iterate through selector (policy rule) list
+ for (TInt i = 0; i < count; i++)
+ {
+ CPolicySelector* ps = selectorList->At(i);
+
+ // Skip 'global', 'bypass/drop_everything_else' and 'interface' selectors
+ if (ps->iGlobalSelector
+ || (ps->iDirection == KPolicySelector_INTERFACE)
+ || IsBypassEverythingElse(*ps)
+ || IsDropEverythingElse(*ps))
+ {
+ continue;
+ }
+
+ UpdatePolicySelectorScopeId(*ps, iVPNNetId);
+ }
+ }
+
+ // If VPN Gateway Network ID is set, store it to policy bundles
+ if (iGwNetId)
+ {
+ CSecurityPolicy* sp = iPieceData->Policies();
+ CSelectorList* selectorList = sp->SelectorList();
+ TInt count = selectorList->Count();
+
+ // Iterate through selector (policy rule) list
+ for (TInt i = 0; i < count; i++)
+ {
+ TBool isTunnelMode = EFalse;
+ CPolicySelector* ps = selectorList->At(i);
+
+ // Skip 'global', 'bypass/drop_everything_else' and 'interface' selectors
+ if (ps->iGlobalSelector
+ || (ps->iDirection == KPolicySelector_INTERFACE)
+ || IsBypassEverythingElse(*ps)
+ || IsDropEverythingElse(*ps))
+ {
+ continue;
+ }
+
+ UpdatePolicyBundleScopeId(*ps, iVPNNetId, iGwNetId, isTunnelMode);
+
+ // If not tunnel mode use VPN Gateway Network Id
+ // as ScopeId when updating policy selector scope
+ if (!isTunnelMode)
+ {
+ UpdatePolicySelectorScopeId(*ps, iGwNetId);
+ }
+ }
+ }
+ }
+
+//
+// CIPSecPolicyManagerHandler::UpdatePolicySelectorScopeId()
+//
+// Updates PolicySelector with the given ScopeId. The ScopeId can be either
+// VPN Network Id or VPN Gateway Network Id.
+//
+// TODO:
+// This method should be included within CPolicySelector class
+// CPolicySelector::UpdateRemoteAddressScopeId(TInt aScopeId)
+//
+//
+void
+CIPSecPolicyManagerHandler::UpdatePolicySelectorScopeId(
+ CPolicySelector& aPolicySelector,
+ TInt aScopeId)
+ {
+ // Check if remote address is specified (other than any)
+ if (!aPolicySelector.iRemote.IsUnspecified())
+ {
+ // Specific address exists, so convert address to IPv6 mapped
+ if (aPolicySelector.iRemote.Family() == KAfInet)
+ {
+ aPolicySelector.iRemote.ConvertToV4Mapped();
+ aPolicySelector.iRemoteMask.ConvertToV4Mapped();
+ }
+
+ // VPN Network ID shall be used only with addresses in network
+ // scope (addresses in other scope levels are handled as global
+ // selectors)
+ if (aPolicySelector.iRemote.Ip6Address().Scope() == KIp6AddrScopeNetwork)
+ {
+ aPolicySelector.iRemote.SetScope(aScopeId);
+ aPolicySelector.iRemoteMask.SetScope(0xFFFFFFFF);
+ }
+ }
+ else
+ {
+ // Unspecified remote address so change address family to AfInet
+ // and then build null address/mask and set ScopeId
+ aPolicySelector.iRemote.SetFamily(KAfInet);
+ aPolicySelector.iRemoteMask.SetFamily(KAfInet);
+ aPolicySelector.iRemote.ConvertToV4Mapped();
+ aPolicySelector.iRemoteMask.ConvertToV4Mapped();
+
+ aPolicySelector.iRemote.SetScope(aScopeId);
+ aPolicySelector.iRemoteMask.SetScope(0xFFFFFFFF);
+ }
+ }
+
+//
+// CIPSecPolicyManagerHandler::UpdatePolicyBundleScopeId()
+//
+// Updates bundle list of given PolicySelector by using the VPN Network Id and
+// VPN Gateway Network Id to set the ScopeId.
+//
+// VPN Gateway Network Id is set as ScopeId to tunnel address. If there are
+// nested tunnels(tunnel-in-tunnel), the VPN Gateway Network Id is stored to
+// the last gateway and VPN Network Id to all other.
+//
+// TODO:
+// This method should be included within CPolicySelector class
+// CPolicySelector::UpdateBundleScopeId(TInt aScopeId, TInt aGwScopeId)
+//
+//
+void
+CIPSecPolicyManagerHandler::UpdatePolicyBundleScopeId(
+ CPolicySelector& aPolicySelector,
+ TInt aScopeId,
+ TInt aGwScopeId,
+ TBool& aIsTunnelMode)
+ {
+ // Iterate through action bundles to set ScopeId
+ TSecpolBundleIter iter(aPolicySelector.iBundle);
+ while (iter)
+ {
+ CSecpolBundleItem* item = (CSecpolBundleItem *)iter++;
+ TBool isLast = (!iter ? ETrue : EFalse);
+ TInt scopeId = (isLast ? aGwScopeId : aScopeId);
+
+ // Check if tunnel address is set
+ if (!item->iTunnel.IsUnspecified())
+ {
+ aIsTunnelMode = ETrue;
+
+ // Map tunnel IPv4 address to Ipv6
+ if (item->iTunnel.Family() == KAfInet)
+ {
+ item->iTunnel.ConvertToV4Mapped();
+ }
+
+ item->iTunnel.SetScope(scopeId);
+ }
+ }
+ }
+
+#ifdef TESTFLAG
+//
+//
+// CIPSecPolicyManagerHandler::RequestInfo()
+//
+// This is used for testing purposes. Test client queries information from the
+// policy server
+// ARG 0 = aBuf which returns the concatenated string send to ipsec protocol
+// module
+// ARG 1 = aHandles which returns loaded autoload handles
+//
+//
+TInt
+CIPSecPolicyManagerHandler::RequestEvent(
+ const RMessage2& aMsg,
+ const CIPSecPolicyManagerSession* /*aIPSecPolicyManagerSession*/ )
+ {
+
+ // In case when there have not yet been any call of
+ // SendAlgorithmsAndPolicyToIPSecL(_L("secpol6"));
+ // This should not be executed
+ if ( !iStringBuf == NULL )
+ {
+ aMsg.WriteL(FIRST_ARGUMENT, (*iStringBuf));
+ }
+
+ // Deletes remained handles and creates new structure
+ delete iHandles;
+ iHandles = NULL;
+ iHandles = new(ELeave) TAutoloadHandles;
+
+ // Initialization
+ iHandles->iHandle1 = 0;
+ iHandles->iHandle2 = 0;
+ iHandles->iHandle3 = 0;
+ iHandles->iHandle4 = 0;
+ iHandles->iHandle5 = 0;
+
+ TInt count(0); // Counting autoload handles
+
+ // Finds active Autoload policies and copies them in right order to the iHandles
+ // structure
+ for (TInt i = 0; i < iActivePolicyList->Count() ; i++)
+ {
+
+ if ( iActivePolicyList->At(i)->iPolicyType == EAutoload ) // Case autoload
+ {
+
+ if ( count == 0 )
+ {
+ iHandles->iHandle1 = iActivePolicyList->At(i)->iPolicyHandle.iHandle;
+ }
+ else if ( count == 1)
+ {
+ iHandles->iHandle2 = iActivePolicyList->At(i)->iPolicyHandle.iHandle;
+ }
+ else if ( count == 2)
+ {
+ iHandles->iHandle3 = iActivePolicyList->At(i)->iPolicyHandle.iHandle;
+ }
+ else if ( count == 3)
+ {
+ iHandles->iHandle4 = iActivePolicyList->At(i)->iPolicyHandle.iHandle;
+ }
+ else if ( count == 4)
+ {
+ iHandles->iHandle5 = iActivePolicyList->At(i)->iPolicyHandle.iHandle;
+ }
+
+ count++;
+ }
+ }
+
+ // Creates the IPC package and copies iHandles to it
+ TPckg<TAutoloadHandles> handlesPckgWrite(*iHandles);
+
+ // Writes IPC message
+ aMsg.WriteL(SECOND_ARGUMENT, handlesPckgWrite);
+
+ return KErrNone;
+ }
+
+#endif
+
+//
+// GetAvailableSelectors - Returns the available selectors information
+//
+//
+TInt CIPSecPolicyManagerHandler::GetAvailableSelectors(const RMessage2& aMsg)
+ {
+ LOG(Log::Printf(_L("AvailableSelectors (GetAvailableSelectors) request\n")));
+ // Write the SelectorInfo block to the client's address space
+ TInt count = iSelectorInfoArray->Count();
+ TPtrC8 selectorInfoWrite(reinterpret_cast<TUint8*>(&(iSelectorInfoArray->At(0))), count * sizeof(TIpsecSelectorInfo));
+ aMsg.WriteL(FIRST_ARGUMENT, selectorInfoWrite);
+
+ // An API call completed
+ LOG(Log::Printf(_L("AvailableSelectors request completed OK\n")));
+ ApiCallCompleted();
+ return KErrNone;
+ }
+
+//
+// GetSelectorsCount - Returns the number of selectors matching the
+// gateway address passed by the client
+//
+//
+ TInt CIPSecPolicyManagerHandler::GetSelectorsCount(const RMessage2& aMsg)
+ {
+ LOG(Log::Printf(_L("EnumerateSelectors (GetSelectorsCount) request\n")));
+
+ // Read the gateway address sent by the client
+ TInetAddrPckg inetAddrPckg(iTunnel);
+ aMsg.ReadL(FIRST_ARGUMENT , inetAddrPckg);
+
+ // Parse all active policy files from string format to IPSecPolParser
+ // class object format
+ ParseAllPolicyFilesL();
+ if (iActivePolicyList->Count() == 0)
+ {
+ ErrorHandlingL(ENoGatewayFound, 0);
+ }
+
+ // Find the selector object that corresponds
+ // to the gateway address sent by the client
+ FillSelectorInfoObject();
+ if (!iSelectorInfoArray->Count())
+ {
+ ErrorHandlingL(ENoGatewayFound, 0);
+ }
+
+
+ TPckg<TInt> selectorCount(iSelectorInfoArray->Count());
+ aMsg.WriteL(SECOND_ARGUMENT, selectorCount);
+
+ // An API call completed
+ LOG(Log::Printf(_L("EnumerateSelectors request completed OK\n")));
+ ApiCallCompleted();
+ return KErrNone;
+ }
+