os/security/authorisation/userpromptservice/server/source/upsclient/rupssession.cpp
Update contrib.
2 * Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * RUpsSession implementation. See class and function definitions
26 #include <ups/upsclient.h>
27 #include <e32property.h>
29 #include "upscommon.h"
30 #include "upsclientconfig.h"
32 namespace UserPromptService
35 NONSHARABLE_CLASS(CPolicyChangeWatcher) : public CActive
38 static CPolicyChangeWatcher *NewL(RUpsSession &aUpsSession);
39 ~CPolicyChangeWatcher();
41 CPolicyChangeWatcher(RUpsSession &aUpsSession);
43 virtual void DoCancel();
45 virtual TInt RunError(TInt aError);
48 RProperty iUpsPolicyChangeProperty;
49 RUpsSession &iUpsSession;
52 EXPORT_C RUpsSession::RUpsSession()
54 This constructor provides a single point of definition from
55 which the superclass constructor is called.
58 iPolicyChangeWatcher(0),
64 EXPORT_C TInt RUpsSession::Connect()
66 Connect to the UPS server.
68 The thread which calls this function must be the same one which later calls Close().
70 Once connected, this session can be shared by multiple RUpsSubsession objects.
72 The RUpsSubsession objects are allowed to be in different threads, in which case ShareAuto() must be called before they are created.
74 @return Symbian OS error code where KErrNone indicates
75 success and any other value indicates failure.
78 TVersion v = UserPromptService::Version();
79 TUidType serverFullUid = UserPromptService::ServerImageFullUid();
81 TInt r = RScsClientBase::Connect(
82 UserPromptService::KUpsServerName, v, UserPromptService::KServerImageName, serverFullUid);
86 // preload the configuration
87 TRAP(r, RetrieveClientConfigL());
90 if((r == KErrNone) && (CActiveScheduler::Current() != 0))
92 delete iPolicyChangeWatcher;
93 iPolicyChangeWatcher = 0;
94 TRAP(r, iPolicyChangeWatcher = CPolicyChangeWatcher::NewL(*this));
106 static void deleteArrayOfTServiceConfig(TAny *aPtr)
108 TServiceConfig *array = reinterpret_cast<TServiceConfig *>(aPtr);
112 void RUpsSession::RetrieveClientConfigL()
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();
120 // Create buffer to hold entries
121 TServiceConfig *rawServiceConfig = new(ELeave) TServiceConfig[count];
122 CleanupStack::PushL(TCleanupItem(deleteArrayOfTServiceConfig, rawServiceConfig));
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)));
129 CUpsClientConfig *tmp = CUpsClientConfig::NewL(count, rawServiceConfig);
130 delete iClientConfig;
133 CleanupStack::PopAndDestroy(); // get rid of rawServiceConfig array
137 EXPORT_C void RUpsSession::Close()
139 Frees the configuration object and calls RScsClientBase::Close
141 This function MUST be called by the same thread which Connect().
144 delete iClientConfig;
147 if(iPolicyChangeWatcher)
149 iPolicyChangeWatcher->Cancel();
151 delete iPolicyChangeWatcher;
152 iPolicyChangeWatcher = 0;
154 RScsClientBase::Close();
157 void RUpsSession::NotifyPolicyFileChangedL()
162 Policy files have changed so update serviceconfig cache.
165 RetrieveClientConfigL();
168 CUpsClientConfig::CUpsClientConfig()
169 : iServiceConfig(1 /* granularity */, 0 /* key offset */)
173 CUpsClientConfig::~CUpsClientConfig()
175 iServiceConfig.Close();
178 CUpsClientConfig* CUpsClientConfig::NewL(TInt aCount, TServiceConfig *aRawServiceConfig)
182 Takes ownership of the serviceConfig array via swap. Callers array will be cleared.
185 CUpsClientConfig *self = new(ELeave) CUpsClientConfig();
186 CleanupStack::PushL(self);
187 self->ConstructL(aCount, aRawServiceConfig);
188 CleanupStack::Pop(self);
193 void CUpsClientConfig::ConstructL(TInt aCount, TServiceConfig *aRawServiceConfig)
195 iServiceConfig.ReserveL(aCount);
196 for(TInt i=0; i < aCount; ++i)
198 iServiceConfig.InsertInUnsignedKeyOrderL(aRawServiceConfig[i]);
202 CUpsClientConfig::TQueryUpsResult
203 CUpsClientConfig::QueryUps(TBool aServerChecksPassed,
204 const TServiceId &aServiceId,
205 const TSecureId &aClientSid,
206 const TProcessId &aClientProcessId) const
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)
213 // Must be no policy file for this service so no point in querying UPS
214 return aServerChecksPassed ? EAllow: EReject;
219 sc = iServiceConfig[i];
226 case ECheckPostManufacture:
228 TBool isProtected = (TUint(aClientSid) & 0x80000000) == 0;
234 // Need to obtain the drive letter for the exe
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)
242 return EReject; // Presumably it exited...
245 TFileName clientExeName = clientProcess.FileName();
246 clientProcess.Close();
247 TChar driveChar= clientExeName[0];
249 if(aServerChecksPassed &&
250 (driveChar == 'z' || driveChar == 'Z'))
258 case ECheckUnprotectedSids:
260 TBool isProtected = (TUint(aClientSid) & 0x80000000) == 0;
262 if(aServerChecksPassed && isProtected)
271 return aServerChecksPassed ? EAllow : EQueryUps;
277 return aServerChecksPassed ? EAllow: EReject;
283 // CPolicyChangeWatcher member functions
285 CPolicyChangeWatcher *CPolicyChangeWatcher::NewL(RUpsSession &aUpsSession)
287 CPolicyChangeWatcher *self = new(ELeave) CPolicyChangeWatcher(aUpsSession);
288 CleanupStack::PushL(self);
290 CleanupStack::Pop(self);
294 CPolicyChangeWatcher::CPolicyChangeWatcher(RUpsSession &aUpsSession)
295 : CActive(CActive::EPriorityStandard+1),
296 iUpsSession(aUpsSession)
298 CActiveScheduler::Add(this);
301 void CPolicyChangeWatcher::ConstructL()
303 User::LeaveIfError(iUpsPolicyChangeProperty.Attach(KUpsServerUid, KUpsServiceConfigProperty, EOwnerThread));
304 iUpsPolicyChangeProperty.Subscribe(iStatus);
308 CPolicyChangeWatcher::~CPolicyChangeWatcher()
311 iUpsPolicyChangeProperty.Close();
314 void CPolicyChangeWatcher::DoCancel()
316 iUpsPolicyChangeProperty.Cancel();
319 void CPolicyChangeWatcher::RunL()
321 // Re-subscribe for policy file change notifications
322 iUpsPolicyChangeProperty.Subscribe(iStatus);
325 // Tell session to update its cache.
326 iUpsSession.NotifyPolicyFileChangedL();
329 TInt CPolicyChangeWatcher::RunError(TInt /* aError */)
332 //RDebug::Printf("CPolicyChangeWatcher::RunError(%d)\n", aError);
337 } // End of namespace UserPromptService