gba/gbafilter/src/HTTPFilterGBA.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
child 14 b75757c81051
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2007 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:  Implementation of CHTTPFilterGBA
       
    15 *
       
    16 */
       
    17 
       
    18 #include <http/rhttptransaction.h>
       
    19 #include <http/rhttpheaders.h>
       
    20 #include <http/rhttpresponse.h>
       
    21 #include <httperr.h>
       
    22 #include <httpstringconstants.h>
       
    23 #include <imcvcodc.h>      //for base64 en/decoding
       
    24 #include "HTTPFilterGBA.h"
       
    25 #include "GbaCommon.h"
       
    26 #include <bautils.h>
       
    27 #include <e32math.h>
       
    28 #include <hash.h>
       
    29 #include <e32const.h>
       
    30 #include "GBALogger.h"
       
    31 
       
    32 //Constants
       
    33 const TInt KStatusTextLength512 = 512;
       
    34 const TInt KB64KeySize = 64;
       
    35 const TInt KIntegerConstant8 = 8;
       
    36 const TInt KIntegerConstant32 = 32;
       
    37 const TInt KIntegerConstant33 = 33;
       
    38 // Length of a digest hash when represented in hex
       
    39 const TInt KHashLength = 32;
       
    40 // Length of a digest hash before converting to hex.
       
    41 const TInt KRawHashLength = 16;
       
    42 // Length of nonce-count
       
    43 const TInt KNonceCountLength = 8;
       
    44 
       
    45 _LIT8( KUserAgentProductToken,"3gpp-gba");
       
    46 _LIT8(K3GPPRealmString,"3GPP-Bootstrapping@");
       
    47 _LIT8( KMd5AlgorithmStr, "MD5" );
       
    48 _LIT8( KMd5SessAlgorithmStr, "MD5-sess" );
       
    49 _LIT8( KQopAuthStr, "auth" );
       
    50 _LIT8( KQopAuthIntStr, "auth-int" );
       
    51 _LIT8( KAuthenticationInfoStr, "Authentication-Info" );
       
    52 _LIT8( KColon, ":" );
       
    53 _LIT8( KDefaultProtocolAlg, "\x01\x00\x00\x00\x02");
       
    54 _LIT(KGBAHttpFilter, "HTTP FILTER GBA");
       
    55 
       
    56 // format for output of data/time values
       
    57 #if defined (_DEBUG) && defined (_LOGGING)
       
    58 _LIT(KDateFormat,"%D%M%Y%/0%1%/1%2%/2%3%/3 %:0%H%:1%T%:2%S.%C%:3");
       
    59 #endif
       
    60 
       
    61 void PanicGBAHttpFilters(TInt aErr = 0)
       
    62 {
       
    63     User::Panic(KGBAHttpFilter, aErr);
       
    64 }
       
    65 
       
    66 // ============================ MEMBER FUNCTIONS ===============================
       
    67 
       
    68 // -----------------------------------------------------------------------------
       
    69 // CHTTPFilterGBA::CHTTPFilterGBA
       
    70 // Constructor
       
    71 // -----------------------------------------------------------------------------
       
    72 //
       
    73 CHTTPFilterGBA::CHTTPFilterGBA()
       
    74 		: iBootstrapCount(0),iHaveGbaBootstrapCredentials(EFalse)
       
    75 {
       
    76 
       
    77 }
       
    78 
       
    79 // -----------------------------------------------------------------------------
       
    80 // CHTTPFilterGBA::InstallFilterL
       
    81 // Initialize the filter and register it to sesssion's filter collection
       
    82 // -----------------------------------------------------------------------------
       
    83 //
       
    84 CEComFilter* CHTTPFilterGBA::InstallFilterL(TAny* aParams)
       
    85 {
       
    86 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::CHTTPFilterGBA++"));
       
    87 	__ASSERT_DEBUG(aParams != NULL, PanicGBAHttpFilters());
       
    88 	RHTTPSession* session = REINTERPRET_CAST(RHTTPSession*, aParams);
       
    89 	CHTTPFilterGBA* filter = new (ELeave) CHTTPFilterGBA();
       
    90 	CleanupStack::PushL(filter);
       
    91 	filter->ConstructL(*session);
       
    92 	CleanupStack::Pop(filter);
       
    93 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::CHTTPFilterGBA--"));
       
    94 	return filter;
       
    95 }
       
    96 	
       
    97 // -----------------------------------------------------------------------------
       
    98 // CHTTPFilterGBA::ConstructL
       
    99 // Memory and resource allocation, leaves
       
   100 // -----------------------------------------------------------------------------
       
   101 //
       
   102 void CHTTPFilterGBA::ConstructL(RHTTPSession aSession)
       
   103 {
       
   104     GBA_TRACE_DEBUG(("CHTTPFilterGBA::ConstructL++"));
       
   105 	
       
   106 	//......................................................................................
       
   107 	
       
   108 	//Unload GBA http filter from existing GBA and MBMS server's
       
   109 	
       
   110 	
       
   111 	//This GBA http filter cannot be loaded from old GBA server (GBAServer) and it's 
       
   112 	//Required to reject a filter loading request from a GBA server  on existing platforms
       
   113 	//where GBA component is already built-in and the GBA server UID3 is 0x2000F868
       
   114 	//Note- some s60 3.2 and 5.0 platforms already has GBA component as built in.
       
   115 	//Reason: Ub interface should not have the User-Agent string "3gpp-gba"
       
   116     if( RProcess().SecureId() == TSecureId (0x2000F868))
       
   117     {
       
   118     	GBA_TRACE_DEBUG(("Not accessible from GBA Server++"));
       
   119         return;
       
   120     }
       
   121     
       
   122     //This GBA http filter cannot be loaded from MBMS server (MBMSServer) and it's 
       
   123     //Required to reject a filter loading request from a MBMS server
       
   124     //where MBMS component is already build-in[N96 platforms only] and the mbms server UID3 is 0x2001957B
       
   125     //Reason: Ub interface should not have the User-Agent string "3gpp-gba"
       
   126     if( RProcess().SecureId() == TSecureId (0x2001957B))
       
   127     {
       
   128         GBA_TRACE_DEBUG(("Not accessible from MBMS Server++"));
       
   129         return;
       
   130     } 
       
   131     //......................................................................................
       
   132        
       
   133    	iProtocolIdentifier.Copy(KDefaultProtocolAlg);
       
   134 
       
   135 	iUICCLabel = KUSIM;
       
   136 	iStringPool = aSession.StringPool();
       
   137 
       
   138 	// register the filter
       
   139 	RStringF filterName = iStringPool.OpenFStringL( KHTTPFilterGBAName );
       
   140 	CleanupClosePushL( filterName );
       
   141 
       
   142     iOpaqueStr = iStringPool.StringF( HTTP::EOpaque, RHTTPSession::GetTable() );
       
   143     iNonceStr = iStringPool.StringF( HTTP::ENonce, RHTTPSession::GetTable() );
       
   144     iQopStr = iStringPool.StringF( HTTP::EQop, RHTTPSession::GetTable() );
       
   145     iStaleStr = iStringPool.StringF( HTTP::EStale, RHTTPSession::GetTable() );
       
   146     
       
   147     iMd5Str = iStringPool.OpenFStringL( KMd5AlgorithmStr );
       
   148     iMd5SessStr = iStringPool.OpenFStringL( KMd5SessAlgorithmStr );
       
   149     iQopAuthStr = iStringPool.OpenFStringL( KQopAuthStr );
       
   150     iAuthInfo = iStringPool.OpenFStringL( KAuthenticationInfoStr );
       
   151     
       
   152     iRealmStr = iStringPool.StringF( HTTP::ERealm, RHTTPSession::GetTable() );
       
   153     iUsernameStr = iStringPool.StringF( HTTP::EUsername, RHTTPSession::GetTable() );
       
   154     iPasswordStr = iStringPool.StringF( HTTP::EPassword, RHTTPSession::GetTable() );
       
   155 	iUserAgent = iStringPool.OpenFStringL( KUserAgentProductToken );
       
   156     
       
   157     //Regsiter for THTTPEvent::ESubmit http event
       
   158     //The User-Agent string gets appended with "3gpp-gba" string, 
       
   159     //indicating client is gba capable to the application server.
       
   160     aSession.FilterCollection().AddFilterL( *this,
       
   161                                             THTTPEvent::ESubmit,
       
   162                                             RStringF(),
       
   163                                             KAnyStatusCode,
       
   164                                             EStatusCodeHandler,
       
   165                                             filterName);
       
   166    
       
   167     //Regsiter for THTTPEvent::EGotResponseHeaders http event with "Authentication-Info" header 
       
   168     //and HTTPStatus::EOk http status code,just to know if the credentials established are valid.
       
   169     aSession.FilterCollection().AddFilterL( *this,
       
   170                                             THTTPEvent::EGotResponseHeaders,
       
   171                                             iAuthInfo,
       
   172                                             HTTPStatus::EOk,
       
   173                                             EStatusCodeHandler,
       
   174                                             filterName );
       
   175 
       
   176     //Regsiter for THTTPEvent::EGotResponseHeaders http event with "WWW-Authenticate" header 
       
   177     //and HTTPStatus::EUnauthorized http status code
       
   178     //The priority for this is set to MHTTPFilter::EStatusCodeHandler - 1,
       
   179     //so the gba filter intercepts the transaction before the default 
       
   180     //http digest authentication filter(which has priority MHTTPFilter::EStatusCodeHandler).
       
   181 
       
   182     aSession.FilterCollection().AddFilterL( *this, 
       
   183 											THTTPEvent::EGotResponseHeaders,	// Any transaction event
       
   184 											iStringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()),
       
   185 											HTTPStatus::EUnauthorized,
       
   186 											MHTTPFilter::EStatusCodeHandler - 1,	  // Priority of filter
       
   187 											filterName );						      // Name of filter
       
   188 
       
   189 	CleanupStack::PopAndDestroy( &filterName );
       
   190 	
       
   191 	//Check if the "user agent" header field in http session headers has "3gpp-gba" string in it.
       
   192 	//If it does n't have "3gpp-gba" string,append  it to the existing value.
       
   193     TBool found = EFalse;
       
   194     TPtrC8 rawFieldData;
       
   195     RHTTPHeaders sessionHeaders = aSession.RequestSessionHeadersL();
       
   196     RStringF sessionHeaderfieldname = aSession.StringPool().StringF( HTTP::EUserAgent, RHTTPSession::GetTable());
       
   197     sessionHeaders.GetRawField(sessionHeaderfieldname, rawFieldData);
       
   198     found = rawFieldData.Find(iUserAgent.DesC()) != KErrNotFound;
       
   199 
       
   200     if(!found)
       
   201         sessionHeaders.SetFieldL( sessionHeaderfieldname, iUserAgent );	    
       
   202 
       
   203     iMD5Calculator = CMD5::NewL();
       
   204 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::ConstructL--"));
       
   205 }
       
   206 
       
   207 
       
   208 //------------------------------------------------------------------------
       
   209 // CHTTPFilterGBA::~CHTTPFilterGBA
       
   210 // Destructor
       
   211 //------------------------------------------------------------------------
       
   212 //
       
   213 CHTTPFilterGBA::~CHTTPFilterGBA()
       
   214 {
       
   215 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::~CHTTPFilterGBA++"));
       
   216 	CleanupAll();															
       
   217 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::~CHTTPFilterGBA--"));
       
   218 }
       
   219 
       
   220 //------------------------------------------------------------------------
       
   221 // CHTTPFilterGBA::MHFLoad
       
   222 //------------------------------------------------------------------------
       
   223 //
       
   224 void CHTTPFilterGBA::MHFLoad(RHTTPSession, THTTPFilterHandle)
       
   225 {
       
   226 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFLoad"));
       
   227 	++iLoadCount;
       
   228 }
       
   229 
       
   230 //------------------------------------------------------------------------
       
   231 // CHTTPFilterGBA::MHFUnload
       
   232 //------------------------------------------------------------------------
       
   233 //
       
   234 void CHTTPFilterGBA::MHFUnload(RHTTPSession , THTTPFilterHandle)
       
   235 {
       
   236 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFUnload++"));
       
   237 	
       
   238     __ASSERT_DEBUG( iLoadCount >= 0, PanicGBAHttpFilters() );
       
   239     
       
   240 	if (--iLoadCount)
       
   241 	{
       
   242 		return;
       
   243 	}
       
   244 	delete this;
       
   245 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFUnload--"));
       
   246 }
       
   247 
       
   248 //------------------------------------------------------------------------
       
   249 // CHTTPFilterGBA::MHFRunL
       
   250 // See MHTTPFilterBase::MHFRunL 
       
   251 //------------------------------------------------------------------------
       
   252 //
       
   253 void CHTTPFilterGBA::MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent)
       
   254 {
       
   255 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFRunL++"));
       
   256 	
       
   257 	GBA_TRACE_DEBUG_NUM(("MHFRunL Event %d"), aEvent.iStatus );
       
   258 	
       
   259 	if (aEvent.iUID != KHTTPUid) 
       
   260 		return;
       
   261 
       
   262 	switch(aEvent.iStatus)
       
   263 	{
       
   264 		case THTTPEvent::ESubmit:
       
   265 		{
       
   266 			DoSubmitL(aTransaction);
       
   267 		}
       
   268 		break;
       
   269 
       
   270 		case THTTPEvent::EGotResponseHeaders:
       
   271 		{
       
   272 			// Get HTTP status code from header (e.g. 200)
       
   273 			RHTTPResponse resp = aTransaction.Response();
       
   274 			TInt status = resp.StatusCode();
       
   275 			GBA_TRACE_DEBUG_NUM(("MHFRunL staus code %d"), status );
       
   276 			// Get status text (e.g. "OK")
       
   277 			TBuf<KStatusTextLength512> statusText;
       
   278 			statusText.Copy(resp.StatusText().DesC());
       
   279 			
       
   280 			GBA_TRACE_DEBUG(("status text:"));
       
   281 			GBA_TRACE_DEBUG(statusText);
       
   282 			CheckHeadersL( aTransaction );
       
   283 		}
       
   284 		break;
       
   285 		case THTTPEvent::EGotResponseBodyData:
       
   286 		{
       
   287             GBA_TRACE_DEBUG(("Event: EGotResponseBodyData"));
       
   288 		}
       
   289 		break;
       
   290 		case THTTPEvent::EResponseComplete:
       
   291 		{
       
   292             GBA_TRACE_DEBUG(("Event: EResponseComplete"));
       
   293 			Cleanup( aTransaction );
       
   294 		}
       
   295 		break;
       
   296 		case THTTPEvent::EFailed:
       
   297 		{
       
   298             GBA_TRACE_DEBUG(("Event: EFailed"));			
       
   299 			Cleanup( aTransaction );		
       
   300 		}
       
   301 		default: 
       
   302 		{
       
   303             GBA_TRACE_DEBUG_NUM(("Unknow Event: ID - %d" ), aEvent.iStatus );
       
   304 		}
       
   305 		break;
       
   306 	}
       
   307 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFRunL--"));
       
   308 }
       
   309 
       
   310 
       
   311 //------------------------------------------------------------------------
       
   312 // CHTTPFilterGBA::MHFRunError
       
   313 // See MHTTPFilterBase::MHFRunError
       
   314 //------------------------------------------------------------------------
       
   315 //
       
   316 TInt CHTTPFilterGBA::MHFRunError(TInt /*aError*/, RHTTPTransaction aTransaction, const THTTPEvent& )
       
   317 {
       
   318     GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFRunError++"));
       
   319 	TInt error = 0;
       
   320 	// map aError to global error message
       
   321 	// pass the errorcode forward
       
   322 	THTTPEvent httpEvent(error);
       
   323 	TRAP_IGNORE(aTransaction.SendEventL(httpEvent, THTTPEvent::EIncoming, THTTPFilterHandle::ECurrentFilter ));
       
   324 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFRunError--"));
       
   325 	return KErrNone;
       
   326 }
       
   327 
       
   328 //------------------------------------------------------------------------
       
   329 // CHTTPFilterGBA::MHFSessionRunL
       
   330 // See MHTTPFilterBase::MHFSessionRunL
       
   331 //------------------------------------------------------------------------
       
   332 //
       
   333 void CHTTPFilterGBA::MHFSessionRunL(const THTTPSessionEvent& )
       
   334 {
       
   335 	// do nothing
       
   336 }
       
   337 
       
   338 //------------------------------------------------------------------------
       
   339 // CHTTPFilterGBA::MHFSessionRunL
       
   340 // See MHTTPFilterBase::MHFSessionRunL
       
   341 //------------------------------------------------------------------------
       
   342 //
       
   343 TInt CHTTPFilterGBA::MHFSessionRunError(TInt aError, const THTTPSessionEvent& )
       
   344 {
       
   345 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::MHFSessionRunError"));
       
   346 	// session problem, need to close GBA engine
       
   347 	return aError;
       
   348 }
       
   349 
       
   350 //------------------------------------------------------------------------
       
   351 // CHTTPFilterGBA::DumpResponseHeadersL
       
   352 // Dump the response headers to LOG file
       
   353 //------------------------------------------------------------------------
       
   354 //
       
   355 #if defined (_DEBUG)
       
   356 void CHTTPFilterGBA::DumpResponseHeadersL( RHTTPResponse& aResponse )
       
   357 {
       
   358 	GBA_TRACE_DEBUG("Dump the header...");
       
   359 
       
   360 	RHTTPHeaders headers = aResponse.GetHeaderCollection();
       
   361 	THTTPHdrFieldIter it = headers.Fields();
       
   362 	
       
   363 	while( it.AtEnd() == EFalse )
       
   364 	{
       
   365         RStringTokenF fieldName = it();
       
   366         RStringF fieldNameStr = iStringPool.StringF (fieldName );
       
   367         THTTPHdrVal fieldVal;
       
   368         TInt fieldParts = 0; // For the case if next the call fails.
       
   369         TRAP_IGNORE( fieldParts =  headers.FieldPartsL( fieldNameStr ) );
       
   370 		// dump the first part of  a  header field
       
   371 		for ( TInt ii = 0; ii < fieldParts; ii++ )
       
   372 		{	
       
   373 			if( headers.GetField( fieldNameStr, ii, fieldVal ) == KErrNone )
       
   374 			{
       
   375 				const TDesC8& fieldNameDesC = fieldNameStr.DesC();
       
   376 				GBA_TRACE_DEBUG(" : ");
       
   377                 GBA_TRACE_DEBUG(fieldNameDesC);
       
   378 
       
   379 				switch( fieldVal.Type() )
       
   380 				{
       
   381 				case THTTPHdrVal::KTIntVal:
       
   382 					{
       
   383 						GBA_TRACE_DEBUG_NUM(("%d"), fieldVal.Int() );
       
   384 					}
       
   385 					break;
       
   386 				case THTTPHdrVal::KStrFVal:
       
   387 					{
       
   388 						RStringF fieldValStr = iStringPool.StringF( fieldVal.StrF() );
       
   389 						const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   390                         GBA_TRACE_DEBUG(fieldValDesC);
       
   391 					}
       
   392 					break;
       
   393 				case THTTPHdrVal::KStrVal:
       
   394 					{
       
   395 						RString fieldValStr = iStringPool.String( fieldVal.Str() );
       
   396 						const TDesC8& fieldValDesC = fieldValStr.DesC();
       
   397 						GBA_TRACE_DEBUG(fieldValDesC);
       
   398 					}
       
   399 					break;
       
   400 				case THTTPHdrVal::KDateVal:
       
   401 					{
       
   402 						TDateTime date = fieldVal.DateTime();
       
   403 						TBuf<KStatusTextLength512> dateTimeString;
       
   404 						TTime t( date );
       
   405 						t.FormatL( dateTimeString, KDateFormat );
       
   406 						TBuf8<KStatusTextLength512> dtStr;
       
   407 						dtStr.Copy( dateTimeString.Left( 128 ) );
       
   408 						GBA_TRACE_DEBUG(dtStr);
       
   409 					}
       
   410 					break;
       
   411 				case THTTPHdrVal::KNoType:
       
   412 				default:
       
   413 					{
       
   414 					GBA_TRACE_DEBUG("Unrecognized value type");
       
   415 					}
       
   416 					break;
       
   417 				}
       
   418 			}
       
   419 		}
       
   420 
       
   421 		++it;
       
   422 	}
       
   423 	GBA_TRACE_DEBUG("Header is Dumped already");
       
   424 }
       
   425 #endif
       
   426 
       
   427 //------------------------------------------------------------------------
       
   428 // CHTTPFilterGBA::CheckHeadersL
       
   429 // Check HTTP headers and extract MIME type
       
   430 //------------------------------------------------------------------------
       
   431 // 
       
   432 void CHTTPFilterGBA::CheckHeadersL(  RHTTPTransaction& aTrans )
       
   433 {
       
   434 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::CheckHeadersL++"));
       
   435 	// read the header data and check the MIME type here	
       
   436 	// check the status and body
       
   437 	RHTTPResponse response = aTrans.Response();
       
   438 	TInt status = response.StatusCode();
       
   439 
       
   440 	#if defined (_DEBUG)
       
   441 	DumpResponseHeadersL( response );
       
   442 	#endif
       
   443 
       
   444 	THTTPHdrVal fieldVal;
       
   445 
       
   446 	// check if status == 401 and realm is 3GPP then we need to bootstrap, if we are already bootstrappign this is the second call
       
   447 	if(  status == HTTPStatus::EUnauthorized )
       
   448 	{
       
   449 	    TInt headerPart = FindHeaderPartToUseL(aTrans);
       
   450         if( headerPart == KErrNotFound )
       
   451             return;
       
   452     	
       
   453 	    THTTPHdrVal headerVal;
       
   454         TInt cred = KErrNotFound;
       
   455 
       
   456 	    if( aTrans.PropertySet().Property( iRealmStr, headerVal ) )
       
   457 	    	cred = DFindCredentials( headerVal, aTrans.Request().URI() );
       
   458 	    RStringF wwwAuthHeader = iStringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
       
   459 	    RHTTPHeaders headers(aTrans.Response().GetHeaderCollection());
       
   460 
       
   461 	    RString realm;
       
   462 	    THTTPHdrVal hdrVal;
       
   463 	    if (!headers.GetParam(wwwAuthHeader, iStringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable()), 
       
   464 				  hdrVal, headerPart))
       
   465 	    {
       
   466 			realm = hdrVal;
       
   467 			const TDesC8& val = realm.DesC();
       
   468 			if(val.FindF(K3GPPRealmString) == 0)
       
   469 			{
       
   470 				GBA_TRACE_DEBUG(("3GPP-Bootstrapping realm detected...\n"));
       
   471 	            THTTPHdrVal authTypeParam;
       
   472 	            if ( headers.GetField( wwwAuthHeader, headerPart, authTypeParam ) == KErrNone )
       
   473 	                // we need to store realm, opaque, nonce and qop values to
       
   474 	                // use them when resubmitting the request
       
   475 	                {
       
   476 	                THTTPHdrVal algorithmVal;
       
   477 	                THTTPHdrVal nonceVal;
       
   478 	                THTTPHdrVal realmVal;
       
   479 	                THTTPHdrVal opaqueVal;
       
   480 	                THTTPHdrVal staleVal;
       
   481 	                TInt algVal( EAlgUnknown );
       
   482 	                TInt authVal( EQopNone );
       
   483 
       
   484 	                aTrans.PropertySet().RemoveProperty( iNonceStr );
       
   485 	                aTrans.PropertySet().RemoveProperty( iRealmStr );
       
   486 	                aTrans.PropertySet().RemoveProperty( iOpaqueStr );
       
   487 	                aTrans.PropertySet().RemoveProperty( iQopStr );
       
   488 	                aTrans.PropertySet().RemoveProperty( iStaleStr );
       
   489 
       
   490 	                if( !headers.GetParam( wwwAuthHeader, 
       
   491 	                                      iStringPool.StringF( HTTP::EAlgorithm, 
       
   492 	                                                      RHTTPSession::GetTable() ), 
       
   493 	                                      algorithmVal, 
       
   494 	                                      headerPart ) )
       
   495 	                    {
       
   496 	                    if( !algorithmVal.Str().DesC().CompareF( iMd5Str.DesC() ) )
       
   497 	                        {
       
   498 	                        algVal = EAlgMd5;
       
   499 	                        }
       
   500 	                    else if( !algorithmVal.Str().DesC().CompareF( iMd5SessStr.DesC() ) )
       
   501 	                        {
       
   502 	                        algVal = EAlgMd5Sess;
       
   503 	                        }
       
   504 	                    }
       
   505 
       
   506 	                authVal = CheckQop( headers, wwwAuthHeader, headerPart );
       
   507 
       
   508 	                headers.GetParam( wwwAuthHeader, iNonceStr, nonceVal, headerPart );
       
   509 	                headers.GetParam( wwwAuthHeader, iRealmStr, realmVal, headerPart );
       
   510 	                headers.GetParam( wwwAuthHeader, iOpaqueStr, opaqueVal, headerPart );
       
   511 	                headers.GetParam( wwwAuthHeader, iStaleStr, staleVal, headerPart );
       
   512 
       
   513 	                if( ( authVal & EQopAuth || authVal == EQopNone )
       
   514 	                    && nonceVal.Type() == THTTPHdrVal::KStrVal
       
   515 	                    && realmVal.Type() == THTTPHdrVal::KStrVal )
       
   516 	                    {
       
   517 	                    aTrans.PropertySet().SetPropertyL( iNonceStr, nonceVal );
       
   518 	                    aTrans.PropertySet().SetPropertyL( iRealmStr, realmVal );
       
   519 	                    // Opaque
       
   520 	                    if( opaqueVal.Type() == THTTPHdrVal::KStrVal )
       
   521 	                        {
       
   522 	                        aTrans.PropertySet().SetPropertyL( iOpaqueStr, opaqueVal );
       
   523 	                        }
       
   524 
       
   525 	                    // Qop
       
   526 	                    aTrans.PropertySet().SetPropertyL( iQopStr, authVal );
       
   527 	                    // Algorithm
       
   528 	                    aTrans.PropertySet().SetPropertyL( iStringPool.StringF( HTTP::EAlgorithm, 
       
   529 	                                                              RHTTPSession::GetTable() ), 
       
   530 	                                                              algVal );
       
   531 
       
   532 	                    _LIT8( KTrue, "TRUE" );
       
   533 	                    if( staleVal.Type() == THTTPHdrVal::KStrVal 
       
   534 	                        && !staleVal.Str().DesC().CompareF( KTrue ) )
       
   535 	                        // stale is true -> nonce expired
       
   536 	                        {
       
   537                             GBA_TRACE_DEBUG(("Stale found"));
       
   538 	                        // update nonce value
       
   539 	                        TDCredentials& creds = iDCredentials[cred];
       
   540 	                        iStringPool.String( creds.iNonce ).Close();
       
   541 	                        creds.iNonce = nonceVal.Str().Copy();
       
   542 
       
   543 	                        // indicate to engine that no uname/pwd dialog needed
       
   544 	                        staleVal.SetInt( 1 );
       
   545 	                        aTrans.PropertySet().SetPropertyL( iStaleStr, staleVal );
       
   546 	                        }
       
   547 
       
   548 	                    }
       
   549 	                }
       
   550 	 				RHTTPTransactionPropertySet propSet = aTrans.PropertySet();
       
   551 	                THTTPHdrVal staleVal;
       
   552 
       
   553 					// don't show the uname&pwd dialog
       
   554 	                staleVal.SetInt( 1 );
       
   555 	                propSet.SetPropertyL( iStaleStr, staleVal );
       
   556 	                // if we are already bootstrapping results will be retrieved when request is resubmitted
       
   557 	                GBA_TRACE_DEBUG(("Do Bootstrap\n"));
       
   558 	                // start bootstrap process
       
   559 	                if(!iGbaUtility)
       
   560 	                    {
       
   561 	                    iGbaUtility = CGbaUtility::NewL(*this);
       
   562 	                    
       
   563 	                    //setbsf address required only for testing purpose
       
   564 	                    if(iBsfAddress.Size())
       
   565 	                        {
       
   566                             iGbaUtility->SetBSFAddress(iBsfAddress);
       
   567 	                        }    
       
   568 	                    }
       
   569 	                
       
   570 	                // obtain NAF FQDN from URI
       
   571 	                iGbaInputParams.iNAFName.Copy(aTrans.Request().URI().UriDes());
       
   572 	                iGbaInputParams.iUICCLabel.Copy(iUICCLabel);
       
   573 	                iGbaInputParams.iProtocolIdentifier.Copy(iProtocolIdentifier);
       
   574 	                
       
   575 	                //iBootstrapCount == 0  - soft bootstrapp - get cradentials from gba cache
       
   576 	                //iBootstrapCount == 1  - force bootstrapp - get cradentials from BSF server
       
   577 	                //iBootstrapCount > 1  need to cancel http transaction to break out of the UE-NAF communication loop
       
   578 	                if(iBootstrapCount == 0){
       
   579 	                iGbaInputParams.iFlags = EGBADefault;
       
   580                         GBA_TRACE_DEBUG(("iCredentials.Flags = EGBADefault"));
       
   581 	                }
       
   582 	                else if(iBootstrapCount == 1){
       
   583 	                iGbaInputParams.iFlags = EGBAForce;
       
   584                         GBA_TRACE_DEBUG(("iCredentials.Flags = EGBAForce"));
       
   585 	                }
       
   586 	                else{
       
   587                         GBA_TRACE_DEBUG(("iCredentials.Flags"));
       
   588                         iBootstrapCount = 0;
       
   589                         return;
       
   590 	                }
       
   591 	                
       
   592 	                //Default accesspoint will be used - iAPID = -1
       
   593 	                iGbaInputParams.iAPID = -1;
       
   594                     
       
   595 	                //Cancel the transaction
       
   596 	                aTrans.Cancel();
       
   597                     
       
   598 	                // fetch credentials from bootstrapper
       
   599 	                iGbaUtility->Bootstrap(iGbaInputParams, iGbaOutputParams);
       
   600 	                iBootstrapCount++;
       
   601 	                iBootstrapPending = ETrue;
       
   602 	                if(!iBootstrapWait.IsStarted())
       
   603 	                    {
       
   604                         iBootstrapWait.Start();
       
   605 	                    }
       
   606 	                
       
   607 	                if( iHaveGbaBootstrapCredentials )
       
   608 	                    {
       
   609                         GBA_TRACE_DEBUG(("Have stored credentials"));
       
   610                         RHTTPTransactionPropertySet propSet = aTrans.PropertySet();
       
   611                         GBA_TRACE_DEBUG(("BTID:"));
       
   612                         GBA_TRACE_DEBUG(iGbaOutputParams.iBTID);
       
   613                         // Encodes the KNAF to generate a password
       
   614                         TImCodecB64 b64coder;
       
   615                         TBuf8<KB64KeySize> keyBase64;
       
   616                         b64coder.Initialise();
       
   617                         b64coder.Encode( iGbaOutputParams.iKNAF, keyBase64 );
       
   618                         RString username = iStringPool.OpenStringL( iGbaOutputParams.iBTID );
       
   619                         CleanupClosePushL<RString>( username );
       
   620                         RString password = iStringPool.OpenStringL( keyBase64 );
       
   621                         CleanupClosePushL<RString>( password );
       
   622                         propSet.SetPropertyL( iUsernameStr, username );
       
   623                         propSet.SetPropertyL( iPasswordStr, password );
       
   624                         CleanupStack::PopAndDestroy(&password);
       
   625                         CleanupStack::PopAndDestroy(&username);
       
   626                         // Re-submit the http request with much needed credentials
       
   627                         aTrans.SubmitL(); 
       
   628                         }
       
   629 	                else
       
   630 	                    {
       
   631                         //Since bootstrapping failed,Do not have to resubmit the http request ?
       
   632                         return;
       
   633                         }
       
   634 			}
       
   635 	    }
       
   636 		}
       
   637 
       
   638 	if( status == HTTPStatus::EOk && iGbaUtility){
       
   639 		// if we have bootstrapped, it seems that we have succeeded
       
   640 		iBootstrapCount = 0;
       
   641 	}
       
   642    	GBA_TRACE_DEBUG(("CHTTPFilterGBA::CheckHeadersL--"));
       
   643 	
       
   644 }
       
   645 
       
   646 void CHTTPFilterGBA::DoSubmitL( RHTTPTransaction aTransaction )
       
   647 {
       
   648 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::DoSubmitL++"));
       
   649 	
       
   650     // always add 3gpp-gba into user-agent field in headers,
       
   651     // THIS CAN BE REMOVED WHEN GBA IS ADDED INTO THE CATALOG OF THE DEVICE
       
   652     // WHICH IS STATIC.
       
   653 	
       
   654 	RHTTPHeaders hdr = aTransaction.Request().GetHeaderCollection();
       
   655 	
       
   656 	RStringF fieldname = aTransaction.Session().StringPool().StringF(HTTP::EUserAgent,RHTTPSession::GetTable());
       
   657 	
       
   658 	TBool found = EFalse;
       
   659 	TPtrC8 rawFieldData;
       
   660 	
       
   661 	hdr.GetRawField(fieldname, rawFieldData);
       
   662 	
       
   663 	found = rawFieldData.Find(iUserAgent.DesC()) != KErrNotFound;
       
   664 	
       
   665 	//Append "3gpp-gba" string to the "user agent" transaction header field only when,
       
   666 	//http transaction user agent header field has been set already(rawFieldData.Size() > 0) by an application,
       
   667 	//which opened the http transaction and also
       
   668 	//the transaction user agent header field value does not have "3gpp-gba" string in it.
       
   669 	
       
   670 	if(!found && rawFieldData.Size())
       
   671 	    hdr.SetFieldL(fieldname, iUserAgent);
       
   672 	
       
   673     TInt cred = KErrNotFound;
       
   674     
       
   675     //iHaveGbaBootstrapCredentials - ETrue ,when the GBA bootstrapping is completed successfully
       
   676     if( iHaveGbaBootstrapCredentials )
       
   677         {
       
   678         // Get credentials from URI, only for wwwAuthenticate
       
   679         // If there are credentials in the transaction properties, add them to the list
       
   680         DGetCredentialsFromPropertiesL( aTransaction );
       
   681     
       
   682         // just in case we always remove stale value from properties
       
   683         aTransaction.PropertySet().RemoveProperty( iStaleStr );
       
   684     
       
   685         // If we have credentials for this URL, add them
       
   686         cred = DFindCredentialsForURI( aTransaction.Request().URI() );
       
   687     
       
   688         if ( cred != KErrNotFound )
       
   689             {
       
   690             EncodeDigestAuthL( cred, aTransaction );
       
   691             }
       
   692         }
       
   693     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DoSubmitL--"));
       
   694 }
       
   695 
       
   696 //-----------------------------------------------------------------------------
       
   697 // CHTTPFilterGBA::Cleanup
       
   698 // Cleanup the resource related with a transaction
       
   699 //-----------------------------------------------------------------------------
       
   700 //
       
   701 void CHTTPFilterGBA::Cleanup( const RHTTPTransaction& /*aTrans*/ )
       
   702 {
       
   703 }
       
   704 
       
   705 //-----------------------------------------------------------------------------
       
   706 // CHTTPFilterGBA::CleanupAll
       
   707 // Cleanup all the GBA transactions, in case a session error happens or a session
       
   708 // is closed.
       
   709 //-----------------------------------------------------------------------------
       
   710 //
       
   711 void CHTTPFilterGBA::CleanupAll()
       
   712 {	
       
   713 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::CleanupAll++"));
       
   714 	while(TInt i = iDCredentials.Count())
       
   715 	{
       
   716 		DRemoveCredentialsFromList(i-1);
       
   717 	} 
       
   718 
       
   719 	iQopAuthStr.Close();
       
   720 	iMd5SessStr.Close();
       
   721 	iMd5Str.Close();
       
   722 	iAuthInfo.Close();
       
   723 	iUserAgent.Close();
       
   724     delete iMD5Calculator;
       
   725     iMD5Calculator = NULL;
       
   726     delete 	iGbaUtility;
       
   727     iGbaUtility = NULL;
       
   728     GBA_TRACE_DEBUG(("CHTTPFilterGBA::CleanupAll--"));
       
   729 }
       
   730 
       
   731 
       
   732 TInt CHTTPFilterGBA::FindHeaderPartToUseL(RHTTPTransaction aTransaction) const
       
   733 {
       
   734     // There may be several different authentication fields. We need
       
   735     // to chose the strongest one we understnad. Currently, we only
       
   736     // support 2, Basic and Digest, and Digest is the strongest
       
   737     // assuming there is a qop that we can accept. Therefore, we keep
       
   738     // track of the last good basic one we found, and return the
       
   739     // moment we find an acceptable digest one.
       
   740 
       
   741     // While we're here, we check that all desired fields are there.
       
   742 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::FindHeaderPartToUseL++"));
       
   743     RStringF wwwAuthenticate = iStringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
       
   744     RStringF realm = iStringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable());
       
   745     RStringF nonce = iStringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable());
       
   746     RStringF qop   = iStringPool.StringF(HTTP::EQop,RHTTPSession::GetTable());
       
   747     TInt lastGoodBasic = KErrNotFound;
       
   748     RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection();
       
   749     const TInt parts = headers.FieldPartsL(wwwAuthenticate);
       
   750     GBA_TRACE_DEBUG_NUM((" FindHeaderPartToUseL part no:1 = %d"), parts );
       
   751     for (TInt ii = 0; ii < parts; ii++)
       
   752     {
       
   753 	THTTPHdrVal fieldVal;// The name of the current field.
       
   754 	THTTPHdrVal hdrVal;//A scratch hdrVal
       
   755 	headers.GetField(wwwAuthenticate, ii, fieldVal);
       
   756 	TInt x = fieldVal.StrF().Index(RHTTPSession::GetTable());
       
   757 	GBA_TRACE_DEBUG_NUM((" FindHeaderPartToUseL part no:1 = %d"), x );
       
   758 	switch (fieldVal.StrF().Index(RHTTPSession::GetTable()))
       
   759 	{
       
   760 	    case HTTP::EDigest:
       
   761 	    	
       
   762 	    	{
       
   763 	    	GBA_TRACE_DEBUG_NUM((" FindHeaderPartToUseL realm  = %d"), headers.GetParam(wwwAuthenticate, realm, hdrVal, ii) );
       
   764 	    	
       
   765 	    	GBA_TRACE_DEBUG_NUM((" FindHeaderPartToUseL nonce  = %d"), headers.GetParam(wwwAuthenticate, nonce, hdrVal, ii) );
       
   766 	    
       
   767 			if (headers.GetParam(wwwAuthenticate, realm, hdrVal, ii) == 
       
   768 			    KErrNone &&
       
   769 			    headers.GetParam(wwwAuthenticate, nonce, hdrVal, ii) == 
       
   770 			    KErrNone)
       
   771 			{
       
   772 				GBA_TRACE_DEBUG_NUM((" FindHeaderPartToUseL qop  = %d"), headers.GetParam(wwwAuthenticate, qop, hdrVal, ii) );
       
   773 				
       
   774 			    // We've got a realm and a nonce. If there's a qop, we
       
   775 			    // need to check it's acceptable.
       
   776 			    if (headers.GetParam(wwwAuthenticate, qop, hdrVal, ii) != 
       
   777 				KErrNone || FindAuth(hdrVal.Str().DesC()))
       
   778 			    	{
       
   779 			    	GBA_TRACE_DEBUG_NUM((" FindHeaderPartToUseL part no = %d"), ii );
       
   780 			    	return ii;
       
   781 			    	}
       
   782 				
       
   783 			}
       
   784 	    	}
       
   785 		break;
       
   786 
       
   787 	    default:
       
   788 		// We don't understand this, whatever it is. Ignore it.
       
   789 		break;
       
   790 	}
       
   791     }
       
   792     GBA_TRACE_DEBUG(("CHTTPFilterGBA::FindHeaderPartToUseL--"));
       
   793     return lastGoodBasic;
       
   794 }
       
   795 
       
   796 
       
   797 TBool CHTTPFilterGBA::FindAuth(const TDesC8& aQop) const
       
   798 {
       
   799 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::FindAuth++"));
       
   800     TPtrC8 tokens = aQop;
       
   801     TPtrC8 token;
       
   802     const TDesC8& auth = iStringPool.StringF(HTTP::EAuth,RHTTPSession::GetTable()).DesC();
       
   803     TInt len;
       
   804     do
       
   805     {
       
   806     	len = tokens.Locate(',');
       
   807     	if(len == -1)
       
   808     		len = tokens.Length();
       
   809     	token.Set(tokens.Ptr(),len);
       
   810 		if (token.Compare(auth) == 0)
       
   811 		{
       
   812 		    return ETrue;
       
   813     	}
       
   814     	tokens.Set(tokens.Ptr()+len);
       
   815     }  while(tokens.Length());
       
   816     GBA_TRACE_DEBUG(("CHTTPFilterGBA::FindAuth--"));
       
   817     return EFalse;
       
   818 }
       
   819 
       
   820 
       
   821 
       
   822 void CHTTPFilterGBA::EncodeDigestAuthL( TInt aCred, RHTTPTransaction aTransaction )
       
   823     {
       
   824     GBA_TRACE_DEBUG(("CHTTPFilterGBA::EncodeDigestAuthL++"));
       
   825 
       
   826 	// For now, only support RFC2069 format. The digest is
       
   827 	// MD5(H(A1):nonce:H(A2))
       
   828 	TBuf8<KHashLength> hash;
       
   829     TBuf8<KNonceCountLength> nonceCount;
       
   830 
       
   831     TDCredentials cred = iDCredentials[aCred];
       
   832     
       
   833 
       
   834     THTTPHdrVal nonce( iStringPool.String( cred.iNonce ) );
       
   835     THTTPHdrVal realm( iStringPool.String( cred.iRealm ) );
       
   836     THTTPHdrVal qop;
       
   837     THTTPHdrVal uname( iStringPool.String( cred.iUser ) );
       
   838     THTTPHdrVal password( iStringPool.String( cred.iPassword ) );
       
   839     THTTPHdrVal opaque( iStringPool.String( cred.iOpaque ) );
       
   840 
       
   841     if( cred.iQop & EQopAuth )
       
   842         // recent release supports only qop 'auth'.
       
   843         {
       
   844         qop.SetStrF( iQopAuthStr );
       
   845         }
       
   846 
       
   847 	THTTPHdrVal requestUri;
       
   848     // we get url from request and modify as made in chttpclienthandler.cpp
       
   849     RString uriStr = RequestUriL( aTransaction );
       
   850     CleanupClosePushL<RString>( uriStr );
       
   851 
       
   852 	requestUri.SetStr( uriStr );
       
   853 	
       
   854 	HBufC8* stringToHash = NULL;
       
   855 	RStringF auth = iStringPool.StringF(HTTP::EAuth,RHTTPSession::GetTable());
       
   856 
       
   857 	TBuf8<KHashLength> cnonce;
       
   858 	if ( cred.iQop != EQopNone )
       
   859 		{
       
   860         GenerateCNonce( cnonce );
       
   861 
       
   862         // 7 is for colons
       
   863         // 8 for nc-value
       
   864         stringToHash = HBufC8::NewMaxLC( KHashLength +  // H(A1)
       
   865                                          1 +    // ":"
       
   866                                          nonce.Str().DesC().Length() + 
       
   867                                          1 +    // ":"
       
   868                                          KIntegerConstant8 +    // nc value
       
   869                                          1 +    // ":"
       
   870                                          KHashLength +  // cnonce
       
   871                                          1 +    // ":"
       
   872 										 qop.StrF().DesC().Length() +
       
   873                                          1 +    // ":"
       
   874 										 KHashLength ); // H(A2)
       
   875 		TPtr8 stringMod = stringToHash->Des();
       
   876 		stringMod.Zero();
       
   877 		HAOneL( cred.iAlgorithm, uname, password, realm.Str(), nonce, cnonce, stringMod );
       
   878 		stringMod.Append(':');
       
   879 		stringMod.Append(nonce.Str().DesC());
       
   880 
       
   881         // nc value
       
   882 		stringMod.Append(':');
       
   883         ++cred.iNc;
       
   884         // nc value is of 8 chars length and in hexadecimal format
       
   885         nonceCount.NumFixedWidth( cred.iNc, EHex, KIntegerConstant8 );
       
   886 		stringMod.Append( nonceCount );
       
   887 		stringMod.Append(':');
       
   888 
       
   889 		stringMod.Append(cnonce);
       
   890 		stringMod.Append(':');
       
   891 		stringMod.Append(auth.DesC());
       
   892 		stringMod.Append(':');
       
   893 		HATwoL(aTransaction.Request().Method(), requestUri.Str(), hash);
       
   894 		stringMod.Append(hash);
       
   895 		}
       
   896 	else
       
   897 		{
       
   898 		// The response is the hash of H(A1):nonce:H(A2).
       
   899 		// Crqeate a buffer for the string to convert into MD5. The
       
   900 		// length is 32 characters for each of the hashes, 2
       
   901 		// characters for the 2 colons, plus the length of the nonce
       
   902 		stringToHash = HBufC8::NewMaxLC(nonce.Str().DesC().Length() + 
       
   903 												 2 * KHashLength + 2);
       
   904 		TPtr8 stringMod = stringToHash->Des();
       
   905 		stringMod.Zero();
       
   906 		HAOneL( cred.iAlgorithm, uname, password, realm.Str(), nonce, cnonce, stringMod );
       
   907 		stringMod.Append(':');
       
   908 		stringMod.Append(nonce.Str().DesC());
       
   909 		stringMod.Append(':');
       
   910 		HATwoL(aTransaction.Request().Method(), requestUri.Str(), hash);
       
   911 		stringMod.Append(hash);
       
   912 		}
       
   913 	
       
   914 	Hash(*stringToHash, hash);
       
   915 	CleanupStack::PopAndDestroy(stringToHash);
       
   916 
       
   917 	// OK. hash now contains the digest response. Set up the header.
       
   918 	RHTTPHeaders requestHeaders(aTransaction.Request().GetHeaderCollection());
       
   919 	
       
   920 	requestHeaders.RemoveField(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable())); 
       
   921 
       
   922 	requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   923 							 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   924 							 iStringPool.StringF(HTTP::EUsername,RHTTPSession::GetTable()),
       
   925 							 uname);
       
   926 	requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   927 							 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   928 							 iStringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable()),
       
   929 							 realm);
       
   930 	requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   931 							 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   932 							 iStringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable()),
       
   933 							 nonce);
       
   934 	RString hashStr = iStringPool.OpenStringL(hash);
       
   935 	CleanupClosePushL<RString>(hashStr);
       
   936 
       
   937 	THTTPHdrVal hdrVal;
       
   938     hdrVal.SetStr(hashStr);
       
   939 	requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   940 							 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   941 							 iStringPool.StringF(HTTP::EResponse,RHTTPSession::GetTable()),
       
   942 							 hdrVal);
       
   943 
       
   944 	requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   945 							 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   946 							 iStringPool.StringF(HTTP::EUri,RHTTPSession::GetTable()),
       
   947 							 requestUri);
       
   948 	CleanupStack::PopAndDestroy(&hashStr);
       
   949 	if ( cred.iQop != EQopNone )
       
   950 		{
       
   951         // QOP
       
   952 		hdrVal.SetStrF( auth );
       
   953 		requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   954 								 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   955 								 iStringPool.StringF(HTTP::EQop,RHTTPSession::GetTable()),
       
   956 								 hdrVal);
       
   957 		RString cnonceString = iStringPool.OpenStringL(cnonce);
       
   958         // CNonce
       
   959 		CleanupClosePushL<RString>( cnonceString );
       
   960 		hdrVal.SetStr(cnonceString);
       
   961 		requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   962 								 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   963 								 iStringPool.StringF(HTTP::ECnonce,RHTTPSession::GetTable()),
       
   964 								 hdrVal);
       
   965 		CleanupStack::PopAndDestroy( &cnonceString );
       
   966         // Nonce-count
       
   967         RString nonceStr = iStringPool.OpenStringL( nonceCount );
       
   968         CleanupClosePushL<RString>( nonceStr );
       
   969 		hdrVal.SetStr( nonceStr );
       
   970 		requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   971 								 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   972 								 iStringPool.StringF(HTTP::ENc,RHTTPSession::GetTable()),
       
   973 								 hdrVal);
       
   974         CleanupStack::PopAndDestroy( &nonceStr );
       
   975 		}
       
   976 	
       
   977 	if(  opaque.Str().DesC().Length() )
       
   978 		requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   979 								 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   980 								 iStringPool.StringF(HTTP::EOpaque,RHTTPSession::GetTable()),
       
   981 								 opaque );	
       
   982 
       
   983     if( cred.iAlgorithm == EAlgMd5 )
       
   984         {
       
   985 		requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   986 								 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   987 								 iStringPool.StringF(HTTP::EAlgorithm,RHTTPSession::GetTable()),
       
   988 								 iMd5Str );
       
   989         }
       
   990     else if( cred.iAlgorithm == EAlgMd5Sess )
       
   991         {
       
   992 		requestHeaders.SetFieldL(iStringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   993 								 THTTPHdrVal(iStringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   994 								 iStringPool.StringF(HTTP::EAlgorithm,RHTTPSession::GetTable()),
       
   995 								 iMd5SessStr );
       
   996         }
       
   997 
       
   998     // set it again
       
   999     // this may be needed if auth. fails and stale is true.
       
  1000     aTransaction.PropertySet().SetPropertyL( iRealmStr, realm );
       
  1001     
       
  1002     CleanupStack::PopAndDestroy( &uriStr );
       
  1003     GBA_TRACE_DEBUG(("CHTTPFilterGBA::EncodeDigestAuthL--"));
       
  1004     }
       
  1005   
       
  1006 void CHTTPFilterGBA::DAddCredentialsToListL( RString aUsernameStr,
       
  1007         RString aPasswordStr,
       
  1008         RString aRealmStr,
       
  1009         RStringF aUriStr,
       
  1010         RString aOpaque,
       
  1011         RString aNonce,
       
  1012         TInt aQop,
       
  1013         TInt aAuthAlg )
       
  1014     {
       
  1015     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DAddCredentialsToListL++"));
       
  1016     GBA_TRACE_DEBUG("uname: ");
       
  1017     GBA_TRACE_DEBUG(aUsernameStr.DesC());
       
  1018     GBA_TRACE_DEBUG("pwd: ");
       
  1019     GBA_TRACE_DEBUG(aPasswordStr.DesC());
       
  1020     GBA_TRACE_DEBUG("realm: ");
       
  1021     GBA_TRACE_DEBUG(aRealmStr.DesC());
       
  1022     GBA_TRACE_DEBUG("uri: ");
       
  1023     GBA_TRACE_DEBUG(aUriStr.DesC());
       
  1024     GBA_TRACE_DEBUG_NUM(("qop: %d"), aQop );
       
  1025     GBA_TRACE_DEBUG_NUM(("alg: %d"), aAuthAlg );
       
  1026 
       
  1027     TDCredentials newCred;
       
  1028     newCred.iUser = aUsernameStr;
       
  1029     newCred.iPassword = aPasswordStr;
       
  1030     newCred.iRealm = aRealmStr;
       
  1031     newCred.iURI = aUriStr;
       
  1032     newCred.iOpaque = aOpaque;
       
  1033     newCred.iNonce = aNonce;
       
  1034     newCred.iQop = aQop;
       
  1035     newCred.iAlgorithm = aAuthAlg;
       
  1036     newCred.iNc = 0;
       
  1037     User::LeaveIfError( iDCredentials.Append( newCred ) );
       
  1038     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DAddCredentialsToListL--"));
       
  1039     }
       
  1040 
       
  1041 // -----------------------------------------------------------------------------
       
  1042 // CHTTPFilterGBA::HAOneL
       
  1043 // Calculates H(A1)
       
  1044 // -----------------------------------------------------------------------------
       
  1045 //
       
  1046 void CHTTPFilterGBA::HAOneL(int aAlgorithm,
       
  1047                                            const RString& aUsername,
       
  1048                                            const RString& aPW,
       
  1049 								           const RString& aRealm, 
       
  1050                                            const RString& aNonceValue,
       
  1051                                            TDesC8& aCNonce,
       
  1052                                            TDes8& aResult )
       
  1053 	{
       
  1054 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::HAOneL++"));
       
  1055     TBuf8<KHashLength> hash;
       
  1056 
       
  1057 	HBufC8* a1 = HBufC8::NewMaxL(aUsername.DesC().Length() + 
       
  1058 								 aPW.DesC().Length() + 
       
  1059 								 aRealm.DesC().Length() + 2 );
       
  1060 	TPtr8 a1Mod = a1->Des();
       
  1061 	a1Mod.Zero();
       
  1062 	a1Mod.Append( aUsername.DesC() );
       
  1063 	a1Mod.Append( KColon );
       
  1064 	a1Mod.Append( aRealm.DesC() );
       
  1065 	a1Mod.Append( KColon );
       
  1066 	a1Mod.Append( aPW.DesC() );
       
  1067 
       
  1068 	GBA_TRACE_DEBUG("a1 first hash material");
       
  1069 	GBA_TRACE_DEBUG(*a1);
       
  1070 	
       
  1071 
       
  1072 	Hash( *a1, hash );
       
  1073 	
       
  1074 	GBA_TRACE_DEBUG("a1 first hash");
       
  1075 	GBA_TRACE_DEBUG(hash);
       
  1076 
       
  1077     delete a1;
       
  1078     a1 = NULL;
       
  1079 
       
  1080     if( aAlgorithm == EAlgMd5Sess )
       
  1081         {
       
  1082 	    a1 = HBufC8::NewMaxL( KHashLength +
       
  1083                                1 +  // ":"
       
  1084                                aNonceValue.DesC().Length() +
       
  1085                                1 +  // ":"
       
  1086 							   aCNonce.Length() );
       
  1087 	    TPtr8 a1Mod = a1->Des();
       
  1088 	    a1Mod.Zero();
       
  1089         a1Mod.Append( hash );
       
  1090         a1Mod.Append( KColon );
       
  1091         a1Mod.Append( aNonceValue.DesC() );
       
  1092         a1Mod.Append( KColon );
       
  1093         a1Mod.Append( aCNonce );
       
  1094 
       
  1095         GBA_TRACE_DEBUG("a1 final hash material");
       
  1096         GBA_TRACE_DEBUG(*a1);
       
  1097 
       
  1098 	    Hash(*a1, aResult);
       
  1099 	    
       
  1100         GBA_TRACE_DEBUG("a1 final hash");
       
  1101         GBA_TRACE_DEBUG(hash);
       
  1102 	    delete a1;
       
  1103         a1 = NULL;
       
  1104         }
       
  1105     else
       
  1106         {
       
  1107         aResult.Copy( hash );
       
  1108         }
       
  1109     GBA_TRACE_DEBUG(("CHTTPFilterGBA::HAOneL--"));
       
  1110 	}
       
  1111 
       
  1112 
       
  1113 // -----------------------------------------------------------------------------
       
  1114 // CHTTPFilterGBA::HAtwoL
       
  1115 // Calculates H(A2)
       
  1116 // -----------------------------------------------------------------------------
       
  1117 //
       
  1118 void CHTTPFilterGBA::HATwoL(const RStringF& aMethod, 
       
  1119 								           const RString& aRequestUri,
       
  1120 								           TDes8& aResult)
       
  1121 	{
       
  1122 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::HAtwoL++"));
       
  1123 	// In the auth qop, a2 is Method:digest-uri-value
       
  1124 	// Digest-uri-value. We don't support auth-int qop
       
  1125 	// Allocate enough space for the method, the URI and the colon.
       
  1126 	TPtrC8 requestUri = aRequestUri.DesC();
       
  1127 	TPtrC8 method = aMethod.DesC();
       
  1128 	HBufC8* a2 = HBufC8::NewMaxLC(requestUri.Length() + method.Length() + 1);
       
  1129 	TPtr8 a2Mod = a2->Des();
       
  1130 	a2Mod.Zero();
       
  1131 	a2Mod.Append(method);
       
  1132 	a2Mod.Append(':');
       
  1133 	a2Mod.Append(requestUri);
       
  1134 
       
  1135     GBA_TRACE_DEBUG("a2 final hash material");
       
  1136     GBA_TRACE_DEBUG(*a2);
       
  1137 
       
  1138 	Hash(*a2, aResult);
       
  1139 
       
  1140     GBA_TRACE_DEBUG("a2 final hash");
       
  1141     GBA_TRACE_DEBUG(aResult);
       
  1142 
       
  1143 	CleanupStack::PopAndDestroy(a2);
       
  1144 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::HAtwoL--"));
       
  1145 	}
       
  1146 
       
  1147 // -----------------------------------------------------------------------------
       
  1148 // CHTTPFilterGBA::Hash
       
  1149 // Calculates hash value
       
  1150 // -----------------------------------------------------------------------------
       
  1151 //
       
  1152 void CHTTPFilterGBA::Hash(const TDesC8& aMessage, TDes8& aHash)
       
  1153 	{
       
  1154 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::Hash++"));
       
  1155 	// Calculate the 128 bit (16 byte) hash
       
  1156 	iMD5Calculator->Reset();
       
  1157 	TPtrC8 hash = iMD5Calculator->Hash( aMessage );
       
  1158 	// Now print it as a 32 byte hex number
       
  1159 	aHash.Zero();
       
  1160 	_LIT8(formatStr, "%02x");
       
  1161 	for (TInt ii = 0; ii < KRawHashLength; ii++)
       
  1162 		{
       
  1163 		TBuf8<2> scratch;
       
  1164 		scratch.Zero();
       
  1165 		scratch.Format( formatStr, hash[ii] );
       
  1166 		aHash.Append( scratch );
       
  1167 		}
       
  1168 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::Hash--"));
       
  1169 	}
       
  1170 
       
  1171 // -----------------------------------------------------------------------------
       
  1172 // CHTTPFilterGBA::GenerateCNonce
       
  1173 // Generate unique cnonce value.
       
  1174 // -----------------------------------------------------------------------------
       
  1175 //
       
  1176 void CHTTPFilterGBA::GenerateCNonce(TDes8& aNonce)
       
  1177 	{
       
  1178 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::GenerateCNonce++"));
       
  1179 	// 'Inspired by' CObexAuthenticator
       
  1180 
       
  1181 	// The purpose of the client nonce is to protect against 'chosen
       
  1182 	// plaintext' attacks where a hostile server tricks the client
       
  1183 	// into supplying a password using a specific server nonce that
       
  1184 	// allows an (as yet undiscovered) flaw in MD5 to recover the
       
  1185 	// password. As such the only important thing about client nonces
       
  1186 	// is that they change and aren't predictable. See section 4.9 of
       
  1187 	// RFC2616
       
  1188 
       
  1189 	TTime time;
       
  1190 	time.UniversalTime();
       
  1191 	TInt64 randomNumber = Math::Rand(iSeed);
       
  1192 	randomNumber <<= KIntegerConstant32;
       
  1193 	randomNumber += Math::Rand(iSeed);
       
  1194 	TBuf8<KIntegerConstant33> key;
       
  1195 	key.Zero();
       
  1196 	key.AppendNum(time.Int64(), EHex);
       
  1197 	key.Append(_L8(":"));
       
  1198 	key.AppendNum(randomNumber, EHex);
       
  1199 	
       
  1200 	Hash(key, aNonce);
       
  1201 	GBA_TRACE_DEBUG(("CHTTPFilterGBA::GenerateCNonce--"));
       
  1202 	}
       
  1203 
       
  1204 // -----------------------------------------------------------------------------
       
  1205 // CHTTPFilterGBA::RequestUriLC
       
  1206 // Returns requested URI in form that can be used in uri field.
       
  1207 // This code comes from 
       
  1208 // Application-protocols/http/httpclient/chttpclienthandler.cpp.
       
  1209 // -----------------------------------------------------------------------------
       
  1210 //
       
  1211 RString CHTTPFilterGBA::RequestUriL( RHTTPTransaction& aTransaction )
       
  1212     {
       
  1213     GBA_TRACE_DEBUG(("CHTTPFilterGBA::RequestUriL++"));
       
  1214     TBool useProxy( EFalse );
       
  1215     THTTPHdrVal useProxyHdr;
       
  1216     RStringF proxyUsage = iStringPool.StringF( HTTP::EProxyUsage, RHTTPSession::GetTable() );
       
  1217     RHTTPRequest request = aTransaction.Request();
       
  1218     const TUriC8& uri = request.URI();
       
  1219     RStringF scheme = iStringPool.OpenFStringL( uri.Extract( EUriScheme ) );
       
  1220     CleanupClosePushL<RStringF>( scheme );
       
  1221     CUri8* uriToUse = CUri8::NewLC( uri );
       
  1222 
       
  1223     if( aTransaction.Session().ConnectionInfo().Property( proxyUsage, useProxyHdr ) )
       
  1224         {
       
  1225 	    // Is a proxy being used?
       
  1226         useProxy = ( useProxyHdr.StrF().Index(RHTTPSession::GetTable()) == HTTP::EUseProxy );
       
  1227         }
       
  1228 
       
  1229 	if( !useProxy || (useProxy && scheme.Index(RHTTPSession::GetTable()) == HTTP::EHTTPS ))
       
  1230 		{
       
  1231 		// Not going via a proxy - need to remove the scheme and authority parts
       
  1232 		uriToUse->RemoveComponentL( EUriScheme );
       
  1233 		uriToUse->RemoveComponentL( EUriHost );	// this also removes the userinfo + port
       
  1234 		}
       
  1235 
       
  1236     RString uriStr = iStringPool.OpenStringL( uriToUse->Uri().UriDes()  );
       
  1237 
       
  1238     CleanupStack::PopAndDestroy( uriToUse );
       
  1239     CleanupStack::PopAndDestroy( &scheme );
       
  1240     GBA_TRACE_DEBUG(("CHTTPFilterGBA::RequestUriL--"));
       
  1241     return uriStr;    
       
  1242     }
       
  1243 
       
  1244 // -----------------------------------------------------------------------------
       
  1245 // CHTTPFilterGBA::CheckQop
       
  1246 //
       
  1247 // -----------------------------------------------------------------------------
       
  1248 //
       
  1249 TInt CHTTPFilterGBA::CheckQop( RHTTPHeaders& aHeaders,
       
  1250                                                 RStringF& aWwwAuthHeader,
       
  1251                                                 TInt aHeaderPart )
       
  1252     {
       
  1253     GBA_TRACE_DEBUG(("CHTTPFilterGBA::CheckQop++"));
       
  1254     THTTPHdrVal qopVal;
       
  1255     TInt retVal( EQopNone );
       
  1256     
       
  1257     if( !aHeaders.GetParam( aWwwAuthHeader, iQopStr, qopVal, aHeaderPart ) )
       
  1258         {
       
  1259         TPtrC8 qopBuf( qopVal.Str().DesC() );
       
  1260         TPtrC8 qopValue;
       
  1261         TInt comma;
       
  1262 
       
  1263         do
       
  1264             {
       
  1265             comma = qopBuf.Locate( ',' );
       
  1266             
       
  1267             if( comma != KErrNotFound )
       
  1268                 {
       
  1269                 qopValue.Set( qopBuf.Left(comma) );
       
  1270                 }
       
  1271             else
       
  1272                 {
       
  1273                 qopValue.Set( qopBuf );
       
  1274                 }
       
  1275 
       
  1276             if( !qopValue.CompareF(iQopAuthStr.DesC()) )
       
  1277                 {
       
  1278                 retVal |= EQopAuth;
       
  1279                 }
       
  1280             else if( !qopValue.CompareF(KQopAuthIntStr) )
       
  1281                 {
       
  1282                 retVal |= EQopAuthInt;
       
  1283                 }
       
  1284             
       
  1285             qopBuf.Set( qopBuf.Right(qopBuf.Length()-comma-1));
       
  1286             }while( comma != KErrNotFound );
       
  1287         }
       
  1288     GBA_TRACE_DEBUG(("CHTTPFilterGBA::CheckQop--"));    
       
  1289     return retVal;
       
  1290     }
       
  1291 
       
  1292 void CHTTPFilterGBA::DGetCredentialsFromPropertiesL( RHTTPTransaction& aTransaction )
       
  1293     {
       
  1294     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DGetCredentialsFromPropertiesL++"));
       
  1295     THTTPHdrVal usernameVal;
       
  1296     THTTPHdrVal passwordVal;
       
  1297     THTTPHdrVal realmVal;
       
  1298     THTTPHdrVal nonceVal;
       
  1299     THTTPHdrVal staleVal;
       
  1300     const TUriC8& uri = aTransaction.Request().URI();
       
  1301     RHTTPTransactionPropertySet propSet = aTransaction.PropertySet();
       
  1302     TBool staleAvail = propSet.Property( iStaleStr, staleVal );
       
  1303     
       
  1304     
       
  1305     if ( propSet.Property( iUsernameStr, usernameVal ) &&
       
  1306          propSet.Property( iPasswordStr, passwordVal ) &&
       
  1307          propSet.Property( iRealmStr, realmVal ) && 
       
  1308          propSet.Property( iNonceStr, nonceVal )
       
  1309           )
       
  1310         // if stale is TRUE we don't need to update credential
       
  1311         {
       
  1312         
       
  1313 
       
  1314         TInt pushCounter( 0 );
       
  1315         TInt cred = DFindCredentialsForURI( uri );
       
  1316         if ( cred != KErrNotFound )
       
  1317             {
       
  1318             // Remove old credentials from the list
       
  1319             DRemoveCredentialsFromList( cred );
       
  1320             }
       
  1321 
       
  1322         TPtrC8 uriPathPtr( uri.UriDes() );
       
  1323 
       
  1324         if ( uriPathPtr.LocateReverse( '/' ) > 0 )
       
  1325             {
       
  1326             uriPathPtr.Set( uriPathPtr.Left( uriPathPtr.LocateReverse( '/' ) ) );
       
  1327             }
       
  1328 
       
  1329         RStringF uriStr = iStringPool.OpenFStringL( uriPathPtr );
       
  1330         CleanupClosePushL( uriStr );
       
  1331         ++pushCounter;
       
  1332 
       
  1333         THTTPHdrVal opaqueVal;
       
  1334 
       
  1335         RString opaqueStr;
       
  1336         
       
  1337         if( !propSet.Property( iOpaqueStr, opaqueVal ) )
       
  1338             // this isn't a error case
       
  1339             {    
       
  1340             opaqueStr = iStringPool.OpenStringL( KNullDesC8 );
       
  1341             CleanupClosePushL<RString>( opaqueStr );
       
  1342             ++pushCounter;
       
  1343             }
       
  1344         else
       
  1345             {
       
  1346             opaqueStr = opaqueVal;
       
  1347             }
       
  1348        
       
  1349         THTTPHdrVal qopVal;
       
  1350 
       
  1351         if( !propSet.Property( iQopStr, qopVal ) )
       
  1352             // this isn't a error case
       
  1353             {
       
  1354             qopVal.SetInt( EQopNone );
       
  1355             }
       
  1356 
       
  1357       
       
  1358         THTTPHdrVal algVal;
       
  1359         if( !propSet.Property( iStringPool.StringF( HTTP::EAlgorithm, 
       
  1360                                            RHTTPSession::GetTable() ), algVal) )
       
  1361             {
       
  1362             algVal.SetInt( EAlgUnknown );
       
  1363             }
       
  1364         // Add credentials to the list from the transaction's properties
       
  1365        DAddCredentialsToListL( usernameVal.Str().Copy(), 
       
  1366                                 passwordVal.Str().Copy(),
       
  1367                                 realmVal.Str().Copy(), 
       
  1368                                 uriStr.Copy(), 
       
  1369                                 opaqueStr.Copy(), 
       
  1370                                 nonceVal.Str().Copy(),
       
  1371                                 qopVal.Int(),
       
  1372                                 algVal.Int()
       
  1373                                 );
       
  1374         // this is not the traditional way to pop and destroy elements
       
  1375         // but in this case this is the simplest one.
       
  1376         CleanupStack::PopAndDestroy( pushCounter ); // [opaqueVal,]uriStr
       
  1377         }
       
  1378   
       
  1379     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DGetCredentialsFromPropertiesL--"));
       
  1380     }
       
  1381 
       
  1382 
       
  1383 TInt CHTTPFilterGBA::DFindCredentialsForURI( const TUriC8& aURI )
       
  1384     {
       
  1385     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DFindCredentialsForURI++"));
       
  1386     // Check if any of the stored URIs are the beginning of the URI
       
  1387     // we're trying now. If they are, we can immediately attempt to
       
  1388     // re-use the existing credentials.
       
  1389     _LIT8 ( KSchemeEnd, "://" );
       
  1390     TInt count = iDCredentials.Count();
       
  1391 
       
  1392     for ( TInt cred = 0; cred < count; ++cred )
       
  1393         {
       
  1394         const TPtrC8& transDes = aURI.UriDes();
       
  1395         const TPtrC8& credDes =
       
  1396             iStringPool.StringF( iDCredentials[ cred ].iURI ).DesC();
       
  1397         TPtrC8 transNoSchemePtr( transDes );
       
  1398         TPtrC8 credNoSchemePtr( credDes );
       
  1399 
       
  1400         if ( transNoSchemePtr.Find( KSchemeEnd() ) > 0 )
       
  1401             {
       
  1402             transNoSchemePtr.Set( transNoSchemePtr.Mid( transNoSchemePtr.Find( KSchemeEnd ) ) );
       
  1403             }
       
  1404 
       
  1405         if ( credNoSchemePtr.Find( KSchemeEnd() ) > 0 )
       
  1406             {
       
  1407             credNoSchemePtr.Set( credNoSchemePtr.Mid( credNoSchemePtr.Find( KSchemeEnd ) ) );
       
  1408             }
       
  1409 
       
  1410         if ( transNoSchemePtr.Length() >= credNoSchemePtr.Length() )
       
  1411             {
       
  1412             // The URI is long enough, which is a good start.
       
  1413 
       
  1414             if ( transNoSchemePtr.Left( credNoSchemePtr.Length() ).Compare( credNoSchemePtr ) == 0 )
       
  1415                 {
       
  1416                 // The descriptors match. Things are looking good. In
       
  1417                 // the interests of paranoia, if we haven't matched
       
  1418                 // the entire URI, check that the character after the
       
  1419                 // match is '/'.
       
  1420                 if ( transNoSchemePtr.Length() == credNoSchemePtr.Length() )
       
  1421                     {
       
  1422                     GBA_TRACE_DEBUG_NUM("Found cred(1): %d", cred ); 
       
  1423                     GBA_TRACE_DEBUG("uri: ");
       
  1424                     GBA_TRACE_DEBUG(aURI.UriDes());
       
  1425                     return cred;
       
  1426                     }
       
  1427 
       
  1428                 else if ( transNoSchemePtr[ credNoSchemePtr.Length() ] == '/' )
       
  1429                     {
       
  1430                     GBA_TRACE_DEBUG_NUM("Found cred(2): %d", cred ); 
       
  1431                     GBA_TRACE_DEBUG("uri: ");
       
  1432                     GBA_TRACE_DEBUG(aURI.UriDes());
       
  1433                     return cred;
       
  1434                     }
       
  1435                 }
       
  1436             }
       
  1437         }
       
  1438     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DFindCredentialsForURI--"));
       
  1439     return KErrNotFound;
       
  1440     }
       
  1441 
       
  1442 
       
  1443 void CHTTPFilterGBA::DRemoveCredentialsFromList( TInt aCredId )
       
  1444     {
       
  1445     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DRemoveCredentialsFromList++"));
       
  1446     GBA_TRACE_DEBUG_NUM("DRemoveCredentialsFromList: %d", aCredId );
       
  1447 
       
  1448     TDCredentials& creds = iDCredentials[ aCredId ];
       
  1449     iStringPool.String( creds.iUser ).Close();
       
  1450     iStringPool.String( creds.iPassword ).Close();
       
  1451     iStringPool.StringF( creds.iURI ).Close();
       
  1452     iStringPool.String( creds.iRealm ).Close();
       
  1453     iStringPool.String( creds.iOpaque ).Close();
       
  1454     iStringPool.String( creds.iNonce ).Close();
       
  1455     iDCredentials.Remove( aCredId );
       
  1456     iDCredentials.Close();
       
  1457     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DRemoveCredentialsFromList--"));
       
  1458     }
       
  1459 
       
  1460 TInt CHTTPFilterGBA::DFindCredentials( const RString& aRealm,
       
  1461         const TUriC8& aURI )
       
  1462     {
       
  1463     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DFindCredentials++"));
       
  1464     TInt count = iDCredentials.Count();
       
  1465 
       
  1466     for ( TInt cred = 0; cred < count; ++cred )
       
  1467         {
       
  1468         if ( iDCredentials[ cred ].iRealm == aRealm )
       
  1469             {
       
  1470             TUriParser8 parser;
       
  1471             parser.Parse( iStringPool.StringF( iDCredentials[ cred ].iURI ).DesC() );
       
  1472 
       
  1473             if ( !parser.Compare( aURI, EUriHost ) &&
       
  1474                  ( ( !parser.Compare( aURI, EUriPort ) )
       
  1475                    || ( !parser.IsPresent( EUriPort ) &&
       
  1476                         !aURI.IsPresent( EUriPort ) ) ) )
       
  1477                 {                
       
  1478                 GBA_TRACE_DEBUG_NUM("Found cred(3): %d", cred );
       
  1479                 return cred;
       
  1480                 }
       
  1481             }
       
  1482         }
       
  1483     GBA_TRACE_DEBUG(("CHTTPFilterGBA::DFindCredentials--"));
       
  1484     return KErrNotFound;
       
  1485     }
       
  1486 
       
  1487 
       
  1488 void CHTTPFilterGBA::BootstrapComplete( TInt aError )
       
  1489 {
       
  1490     GBA_TRACE_DEBUG(("CHTTPFilterGBA::BootstrapComplete--"));
       
  1491     if( aError == KErrNone)
       
  1492         {
       
  1493         iBootstrapPending = EFalse;
       
  1494         iHaveGbaBootstrapCredentials = ETrue;
       
  1495         }
       
  1496     else
       
  1497         {
       
  1498         iBootstrapPending = EFalse;
       
  1499         iHaveGbaBootstrapCredentials = EFalse;
       
  1500         }
       
  1501     iBootstrapWait.AsyncStop();
       
  1502 }
       
  1503 
       
  1504 //EOF
       
  1505