realtimenetprots/sipfw/SIP/SIPSec/DigestPlugin/inc/sipsecdigestcache.h
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     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