Symbian3/SDK/Source/GUID-85D9878E-4FEF-5E45-9F87-53634CD171E0.dita
changeset 7 51a74ef9ed63
equal deleted inserted replaced
6:43e37759235e 7:51a74ef9ed63
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-85D9878E-4FEF-5E45-9F87-53634CD171E0" xml:lang="en"><title>Integrating
       
    13 a System Server with UPS</title><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <section id="GUID-78B46051-E035-4798-9A4D-B274D4783164"><title>Introduction</title> <p>User Prompt Service (UPS) functionality
       
    15 is provided by the server process <filepath>upsserver.exe</filepath>. The
       
    16 process starts on demand when system servers make calls to the UPS client
       
    17 library. Only applications with a capability of <codeph>ProtServ</codeph> or
       
    18 higher can access <filepath>upsserver.exe</filepath>. </p> <p>A system server
       
    19 should only invoke the UPS for security decisions that a typical phone user
       
    20 will understand (For example, it is inappropriate to ask the user for permission
       
    21 to change a low level network setting.) . </p> <p>Device creators can write
       
    22 a system server that invokes the UPS, if a compatible dialog creator is available
       
    23 and the policies are delivered in an appropriately signed SIS file. They can
       
    24 also write a policy evaluator, but a default policy evaluator is provided
       
    25 by the Symbian platform. </p> <p>If the device creators do not
       
    26 specify any policy file, the UPS uses the platform security check results
       
    27 to decide whether to access requested services. Thus not supplying policy
       
    28 files effectively turns UPS off. </p> </section>
       
    29 <section id="GUID-718CF580-05FE-4F75-A7D8-4487C35675B6"><title>Required background</title><p id="GUID-9C6EBADD-175A-5122-90C4-CED8A9855BAB"><b>Configuring
       
    30 the system server</b> </p> <p>For each system server that accesses the UPS,
       
    31 you need to do the following: </p> <ol id="GUID-D14BDAE1-BD62-530E-B3C4-2FA380BDBDC5">
       
    32 <li id="GUID-090CE65B-44BF-54CF-8961-69059655C5F5"><p>Create one <codeph>RUpsSession</codeph> per
       
    33 server. </p> <p>Typically, an <codeph>RUpsSubession</codeph> object is created
       
    34 for each connection by a client to the system server and can only have one
       
    35 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>
       
    36 <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
       
    37 immediately and uses the result of its <codeph>aServerCheckOk</codeph> parameter
       
    38 to set its <codeph>aDecision</codeph> parameter, if a policy file is not defined
       
    39 for a service. Therefore, the default behaviour of an unconfigured UPS is
       
    40 compatible with the existing platform security implementation. </p> </li>
       
    41 <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>
       
    42 </ol><p id="GUID-75BD33B9-28AC-55CD-BF3E-7F62A8D039EB"><b>Considerations</b> </p> <p>Consider
       
    43 the following points before integrating the UPS to a system server </p> <ul>
       
    44 <li id="GUID-11A0A48F-47A3-5A89-9925-8FBAB3F5D8DE"><p>Even though the APIs
       
    45 for the UPS are relatively small, the integration is slightly more complicated
       
    46 than might be expected. This is because existing synchronous security checks
       
    47 must become asynchronous since interaction with the device user is inherently
       
    48 an asynchronous operation. For example, it would be undesirable to block the
       
    49 entire comms server while waiting for the user to respond to a dialog. </p> </li>
       
    50 <li id="GUID-747A3037-13E6-5895-895E-F700368A81B6"><p>Provide an informed
       
    51 security decision the user may need to know about the request they are authorizing.
       
    52 Consequently, it may be necessary to extract the parameters from the client
       
    53 application at the security check stage. </p> </li>
       
    54 <li id="GUID-27A11CBD-BBB5-5D32-8207-D01D207FEC9E"><p>Finally, depending on
       
    55 the service and the security requirements of the manufacturer, an operator
       
    56 user prompts may be in addition to the platform security (e.g. capabilities)
       
    57 checks. Alternatively, user prompts could be used to allow applications without
       
    58 capabilities limited access to a protected service. Because most implementations
       
    59 of the <codeph>CPolicyServer</codeph> fail the client immediately if the platsec
       
    60 check fails these checks may have to be modified. </p> </li>
       
    61 </ul><p> <b>Note</b>: For an example of how to include the above, see the
       
    62 example code later in this document. </p></section>
       
    63 <section id="GUID-3C0A43C1-1CEF-4C0F-83A6-64B3EF73E955"><title>Integration of UPS</title> <p>If the system server uses the <codeph>CPolicyServer</codeph> framework,
       
    64 there are three candidates for the main integration point. </p> <table id="GUID-BBE389D8-77A0-52BA-910D-368BAC25DCC3">
       
    65 <tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
       
    66 <tbody>
       
    67 <row>
       
    68 <entry><p>Function </p> </entry>
       
    69 <entry><p>Description </p> </entry>
       
    70 </row>
       
    71 <row>
       
    72 <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>
       
    73 <entry><p>This allows an arbitrary and even asynchronous check to be made
       
    74 instead of using static security policies. </p> </entry>
       
    75 </row>
       
    76 <row>
       
    77 <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>
       
    78 <entry><p>This virtual method is invoked if the client fails the static security
       
    79 checks. The failure may be overridden or deferred. Asynchronous operations
       
    80 are possible. </p> </entry>
       
    81 </row>
       
    82 <row>
       
    83 <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>
       
    84 <entry><p>The static policy checks could be deferred until the session is
       
    85 created provided that the server connection API is not guarded by user prompts. </p> </entry>
       
    86 </row>
       
    87 </tbody>
       
    88 </tgroup>
       
    89 </table> <p>Use one or a combination of above functions as required to implement
       
    90 UPS APIs </p><p><b>Procedure</b> </p> <p>This demonstrates how user permission
       
    91 prompt support (UPS) may be added to a system server. </p> <ol id="GUID-BC8CDF54-101F-563E-BA74-7DE871A93782">
       
    92 <li id="GUID-55A1C176-857B-539F-81F1-66FCDEDEF299"><p>An <codeph>RUpsSession</codeph> object
       
    93 has been added to the <codeph>CMsgServer</codeph> class. This is initialized
       
    94 at startup. </p> </li>
       
    95 <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
       
    96 changed to cause <codeph>CustomFailureActionL</codeph> to be invoked if the
       
    97 static security policy check fails instead of failing the client. </p> </li>
       
    98 <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
       
    99 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
       
   100 this information to allow unconfigured systems to be compatible with platsec.
       
   101 It also increases the flexibility of the UPS policy definitions. </p> </li>
       
   102 <li id="GUID-63A4E019-BDFF-5B37-993B-3ED8233EC781"><p>An <codeph>RUpsSubsession</codeph> instance
       
   103 is created for each <codeph>CSession2</codeph> object, i.e. requests from
       
   104 different clients are authorized independently. This could be modified so
       
   105 that there is one UPS sub-session for each client process instead of each
       
   106 connection from a client process. </p> </li>
       
   107 <li id="GUID-82211891-BA54-501F-9E81-D6D78C4476E7"><p>An extra state (<codeph>iAuthorising</codeph>)
       
   108 is added at the start of the CMsgProcessor state machine. </p> </li>
       
   109 <li id="GUID-EC85BB4D-83B9-5AF0-9A19-818B6AD4CE6C"><p>The <codeph>RMessage2</codeph> parameters
       
   110 from the client API are now extracted in the authorization stage to enable
       
   111 the information to be passed to the UPS. </p> </li>
       
   112 <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
       
   113 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>,
       
   114 if the client cancels the sending of the message or disconnects. </p> </li>
       
   115 <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
       
   116 checks whether the request was authorized before changing from the authorization
       
   117 to the sending state. </p> </li>
       
   118 </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">
       
   119 
       
   120 using namespace UserPromptService;
       
   121 
       
   122 TUpsDecision AuthoriseL(RThread &amp;aClientThread, TDesC aDestination)
       
   123     {
       
   124  // Create and connect the session.
       
   125  // In a real server this should be done once at server startup as it is a relatively
       
   126  // expensive operation.
       
   127  RUpsSession session;
       
   128  User::LeaveIfError(session.Connect());
       
   129  CleanupClosePushL(session);
       
   130 
       
   131  // Initialise the subsession
       
   132  // One of these is required per a concurrent Authorise request.
       
   133  // Note that it only connects to the UPS if it has to.
       
   134     RUpsSubsession subsession;
       
   135  subsession.Initialise(session, aClientThread);
       
   136  CleanupClosePushL(subsession);
       
   137 
       
   138  TServiceId serviceId = {43};
       
   139  // Out "service id", typically a constant
       
   140  // Variable for the result, typically a member variable because it must exist until
       
   141  // the Authorise request completes.
       
   142  TUpsDecision decision = EUpsDecYes;
       
   143 
       
   144  // Issue the Authorise request
       
   145  TRequestStatus rs;
       
   146  subsession.Authorise(EFalse, // Did out platsec checks pass?
       
   147                          serviceId, 
       
   148                          aDestination, 
       
   149                          decision, 
       
   150                          rs); // Would typically be the iStatus of a CActive object
       
   151 
       
   152     // Wait for the request to complete
       
   153  User::WaitForRequest(rs);
       
   154 
       
   155  CleanupStack::PopAndDestroy(&amp;subsession);
       
   156  CleanupStack::PopAndDestroy(&amp;session);
       
   157  return decision;
       
   158  }
       
   159 
       
   160 
       
   161 TInt E32Main()
       
   162  {
       
   163  __UHEAP_MARK;
       
   164 
       
   165  // allocating a cleanup stack also installs it
       
   166  CTrapCleanup* tc = CTrapCleanup::New();
       
   167  if (tc == 0)
       
   168   return KErrNoMemory;
       
   169 
       
   170  RThread thd;
       
   171  TRAPD(err, AuthoriseL(thd, _L("destination")));
       
   172  if(err != KErrNone)
       
   173   {
       
   174   User::Panic(_L("example failed: "), err);
       
   175   }
       
   176  delete tc;
       
   177 
       
   178  __UHEAP_MARKEND;
       
   179  return KErrNone;
       
   180  }
       
   181 </codeblock> </section>
       
   182 </conbody></concept>