diff -r 000000000000 -r 99ef825efeca rtsecuritymanager/rtsecuritymanagerclient/src/rtsecmgrclient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rtsecuritymanager/rtsecuritymanagerclient/src/rtsecmgrclient.cpp Mon Mar 30 12:51:20 2009 +0300 @@ -0,0 +1,591 @@ +/* +* Copyright (c) 2007-2008 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: Defines security manager client side session and sub-session classes + * +*/ + + + + + + + +#include +#include +#include +#include +#include +#include "rtsecmgrmsg.h" +#include "rtsecmgrdef.h" +#include "rtsecmgrclient.h" +#include "rtsecmgrtracer.h" + +#ifdef _DEBUG +_LIT(KServerStartFailed, "Security manager server starting failed"); +#endif + +// --------------------------------------------------------------------------- +// Defintiion of default private constructor +// --------------------------------------------------------------------------- +// +RSecMgrSession::RSecMgrSession() + { + } + +// --------------------------------------------------------------------------- +// Connects to the runtime security manager server +// +// This function attemtps to kick start security manager server if +// it is not running already. The number of attempts is currently 2. +// The number of message slot is defaulted to 4. +// --------------------------------------------------------------------------- +// +TInt RSecMgrSession::Connect() + { + RTSecMgrTraceFunction("RSecMgrSession::Connect()") ; + TInt retry(KSecSrvClientTryCount); // Try this twice + TInt err(KErrNone); + while (retry>KErrNone) + { + // Try to create a Server session + err = CreateSession ( KSecServerProcessName, Version (), + KDefaultMessageSlots); + + if ( err != KErrNotFound && err != KErrServerTerminated) + { + // KErrNone or unrecoverable error + if ( err != KErrNone) + { +#ifdef _DEBUG + RDebug::Print(KServerStartFailed); +#endif + } + retry = 0; + } + else + { + // Return code was KErrNotFound or KErrServerTerminated. + // Try to start a new security manager server instance + err = StartSecManagerServer (); + if ( err != KErrNone && err != KErrAlreadyExists) + { + // Unrecoverable error +#ifdef _DEBUG + RDebug::Print(KServerStartFailed); +#endif + retry = 0; + } + } + + retry--; + } + return (err); + } + +// --------------------------------------------------------------------------- +// Starts runtime security manager server +// +// --------------------------------------------------------------------------- +// +TInt RSecMgrSession::StartSecManagerServer() const + { + RTSecMgrTraceFunction("RSecMgrSession::StartSecManagerServer()") ; + RProcess server; + const TUidType serverUid( KNullUid, KSecMgrServerUid2, KNullUid); + TInt err = server.Create ( ServerLocation (), + KNullDesC, + serverUid, + EOwnerProcess); + + // Return error code if we the process couldn't be created + if ( KErrNone == err) + { + // Rendezvous is used to detect server start + TRequestStatus status; + server.Rendezvous ( status); + if ( status != KRequestPending) + { + // Log Abort Error +#ifdef _DEBUG + RDebug::Print(KServerStartFailed); +#endif + server.Kill ( 0); // Abort startup + } + else + { + server.Resume (); // Logon OK - start the server + } + User::WaitForRequest (status); // Wait for start or death + + if ( server.ExitType ()== EExitPanic) + { +#ifdef _DEBUG + RDebug::Print(KServerStartFailed); +#endif + err = KErrGeneral; + } + else + { + err = status.Int (); + } + + // We can close the handle now + server.Close (); + } + return err; + } + +// --------------------------------------------------------------------------- +// Returns runtime security manager server location +// +// --------------------------------------------------------------------------- +// +TFullName RSecMgrSession::ServerLocation() const + { + TFullName fullPathAndName; + fullPathAndName.Append ( KSecMgrServerExeName); + return fullPathAndName; + } + +// --------------------------------------------------------------------------- +// Returns the earliest version number of the security manager server +// +// --------------------------------------------------------------------------- +// +TVersion RSecMgrSession::Version(void) const + { + return (TVersion(KRTSecMgrServMajorVersionNumber,KRTSecMgrServMinorVersionNumber,KRTSecMgrServBuildVersionNumber)); + } + +// --------------------------------------------------------------------------- +// A request to close the session. +// +// It makes a call to the server, which deletes the object container and object index +// for this session, before calling Close() on the base class. +// --------------------------------------------------------------------------- +// +void RSecMgrSession::Close() + { + if(iHandle) + { + SendReceive (ESecServCloseSession); + RSessionBase::Close(); + } + } + +// +// Registers the runtime security policy with security manager. This method +// packs the message parameters required for registering the policy. +// +// The various parameters required for SetPolicy operation are : +// +// Operation Code : ESetPolicy +// IPC Argument[0] : Policy Identifier (as inOut parameter) +// IPC Argument[1] : SecurityPolicy FileHandle +// IPC Argument[2] : SecurityPolicy FileSession object +// IPC Argument[3] : none +// +TInt RSecMgrSession::SetPolicy(const RFile& aSecPolicy) + { + TPckgBuf pckgPId; + TIpcArgs args(&pckgPId); + + TInt ret = aSecPolicy.TransferToServer (args, EMsgArgOne, + EMsgArgTwo); + + if ( KErrNone==ret) + { + ret = SendReceive (ESetPolicy, args); + + if ( KErrNone==ret) + return pckgPId (); // Extract the policyID returned from the server. + } + + return ret; + } + +TPolicyID RSecMgrSession::SetPolicy(const TDesC8& aPolicyBuffer) + { + TInt ret(ErrInvalidParameters); + if(0==aPolicyBuffer.CompareC(KNullDesC8)) + { + return ret; + } + + TFileName tempDirPath; + TFileName tempPath; + + { + RFs fileSession; + if ( KErrNone==fileSession.Connect ()) + { + fileSession.PrivatePath (tempDirPath); + BaflUtils::EnsurePathExistsL (fileSession, tempDirPath); + + RFile secPolicyFile; + secPolicyFile.Temp (fileSession, tempDirPath, tempPath, EFileWrite); + secPolicyFile.Write(aPolicyBuffer); + secPolicyFile.Close(); + } + fileSession.Close(); + } + + RFs fileSession; + if ( KErrNone==fileSession.Connect ()) + { + CleanupClosePushL (fileSession); + if ( KErrNone==fileSession.ShareProtected ()) + { + RFile secPolicyFile; + + if(KErrNone == secPolicyFile.Open(fileSession,tempPath,EFileRead)) + { + ret = SetPolicy (secPolicyFile); + + secPolicyFile.Close(); + + } + + fileSession.Delete (tempPath); + } + + CleanupStack::PopAndDestroy (&fileSession);//fileSession + } + + fileSession.Close(); + + return ret; + } + +// +// UnRegisters a registered security policy. Runtimes should call this function +// to de-register the already registered security policy. +// +// The various parameters required for UnSetPolicy operation are : +// +// Operation Code : EUnsetPolicy +// IPC Argument[0] : Policy Identifier to un-register +// IPC Argument[1] : Successcode (as inOut parameter) +// IPC Argument[2] : none +// IPC Argument[3] : none +// +TInt RSecMgrSession::UnSetPolicy(TPolicyID aPolicyID) + { + if ( aPolicyID<=KErrNone) + return ErrInvalidPolicyID; + + TPckgBuf sucess(KErrNone); + TIpcArgs args(aPolicyID, &sucess); + + TInt ret = SendReceive (EUnsetPolicy, args); + + if ( KErrNone==ret) + return sucess (); // Extract the value returned from the server. + + return ret; + } + +// +// Updates an already registered security policy. Runtimes should call this function +// to update their policy. +// +// The various parameters required for UpdatePolicy operation are : +// +// Operation Code : EUpdatePolicy +// IPC Argument[0] : Policy Identifier +// IPC Argument[1] : SecurityPolicy FileHandle +// IPC Argument[2] : SecurityPolicy FileSession object +// IPC Argument[3] : none +// +TPolicyID RSecMgrSession::UpdatePolicy(TPolicyID aPolicyID, + const RFile& aSecPolicy) + { + if ( aPolicyID<=KErrNone) + { + return ErrInvalidPolicyID; + } + + TPckgBuf pckgPID(aPolicyID); + TIpcArgs args(&pckgPID); + + TInt ret = aSecPolicy.TransferToServer (args, EMsgArgOne, + EMsgArgTwo); + + if ( KErrNone==ret) + { + ret = SendReceive (EUpdatePolicy, args); + + if ( KErrNone==ret) + ret = pckgPID (); + } + + return ret; + } + +TPolicyID RSecMgrSession::UpdatePolicy(TPolicyID aPolicyID, + const TDesC8& aPolicyBuffer) + { + TInt ret(ErrInvalidParameters); + if(0==aPolicyBuffer.CompareC(KNullDesC8)) + { + return ret; + } + + TFileName tempDirPath; + TFileName tempPath; + + { + RFs fileSession; + if ( KErrNone==fileSession.Connect ()) + { + fileSession.PrivatePath (tempDirPath); + BaflUtils::EnsurePathExistsL (fileSession, tempDirPath); + + RFile secPolicyFile; + secPolicyFile.Temp (fileSession, tempDirPath, tempPath, EFileWrite); + secPolicyFile.Write(aPolicyBuffer); + secPolicyFile.Close(); + } + fileSession.Close(); + } + + RFs fileSession; + if ( KErrNone==fileSession.Connect ()) + { + CleanupClosePushL (fileSession); + if ( KErrNone==fileSession.ShareProtected ()) + { + RFile secPolicyFile; + + if(KErrNone == secPolicyFile.Open(fileSession,tempPath,EFileRead)) + { + + ret = UpdatePolicy (aPolicyID, secPolicyFile); + + secPolicyFile.Close(); + + } + + fileSession.Delete (tempPath); + } + + CleanupStack::PopAndDestroy (&fileSession);//fileSession + } + + fileSession.Close(); + + return ret; + } + +// +// Registers a script/executable. Runtimes should specify the trust information +// of the script to be registered. +// +// Operation Code : ERegisterScript +// IPC Argument[0] : Policy Identifier +// IPC Argument[1] : Script Identifier (as inOut Parameter) +// IPC Argument[2] : none +// IPC Argument[3] : none +// +TExecutableID RSecMgrSession::RegisterScript(TPolicyID aPolicyID, const CTrustInfo& /*aTrustInfo*/) + { + if ( aPolicyID scriptID(KAnonymousScript); + TIpcArgs args(aPolicyID, &scriptID); + + TInt result = SendReceive (ERegisterScript, args); + + if ( KErrNone==result) + result=scriptID (); + + return result; + } + +// +// Registers a script/executable. Runtimes should specify the trust information +// of the script to be registered. +// +// Operation Code : ERegisterScript +// IPC Argument[0] : Policy Identifier +// IPC Argument[1] : Script Identifier (as inOut Parameter) +// IPC Argument[2] : Hash value of script +// IPC Argument[3] : none +// +TExecutableID RSecMgrSession::RegisterScript(TPolicyID aPolicyID, + const TDesC& aHashMarker, const CTrustInfo& /*aTrustInfo*/) + { + __UHEAP_MARK; + + if(!(aHashMarker.Compare(KNullDesC))) + return ErrInvalidParameters; + CRTSecMgrRegisterScriptMsg* scriptMsg = CRTSecMgrRegisterScriptMsg::NewL ( + aPolicyID, aHashMarker); + + HBufC8* dataDes(NULL); + TRAPD(ret, dataDes = scriptMsg->PackMsgL()); + if ( dataDes) + { + TExecutableID scriptID(KAnonymousScript); + TPckgBuf scriptIDBuf(scriptID); + TIpcArgs args(dataDes, &scriptIDBuf); + + ret = SendReceive (ERegisterScriptWithHash, args); + delete dataDes; + + if(KErrNone==ret) + ret = scriptIDBuf(); + } + + delete scriptMsg; + + __UHEAP_MARKEND; + + return ret; + } + +// +// De-Registers a script/executable. Runtimes should pass the previously registered +// script identifier corresponding to the script to be de-registered. +// +// Operation Code : EUnRegisterScript +// IPC Argument[0] : Script Identifier +// IPC Argument[1] : Policy Identifier +// IPC Argument[2] : Success code (as inOut parameter) +// IPC Argument[3] : none +// +TInt RSecMgrSession::UnRegisterScript(TExecutableID aExeID, TPolicyID aPolicyID) + { + if (aExeID<=KErrNone) + return ErrInvalidScriptID; + if (aPolicyID<=KErrNone) + return ErrInvalidPolicyID; + + TPckgBuf errCode(KErrNone); + TIpcArgs args(aExeID, aPolicyID, &errCode); + + TInt result = SendReceive (EUnRegisterScript, args); + + if ( KErrNone==result) + return errCode (); + + return result; + } + +RSecMgrSubSession::RSecMgrSubSession() + { + + } +// +// Opens client-side sub-session for a registered script. The script session is modelled as a +// client side sub-session with a peer server side sub-session. +// +TInt RSecMgrSubSession::Open(const RSessionBase& aSession, + CScript& aScriptInfo, TPolicyID aPolicyID, const TDesC& aHashValue) + { + TIpcArgs args(aScriptInfo.ScriptID (), aPolicyID); + + TInt errCode(KErrNone); + errCode = iFs.Connect(); + if(errCode == KErrNone) + { + if ( KAnonymousScript==aScriptInfo.ScriptID ()) + errCode = CreateSubSession (aSession, EGetTrustedUnRegScriptSession, + args); + else + errCode = CreateSubSession (aSession, EGetScriptSession, args); + + if ( errCode==KErrNone) + { + // Retrieve the RFs and RFile handles from the server + TPckgBuf fh; // sub-session (RFile) handle + TIpcArgs args(&fh); + + RFile file; + CleanupClosePushL(file); + + if ( KErrNone==errCode) + { + iFs.ShareProtected (); + + TFileName tempDirPath; + TFileName tempPath; + + iFs.PrivatePath (tempDirPath); + BaflUtils::EnsurePathExistsL (iFs, tempDirPath); + + errCode = file.Temp (iFs, tempDirPath, tempPath, EFileWrite); + + if ( KErrNone==errCode) + { + file.TransferToServer (args, EMsgArgOne, EMsgArgTwo); + errCode = SendReceive (EGetScriptFile, args); + + if ( KErrNone==errCode) + { + RFileReadStream rfs(file); + CleanupClosePushL(rfs); + aScriptInfo.InternalizeL (rfs); + TBufC hashValue(aScriptInfo.Hash()); + if(0 != hashValue.Compare(KNullDesC)) + { + if(!aScriptInfo.HashMatch(aHashValue)) + { + //hash check failed + errCode = KErrNotFound; + } + } + + CleanupStack::PopAndDestroy(&rfs); + } + } + iFs.Delete (tempPath); + } + + CleanupStack::PopAndDestroy(&file); + } + } + return errCode; + } + +// +// Opens client-side sub-session for an un-registered trusted script. The script session is modelled as a +// client side sub-session with a peer server side sub-session. +// +TInt RSecMgrSubSession::Open(const RSessionBase& aSession, + CScript& aScriptInfo, TPolicyID aPolicyID, const CTrustInfo& /*aTrustInfo*/) + { + return Open (aSession, aScriptInfo, aPolicyID); + } + +// +// Updates the blanket permission data of the script +// +TInt RSecMgrSubSession::UpdatePermGrant(TExecutableID aScriptID, + TPermGrant aPermGrant, TPermGrant aPermDenied) const + { + TIpcArgs args(aScriptID, (TInt)aPermGrant, (TInt)aPermDenied); + return SendReceive (EUpdatePermanentGrant, args); + } + +// +// Close the subsession. +// +void RSecMgrSubSession::Close() + { + iFs.Close(); + RSubSessionBase::CloseSubSession (ECloseScriptSession); + } +