diff -r 43e37759235e -r 51a74ef9ed63 Symbian3/SDK/Source/GUID-85D9878E-4FEF-5E45-9F87-53634CD171E0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/SDK/Source/GUID-85D9878E-4FEF-5E45-9F87-53634CD171E0.dita Wed Mar 31 11:11:55 2010 +0100 @@ -0,0 +1,182 @@ + + + + + +Integrating +a System Server with UPS +
Introduction

User Prompt Service (UPS) functionality +is provided by the server process upsserver.exe. The +process starts on demand when system servers make calls to the UPS client +library. Only applications with a capability of ProtServ or +higher can access upsserver.exe.

A system server +should only invoke the UPS for security decisions that a typical phone user +will understand (For example, it is inappropriate to ask the user for permission +to change a low level network setting.) .

Device creators can write +a system server that invokes the UPS, if a compatible dialog creator is available +and the policies are delivered in an appropriately signed SIS file. They can +also write a policy evaluator, but a default policy evaluator is provided +by the Symbian platform.

If the device creators do not +specify any policy file, the UPS uses the platform security check results +to decide whether to access requested services. Thus not supplying policy +files effectively turns UPS off.

+
Required background

Configuring +the system server

For each system server that accesses the UPS, +you need to do the following:

    +
  1. Create one RUpsSession per +server.

    Typically, an RUpsSubession object is created +for each connection by a client to the system server and can only have one +outstanding call to RUpsSubsession::Authorise().

  2. +
  3. RUpsSubsession::Authorise() completes +immediately and uses the result of its aServerCheckOk parameter +to set its aDecision parameter, if a policy file is not defined +for a service. Therefore, the default behaviour of an unconfigured UPS is +compatible with the existing platform security implementation.

  4. +
  5. Close each RUpsSubsession.

  6. +

Considerations

Consider +the following points before integrating the UPS to a system server

    +
  • Even though the APIs +for the UPS are relatively small, the integration is slightly more complicated +than might be expected. This is because existing synchronous security checks +must become asynchronous since interaction with the device user is inherently +an asynchronous operation. For example, it would be undesirable to block the +entire comms server while waiting for the user to respond to a dialog.

  • +
  • Provide an informed +security decision the user may need to know about the request they are authorizing. +Consequently, it may be necessary to extract the parameters from the client +application at the security check stage.

  • +
  • Finally, depending on +the service and the security requirements of the manufacturer, an operator +user prompts may be in addition to the platform security (e.g. capabilities) +checks. Alternatively, user prompts could be used to allow applications without +capabilities limited access to a protected service. Because most implementations +of the CPolicyServer fail the client immediately if the platsec +check fails these checks may have to be modified.

  • +

Note: For an example of how to include the above, see the +example code later in this document.

+
Integration of UPS

If the system server uses the CPolicyServer framework, +there are three candidates for the main integration point.

+ + + +

Function

+

Description

+
+ +

CPolicyServer::CustomSecurityCheckL()

+

This allows an arbitrary and even asynchronous check to be made +instead of using static security policies.

+
+ +

CPolicyServer::CustomFailureActionL()

+

This virtual method is invoked if the client fails the static security +checks. The failure may be overridden or deferred. Asynchronous operations +are possible.

+
+ +

CSession2::ServiceL()

+

The static policy checks could be deferred until the session is +created provided that the server connection API is not guarded by user prompts.

+
+ + +

Use one or a combination of above functions as required to implement +UPS APIs

Procedure

This demonstrates how user permission +prompt support (UPS) may be added to a system server.

    +
  1. An RUpsSession object +has been added to the CMsgServer class. This is initialized +at startup.

  2. +
  3. CMsgServer::iPolicyElements was +changed to cause CustomFailureActionL to be invoked if the +static security policy check fails instead of failing the client.

  4. +
  5. CMsgServer::CustomFailureActionL() notifies +the session object that the platsec check failed. This is important because RUpsSubsession::Authorise() requires +this information to allow unconfigured systems to be compatible with platsec. +It also increases the flexibility of the UPS policy definitions.

  6. +
  7. An RUpsSubsession instance +is created for each CSession2 object, i.e. requests from +different clients are authorized independently. This could be modified so +that there is one UPS sub-session for each client process instead of each +connection from a client process.

  8. +
  9. An extra state (iAuthorising) +is added at the start of the CMsgProcessor state machine.

  10. +
  11. The RMessage2 parameters +from the client API are now extracted in the authorization stage to enable +the information to be passed to the UPS.

  12. +
  13. CMsgProcessor::DoCancel is +updated to cancel the call to RUpsSubsession::Authorise, +if the client cancels the sending of the message or disconnects.

  14. +
  15. CMsgProcessor::RunL now +checks whether the request was authorized before changing from the authorization +to the sending state.

  16. +

The following code snippet explains how the UPS APIs can be called.

+ +using namespace UserPromptService; + +TUpsDecision AuthoriseL(RThread &aClientThread, TDesC aDestination) + { + // Create and connect the session. + // In a real server this should be done once at server startup as it is a relatively + // expensive operation. + RUpsSession session; + User::LeaveIfError(session.Connect()); + CleanupClosePushL(session); + + // Initialise the subsession + // One of these is required per a concurrent Authorise request. + // Note that it only connects to the UPS if it has to. + RUpsSubsession subsession; + subsession.Initialise(session, aClientThread); + CleanupClosePushL(subsession); + + TServiceId serviceId = {43}; + // Out "service id", typically a constant + // Variable for the result, typically a member variable because it must exist until + // the Authorise request completes. + TUpsDecision decision = EUpsDecYes; + + // Issue the Authorise request + TRequestStatus rs; + subsession.Authorise(EFalse, // Did out platsec checks pass? + serviceId, + aDestination, + decision, + rs); // Would typically be the iStatus of a CActive object + + // Wait for the request to complete + User::WaitForRequest(rs); + + CleanupStack::PopAndDestroy(&subsession); + CleanupStack::PopAndDestroy(&session); + return decision; + } + + +TInt E32Main() + { + __UHEAP_MARK; + + // allocating a cleanup stack also installs it + CTrapCleanup* tc = CTrapCleanup::New(); + if (tc == 0) + return KErrNoMemory; + + RThread thd; + TRAPD(err, AuthoriseL(thd, _L("destination"))); + if(err != KErrNone) + { + User::Panic(_L("example failed: "), err); + } + delete tc; + + __UHEAP_MARKEND; + return KErrNone; + } +
+
\ No newline at end of file