Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]

#include <e32base.h>
Link against: euser.lib

Class CPolicyServer

class CPolicyServer : public CServer2;

Description

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 CPolicyServer::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 CPolicyServer::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 CPolicyServer::TPolicy::iRanges. This yields a range number R, which is between 0 and CPolicyServer::TPolicy::iRangeCount-1. The policy index, X, for this range is then fetched from CPolicyServer::TPolicy::iElementsIndex[R]. If the message is a Connect message, then X is fetched directly from CPolicyServer::TPolicy::iOnConnect instead.

The further action taken is determined by the value of X.

Handling Policy Check Failure

The CPolicyServer::CheckFailedL(const RMessage2 &,TInt,const TSecurityInfo &) method is called when a security check has failed. It performs an action according to the aAction value given to it:

Derivation

Members

Defined in CPolicyServer:

Inherited from CActive:

Inherited from CBase:

Inherited from CServer2:


Construction and destruction


CPolicyServer(TInt,const TPolicy &,TServerType)

protected: IMPORT_C CPolicyServer(TInt aPriority, const TPolicy &aPolicy, TServerType aType=EUnsharableSessions);

Description

Construct a policy server

Parameters

TInt aPriority

Active object priority for this server

const CPolicyServer::TPolicy &aPolicy

Reference 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.

CServer2::TServerType aType

Type of session sharing supported by this server

[Top]


Member functions


ProcessL(const RMessage2 &)

IMPORT_C void ProcessL(const RMessage2 &aMsg);

Description

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 CPolicyServer::RunL() to process a message which has passed its security check. If the server implementation returns EAsync from either CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &) or CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &), 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


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

IMPORT_C void CheckFailedL(const RMessage2 &aMsg, TInt aAction, const TSecurityInfo &aMissing);

Description

Called when a security check has failed.

The aAction parameter determines the action taken:

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

Parameters

const RMessage2 &aMsg

The message which failed its check.

TInt aAction

The action to take. (See description.)

const TSecurityInfo &aMissing

A list of the security attributes that were missing from the checked process.


ProcessError(const RMessage2 &,TInt)

IMPORT_C void ProcessError(const RMessage2 &aMsg, TInt aError);

Description

Called if a leave occurs during processing of a message. The underlying framework ensures that leaves which occur during CSession2::ServiceL(const RMessage2 &) are passed to CSession2::ServiceError(const RMessage2 &,TInt). Leaves occuring prior to this (ie. during CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &) or CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &) ) 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 CPolicyServer::RunError(TInt) of that other active object must call CPolicyServer::ProcessError(const RMessage2 &,TInt).

Parameters

const RMessage2 &aMsg

The message being processed when the leave occurred.

TInt aError

The leave code.


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

protected: IMPORT_C virtual TCustomResult CustomSecurityCheckL(const RMessage2 &aMsg, TInt &aAction, TSecurityInfo &aMissing);

Description

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:

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.

Parameters

const RMessage2 &aMsg

The message to check.

TInt &aAction

A 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 CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &) 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 &aMissing

A 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 CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &), then they should set those missing attributes here in CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &).

Return value

CPolicyServer::TCustomResult

A value from TCustomResult.

Panic codes

CBase

95 If the default implementation is called.


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

protected: IMPORT_C virtual TCustomResult CustomFailureActionL(const RMessage2 &aMsg, TInt aAction, const TSecurityInfo &aMissing);

Description

Performs a custom action after the failure of a security check. Derived server classes must implement this function if the aAction value passed to CPolicyServer::CheckFailedL(const RMessage2 &,TInt,const TSecurityInfo &) 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 CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &) 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:

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.

Parameters

const RMessage2 &aMsg

The message to check

TInt aAction

The custom failure action requested. This is either a value from TFailureAction or a negative value which has meaning to the CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &) method of a derived class.

const TSecurityInfo &aMissing

A 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 CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &) method filled it in.

Return value

CPolicyServer::TCustomResult

A value from TCustomResult.

Panic codes

CBase

95 If the default implementation is called.


Extension_(TUint,TAny *&,TAny *)

protected: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny *&a0, TAny *a1);

Description

Extension function

Parameters

TUint aExtensionId

TAny *&a0

TAny *a1

Return value

TInt


RunL()

private: IMPORT_C virtual void RunL();

Description

Handles the receipt of a message.


RunError(TInt)

private: IMPORT_C virtual TInt RunError(TInt aError);

Description

Handles the situation where a call to CServer2::RunL(), leaves.

This is the server active object's implementation of the active object framework's CPolicyServer::RunError(TInt) function.

In practice, the leave can only be caused by a session's ServiceL() function, which is called from this CPolicyServer::RunL(); this error is reflected back to that session by calling its ServiceError() function.

Parameters

TInt aError

The leave code.

Return value

TInt

KErrNone.

See also:

[Top]


Member classes


Class TPolicyElement

class TPolicyElement;

Description

Class specifying a security check and the action to take

If iAction is >=0 it must be a member of TFailureAction If iAction is <0 it is assumed to specify a custom action specific to the derived implementation. In this case, CustomFailureActionL must be implemented by the derived class.

Members

Defined in CPolicyServer::TPolicyElement:

Member data


iPolicy

TStaticSecurityPolicy iPolicy;

Description

Security policy to check against the client which sent a message.

This class can specify a security policy consisting of either:

  1. A check for between 0 and 7 capabilities

  2. A check for a given Secure ID along with 0-3 capabilities

  3. A check for a given Vendor ID along with 0-3 capabilities

This member should only be initialised by one of the following macros:

See also:


iAction

TInt iAction;

Description

Action to take on failure. Either a value from TFailureAction or a negative value which has meaning to the CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &) method of a derived class.


Class TPolicy

class TPolicy;

Description

Object specifying which security checks to perform on each request number and what action to take if the check fails.

Explanations of each of the members of this class are detailed below.

As explained in CPolicyServer::CPolicyServer(TInt,const TPolicy &,TServerType), it is important that the instance of this class (CPolicyServer::TPolicy) given to the policy server constructor, exists for the lifetime of the server. For this reason, as well as code size considerations, it is recommended that the CPolicyServer::TPolicy instance is const static data. The following code segment shows the recommended way of doing this. Further detail on what each of these statements means is given below.

    const TUint myRangeCount = 4;
    const TInt myRanges[myRangeCount] = 
        {
        0, //range is 0-2 inclusive
        3, //range is 3-6 inclusive
        7, //range is 7
        8, //range is 8-KMaxTInt inclusive
        };
    const TUint8 myElementsIndex[myRangeCount] = 
        {
        1,                                 //applies to 0th range (req num: 0-2)
        CPolicyServer::ECustomCheck,   //applies to 1st range (req num: 3-6)
        0,                                 //applies to 2nd range (req num: 7)
        CPolicyServer::ENotSupported,   //applies to 3rd range (req num: 8-KMaxTInt)
        };
    const CPolicyServer::TPolicyElement myElements[] = 
        {
        {_INIT_SECURITY_POLICY_C1(ECapabilityDiskAdmin), CPolicyServer::EFailClient},
        {_INIT_SECURITY_POLICY_C1(ECapabilityLocation), CMyPolicyServer::EQueryUser},
        }
    const CPolicySErver::TPolicy myPolicy =
        {
        CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
        myRangeCount,                   
        myRanges,
        myElementsIndex,
        myElements,
        }

Members

Defined in CPolicyServer::TPolicy:

Member data


iOnConnect

TUint8 iOnConnect;

Description

The index into iElements, or an allowed value of TSpecialCase, that is used to check a connection attempt .


iRangeCount

TUint16 iRangeCount;

Description

Number of ranges in the iRanges array.


iRanges

const TInt * iRanges;

Description

A pointer to an array of ordered ranges of request numbers. Each element in this array refers to the starting request number of a range. The range of the previous element is up to and including the current element minus 1. Thus an array like:

        const TInt myRanges[4] = {0, 3, 7, 8};

means that:

Note that the all possible request numbers must be accounted for. This implies that the first element must be 0. It also implies that the last range goes from the that element to KMaxTint. Finally, each element must be strictly greater than the previous element. As the first element is 0, this clearly implies that iRanges must not contain negative elements.


iElementsIndex

const TUint8 * iElementsIndex;

Description

A pointer to an array of TUint8 values specifying the appropriate action to take for each range in iRanges. For example, the 0th element of iElementsIndex specifies the appropriate action to take for the 0th range in iRanges. As such, iElementsIndex must have precisely the same number of elements as iRanges.

The following rules apply to the value of each element in iElementsIndex:

  1. Each value must be a valid index into iElements (that is, less than the number of elements in iElements) OR a valid value from TSpecialCase.

  2. Elements' values need not follow any special ordering.

  3. Elements may repeat values.

Continuing the example from iRanges:

        const TInt myRanges[4] = {0, 3, 7, 8};
        const TUInt8 myElementsIndex[4] = {
            1, 
            CPolicyServer::ECustomCheck, 
            0, 
            CPolicyServer::ENotSupported
            };

This means that:

  1. Requests within the first range of myRanges (request numbers 0-2) will be checked against the policy specified by the 1st element of iElements.

  2. Requests with the the second range of myRanges (request numbers 3-6) require a custom check to determine if they are allowed. This requires derived server implementations to implement CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &)

  3. Requests within the third range of myRanges (request number 7) will be checked against the policy specified by the 0th element of iElements.

  4. Requests within the fourth range of myRanges (request numbers 8-KMaxTInt) will automatically be completed with KErrNotSupported by the policy server framework.


iElements

const TPolicyElement * iElements;

Description

A pointer to an array of distinct policy elements.

Continuing with the previous examples:

        const TInt myRanges[4] = {0, 3, 7, 8};
        const TUInt8 myElementsIndex[4] = {
            1, 
            CPolicyServer::ECustomCheck, 
            0, 
            CPolicyServer::ENotSupported
            };
        const TPolicyElement iElements[] = {
            {_INIT_SECURITY_POLICY_C1(ECapabilityDiskAdmin), CPolicyServer::EFailClient},
            {_INIT_SECURITY_POLICY_C1(ECapabilityLocation), CMyPolicyServer::EQueryUser}
            }

The instantiation of iElements specifies that:

  1. Request numbers 0-2 require the Location capability. As the iAction member of the 1st element specifies a custom action (represented by the negative number, CMyPolicyServer::EQueryUser), requests without Location will passed to the reimplementation of CustomFailureActionL.

  2. Request number 7 requires the DiskAdmin capability. Requestors without DiskAdmin will have their request completed with KErrPermissionDenied.

[Top]


Member enumerations


Enum TFailureAction

TFailureAction

Description

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

EFailClient

Complete message with KErrPermissionDenied

EPanicClient

Panic client


Enum TCustomResult

TCustomResult

Description

Enumeration of acceptable return codes from both of CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &) and CPolicyServer::CustomFailureActionL(const RMessage2 &,TInt,const TSecurityInfo &). 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 CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &) and CustomFailureActionL for more information.

EPass

Security check passed.

EFail

Security check failed.

EAsync

Security checking will be performed asynchronously.


Enum TSpecialCase

TSpecialCase

Description

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

ECustomCheck

Indicates a custom check should be made by calling CPolicyServer::CustomSecurityCheckL(const RMessage2 &,TInt &,TSecurityInfo &)

ENotSupported

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

EAlwaysPass

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