os/security/authorisation/userpromptservice/server/source/upsclient/rupssubsession.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/authorisation/userpromptservice/server/source/upsclient/rupssubsession.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,329 @@
1.4 +/*
1.5 +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +* RUpsSubsession implementation. See class and function definitions
1.19 +* for more detail.
1.20 +*
1.21 +*/
1.22 +
1.23 +
1.24 +/**
1.25 + @file
1.26 +*/
1.27 +
1.28 +#include <ups/upsclient.h>
1.29 +#include "upsclientconfig.h"
1.30 +#include "upscommon.h"
1.31 +#include <ups/upserr.h>
1.32 +
1.33 +namespace UserPromptService
1.34 + {
1.35 +
1.36 +
1.37 +EXPORT_C RUpsSubsession::RUpsSubsession()
1.38 +/**
1.39 + This constructor provides a single point of definition from
1.40 + which the superclass constructor is called.
1.41 + */
1.42 +: RScsClientSubsessionBase(),
1.43 + iDecPtr(NULL, 0),
1.44 + iSubsessionCreated(EFalse), iClientTid(), iClientSid(TUid::Null()), iClientPid(0), iUpsSession(0)
1.45 + {
1.46 + // empty.
1.47 + }
1.48 +
1.49 +EXPORT_C TInt RUpsSubsession::Initialise(RUpsSession& aSession, const RThread& aClient)
1.50 +/**
1.51 +Saves the details required to create a subsession specific to the client thread.
1.52 +
1.53 +The actual subsession creation is defered until the subsession is required (which
1.54 +may be never if the policy says server checks are sufficient).
1.55 +
1.56 +Several RUpsSubsession objects can share a single RUpsSession.
1.57 +
1.58 +If any of the RUpsSubsession objects are to be used in a different thread to the RUpsSession, then
1.59 +ShareAuto() must be called on the RUpsSession.
1.60 +
1.61 +@see RSubSessionBase::CreateSubsession
1.62 +
1.63 +@param aSession Connected session to the UPS server.
1.64 +@param aClient SS client for whom this session is set up.
1.65 +@return Symbian OS error code where KErrNone indicates success
1.66 + and any other value indicates failure.
1.67 +*/
1.68 + {
1.69 + iClientTid = aClient.Id();
1.70 + iClientSid = aClient.SecureId();
1.71 +
1.72 + // Need to obtain the drive letter for the exe
1.73 + RProcess clientProcess;
1.74 + TInt r = aClient.Process(clientProcess);
1.75 + if(r != KErrNone)
1.76 + {
1.77 + return r; // Presumably it exited...
1.78 + }
1.79 + iClientPid = clientProcess.Id();
1.80 + clientProcess.Close();
1.81 +
1.82 + iUpsSession = &aSession;
1.83 + return KErrNone;
1.84 + }
1.85 +
1.86 +TInt RUpsSubsession::CreateSubsession()
1.87 +/**
1.88 + Create a subsession for a specific SS client over the supplied session.
1.89 +
1.90 + @param aSession Connected session to the UPS server.
1.91 + @param aClient SS client for whom this session is set up.
1.92 + @return Symbian OS error code where KErrNone indicates success
1.93 + and any other value indicates failure.
1.94 + @capability ProtServ
1.95 + */
1.96 + {
1.97 + __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
1.98 + TPckgBuf<TThreadId> tidBuf = iClientTid;
1.99 + TPckgBuf<TProcessId> pidBuf = iClientPid;
1.100 + TIpcArgs args(&tidBuf, &pidBuf);
1.101 + return RScsClientSubsessionBase::CreateSubsession(*iUpsSession, ESessSubsessFromThreadId, args);
1.102 + }
1.103 +
1.104 +EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk,
1.105 + const TServiceId& aServiceId, const TDesC& aDestination,
1.106 + TUpsDecision& aDecision, TRequestStatus& aStatus)
1.107 +/**
1.108 + Determines whether the system server should perform the service requested
1.109 + by the client application. Depending on licensee configuration this function
1.110 + will either complete immediately if the client passed the system servers
1.111 + security policy check. Alternatively, every request may require additional
1.112 + authorisation by the User Prompt Service.
1.113 +
1.114 + @see RUpsSubsession::AuthoriseInternal
1.115 +
1.116 + @param aServerCheckOk Whether the client request passed the security check
1.117 + implemented by the system server e.g. does the client
1.118 + have the correct capabilities for the requested service.
1.119 + @param aServiceId Service which the client wants to use.
1.120 + @param aDestination More information about the service, e.g. this
1.121 + could be a telephone number is the client wanted
1.122 + to make a call.
1.123 + @param aDecision When the request completes successfully, the verdict
1.124 + is written to this variable.
1.125 + @param aStatus The server completes this request object when it
1.126 + has finished handling the request.
1.127 + @capability ProtServ
1.128 + */
1.129 + {
1.130 + __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
1.131 +
1.132 + AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, KNullDesC8, aDecision, aStatus);
1.133 + }
1.134 +
1.135 +EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk,
1.136 + const TServiceId& aServiceId, const TDesC& aDestination,
1.137 + const TDesC8& aOpaqueData,
1.138 + TUpsDecision& aDecision, TRequestStatus& aStatus)
1.139 +/**
1.140 + Determines whether the system server should perform the service requested
1.141 + by the client application. Depending on licensee configuration this function
1.142 + will either complete immediately if the client passed the system servers
1.143 + security policy check. Alternatively, every request may require additional
1.144 + authorisation by the User Prompt Service.
1.145 +
1.146 + @see RUpsSubsession::AuthoriseInternal
1.147 +
1.148 + @param aServerCheckOk Whether the client request passed the security check
1.149 + implemented by the system server e.g. does the client
1.150 + have the correct capabilities for the requested service.
1.151 + @param aServiceId Service which the client wants to use.
1.152 + @param aDestination More information about the service, e.g. this
1.153 + could be a telephone number is the client wanted
1.154 + to make a call.
1.155 + @param aOpaqueData Additional information to describe the request.
1.156 + @param aDecision When the request completes successfully, the verdict
1.157 + is written to this variable.
1.158 + @param aStatus The server completes this request object when it
1.159 + has finished handling the request.
1.160 + @capability ProtServ
1.161 + */
1.162 + {
1.163 + __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
1.164 +
1.165 + AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, aOpaqueData, aDecision, aStatus);
1.166 + }
1.167 +
1.168 +
1.169 +void RUpsSubsession::AuthoriseInternal(
1.170 + TBool aServerCheckOk,
1.171 + const TServiceId& aServiceId,
1.172 + const TDesC& aDestination,
1.173 + const TDesC8& aOpaqueData,
1.174 + TUpsDecision& aDecision,
1.175 + TRequestStatus& aStatus)
1.176 +/**
1.177 + This helper function is called by the exported overloads of Authorise.
1.178 + It sends the data supplied by the SS to the UPS server.
1.179 +
1.180 + @param aServerCheckOk Did the system server checks pass?
1.181 + @param aServiceId Service which the client wants to use.
1.182 + @param aDestination More information about the service, e.g. this
1.183 + could be a telephone number is the client wanted
1.184 + to make a call.
1.185 + @param aOpaqueData Additional information to describe the request.
1.186 + This is KNullDesC8 if the SS used the Authorise overload
1.187 + which did not take opaque data.
1.188 + @param aDecision When the request completes successfully, the verdict
1.189 + is written to this variable.
1.190 + @param aStatus The server completes this request object when it
1.191 + has finished handling the request.
1.192 + @capability ProtServ
1.193 + */
1.194 + {
1.195 + TBool decided = EFalse;
1.196 + TInt err = KErrNone;
1.197 +
1.198 + __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
1.199 + CUpsClientConfig::TQueryUpsResult result = iUpsSession->iClientConfig->QueryUps(aServerCheckOk, aServiceId, iClientSid, iClientPid);
1.200 + switch(result)
1.201 + {
1.202 + case CUpsClientConfig::EAllow:
1.203 + decided = ETrue;
1.204 + aDecision = EUpsDecYes;
1.205 + break;
1.206 +
1.207 + case CUpsClientConfig::EQueryUps:
1.208 + break;
1.209 +
1.210 + case CUpsClientConfig::EReject:
1.211 + decided = ETrue;
1.212 + aDecision = EUpsDecNo;
1.213 + break;
1.214 + BULLSEYE_OFF
1.215 + default:
1.216 + break;
1.217 + }
1.218 + BULLSEYE_RESTORE
1.219 +
1.220 + if(!decided && !iSubsessionCreated)
1.221 + {
1.222 + // We need to query the UPS, but have not created the subsession yet.
1.223 + err = CreateSubsession();
1.224 + if(err != KErrNone)
1.225 + {
1.226 + aDecision = EUpsDecNo;
1.227 + decided = ETrue;
1.228 + }
1.229 + else
1.230 + {
1.231 + iSubsessionCreated = ETrue;
1.232 + // aDecision will be set when we query the UPS
1.233 + }
1.234 + }
1.235 +
1.236 + if(decided)
1.237 + {
1.238 + // Either do not need to query UPS, or an error occured, so complete client
1.239 + // and return
1.240 + aStatus = KRequestPending;
1.241 + TRequestStatus* status = &aStatus;
1.242 + User::RequestComplete(status, err);
1.243 + return; // Either do not need to query UPS, or an error occured, so return
1.244 + }
1.245 +
1.246 + //
1.247 + // Query UPS
1.248 + //
1.249 + // only three arguments can be sent to a subsession, so split
1.250 + // this operation into two stages.
1.251 +
1.252 + TInt r = PreparePrompt(aServiceId, aDestination, aOpaqueData);
1.253 + if (r != KErrNone)
1.254 + {
1.255 + TRequestStatus* prs = &aStatus;
1.256 + User::RequestComplete(prs, r);
1.257 + return;
1.258 + }
1.259 +
1.260 + ExecutePrompt(aServerCheckOk, aDecision, aStatus);
1.261 + }
1.262 +
1.263 +TInt RUpsSubsession::PreparePrompt(const TServiceId& aServiceId, const TDesC& aDestination, const TDesC8& aOpaqueData)
1.264 +/**
1.265 + Ask the UPS server to prepare to make a decision. This will be followed
1.266 + by a call to ExecutePrompt.
1.267 +
1.268 + @param aServiceId Service which the client wants to use.
1.269 + @param aDestination More information about the service, e.g. this
1.270 + could be a telephone number is the client wanted
1.271 + to make a call.
1.272 + @param aOpaqueData Additional information to describe the request.
1.273 + This is KNullDesC8 if the SS used the Authorise overload
1.274 + which did not take opaque data.
1.275 + @return Error code with which the server completed the request.
1.276 + @capability ProtServ
1.277 + @see ExecutePrompt
1.278 + */
1.279 + {
1.280 + TIpcArgs args(aServiceId.iUid, &aDestination, &aOpaqueData);
1.281 + return CallSubsessionFunction(ESubsessPreparePrompt, args);
1.282 + }
1.283 +
1.284 +void RUpsSubsession::ExecutePrompt(TBool aServerCheckOk, TUpsDecision& aDecision, TRequestStatus& aStatus)
1.285 +/**
1.286 + Ask the UPS to execute the request which was set up with PreparePrompt.
1.287 +
1.288 + @param aDecision When the request completes successfully, this argument
1.289 + is updated with the verdict.
1.290 + @param aStatus The server completes this request object when it
1.291 + has finished handling the request.
1.292 + @capability ProtServ
1.293 + @see PreparePrompt
1.294 + */
1.295 + {
1.296 + TUint8* decPtr = reinterpret_cast<TUint8*>(&aDecision);
1.297 + iDecPtr.Set(decPtr, sizeof(TUpsDecision), sizeof(TUpsDecision));
1.298 +
1.299 + TIpcArgs args(&iDecPtr, aServerCheckOk);
1.300 + CallSubsessionFunction(ESubsessExecutePrompt, args, aStatus);
1.301 + }
1.302 +
1.303 +EXPORT_C void RUpsSubsession::CancelPrompt()
1.304 +/**
1.305 + Cancel the prompt request which was launched by calling Authorise.
1.306 +
1.307 + This function has no effect if there is no outstanding request.
1.308 + @capability ProtServ
1.309 + */
1.310 + {
1.311 + if(iSubsessionCreated)
1.312 + {
1.313 + CancelSubsessionFunction(ESubsessExecutePrompt);
1.314 + }
1.315 + }
1.316 +
1.317 +EXPORT_C void RUpsSubsession::Close()
1.318 + /**
1.319 + Close and clean up this subsession object.
1.320 + */
1.321 + {
1.322 + if(iSubsessionCreated)
1.323 + {
1.324 + RScsClientSubsessionBase::Close();
1.325 + }
1.326 + }
1.327 +
1.328 +
1.329 +
1.330 +} // End of namespace UserPromptService
1.331 +
1.332 +// End of file