gba/gbaserver/src/dataretriever.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
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 bootstrap and data retriever
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32math.h> 
       
    20 #include <hash.h>
       
    21 #include <commdb.h>
       
    22 #include <es_enum.h>
       
    23 #include <centralrepository.h>
       
    24 #include <cmconnectionmethodext.h>
       
    25 #include <cmconnectionmethoddef.h>
       
    26 #include <cmpluginpacketdatadef.h>
       
    27 #include <cmdestinationext.h>
       
    28 #include <http/thttpevent.h>
       
    29 #include "dataretriever.h"
       
    30 #include "GbaCommon.h"
       
    31 #include "GBALogger.h"
       
    32 #include "bootstrap.h"	 
       
    33 
       
    34 _LIT8(KUserAgent,"S60 GBA 1.0");
       
    35 _LIT8(KAccept,"*/*");
       
    36 _LIT8(KNCVal_2, ":00000001:");
       
    37 _LIT8(Kfopaque,"");
       
    38 _LIT8(Kfalgo,"AKAv1-MD5");
       
    39 _LIT8(Kalgorithm,"algorithm");
       
    40 _LIT8(formatStr, "%02x");
       
    41 _LIT8(KAuthInt,"auth-int");
       
    42 _LIT8(KAuts,"auts");
       
    43 _LIT8(KHTTPAuthInfo,"Authentication-Info");
       
    44 _LIT8(KMD5HashofEmpty,"d41d8cd98f00b204e9800998ecf8427e");
       
    45 _LIT8(KClose, "Close");
       
    46 _LIT(KColon, ":");
       
    47 
       
    48 
       
    49 //Constants
       
    50 const TInt KNumber3 = 3;
       
    51 const TInt KNumber5 = 5;
       
    52 const TInt KNumber8 = 8;
       
    53 const TInt KNumber32 = 32;
       
    54 const TInt KNumber33 = 33;
       
    55 const TInt KNumber34 = 34;
       
    56 // Length of a digest hash when represented in hex
       
    57 const TInt KHashLength = 32;
       
    58 // Length of a digest hash before converting to hex.
       
    59 const TInt KRawHashLength = 16;
       
    60 const TInt KMaxRequestBuffer = 255;
       
    61 const TInt KAlgLength = 40;
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // CDataRetriever::NewL()
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CDataRetriever* CDataRetriever::NewL( MBootstrapCallBack* aBootstrapCallBack )
       
    68     {
       
    69     CDataRetriever* self = NewLC( aBootstrapCallBack );
       
    70     CleanupStack::Pop( self );
       
    71     return self;
       
    72     }
       
    73 
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // CDataRetriever::NewLC()
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 CDataRetriever* CDataRetriever::NewLC( MBootstrapCallBack* aBootstrapCallBack )
       
    80     {
       
    81     CDataRetriever* self = new (ELeave) CDataRetriever( aBootstrapCallBack ) ;
       
    82     CleanupStack::PushL( self );
       
    83     self->ConstructL();
       
    84     return self;
       
    85     }
       
    86 
       
    87 
       
    88 // ---------------------------------------------------------------------------
       
    89 // CDataRetriever::CDataRetriever()
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 CDataRetriever::CDataRetriever( MBootstrapCallBack* aBootstrapCallBack ) 
       
    93     : iBootstrapCallBack( aBootstrapCallBack ) 
       
    94     { 
       
    95     }
       
    96     
       
    97     
       
    98 // ---------------------------------------------------------------------------
       
    99 // CDataRetriever::ConstructL()
       
   100 // ---------------------------------------------------------------------------
       
   101 //
       
   102 void CDataRetriever::ConstructL()
       
   103     {
       
   104     iHttpHandler = C3GPPBootstrapHttpHandler::NewL( this, iBootstrapCallBack );
       
   105     iInternalState = EReadyForRequest;
       
   106     iCmManagerExt.OpenL();
       
   107     }
       
   108 
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 // CDataRetriever::~CDataRetriever()
       
   112 // ---------------------------------------------------------------------------
       
   113 //
       
   114 CDataRetriever::~CDataRetriever()
       
   115     {
       
   116     GBA_TRACE_DEBUG(("CDataRetriever::~CDataRetriever"));
       
   117     
       
   118     delete iHttpHandler;
       
   119     iHTTPTransaction.Close();
       
   120     iHTTPSession.Close();
       
   121     iConnection.Close();
       
   122     iSockServ.Close();
       
   123     iCmManagerExt.Close();
       
   124     
       
   125     if ( iInternalState == EMakeRequestCalled )
       
   126         {
       
   127         GBA_TRACE_DEBUG(("CDataRetriever::~CDataRetriever EMakeRequestCalled"));
       
   128         User::RequestComplete(iCallerRequestStatus, KErrCancel);
       
   129         }
       
   130     
       
   131     GBA_TRACE_DEBUG(("CDataRetriever::~CDataRetriever End"));
       
   132     }
       
   133 
       
   134 // ---------------------------------------------------------------------------
       
   135 // CDataRetriever::EventRequestCompletedL()
       
   136 // ---------------------------------------------------------------------------
       
   137 //
       
   138 void CDataRetriever::EventRequestCompletedL(TInt aErrorCode)
       
   139     {
       
   140     GBA_TRACE_DEBUG(("CDataRetriever::EventRequestCompletedL enter"));
       
   141     
       
   142     if ( iInternalState == EMakeRequestCalled )
       
   143         {
       
   144         GBA_TRACE_DEBUG(("CDataRetriever::EventRequestCompletedL EMakeRequestCalled"));
       
   145 
       
   146         TRAPD( err, iBootstrapCallBack->CompleteBootStrappingL( aErrorCode ) );
       
   147         if( err == KErrNone )
       
   148             User::RequestComplete(iCallerRequestStatus,aErrorCode);
       
   149         else
       
   150             User::RequestComplete(iCallerRequestStatus, err);
       
   151         // Get Ready for new request
       
   152         iHttpHandler->Reset();
       
   153         iHTTPTransaction.Close();
       
   154         iHTTPSession.Close();
       
   155         iConnection.Close();
       
   156         iSockServ.Close();
       
   157         iInternalState = EReadyForRequest;
       
   158         }
       
   159     }
       
   160 
       
   161 
       
   162 // ---------------------------------------------------------------------------
       
   163 // CDataRetriever::CancelRequest()
       
   164 // ---------------------------------------------------------------------------
       
   165 //
       
   166 void CDataRetriever::CancelRequest()
       
   167     {
       
   168     GBA_TRACE_DEBUG(("CDataRetriever::CancelRequest"));
       
   169     if ( iInternalState == EMakeRequestCalled )
       
   170         {        
       
   171         iInternalState = EReadyForRequest;
       
   172         iHttpHandler->Reset();
       
   173         iHTTPTransaction.Close();
       
   174         iHTTPSession.Close();
       
   175         iConnection.Close();
       
   176         iSockServ.Close();
       
   177         User::RequestComplete( iCallerRequestStatus, KErrCancel );
       
   178         }
       
   179     }
       
   180     
       
   181     
       
   182 // ---------------------------------------------------------------------------
       
   183 // CDataRetriever::MakeRequestL()
       
   184 // ---------------------------------------------------------------------------
       
   185 //
       
   186 void CDataRetriever::MakeRequestL(
       
   187                  TRequestStatus* aRequestStatus,
       
   188                  const TDesC8& aIdentity,
       
   189                  const TDesC8& aRealm,
       
   190                  const TDesC8& aBsfUri,
       
   191                  const TDesC8& aReferrerNAFUri,
       
   192                  const TInt& aIAPID )
       
   193     {
       
   194     GBA_TRACE_BEGIN(); 
       
   195     
       
   196     if ( iInternalState != EReadyForRequest )
       
   197         {        
       
   198         User::LeaveIfError( KErrInUse );
       
   199         }
       
   200     
       
   201     iCallerRequestStatus = aRequestStatus;
       
   202   
       
   203     SetupSessionL( aIAPID );
       
   204 
       
   205     // Add headers appropriate to all methods
       
   206     TUriParser8 URIParse; 
       
   207 
       
   208     User::LeaveIfError( URIParse.Parse( aBsfUri ) );
       
   209 
       
   210     iHTTPTransaction = iHTTPSession.OpenTransactionL( URIParse, *iHttpHandler );
       
   211     RHTTPHeaders hdr = iHTTPTransaction.Request().GetHeaderCollection();
       
   212     
       
   213     GBA_TRACE_DEBUG(URIParse.Extract(EUriHost) );
       
   214          
       
   215     SetHeaderL(hdr,HTTP::EHost, URIParse.Extract(EUriHost) );     
       
   216     SetHeaderL(hdr,HTTP::EUserAgent, KUserAgent);
       
   217     SetHeaderL(hdr,HTTP::EAccept, KAccept);     
       
   218     SetHeaderL(hdr,HTTP::EReferer, aReferrerNAFUri);
       
   219     
       
   220     SetHeaderL(hdr, HTTP::EConnection, KClose);
       
   221   
       
   222     TBuf8<KMaxRequestBuffer> bufAuth;
       
   223     bufAuth.Copy(_L8("Digest username=\""));
       
   224     bufAuth.Append(aIdentity);
       
   225     bufAuth.Append(_L8("\", realm=\""));
       
   226     
       
   227     bufAuth.Append(aRealm);
       
   228     bufAuth.Append(_L8("\", nonce=\"\", uri=\"/\", response=\"\""));
       
   229 
       
   230     GBA_TRACE_DEBUG(bufAuth);
       
   231     SetHeaderL(hdr,HTTP::EAuthorization,bufAuth);
       
   232     
       
   233     iHTTPTransaction.SubmitL();    
       
   234     iInternalState = EMakeRequestCalled;
       
   235     GBA_TRACE_END();
       
   236     }
       
   237 
       
   238 // ---------------------------------------------------------------------------
       
   239 // CDataRetriever::SetHeaderL()
       
   240 // ---------------------------------------------------------------------------
       
   241 //
       
   242 void CDataRetriever::SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue)
       
   243     {
       
   244     RStringF valStr = iHTTPSession.StringPool().OpenFStringL(aHdrValue);
       
   245     THTTPHdrVal val(valStr);
       
   246     aHeaders.SetFieldL(iHTTPSession.StringPool().StringF(aHdrField,RHTTPSession::GetTable()), val);
       
   247     valStr.Close();
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------------------------
       
   251 // CDataRetriever::SetupSessionL()
       
   252 // Establish a connection for bootstrapping
       
   253 // ---------------------------------------------------------------------------
       
   254 //
       
   255 void CDataRetriever::SetupSessionL( const TInt& aIAPID )
       
   256     {
       
   257     GBA_TRACE_DEBUG(("CDataRetriever::SetupSession"));
       
   258     // check that sockserver is available
       
   259 
       
   260     User::LeaveIfError(iSockServ.Connect() );
       
   261     GBA_TRACE_DEBUG(("Socket server connected")); 
       
   262 
       
   263     // check that connection is possible
       
   264     User::LeaveIfError(iConnection.Open(iSockServ) );
       
   265     GBA_TRACE_DEBUG(("Connection opened")); 
       
   266     
       
   267     if ( !ValidateGivenIAPIDL( aIAPID ) )
       
   268         {	
       
   269         GBA_TRACE_DEBUG(("No valid iapid from user")); 
       
   270         TConnSnapPref snapPref;
       
   271         TUint32 snapid = GetInternetDestIDL();
       
   272         GBA_TRACE_DEBUG_NUM(("the chosen snap id is %d"), snapid ); 
       
   273         snapPref.SetSnap( snapid );
       
   274         TInt err = iConnection.Start( snapPref );
       
   275         
       
   276         if ( err != KErrNone )
       
   277             {
       
   278             GBA_TRACE_DEBUG_NUM(("internet nap error is %d"), err ); 
       
   279             TCommDbConnPref connPref;
       
   280             connPref.SetDialogPreference( ECommDbDialogPrefPrompt );
       
   281             User::LeaveIfError( iConnection.Start( connPref ) );
       
   282             }    
       
   283        }
       
   284     else
       
   285         {
       
   286         GBA_TRACE_DEBUG(("User gives valid iapid go with it"));
       
   287         //given iapid is valid, go with it
       
   288         TCommDbConnPref connPref;
       
   289         connPref.SetDirection( ECommDbConnectionDirectionOutgoing );
       
   290         
       
   291         //No dialog present
       
   292         connPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
   293         connPref.SetIapId( aIAPID );	
       
   294          
       
   295         User::LeaveIfError( iConnection.Start( connPref ) );
       
   296         }
       
   297     
       
   298     GBA_TRACE_DEBUG(("Access point selection done!"));       
       
   299 
       
   300     GBA_TRACE_DEBUG(("CDataRetriever::SetupSession, connect choosen is done "));
       
   301     
       
   302     iHTTPSession.OpenL();
       
   303 	    
       
   304     //GBA Http  filter gets loaded into to http session when session is opened
       
   305 	//Remove GBA http filter from http session iHTTPSession
       
   306     //Reason: Ub interface should not have the User-Agent string "3gpp-gba"
       
   307 	RStringF filterName = iHTTPSession.StringPool().OpenFStringL( KHTTPFilterGBAName );
       
   308     CleanupClosePushL<RStringF>( filterName );
       
   309     iHTTPSession.FilterCollection().RemoveFilter( filterName );
       
   310     CleanupStack::PopAndDestroy( &filterName );
       
   311 	
       
   312     GBA_TRACE_DEBUG(("Session opened"));  
       
   313     
       
   314     //Set selected access point.
       
   315     RStringPool strPool = iHTTPSession.StringPool();
       
   316     RHTTPConnectionInfo httpconnInfo = iHTTPSession.ConnectionInfo();
       
   317     
       
   318     httpconnInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketServ,
       
   319             RHTTPSession::GetTable() ), THTTPHdrVal (iSockServ.Handle()) );
       
   320     
       
   321     TInt connPtr = REINTERPRET_CAST(TInt, &iConnection);
       
   322 
       
   323     httpconnInfo.SetPropertyL ( strPool.StringF(HTTP::EHttpSocketConnection,
       
   324               RHTTPSession::GetTable() ), THTTPHdrVal (connPtr) );
       
   325     
       
   326     //if 2G interface and cert is untrusted, surpress the warning dialog
       
   327     if ( iBootstrapCallBack->InterfaceIs2G() )
       
   328         {
       
   329         //surpress the warning dialog
       
   330         httpconnInfo.SetPropertyL ( strPool.StringF(HTTP::ESecureDialog,
       
   331               RHTTPSession::GetTable() ),strPool.StringF(HTTP::EDialogNoPrompt,
       
   332               RHTTPSession::GetTable() )  );
       
   333         }
       
   334   
       
   335     GBA_TRACE_DEBUG(("SetupSession done")); 
       
   336     }
       
   337 
       
   338 
       
   339 // ---------------------------------------------------------------------------
       
   340 // CDataRetriever::ValidateGivenIAPIDL()
       
   341 // ---------------------------------------------------------------------------
       
   342 //
       
   343 TBool CDataRetriever::ValidateGivenIAPIDL( const TInt& aIAPID )
       
   344     {
       
   345     using namespace CMManager;
       
   346     GBA_TRACE_DEBUG((" start valid iapid given by user"));
       
   347     //aIAPID == -1 selected default accesspoint
       
   348     if ( aIAPID == -1 )
       
   349         {
       
   350         return EFalse;
       
   351         }
       
   352     else
       
   353         {
       
   354         TInt CleanupCounter = 0;
       
   355    
       
   356         RArray<TUint32> destIdArray;
       
   357         CleanupClosePushL( destIdArray );
       
   358         CleanupCounter++;
       
   359         iCmManagerExt.AllDestinationsL( destIdArray );
       
   360 
       
   361         for ( TInt i = 0; i< destIdArray.Count(); i++ )
       
   362            {
       
   363            RCmDestinationExt dest = iCmManagerExt.DestinationL( destIdArray[i] );
       
   364            CleanupClosePushL( dest );
       
   365            CleanupCounter++;
       
   366          
       
   367            for ( TInt j=0; j < dest.ConnectionMethodCount(); j++ )
       
   368               {
       
   369            
       
   370               TUint32 iapId = dest. ConnectionMethodL(j).GetIntAttributeL( ECmIapId );
       
   371               
       
   372               if ( iapId == aIAPID )
       
   373                   {
       
   374                   GBA_TRACE_DEBUG((" IAPID matches !!"));
       
   375                   CleanupStack::PopAndDestroy( CleanupCounter );
       
   376                   return ETrue;
       
   377                   }
       
   378               }
       
   379              
       
   380            CleanupStack::PopAndDestroy( &dest ); //dest
       
   381            CleanupCounter--; // dest
       
   382            }
       
   383         GBA_TRACE_DEBUG((" search is over no matching IAPID!!"));
       
   384         CleanupStack::PopAndDestroy( CleanupCounter );
       
   385         return EFalse;    
       
   386         }    
       
   387     }
       
   388 
       
   389 // ---------------------------------------------------------------------------
       
   390 // CDataRetriever::QueryResponseValueL()
       
   391 // ---------------------------------------------------------------------------
       
   392 //
       
   393 HBufC8* CDataRetriever::QueryResponseValueL() 
       
   394     {
       
   395     return iHttpHandler->GetResponse();
       
   396     } 
       
   397 
       
   398 // ---------------------------------------------------------------------------
       
   399 // CDataRetriever::GetInternetDestIDL()
       
   400 // ---------------------------------------------------------------------------
       
   401 //
       
   402 TUint32 CDataRetriever::GetInternetDestIDL()
       
   403     {
       
   404     using namespace CMManager;
       
   405     GBA_TRACE_DEBUG((" Get the Dest ID of Internet"));
       
   406 
       
   407     TInt CleanupCounter = 0;
       
   408    
       
   409     RArray<TUint32> destIdArray;
       
   410     CleanupClosePushL( destIdArray );
       
   411     CleanupCounter++;
       
   412     iCmManagerExt.AllDestinationsL( destIdArray );
       
   413 
       
   414     for ( TInt i = 0; i< destIdArray.Count(); i++ )
       
   415          {
       
   416          RCmDestinationExt dest = iCmManagerExt.DestinationL( destIdArray[i] );
       
   417          CleanupClosePushL( dest );
       
   418          CleanupCounter++;
       
   419          
       
   420          if ( dest.MetadataL( ESnapMetadataInternet ) )
       
   421              {
       
   422              GBA_TRACE_DEBUG_NUM((" found the internet dest id = %d"), destIdArray[i] );
       
   423              
       
   424              TUint32 desID = destIdArray[i];
       
   425              CleanupStack::PopAndDestroy( CleanupCounter );
       
   426              return desID; 
       
   427              }
       
   428              
       
   429          CleanupStack::PopAndDestroy( &dest );
       
   430          CleanupCounter--; // dest
       
   431          }
       
   432     GBA_TRACE_DEBUG(("not found the internet dest id") );
       
   433     CleanupStack::PopAndDestroy( CleanupCounter );
       
   434     return NULL;
       
   435 	}
       
   436     
       
   437 
       
   438 // C3GPPBootstrapHttpHandler 
       
   439 // -----------------------------------------------------------------------------
       
   440 // C3GPPBootstrapHttpHandler::ConstructL()
       
   441 // -----------------------------------------------------------------------------
       
   442 //
       
   443 void C3GPPBootstrapHttpHandler::ConstructL()
       
   444     {
       
   445     iResponse=HBufC8::NewL(KMaxBootstrapRespLen);
       
   446     iMD5Calculator =  CMD5::NewL(); 
       
   447     iSucceeded=EFalse;
       
   448     }
       
   449 
       
   450 // -----------------------------------------------------------------------------
       
   451 // C3GPPBootstrapHttpHandler::C3GPPBootstrapHttpHandler()
       
   452 // -----------------------------------------------------------------------------
       
   453 //
       
   454 C3GPPBootstrapHttpHandler::C3GPPBootstrapHttpHandler( MHttpRequestEvents* aEventSink, M3GPPAuthenticationCallback* aDataRetrieverCallBack )
       
   455         : iEventSink ( aEventSink ), iDataRetrieverCallBack ( aDataRetrieverCallBack )
       
   456     {
       
   457     }
       
   458 
       
   459 
       
   460 // -----------------------------------------------------------------------------
       
   461 // C3GPPBootstrapHttpHandler::~C3GPPBootstrapHttpHandler()
       
   462 // -----------------------------------------------------------------------------
       
   463 //
       
   464 C3GPPBootstrapHttpHandler::~C3GPPBootstrapHttpHandler()
       
   465     {
       
   466     GBA_TRACE_DEBUG(("C3GPPBootstrapHttpHandler::~C3GPPBootstrapHttpHandler()"));
       
   467     Reset();
       
   468 	delete iResponse;
       
   469 	delete iMD5Calculator;
       
   470     GBA_TRACE_DEBUG(("C3GPPBootstrapHttpHandler::~C3GPPBootstrapHttpHandler() end"));
       
   471     }
       
   472 
       
   473 
       
   474 
       
   475 // -----------------------------------------------------------------------------
       
   476 // C3GPPBootstrapHttpHandler::Reset()
       
   477 // -----------------------------------------------------------------------------
       
   478 //
       
   479 void C3GPPBootstrapHttpHandler::Reset()
       
   480     {
       
   481     // close strings in string pool if they were opened 
       
   482     iUsername.Close();
       
   483     iPassword.Close();
       
   484     iNonce.Close();
       
   485     iCnonce.Close();
       
   486     iUri.Close();
       
   487     iRealm.Close();
       
   488     iMethod.Close();
       
   489     }
       
   490 
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 // C3GPPBootstrapHttpHandler::NewLC()
       
   494 // -----------------------------------------------------------------------------
       
   495 //
       
   496 C3GPPBootstrapHttpHandler* C3GPPBootstrapHttpHandler::NewLC( MHttpRequestEvents* aEventSink, 
       
   497                                                              M3GPPAuthenticationCallback* aDataRetrieverCallBack )
       
   498     {
       
   499     C3GPPBootstrapHttpHandler* me = new(ELeave)C3GPPBootstrapHttpHandler( aEventSink, aDataRetrieverCallBack );
       
   500     CleanupStack::PushL(me);
       
   501     me->ConstructL();
       
   502     return me;
       
   503     }
       
   504 
       
   505 
       
   506 // -----------------------------------------------------------------------------
       
   507 // C3GPPBootstrapHttpHandler::NewL()
       
   508 // -----------------------------------------------------------------------------
       
   509 //
       
   510 C3GPPBootstrapHttpHandler* C3GPPBootstrapHttpHandler::NewL( MHttpRequestEvents* aEventSink ,
       
   511                                                             M3GPPAuthenticationCallback* aDataRetrieverCallBack )
       
   512     {
       
   513     C3GPPBootstrapHttpHandler* me = NewLC(aEventSink, aDataRetrieverCallBack );
       
   514     CleanupStack::Pop(me);
       
   515     return me;
       
   516     }
       
   517 
       
   518 
       
   519 
       
   520 // -----------------------------------------------------------------------------
       
   521 // C3GPPBootstrapHttpHandler::MHFRunL()
       
   522 // -----------------------------------------------------------------------------
       
   523 //
       
   524 void C3GPPBootstrapHttpHandler::MHFRunL( RHTTPTransaction aTransaction, const THTTPEvent& aEvent )
       
   525     {
       
   526     GBA_TRACE_DEBUG_NUM(("MHFRunL received event %d"), aEvent.iStatus );
       
   527     
       
   528     switch (aEvent.iStatus)
       
   529        {
       
   530        case THTTPEvent::EGotResponseHeaders:
       
   531           {
       
   532           // HTTP response headers have been received. 
       
   533           // We can determine now if there is going to be a response body to save.
       
   534           GBA_TRACE_DEBUG(("THTTPEvent::EGotResponseHeaders"));
       
   535           RHTTPResponse resp = aTransaction.Response();
       
   536           TInt status = resp.StatusCode();
       
   537           
       
   538           RStringF statusStr = resp.StatusText();
       
   539       
       
   540           // 401 = we received a authorization challenge
       
   541           if ( status == HTTPStatus::EUnauthorized )
       
   542              {
       
   543              // resubmit the transaction and hope for the best
       
   544              TInt result = HandleAuthorizationChallengeL(aTransaction, aEvent);
       
   545              if( result == KErrNone )
       
   546                  {
       
   547                  aTransaction.Cancel();
       
   548                  aTransaction.SubmitL();
       
   549                  }
       
   550              else
       
   551                  {
       
   552                  aTransaction.Cancel();
       
   553                  iEventSink->EventRequestCompletedL( result );
       
   554                  }
       
   555              //a new request with password is sent.
       
   556              return;
       
   557              }
       
   558           TInt responseBodySize = 0;
       
   559       
       
   560           // 200 received, succeeded with body
       
   561           if ( resp.HasBody() && ( status == HTTPStatus::EOk ) )
       
   562               {
       
   563               MHTTPDataSupplier *respbody = resp.Body();
       
   564               if ( respbody )
       
   565                   {
       
   566                   responseBodySize = respbody->OverallDataSize();
       
   567                   GBA_TRACE_DEBUG_NUM(("Response body size is %d"), responseBodySize );
       
   568                   iSucceeded = ETrue;
       
   569                   }
       
   570               }
       
   571           //Reallocate iResponse buffer size if the response size is greater than KMaxBootstrapRespLen
       
   572           if( responseBodySize > KMaxBootstrapRespLen )
       
   573               iResponse = iResponse->ReAllocL( responseBodySize );
       
   574           // we take this opportunity to reset our own buffers
       
   575           TPtr8 ptrResp(iResponse->Des());
       
   576           
       
   577           ptrResp.Zero();
       
   578           } 
       
   579           break;
       
   580       
       
   581       case THTTPEvent::EGotResponseBodyData:
       
   582           {
       
   583           GBA_TRACE_DEBUG(("THTTPEvent::EGotResponseBodyData"));
       
   584           // Get the body data supplier
       
   585           iRespBody = aTransaction.Response().Body();
       
   586       
       
   587           // Some (more) body data has been received (in the HTTP response)
       
   588           // Append to the output file if we're saving responses
       
   589           TPtr8 ptrResp(iResponse->Des());
       
   590           
       
   591           TPtrC8 bodyData;
       
   592           TBool lastChunk = EFalse;
       
   593                     
       
   594           while ( !lastChunk ) 
       
   595               {
       
   596               GBA_TRACE_DEBUG(("THTTPEvent::EGotResponseBodyData in loop"));
       
   597               lastChunk = iRespBody->GetNextDataPart( bodyData );
       
   598               
       
   599               //Issue with formatting string with a special character
       
   600               //GBA_TRACE_DEBUG( bodyData );
       
   601               if ( bodyData.Length() <= ( ptrResp.MaxLength() - ptrResp.Length() ) )
       
   602                   { 
       
   603                   ptrResp.Append( bodyData );  
       
   604                   }
       
   605               else
       
   606                   {
       
   607                   break;  
       
   608                   }
       
   609               } 
       
   610       
       
   611           GBA_TRACE_DEBUG_NUM(("Response body received size is %d"), iResponse->Length() );
       
   612           // Done with that bit of body data
       
   613           iRespBody->ReleaseData();
       
   614           } 
       
   615           break;
       
   616           
       
   617       case THTTPEvent::EResponseComplete:
       
   618           {
       
   619           GBA_TRACE_DEBUG(("THTTPEvent::EResponseComplete"));
       
   620           // The transaction's response is complete
       
   621           } 
       
   622           break;
       
   623           
       
   624       case THTTPEvent::ESucceeded:
       
   625          {
       
   626          GBA_TRACE_DEBUG(("THTTPEvent::ESucceeded || KErrDisconnected"));
       
   627          if ( iSucceeded )
       
   628              {
       
   629               // verify authrsp
       
   630               User::LeaveIfError(CheckRspAuthL(aTransaction));
       
   631               
       
   632               //Set it back
       
   633               iSucceeded=EFalse;
       
   634               
       
   635               GBA_TRACE_DEBUG(("THTTPEvent::ESucceeded || KErrDisconnected 1"));
       
   636               iEventSink->EventRequestCompletedL(KErrNone); 
       
   637              }
       
   638          else
       
   639             {
       
   640             iEventSink->EventRequestCompletedL( KErrDisconnected );        
       
   641             GBA_TRACE_DEBUG(("Connection was closed"));
       
   642             }
       
   643         } 
       
   644         break;
       
   645         
       
   646      case THTTPEvent::EFailed:
       
   647         {
       
   648         GBA_TRACE_DEBUG(("THTTPEvent::EFailed"));
       
   649         RHTTPResponse resp = aTransaction.Response();
       
   650         TInt status = resp.StatusCode();
       
   651         GBA_TRACE_DEBUG_NUM( ("http StatusCode : %d "), status );
       
   652         iEventSink->EventRequestCompletedL( KErrUnknown );
       
   653         } 
       
   654         break;
       
   655      
       
   656      //The transaction is being cancelled. An outgoing event. 
       
   657      case THTTPEvent::ECancel:
       
   658         {
       
   659         GBA_TRACE_DEBUG(("THTTPEvent::ECancel"));
       
   660         aTransaction.Cancel();
       
   661         } 
       
   662         break;
       
   663 
       
   664      // this warning can come when going through proxies
       
   665      case THTTPEvent::ERedirectedTemporarily:
       
   666         break;
       
   667         
       
   668      default:
       
   669          {
       
   670          GBA_TRACE_DEBUG_NUM(("Failed with HTTP event event: %d "),aEvent.iStatus );
       
   671          if( aEvent.iStatus < 0 )
       
   672              {
       
   673              // close off the transaction if it's an error
       
   674              aTransaction.Cancel();
       
   675              iEventSink->EventRequestCompletedL( aEvent.iStatus );
       
   676              }
       
   677          } 
       
   678          break;
       
   679        }
       
   680     }
       
   681 
       
   682 
       
   683 // -----------------------------------------------------------------------------
       
   684 // C3GPPBootstrapHttpHandler::MHFRunError()
       
   685 // -----------------------------------------------------------------------------
       
   686 // 
       
   687 TInt C3GPPBootstrapHttpHandler::MHFRunError(TInt aError, RHTTPTransaction /*aTransaction*/, const THTTPEvent& aEvent)
       
   688     {
       
   689     GBA_TRACE_DEBUG_NUM(("MHFRunError called with error code = %d"), aError);    
       
   690     GBA_TRACE_DEBUG_NUM(("MHFRunError called with http event = %d"),aEvent.iStatus );
       
   691     // tell caller that there was an error
       
   692     TRAPD(err, iEventSink->EventRequestCompletedL(aError));
       
   693     return err;
       
   694     }
       
   695   
       
   696 
       
   697 // -----------------------------------------------------------------------------
       
   698 // C3GPPBootstrapHttpHandler::HandleAuthorizationChallengeL()
       
   699 // -----------------------------------------------------------------------------
       
   700 // 
       
   701 TInt C3GPPBootstrapHttpHandler::HandleAuthorizationChallengeL( RHTTPTransaction aTransaction, const THTTPEvent& /*aEvent*/ )
       
   702     {
       
   703     GBA_TRACE_BEGIN();
       
   704     TInt pushCount = 0;
       
   705     RStringPool stringPool = aTransaction.Session().StringPool(); 
       
   706     RStringF wwwAuthHeader = stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
       
   707     RHTTPHeaders headers(aTransaction.Response().GetHeaderCollection());
       
   708     
       
   709     //find header which has digest algorithm and qop is auth-int
       
   710     TInt headerPart = FindHeaderPartToUseL( aTransaction );
       
   711 
       
   712     if ( headerPart == KErrNotFound )
       
   713         {
       
   714         return KErrArgument;
       
   715         }
       
   716 
       
   717     THTTPHdrVal authTypeParam;
       
   718     TInt error = headers.GetField( wwwAuthHeader, headerPart, authTypeParam );
       
   719   
       
   720     // If anything goes wrong, just stop. This will have the effect of
       
   721     // returning the error response from the server to the client.
       
   722     if ( error != KErrNone )
       
   723         {
       
   724         return error;     
       
   725         }
       
   726         
       
   727     TBool    haveUserPW = EFalse;
       
   728     RString  realm;
       
   729     RString  username;
       
   730     RString  password;
       
   731     RString  nonce;
       
   732     RString  algorithm;
       
   733     RString  resync;                  
       
   734   
       
   735     // Get realm value from response header
       
   736     THTTPHdrVal realmVal;
       
   737     error  = headers.GetParam( wwwAuthHeader, 
       
   738                            stringPool.StringF( HTTP::ERealm, RHTTPSession::GetTable() ), realmVal, headerPart ) ;
       
   739     if ( error != KErrNone )
       
   740         {
       
   741         return error;
       
   742         }
       
   743     
       
   744     realm = realmVal.Str();
       
   745     GBA_TRACE_DEBUG(("Realm:"));
       
   746     GBA_TRACE_DEBUG(realm.DesC());
       
   747     
       
   748     THTTPHdrVal nonceVal;
       
   749     //Get nonce value from response header
       
   750     // contain the RAND and AUTH
       
   751     error = headers.GetParam( stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
   752                               stringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable()),
       
   753                               nonceVal,
       
   754                               headerPart);
       
   755     if ( error != KErrNone )
       
   756         {
       
   757         return error;
       
   758         }
       
   759     
       
   760     nonce=nonceVal.Str();
       
   761     GBA_TRACE_DEBUG(("Nonce:"));
       
   762     GBA_TRACE_DEBUG(nonce.DesC());
       
   763   
       
   764     //Fetch algorithm type
       
   765     THTTPHdrVal algVal;  
       
   766     error = headers.GetParam( stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
   767                               stringPool.StringF(HTTP::EAlgorithm,RHTTPSession::GetTable()),
       
   768                               algVal,
       
   769                               headerPart);
       
   770     if ( error != KErrNone )
       
   771         {
       
   772         return error;
       
   773         }
       
   774     
       
   775     algorithm=algVal.Str();
       
   776     GBA_TRACE_DEBUG(("Algorithm:"));
       
   777     GBA_TRACE_DEBUG(algorithm.DesC());
       
   778     
       
   779     // If the SQN is out of range, Resync is required
       
   780     TBool resyncrequired = EFalse;
       
   781     
       
   782     //Get password from smart card
       
   783     //The smart card will first authenticate the nonce value 
       
   784     RStringF authType = authTypeParam.StrF(); 
       
   785     
       
   786     TRAP( error, haveUserPW = iDataRetrieverCallBack->GetCredentialsL( aTransaction.Request().URI(),
       
   787               realm, nonce, algorithm, username, password, resync, resyncrequired ) ) ;
       
   788     
       
   789     if ( error != KErrNone )
       
   790         {
       
   791         GBA_TRACE_DEBUG_NUM(("Get Gredentails failed with error %d"), error );
       
   792         return error;
       
   793         }
       
   794     
       
   795     if ( haveUserPW || resyncrequired )
       
   796         {
       
   797         CleanupClosePushL(username);
       
   798         pushCount++;
       
   799         CleanupClosePushL(password);
       
   800         pushCount++;       
       
   801         //Resync required
       
   802         if( resyncrequired )
       
   803             {
       
   804             CleanupClosePushL(resync);
       
   805             pushCount++;     
       
   806             }
       
   807         
       
   808         GBA_TRACE_DEBUG(("HandleAuthorizationChallengeL: received following credentials"));
       
   809         GBA_TRACE_DEBUG(("Realm:"));
       
   810         GBA_TRACE_DEBUG(realm.DesC());
       
   811         GBA_TRACE_DEBUG(("Username:"));
       
   812         GBA_TRACE_DEBUG(username.DesC());
       
   813         GBA_TRACE_DEBUG(("Password:"));
       
   814         GBA_TRACE_DEBUG_BINARY(password.DesC());
       
   815         GBA_TRACE_DEBUG(("Resync:"));
       
   816         GBA_TRACE_DEBUG_BINARY(resync.DesC());
       
   817         
       
   818         }
       
   819     else //No password and no resync required
       
   820         {
       
   821         CleanupStack::PopAndDestroy( pushCount ); 
       
   822         return KErrNotFound;  
       
   823         }
       
   824 
       
   825     // Encode the Username/Password
       
   826     switch ( authType.Index( RHTTPSession::GetTable() ) )
       
   827         {
       
   828         case HTTP::EDigest:
       
   829            {
       
   830            THTTPHdrVal requestUri;
       
   831            RHTTPTransactionPropertySet propSet = aTransaction.PropertySet();
       
   832            propSet.Property( stringPool.StringF(HTTP::EUri,RHTTPSession::GetTable()), requestUri );
       
   833            //save rsp auth calcuation
       
   834            //Save the string handle for rsp auth checking
       
   835            //Close the previous handle, then set new one
       
   836            iUsername.Close();
       
   837            iUsername = username.Copy();
       
   838            iPassword.Close();
       
   839            iPassword = password.Copy();
       
   840            iRealm.Close();
       
   841            iRealm = realm.Copy();
       
   842            iNonce.Close();
       
   843            iNonce = nonce.Copy();
       
   844            iUri.Close();
       
   845            iUri = requestUri.Str().Copy();
       
   846            
       
   847            TRAP ( error, EncodeDigestAuthL( username, password, aTransaction, headerPart, requestUri ) );
       
   848            GBA_TRACE_DEBUG(("After Encode Digest AuthL"));
       
   849            if ( error != KErrNone )
       
   850                {
       
   851                GBA_TRACE_DEBUG_NUM(("After Encode Digest AuthL error %d"), error );
       
   852                CleanupStack::PopAndDestroy( pushCount );
       
   853                return error;
       
   854                }
       
   855            }
       
   856            break;
       
   857         default:
       
   858            {
       
   859            CleanupStack::PopAndDestroy( pushCount );
       
   860            return KErrArgument;
       
   861            }
       
   862            
       
   863         }
       
   864      GBA_TRACE_DEBUG(("After Encode Digest AuthL 1"));
       
   865     // Resubmit the request to the server
       
   866     // add resyncronization header to the request if it is available
       
   867     if ( resyncrequired )
       
   868         {
       
   869         THTTPHdrVal hdrVal;
       
   870         RStringF unStr = stringPool.OpenFStringL(KAuts);
       
   871         CleanupClosePushL(unStr);
       
   872         pushCount++;
       
   873         hdrVal.SetStr(resync);
       
   874         RHTTPHeaders requestHeaders(aTransaction.Request().GetHeaderCollection());
       
   875         requestHeaders.SetFieldL( stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
   876                                  THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
   877                                  unStr,
       
   878                                  hdrVal );
       
   879        }
       
   880     GBA_TRACE_DEBUG(("After Encode Digest AuthL 2"));   
       
   881     CleanupStack::PopAndDestroy( pushCount ); 
       
   882     GBA_TRACE_DEBUG(("After Encode Digest AuthL 3"));
       
   883     return KErrNone;
       
   884     }
       
   885 
       
   886 
       
   887 // -----------------------------------------------------------------------------
       
   888 // C3GPPBootstrapHttpHandler::FindHeaderPartToUseL()
       
   889 // -----------------------------------------------------------------------------
       
   890 //
       
   891 TInt C3GPPBootstrapHttpHandler::FindHeaderPartToUseL( RHTTPTransaction aTransaction ) const
       
   892     {
       
   893     //We only pick up the first digest authentication fields:
       
   894     
       
   895     RStringPool stringPool = aTransaction.Session().StringPool(); 
       
   896 
       
   897     RStringF wwwAuthenticate = stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable());
       
   898     RStringF realm = stringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable());
       
   899     RStringF nonce = stringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable());
       
   900     RStringF qop   = stringPool.StringF(HTTP::EQop,RHTTPSession::GetTable());
       
   901     
       
   902     RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection();
       
   903     const TInt parts = headers.FieldPartsL( wwwAuthenticate );
       
   904     
       
   905     for ( TInt i = 0; i < parts; i++ )
       
   906     {
       
   907     THTTPHdrVal fieldVal;// The name of the current field.
       
   908     THTTPHdrVal hdrVal;//A scratch hdrVal
       
   909     headers.GetField(wwwAuthenticate, i, fieldVal);
       
   910     switch ( fieldVal.StrF().Index(RHTTPSession::GetTable() ) )
       
   911         {
       
   912         case HTTP::EDigest:
       
   913             {
       
   914             // It is Digest, let us check realm, nonce, qop then
       
   915             if ( headers.GetParam(wwwAuthenticate, realm, hdrVal, i ) == KErrNone 
       
   916                  &&
       
   917                  headers.GetParam(wwwAuthenticate, nonce, hdrVal, i ) == KErrNone)
       
   918                 {
       
   919                 // We've got a realm and a nonce. If there's a qop, we
       
   920                 // need to check it's acceptable.
       
   921                if ( headers.GetParam(wwwAuthenticate, qop, hdrVal, i ) == KErrNone 
       
   922                     && 
       
   923                     FindAuth( hdrVal.Str().DesC() ) )
       
   924                      {
       
   925                      // the header has qop and it is auth-int.
       
   926                      // we found it
       
   927                      return i;
       
   928                      }
       
   929 
       
   930                 }
       
   931             }
       
   932             break;
       
   933 
       
   934         default:
       
   935             //Ingore if it is not Digest
       
   936             break;
       
   937         }
       
   938     }
       
   939     return KErrNotFound;
       
   940 }
       
   941 
       
   942 
       
   943 
       
   944 // -----------------------------------------------------------------------------
       
   945 // C3GPPBootstrapHttpHandler::EncodeDigestAuthL()
       
   946 // -----------------------------------------------------------------------------
       
   947 //
       
   948 void C3GPPBootstrapHttpHandler::EncodeDigestAuthL( const RString& aUsername, 
       
   949             const RString& aPW, 
       
   950             RHTTPTransaction& aTransaction,
       
   951             TInt aHeaderPart,
       
   952             const THTTPHdrVal& aRequestUri )
       
   953     {
       
   954     GBA_TRACE_BEGIN();
       
   955     TInt pushCount = 0; 
       
   956     
       
   957     RStringPool stringPool = aTransaction.Session().StringPool(); 
       
   958 
       
   959     GBA_TRACE_DEBUG(("Username:"));
       
   960     GBA_TRACE_DEBUG(aUsername.DesC());
       
   961 
       
   962     GBA_TRACE_DEBUG(("Passwd:"));
       
   963     GBA_TRACE_DEBUG_BINARY(aPW.DesC());
       
   964   
       
   965     TBuf8<KHashLength> hash;
       
   966     TBuf8<KHashLength> cnonce;
       
   967     //Nonce
       
   968     THTTPHdrVal nonce;
       
   969     RHTTPHeaders headers = aTransaction.Response().GetHeaderCollection();
       
   970     TInt error = headers.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
   971           stringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable()), nonce,
       
   972           aHeaderPart);
       
   973     
       
   974     if ( error != KErrNone )
       
   975         {
       
   976         User::LeaveIfError( error );
       
   977         }
       
   978     
       
   979     //realm
       
   980     THTTPHdrVal realm;
       
   981     error = headers.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()),
       
   982            stringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable()), realm,
       
   983            aHeaderPart);
       
   984     
       
   985     if ( error != KErrNone )
       
   986         {
       
   987         User::LeaveIfError( error );
       
   988         }
       
   989     
       
   990     //qop       
       
   991     THTTPHdrVal qop;
       
   992     error = headers.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()),
       
   993            stringPool.StringF(HTTP::EQop,RHTTPSession::GetTable()), qop,
       
   994            aHeaderPart);
       
   995     
       
   996    if ( error != KErrNone )
       
   997         {
       
   998         User::LeaveIfError( error );
       
   999         }
       
  1000     
       
  1001     GenerateCNonce( cnonce );
       
  1002     
       
  1003     GBA_TRACE_DEBUG(("cnonce:"));
       
  1004     GBA_TRACE_DEBUG_BINARY( cnonce );
       
  1005     
       
  1006     RString cnonceString = stringPool.OpenStringL(cnonce); 
       
  1007     CleanupClosePushL(cnonceString);
       
  1008     pushCount++;
       
  1009     
       
  1010     // stored for auth calculations
       
  1011     iCnonce.Close();
       
  1012     iCnonce = cnonceString.Copy();
       
  1013     
       
  1014     // stored for auth calculations
       
  1015     iMethod.Close();
       
  1016     iMethod = aTransaction.Request().Method().Copy();
       
  1017     
       
  1018     DigestCalcL( KMD5HashofEmpty, hash );
       
  1019     
       
  1020     GBA_TRACE_DEBUG(("hash:"));
       
  1021     GBA_TRACE_DEBUG_BINARY( hash );
       
  1022     
       
  1023     // OK. hash now contains the digest response. Set up the header.
       
  1024     RHTTPHeaders requestHeaders(aTransaction.Request().GetHeaderCollection());
       
  1025     RHTTPHeaders responseHeaders(aTransaction.Response().GetHeaderCollection());
       
  1026   
       
  1027     requestHeaders.RemoveField(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable())); 
       
  1028     
       
  1029     //Copy useranme
       
  1030     THTTPHdrVal hdrVal;
       
  1031     hdrVal.SetStr(aUsername);
       
  1032     
       
  1033     //Set the username to request header
       
  1034     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1035            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1036            stringPool.StringF(HTTP::EUsername,RHTTPSession::GetTable()),
       
  1037            hdrVal);
       
  1038         
       
  1039     // copy Realm from response headers
       
  1040     responseHeaders.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
  1041            stringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable()),
       
  1042            hdrVal, 
       
  1043            aHeaderPart);
       
  1044     
       
  1045     // Set the Realm to request header
       
  1046     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1047            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1048            stringPool.StringF(HTTP::ERealm,RHTTPSession::GetTable()),
       
  1049            hdrVal);
       
  1050     
       
  1051     // copy nonce from response headers
       
  1052     responseHeaders.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
  1053            stringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable()), 
       
  1054            hdrVal,
       
  1055            aHeaderPart);
       
  1056     
       
  1057     // set nonce to request header
       
  1058     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1059            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1060            stringPool.StringF(HTTP::ENonce,RHTTPSession::GetTable()),
       
  1061            hdrVal);
       
  1062     
       
  1063     // Set uri to request header.
       
  1064     // the uri has already been fetched from http property setting
       
  1065     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1066            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1067            stringPool.StringF(HTTP::EUri,RHTTPSession::GetTable()),
       
  1068            aRequestUri);
       
  1069     
       
  1070     // Qop with quotation marks   
       
  1071     // copy qop from response headers
       
  1072      responseHeaders.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
  1073            stringPool.StringF(HTTP::EQop,RHTTPSession::GetTable()), 
       
  1074            hdrVal,
       
  1075            aHeaderPart);
       
  1076     
       
  1077     // Set Qop to request header
       
  1078      requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1079            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1080            stringPool.StringF(HTTP::EQop,RHTTPSession::GetTable()),
       
  1081            hdrVal);
       
  1082      
       
  1083     //Set Nc
       
  1084     hdrVal.SetStrF(stringPool.StringF(HTTP::E00000001,RHTTPSession::GetTable()));
       
  1085     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1086                   THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1087                   stringPool.StringF(HTTP::ENc,RHTTPSession::GetTable()),
       
  1088                   hdrVal);
       
  1089      
       
  1090     // Set Cnonce to request header.
       
  1091     hdrVal.SetStr(cnonceString);
       
  1092     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1093            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1094            stringPool.StringF(HTTP::ECnonce,RHTTPSession::GetTable()),
       
  1095            hdrVal);
       
  1096    
       
  1097     // Set response to request header.
       
  1098     RString hashStr = stringPool.OpenStringL(hash);
       
  1099     CleanupClosePushL(hashStr);
       
  1100     hdrVal.SetStr(hashStr);
       
  1101     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1102            THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1103            stringPool.StringF(HTTP::EResponse,RHTTPSession::GetTable()),
       
  1104            hdrVal);
       
  1105     CleanupStack::PopAndDestroy(&hashStr);
       
  1106 
       
  1107     // Get Opaque from response header.
       
  1108     error = responseHeaders.GetParam(stringPool.StringF(HTTP::EWWWAuthenticate,RHTTPSession::GetTable()), 
       
  1109              stringPool.StringF(HTTP::EOpaque,RHTTPSession::GetTable()), 
       
  1110              hdrVal, aHeaderPart);
       
  1111     
       
  1112     // Set Opaque 
       
  1113     if ( error != KErrNotFound )
       
  1114         {
       
  1115         GBA_TRACE_DEBUG((" found the opaque value and copy it"));
       
  1116         requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1117                        THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1118                        stringPool.StringF(HTTP::EOpaque,RHTTPSession::GetTable()),
       
  1119                        hdrVal);
       
  1120         } 
       
  1121     else
       
  1122         {
       
  1123         GBA_TRACE_DEBUG((" No opaque value send empty one"));
       
  1124         RString opaque =  stringPool.OpenStringL(Kfopaque);
       
  1125         GBA_TRACE_DEBUG((" No opaque value send empty one 1"));
       
  1126         CleanupClosePushL(opaque);
       
  1127         pushCount++;
       
  1128         hdrVal.SetStr(opaque);
       
  1129        GBA_TRACE_DEBUG((" No opaque value send empty one 2"));
       
  1130         requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), 
       
  1131              THTTPHdrVal(stringPool.StringF(HTTP::EDigest,RHTTPSession::GetTable())),
       
  1132              stringPool.StringF(HTTP::EOpaque,RHTTPSession::GetTable()),
       
  1133              hdrVal);
       
  1134        }
       
  1135     GBA_TRACE_DEBUG((" No opaque value send empty one 3"));
       
  1136     // Set algorithm.   
       
  1137     TBuf8<KAlgLength> algbuf;
       
  1138     algbuf.Copy(_L8(", "));
       
  1139     algbuf.Append(Kalgorithm);
       
  1140     algbuf.Append(_L8("="));
       
  1141     algbuf.Append(Kfalgo);
       
  1142    
       
  1143     GBA_TRACE_DEBUG((" No opaque value send empty one 5"));
       
  1144    
       
  1145     RStringF valStr = stringPool.OpenFStringL(algbuf);
       
  1146     THTTPHdrVal val(valStr);
       
  1147     requestHeaders.SetFieldL(stringPool.StringF(HTTP::EAuthorization,RHTTPSession::GetTable()), val);
       
  1148     valStr.Close();
       
  1149     
       
  1150     GBA_TRACE_DEBUG((" No opaque value send empty one 4"));
       
  1151 
       
  1152     CleanupStack::PopAndDestroy(pushCount);
       
  1153     GBA_TRACE_DEBUG((" No opaque value send empty one 6"));
       
  1154     }
       
  1155 
       
  1156 
       
  1157 // -----------------------------------------------------------------------------
       
  1158 // C3GPPBootstrapHttpHandler::FindAuth()
       
  1159 // -----------------------------------------------------------------------------
       
  1160 //
       
  1161 TBool C3GPPBootstrapHttpHandler::FindAuth(const TDesC8& aQop) const
       
  1162     {
       
  1163     GBA_TRACE_BEGIN();
       
  1164     if ( aQop == KAuthInt )
       
  1165         {
       
  1166         GBA_TRACE_DEBUG((" qop is equal to auth-int"));
       
  1167         return ETrue;
       
  1168         }
       
  1169     else
       
  1170         {
       
  1171         GBA_TRACE_DEBUG((" qop is NOT equal to auth-int"));
       
  1172         GBA_TRACE_DEBUG((""));
       
  1173         return EFalse;    
       
  1174         }    
       
  1175     }
       
  1176 
       
  1177 
       
  1178 // -----------------------------------------------------------------------------
       
  1179 // C3GPPBootstrapHttpHandler::HA1L()
       
  1180 // -----------------------------------------------------------------------------
       
  1181 //
       
  1182 void C3GPPBootstrapHttpHandler::HAOneL(const RString& aUsername,const RString& aPW,
       
  1183            const RString& aRealm, TDes8& aResult)
       
  1184     {
       
  1185     HBufC8* a1 = HBufC8::NewMaxLC(aUsername.DesC().Length() 
       
  1186            + aPW.DesC().Length()  
       
  1187            + 1
       
  1188            + aRealm.DesC().Length() + 1
       
  1189            );
       
  1190     TPtr8 a1Mod = a1->Des();
       
  1191     a1Mod.Zero();
       
  1192     
       
  1193     a1Mod.Append(aUsername.DesC());
       
  1194     a1Mod.Append(':');
       
  1195     a1Mod.Append(aRealm.DesC());
       
  1196     a1Mod.Append(':');
       
  1197     a1Mod.Append(aPW.DesC().Ptr(),aPW.DesC().Length());
       
  1198 
       
  1199     GBA_TRACE_DEBUG(a1Mod);
       
  1200     Hash(*a1, aResult);
       
  1201     GBA_TRACE_DEBUG(("after hash"));
       
  1202     CleanupStack::PopAndDestroy(a1);
       
  1203     }
       
  1204 
       
  1205 
       
  1206 // -----------------------------------------------------------------------------
       
  1207 // C3GPPBootstrapHttpHandler::HAtwoL()
       
  1208 // -----------------------------------------------------------------------------
       
  1209 //
       
  1210 void C3GPPBootstrapHttpHandler::HATwoL(const RStringF& aMethod, 
       
  1211            const RString& aRequestUri,
       
  1212            const TDesC8& aHentity,
       
  1213            TDes8& aResult)
       
  1214     {
       
  1215     // In the auth qop, a2 is Method:digest-uri-value:empty body hash
       
  1216     // Allocate enough space for the method, the URI and the colon, empty content-hash and colon.
       
  1217     TPtrC8 requestUri = aRequestUri.DesC();
       
  1218     TPtrC8 method = aMethod.DesC();
       
  1219     HBufC8* a2 = HBufC8::NewMaxLC( requestUri.Length() + method.Length() + KNumber34 );
       
  1220     TPtr8 a2Mod = a2->Des();
       
  1221     a2Mod.Zero();
       
  1222     a2Mod.Append(method);
       
  1223     a2Mod.Append(':');
       
  1224     
       
  1225     a2Mod.Append( requestUri );
       
  1226     GBA_TRACE_DEBUG( requestUri );
       
  1227     // since for this method is always auth-int we always add hentity
       
  1228     a2Mod.Append(':');
       
  1229     a2Mod.Append(aHentity);
       
  1230     GBA_TRACE_DEBUG(a2Mod);
       
  1231 
       
  1232     Hash(*a2, aResult);
       
  1233 
       
  1234     GBA_TRACE_DEBUG_BINARY(aResult);
       
  1235     CleanupStack::PopAndDestroy(a2);
       
  1236     
       
  1237     GBA_TRACE_DEBUG(("Exit HATwoL"));
       
  1238     }
       
  1239 
       
  1240 
       
  1241 // -----------------------------------------------------------------------------
       
  1242 // C3GPPBootstrapHttpHandler::Hash()
       
  1243 // -----------------------------------------------------------------------------
       
  1244 //
       
  1245 void C3GPPBootstrapHttpHandler::Hash(const TDesC8& aMessage, TDes8& aHash)
       
  1246     {
       
  1247     GBA_TRACE_DEBUG(("hash"));
       
  1248     // Calculate the 128 bit (16 byte) hash
       
  1249     iMD5Calculator->Reset();
       
  1250     TPtrC8 hash = iMD5Calculator->Hash(aMessage);
       
  1251     GBA_TRACE_DEBUG(("after hash"));
       
  1252     // Now print it as a 32 byte hex number
       
  1253     aHash.Zero();
       
  1254     for ( TInt ii = 0; ii < KRawHashLength; ii++ )
       
  1255         {
       
  1256         TBuf8<2> scratch;
       
  1257         scratch.Zero();
       
  1258         scratch.Format(formatStr, hash[ii]);
       
  1259         aHash.Append(scratch);
       
  1260       }
       
  1261     }
       
  1262 
       
  1263 
       
  1264 // -----------------------------------------------------------------------------
       
  1265 // C3GPPBootstrapHttpHandler::GenerateCNonce()
       
  1266 // -----------------------------------------------------------------------------
       
  1267 //
       
  1268 void C3GPPBootstrapHttpHandler::GenerateCNonce(TDes8& aNonce)
       
  1269     {
       
  1270     // The purpose of the client nonce is to protect aextst 'chosen
       
  1271     // plaintext' attacks where a hostile server tricks the client
       
  1272     // into supplying a password using a specific server nonce that
       
  1273     // allows an (as yet undiscovered) flaw in MD5 to recover the
       
  1274     // password. As such the only important thing about client nonces
       
  1275     // is that they change and aren't predictable. See section 4.9 of
       
  1276     // RFC2616
       
  1277 
       
  1278     TTime time;
       
  1279     time.UniversalTime();
       
  1280     TInt64 randomNumber = Math::Rand(iSeed);
       
  1281     randomNumber <<= KNumber32;
       
  1282     randomNumber += Math::Rand(iSeed);
       
  1283     TBuf8<KNumber33> key;
       
  1284     key.Zero();
       
  1285     key.AppendNum(time.Int64(), EHex);
       
  1286     key.Append(KColon);
       
  1287     key.AppendNum(randomNumber, EHex);
       
  1288   
       
  1289     Hash(key, aNonce);
       
  1290     }
       
  1291 
       
  1292 
       
  1293 // -----------------------------------------------------------------------------
       
  1294 // C3GPPBootstrapHttpHandler::CheckRspAuthL()
       
  1295 // -----------------------------------------------------------------------------
       
  1296 //
       
  1297 TInt C3GPPBootstrapHttpHandler::CheckRspAuthL(RHTTPTransaction aTransaction)
       
  1298     {
       
  1299     RStringF wwwAuthInfoHeader = aTransaction.Session().StringPool().OpenFStringL(KHTTPAuthInfo);
       
  1300     RHTTPHeaders headers(aTransaction.Response().GetHeaderCollection());
       
  1301 
       
  1302     THTTPHdrVal rspAuthVal;
       
  1303     
       
  1304     TInt retVal = headers.FieldPartsL(wwwAuthInfoHeader);
       
  1305 
       
  1306     TInt error = headers.GetField(wwwAuthInfoHeader, 0, rspAuthVal);
       
  1307 
       
  1308     if(error != KErrNone)
       
  1309     {
       
  1310     	wwwAuthInfoHeader.Close();
       
  1311     	return error;
       
  1312     } 
       
  1313     wwwAuthInfoHeader.Close();
       
  1314     return KErrNone;      
       
  1315     }
       
  1316 
       
  1317 
       
  1318 // -----------------------------------------------------------------------------
       
  1319 // C3GPPBootstrapHttpHandler::DigestCalcL()
       
  1320 // -----------------------------------------------------------------------------
       
  1321 //
       
  1322 void C3GPPBootstrapHttpHandler::DigestCalcL(
       
  1323     const TDesC8& aHentity,
       
  1324     TDes8& aResult )
       
  1325     {
       
  1326     TInt stringToHashLength = iNonce.DesC().Length() + 
       
  1327           KNumber8 + // auth-int length 
       
  1328           KNumber3 * KHashLength + KNumber8 + iPassword.DesC().Length() + KNumber5;
       
  1329     HBufC8* stringToHash = HBufC8::NewMaxLC(stringToHashLength);
       
  1330     TPtr8 stringMod = stringToHash->Des();
       
  1331     stringMod.Zero();
       
  1332     HAOneL(iUsername, iPassword, iRealm, stringMod);
       
  1333     stringMod.Append(':');
       
  1334     stringMod.Append(iNonce.DesC());
       
  1335     stringMod.Append(KNCVal_2);
       
  1336     stringMod.Append(iCnonce.DesC());
       
  1337     stringMod.Append(':');
       
  1338     stringMod.Append(KAuthInt);
       
  1339     stringMod.Append(':');
       
  1340     TBuf8<KHashLength> hash;
       
  1341     HATwoL(iMethod, iUri, aHentity,hash);
       
  1342     GBA_TRACE_DEBUG_BINARY(stringMod);
       
  1343     stringMod.Append(hash);   
       
  1344     GBA_TRACE_DEBUG(stringMod);
       
  1345     Hash(*stringToHash, aResult);
       
  1346     CleanupStack::PopAndDestroy(stringToHash);
       
  1347     };
       
  1348 
       
  1349 // -----------------------------------------------------------------------------
       
  1350 // C3GPPBootstrapHttpHandler::GetResponse()
       
  1351 // -----------------------------------------------------------------------------
       
  1352 //
       
  1353  HBufC8* C3GPPBootstrapHttpHandler::GetResponse()
       
  1354     {
       
  1355     return iResponse->Alloc();
       
  1356     };
       
  1357     
       
  1358 //EOF