os/security/authorisation/userpromptservice/server/source/upsclient/rupssubsession.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
* RUpsSubsession implementation.	See class and function definitions
sl@0
    16
* for more detail.
sl@0
    17
*
sl@0
    18
*/
sl@0
    19
sl@0
    20
sl@0
    21
/**
sl@0
    22
 @file
sl@0
    23
*/
sl@0
    24
sl@0
    25
#include <ups/upsclient.h>
sl@0
    26
#include "upsclientconfig.h"
sl@0
    27
#include "upscommon.h"
sl@0
    28
#include <ups/upserr.h>
sl@0
    29
sl@0
    30
namespace UserPromptService
sl@0
    31
	{
sl@0
    32
sl@0
    33
sl@0
    34
EXPORT_C RUpsSubsession::RUpsSubsession()
sl@0
    35
/**
sl@0
    36
	This constructor provides a single point of definition from
sl@0
    37
	which the superclass constructor is called.
sl@0
    38
 */
sl@0
    39
:	RScsClientSubsessionBase(),
sl@0
    40
	iDecPtr(NULL, 0),
sl@0
    41
	iSubsessionCreated(EFalse), iClientTid(), iClientSid(TUid::Null()), iClientPid(0), iUpsSession(0)
sl@0
    42
	{
sl@0
    43
	// empty.
sl@0
    44
	}
sl@0
    45
sl@0
    46
EXPORT_C TInt RUpsSubsession::Initialise(RUpsSession& aSession, const RThread& aClient)
sl@0
    47
/**
sl@0
    48
Saves the details required to create a subsession specific to the client thread.
sl@0
    49
sl@0
    50
The actual subsession creation is defered until the subsession is required (which
sl@0
    51
may be never if the policy says server checks are sufficient).
sl@0
    52
sl@0
    53
Several RUpsSubsession objects can share a single RUpsSession.
sl@0
    54
sl@0
    55
If any of the RUpsSubsession objects are to be used in a different thread to the RUpsSession, then
sl@0
    56
ShareAuto() must be called on the RUpsSession.
sl@0
    57
sl@0
    58
@see RSubSessionBase::CreateSubsession
sl@0
    59
sl@0
    60
@param	aSession		Connected session to the UPS server.
sl@0
    61
@param	aClient			SS client for whom this session is set up.
sl@0
    62
@return					Symbian OS error code where KErrNone indicates success
sl@0
    63
						and any other value indicates failure.
sl@0
    64
*/
sl@0
    65
	{
sl@0
    66
	iClientTid = aClient.Id();
sl@0
    67
	iClientSid = aClient.SecureId();
sl@0
    68
sl@0
    69
	// Need to obtain the drive letter for the exe
sl@0
    70
	RProcess clientProcess;
sl@0
    71
	TInt r = aClient.Process(clientProcess);
sl@0
    72
	if(r != KErrNone)
sl@0
    73
				{
sl@0
    74
				return r; // Presumably it exited...
sl@0
    75
				}
sl@0
    76
	iClientPid = clientProcess.Id();
sl@0
    77
	clientProcess.Close();
sl@0
    78
	
sl@0
    79
	iUpsSession = &aSession;
sl@0
    80
	return KErrNone;
sl@0
    81
	}
sl@0
    82
sl@0
    83
TInt RUpsSubsession::CreateSubsession()
sl@0
    84
/**
sl@0
    85
	Create a subsession for a specific SS client over the supplied session.
sl@0
    86
sl@0
    87
	@param	aSession		Connected session to the UPS server.
sl@0
    88
	@param	aClient			SS client for whom this session is set up.
sl@0
    89
	@return					Symbian OS error code where KErrNone indicates success
sl@0
    90
							and any other value indicates failure.
sl@0
    91
	@capability ProtServ 
sl@0
    92
 */
sl@0
    93
	{
sl@0
    94
	__ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
sl@0
    95
	TPckgBuf<TThreadId> tidBuf = iClientTid;
sl@0
    96
	TPckgBuf<TProcessId> pidBuf = iClientPid;
sl@0
    97
	TIpcArgs args(&tidBuf, &pidBuf);
sl@0
    98
	return RScsClientSubsessionBase::CreateSubsession(*iUpsSession, ESessSubsessFromThreadId, args);
sl@0
    99
	}
sl@0
   100
sl@0
   101
EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk,
sl@0
   102
										const TServiceId& aServiceId, const TDesC& aDestination,
sl@0
   103
										TUpsDecision& aDecision, TRequestStatus& aStatus)
sl@0
   104
/**
sl@0
   105
	Determines whether the system server should perform the service requested
sl@0
   106
	by the client application. Depending on licensee configuration this function
sl@0
   107
	will either complete immediately if the client passed the system servers
sl@0
   108
	security policy check. Alternatively, every request may require additional
sl@0
   109
	authorisation by the User Prompt Service.
sl@0
   110
	
sl@0
   111
	@see RUpsSubsession::AuthoriseInternal
sl@0
   112
sl@0
   113
	@param	aServerCheckOk	Whether the client request passed the security check
sl@0
   114
							implemented by the system server e.g. does the client
sl@0
   115
							have the correct capabilities for the requested service.
sl@0
   116
	@param	aServiceId		Service which the client wants to use.
sl@0
   117
	@param	aDestination	More information about the service, e.g. this
sl@0
   118
							could be a telephone number is the client wanted
sl@0
   119
							to make a call.
sl@0
   120
	@param	aDecision		When the request completes successfully, the verdict
sl@0
   121
							is written to this variable.
sl@0
   122
	@param	aStatus			The server completes this request object when it
sl@0
   123
							has finished handling the request.
sl@0
   124
	@capability ProtServ 
sl@0
   125
 */
sl@0
   126
	{
sl@0
   127
	__ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
sl@0
   128
sl@0
   129
	AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, KNullDesC8, aDecision, aStatus);
sl@0
   130
	}
sl@0
   131
sl@0
   132
EXPORT_C void RUpsSubsession::Authorise(TBool aServerCheckOk, 
sl@0
   133
										const TServiceId& aServiceId, const TDesC& aDestination, 
sl@0
   134
										const TDesC8& aOpaqueData, 
sl@0
   135
										TUpsDecision& aDecision, TRequestStatus& aStatus)
sl@0
   136
/**
sl@0
   137
	Determines whether the system server should perform the service requested
sl@0
   138
	by the client application. Depending on licensee configuration this function
sl@0
   139
	will either complete immediately if the client passed the system servers
sl@0
   140
	security policy check. Alternatively, every request may require additional
sl@0
   141
	authorisation by the User Prompt Service.
sl@0
   142
	
sl@0
   143
	@see RUpsSubsession::AuthoriseInternal
sl@0
   144
sl@0
   145
	@param	aServerCheckOk	Whether the client request passed the security check
sl@0
   146
							implemented by the system server e.g. does the client
sl@0
   147
							have the correct capabilities for the requested service.
sl@0
   148
	@param	aServiceId		Service which the client wants to use.
sl@0
   149
	@param	aDestination	More information about the service, e.g. this
sl@0
   150
							could be a telephone number is the client wanted
sl@0
   151
							to make a call.
sl@0
   152
	@param	aOpaqueData		Additional information to describe the request.
sl@0
   153
	@param	aDecision		When the request completes successfully, the verdict
sl@0
   154
							is written to this variable.
sl@0
   155
	@param	aStatus			The server completes this request object when it
sl@0
   156
							has finished handling the request.
sl@0
   157
	@capability ProtServ 
sl@0
   158
 */
sl@0
   159
	{
sl@0
   160
	__ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
sl@0
   161
sl@0
   162
	AuthoriseInternal(aServerCheckOk, aServiceId, aDestination, aOpaqueData, aDecision, aStatus);
sl@0
   163
	}
sl@0
   164
sl@0
   165
sl@0
   166
void RUpsSubsession::AuthoriseInternal(
sl@0
   167
	TBool aServerCheckOk,
sl@0
   168
	const TServiceId& aServiceId,
sl@0
   169
	const TDesC& aDestination,
sl@0
   170
	const TDesC8& aOpaqueData,
sl@0
   171
	TUpsDecision& aDecision,
sl@0
   172
	TRequestStatus& aStatus)
sl@0
   173
/**
sl@0
   174
	This helper function is called by the exported overloads of Authorise.
sl@0
   175
	It sends the data supplied by the SS to the UPS server.
sl@0
   176
sl@0
   177
	@param	aServerCheckOk	Did the system server checks pass?
sl@0
   178
	@param	aServiceId		Service which the client wants to use.
sl@0
   179
	@param	aDestination	More information about the service, e.g. this
sl@0
   180
							could be a telephone number is the client wanted
sl@0
   181
							to make a call.
sl@0
   182
	@param	aOpaqueData		Additional information to describe the request.
sl@0
   183
							This is KNullDesC8 if the SS used the Authorise overload
sl@0
   184
							which did not take opaque data.
sl@0
   185
	@param	aDecision		When the request completes successfully, the verdict
sl@0
   186
							is written to this variable.
sl@0
   187
	@param	aStatus			The server completes this request object when it
sl@0
   188
							has finished handling the request.
sl@0
   189
	@capability ProtServ 
sl@0
   190
 */
sl@0
   191
	{
sl@0
   192
	TBool decided = EFalse;
sl@0
   193
	TInt err = KErrNone;	
sl@0
   194
sl@0
   195
	__ASSERT_ALWAYS(iUpsSession, User::Panic(KUpsClientPanicCat, EUpsClientNotInitialised));
sl@0
   196
	CUpsClientConfig::TQueryUpsResult result = iUpsSession->iClientConfig->QueryUps(aServerCheckOk, aServiceId, iClientSid, iClientPid);
sl@0
   197
	switch(result)
sl@0
   198
		{
sl@0
   199
		case CUpsClientConfig::EAllow:
sl@0
   200
			decided = ETrue;
sl@0
   201
			aDecision = EUpsDecYes;
sl@0
   202
			break;
sl@0
   203
sl@0
   204
		case CUpsClientConfig::EQueryUps:
sl@0
   205
			break;
sl@0
   206
sl@0
   207
		case CUpsClientConfig::EReject:
sl@0
   208
			decided = ETrue;
sl@0
   209
			aDecision = EUpsDecNo;
sl@0
   210
			break;
sl@0
   211
		BULLSEYE_OFF
sl@0
   212
		default:
sl@0
   213
			break;	
sl@0
   214
		}
sl@0
   215
		BULLSEYE_RESTORE
sl@0
   216
			
sl@0
   217
	if(!decided && !iSubsessionCreated)
sl@0
   218
		{
sl@0
   219
		// We need to query the UPS, but have not created the subsession yet.
sl@0
   220
		err = CreateSubsession();
sl@0
   221
		if(err != KErrNone)
sl@0
   222
			{
sl@0
   223
			aDecision = EUpsDecNo;
sl@0
   224
			decided = ETrue;
sl@0
   225
			}
sl@0
   226
		else
sl@0
   227
			{
sl@0
   228
			iSubsessionCreated = ETrue;
sl@0
   229
			// aDecision will be set when we query the UPS
sl@0
   230
			}
sl@0
   231
		}
sl@0
   232
sl@0
   233
	if(decided)
sl@0
   234
		{
sl@0
   235
		// Either do not need to query UPS, or an error occured, so complete client
sl@0
   236
		// and return
sl@0
   237
		aStatus = KRequestPending;
sl@0
   238
		TRequestStatus* status = &aStatus;
sl@0
   239
		User::RequestComplete(status, err);
sl@0
   240
		return; // Either do not need to query UPS, or an error occured, so return
sl@0
   241
		}
sl@0
   242
sl@0
   243
	//
sl@0
   244
	// Query UPS
sl@0
   245
	//
sl@0
   246
	// only three arguments can be sent to a subsession, so split
sl@0
   247
	// this operation into two stages.
sl@0
   248
sl@0
   249
	TInt r = PreparePrompt(aServiceId, aDestination, aOpaqueData);
sl@0
   250
	if (r != KErrNone)
sl@0
   251
		{
sl@0
   252
		TRequestStatus* prs = &aStatus;
sl@0
   253
		User::RequestComplete(prs, r);
sl@0
   254
		return;
sl@0
   255
		}
sl@0
   256
	
sl@0
   257
	ExecutePrompt(aServerCheckOk, aDecision, aStatus);
sl@0
   258
	}
sl@0
   259
sl@0
   260
TInt RUpsSubsession::PreparePrompt(const TServiceId& aServiceId, const TDesC& aDestination, const TDesC8& aOpaqueData)
sl@0
   261
/**
sl@0
   262
	Ask the UPS server to prepare to make a decision.  This will be followed
sl@0
   263
	by a call to ExecutePrompt.
sl@0
   264
sl@0
   265
	@param	aServiceId		Service which the client wants to use.
sl@0
   266
	@param	aDestination	More information about the service, e.g. this
sl@0
   267
							could be a telephone number is the client wanted
sl@0
   268
							to make a call.
sl@0
   269
	@param	aOpaqueData		Additional information to describe the request.
sl@0
   270
							This is KNullDesC8 if the SS used the Authorise overload
sl@0
   271
							which did not take opaque data.
sl@0
   272
	@return					Error code with which the server completed the request.
sl@0
   273
	@capability ProtServ 
sl@0
   274
	@see ExecutePrompt
sl@0
   275
 */
sl@0
   276
	{
sl@0
   277
	TIpcArgs args(aServiceId.iUid, &aDestination, &aOpaqueData);
sl@0
   278
	return CallSubsessionFunction(ESubsessPreparePrompt, args);
sl@0
   279
	}
sl@0
   280
sl@0
   281
void RUpsSubsession::ExecutePrompt(TBool aServerCheckOk, TUpsDecision& aDecision, TRequestStatus& aStatus)
sl@0
   282
/**
sl@0
   283
	Ask the UPS to execute the request which was set up with PreparePrompt.
sl@0
   284
sl@0
   285
	@param	aDecision		When the request completes successfully, this argument
sl@0
   286
							is updated with the verdict.
sl@0
   287
	@param	aStatus			The server completes this request object when it
sl@0
   288
							has finished handling the request.
sl@0
   289
	@capability ProtServ 
sl@0
   290
	@see PreparePrompt
sl@0
   291
 */
sl@0
   292
	{
sl@0
   293
	TUint8* decPtr = reinterpret_cast<TUint8*>(&aDecision);
sl@0
   294
	iDecPtr.Set(decPtr, sizeof(TUpsDecision), sizeof(TUpsDecision));
sl@0
   295
	
sl@0
   296
	TIpcArgs args(&iDecPtr, aServerCheckOk);
sl@0
   297
	CallSubsessionFunction(ESubsessExecutePrompt, args, aStatus);
sl@0
   298
	}
sl@0
   299
sl@0
   300
EXPORT_C void RUpsSubsession::CancelPrompt()
sl@0
   301
/**
sl@0
   302
	Cancel the prompt request which was launched by calling Authorise.
sl@0
   303
sl@0
   304
	This function has no effect if there is no outstanding request.
sl@0
   305
	@capability ProtServ 
sl@0
   306
 */
sl@0
   307
	{
sl@0
   308
	if(iSubsessionCreated)
sl@0
   309
		{
sl@0
   310
		CancelSubsessionFunction(ESubsessExecutePrompt);
sl@0
   311
		}
sl@0
   312
	}
sl@0
   313
sl@0
   314
EXPORT_C void RUpsSubsession::Close()
sl@0
   315
	/**
sl@0
   316
	   Close and clean up this subsession object.
sl@0
   317
	*/
sl@0
   318
	{
sl@0
   319
	if(iSubsessionCreated)
sl@0
   320
		{
sl@0
   321
		RScsClientSubsessionBase::Close();
sl@0
   322
		}
sl@0
   323
	}
sl@0
   324
sl@0
   325
sl@0
   326
sl@0
   327
} // End of namespace UserPromptService
sl@0
   328
sl@0
   329
// End of file