diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/SIPSec/DigestPlugin/inc/sipsecdigestcache.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/SIPSec/DigestPlugin/inc/sipsecdigestcache.h Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,500 @@ +/* +* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Name : sipsecdigestcache.h +* Part of : SIPSec +* Version : SIP/6.0 +* +*/ + + + + +/** + @internalComponent +*/ + +#ifndef __SIPSEC_DIGESTCACHE_H__ +#define __SIPSEC_DIGESTCACHE_H__ + +// INCLUDES +#include "CSIPSecDigestCacheEntry.h" +#include + +// FORWARD DECLARATIONS +class CSIPMessage; +class CSIPResponse; +class CSIPRequest; +class CSIPAuthHeaderBase; +class MSIPSecSecurityMechanismObserver; +class CSIPSecDigestObserver; +class MTimerManager; +class TSIPSecPluginContext; +class CSIPSecUserRecord; + + +// CLASS DECLARATION +/** + * @brief Class is cache entry iterator + * + * @class TSIPSecDigestCacheEntryIterator sipsecdigestcache.h + * "sipsecdigestcache.h" + */ +class TSIPSecDigestCacheEntryIterator : + public TSglQueIter + { +public: + + /** + * Constructor + * @param aList The list to iterate + */ + TSIPSecDigestCacheEntryIterator( + TSglQue< CSIPSecDigestCacheEntry >& aList ); + + /** + * Returns next matching entry for the matching context + * @param aContext a context + * @return next matching entry or NULL + */ + CSIPSecDigestCacheEntry* Next( TSIPSecPluginContext& aContext ); + + /** + * Returns next matching entry regardless of context + * @return next matching entry or NULL + */ + CSIPSecDigestCacheEntry* Next(); + +public: // Data + + static const TInt iSIPSecOffset; + + TSglQueLink iLink; + }; + + + + +/** + * @brief Class is cache iterator + * + * @class TSIPSecDigestCacheIterator sipsecdigestcache.h "sipsecdigestcache.h" + * + */ +class TSIPSecDigestCacheIterator + { +public: + + /** + * Constructor + */ + TSIPSecDigestCacheIterator(); + + /** + * Constructor + * @param aContext the context + */ + TSIPSecDigestCacheIterator( TSIPSecPluginContext& aContext ); + + /** + * Returns next matching entry + * @return Next matching entry or NULL + */ + CSIPSecDigestCacheEntry* Next(); + +public: // Data + + // Queue + TSglQue iList; + + TSglQueIter iListIterator; + + // Not owned + TSIPSecPluginContext* iContext; + }; + + + +/** + * @brief Class represents cache for credentials + * + * @class CSIPSecDigestCache sipsecdigestcache.h "sipsecdigestcache.h" + * + * Class provides caching (adding, removing and seraching) of + * - credentials, searced based on request context + * - user credentials, searched based on realm + * Class also holds array of SIPSec observers + * + * + * Cache can have many CSIPSecUserRecords with a same realm, if MSIPSecUser + * differs. + * + * For one MSIPSecUser, cache can have one CSIPSecUserRecord per realm. + * Further challenges with the same MSIPSecUser and realm use the same record. + * + * For one transaction id, cache can have many CSIPSecUserRecords if the realms + * differ (SIP response had challenges with different realms). + * This does not apply to a case when the transaction id is empty. + */ +class CSIPSecDigestCache : public CBase + { +public: // Constructors and destructor + + /** + * Constructs an object; leaves on failure. + * @param aTimerManager Timer Manager + * @return new instance + */ + static CSIPSecDigestCache* NewL( MTimerManager& aTimerManager ); + + /** + * Constructs an object and adds the pointer to the cleanup stack; + * leaves on failure. + * @param aTimerManager Timer Manager + * @return new instance + */ + static CSIPSecDigestCache* NewLC( MTimerManager& aTimerManager ); + + /** + * Destructor + */ + ~CSIPSecDigestCache(); + +public: // New functions + + /** + * Creates cache iterator + * + * @param aContext the context + * @return iterator + */ + void InitializeIterator( TSIPSecDigestCacheIterator& aIterator ); + + /** + * Adds an CSIPSecDigestCacheEntry object into the cache. + * @pre aCacheEntry != NULL + * @pre aCacheEntry is not yet stored in the cache + * @param aCacheEntry an cache entry. Ownership is transferred. + */ + void AddEntry( CSIPSecDigestCacheEntry* aCacheEntry ); + + /** + * Removes the entry from the cache and deletes the entry. + * @pre aCacheEntry is in the cache + * @param aCacheEntry Cache entry + */ + void RemoveEntry( CSIPSecDigestCacheEntry& aCacheEntry ); + + /** + * Checks if the specified entry is in the cache. + * @param aCacheEntry Cache entry + * @return ETrue if entry is in the cache, EFalse if not. + */ + TBool IsEntryInCache( CSIPSecDigestCacheEntry& aCacheEntry ); + + /** + * Adds an CSIPSecUserRecord object into the cache. + * @pre aCredentials != NULL + * @param aCredentials user credentials + * The ownership is transferred. + */ + void AddUserCredentials( CSIPSecUserRecord* aCredentials ); + + /** + * Search for an user record with a matching realm and is related to the + * specified SIPSec user (or its trusted user). + * @pre aRealm.Length() > 0 + * @param aRealm realm + * @param aUser SIPSec user + * @param aRegistrationId Registration id + * @return CSIPSecUserRecord Found record or NULL if there is no match. + * The ownership is not transferred. + */ + CSIPSecUserRecord* + SearchRecordForResponse( const TDesC8& aRealm, + const MSIPSecUser& aUser, + TRegistrationId aRegistrationId ); + + /** + * Search for an user record with a matching realm and transaction id. + * @pre aRealm.Length() > 0 + * @param aRealm realm + * @param aTransactionId Transaction id, can be empty. + * @return CSIPSecUserRecord Found record or NULL if there is no match. + * The ownership is not transferred. + */ + CSIPSecUserRecord* SearchRecord( const TDesC8& aRealm, + TTransactionId aTransactionId ); + + /** + * Search for an user record with a matching realm and SIPSec user. + * @pre aRealm.Length() > 0 + * @param aRealm realm + * @param aUser SIPSec user that is setting the credentials + * @return CSIPSecUserRecord Found record or NULL if there is no match. + * The ownership is not transferred. + */ + CSIPSecUserRecord* SearchRecord( const TDesC8& aRealm, + const MSIPSecUser& aUser ); + + /** + * Clears all cache entries belonging to a user + * @param aUser SIPSec user + */ + void ClearCache( const MSIPSecUser& aUser ); + + /** + * Clears all cache entries belonging to realm (credentials). + * @param aCredentials User credentials + * @param aAKAOnly If ETrue, only AKA cache entries are cleared + * If EFalse, all cache entries are cleared + */ + void ClearCache( CSIPSecUserRecord& aCredentials, TBool aAKAOnly ); + + /** + * Clears all AKA cache entries that have a different realm than aRealm. + * @param aRealm Realm + */ + void ClearAKAEntriesWithOldRealm( const TDesC8& aRealm ); + + /** + * Registers mechanism observer and returns matching digest observer + * @param aObserver Mechanism observer + * @param aUserData User record for which the observer is for + * @return Digest observer, ownership is not transferred. + */ + CSIPSecDigestObserver* + RegisterObserverL( MSIPSecSecurityMechanismObserver& aObserver, + CSIPSecUserRecord& aUserData ); + + /** + * Removes observers, which do not have pending operations. + */ + void CleanObservers(); + + /** + * Cancels pending operations requested by SIP + * @param aObserver observer + */ + void CancelPendingOperations( MSIPSecSecurityMechanismObserver* aObserver ); + + /** + * Removes an entry from the cache, or cancels pending operations. + * @param aTransactionId Transaction id of the targeted cache entry, can be + * empty. + * @param aRealm Realm of the targeted cache entry + * @param aRemove ETrue if the entry is to be removed + * EFalse if the pending operations related to the cache + * entry will be canceled + * @return KErrNone if successful, otherwise a system-wide error code + */ + TInt Cancel( TTransactionId aTransactionId, + const TDesC8& aRealm, + const MSIPSecUser* aTrustedUser ); + + /** + * Removes all cache entries for the realm + * @param aRealm Realm of the targeted cache entry + * @return KErrNone if successful, otherwise a system-wide error code + */ + TInt Remove( const TDesC8& aRealm ); + + /* + * Checks if too many successive 401 responses are received with the same + * realm. This affects only IMS. + * @param aResponse SIP response + * @param aRequest SIP request + * @param aTransactionId Transaction id + * @param aDefaultAlgorithm Default algorithm + * @return KErrSIPForbidden Too many successive 401 responses received + * KErrNone otherwise + */ + TInt CountResponses( CSIPResponse& aResponse, + CSIPRequest& aRequest, + TTransactionId aTransactionId, + RStringF aDefaultAlgorithm ); + + /** + * Return timer services interface + */ + inline MTimerManager& Timer() + { + return iTimerManager; + } + +private: // New functions, for internal use + + /** + * Constructor + * @param aTimerManager Timer Manager + */ + CSIPSecDigestCache( MTimerManager& aTimerManager ); + + /** + * Returns the cache that is associated with aCacheEntry. + * @param aCacheEntry Cache enty + * @return Cache to use with aCacheEntry + */ + TSglQue< CSIPSecDigestCacheEntry >& + SelectCache( const CSIPSecDigestCacheEntry& aCacheEntry ); + + /** + * Removes all entries + */ + void RemoveAllEntries(); + + /** + * Removes all entries from aList. + */ + void RemoveAllEntriesFromList( TSglQue& aList ); + + /** + * Removes all credentials + */ + void RemoveAllCredentials(); + + /** + * Checks if the specified credentials are in the list. + * @param aCredentials Credentials + * @return ETrue if credentials are in the list, + * EFalse otherwise + */ + TBool IsCredentialsInList( const CSIPSecUserRecord& aCredentials ); + + /** + * Clears all entries from the specified cache belonging to the given user. + * @param aList Cache list + * @param aUser SIPSec user + */ + void RemoveUsedEntry( TSglQue& aList, + const MSIPSecUser& aUser ); + + /** + * If aList contains aCredentials, the aCredentials and the cache entries + * referring to it are removed from aList and deleted. + * @param aList Queue of cache entries + * @param aCredentials Credentials + * @param aAKAOnly If ETrue, only AKA cache entries are cleared + * If EFalse, all cache entries are cleared + */ + void RemoveMatchingEntry( TSglQue& aList, + CSIPSecUserRecord& aCredentials, + TBool aAKAOnly ); + + /** + * Removes entry from cache and deletes it. If the associated + * CSIPSecUserRecord is no longer referred, it is also deleted. + * @param aEntry Cache entry + * @return ETrue if the associated CSIPSecUserRecord was also deleted, + * EFalse otherwise. + */ + TBool RemoveCacheEntry( CSIPSecDigestCacheEntry& aEntry, + const MSIPSecUser& aUser ); + + /* + * Search the challenges present in aResponse, and check if they match the + * cache entry. + * @param aResponse SIP response + * @param aAlgorithm Algorithm from Security-Server header or empty. + * @param aDefaultAlgorithm Default algorithm + * @param aRealm Realm in the cache + * @param aMatch OUT: Set to ETrue if a challenge matches the cache entry. + * @return ETrue if the SIP response had at least one challenge + */ + TBool HandleChallenges( CSIPResponse& aResponse, + RStringF aAlgorithm, + RStringF aDefaultAlgorithm, + const TDesC8& aRealm, + TBool& aMatch ) const; + + /* + * Check if an authorization-header in aRequest matches a cache entry. + * @param aRequest SIP request + * @param aAlgorithm Algorithm from Security-Server header or empty + * @param aDefaultAlgorithm Default algorithm + * @param aRealm Realm in the cache entry + * @return ETrue If a header matched the cache entry. + */ + TBool HandleAuthorizations( CSIPRequest& aRequest, + RStringF aAlgorithm, + RStringF aDefaultAlgorithm, + const TDesC8& aRealm ) const; + + /* + * Check if the authenticate- or authorization-headers present in aMessage, + * match the cache entry. + * @param aMessage SIP message + * @param aAlgorithm Algorithm from Security-Server header or empty + * @param aDefaultAlgorithm Default algorithm + * @param aHeaderName Name of the headers to process. + * @param aRealm Realm in the cache entry + * @param aCheckChallenges ETrue if the challenges in authenticate must be + * checked that they are valid digest challenges. + * @param aChallengeFound ETrue if response had at least one challenge. + * @return ETrue If a header matched the cache entry. + */ + TBool HandleAuthHeaders( CSIPMessage& aMessage, + RStringF aAlgorithm, + RStringF aDefaultAlgorithm, + RStringF aHeaderName, + const TDesC8& aRealm, + TBool aCheckChallenges, + TBool& aChallengeFound ) const; + + TBool CompareAKARealm( CSIPAuthHeaderBase& aHeader, + const TDesC8& aCachedRealm, + RStringF aAlgorithm, + RStringF aDefaultAlgorithm ) const; + + /* + * When proxy- or endpoint cache entry is removed from the cache, checks + * if the MSIPSecUser of the CSIPSecUserRecord that was pointed by the + * removed cache entry, needs to be changed. + * @param + */ + void ChangeRecordUserIfNeeded( CSIPSecUserRecord& record, + const MSIPSecUser& aUser ); + +private: // Data + + // Proxy cache entries, owned. + TSglQue< CSIPSecDigestCacheEntry > iProxyList; + // Proxy cache iterator + TSIPSecDigestCacheEntryIterator iProxyListIter; + + // Endpoint cache entries, owned. + TSglQue< CSIPSecDigestCacheEntry > iEndpointList; + // Endpoint cache iterator + TSIPSecDigestCacheEntryIterator iEndpointListIter; + + // Credentials list, owned. + TSglQue< CSIPSecUserRecord > iCredentialsList; + // Credentials list iterator + TSglQueIter< CSIPSecUserRecord > iCredentialsListIter; + + // Requests, owned. + RPointerArray< CSIPSecDigestObserver > iDigestObservers; + + // Timer services + MTimerManager& iTimerManager; + +#ifdef CPPUNIT_TEST + friend class CSIPSecDigestTest; + friend class CSIPSecDigestCacheTest; +#endif + }; + +#endif // __SIPSEC_DIGESTCACHE_H__ + +// End of File