--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/policymanagement/policyengine/policyengineserver/src/PolicyManager.cpp Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,1285 @@
+/*
+* Copyright (c) 2002-2004 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: Implementation of policymanagement components
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "PolicyManager.h"
+#include "elements.h"
+#include "DataTypes.h"
+#include "PolicyParser.h"
+#include "ElementBase.h"
+#include "PolicyProcessor.h"
+#include "TrustedSession.h"
+#include "ErrorCodes.h"
+#include "OperationParser.h"
+#include "OperationParserConstants.h"
+#include "SettingEnforcementManager.h"
+#include "PolicyEngineServer.h"
+#include "PolicyEngineXACML.h"
+#include "debug.h"
+
+
+#include "DMUtilClient.h"
+#include <PolicyEngineClientServer.h>
+#include <ManagementContext.h>
+
+
+// CONSTANTS
+const TInt KMaxServerIdLength = 250;
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::CPolicyManager()
+// -----------------------------------------------------------------------------
+//
+
+CPolicyManager::CPolicyManager( CPolicyProcessor * aPolicyProcessor)
+ : CActive( EPriorityLow), iPolicyProcessor( aPolicyProcessor)
+{
+ iPolicyStorage = CPolicyStorage::PolicyStorage();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::~CPolicyManager()
+// -----------------------------------------------------------------------------
+//
+
+CPolicyManager::~CPolicyManager()
+{
+ //CSettingEnforcementManager
+ delete iSEManager;
+
+ //descriptors used in operations
+ delete iActiveChildList;
+ delete iActiveXACMLContent;
+ delete iActiveElementList;
+ delete iOperationParser;
+ delete iCurrentManagementCommand;
+
+ CPolicyEngineServer::RemoveActiveObject( this);
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::ConstructL()
+{
+ CPolicyEngineServer::AddActiveObjectL( this);
+ iSEManager = CSettingEnforcementManager::NewL();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyStorage::NewL()
+// -----------------------------------------------------------------------------
+//
+
+CPolicyManager * CPolicyManager::NewL( CPolicyProcessor * aPolicyProcessor)
+{
+ CPolicyManager * self = new(ELeave) CPolicyManager( aPolicyProcessor);
+
+ CleanupStack::PushL( self);
+ self->ConstructL();
+ CleanupStack::Pop( self);
+
+ return self;
+
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::ExecuteOperationL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::ExecuteOperation( CTrustedSession * aSession, const RMessage2& aMessage)
+{
+ iMessage = &aMessage;
+
+ //Only one management session is accepted
+ if ( CPolicyEngineServer::StatusFlags()->iManagementActive )
+ {
+ CompleteOperation( KErrInUse);
+ return;
+ }
+
+ CPolicyEngineServer::StatusFlags()->iManagementActive = ETrue;
+
+
+ //set pointer to trusted session and save reference to RMessage
+ iTrustedSession = aSession;
+
+ //initialize states
+ iOperationStatus = 0;
+ iUseBearerCertificate = EFalse;
+ iCertificateUpdates = EFalse;
+
+
+ //Add this active object active scheduler
+ if ( !IsAdded())
+ {
+ CActiveScheduler::Add( this);
+ }
+
+ //Complete own request
+ SetActive();
+ TRequestStatus * status = &iStatus;
+ User::RequestComplete( status, KErrNone);
+}
+
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::RunL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::RunL()
+{
+ CPolicyEngineServer::SetActiveSubSession( this);
+
+ //management operations are allowed only when server is free
+ if ( CPolicyEngineServer::StatusFlags()->iProcessorActive )
+ {
+ SetActive();
+ TRequestStatus * status = &iStatus;
+ User::RequestComplete( status, KErrNone);
+ return;
+ }
+
+ if ( iOperationStatus == 0)
+ {
+ //Start management session for next operations
+ iPolicyStorage->StartCommitSessionL();
+
+ iCurrentManagementCommand = HBufC8::NewL( iMessage->GetDesLength(0));
+ //Read policy description
+ TPtr8 ptr = iCurrentManagementCommand->Des();
+ iMessage->ReadL(0, ptr, 0);
+ iOperationParser = COperationParser::NewL( ptr);
+
+ //parse operations, "iMsg" stores error message
+ iOperationParser->ParseOperationsL( iMsg);
+ }
+ else if ( (iOperationStatus - 1) < iOperationParser->OperationCount())
+ {
+ //Execute operations, "this" is pointer to callback function
+ iCertificateUpdates = EFalse;
+ iOperationParser->ExecuteL( iOperationStatus - 1, this);
+
+ if ( iCertificateUpdates)
+ {
+ CPolicyEngineServer::CertificateMaps()->NewMappingsAvailable();
+ }
+ }
+
+ if ( iOperationStatus == iOperationParser->OperationCount() + 2)
+ {
+ //Finish management session and commit changes in repository
+ iMsg = ManagementErrors::OperationOk;
+
+ if ( iStatus.Int() == KErrNone)
+ {
+ CommitChangesL();
+ CompleteOperation( iStatus.Int());
+ CPolicyStorage::PolicyStorage()->ReleaseElements();
+ }
+ else
+ {
+ RunError( iStatus.Int());
+ }
+
+ }
+ else
+ if ( iOperationStatus == iOperationParser->OperationCount() + 1)
+ {
+ //Make setting enforcements...
+ MakeEnforcementL( KErrNone);
+ }
+ else
+ {
+ SetActive();
+ TRequestStatus * status = &iStatus;
+ User::RequestComplete( status, KErrNone);
+ }
+
+ iOperationStatus++;
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::DoCancel()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::DoCancel()
+{
+ RunError( KErrAbort);
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::DoCancel()
+// -----------------------------------------------------------------------------
+//
+
+TInt CPolicyManager::RunError( TInt aError)
+{
+ RDEBUG("CPolicyManager::RunError");
+ RDEBUG8_2("Policy engine operation error message: %S", &iMsg);
+
+ //restores possible changes in policy storage
+ TRAPD( err, iPolicyStorage->CommitChangesL( EFalse))
+
+ if ( err != KErrNone )
+ {
+ aError = err;
+ }
+
+ //complete operation
+ CompleteOperation( aError);
+
+ return KErrNone;
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::MakeEnforcementL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::MakeEnforcementL( TInt aError)
+{
+ //initialize enforcement session
+ iSEManager->StartEnforcementSessionL( iStatus, iTrustedSession->SessionCertificate());
+
+ //get modified elements
+ iPolicyStorage->GetEditedElementsL( iSEManager);
+
+ //start enforcement session enforcement policies
+ if ( aError == KErrNone)
+ {
+ iSEManager->ExecuteEnforcementSessionL();
+ }
+
+
+ //set active (waiting for enforcement completing)
+ SetActive();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::CompleteOperation()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::CompleteOperation( TInt aError )
+ {
+ RDEBUG_2("CPolicyManager::CompleteOperation( %d )", aError );
+
+ if( aError != KErrNone && aError != KErrParser && KErrOpParser != aError && KErrPolicyManager != aError)
+ {
+ iMsg = KNullDesC8;
+ aError = KErrGeneral;
+ }
+ else
+ {
+ aError = KErrNone;
+ }
+
+ //finish storage session and enforcement session
+ iPolicyStorage->ResetEditableMemory();
+ iSEManager->EndEnforcementSession( KErrNone == aError );
+
+ if ( iCertificateUpdates )
+ {
+ CPolicyEngineServer::CertificateMaps()->NewMappingsAvailable();
+ }
+
+ CPolicyEngineServer::StatusFlags()->iManagementActive = EFalse;
+
+ //release resources
+ delete iOperationParser;
+ iOperationParser = NULL;
+ delete iCurrentManagementCommand;
+ iCurrentManagementCommand = NULL;
+
+ //write return message to client process
+ TParserResponse response( iMsg);
+ TPckgC<TParserResponse> retPack(response);
+ TRAPD( err, iMessage->WriteL( 1, retPack ) );
+ if( err != KErrNone )
+ {
+ iMessage->Complete( err );
+ return;
+ }
+
+ iMessage->Complete( aError);
+ }
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::UpdateStateFlags()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::UpdateStateFlagsL()
+{
+ RDEBUG("CPolicyManager::UpdateStateFlagsL - start");
+
+ RDMUtil dmutil;
+ User::LeaveIfError( dmutil.Connect());
+ CleanupClosePushL( dmutil);
+ TBool securityActive = EFalse;
+ User::LeaveIfError( dmutil.UpdatePolicyMngStatusFlags( EPolicyChanged));
+
+ //Check is terminal security activated
+ CElementBase * iElement = iPolicyStorage->GetElementL( PolicyLanguage::Constants::RolesMappingPolicy);
+ if (iElement)
+ {
+ TElementReserver reserver(iElement);
+
+ iPolicyStorage->CheckElementL(iElement);
+
+
+ //check child elements, any rule child means that terminal security is acticated
+ for (TInt i(0); i < iElement->ElementCount(); i++) {
+ CElementBase * element = iElement->Element(i);
+
+ if (element->ElementType() == ERule) {
+ RDEBUG("CPolicyManager::UpdateStateFlagsL -> securityActive = ETrue");
+ securityActive = ETrue;
+ break;
+ }
+ }
+ reserver.Release();
+ }
+
+ //update policy management flags
+ if ( securityActive)
+ {
+ User::LeaveIfError( dmutil.UpdatePolicyMngStatusFlags( ETerminalSecurityActive));
+ }
+ else
+ {
+ User::LeaveIfError( dmutil.UpdatePolicyMngStatusFlags( ETerminalSecurityDeactive));
+ }
+
+
+ CleanupStack::PopAndDestroy( &dmutil);
+
+ RDEBUG("CPolicyManager::UpdateStateFlagsL - end");
+}
+
+
+
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::CommitChangesL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::CommitChangesL()
+{
+ //Accept or decline changes to storage...
+ iPolicyStorage->SaveEditableMemoryL();
+
+ //This ensures that enforcement settings are committed
+ iSEManager->CommitChanges();
+
+ //This ensures that all changes are commited (also enforcement)
+ iPolicyStorage->CommitChangesL( ETrue);
+
+ //update state flags
+ UpdateStateFlagsL();
+
+ RDEBUG8_2("Policy engine operation message: %S", &iMsg);
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::NewPolicy()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::NewElementL( const TInt& aLineOffset, const TDesC8& aTargetElement, const TDesC8& aElementDescription, const TBool& aUseBearerCertificate )
+{
+ RDEBUG("PolicyEngineServer: CPolicyManager::NewElementL");
+
+ //initialize policy parser...
+ CPolicyParser * parser = CPolicyParser::NewL( iPolicyStorage);
+ CleanupStack::PushL( parser);
+ parser->SetExternalIdChecked( KNoExternalIdConflictsAllowed);
+ parser->SetLineOffset( aLineOffset);
+ iUseBearerCertificate = aUseBearerCertificate;
+
+ //Parse native model from XACML description
+ TInt err(KErrNone);
+ TBuf8<KMaxReturnMessageLength> msg;
+ CElementBase * element = parser->ParseXACMLObjects( err, aElementDescription, msg);
+ CleanupStack::PopAndDestroy( parser); //Parser
+
+ if ( err != KErrNone )
+ {
+ iMsg = msg;
+ User::Leave( KErrParser);
+ }
+
+
+ //Add element to policy storage (storage take responsibility to delete object)
+ RDEBUG_2("PolicyEngineServer: Element parsed and id created(id %d)", element->GetId());
+
+ element->CreateIdL();
+ element->CreateExternalId();
+ iPolicyStorage->AddNewElementL( element);
+ TElementReserver newElement( element);
+
+ //Check is the policy valid and if so, add element to temporary storage
+ AssignElementL( aTargetElement, element);
+
+ newElement.Release();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::ReplaceElementL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::ReplaceElementL( const TInt& aLineOffset, const TDesC8& aTargetElement, const TDesC8& aElementDescription )
+{
+ RDEBUG("PolicyEngineServer: CPolicyManager::ReplaceElementL");
+
+ //initialize policy parser...
+ CPolicyParser * parser = CPolicyParser::NewL( iPolicyStorage);
+ CleanupStack::PushL( parser);
+ parser->SetExternalIdChecked( KSameExternalIdAllowedForRoot);
+ parser->SetLineOffset( aLineOffset);
+
+ //Parse native model from XACML description
+ TInt err(KErrNone);
+ TBuf8<KMaxReturnMessageLength> msg;
+ CElementBase * element = parser->ParseXACMLObjects( err, aElementDescription, msg);
+ CleanupStack::PopAndDestroy( parser); //Parser
+
+ if ( err != KErrNone )
+ {
+ iMsg = msg;
+ User::Leave( KErrParser);
+ }
+
+
+ //Add element to policy storage (storage take responsibility to delete object)
+ RDEBUG_2("PolicyEngineServer: Element parsed and id created(id %d)", element->GetId());
+
+ element->CreateIdL();
+ element->CreateExternalId();
+ iPolicyStorage->AddNewElementL( element);
+ TElementReserver newElement( element);
+
+ //Check is the policy valid and if so, add element to temporary storage
+ ReAssignElementL( aTargetElement, element);
+
+ newElement.Release();
+
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::AssignPolicyL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::AssignElementL( const TDesC8& aTargetElement, CElementBase * aElement)
+{
+ RDEBUG("PolicyEngineServer: CPolicyManager::AssignElementL");
+
+ //get parent element and load it
+ CElementBase * parentElement = iPolicyStorage->GetEditableElementL( aTargetElement);
+
+ //if parent eleemnt is valid
+ if ( !parentElement)
+ {
+ RDEBUG("PolicyEngineServer: Target element not found");
+ iMsg = ManagementErrors::ElementNotFound;
+ User::Leave( KErrPolicyManager);
+ }
+
+ TElementReserver assignReserver( parentElement);
+ iPolicyStorage->CheckElementL( parentElement);
+
+ //add parant id to components
+ aElement->AddParentIdL( parentElement->GetId());
+
+ //Check is assignment acceptable
+ IsAssigmentAcceptableL( parentElement, aElement, ETrue);
+ assignReserver.Release();
+
+
+ //Add element to parent element, check is assigment valid
+ parentElement->AddIdElementL( aElement);
+ parentElement->iElementState = EEditedElement;
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::AssignPolicyL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::ReAssignElementL( const TDesC8& aTargetElement, CElementBase * aElement)
+{
+ RDEBUG("PolicyEngineServer: CPolicyManager::ReAssignElementL");
+
+ //get replaced element and load it
+ CElementBase * replacedElement = iPolicyStorage->GetEditableElementL( aTargetElement);
+
+ //check that element is valid
+ if ( !replacedElement)
+ {
+ RDEBUG("PolicyEngineServer: Target element not found");
+ iMsg = ManagementErrors::ElementNotFound;
+ User::Leave( KErrPolicyManager);
+ }
+
+ //Check element
+ TElementReserver assignReserver( replacedElement);
+ iPolicyStorage->CheckElementL( replacedElement);
+
+ //copy parents to new element
+ aElement->AddParentIdL( replacedElement->iParentId);
+
+ //Get parent elements
+ CElementBase * parentElement = iPolicyStorage->GetEditableElementL( replacedElement->iParentId);
+
+ //check that element is valid
+ if ( !parentElement)
+ {
+ iMsg = ManagementErrors::ElementNotFound;
+ User::Leave( KErrPolicyManager);
+ }
+
+ //Check element
+ TElementReserver parentReserver( parentElement);
+ iPolicyStorage->CheckElementL( parentElement);
+
+ //Check is reassignment acceptable
+ IsAssigmentAcceptableL( parentElement, aElement, EFalse);
+
+ //remove child from parent child list
+ parentElement->RemoveChild( replacedElement->GetId());
+
+ //Add element to parent element and mark to modified
+ parentElement->AddIdElementL( aElement);
+ parentElement->iElementState = EEditedElement;
+
+ //When edited element list is committed all "EDeletedEditableElement"s will be deleted...
+ replacedElement->DeleteMarkRecursiveL();
+
+
+
+
+ parentReserver.Release();
+ assignReserver.Release();
+}
+// -----------------------------------------------------------------------------
+// CPolicyManager::RemoveElementL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::RemoveElementL( const TDesC8& aTargetElement)
+{
+ RDEBUG("CPolicyManager::RemoveElementL");
+
+
+ iMsg = ManagementErrors::OperationOk;
+
+ //get parent element and load it
+ CElementBase * element = iPolicyStorage->GetEditableElementL( aTargetElement);
+
+ //error if element not found
+ if ( !element )
+ {
+ RDEBUG("PolicyEngineServer: Target element not found");
+ iMsg = ManagementErrors::ElementNotFound;
+ User::Leave( KErrPolicyManager);
+ }
+
+
+ TElementReserver elementReserver( element);
+ iPolicyStorage->CheckElementL( element);
+
+
+ if ( element->iParentId)
+ {
+ //Remove element reference from parent element
+
+ CElementBase * parentElement = iPolicyStorage->GetEditableElementL( element->iParentId);
+ __ASSERT_ALWAYS ( parentElement, User::Panic( Panics::PolicyManagerPanic, KErrGeneral));
+
+ //check element, use editable cache
+ TElementReserver elementReserver( parentElement);
+ iPolicyStorage->CheckElementL( parentElement);
+
+ IsRemoveAcceptableL( parentElement, element );
+
+ TInt err = parentElement->RemoveChild( element->GetId());
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrPolicyManager);
+ }
+
+ parentElement->iElementState = EEditedElement;
+
+ elementReserver.Release();
+ }
+
+ //When edited element list is committed all "EDeletedEditableElement" will be deleted...
+ element->DeleteMarkRecursiveL();
+
+ elementReserver.Release();
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::IsAssigmentAcceptable()
+// -----------------------------------------------------------------------------
+//
+
+
+void CPolicyManager::IsAssigmentAcceptableL( CElementBase * aParentElement, CElementBase * aElement, TBool aNewElement)
+{
+ RDEBUG("CPolicyManager::IsAssigmentAcceptableL");
+
+ using namespace PolicyLanguage::Constants;
+ using namespace AttributeContainerHelper;
+ using namespace PolicyLanguage::NativeLanguage::AttributeValues;
+
+ //return if policy check is not needed
+ NO_POLICY_CHECK_RETURN;
+ RDEBUG_3("CPolicyManager: Parent element (%d) element (%d)", aParentElement->GetId(), aElement->GetId());
+
+ HBufC8* extId = aParentElement->ExternalId();
+ TInt match = extId->CompareF( PolicyLanguage::Constants::RolesMappingPolicy );
+ if( (match == 0) && aNewElement )
+ {
+ RDEBUG("CPolicyManager: Parent element is RolesMappingPolicy. Adding trust for server");
+ TInt rolesElements = aParentElement->GetChildElementCountL();
+
+ RDEBUG_2("CPolicyManager: rolesElements count (%d)", rolesElements);
+ if( rolesElements >= 1 )
+ {
+ RDEBUG("CPolicyManager: Trust already exists");
+ iMsg = ManagementErrors::AccessDenied;
+ User::Leave( KErrPolicyManager);
+ }
+ RDEBUG("CPolicyManager: No trust created yet");
+ }
+ //setup request context
+ iPolicyProcessor->ResetRequestContext();
+ iPolicyProcessor->SetTargetElement( aElement);
+ iPolicyProcessor->SetSessionTrust( iTrustedSession);
+
+ //attribute list for request attributes
+ RAttributeContainer attributes;
+ CleanupClosePushL( attributes);
+
+ //action attributes for meta_policy_Set
+ if ( aNewElement)
+ {
+ attributes.AppendL( EActionAttributes, CAttribute::NewL( PolicyEngineXACML::KActionId, AddPolicy, StringDataType));
+ }
+ else
+ {
+ attributes.AppendL( EActionAttributes, CAttribute::NewL( PolicyEngineXACML::KActionId, ReplacePolicy, StringDataType));
+ }
+
+ //Trusted subject is either trustedsubject of session or trustedsubject used in element to be added.
+ //In a cases where new element contains trustedsubject, it is used. Other cases sessions trustedsubject
+
+ //Get new element subjectmatch-elements
+ RElementArray subjectMatches;
+ CleanupClosePushL( subjectMatches);
+ aElement->FindAttributesL( ESubjectMatch, subjectMatches);
+
+ //util variables
+ TPtrC8 trustedSubject( KNullDesC8);
+ TBool oneTrustedSubject = EFalse;
+
+ //add trusted subject from target element
+ for ( TInt i(0); i < subjectMatches.Count(); i++)
+ {
+ CMatchObject* subjectMatch = (CMatchObject*) subjectMatches[i];
+
+ //check attribute id (Certificate id is also trusted subject!)
+ TPtrC8 attributeId = subjectMatch->AttributeDesignator()->GetAttributeid();
+ if ( attributeId == PolicyEngineXACML::KTrustedSubject || attributeId == PolicyEngineXACML::KCertificate )
+ {
+ //Only one target policy is valid
+ if ( oneTrustedSubject && trustedSubject.Compare( subjectMatch->AttributeValue()->Data()->Value()) != 0)
+ {
+ iMsg = ParserErrors::InvalidElement;
+ User::Leave( KErrPolicyManager);
+ }
+
+ oneTrustedSubject = ETrue;
+
+ //add trusted subject to attribute list
+ trustedSubject.Set( subjectMatch->AttributeValue()->Data()->Value());
+
+ //certificates have to be transformed to CASN form
+ if ( attributeId == PolicyEngineXACML::KCertificate)
+ {
+ //create CSubject info
+ CCertificateMaps::CSubjectInfo* info = new (ELeave) CCertificateMaps::CSubjectInfo();
+ CleanupStack::PushL( info);
+
+ //parse CASN info from certificate and add TargetTrustedSubject attribute with CASN value
+ CCertificateMaps::CreateSubjectInfoL( info, trustedSubject);
+ attributes.AppendL( ESubjectAttributes, CAttribute::NewL( TargetTrustedSubject, *info->iCASN, StringDataType));
+ CleanupStack::PopAndDestroy( info);
+ }
+ else
+ {
+ attributes.AppendL( ESubjectAttributes, CAttribute::NewL( TargetTrustedSubject, trustedSubject, StringDataType));
+ }
+
+ }
+ }
+ CleanupStack::PopAndDestroy( &subjectMatches); //subjectMatches
+
+
+
+ if ( iUseBearerCertificate )
+ {
+ if ( !iTrustedSession->CertificatedSession())
+ {
+ RDEBUG("PolicyEngineServer: Certificated session is required");
+ //when bearer certificate is used, session must be certificated
+ iMsg = ManagementErrors::SessionMustBeCertificated;
+ User::Leave( KErrPolicyManager);
+ }
+
+ //add certificate mapping for alias, certificate (TCertInfo) is available inside of trusted session
+ CElementBase * rule = iTrustedSession->CreateCertificateMappingL( trustedSubject);
+ CleanupStack::PushL( rule);
+
+ if ( !rule)
+ {
+ RDEBUG("PolicyEngineServer: Invalid certificate!");
+ iMsg = ManagementErrors::InvalidCertificateMapping;
+ User::Leave( KErrPolicyManager);
+ }
+ else
+ {
+ rule->CreateIdL();
+ rule->CreateExternalId();
+ iPolicyStorage->AddNewElementL( rule);
+
+ RDEBUG_2("PolicyEngineServer: Auto certifate created (id %d)", rule->GetId());
+
+ //add parant id to cert policy
+ CElementBase* certMappingPolicy = iPolicyStorage->GetEditableElementL( CertMappingPolicy);
+ //if element is not valid
+ if (!certMappingPolicy)
+ {
+ return;
+ }
+ TElementReserver certReserver( certMappingPolicy);
+ iPolicyStorage->CheckElementL( certMappingPolicy);
+
+ rule->AddParentIdL( certMappingPolicy->GetId());
+
+ //Add element to parent element, check is assigment valid
+ certMappingPolicy->AddIdElementL( rule);
+ certMappingPolicy->iElementState = EEditedElement;
+
+
+ certReserver.Release();
+
+ CPolicyEngineServer::CertificateMaps()->NewMappingsAvailable();
+ iCertificateUpdates = ETrue;
+ }
+ CleanupStack::Pop( rule);
+ }
+
+
+ //add session trusted subject
+ if ( iTrustedSession->CertificatedSession())
+ {
+ attributes.AppendL( ESubjectAttributes,
+ CAttribute::NewL( PolicyEngineXACML::KTrustedSubject, iTrustedSession->CASNForSessionL(), StringDataType));
+ attributes.AppendL( ESubjectAttributes,
+ CAttribute::NewL( PolicyEngineXACML::KRoleId, iTrustedSession->CASNForSessionL(), StringDataType));
+ }
+ else
+ {
+ attributes.AppendL( ESubjectAttributes,
+ CAttribute::NewL( PolicyEngineXACML::KSubjectId, iTrustedSession->SIDForSession(), StringDataType));
+ }
+
+ //certificate mapping must be checked first!!
+ if ( *aParentElement->ExternalId() == CertMappingPolicy)
+ {
+ TBool validCertificate = EFalse;
+ TRAPD( err, validCertificate = iTrustedSession->IsCertificateMappingValidL( aElement))
+
+ if ( !validCertificate || err != KErrNone)
+ {
+ RDEBUG("PolicyEngineServer: Invalid certificate mapping!");
+ iMsg = ManagementErrors::InvalidCertificateMapping;
+ User::Leave( KErrPolicyManager);
+ }
+
+ iCertificateUpdates = ETrue;
+ }
+
+
+ //parent element for new policy
+ attributes.AppendL( EResourceAttributes, CAttribute::NewL( PolicyTargetAttr, *aParentElement->ExternalId(), StringDataType));
+
+ //make request
+ TMatchResponse response;
+
+ RDEBUG("CPolicyManager - Start request execution");
+ iPolicyProcessor->ExecuteRequestL( attributes, response);
+ RDEBUG("CPolicyManager - End request execution");
+
+ CleanupStack::PopAndDestroy( &attributes);
+ RDEBUG("CPolicyManager - CleanupStack::PopAndDestroy( &attributes);");
+
+ if ( response != EPermit)
+ {
+ RDEBUG("CPolicyManager - Access denied");
+ iMsg = ManagementErrors::AccessDenied;
+ User::Leave( KErrPolicyManager);
+ }
+
+ //add current DM session server id to list which defines server ids which DM operations are silent.
+ if ( iUseBearerCertificate)
+ {
+ AddSilentDMOperationServerIdL();
+ }
+
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::IdRemoveAcceptableL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::IsRemoveAcceptableL( CElementBase* aParentElement, CElementBase* aElement )
+ {
+ RDEBUG("CPolicyManager::IsRemoveAcceptableL");
+
+ using namespace PolicyLanguage::Constants;
+ using namespace AttributeContainerHelper;
+ using namespace PolicyLanguage::NativeLanguage::AttributeValues;
+
+ //return if policy check is not needed
+ NO_POLICY_CHECK_RETURN;
+
+ //setup request context
+ iPolicyProcessor->ResetRequestContext();
+ iPolicyProcessor->SetTargetElement( aElement );
+ iPolicyProcessor->SetSessionTrust( iTrustedSession );
+
+ //attribute list for request attributes
+ RAttributeContainer attributes;
+ CleanupClosePushL( attributes );
+
+ //action attributes for meta_policy_Set
+ attributes.AppendL( EActionAttributes, CAttribute::NewL( PolicyEngineXACML::KActionId, RemovePolicy, StringDataType));
+
+ //subject attributes for trusted sessions
+ if( iTrustedSession->CertificatedSession() )
+ {
+ attributes.AppendL( ESubjectAttributes,
+ CAttribute::NewL( PolicyEngineXACML::KRoleId, iTrustedSession->CASNForSessionL(), StringDataType));
+ attributes.AppendL( ESubjectAttributes,
+ CAttribute::NewL( PolicyEngineXACML::KTrustedSubject, iTrustedSession->CASNForSessionL(), StringDataType));
+ }
+ else
+ {
+ attributes.AppendL( ESubjectAttributes,
+ CAttribute::NewL( PolicyEngineXACML::KSubjectId, iTrustedSession->SIDForSession(), StringDataType));
+
+ }
+
+ // ======= original certificate mapping ======================
+ //search trustedsubject from target element (element to be deleted)
+ HBufC8* targetTrustedSubject = iTrustedSession->GetTargetTrustedSubjectL( aElement, ETrue );
+
+ //and target element trusted subject to request context....
+ if( targetTrustedSubject )
+ {
+ CleanupStack::PushL( targetTrustedSubject);
+ attributes.AppendL( ESubjectAttributes, CAttribute::NewL( TargetTrustedSubject, *targetTrustedSubject, StringDataType));
+ CleanupStack::PopAndDestroy( targetTrustedSubject);
+ }
+ // ===========================================================
+
+
+ // ======= mapped certificates ===============================
+ // all certificate mappings, including mapped certificates, are under "cert_mapping_policy"
+ CElementBase* certMappings = iPolicyStorage->GetEditableElementL( _L8("cert_mapping_policy") );
+ if( certMappings )
+ {
+ TElementReserver mappedElementReserver( certMappings );
+ iPolicyStorage->CheckElementL( certMappings );
+
+ RPointerArray<HBufC8> mappedTargetTrustedSubjects;
+ iTrustedSession->GetMappedTargetTrustedSubjectL( mappedTargetTrustedSubjects, certMappings, ETrue );
+ TInt count = mappedTargetTrustedSubjects.Count();
+ if( count )
+ {
+ for( TInt i = 0; i < count; i++ )
+ {
+ HBufC8* mappedTargetTrustedSubject = mappedTargetTrustedSubjects[ i ];
+ CleanupStack::PushL( mappedTargetTrustedSubject);
+ attributes.AppendL( ESubjectAttributes, CAttribute::NewL( PolicyEngineXACML::KCertificateMapped, *mappedTargetTrustedSubject, StringDataType));
+ CleanupStack::PopAndDestroy( mappedTargetTrustedSubject );
+ }
+ }
+
+ mappedTargetTrustedSubjects.Close();
+ mappedElementReserver.Release();
+ }
+ // ===========================================================
+
+ //parent element for new policy
+ attributes.AppendL( EResourceAttributes, CAttribute::NewL( PolicyTargetAttr, *aParentElement->ExternalId(), StringDataType));
+
+ //make request
+ TMatchResponse response;
+ iPolicyProcessor->ExecuteRequestL( attributes, response );
+ CleanupStack::PopAndDestroy( &attributes );
+
+ if( response != EPermit )
+ {
+ iMsg = ManagementErrors::AccessDenied;
+ User::Leave( KErrPolicyManager );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementListL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::GetElementListL( const RMessage2& aMessage)
+{
+
+ //element info is two phase operation...
+ if ( aMessage.Function() == EGetElementListLength)
+ {
+ //In first phase descriptor lengths are fetched
+
+ //Read element types
+ TElementType type;
+ TPckg<TElementType> typePack( type);
+ aMessage.ReadL(0, typePack, 0);
+
+ //fetch element
+ CElementBase * element = iPolicyStorage->GetElementL( PolicyLanguage::Constants::RootElement);
+
+ if ( element)
+ {
+ //reserve element and check it
+ TElementReserver elementReserver( element);
+ iPolicyStorage->CheckElementL( element);
+
+ //get list length
+ TInt length = element->GetElementsListLengthL( type);
+
+ delete iActiveElementList;
+ iActiveElementList = NULL;
+
+ iActiveElementList = HBufC8::NewL( length);
+ TPtr8 ptr = iActiveElementList->Des();
+ element->GetElementsListL( type, ptr);
+
+
+ //write values to client side
+ TPckgC<TInt> intPack( length);
+ aMessage.WriteL(1, intPack);
+
+ elementReserver.Release();
+ }
+ else
+ {
+ User::Leave( KErrNotFound);
+ }
+ }
+ else
+ {
+ // and in second phase descriptor are written to client side
+ if ( iActiveElementList )
+ {
+ aMessage.WriteL(0, *iActiveElementList);
+ }
+
+ //delete child list
+ delete iActiveElementList;
+ iActiveElementList = 0;
+ }
+
+}
+
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementInfoL()
+// -----------------------------------------------------------------------------
+//
+
+
+void CPolicyManager::GetElementInfoL( const RMessage2& aMessage)
+{
+
+
+ //element info is two phase operation...
+ if ( aMessage.Function() == EGetElementDescriptionAndChildListLength)
+ {
+ //In first phase descriptor lengths are fetched
+
+ //Read element id
+ TPtr8 id = HBufC8::NewLC( aMessage.GetDesLength(0))->Des();
+ aMessage.ReadL(0, id, 0);
+
+ //fetch element
+ CElementBase * element = iPolicyStorage->GetElementL( id);
+
+ if ( element)
+ {
+ //reserve element and check it
+ TElementReserver elementReserver( element);
+ iPolicyStorage->CheckElementL( element);
+
+ //Create helper pack, which is delivered to client side
+ TElementInfoHelpPack helper;
+ helper.iDescriptionLength = 0;
+
+ //get description and child list
+ iActiveDescription = element->DescriptionL();
+ if ( iActiveDescription)
+ {
+ helper.iDescriptionLength = iActiveDescription->Length();
+ }
+
+ helper.iChildListLength = element->GetChildListLengthL();
+
+ //write values to client side
+ TPckgC<TElementInfoHelpPack> helperPack( helper);
+
+ delete iActiveChildList;
+ iActiveChildList = NULL;
+ iActiveChildList = HBufC8::NewL( helper.iChildListLength);
+ TPtr8 ptr = iActiveChildList->Des();
+ element->GetChildListL( ptr);
+
+ aMessage.WriteL(1, helperPack);
+
+ elementReserver.Release();
+ }
+ else
+ {
+ User::Leave( KErrNotFound);
+ }
+
+ CleanupStack::PopAndDestroy(); //HBufC8
+ }
+ else
+ {
+ // and in second phase descriptor are written to client side
+ if ( iActiveDescription)
+ {
+ aMessage.WriteL(0, *iActiveDescription);
+ }
+
+ if ( iActiveChildList)
+ {
+ aMessage.WriteL(1, *iActiveChildList);
+ }
+
+
+ //description is owned by descriptor element (do not delete)
+ iActiveDescription = 0;
+ //delete child list
+ delete iActiveChildList;
+ iActiveChildList = 0;
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementXACMLDescriptionL()
+// -----------------------------------------------------------------------------
+//
+
+void CPolicyManager::GetElementXACMLDescriptionL( const RMessage2& aMessage)
+{
+
+
+ //get element XACML description is two phase operation...
+ if ( aMessage.Function() == EGetElementXACMLLength)
+ {
+ //Read element id
+ TPtr8 id = HBufC8::NewLC( aMessage.GetDesLength(0))->Des();
+ aMessage.ReadL(0, id, 0);
+
+ //In first phase descriptor length is fetched.
+ CElementBase * element = iPolicyStorage->GetElementL( id);
+
+ if ( element)
+ {
+ //reserve element and check it
+ TElementReserver elementReserver( element);
+ iPolicyStorage->CheckElementL( element);
+
+ //Member pointer is used to save XACML description during two phase operation
+ delete iActiveXACMLContent;
+ iActiveXACMLContent = NULL;
+ iActiveXACMLContent = element->DecodeElementL( EXACML, EFullMode);
+
+ TInt length = 0;
+ if ( iActiveXACMLContent)
+ {
+ length = iActiveXACMLContent->Length();
+ }
+
+ //write values to client side
+ TPckg<TInt> descriptionLength( length);
+ aMessage.WriteL(1, descriptionLength);
+
+ elementReserver.Release();
+ }
+ else
+ {
+ User::Leave( KErrNotFound);
+ }
+
+ CleanupStack::PopAndDestroy(); //HBufC8
+ }
+ else
+ {
+ // and in second phase descriptor are written to client side
+ if ( iActiveXACMLContent )
+ {
+ aMessage.WriteL(0, *iActiveXACMLContent);
+ }
+
+ //delete XACML content
+ delete iActiveXACMLContent;
+ iActiveXACMLContent = NULL;
+
+ }
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetElementXACMLDescriptionL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::IsServerIdValidL( const RMessage2& aMessage)
+{
+ RDEBUG("PolicyEngineServer: CPolicyManager: Is allowed server id");
+
+ //Read server id
+ TPtr8 id = HBufC8::NewLC( aMessage.GetDesLength(0))->Des();
+ aMessage.ReadL(0, id, 0);
+
+ //Create package for data
+ TBool response;
+ TPckg<TBool> respPck( response);
+
+ //check id
+ response = CPolicyStorage::PolicyStorage()->IsServerIdValid( id);
+
+ if ( response )
+ {
+ RDEBUG("CPolicyManager: Is allowed server id -> TRUE");
+ }
+ else
+ {
+ RDEBUG("CPolicyManager: Is allowed server id -> FALSE");
+ }
+
+ //write response
+ aMessage.WriteL(1, respPck);
+
+ CleanupStack::PopAndDestroy();
+}
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::GetCertificateRoleL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::GetCertificateRoleL( const RMessage2& aMessage)
+ {
+ RDEBUG("PolicyEngineServer: CPolicyManager::GetCertificateRoleL");
+
+ //Create package for data
+ TCertInfo certInfo;
+ TPckg<TCertInfo> certInfoPck( certInfo);
+ aMessage.ReadL(0, certInfoPck, 0);
+
+ //TRole
+ TRole role;
+ TPckg<TRole> rolePck( role);
+
+ //get certificate role...
+ role = CPolicyEngineServer::CertificateMaps()->CertificateRoleL( certInfo, EFalse );
+
+ //write response
+ aMessage.WriteL( 1, rolePck );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::AddSilentDMOperationServerIdL()
+// -----------------------------------------------------------------------------
+//
+void CPolicyManager::AddSilentDMOperationServerIdL()
+{
+ //connect to DM util client...
+ RDMUtil dmutil;
+ User::LeaveIfError( dmutil.Connect());
+ CleanupClosePushL( dmutil);
+
+ //..and get server id
+ TBuf8<KMaxServerIdLength> serverid;
+ User::LeaveIfError( dmutil.GetDMSessionServerId( serverid));
+
+ User::LeaveIfError( CPolicyStorage::PolicyStorage()->AddNewServerId( serverid));
+
+
+ CleanupStack::PopAndDestroy( &dmutil);
+}
+
+
+// -----------------------------------------------------------------------------
+// CPolicyManager::IsCurrentServerIdTrustedL()
+// -----------------------------------------------------------------------------
+//
+TBool CPolicyManager::IsCurrentServerIdTrustedL()
+{
+ TBool trustedServer = EFalse;
+
+ //connect to DM util client...
+ RDMUtil dmutil;
+ User::LeaveIfError( dmutil.Connect());
+ CleanupClosePushL( dmutil);
+
+ //..and get server id
+ TBuf8<KMaxServerIdLength> serverid;
+ User::LeaveIfError( dmutil.GetDMSessionServerId( serverid));
+ TRAPD( err, trustedServer = CPolicyStorage::PolicyStorage()->IsServerIdValid( serverid) );
+ User::LeaveIfError( err );
+ CleanupStack::PopAndDestroy( &dmutil);
+
+ return trustedServer;
+}