diff -r 000000000000 -r b497e44ab2fc policymanagement/policyengine/policyengineserver/src/PolicyManager.cpp --- /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 +#include + + +// 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 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 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 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 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 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 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 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 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 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 certInfoPck( certInfo); + aMessage.ReadL(0, certInfoPck, 0); + + //TRole + TRole role; + TPckg 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 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 serverid; + User::LeaveIfError( dmutil.GetDMSessionServerId( serverid)); + TRAPD( err, trustedServer = CPolicyStorage::PolicyStorage()->IsServerIdValid( serverid) ); + User::LeaveIfError( err ); + CleanupStack::PopAndDestroy( &dmutil); + + return trustedServer; +}