os/security/authorisation/userpromptservice/server/source/upsclient/rupssession.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2007-2010 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
* RUpsSession 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
sl@0
    26
#include <ups/upsclient.h>
sl@0
    27
#include <e32property.h>
sl@0
    28
#include <e32debug.h>
sl@0
    29
#include "upscommon.h"
sl@0
    30
#include "upsclientconfig.h"
sl@0
    31
sl@0
    32
namespace UserPromptService
sl@0
    33
	{
sl@0
    34
sl@0
    35
NONSHARABLE_CLASS(CPolicyChangeWatcher) : public CActive
sl@0
    36
	{
sl@0
    37
public:
sl@0
    38
	static CPolicyChangeWatcher *NewL(RUpsSession &aUpsSession);
sl@0
    39
	~CPolicyChangeWatcher();
sl@0
    40
private:
sl@0
    41
	CPolicyChangeWatcher(RUpsSession &aUpsSession);
sl@0
    42
	void ConstructL();
sl@0
    43
	virtual void DoCancel();
sl@0
    44
	virtual void RunL();
sl@0
    45
	virtual TInt RunError(TInt aError);
sl@0
    46
sl@0
    47
private:
sl@0
    48
	RProperty iUpsPolicyChangeProperty;
sl@0
    49
	RUpsSession &iUpsSession;
sl@0
    50
	};
sl@0
    51
sl@0
    52
EXPORT_C RUpsSession::RUpsSession()
sl@0
    53
/**
sl@0
    54
	This constructor provides a single point of definition from
sl@0
    55
	which the superclass constructor is called.
sl@0
    56
 */
sl@0
    57
:	RScsClientBase(),
sl@0
    58
	iPolicyChangeWatcher(0),
sl@0
    59
	iClientConfig(0)
sl@0
    60
	{
sl@0
    61
	// empty.
sl@0
    62
	}
sl@0
    63
sl@0
    64
EXPORT_C TInt RUpsSession::Connect()
sl@0
    65
/**
sl@0
    66
	Connect to the UPS server.
sl@0
    67
sl@0
    68
	The thread which calls this function must be the same one which later calls Close().
sl@0
    69
sl@0
    70
	Once connected, this session can be shared by multiple RUpsSubsession objects.
sl@0
    71
sl@0
    72
	The RUpsSubsession objects are allowed to be in different threads, in which case ShareAuto() must be called before they are created.
sl@0
    73
sl@0
    74
	@return					Symbian OS error code where KErrNone indicates
sl@0
    75
							success and any other value indicates failure.
sl@0
    76
 */
sl@0
    77
	{
sl@0
    78
	TVersion v = UserPromptService::Version();
sl@0
    79
	TUidType serverFullUid = UserPromptService::ServerImageFullUid();
sl@0
    80
sl@0
    81
	TInt r = RScsClientBase::Connect(
sl@0
    82
		UserPromptService::KUpsServerName, v, UserPromptService::KServerImageName, serverFullUid);
sl@0
    83
	
sl@0
    84
	if (r == KErrNone)	
sl@0
    85
		{
sl@0
    86
		// preload the configuration
sl@0
    87
		TRAP(r, RetrieveClientConfigL());
sl@0
    88
		}
sl@0
    89
sl@0
    90
	if((r == KErrNone) && (CActiveScheduler::Current() != 0))
sl@0
    91
		{
sl@0
    92
		delete iPolicyChangeWatcher;
sl@0
    93
		iPolicyChangeWatcher = 0;
sl@0
    94
		TRAP(r, iPolicyChangeWatcher = CPolicyChangeWatcher::NewL(*this));
sl@0
    95
		}
sl@0
    96
sl@0
    97
	if(r != KErrNone)
sl@0
    98
		{
sl@0
    99
		Close();
sl@0
   100
		}
sl@0
   101
	
sl@0
   102
	return r;
sl@0
   103
	}
sl@0
   104
	
sl@0
   105
sl@0
   106
static void deleteArrayOfTServiceConfig(TAny *aPtr)
sl@0
   107
	{
sl@0
   108
	TServiceConfig *array = reinterpret_cast<TServiceConfig *>(aPtr);
sl@0
   109
	delete [] array;
sl@0
   110
	}
sl@0
   111
sl@0
   112
void RUpsSession::RetrieveClientConfigL()
sl@0
   113
	{
sl@0
   114
	// Query how many TServiceConfig entries there are.
sl@0
   115
	TPckgBuf<TInt> countBuf;
sl@0
   116
	User::LeaveIfError(CallSessionFunction(EGetClientConfigLength, TIpcArgs(&countBuf)));
sl@0
   117
	// Retrieve count from buffer
sl@0
   118
	TInt count = countBuf();
sl@0
   119
	
sl@0
   120
	// Create buffer to hold entries
sl@0
   121
	TServiceConfig *rawServiceConfig = new(ELeave) TServiceConfig[count];
sl@0
   122
	CleanupStack::PushL(TCleanupItem(deleteArrayOfTServiceConfig, rawServiceConfig));
sl@0
   123
sl@0
   124
	// Wrap array in a TPtr8 and use it to read array from server
sl@0
   125
	TInt size = count * sizeof(TServiceConfig);
sl@0
   126
	TPtr8 ptr((TUint8*)rawServiceConfig, size, size);
sl@0
   127
	User::LeaveIfError(CallSessionFunction(EGetClientConfigData, TIpcArgs(&ptr)));
sl@0
   128
sl@0
   129
	CUpsClientConfig *tmp = CUpsClientConfig::NewL(count, rawServiceConfig);
sl@0
   130
	delete iClientConfig;
sl@0
   131
	iClientConfig = tmp;
sl@0
   132
sl@0
   133
	CleanupStack::PopAndDestroy(); // get rid of rawServiceConfig array
sl@0
   134
	}
sl@0
   135
	
sl@0
   136
sl@0
   137
EXPORT_C void RUpsSession::Close()
sl@0
   138
/**
sl@0
   139
Frees the configuration object and calls RScsClientBase::Close
sl@0
   140
sl@0
   141
This function MUST be called by the same thread which Connect().
sl@0
   142
*/
sl@0
   143
	{
sl@0
   144
	delete iClientConfig;
sl@0
   145
	iClientConfig = 0;
sl@0
   146
sl@0
   147
	if(iPolicyChangeWatcher)
sl@0
   148
		{
sl@0
   149
		iPolicyChangeWatcher->Cancel();
sl@0
   150
		}
sl@0
   151
	delete iPolicyChangeWatcher;
sl@0
   152
	iPolicyChangeWatcher = 0;
sl@0
   153
	
sl@0
   154
	RScsClientBase::Close();
sl@0
   155
	}
sl@0
   156
sl@0
   157
void RUpsSession::NotifyPolicyFileChangedL()
sl@0
   158
/**
sl@0
   159
	@internalComponent
sl@0
   160
	@released
sl@0
   161
sl@0
   162
	Policy files have changed so update serviceconfig cache.
sl@0
   163
*/
sl@0
   164
	{
sl@0
   165
	RetrieveClientConfigL();
sl@0
   166
	}
sl@0
   167
sl@0
   168
CUpsClientConfig::CUpsClientConfig()
sl@0
   169
	: iServiceConfig(1 /* granularity */, 0 /* key offset */)
sl@0
   170
	{
sl@0
   171
	}
sl@0
   172
	
sl@0
   173
CUpsClientConfig::~CUpsClientConfig()
sl@0
   174
	{
sl@0
   175
	iServiceConfig.Close();
sl@0
   176
	}
sl@0
   177
	
sl@0
   178
CUpsClientConfig* CUpsClientConfig::NewL(TInt aCount, TServiceConfig *aRawServiceConfig)
sl@0
   179
	/**
sl@0
   180
	   @param serviceConfig
sl@0
   181
sl@0
   182
	   Takes ownership of the serviceConfig array via swap. Callers array will be cleared.
sl@0
   183
	*/
sl@0
   184
	{
sl@0
   185
	CUpsClientConfig *self = new(ELeave) CUpsClientConfig();
sl@0
   186
	CleanupStack::PushL(self);
sl@0
   187
	self->ConstructL(aCount, aRawServiceConfig);
sl@0
   188
	CleanupStack::Pop(self);
sl@0
   189
	return self;
sl@0
   190
	}
sl@0
   191
sl@0
   192
	
sl@0
   193
void CUpsClientConfig::ConstructL(TInt aCount, TServiceConfig *aRawServiceConfig)
sl@0
   194
	{
sl@0
   195
	iServiceConfig.ReserveL(aCount);
sl@0
   196
	for(TInt i=0; i < aCount; ++i)
sl@0
   197
		{
sl@0
   198
		iServiceConfig.InsertInUnsignedKeyOrderL(aRawServiceConfig[i]);
sl@0
   199
		}
sl@0
   200
	}
sl@0
   201
sl@0
   202
CUpsClientConfig::TQueryUpsResult
sl@0
   203
CUpsClientConfig::QueryUps(TBool aServerChecksPassed,
sl@0
   204
							  const TServiceId &aServiceId, 
sl@0
   205
							  const TSecureId &aClientSid,
sl@0
   206
							  const TProcessId &aClientProcessId) const
sl@0
   207
	{
sl@0
   208
	TServiceConfig sc = {0};
sl@0
   209
	sc.iServiceId = aServiceId.iUid; /* Only service id is used in lookup */
sl@0
   210
	TInt i = iServiceConfig.FindInUnsignedKeyOrder(sc);
sl@0
   211
	if(i == KErrNotFound)
sl@0
   212
		{
sl@0
   213
		// Must be no policy file for this service so no point in querying UPS
sl@0
   214
		return aServerChecksPassed ? EAllow: EReject;
sl@0
   215
		}
sl@0
   216
	
sl@0
   217
	
sl@0
   218
	// Read entry
sl@0
   219
	sc = iServiceConfig[i];
sl@0
   220
sl@0
   221
	switch(sc.iPolicy)
sl@0
   222
		{
sl@0
   223
		case EAlwaysCheck:
sl@0
   224
			return EQueryUps;
sl@0
   225
			
sl@0
   226
		case ECheckPostManufacture:
sl@0
   227
			{
sl@0
   228
			TBool isProtected = (TUint(aClientSid) & 0x80000000) == 0;
sl@0
   229
			if(! isProtected)
sl@0
   230
				{
sl@0
   231
				return EQueryUps;
sl@0
   232
				}
sl@0
   233
sl@0
   234
			// Need to obtain the drive letter for the exe
sl@0
   235
			//
sl@0
   236
			// This requires opening the RProcess and two copies of a full filename (one 8 bit the other unicode)......
sl@0
   237
			// We could optimse this by doing it when Initialise() is called, but that then slows down all Initialise calls even ones
sl@0
   238
			// not doing the  ECheckPostManufacture check.
sl@0
   239
			RProcess clientProcess;
sl@0
   240
			if(clientProcess.Open(aClientProcessId) != KErrNone)
sl@0
   241
				{
sl@0
   242
				return EReject; // Presumably it exited...
sl@0
   243
				}
sl@0
   244
			
sl@0
   245
			TFileName clientExeName = clientProcess.FileName();
sl@0
   246
			clientProcess.Close();
sl@0
   247
			TChar driveChar= clientExeName[0];
sl@0
   248
			
sl@0
   249
			if(aServerChecksPassed && 
sl@0
   250
			   (driveChar == 'z' || driveChar == 'Z'))
sl@0
   251
				{
sl@0
   252
				return EAllow;
sl@0
   253
				}
sl@0
   254
sl@0
   255
			return EQueryUps;
sl@0
   256
			}
sl@0
   257
			
sl@0
   258
		case ECheckUnprotectedSids:
sl@0
   259
			{
sl@0
   260
			TBool isProtected = (TUint(aClientSid) & 0x80000000) == 0;
sl@0
   261
			
sl@0
   262
			if(aServerChecksPassed && isProtected)
sl@0
   263
				{
sl@0
   264
				return EAllow;
sl@0
   265
				}
sl@0
   266
			
sl@0
   267
			return EQueryUps;
sl@0
   268
			}
sl@0
   269
			
sl@0
   270
		case ECheckIfFailed:
sl@0
   271
			return aServerChecksPassed ? EAllow : EQueryUps;
sl@0
   272
sl@0
   273
		BULLSEYE_OFF
sl@0
   274
		default:
sl@0
   275
		BULLSEYE_RESTORE
sl@0
   276
		case ENeverCheck:
sl@0
   277
			return aServerChecksPassed ? EAllow: EReject;
sl@0
   278
			}
sl@0
   279
	// Never gets here
sl@0
   280
	}
sl@0
   281
sl@0
   282
//
sl@0
   283
// CPolicyChangeWatcher member functions
sl@0
   284
//
sl@0
   285
CPolicyChangeWatcher *CPolicyChangeWatcher::NewL(RUpsSession &aUpsSession)
sl@0
   286
	{
sl@0
   287
	CPolicyChangeWatcher *self = new(ELeave) CPolicyChangeWatcher(aUpsSession);
sl@0
   288
	CleanupStack::PushL(self);
sl@0
   289
	self->ConstructL();
sl@0
   290
	CleanupStack::Pop(self);
sl@0
   291
	return self;
sl@0
   292
	}
sl@0
   293
sl@0
   294
CPolicyChangeWatcher::CPolicyChangeWatcher(RUpsSession &aUpsSession)
sl@0
   295
	:	CActive(CActive::EPriorityStandard+1), 
sl@0
   296
		iUpsSession(aUpsSession)
sl@0
   297
	{
sl@0
   298
	CActiveScheduler::Add(this);
sl@0
   299
	}
sl@0
   300
sl@0
   301
void CPolicyChangeWatcher::ConstructL()
sl@0
   302
	{
sl@0
   303
	User::LeaveIfError(iUpsPolicyChangeProperty.Attach(KUpsServerUid, KUpsServiceConfigProperty, EOwnerThread));
sl@0
   304
	iUpsPolicyChangeProperty.Subscribe(iStatus);
sl@0
   305
	SetActive();
sl@0
   306
	}
sl@0
   307
sl@0
   308
CPolicyChangeWatcher::~CPolicyChangeWatcher()
sl@0
   309
	{
sl@0
   310
	Cancel();
sl@0
   311
	iUpsPolicyChangeProperty.Close();
sl@0
   312
	}
sl@0
   313
sl@0
   314
void CPolicyChangeWatcher::DoCancel()
sl@0
   315
	{
sl@0
   316
	iUpsPolicyChangeProperty.Cancel();
sl@0
   317
	}
sl@0
   318
sl@0
   319
void CPolicyChangeWatcher::RunL()
sl@0
   320
	{
sl@0
   321
	// Re-subscribe for policy file change notifications
sl@0
   322
	iUpsPolicyChangeProperty.Subscribe(iStatus);
sl@0
   323
	SetActive();
sl@0
   324
sl@0
   325
	// Tell session to update its cache.
sl@0
   326
	iUpsSession.NotifyPolicyFileChangedL();
sl@0
   327
	}
sl@0
   328
sl@0
   329
TInt CPolicyChangeWatcher::RunError(TInt /* aError */)
sl@0
   330
	{
sl@0
   331
	// Ignore all errors
sl@0
   332
	//RDebug::Printf("CPolicyChangeWatcher::RunError(%d)\n", aError);
sl@0
   333
	return KErrNone;
sl@0
   334
	}
sl@0
   335
sl@0
   336
sl@0
   337
} // End of namespace UserPromptService
sl@0
   338
sl@0
   339
// End of file
sl@0
   340