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