First public contribution.
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\cbase\ub_polsvr.cpp
20 _LIT(KPolicyServer, "CPolicyServer");
23 #define __PSD(x) __PLATSEC_DIAGNOSTIC_STRING(x)
25 EXPORT_C CPolicyServer::CPolicyServer(TInt aPriority, const TPolicy& aPolicy, TServerType aType)
26 : CServer2(aPriority, aType), iPolicy(aPolicy)
30 TInt prev = iPolicy.iRanges[0];
31 //iPolicy.iRangeCount must be greater than 0. (ie you must have at least
33 __ASSERT_DEBUG(iPolicy.iRangeCount > 0, Panic(EPolSvrIRangeCountInvalid));
34 //iRanges must start from request number 0.
35 __ASSERT_DEBUG(prev == 0, Panic(EPolSvr1stRangeNotZero));
36 __ASSERT_DEBUG((iPolicy.iElementsIndex[0] < ESpecialCaseHardLimit
37 || iPolicy.iElementsIndex[0] > ESpecialCaseLimit),
38 Panic(EPolSvrElementsIndexValueInvalid) );
39 for(i=1; i<iPolicy.iRangeCount; i++)
41 TInt next = iPolicy.iRanges[i];
42 //iRanges must be in increasing order.
43 __ASSERT_DEBUG(next > prev, Panic(EPolSvrRangesNotIncreasing));
44 //iElementsIndex must not contain invalid values.
45 __ASSERT_DEBUG((iPolicy.iElementsIndex[i] < ESpecialCaseHardLimit
46 || iPolicy.iElementsIndex[i] > ESpecialCaseLimit),
47 Panic(EPolSvrElementsIndexValueInvalid) );
50 //iOnConnect must not be an invalid value.
51 __ASSERT_DEBUG((iPolicy.iOnConnect < ESpecialCaseHardLimit
52 || iPolicy.iOnConnect > ESpecialCaseLimit),
53 Panic(EPolSvrIOnConnectValueInvalid) );
57 EXPORT_C void CPolicyServer::RunL()
59 const RMessage2& msg = Message();
60 msg.ClearAuthorised();
61 TInt fn = msg.Function();
63 __ASSERT_COMPILE(-1 == RMessage2::EConnect);
64 if(fn >= RMessage2::EConnect)
65 //So this implies any "normal" message or Connect
66 //Now we have two steps to follow each having two mutually exculsive
68 //Step 1: Find policy.
69 //Step 2: Apply policy.
71 const TPolicyElement* element = 0;
72 TUint specialCase = 0;
73 //1a: If its a normal message. Find the associate policy or special
77 element = FindPolicyElement(fn, specialCase);
79 //1b: If its a connect message, there's a shortcut to the policy.
82 TUint8 i = iPolicy.iOnConnect;
83 if(i >= ESpecialCaseHardLimit)
86 element = &(iPolicy.iElements[i]);
88 //2a: We found a policy that we can automatically apply... Apply it!
91 TSecurityInfo missing;
92 //If policy check succeeds, allow it through
93 if(element->iPolicy.CheckPolicy(msg, missing, __PSD("Checked by CPolicyServer::RunL")))
97 //Else see what failure action is required (return error code,
98 //panic client, ask user, etc...)
101 CheckFailedL(msg, element->iAction, missing);
104 //2b: The policy is a special case
109 //If you change this you'll have to add to the switch statement
110 __ASSERT_COMPILE(ESpecialCaseLimit == 252u);
113 TInt action = EFailClient;
114 //The default action after failing a CustomSecurityCheck is
115 //to complete the message with KErrPermissionDenied. If
116 //you want a different action, then change the action
117 //parameter prior to returning from your derived
118 //implementation of CustomSecurityCheckL
119 TSecurityInfo missing;
120 __ASSERT_COMPILE(SCapabilitySet::ENCapW == 2);
121 memset(&missing, 0, sizeof(SSecurityInfo));
122 TCustomResult result = CustomSecurityCheckL(msg, action, missing);
127 else if(result == EFail)
129 CheckFailedL(msg, action, missing);
131 else if(result == EAsync)
133 //Do Nothing. Derived CustomSecurityCheck is
134 //responsible for calling ProcessL/CheckFailedL
137 Panic(EPolSvrInvalidCustomResult);
141 msg.Complete(KErrNotSupported);
147 Panic(EPolSvrPolicyInvalid);
152 //else it must be either Disconnect or bad message. Both are handled by
159 // Queue reception of next message if it hasn't already been done
164 EXPORT_C TInt CPolicyServer::RunError(TInt aError)
166 ProcessError(Message(), aError);
172 EXPORT_C void CPolicyServer::ProcessL(const RMessage2& aMsg)
174 aMsg.SetAuthorised();
175 TInt fn = aMsg.Function();
179 CSession2* session=aMsg.Session();
182 session->ServiceL(aMsg);
189 else if(fn==RMessage2::EConnect)
193 else if(fn==RMessage2::EDisConnect)
203 EXPORT_C void CPolicyServer::ProcessError(const RMessage2& aMsg, TInt aError)
205 __ASSERT_COMPILE(-1 == RMessage2::EConnect);
206 __ASSERT_ALWAYS(aMsg.Function() >= RMessage2::EConnect, User::Panic(KPolicyServer, 2));
207 if(aMsg.Authorised() && aMsg.Function() >= 0)
209 aMsg.Session()->ServiceError(aMsg, aError);
211 else //Either ServiceL hadn't been called yet (not (yet) authorised) or
212 //it's a Connect message
214 aMsg.Complete(aError);
218 EXPORT_C CPolicyServer::TCustomResult CPolicyServer::CustomSecurityCheckL(const RMessage2& /*aMsg*/, TInt& /*aAction*/, TSecurityInfo& /*aMissing*/)
220 Panic(EPolSvrCallingBaseImplementation);
224 EXPORT_C void CPolicyServer::CheckFailedL(const RMessage2& aMsg, TInt aAction, const TSecurityInfo& aMissing)
228 TCustomResult result = CustomFailureActionL(aMsg, aAction, aMissing);
231 else if(result == EFail)
232 aMsg.Complete(KErrPermissionDenied);
233 else if(result == EAsync)
235 //Do Nothing. Derived CustomFailureActionL is responsible for
236 //calling ProcessL/completing message with KErrPermissionDenied
238 Panic(EPolSvrInvalidCustomResult);
240 else if(aAction == EFailClient)
242 aMsg.Complete(KErrPermissionDenied);
244 else //if (aAction == EPanic) and all other +ve values
246 _LIT(KE32UserCBase, "E32USER-CBase");
247 aMsg.Panic(KE32UserCBase, EPolSvrActionPanicClient);
251 EXPORT_C CPolicyServer::TCustomResult CPolicyServer::CustomFailureActionL(const RMessage2& /*aMsg*/, TInt /*aAction*/, const TSecurityInfo& /*aMissing*/)
253 Panic(EPolSvrCallingBaseImplementation);
257 const CPolicyServer::TPolicyElement* CPolicyServer::FindPolicyElement(TInt aFn, TUint& aSpecialCase) const
259 //Connect (aFn == -1) is handled through iPolicy.iOnConnect. So aFn should
260 //always be greater than -1.
261 __ASSERT_DEBUG(aFn >= 0, User::Panic(KPolicyServer, 1));
264 TUint u = iPolicy.iRangeCount;
269 if(iPolicy.iRanges[m] > aFn)
275 //the mth element of iElementsIndex tells us the index in iElements
277 TUint8 i = iPolicy.iElementsIndex[l];
278 //if the mth element of iElementsIndex is >= 250 -> Special Case
279 if(i >= ESpecialCaseHardLimit)
284 return &(iPolicy.iElements[i]);
295 EXPORT_C TInt CPolicyServer::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
297 return CServer2::Extension_(aExtensionId, a0, a1);