CPolicyServer Class Reference

class CPolicyServer : public CServer2

A security policy framework built on top of the normal CServer2 class.

The two major functions of the Policy Server framework are to check a received message against a security policy and then to perform an action depending on the result of this check. The exact behaviour is defined by the contents of the TPolicy structure given in the constructor for CPolicyServer.

The processing performed when a server receives a message are describe below. This should aid understanding of the interaction of the TPolicy structure and virtual member functions which may be implemented by classes derived from CPolicyServer.

Checking the Security Policy

On receipt of a message, the message function number is used to search the list of ranges pointed to by TPolicy::iRanges. This yields a range number R, which is between 0 and TPolicy::iRangeCount-1. The policy index, X, for this range is then fetched from TPolicy::iElementsIndex[R]. If the message is a Connect message, then X is fetched directly from TPolicy::iOnConnect instead.

The further action taken is determined by the value of X.
  • If X==TSpecialCaseEAlwaysPass, the message is processed as normal; either by passing it to the ServiceL() method of a session, or, in the case of a connection message, a new session is created.

  • If X==TSpecialCaseENotSupported, the message is completed with KErrNotSupported.

  • If X==TSpecialCaseECustomCheck, a call to the virtual function CustomSecurityCheckL() is made. The implementation of this method must return one of the TCustomResult enumerations which determine what further action is to be taken:
    • TCustomResult::EPass The message is processed as normal; either by passing it to the ServiceL() method of a session, or, in the case of a connection message, a new session is created.

    • TCustomResult::EFail This causes CheckFailedL() to be called with the action specified by the aAction reference given to CustomSecurityCheckL() (This defaults to TFailureAction::EFailClient.)

    • TCustomResult::EAsync The derived class is responsible for further processing of the message, the Policy Server framework will do nothing more with it.

  • If X < TSpecialCase::ESpecialCaseHardLimit, X is taken as an index into the array of TPolicyElement objects pointed to by TPolicy::iElements. The platform security attributes of the process which sent the message being processed are checked against the security policy specified in this TPolicyElement. If the process possesses all of the attributes specified then the message processed as normal. Otherwise, CheckFailedL() is called with the action value specified in the TPolicyElement .

Handling Policy Check Failure

The CheckFailedL() method is called when a security check has failed. It performs an action according to the aAction value given to it:

  • If aAction==TFailureActionEFailClient, the message is completed with KErrPermissionDenied.

  • If aAction==TFailureActionEPanicClient, the client thread is panicked.

  • If aAction < 0 a call to the virtual function CustomFailureActionL() is made. The implementation of this method must return one of the TCustomResult enumerations which determine what further action is to be taken:
    • TCustomResult::EPass The message is processed as normal; either by passing it to the ServiceL() method of a session, or, in the case of a connection message, a new session is created.

    • TCustomResult::EFail The message is completed with KErrPermissionDenied.

    • TCustomResult::EAsync The derived class is responsible for further processing of the message, the Policy Server framework will do nothing more with it.

Inherits from

Public Member Functions
IMPORT_C voidCheckFailedL(const RMessage2 &, TInt, const TSecurityInfo &)
IMPORT_C voidProcessError(const RMessage2 &, TInt)
IMPORT_C voidProcessL(const RMessage2 &)
Protected Member Functions
CPolicyServer(TInt, const TPolicy &, TServerType)
IMPORT_C TCustomResultCustomFailureActionL(const RMessage2 &, TInt, const TSecurityInfo &)
IMPORT_C TCustomResultCustomSecurityCheckL(const RMessage2 &, TInt &, TSecurityInfo &)
IMPORT_C TIntExtension_(TUint, TAny *&, TAny *)
Private Member Functions
const CPolicyServer::TPolicyElement *FindPolicyElement(TInt, TUint &)
IMPORT_C TIntRunError(TInt)
IMPORT_C voidRunL()
Inherited Functions
CActive::CActive(TInt)
CActive::Cancel()
CActive::Deque()
CActive::IsActive()const
CActive::IsAdded()const
CActive::Priority()const
CActive::SetActive()
CActive::SetPriority(TInt)
CActive::~CActive()
CBase::CBase()
CBase::Delete(CBase *)
CBase::operator new(TUint)
CBase::operator new(TUint,TAny *)
CBase::operator new(TUint,TLeave)
CBase::operator new(TUint,TLeave,TUint)
CBase::operator new(TUint,TUint)
CBase::~CBase()
CServer2::CServer2(TInt,TServerType)
CServer2::DoCancel()
CServer2::DoConnect(const RMessage2 &)
CServer2::Message()const
CServer2::ReStart()
CServer2::Server()const
CServer2::SetMaster(const CServer2 *)
CServer2::SetPinClientDescriptors(TBool)
CServer2::Start(const TDesC &)
CServer2::StartL(const TDesC &)
CServer2::~CServer2()
Public Member Enumerations
enumTCustomResult { EPass = 0, EFail = 1, EAsync = 2 }
enumTFailureAction { EFailClient = 0, EPanicClient = 1 }
enumTSpecialCase { ECustomCheck = 255u, ENotSupported = 254u, EAlwaysPass = 253u, ESpecialCaseLimit = 252u, ESpecialCaseHardLimit = 250u }
Inherited Enumerations
CActive:TPriority
CServer2:TPanic
CServer2:TServerType
Private Attributes
const TPolicy &iPolicy
Inherited Attributes
CActive::iStatus
CServer2::iSessionIter

Constructor & Destructor Documentation

CPolicyServer(TInt, const TPolicy &, TServerType)

IMPORT_CCPolicyServer(TIntaPriority,
const TPolicy &aPolicy,
TServerTypeaType = EUnsharableSessions
)[protected]

Construct a policy server

Parameters

TInt aPriorityActive object priority for this server
const TPolicy & aPolicyReference to a policy object describing the security checks required for each message type. The server does not make a copy of policy, and therefore this object must exist for the lifetime of the server. It is recommended that aPolicy is in const static data.
TServerType aType = EUnsharableSessionsType of session sharing supported by this server

Member Functions Documentation

CheckFailedL(const RMessage2 &, TInt, const TSecurityInfo &)

IMPORT_C voidCheckFailedL(const RMessage2 &aMsg,
TIntaAction,
const TSecurityInfo &aMissing
)

Called when a security check has failed.

The aAction parameter determines the action taken:
  • If aAction==TFailureActionEFailClient, the message is completed with KErrPermissionDenied.

  • If aAction==TFailureActionEPanicClient, the client thread is panicked.

  • If aAction < 0 a call to the virtual function CustomFailureActionL() is made.

This function should only ever be called by derived implementations if asynchronous security checks are in use.

Parameters

const RMessage2 & aMsgThe message which failed its check.
TInt aActionThe action to take. (See description.)
const TSecurityInfo & aMissingA list of the security attributes that were missing from the checked process.

CustomFailureActionL(const RMessage2 &, TInt, const TSecurityInfo &)

IMPORT_C TCustomResultCustomFailureActionL(const RMessage2 &aMsg,
TIntaAction,
const TSecurityInfo &aMissing
)[protected, virtual]

Performs a custom action after the failure of a security check. Derived server classes must implement this function if the aAction value passed to CheckFailedL() is less than zero. This can happened if the policy specified a negative number in the iAction member of any of the TPolicyElements, or, if the derived CustomSecurityCheckL() modified the value of aAction prior to returning.

If negative aAction values are used, there are two further cases to consider:
  1. The custom security check can synchronously decide if the message should pass. In this case, the derived implementation must simply return either EPass or EFail depending on the result of the security check.

  2. The custom security check needs to use asynchronous methods in order to determine whether the message should still proceed. In this case, these asysnchronous methods should be started and then the EAsync value returned. Furthermore, implmentations returning EAsync commit to the following:
    • If the security check eventually passes, ProcessL() must be called with the appropriate message.

    • If the security check eventually fails, or if a fatal error condition occurs, including if the previously mentioned call to ProcessL() leaves; then CPolicyServer::ProcessError() should be called passing the message and relevant error code.

    • Pending messages on a given session need to be completed and discarded if the session is closed.

IMPORTANT NOTE. When processing a message asynchronously, a copy must be made of the RMessage2 object. Saving a refernece or pointer to the original message will produce unpredictable defects. This is because the object will be reused for the next message that the server receives.

The default implementation of this function panics the server.

A value from TCustomResult.

panic

CBase 95 If the default implementation is called.

Parameters

const RMessage2 & aMsgThe message to check
TInt aActionThe custom failure action requested. This is either a value from TFailureAction or a negative value which has meaning to the CustomFailureActionL() method of a derived class.
const TSecurityInfo & aMissingA const reference to the list of security attributes missing from the checked process. There are two cases to consider: (a) If this message was checked (and failed) by a static policy applied by the policy server framework, aMissing will contain a list of the security attributes that caused the policy to fail. An completely zeroed aMissing implies that an always fail policy was encountered. (b) If this message was failed by a custom security check, then aMissing will be zeroed unless the CustomSecurityCheckL() method filled it in.

CustomSecurityCheckL(const RMessage2 &, TInt &, TSecurityInfo &)

IMPORT_C TCustomResultCustomSecurityCheckL(const RMessage2 &aMsg,
TInt &aAction,
TSecurityInfo &aMissing
)[protected, virtual]

Performs a custom security check. Derived server classes must implement this function if any element in iElementsIndex has the value CPolicyServer::ECustomCheck. Similarly, if CPolicyServer::ECustomCheck is not used, then this function can be safely ignored.

If CPolicyServer::ECustomCheck is used, there are two further cases to consider:
  1. The custom security check can synchronously decide if the message should pass. In this case, the derived implementation must simply return either EPass or EFail depending on the result of the security check.

  2. The custom security check needs to use asynchronous methods in order to determine whether the message should procceed. In this case, these asysnchronous methods should be started and then the EAsync value returned. Furthermore, implmentations returning EAsync commit to the following:
    • If the security check eventually passes, ProcessL() must be called with the appropriate message.

    • If the security check eventually fails, CheckFailedL() must be called with that message.

    • Pending messages on a given session need to be completed and discarded if the session is closed.

IMPORTANT NOTE. When processing a message asynchronously, a copy must be made of the RMessage2 object. Saving a refernece or pointer to the original message will produce unpredictable defects. This is because the object will be reused for the next message that the server receives.

In both cases, synchronous and asynchronous, the derived implementation has the option of updating the aAction and/or aMissing parameters if that is appropriate.

A value from TCustomResult.

panic

CBase 95 If the default implementation is called.

Parameters

const RMessage2 & aMsgThe message to check.
TInt & aActionA reference to the action to take if the security check fails. This is either a value from TFailureAction or a negative value which has meaning to the CustomFailureActionL() method of a derived class. The policy server framework gives this value a default of EFailClient. If a derived implementation wishes a different value, then it should change this.
TSecurityInfo & aMissingA reference to the list of security attributes missing from the checked process. The policy server initialises this object to zero (that is a sid of 0, a vid of 0, and no capabilities). If derived implementations wish to take advantage of a list of missing attributes in their implementation of CustomFailureActionL(), then they should set those missing attributes here in CustomSecurityCheckL().

Extension_(TUint, TAny *&, TAny *)

IMPORT_C TIntExtension_(TUintaExtensionId,
TAny *&a0,
TAny *a1
)[protected, virtual]

Parameters

TUint aExtensionId
TAny *& a0
TAny * a1

FindPolicyElement(TInt, TUint &)

const CPolicyServer::TPolicyElement *FindPolicyElement(TIntaFn,
TUint &aSpecialCase
)const [private]

Parameters

TInt aFn
TUint & aSpecialCase

ProcessError(const RMessage2 &, TInt)

IMPORT_C voidProcessError(const RMessage2 &aMsg,
TIntaError
)

Called if a leave occurs during processing of a message. The underlying framework ensures that leaves which occur during CSession2::ServiceL are passed to CSession2::ServiceError. Leaves occuring prior to this (ie. during CustomSecurityCheckL() or CustomFailureActionL() ) are completed with the leave code.

This function should only ever be called by derived implementations if asynchronous security checks are in use. In this case the RunError() of that other active object must call ProcessError().

Parameters

const RMessage2 & aMsgThe message being processed when the leave occurred.
TInt aErrorThe leave code.

ProcessL(const RMessage2 &)

IMPORT_C voidProcessL(const RMessage2 &aMsg)

Process an accepted message which has passed its policy check.

The message is either passed to the ServiceL() method of a session, or, in the case of a connection message, a new session is created.

This is called by RunL() to process a message which has passed its security check. If the server implementation returns EAsync from either CustomSecurityCheckL() or CustomFailureActionL(), then it is the responsibility of the derived server implementation to call ProcessL at a later point if the messages passes the asynchronous check.

This function should only ever be called by derived implementations if asynchronous security checks are in use.

Parameters

const RMessage2 & aMsg

RunError(TInt)

IMPORT_C TIntRunError(TIntaError)[private, virtual]

Parameters

TInt aError

RunL()

IMPORT_C voidRunL()[private, virtual]

Handles an active object's request completion event.

A derived class must provide an implementation to handle the completed request. If appropriate, it may issue another request.

The function is called by the active scheduler when a request completion event occurs, i.e. after the active scheduler's WaitForAnyRequest() function completes.

Before calling this active object's RunL() function, the active scheduler has:

1. decided that this is the highest priority active object with a completed request

2. marked this active object's request as complete (i.e. the request is no longer outstanding)

RunL() runs under a trap harness in the active scheduler. If it leaves, then the active scheduler calls RunError() to handle the leave.

Note that once the active scheduler's Start() function has been called, all user code is run under one of the program's active object's RunL() or RunError() functions.

CActiveScheduler::Start

CActiveScheduler::Error

CActiveScheduler::WaitForAnyRequest

TRAPD

Member Enumerations Documentation

Enum TCustomResult

Enumeration of acceptable return codes from both of CustomSecurityCheckL() and CustomFailureActionL(). Results of EPass or EFail are handled by the CPolicyServer framework. No other action is required on the part of the derived implementation. However, results of EAsync imply that the derived implementation will call the appropriate function once the result is known. See CustomSecurityCheckL() and CustomFailureActionL for more information.

Enumerators

EPass = 0

Security check passed.

EFail = 1

Security check failed.

EAsync = 2

Security checking will be performed asynchronously.

Enum TFailureAction

Enumeration specifying action to take if a security check fails. Values >= 0 are handled by CheckFailedL(). Values < 0 are specific to the derived implementation of the policy server and will result in a call to CustomFailureActionL() if a security check fails. Attempts to use undefined values >= 0 will result in a panic in CheckFailedL().

Enumerators

EFailClient = 0

Complete message with KErrPermissionDenied

EPanicClient = 1

Panic client

Enum TSpecialCase

Special case values which can be used instead of a policy element index contained in the array TPolicy::iElementsIndex

Enumerators

ECustomCheck = 255u

Indicates a custom check should be made by calling CustomSecurityCheckL()

ENotSupported = 254u

Indicates that message is requesting an unsupported function. The message is completed with KErrNotSupported.

EAlwaysPass = 253u

Indicates that the message is requesting an unrestricted function and therefore should be processed without any further checks.

ESpecialCaseLimit = 252u
ESpecialCaseHardLimit = 250u

Member Data Documentation

const TPolicy & iPolicy

const TPolicy &iPolicy[private]