Symbian3/SDK/Source/GUID-85D9878E-4FEF-5E45-9F87-53634CD171E0.dita
changeset 7 51a74ef9ed63
--- /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 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-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: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-85D9878E-4FEF-5E45-9F87-53634CD171E0" xml:lang="en"><title>Integrating
+a System Server with UPS</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<section id="GUID-78B46051-E035-4798-9A4D-B274D4783164"><title>Introduction</title> <p>User Prompt Service (UPS) functionality
+is provided by the server process <filepath>upsserver.exe</filepath>. The
+process starts on demand when system servers make calls to the UPS client
+library. Only applications with a capability of <codeph>ProtServ</codeph> or
+higher can access <filepath>upsserver.exe</filepath>. </p> <p>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.) . </p> <p>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. </p> <p>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. </p> </section>
+<section id="GUID-718CF580-05FE-4F75-A7D8-4487C35675B6"><title>Required background</title><p id="GUID-9C6EBADD-175A-5122-90C4-CED8A9855BAB"><b>Configuring
+the system server</b> </p> <p>For each system server that accesses the UPS,
+you need to do the following: </p> <ol id="GUID-D14BDAE1-BD62-530E-B3C4-2FA380BDBDC5">
+<li id="GUID-090CE65B-44BF-54CF-8961-69059655C5F5"><p>Create one <codeph>RUpsSession</codeph> per
+server. </p> <p>Typically, an <codeph>RUpsSubession</codeph> object is created
+for each connection by a client to the system server and can only have one
+outstanding call to <xref href="GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74.dita#GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74/GUID-82C3C51A-F785-3DBA-910A-47CAF47B39F6"><apiname>RUpsSubsession::Authorise()</apiname></xref>. </p> </li>
+<li id="GUID-61E4A569-F5C3-593C-9954-2803E822F0BF"><p> <xref href="GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74.dita#GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74/GUID-82C3C51A-F785-3DBA-910A-47CAF47B39F6"><apiname>RUpsSubsession::Authorise()</apiname></xref> completes
+immediately and uses the result of its <codeph>aServerCheckOk</codeph> parameter
+to set its <codeph>aDecision</codeph> 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. </p> </li>
+<li id="GUID-035F2AEE-95B8-5085-9079-A4B8A6EC9B6A"><p>Close each <xref href="GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74.dita"><apiname>RUpsSubsession</apiname></xref>. </p> </li>
+</ol><p id="GUID-75BD33B9-28AC-55CD-BF3E-7F62A8D039EB"><b>Considerations</b> </p> <p>Consider
+the following points before integrating the UPS to a system server </p> <ul>
+<li id="GUID-11A0A48F-47A3-5A89-9925-8FBAB3F5D8DE"><p>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. </p> </li>
+<li id="GUID-747A3037-13E6-5895-895E-F700368A81B6"><p>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. </p> </li>
+<li id="GUID-27A11CBD-BBB5-5D32-8207-D01D207FEC9E"><p>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 <codeph>CPolicyServer</codeph> fail the client immediately if the platsec
+check fails these checks may have to be modified. </p> </li>
+</ul><p> <b>Note</b>: For an example of how to include the above, see the
+example code later in this document. </p></section>
+<section id="GUID-3C0A43C1-1CEF-4C0F-83A6-64B3EF73E955"><title>Integration of UPS</title> <p>If the system server uses the <codeph>CPolicyServer</codeph> framework,
+there are three candidates for the main integration point. </p> <table id="GUID-BBE389D8-77A0-52BA-910D-368BAC25DCC3">
+<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
+<tbody>
+<row>
+<entry><p>Function </p> </entry>
+<entry><p>Description </p> </entry>
+</row>
+<row>
+<entry><p> <xref href="GUID-5BDFF5B1-DC1F-393A-879B-9D8DE080B4E2.dita#GUID-5BDFF5B1-DC1F-393A-879B-9D8DE080B4E2/GUID-49DDDDAC-B256-3B43-B059-EE369EAEA2BB"><apiname>CPolicyServer::CustomSecurityCheckL()</apiname></xref>  </p> </entry>
+<entry><p>This allows an arbitrary and even asynchronous check to be made
+instead of using static security policies. </p> </entry>
+</row>
+<row>
+<entry><p> <xref href="GUID-5BDFF5B1-DC1F-393A-879B-9D8DE080B4E2.dita#GUID-5BDFF5B1-DC1F-393A-879B-9D8DE080B4E2/GUID-93C9B0EE-8B94-3A95-BBA7-5B1C8BED6E28"><apiname> CPolicyServer::CustomFailureActionL()</apiname></xref>  </p> </entry>
+<entry><p>This virtual method is invoked if the client fails the static security
+checks. The failure may be overridden or deferred. Asynchronous operations
+are possible. </p> </entry>
+</row>
+<row>
+<entry><p> <xref href="GUID-D5A30C75-E22C-34E8-913B-7D2CA6AD5C51.dita#GUID-D5A30C75-E22C-34E8-913B-7D2CA6AD5C51/GUID-B37413F7-D8FD-35AD-A037-99023D7CE986"><apiname> CSession2::ServiceL()</apiname></xref>  </p> </entry>
+<entry><p>The static policy checks could be deferred until the session is
+created provided that the server connection API is not guarded by user prompts. </p> </entry>
+</row>
+</tbody>
+</tgroup>
+</table> <p>Use one or a combination of above functions as required to implement
+UPS APIs </p><p><b>Procedure</b> </p> <p>This demonstrates how user permission
+prompt support (UPS) may be added to a system server. </p> <ol id="GUID-BC8CDF54-101F-563E-BA74-7DE871A93782">
+<li id="GUID-55A1C176-857B-539F-81F1-66FCDEDEF299"><p>An <codeph>RUpsSession</codeph> object
+has been added to the <codeph>CMsgServer</codeph> class. This is initialized
+at startup. </p> </li>
+<li id="GUID-8DD68273-846D-568A-A7BE-330523722503"><p> <xref href="GUID-AB9191BA-9E9B-3ED8-9968-4E43C1803C0D.dita#GUID-AB9191BA-9E9B-3ED8-9968-4E43C1803C0D/GUID-6A3E9888-EA11-3352-A634-946C66A3946C"><apiname>CMsgServer::iPolicyElements</apiname></xref> was
+changed to cause <codeph>CustomFailureActionL</codeph> to be invoked if the
+static security policy check fails instead of failing the client. </p> </li>
+<li id="GUID-C2AF0E9B-C46A-59E4-ADB7-21D2018582DD"><p> <xref href="GUID-AB9191BA-9E9B-3ED8-9968-4E43C1803C0D.dita#GUID-AB9191BA-9E9B-3ED8-9968-4E43C1803C0D/GUID-3498AEBD-A092-3D0B-98EB-50A1B9DC65B5"><apiname>CMsgServer::CustomFailureActionL()</apiname></xref> notifies
+the session object that the platsec check failed. This is important because <xref href="GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74.dita#GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74/GUID-82C3C51A-F785-3DBA-910A-47CAF47B39F6"><apiname>RUpsSubsession::Authorise()</apiname></xref> requires
+this information to allow unconfigured systems to be compatible with platsec.
+It also increases the flexibility of the UPS policy definitions. </p> </li>
+<li id="GUID-63A4E019-BDFF-5B37-993B-3ED8233EC781"><p>An <codeph>RUpsSubsession</codeph> instance
+is created for each <codeph>CSession2</codeph> 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. </p> </li>
+<li id="GUID-82211891-BA54-501F-9E81-D6D78C4476E7"><p>An extra state (<codeph>iAuthorising</codeph>)
+is added at the start of the CMsgProcessor state machine. </p> </li>
+<li id="GUID-EC85BB4D-83B9-5AF0-9A19-818B6AD4CE6C"><p>The <codeph>RMessage2</codeph> parameters
+from the client API are now extracted in the authorization stage to enable
+the information to be passed to the UPS. </p> </li>
+<li id="GUID-91D30A49-B703-5E01-BAC9-F9205DB9BAA2"><p> <xref href="GUID-C4092739-2792-3411-90CC-174398AE4A4C.dita#GUID-C4092739-2792-3411-90CC-174398AE4A4C/GUID-9DE31D77-70B7-3072-A602-75D995749DB3"><apiname>CMsgProcessor::DoCancel</apiname></xref> is
+updated to cancel the call to <xref href="GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74.dita#GUID-1C63BE5E-6F66-38CB-931E-B2C51309CB74/GUID-06BF925F-53C1-33D4-97F3-46ECB10CC27F"><apiname>RUpsSubsession::Authorise</apiname></xref>,
+if the client cancels the sending of the message or disconnects. </p> </li>
+<li id="GUID-684BEA9C-B6F7-5369-A243-9D0689BBD421"><p> <xref href="GUID-C4092739-2792-3411-90CC-174398AE4A4C.dita#GUID-C4092739-2792-3411-90CC-174398AE4A4C/GUID-013B385A-2A30-36D6-990A-873CF329F9E7"><apiname>CMsgProcessor::RunL</apiname></xref> now
+checks whether the request was authorized before changing from the authorization
+to the sending state. </p> </li>
+</ol> <p>The following code snippet explains how the UPS APIs can be called. </p> <codeblock id="GUID-1B2C7094-BFA3-5C49-ABDB-4721BC71D8CE" xml:space="preserve">
+
+using namespace UserPromptService;
+
+TUpsDecision AuthoriseL(RThread &amp;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(&amp;subsession);
+ CleanupStack::PopAndDestroy(&amp;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;
+ }
+</codeblock> </section>
+</conbody></concept>
\ No newline at end of file