|
1 /* |
|
2 * Copyright (c) 2008-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 "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 * Name : sipsecdigestcache.h |
|
16 * Part of : SIPSec |
|
17 * Version : SIP/6.0 |
|
18 * |
|
19 */ |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 /** |
|
25 @internalComponent |
|
26 */ |
|
27 |
|
28 #ifndef __SIPSEC_DIGESTCACHE_H__ |
|
29 #define __SIPSEC_DIGESTCACHE_H__ |
|
30 |
|
31 // INCLUDES |
|
32 #include "CSIPSecDigestCacheEntry.h" |
|
33 #include <e32base.h> |
|
34 |
|
35 // FORWARD DECLARATIONS |
|
36 class CSIPMessage; |
|
37 class CSIPResponse; |
|
38 class CSIPRequest; |
|
39 class CSIPAuthHeaderBase; |
|
40 class MSIPSecSecurityMechanismObserver; |
|
41 class CSIPSecDigestObserver; |
|
42 class MTimerManager; |
|
43 class TSIPSecPluginContext; |
|
44 class CSIPSecUserRecord; |
|
45 |
|
46 |
|
47 // CLASS DECLARATION |
|
48 /** |
|
49 * @brief Class is cache entry iterator |
|
50 * |
|
51 * @class TSIPSecDigestCacheEntryIterator sipsecdigestcache.h |
|
52 * "sipsecdigestcache.h" |
|
53 */ |
|
54 class TSIPSecDigestCacheEntryIterator : |
|
55 public TSglQueIter<CSIPSecDigestCacheEntry> |
|
56 { |
|
57 public: |
|
58 |
|
59 /** |
|
60 * Constructor |
|
61 * @param aList The list to iterate |
|
62 */ |
|
63 TSIPSecDigestCacheEntryIterator( |
|
64 TSglQue< CSIPSecDigestCacheEntry >& aList ); |
|
65 |
|
66 /** |
|
67 * Returns next matching entry for the matching context |
|
68 * @param aContext a context |
|
69 * @return next matching entry or NULL |
|
70 */ |
|
71 CSIPSecDigestCacheEntry* Next( TSIPSecPluginContext& aContext ); |
|
72 |
|
73 /** |
|
74 * Returns next matching entry regardless of context |
|
75 * @return next matching entry or NULL |
|
76 */ |
|
77 CSIPSecDigestCacheEntry* Next(); |
|
78 |
|
79 public: // Data |
|
80 |
|
81 static const TInt iSIPSecOffset; |
|
82 |
|
83 TSglQueLink iLink; |
|
84 }; |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 /** |
|
90 * @brief Class is cache iterator |
|
91 * |
|
92 * @class TSIPSecDigestCacheIterator sipsecdigestcache.h "sipsecdigestcache.h" |
|
93 * |
|
94 */ |
|
95 class TSIPSecDigestCacheIterator |
|
96 { |
|
97 public: |
|
98 |
|
99 /** |
|
100 * Constructor |
|
101 */ |
|
102 TSIPSecDigestCacheIterator(); |
|
103 |
|
104 /** |
|
105 * Constructor |
|
106 * @param aContext the context |
|
107 */ |
|
108 TSIPSecDigestCacheIterator( TSIPSecPluginContext& aContext ); |
|
109 |
|
110 /** |
|
111 * Returns next matching entry |
|
112 * @return Next matching entry or NULL |
|
113 */ |
|
114 CSIPSecDigestCacheEntry* Next(); |
|
115 |
|
116 public: // Data |
|
117 |
|
118 // Queue |
|
119 TSglQue<TSIPSecDigestCacheEntryIterator> iList; |
|
120 |
|
121 TSglQueIter<TSIPSecDigestCacheEntryIterator> iListIterator; |
|
122 |
|
123 // Not owned |
|
124 TSIPSecPluginContext* iContext; |
|
125 }; |
|
126 |
|
127 |
|
128 |
|
129 /** |
|
130 * @brief Class represents cache for credentials |
|
131 * |
|
132 * @class CSIPSecDigestCache sipsecdigestcache.h "sipsecdigestcache.h" |
|
133 * |
|
134 * Class provides caching (adding, removing and seraching) of |
|
135 * - credentials, searced based on request context |
|
136 * - user credentials, searched based on realm |
|
137 * Class also holds array of SIPSec observers |
|
138 * |
|
139 * |
|
140 * Cache can have many CSIPSecUserRecords with a same realm, if MSIPSecUser |
|
141 * differs. |
|
142 * |
|
143 * For one MSIPSecUser, cache can have one CSIPSecUserRecord per realm. |
|
144 * Further challenges with the same MSIPSecUser and realm use the same record. |
|
145 * |
|
146 * For one transaction id, cache can have many CSIPSecUserRecords if the realms |
|
147 * differ (SIP response had challenges with different realms). |
|
148 * This does not apply to a case when the transaction id is empty. |
|
149 */ |
|
150 class CSIPSecDigestCache : public CBase |
|
151 { |
|
152 public: // Constructors and destructor |
|
153 |
|
154 /** |
|
155 * Constructs an object; leaves on failure. |
|
156 * @param aTimerManager Timer Manager |
|
157 * @return new instance |
|
158 */ |
|
159 static CSIPSecDigestCache* NewL( MTimerManager& aTimerManager ); |
|
160 |
|
161 /** |
|
162 * Constructs an object and adds the pointer to the cleanup stack; |
|
163 * leaves on failure. |
|
164 * @param aTimerManager Timer Manager |
|
165 * @return new instance |
|
166 */ |
|
167 static CSIPSecDigestCache* NewLC( MTimerManager& aTimerManager ); |
|
168 |
|
169 /** |
|
170 * Destructor |
|
171 */ |
|
172 ~CSIPSecDigestCache(); |
|
173 |
|
174 public: // New functions |
|
175 |
|
176 /** |
|
177 * Creates cache iterator |
|
178 * |
|
179 * @param aContext the context |
|
180 * @return iterator |
|
181 */ |
|
182 void InitializeIterator( TSIPSecDigestCacheIterator& aIterator ); |
|
183 |
|
184 /** |
|
185 * Adds an CSIPSecDigestCacheEntry object into the cache. |
|
186 * @pre aCacheEntry != NULL |
|
187 * @pre aCacheEntry is not yet stored in the cache |
|
188 * @param aCacheEntry an cache entry. Ownership is transferred. |
|
189 */ |
|
190 void AddEntry( CSIPSecDigestCacheEntry* aCacheEntry ); |
|
191 |
|
192 /** |
|
193 * Removes the entry from the cache and deletes the entry. |
|
194 * @pre aCacheEntry is in the cache |
|
195 * @param aCacheEntry Cache entry |
|
196 */ |
|
197 void RemoveEntry( CSIPSecDigestCacheEntry& aCacheEntry ); |
|
198 |
|
199 /** |
|
200 * Checks if the specified entry is in the cache. |
|
201 * @param aCacheEntry Cache entry |
|
202 * @return ETrue if entry is in the cache, EFalse if not. |
|
203 */ |
|
204 TBool IsEntryInCache( CSIPSecDigestCacheEntry& aCacheEntry ); |
|
205 |
|
206 /** |
|
207 * Adds an CSIPSecUserRecord object into the cache. |
|
208 * @pre aCredentials != NULL |
|
209 * @param aCredentials user credentials |
|
210 * The ownership is transferred. |
|
211 */ |
|
212 void AddUserCredentials( CSIPSecUserRecord* aCredentials ); |
|
213 |
|
214 /** |
|
215 * Search for an user record with a matching realm and is related to the |
|
216 * specified SIPSec user (or its trusted user). |
|
217 * @pre aRealm.Length() > 0 |
|
218 * @param aRealm realm |
|
219 * @param aUser SIPSec user |
|
220 * @param aRegistrationId Registration id |
|
221 * @return CSIPSecUserRecord Found record or NULL if there is no match. |
|
222 * The ownership is not transferred. |
|
223 */ |
|
224 CSIPSecUserRecord* |
|
225 SearchRecordForResponse( const TDesC8& aRealm, |
|
226 const MSIPSecUser& aUser, |
|
227 TRegistrationId aRegistrationId ); |
|
228 |
|
229 /** |
|
230 * Search for an user record with a matching realm and transaction id. |
|
231 * @pre aRealm.Length() > 0 |
|
232 * @param aRealm realm |
|
233 * @param aTransactionId Transaction id, can be empty. |
|
234 * @return CSIPSecUserRecord Found record or NULL if there is no match. |
|
235 * The ownership is not transferred. |
|
236 */ |
|
237 CSIPSecUserRecord* SearchRecord( const TDesC8& aRealm, |
|
238 TTransactionId aTransactionId ); |
|
239 |
|
240 /** |
|
241 * Search for an user record with a matching realm and SIPSec user. |
|
242 * @pre aRealm.Length() > 0 |
|
243 * @param aRealm realm |
|
244 * @param aUser SIPSec user that is setting the credentials |
|
245 * @return CSIPSecUserRecord Found record or NULL if there is no match. |
|
246 * The ownership is not transferred. |
|
247 */ |
|
248 CSIPSecUserRecord* SearchRecord( const TDesC8& aRealm, |
|
249 const MSIPSecUser& aUser ); |
|
250 |
|
251 /** |
|
252 * Clears all cache entries belonging to a user |
|
253 * @param aUser SIPSec user |
|
254 */ |
|
255 void ClearCache( const MSIPSecUser& aUser ); |
|
256 |
|
257 /** |
|
258 * Clears all cache entries belonging to realm (credentials). |
|
259 * @param aCredentials User credentials |
|
260 * @param aAKAOnly If ETrue, only AKA cache entries are cleared |
|
261 * If EFalse, all cache entries are cleared |
|
262 */ |
|
263 void ClearCache( CSIPSecUserRecord& aCredentials, TBool aAKAOnly ); |
|
264 |
|
265 /** |
|
266 * Clears all AKA cache entries that have a different realm than aRealm. |
|
267 * @param aRealm Realm |
|
268 */ |
|
269 void ClearAKAEntriesWithOldRealm( const TDesC8& aRealm ); |
|
270 |
|
271 /** |
|
272 * Registers mechanism observer and returns matching digest observer |
|
273 * @param aObserver Mechanism observer |
|
274 * @param aUserData User record for which the observer is for |
|
275 * @return Digest observer, ownership is not transferred. |
|
276 */ |
|
277 CSIPSecDigestObserver* |
|
278 RegisterObserverL( MSIPSecSecurityMechanismObserver& aObserver, |
|
279 CSIPSecUserRecord& aUserData ); |
|
280 |
|
281 /** |
|
282 * Removes observers, which do not have pending operations. |
|
283 */ |
|
284 void CleanObservers(); |
|
285 |
|
286 /** |
|
287 * Cancels pending operations requested by SIP |
|
288 * @param aObserver observer |
|
289 */ |
|
290 void CancelPendingOperations( MSIPSecSecurityMechanismObserver* aObserver ); |
|
291 |
|
292 /** |
|
293 * Removes an entry from the cache, or cancels pending operations. |
|
294 * @param aTransactionId Transaction id of the targeted cache entry, can be |
|
295 * empty. |
|
296 * @param aRealm Realm of the targeted cache entry |
|
297 * @param aRemove ETrue if the entry is to be removed |
|
298 * EFalse if the pending operations related to the cache |
|
299 * entry will be canceled |
|
300 * @return KErrNone if successful, otherwise a system-wide error code |
|
301 */ |
|
302 TInt Cancel( TTransactionId aTransactionId, |
|
303 const TDesC8& aRealm, |
|
304 const MSIPSecUser* aTrustedUser ); |
|
305 |
|
306 /** |
|
307 * Removes all cache entries for the realm |
|
308 * @param aRealm Realm of the targeted cache entry |
|
309 * @return KErrNone if successful, otherwise a system-wide error code |
|
310 */ |
|
311 TInt Remove( const TDesC8& aRealm ); |
|
312 |
|
313 /* |
|
314 * Checks if too many successive 401 responses are received with the same |
|
315 * realm. This affects only IMS. |
|
316 * @param aResponse SIP response |
|
317 * @param aRequest SIP request |
|
318 * @param aTransactionId Transaction id |
|
319 * @param aDefaultAlgorithm Default algorithm |
|
320 * @return KErrSIPForbidden Too many successive 401 responses received |
|
321 * KErrNone otherwise |
|
322 */ |
|
323 TInt CountResponses( CSIPResponse& aResponse, |
|
324 CSIPRequest& aRequest, |
|
325 TTransactionId aTransactionId, |
|
326 RStringF aDefaultAlgorithm ); |
|
327 |
|
328 /** |
|
329 * Return timer services interface |
|
330 */ |
|
331 inline MTimerManager& Timer() |
|
332 { |
|
333 return iTimerManager; |
|
334 } |
|
335 |
|
336 private: // New functions, for internal use |
|
337 |
|
338 /** |
|
339 * Constructor |
|
340 * @param aTimerManager Timer Manager |
|
341 */ |
|
342 CSIPSecDigestCache( MTimerManager& aTimerManager ); |
|
343 |
|
344 /** |
|
345 * Returns the cache that is associated with aCacheEntry. |
|
346 * @param aCacheEntry Cache enty |
|
347 * @return Cache to use with aCacheEntry |
|
348 */ |
|
349 TSglQue< CSIPSecDigestCacheEntry >& |
|
350 SelectCache( const CSIPSecDigestCacheEntry& aCacheEntry ); |
|
351 |
|
352 /** |
|
353 * Removes all entries |
|
354 */ |
|
355 void RemoveAllEntries(); |
|
356 |
|
357 /** |
|
358 * Removes all entries from aList. |
|
359 */ |
|
360 void RemoveAllEntriesFromList( TSglQue<CSIPSecDigestCacheEntry>& aList ); |
|
361 |
|
362 /** |
|
363 * Removes all credentials |
|
364 */ |
|
365 void RemoveAllCredentials(); |
|
366 |
|
367 /** |
|
368 * Checks if the specified credentials are in the list. |
|
369 * @param aCredentials Credentials |
|
370 * @return ETrue if credentials are in the list, |
|
371 * EFalse otherwise |
|
372 */ |
|
373 TBool IsCredentialsInList( const CSIPSecUserRecord& aCredentials ); |
|
374 |
|
375 /** |
|
376 * Clears all entries from the specified cache belonging to the given user. |
|
377 * @param aList Cache list |
|
378 * @param aUser SIPSec user |
|
379 */ |
|
380 void RemoveUsedEntry( TSglQue<CSIPSecDigestCacheEntry>& aList, |
|
381 const MSIPSecUser& aUser ); |
|
382 |
|
383 /** |
|
384 * If aList contains aCredentials, the aCredentials and the cache entries |
|
385 * referring to it are removed from aList and deleted. |
|
386 * @param aList Queue of cache entries |
|
387 * @param aCredentials Credentials |
|
388 * @param aAKAOnly If ETrue, only AKA cache entries are cleared |
|
389 * If EFalse, all cache entries are cleared |
|
390 */ |
|
391 void RemoveMatchingEntry( TSglQue<CSIPSecDigestCacheEntry>& aList, |
|
392 CSIPSecUserRecord& aCredentials, |
|
393 TBool aAKAOnly ); |
|
394 |
|
395 /** |
|
396 * Removes entry from cache and deletes it. If the associated |
|
397 * CSIPSecUserRecord is no longer referred, it is also deleted. |
|
398 * @param aEntry Cache entry |
|
399 * @return ETrue if the associated CSIPSecUserRecord was also deleted, |
|
400 * EFalse otherwise. |
|
401 */ |
|
402 TBool RemoveCacheEntry( CSIPSecDigestCacheEntry& aEntry, |
|
403 const MSIPSecUser& aUser ); |
|
404 |
|
405 /* |
|
406 * Search the challenges present in aResponse, and check if they match the |
|
407 * cache entry. |
|
408 * @param aResponse SIP response |
|
409 * @param aAlgorithm Algorithm from Security-Server header or empty. |
|
410 * @param aDefaultAlgorithm Default algorithm |
|
411 * @param aRealm Realm in the cache |
|
412 * @param aMatch OUT: Set to ETrue if a challenge matches the cache entry. |
|
413 * @return ETrue if the SIP response had at least one challenge |
|
414 */ |
|
415 TBool HandleChallenges( CSIPResponse& aResponse, |
|
416 RStringF aAlgorithm, |
|
417 RStringF aDefaultAlgorithm, |
|
418 const TDesC8& aRealm, |
|
419 TBool& aMatch ) const; |
|
420 |
|
421 /* |
|
422 * Check if an authorization-header in aRequest matches a cache entry. |
|
423 * @param aRequest SIP request |
|
424 * @param aAlgorithm Algorithm from Security-Server header or empty |
|
425 * @param aDefaultAlgorithm Default algorithm |
|
426 * @param aRealm Realm in the cache entry |
|
427 * @return ETrue If a header matched the cache entry. |
|
428 */ |
|
429 TBool HandleAuthorizations( CSIPRequest& aRequest, |
|
430 RStringF aAlgorithm, |
|
431 RStringF aDefaultAlgorithm, |
|
432 const TDesC8& aRealm ) const; |
|
433 |
|
434 /* |
|
435 * Check if the authenticate- or authorization-headers present in aMessage, |
|
436 * match the cache entry. |
|
437 * @param aMessage SIP message |
|
438 * @param aAlgorithm Algorithm from Security-Server header or empty |
|
439 * @param aDefaultAlgorithm Default algorithm |
|
440 * @param aHeaderName Name of the headers to process. |
|
441 * @param aRealm Realm in the cache entry |
|
442 * @param aCheckChallenges ETrue if the challenges in authenticate must be |
|
443 * checked that they are valid digest challenges. |
|
444 * @param aChallengeFound ETrue if response had at least one challenge. |
|
445 * @return ETrue If a header matched the cache entry. |
|
446 */ |
|
447 TBool HandleAuthHeaders( CSIPMessage& aMessage, |
|
448 RStringF aAlgorithm, |
|
449 RStringF aDefaultAlgorithm, |
|
450 RStringF aHeaderName, |
|
451 const TDesC8& aRealm, |
|
452 TBool aCheckChallenges, |
|
453 TBool& aChallengeFound ) const; |
|
454 |
|
455 TBool CompareAKARealm( CSIPAuthHeaderBase& aHeader, |
|
456 const TDesC8& aCachedRealm, |
|
457 RStringF aAlgorithm, |
|
458 RStringF aDefaultAlgorithm ) const; |
|
459 |
|
460 /* |
|
461 * When proxy- or endpoint cache entry is removed from the cache, checks |
|
462 * if the MSIPSecUser of the CSIPSecUserRecord that was pointed by the |
|
463 * removed cache entry, needs to be changed. |
|
464 * @param |
|
465 */ |
|
466 void ChangeRecordUserIfNeeded( CSIPSecUserRecord& record, |
|
467 const MSIPSecUser& aUser ); |
|
468 |
|
469 private: // Data |
|
470 |
|
471 // Proxy cache entries, owned. |
|
472 TSglQue< CSIPSecDigestCacheEntry > iProxyList; |
|
473 // Proxy cache iterator |
|
474 TSIPSecDigestCacheEntryIterator iProxyListIter; |
|
475 |
|
476 // Endpoint cache entries, owned. |
|
477 TSglQue< CSIPSecDigestCacheEntry > iEndpointList; |
|
478 // Endpoint cache iterator |
|
479 TSIPSecDigestCacheEntryIterator iEndpointListIter; |
|
480 |
|
481 // Credentials list, owned. |
|
482 TSglQue< CSIPSecUserRecord > iCredentialsList; |
|
483 // Credentials list iterator |
|
484 TSglQueIter< CSIPSecUserRecord > iCredentialsListIter; |
|
485 |
|
486 // Requests, owned. |
|
487 RPointerArray< CSIPSecDigestObserver > iDigestObservers; |
|
488 |
|
489 // Timer services |
|
490 MTimerManager& iTimerManager; |
|
491 |
|
492 #ifdef CPPUNIT_TEST |
|
493 friend class CSIPSecDigestTest; |
|
494 friend class CSIPSecDigestCacheTest; |
|
495 #endif |
|
496 }; |
|
497 |
|
498 #endif // __SIPSEC_DIGESTCACHE_H__ |
|
499 |
|
500 // End of File |