--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/authorisation/userpromptservice/server/source/upsclient/rupssubsession.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,329 @@
+/*
+* Copyright (c) 2007-2009 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:
+*
+* Description:
+* RUpsSubsession implementation. See class and function definitions
+* for more detail.
+*
+*/
+
+
+/**
+ @file
+*/
+
+#include <ups/upsclient.h>
+#include "upsclientconfig.h"
+#include "upscommon.h"
+#include <ups/upserr.h>
+
+namespace UserPromptService
+ {
+
+
+EXPORT_C RUpsSubsession::RUpsSubsession()
+/**
+ This constructor provides a single point of definition from
+ which the superclass constructor is called.
+ */
+: RScsClientSubsessionBase(),
+ iDecPtr(NULL, 0),
+ iSubsessionCreated(EFalse), iClientTid(), iClientSid(TUid::Null()), iClientPid(0), iUpsSession(0)
+ {
+ // empty.
+ }
+
+EXPORT_C TInt RUpsSubsession::Initialise(RUpsSession& aSession, const RThread& aClient)
+/**
+Saves the details required to create a subsession specific to the client thread.
+
+The actual subsession creation is defered until the subsession is required (which
+may be never if the policy says server checks are sufficient).
+
+Several RUpsSubsession objects can share a single RUpsSession.
+
+If any of the RUpsSubsession objects are to be used in a different thread to the RUpsSession, then
+ShareAuto() must be called on the RUpsSession.
+
+@see RSubSessionBase::CreateSubsession
+
+@param aSession Connected session to the UPS server.
+@param aClient SS client for whom this session is set up.
+@return Symbian OS error code where KErrNone indicates success
+ and any other value indicates failure.
+*/
+ {
+ iClientTid = aClient.Id();
+ iClientSid = aClient.SecureId();
+
+ // Need to obtain the drive letter for the exe
+ RProcess clientProcess;
+ TInt r = aClient.Process(clientProcess);
+ if(r != KErrNone)
+ {
+ return r; // Presumably it exited...
+ }
+ iClientPid = clientProcess.Id();
+ clientProcess.Close();
+
+ iUpsSession = &aSession;
+ return KErrNone;
+ }
+
+TInt RUpsSubsession::CreateSubsession()
+/**
+ Create a subsession for a specific SS client over the supplied session.
+
+ @param aSession Connected session to the UPS server.
+ @param aClient SS client for whom this session is set up.
+ @return Symbian OS error code where KErrNone indicates success
+ and any other value indicates failure.
+ @capability ProtServ
+ */
+ {
+ __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
+ TPckgBuf<TThreadId> tidBuf = iClientTid;
+ TPckgBuf<TProcessId> pidBuf = iClientPid;
+ TIpcArgs args(&tidBuf, &pidBuf);
+ return RScsClientSubsessionBase::CreateSubsession(*iUpsSession, ESessSubsessFromThreadId, args);
+ }
+
+EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk,
+ const TServiceId& aServiceId, const TDesC& aDestination,
+ TUpsDecision& aDecision, TRequestStatus& aStatus)
+/**
+ Determines whether the system server should perform the service requested
+ by the client application. Depending on licensee configuration this function
+ will either complete immediately if the client passed the system servers
+ security policy check. Alternatively, every request may require additional
+ authorisation by the User Prompt Service.
+
+ @see RUpsSubsession::AuthoriseInternal
+
+ @param aServerCheckOk Whether the client request passed the security check
+ implemented by the system server e.g. does the client
+ have the correct capabilities for the requested service.
+ @param aServiceId Service which the client wants to use.
+ @param aDestination More information about the service, e.g. this
+ could be a telephone number is the client wanted
+ to make a call.
+ @param aDecision When the request completes successfully, the verdict
+ is written to this variable.
+ @param aStatus The server completes this request object when it
+ has finished handling the request.
+ @capability ProtServ
+ */
+ {
+ __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
+
+ AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, KNullDesC8, aDecision, aStatus);
+ }
+
+EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk,
+ const TServiceId& aServiceId, const TDesC& aDestination,
+ const TDesC8& aOpaqueData,
+ TUpsDecision& aDecision, TRequestStatus& aStatus)
+/**
+ Determines whether the system server should perform the service requested
+ by the client application. Depending on licensee configuration this function
+ will either complete immediately if the client passed the system servers
+ security policy check. Alternatively, every request may require additional
+ authorisation by the User Prompt Service.
+
+ @see RUpsSubsession::AuthoriseInternal
+
+ @param aServerCheckOk Whether the client request passed the security check
+ implemented by the system server e.g. does the client
+ have the correct capabilities for the requested service.
+ @param aServiceId Service which the client wants to use.
+ @param aDestination More information about the service, e.g. this
+ could be a telephone number is the client wanted
+ to make a call.
+ @param aOpaqueData Additional information to describe the request.
+ @param aDecision When the request completes successfully, the verdict
+ is written to this variable.
+ @param aStatus The server completes this request object when it
+ has finished handling the request.
+ @capability ProtServ
+ */
+ {
+ __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
+
+ AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, aOpaqueData, aDecision, aStatus);
+ }
+
+
+void RUpsSubsession::AuthoriseInternal(
+ TBool aServerCheckOk,
+ const TServiceId& aServiceId,
+ const TDesC& aDestination,
+ const TDesC8& aOpaqueData,
+ TUpsDecision& aDecision,
+ TRequestStatus& aStatus)
+/**
+ This helper function is called by the exported overloads of Authorise.
+ It sends the data supplied by the SS to the UPS server.
+
+ @param aServerCheckOk Did the system server checks pass?
+ @param aServiceId Service which the client wants to use.
+ @param aDestination More information about the service, e.g. this
+ could be a telephone number is the client wanted
+ to make a call.
+ @param aOpaqueData Additional information to describe the request.
+ This is KNullDesC8 if the SS used the Authorise overload
+ which did not take opaque data.
+ @param aDecision When the request completes successfully, the verdict
+ is written to this variable.
+ @param aStatus The server completes this request object when it
+ has finished handling the request.
+ @capability ProtServ
+ */
+ {
+ TBool decided = EFalse;
+ TInt err = KErrNone;
+
+ __ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
+ CUpsClientConfig::TQueryUpsResult result = iUpsSession->iClientConfig->QueryUps(aServerCheckOk, aServiceId, iClientSid, iClientPid);
+ switch(result)
+ {
+ case CUpsClientConfig::EAllow:
+ decided = ETrue;
+ aDecision = EUpsDecYes;
+ break;
+
+ case CUpsClientConfig::EQueryUps:
+ break;
+
+ case CUpsClientConfig::EReject:
+ decided = ETrue;
+ aDecision = EUpsDecNo;
+ break;
+ BULLSEYE_OFF
+ default:
+ break;
+ }
+ BULLSEYE_RESTORE
+
+ if(!decided && !iSubsessionCreated)
+ {
+ // We need to query the UPS, but have not created the subsession yet.
+ err = CreateSubsession();
+ if(err != KErrNone)
+ {
+ aDecision = EUpsDecNo;
+ decided = ETrue;
+ }
+ else
+ {
+ iSubsessionCreated = ETrue;
+ // aDecision will be set when we query the UPS
+ }
+ }
+
+ if(decided)
+ {
+ // Either do not need to query UPS, or an error occured, so complete client
+ // and return
+ aStatus = KRequestPending;
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, err);
+ return; // Either do not need to query UPS, or an error occured, so return
+ }
+
+ //
+ // Query UPS
+ //
+ // only three arguments can be sent to a subsession, so split
+ // this operation into two stages.
+
+ TInt r = PreparePrompt(aServiceId, aDestination, aOpaqueData);
+ if (r != KErrNone)
+ {
+ TRequestStatus* prs = &aStatus;
+ User::RequestComplete(prs, r);
+ return;
+ }
+
+ ExecutePrompt(aServerCheckOk, aDecision, aStatus);
+ }
+
+TInt RUpsSubsession::PreparePrompt(const TServiceId& aServiceId, const TDesC& aDestination, const TDesC8& aOpaqueData)
+/**
+ Ask the UPS server to prepare to make a decision. This will be followed
+ by a call to ExecutePrompt.
+
+ @param aServiceId Service which the client wants to use.
+ @param aDestination More information about the service, e.g. this
+ could be a telephone number is the client wanted
+ to make a call.
+ @param aOpaqueData Additional information to describe the request.
+ This is KNullDesC8 if the SS used the Authorise overload
+ which did not take opaque data.
+ @return Error code with which the server completed the request.
+ @capability ProtServ
+ @see ExecutePrompt
+ */
+ {
+ TIpcArgs args(aServiceId.iUid, &aDestination, &aOpaqueData);
+ return CallSubsessionFunction(ESubsessPreparePrompt, args);
+ }
+
+void RUpsSubsession::ExecutePrompt(TBool aServerCheckOk, TUpsDecision& aDecision, TRequestStatus& aStatus)
+/**
+ Ask the UPS to execute the request which was set up with PreparePrompt.
+
+ @param aDecision When the request completes successfully, this argument
+ is updated with the verdict.
+ @param aStatus The server completes this request object when it
+ has finished handling the request.
+ @capability ProtServ
+ @see PreparePrompt
+ */
+ {
+ TUint8* decPtr = reinterpret_cast<TUint8*>(&aDecision);
+ iDecPtr.Set(decPtr, sizeof(TUpsDecision), sizeof(TUpsDecision));
+
+ TIpcArgs args(&iDecPtr, aServerCheckOk);
+ CallSubsessionFunction(ESubsessExecutePrompt, args, aStatus);
+ }
+
+EXPORT_C void RUpsSubsession::CancelPrompt()
+/**
+ Cancel the prompt request which was launched by calling Authorise.
+
+ This function has no effect if there is no outstanding request.
+ @capability ProtServ
+ */
+ {
+ if(iSubsessionCreated)
+ {
+ CancelSubsessionFunction(ESubsessExecutePrompt);
+ }
+ }
+
+EXPORT_C void RUpsSubsession::Close()
+ /**
+ Close and clean up this subsession object.
+ */
+ {
+ if(iSubsessionCreated)
+ {
+ RScsClientSubsessionBase::Close();
+ }
+ }
+
+
+
+} // End of namespace UserPromptService
+
+// End of file