--- a/installationservices/swcomponentregistry/source/server/scrserver.cpp Tue Aug 31 15:21:33 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +0,0 @@
-/*
-* Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "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:
-* Implements CScrServer providing management of SCR services.
-*
-*/
-
-
-/**
- @file
- @internalComponent
- @released
-*/
-
-#include "scrserver.h"
-#include "scrrequestimpl.h"
-#include "usiflog.h"
-#include <scs/cleanuputils.h>
-#include "scrhelperclient.h"
-#include <scs/securityutils.h>
-
-using namespace Usif;
-
-static const TUint scrRangeCount = 13;
-
-static const TInt scrRanges[scrRangeCount] =
- {
- 0, // Range-0 - 0 to EBaseSession-1. Not used.
- CScsServer::EBaseSession, // Range-1 - EBaseSession to EBaseMustAllow exclusive.
- CScsServer::EBaseSession | EGetSingleComponentSize, // Modification and transaction APIs have custom checks
- CScsServer::EBaseSession | EGetComponentIdListSize, // Component-specific APIs are free for all
- CScsServer::EBaseSession | EGetApplicationLaunchersSize, // Getting all component IDs is restricted to ReadUserData
- CScsServer::EBaseSession | EGetIsMediaPresent, // Only allowed by apparc
- CScsServer::EBaseSession | EAddApplicationEntry, // Component-specific APIs are free for all
- CScsServer::EBaseSession | EGetPluginUidWithMimeType, // Custom checks (as with the rest of modification APIs)
- CScsServer::EBaseSession | EAddSoftwareType, // File filter sub-sessions and plugin-fetching APIs are free for all
- CScsServer::EBaseSubSession | EOpenComponentsView, // Software Type management APIs are only allowed for SWI
- CScsServer::EBaseSubSession | EOpenFileList, // Component filter sub-sessions require ReadUserData
- CScsServer::EBaseSubSession | EOpenApplicationRegistrationInfoView, // Always pass
- CScsServer::EBaseMustAllow // Application Registration view to be only allowed by apparc, the rest of the range is reserved for SCS, and must be allowed( EBaseMustAllow to KMaxTInt inclusive)
- };
-
-static const TUint8 scrElementsIndex[scrRangeCount] =
- {
- CPolicyServer::ENotSupported, // Range 0 is not supported.
- CPolicyServer::ECustomCheck,
- CPolicyServer::EAlwaysPass,
- 0, // Require ReadUserData
- 2, // Only Apparc process can invoke
- CPolicyServer::EAlwaysPass,
- CPolicyServer::ECustomCheck,
- CPolicyServer::EAlwaysPass,
- 1, // Only SWI process can invoke
- 0, // Require ReadUserData
- CPolicyServer::EAlwaysPass,
- 2, // Only Apparc process can invoke
- CPolicyServer::EAlwaysPass
- };
-
-static const CPolicyServer::TPolicyElement scrElements[] =
- {
- {_INIT_SECURITY_POLICY_C1(ECapabilityReadUserData), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_S0(KSisRegistryServerSid.iId), CPolicyServer::EFailClient},
- {_INIT_SECURITY_POLICY_S0(KApparcServerSid.iId), CPolicyServer::EFailClient}
- };
-
-static const CPolicyServer::TPolicy scrPolicy =
- {
- CPolicyServer::EAlwaysPass, // Allow all connections
- scrRangeCount,
- scrRanges,
- scrElementsIndex,
- scrElements,
- };
-
-//
-// CScrServer
-//
-
-CScrServer::CScrServer()
-/**
- Intializes the SCR server object with its version and policy.
- */
- : CScsServer(ScrServerVersion(), scrPolicy)
- {
- DEBUG_PRINTF(_L8("SCR server construction!"));
- }
-
-CScrServer::~CScrServer()
-/**
- Destructor. Cleanup the SCR Server.
- */
- {
- DEBUG_PRINTF(_L8("SCR server destruction!"));
- delete iRequestImpl;
- iDatabaseFile.Close();
- iJournalFile.Close();
- iFs.Close();
- iSubsessionOwners.Close();
- }
-
-
-CScrServer* CScrServer::NewLC()
-/**
- Factory function allocates a new instance of CScrServer.
-
- @return The newly created instance of CScrServer which is left on the cleanup stack.
- */
- {
- CScrServer *self = new (ELeave) CScrServer();
- CleanupStack::PushL(self);
- self->ConstructL();
- return self;
- }
-
-
-void CScrServer::ConstructL()
-/**
- Second phase constructor starts the SCR server.
- */
- {
- // StartL() must be called first in order to avoid concurrency issue when starting the server from two or more processes
- StartL(KSoftwareComponentRegistryName);
- CScsServer::ConstructL(KScrServerShutdownPeriod);
- SetupL();
- }
-
-void CheckFilePathL(RFs& aFs, RFile& aFile, const TDesC& aExpectedPath)
- {
- RBuf fileName;
- fileName.CreateL(KMaxFileName);
- fileName.CleanupClosePushL();
- User::LeaveIfError(aFile.FullName(fileName));
-
- RBuf expectedFileName;
- expectedFileName.CreateL(aExpectedPath.Length());
- expectedFileName.CleanupClosePushL();
- expectedFileName.Copy(aExpectedPath);
- expectedFileName[0] = aFs.GetSystemDriveChar();
-
- __ASSERT_ALWAYS(!fileName.CompareF(expectedFileName), User::Leave(KErrBadHandle));
-
- CleanupStack::PopAndDestroy(2, &fileName); // fileName, expectedFileName
- }
-
-void CScrServer::SetupL()
- {
- // Connect to the file server
- User::LeaveIfError(iFs.Connect());
- User::LeaveIfError(iFs.ShareProtected());
-
- // Connect to the SCR database
- RScrHelper sh;
- User::LeaveIfError(sh.Connect());
- CleanupClosePushL(sh);
-
- // Retrieve handles for database and journal files
- sh.RetrieveFileHandlesL(iDatabaseFile, iJournalFile);
- CleanupStack::PopAndDestroy(&sh);
-
- // Check if the retrieved file handles belong to the expected files (KScrDatabaseFilePath/KScrJournalFilePath).
- // This is an extra security measure in the SCR to check that the file handle transferred from SCR Helper Server
- // really corresponds to scr.db/scr.db-journal in the expected location.
- CheckFilePathL(iFs, iDatabaseFile, KScrDatabaseFilePath);
- CheckFilePathL(iFs, iJournalFile, KScrJournalFilePath);
-
- ReconnectL();
- }
-
-CScsSession* CScrServer::DoNewSessionL(const RMessage2& aMessage)
-/**
- Implement CScsServer by allocating a new instance of CScrSession.
-
- @param aMessage Standard server-side handle to message.
- @return New instance of the SCR session class which is owned by the caller.
- */
- {
- DEBUG_PRINTF(_L8("SCR session creation!"));
- return CScrSession::NewL(*this, aMessage);
- }
-
-CPolicyServer::TCustomResult CScrServer::CheckComponentIdMatchingEnvironmentL(const RMessage2& aMsg, TBool aCheckForSingleApp)
- {
- TComponentId componentId = 0;
- if(aCheckForSingleApp)
- {
- // Get the application uid from RMessage2
- TInt applicationUid = aMsg.Int0();
- // Get the component id for the application
- if(!iRequestImpl->GetComponentIdForAppInternalL(TUid::Uid(applicationUid), componentId))
- return EFail;
- }
- else
- {
- componentId = CScrRequestImpl::GetComponentIdFromMsgL(aMsg);
- }
-
- TSecureId clientSid = aMsg.SecureId();
-
- if (componentId == 0)
- {
- if (clientSid == KSisRegistryServerSid)
- return EPass;
- }
-
- TBool vaildSid = EFalse;
- RArray<TSecureId> installerSids;
- CleanupClosePushL(installerSids);
- if (iRequestImpl->GetInstallerOrExecutionEnvSidsForComponentL(componentId, installerSids))
- {
- TInt count = installerSids.Count();
- for (TInt i = 0; i < count; i++)
- {
- if (clientSid == installerSids[i])
- {
- vaildSid = ETrue;
- break;
- }
- }
- }
- CleanupStack::PopAndDestroy(&installerSids);
-
- if (vaildSid)
- return EPass;
-
- DEBUG_PRINTF3(_L("Neither installer nor execution environment matched the client while checking for component-matching environment. Client SID %d, Component ID %d"),
- TUint32(clientSid), componentId);
- return EFail;
- }
-
-CPolicyServer::TCustomResult CScrServer::CheckDeleteComponentAllowedL(const RMessage2& aMsg)
- {
- const TUint KSifServerSid = 0x10285BCB;
-
- if (CheckComponentIdMatchingEnvironmentL(aMsg) == EPass)
- return EPass;
-
- TSecureId clientSid = aMsg.SecureId();
- TComponentId componentId = CScrRequestImpl::GetComponentIdFromMsgL(aMsg);
- // If a component does not have corresponding environments, it means that it is orphaned. In this case, SIF is allowed to forcefully remove it
- if (iRequestImpl->GetIsComponentOrphanedL(componentId) && (TUint32(clientSid) == KSifServerSid))
- {
- DEBUG_PRINTF2(_L("Allowing SIF to uninstall orphaned component %d"), componentId);
- return EPass;
- }
-
- return EFail;
- }
-
-CPolicyServer::TCustomResult CScrServer::CheckSoftwareNameMatchingEnvironmentL(const RMessage2& aMsg)
- {
- HBufC* softwareTypeName = CScrRequestImpl::GetSoftwareTypeNameFromMsgLC(aMsg);
- TSecureId clientSid = aMsg.SecureId();
-
- TBool vaildSid = EFalse;
- RArray<TSecureId> installerSids;
- CleanupClosePushL(installerSids);
- if (iRequestImpl->GetSidsForSoftwareTypeL(softwareTypeName, installerSids))
- {
- TInt count = installerSids.Count();
- for (TInt i = 0; i < count; i++)
- {
- if (clientSid == installerSids[i])
- {
- vaildSid = ETrue;
- break;
- }
- }
- }
- CleanupStack::PopAndDestroy(2, softwareTypeName);
-
- if (vaildSid)
- return EPass;
-
- DEBUG_PRINTF(_L("Client Sid is not a valid one software type!"));
- return EFail;
- }
-
-CPolicyServer::TCustomResult CScrServer::CheckAllowedFilePathL(const RMessage2& aMsg)
- {
- HBufC* fileName = CScrRequestImpl::ReadFileNameFromMsgLC(aMsg);
-
- // Retrieve the required capabilities for write access to this path
- TCapabilitySet requiredCapabilities = SecCommonUtils::FileModificationRequiredCapabilitiesL(*fileName, aMsg.SecureId());
-
- TBool result = EFalse;
- TBool allFilesRequired = requiredCapabilities.HasCapability(ECapabilityAllFiles);
- TBool tcbRequired = requiredCapabilities.HasCapability(ECapabilityTCB);
-
- // Test whether the client has at least one of the required capabilities
- if (allFilesRequired)
- result = aMsg.HasCapability(ECapabilityAllFiles);
- if (!result && tcbRequired)
- result = aMsg.HasCapability(ECapabilityTCB);
- if (!allFilesRequired && !tcbRequired)
- result = ETrue;
-
- CleanupStack::PopAndDestroy(fileName);
- return result ? EPass : EFail;
- }
-
-CPolicyServer::TCustomResult CScrServer::CheckClientIsInstallerL(const RMessage2& aMsg)
- {
- TSecureId clientSid = aMsg.SecureId();
- DEBUG_PRINTF2(_L("The client SID is 0x%X"), clientSid.iId);
- TBool isInstallerSid = iRequestImpl->IsInstallerOrExecutionEnvSidL(clientSid);
- return isInstallerSid ? EPass : EFail;
- }
-
-CPolicyServer::TCustomResult CScrServer::CheckCommonComponentPropertySettableL(const RMessage2& aMsg, TCapability aRequiredCapability)
- {
- // Setting a common component property is allowed either for the owning installer or for a process with corresponding capability
- if (CheckComponentIdMatchingEnvironmentL(aMsg) == EPass)
- return EPass;
- return aMsg.HasCapability(aRequiredCapability)? EPass : EFail;
- }
-
-CPolicyServer::TCustomResult CScrServer::CustomSecurityCheckL(const RMessage2& aMsg, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/)
- {
- // SCS framework adds its own bitmask to the function id - we need to strip it in order to detect the actual function invoked
- TInt functionId = StripScsFunctionMask(aMsg.Function());
-
- switch (functionId)
- {
- case ECreateTransaction:
- case ERollbackTransaction:
- case ECommitTransaction:
- return CheckClientIsInstallerL(aMsg);
- case EAddComponent:
- case EAddComponentDependency:
- case EDeleteComponentDependency:
- return CheckSoftwareNameMatchingEnvironmentL(aMsg);
- case ERegisterComponentFile:
- case ESetFileStringProperty:
- case ESetFileNumericProperty:
- case EDeleteFileProperty:
- case EUnregisterComponentFile:
- // For file registration we check that the client is actually allowed to modify files under this location
- // We do not check for the installer SID, since if the client can write to this location, then registering this location for other components
- // does not pose additional risk
- return CheckAllowedFilePathL(aMsg);
- case ESetComponentLocalizableProperty:
- case ESetComponentNumericProperty:
- case ESetComponentBinaryProperty:
- case ESetComponentName:
- case ESetComponentVendor:
- case ESetComponentVersion:
- case ESetComponentSize:
- case EDeleteComponentProperty:
- case ESetScomoState:
- case ESetIsComponentPresent:
- return CheckComponentIdMatchingEnvironmentL(aMsg);
- case EDeleteComponent:
- return CheckDeleteComponentAllowedL(aMsg);
- case ESetIsComponentRemovable:
- return CheckCommonComponentPropertySettableL(aMsg, ECapabilityAllFiles);
- case ESetIsComponentDrmProtected:
- case ESetIsComponentHidden:
- case ESetIsComponentKnownRevoked:
- case ESetIsComponentOriginVerified:
- return CheckCommonComponentPropertySettableL(aMsg, ECapabilityWriteDeviceData);
- case EAddApplicationEntry:
- case EDeleteApplicationEntries:
- return CheckComponentIdMatchingEnvironmentL(aMsg);
- case EDeleteApplicationEntry:
- return CheckComponentIdMatchingEnvironmentL(aMsg, ETrue);
- default:
- DEBUG_PRINTF2(_L("Unknown function was invoked in CustomSecurityCheck - %d"), functionId);
- __ASSERT_DEBUG(0, User::Invariant());
- return EFail;
- }
- }
-
-void CScrServer::ReconnectL()
- {
- DeleteObjectZ(iRequestImpl);
- iRequestImpl = CScrRequestImpl::NewL(iFs, iDatabaseFile, iJournalFile);
- }
-
-void CScrServer::AddSubsessionOwnerL(CScrSession* aSession)
- {
- iSubsessionOwners.InsertInAddressOrderAllowRepeatsL(aSession);
- }
-
-void CScrServer::RemoveSubsessionOwner(CScrSession* aSession)
- {
- TInt index = iSubsessionOwners.FindInAddressOrder(aSession);
- if(KErrNotFound != index)
- iSubsessionOwners.Remove(index);
- }
-
-TBool CScrServer::IsTheOnlySubsessionOwner(CScrSession* aSession)
- {
- TInt firstElementIdx = 0;
- TInt lastElementIdx = iSubsessionOwners.Count();
- // if both first element and the last element in the array is the provided session
- // it means that all active subsessions is owned by this session.
- if(firstElementIdx == iSubsessionOwners.SpecificFindInAddressOrder(aSession, EArrayFindMode_First) &&
- lastElementIdx == iSubsessionOwners.SpecificFindInAddressOrder(aSession, EArrayFindMode_Last))
- {
- return ETrue;
- }
- return EFalse;
- }
-
-TInt CScrServer::SubsessionCount()
- {
- return iSubsessionOwners.Count();
- }
-
-void CScrServer::SetTransactionOwner(CScrSession* aSession)
- {
- iTransactionOwningSession = aSession;
- }
-
-
-TBool CScrServer::IsTransactionInProgress()
- {
- if(iTransactionOwningSession)
- return ETrue;
- else
- return EFalse;
- }
-
-
-TBool CScrServer::IsTransactionOwner(CScrSession* aSession)
- {
- __ASSERT_ALWAYS(aSession, User::Invariant());
- if(aSession == iTransactionOwningSession)
- return ETrue;
- else
- return EFalse;
- }
-
-void CScrServer::DoPreHeapMarkOrCheckL()
-/**
- This function is called by the framework just before settingchecking a heap mark. We need to compress/free memory
- down to a state which should be the same both before and after the test operations.
-*/
-{
-#ifdef _DEBUG
-iSubsessionOwners.Compress();
-DeleteObjectZ(iRequestImpl);
-#endif
-}
-
-void CScrServer::DoPostHeapMarkOrCheckL()
-/**
- This function is called by the framework just before settingchecking a heap mark. We need to compress/free memory
- down to a state which should be the same both before and after the test operations.
-*/
-{
-#ifdef _DEBUG
-this->ReconnectL();
-#endif
-}