natfw/natfwstunturnclient/src/cstunsharedsecret.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "stunassert.h"
       
    22 #include "natfwunsaflog.h"
       
    23 #include "cnatfwunsaftlstransport.h"
       
    24 #include "natfwunsafsharedsecretrequest.h"
       
    25 #include "natfwunsaftextattribute.h"
       
    26 #include "natfwunsaferrorcodeattribute.h"
       
    27 #include "natfwunsafusernameattribute.h"
       
    28 #include "natfwunsafrealmattribute.h"
       
    29 #include "natfwunsafnonceattribute.h"
       
    30 #include "cstunsharedsecret.h"
       
    31 #include "cstunsharedsecretconnecting.h"
       
    32 #include "cstunsharedsecretwaitresponse.h"
       
    33 #include "cstunsharedsecretactive.h"
       
    34 #include "cstunsharedsecretwaittoretry.h"
       
    35 #include "msharedsecretobserver.h"
       
    36 #include "ctransactionidgenerator.h"
       
    37 #include "stunutils.h"
       
    38 #include "stunturnclientlogs.h"
       
    39 #include "natfwstunclientdefs.h"
       
    40 
       
    41 
       
    42 const TInt KMaxSameErrorCount = 3;
       
    43 
       
    44 // ======== MEMBER FUNCTIONS ========
       
    45 
       
    46 // ---------------------------------------------------------------------------
       
    47 // CSTUNSharedSecret::NewL
       
    48 // ---------------------------------------------------------------------------
       
    49 //
       
    50 CSTUNSharedSecret*
       
    51 CSTUNSharedSecret::NewL( RSocketServ& aSocketServer,
       
    52                          RConnection& aConnection,
       
    53                          CDeltaTimer& aTimer,
       
    54                          const TInetAddr& aAddr,
       
    55                          CTransactionIDGenerator& aTransactionIDGenerator,
       
    56                          MSharedSecretObserver& aObserver,
       
    57                          const TDesC8& aLtUsername,
       
    58                          const TDesC8& aLtPassword )
       
    59     {
       
    60     CSTUNSharedSecret* self =
       
    61         new ( ELeave ) CSTUNSharedSecret( aTimer,
       
    62                                           aTransactionIDGenerator,
       
    63                                           aObserver );
       
    64     CleanupStack::PushL( self );
       
    65     self->ConstructL( aSocketServer, aConnection, aAddr, 
       
    66         aLtUsername, aLtPassword );
       
    67     CleanupStack::Pop( self );
       
    68     return self;
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // CSTUNSharedSecret::CSTUNSharedSecret
       
    73 // ---------------------------------------------------------------------------
       
    74 //
       
    75 CSTUNSharedSecret::CSTUNSharedSecret(
       
    76     CDeltaTimer& aTimer,
       
    77     CTransactionIDGenerator& aTransactionIDGenerator,
       
    78     MSharedSecretObserver& aObserver ) :
       
    79     CSTUNTimerUser( aTimer ),
       
    80     iObserver( aObserver ),
       
    81     iTransactionIDGenerator( aTransactionIDGenerator )
       
    82     {
       
    83     }
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // CSTUNSharedSecret::CSTUNSharedSecret
       
    87 // Dummy implementation. Default constructor is declared private and not used.
       
    88 // ---------------------------------------------------------------------------
       
    89 //
       
    90 CSTUNSharedSecret::CSTUNSharedSecret() :
       
    91     CSTUNTimerUser( *( CDeltaTimer* )0x1 ),
       
    92     iObserver( *( MSharedSecretObserver* )0x1 ),
       
    93     iTransactionIDGenerator( *( CTransactionIDGenerator* )0x1  )
       
    94     {        
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 // CSTUNSharedSecret::CSTUNSharedSecret
       
    99 // Dummy implementation. Copy constructor is declared private and not used.
       
   100 // ---------------------------------------------------------------------------
       
   101 //
       
   102 CSTUNSharedSecret::CSTUNSharedSecret(
       
   103     const CSTUNSharedSecret& aSharedSecret ) :
       
   104     CSTUNTimerUser( *( CDeltaTimer* )0x1 ),
       
   105     iObserver( aSharedSecret.iObserver ),
       
   106     iTransactionIDGenerator( aSharedSecret.iTransactionIDGenerator )
       
   107     {
       
   108     }
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 // CSTUNSharedSecret::ConstructL
       
   112 // ---------------------------------------------------------------------------
       
   113 //
       
   114 void CSTUNSharedSecret::ConstructL( RSocketServ& aSocketServer,
       
   115                                     RConnection& aConnection,
       
   116                                     const TInetAddr& aAddr,
       
   117                                     const TDesC8& aLtUsername,
       
   118                                     const TDesC8& aLtPassword )
       
   119     {
       
   120     __STUNTURNCLIENT( "CSTUNSharedSecret::ConstructL" )
       
   121     
       
   122     iActive = new ( ELeave ) CSTUNSharedSecretActive;
       
   123     iWaitToRetry = new ( ELeave ) CSTUNSharedSecretWaitToRetry;
       
   124     iWaitResponse =
       
   125         new ( ELeave ) CSTUNSharedSecretWaitResponse( *iActive, *iWaitToRetry );
       
   126     iConnecting = new ( ELeave ) CSTUNSharedSecretConnecting( *iWaitResponse );    
       
   127     iWaitToRetry->SetNeighbourStates( *iWaitResponse );
       
   128     iState = iConnecting;
       
   129     
       
   130     if ( aLtUsername.Length() > 0 && aLtPassword.Length() > 0 )
       
   131         {
       
   132         iLtUsername = aLtUsername.AllocL();
       
   133         iLtPassword = aLtPassword.AllocL();
       
   134         }
       
   135 
       
   136     iTlsTransport = CNATFWUNSAFTlsTransport::NewL( aSocketServer,
       
   137                                                    aConnection,
       
   138                                                    aAddr,
       
   139                                                    *this );
       
   140     
       
   141     StartTimer( KTlsHandshakeTimeout );
       
   142     }
       
   143        
       
   144 // ---------------------------------------------------------------------------
       
   145 // CSTUNSharedSecret::~CSTUNSharedSecret
       
   146 // ---------------------------------------------------------------------------
       
   147 //
       
   148 CSTUNSharedSecret::~CSTUNSharedSecret()
       
   149     {
       
   150     __STUNTURNCLIENT( "CSTUNSharedSecret::~CSTUNSharedSecret" )
       
   151     delete iLtUsername;
       
   152     delete iLtPassword;
       
   153     delete iNonce;
       
   154     delete iRealm;  
       
   155     delete iTlsTransport;
       
   156     delete iRequest;
       
   157     delete iUsername;
       
   158     delete iPassword;
       
   159     
       
   160     delete iConnecting;
       
   161     delete iWaitResponse;
       
   162     delete iWaitToRetry;
       
   163     delete iActive;
       
   164     iErrorBuffer.Close();
       
   165     }
       
   166     
       
   167 // ---------------------------------------------------------------------------
       
   168 // CSTUNSharedSecret::TlsConnectedL
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 void CSTUNSharedSecret::TlsConnectedL()
       
   172     {
       
   173     __STUNTURNCLIENT( "CSTUNSharedSecret::TlsConnectedL" )
       
   174     __TEST_INVARIANT;
       
   175 
       
   176     if ( iState )
       
   177         {
       
   178         // Stop TLS handshake timer
       
   179         StopTimer();
       
   180         iState->TlsConnectedL( *this );
       
   181         }
       
   182 
       
   183     __TEST_INVARIANT;
       
   184     }
       
   185 
       
   186 // ---------------------------------------------------------------------------
       
   187 // CSTUNSharedSecret::IncomingMessageL
       
   188 // ---------------------------------------------------------------------------
       
   189 //
       
   190 void CSTUNSharedSecret::IncomingMessageL( CNATFWUNSAFMessage* aMessage )
       
   191     {
       
   192     __STUNTURNCLIENT( "CSTUNSharedSecret::IncomingMessageL" )
       
   193     __TEST_INVARIANT;
       
   194     __STUN_ASSERT_L( aMessage != NULL, KErrArgument );
       
   195 
       
   196     if ( iState )
       
   197         {
       
   198         iState->IncomingMessageL( *this, aMessage );
       
   199         }
       
   200         
       
   201     __TEST_INVARIANT;
       
   202     }
       
   203 
       
   204 // ---------------------------------------------------------------------------
       
   205 // CSTUNSharedSecret::ErrorOccured
       
   206 // ---------------------------------------------------------------------------
       
   207 //
       
   208 void CSTUNSharedSecret::ErrorOccured( TInt aError )
       
   209     {
       
   210     __STUNTURNCLIENT( "CSTUNSharedSecret::ErrorOccured" )
       
   211     __TEST_INVARIANT;
       
   212     __STUN_ASSERT_RETURN( aError != KErrNone, KErrArgument );
       
   213 
       
   214     if ( iState )
       
   215         {
       
   216         iState->ErrorOccured( *this, aError );
       
   217         }
       
   218         
       
   219     // Do not call __TEST_INVARIANT here because the previous call might have
       
   220     // led to deletion of this object.
       
   221     }
       
   222 
       
   223 // -----------------------------------------------------------------------------
       
   224 // CSTUNSharedSecret::TimerExpiredL
       
   225 // -----------------------------------------------------------------------------
       
   226 //
       
   227 void CSTUNSharedSecret::TimerExpiredL()
       
   228     {
       
   229     __STUNTURNCLIENT( "CSTUNSharedSecret::TimerExpiredL" )
       
   230     if ( iState )
       
   231         {
       
   232         iState->TimerExpiredL( *this );
       
   233         }
       
   234     }
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // CSTUNSharedSecret::LeaveFromTimerExpired
       
   238 // -----------------------------------------------------------------------------
       
   239 //
       
   240 void CSTUNSharedSecret::LeaveFromTimerExpired( TInt aError )
       
   241     {
       
   242     __STUNTURNCLIENT( "CSTUNSharedSecret::LeaveFromTimerExpired" )
       
   243     __TEST_INVARIANT;
       
   244     __STUN_ASSERT_RETURN( aError != KErrNone, KErrArgument );
       
   245 
       
   246     Terminate( aError );
       
   247     }
       
   248 
       
   249 // -----------------------------------------------------------------------------
       
   250 // CSTUNSharedSecret::Username
       
   251 // -----------------------------------------------------------------------------
       
   252 //
       
   253 const TDesC8& CSTUNSharedSecret::Username() const
       
   254     {
       
   255     __STUNTURNCLIENT( "CSTUNSharedSecret::Username" )
       
   256     __TEST_INVARIANT;
       
   257 
       
   258     if ( iUsername )
       
   259         {
       
   260         return *iUsername;
       
   261         }
       
   262 
       
   263     return KNullDesC8;    
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CSTUNSharedSecret::Password
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 const TDesC8& CSTUNSharedSecret::Password() const
       
   271     {
       
   272     __STUNTURNCLIENT( "CSTUNSharedSecret::Password" )
       
   273     __TEST_INVARIANT;
       
   274 
       
   275     if ( iPassword )
       
   276         {
       
   277         return *iPassword;
       
   278         }
       
   279 
       
   280     return KNullDesC8;
       
   281     }
       
   282 
       
   283 // -----------------------------------------------------------------------------
       
   284 // CSTUNSharedSecret::ChangeState
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 void CSTUNSharedSecret::ChangeState( const CSTUNSharedSecretState* aNewState )
       
   288     {
       
   289     __STUNTURNCLIENT( "CSTUNSharedSecret::ChangeState" )
       
   290     __TEST_INVARIANT;
       
   291 
       
   292     iState = aNewState;
       
   293 
       
   294     __TEST_INVARIANT;
       
   295     }
       
   296 
       
   297 // ---------------------------------------------------------------------------
       
   298 // CSTUNSharedSecret::Terminate
       
   299 // ---------------------------------------------------------------------------
       
   300 //
       
   301 void CSTUNSharedSecret::Terminate( TInt aError )
       
   302     {
       
   303     __STUNTURNCLIENT( "CSTUNSharedSecret::Terminate" )
       
   304     __TEST_INVARIANT;
       
   305     // Terminate only once
       
   306     __STUN_ASSERT_RETURN( iState != NULL, KErrDied );
       
   307     __STUN_ASSERT_RETURN( aError != KErrNone, KErrArgument );
       
   308     NATFWUNSAF_INTLOG( "STUNSharedSecret terminated, reason", aError )
       
   309 
       
   310     ChangeState( NULL );
       
   311     TRAP_IGNORE( iObserver.SharedSecretErrorL( aError ) )
       
   312     
       
   313     // Do not call __TEST_INVARIANT here because the call to observer's
       
   314     // SharedSecretErrorL might have led to deletion of this object.
       
   315     }
       
   316 
       
   317 // -----------------------------------------------------------------------------
       
   318 // CSTUNSharedSecret::SendRequestL
       
   319 // -----------------------------------------------------------------------------
       
   320 //
       
   321 void CSTUNSharedSecret::SendRequestL()
       
   322     {
       
   323     __STUNTURNCLIENT( "CSTUNSharedSecret::SendRequestL in" )
       
   324     __TEST_INVARIANT;
       
   325     __STUN_ASSERT_L( !iRequest, KErrAlreadyExists );
       
   326 
       
   327     TNATFWUNSAFTransactionID transactionID;
       
   328     iTransactionIDGenerator.GetIDL( this, sizeof( *this ), transactionID );
       
   329     iRequest = CNATFWUNSAFSharedSecretRequest::NewL( transactionID );
       
   330   
       
   331     
       
   332     if ( iLtUsername && iLtPassword && iAddUsernameAttr )
       
   333         {
       
   334         __STUNTURNCLIENT( "CSTUNSharedSecret::SendRequestL -username attr" )
       
   335         iRequest->AddAttributeL(
       
   336             CNATFWUNSAFUsernameAttribute::NewLC( *iLtUsername ) );
       
   337         CleanupStack::Pop(); //CNATFWUNSAFUsernameAttribute
       
   338         }
       
   339     
       
   340     if ( iRealm )
       
   341         {
       
   342         __STUNTURNCLIENT( "CSTUNSharedSecret::SendRequestL -realm attr" )
       
   343         iRequest->AddAttributeL( CNATFWUNSAFRealmAttribute::NewLC( *iRealm ) );
       
   344         CleanupStack::Pop(); //CNATFWUNSAFRealmAttribute        
       
   345         }
       
   346     
       
   347     if ( iNonce )
       
   348         {
       
   349         __STUNTURNCLIENT( "CSTUNSharedSecret::SendRequestL -nonce attr" )
       
   350         iRequest->AddAttributeL( CNATFWUNSAFNonceAttribute::NewLC( *iNonce ) );
       
   351         CleanupStack::Pop(); //CNATFWUNSAFNonceAttribute        
       
   352         }
       
   353     
       
   354     if ( iLtUsername && iLtPassword && iRealm )
       
   355         {
       
   356         // create credential string; username:realm:password
       
   357         // space for two colons (:)
       
   358         __STUNTURNCLIENT( "CSTUNSharedSecret::\
       
   359             SendRequestL make credential string" )
       
   360         const TInt marks(2);
       
   361         _LIT8( Kcolon, ":" ); 
       
   362         TInt stringlength( iLtUsername->Length() + 
       
   363             iLtPassword->Length() + iRealm->Length() + marks );
       
   364         
       
   365         HBufC8* credential = HBufC8::NewL( stringlength );
       
   366         TPtr8 des = credential->Des();
       
   367         des.Append( *iLtUsername );
       
   368         des.Append( Kcolon );
       
   369         des.Append( *iRealm );
       
   370         des.Append( Kcolon );
       
   371         des.Append( *iLtPassword );
       
   372         
       
   373         CleanupStack::PushL( credential );
       
   374         __STUNTURNCLIENT_STR8( "CSTUNSharedSecret::\
       
   375             SendRequestL credential string: ", *credential )
       
   376         iTlsTransport->SendL( *iRequest, *credential );
       
   377         CleanupStack::PopAndDestroy( credential );
       
   378         }
       
   379     else
       
   380         {
       
   381         // A null descriptor used for long term shared secret for now.
       
   382         iTlsTransport->SendL( *iRequest, KNullDesC8 );
       
   383         }
       
   384     
       
   385     StartTimer( KSharedSecretRequestTimeout );
       
   386     __STUNTURNCLIENT( "CSTUNSharedSecret::SendRequestL End" )
       
   387     __TEST_INVARIANT;
       
   388     }
       
   389 
       
   390 // ---------------------------------------------------------------------------
       
   391 // CSTUNSharedSecret::CheckMessage
       
   392 // ---------------------------------------------------------------------------
       
   393 //
       
   394 TBool CSTUNSharedSecret::CheckMessage( 
       
   395     const CNATFWUNSAFMessage& aMessage ) const
       
   396     {
       
   397     __STUNTURNCLIENT( "CSTUNSharedSecret::CheckMessage in" )
       
   398     __TEST_INVARIANT;
       
   399     __STUN_ASSERT_RETURN_VALUE( iRequest != NULL, EFalse );
       
   400 
       
   401     __STUNTURNCLIENT_STR8( "CSTUNSharedSecret::\
       
   402     CheckMessage transcation id from message :", aMessage.TransactionID() )
       
   403     __STUNTURNCLIENT_STR8( "CSTUNSharedSecret::\
       
   404     CheckMessage transcation id from request :", iRequest->TransactionID() )
       
   405     
       
   406     if ( aMessage.Type() == CNATFWUNSAFMessage::ESharedSecretResponse &&
       
   407          aMessage.Validate() )
       
   408         {
       
   409         __STUNTURNCLIENT( "CSTUNSharedSecret::CheckMessage\
       
   410         SharedSecretResponse -> CORRECT THIS IMPLEMENTATION AFTER SERVER\
       
   411         DOES NOT MESS UP THE TRANSACTION ID - TODO" )
       
   412         return ETrue;
       
   413         }
       
   414     
       
   415     else if ( aMessage.Validate() &&
       
   416         ( aMessage.TransactionID() == iRequest->TransactionID() ) &&
       
   417         ( aMessage.Type() == CNATFWUNSAFMessage::ESharedSecretErrorResponse ) )
       
   418         {
       
   419         return ETrue;
       
   420         }
       
   421     else 
       
   422         {
       
   423         return EFalse;
       
   424         }
       
   425     }
       
   426 
       
   427 // -----------------------------------------------------------------------------
       
   428 // CSTUNSharedSecret::ResponseReceivedL
       
   429 // Store username and password before calling SharedSecretObtainedL.
       
   430 // -----------------------------------------------------------------------------
       
   431 //
       
   432 void CSTUNSharedSecret::ResponseReceivedL( const CNATFWUNSAFMessage& aResponse )
       
   433     {
       
   434     __STUNTURNCLIENT( "CSTUNSharedSecret::ResponseReceivedL" )
       
   435     __TEST_INVARIANT;
       
   436     __STUN_ASSERT_L( !iUsername && !iPassword, KErrAlreadyExists );
       
   437     __STUN_ASSERT_L( aResponse.Type() == CNATFWUNSAFMessage::ESharedSecretResponse,
       
   438                      KErrArgument );
       
   439     NATFWUNSAF_LOG( "STUNSharedSecret received SharedSecretResp" )
       
   440 
       
   441     StopTimer();
       
   442     StoreValueL( aResponse.Attribute( CNATFWUNSAFAttribute::EUsername ), &iUsername );
       
   443     StoreValueL( aResponse.Attribute( CNATFWUNSAFAttribute::EPassword ), &iPassword );
       
   444     
       
   445     __STUNTURNCLIENT_STR8( "CSTUNSharedSecret::username:", *iUsername )
       
   446     __STUNTURNCLIENT_STR8( "CSTUNSharedSecret::password:", *iPassword )
       
   447     
       
   448     NATFWUNSAF_BYTESTREAMLOG( "username", *iUsername )
       
   449     NATFWUNSAF_BYTESTREAMLOG( "password", *iPassword )
       
   450     
       
   451     iErrorBuffer.Reset();
       
   452 
       
   453     // Close TLS connection
       
   454     delete iTlsTransport;
       
   455     iTlsTransport = NULL;
       
   456 
       
   457     iObserver.SharedSecretObtainedL();
       
   458 
       
   459     __TEST_INVARIANT;
       
   460     }    
       
   461 
       
   462 // -----------------------------------------------------------------------------
       
   463 // CSTUNSharedSecret::StoreValueL
       
   464 // Empty value is an error. Don't use __TEST_INVARIANT, as it checks username
       
   465 // and password.
       
   466 // -----------------------------------------------------------------------------
       
   467 //
       
   468 void CSTUNSharedSecret::StoreValueL( CNATFWUNSAFAttribute* aAttribute,
       
   469                                      HBufC8** aDest ) const
       
   470     {
       
   471     __STUNTURNCLIENT( "CSTUNSharedSecret::StoreValueL" )
       
   472     __STUN_ASSERT_L( aAttribute, KErrCorrupt );
       
   473 
       
   474     const TDesC8& value =
       
   475         static_cast<CNATFWUNSAFTextAttribute*>( aAttribute )->Value();
       
   476     __ASSERT_ALWAYS( value.Length() > 0 && aDest != NULL,
       
   477         User::Leave( KErrArgument ) );
       
   478     *aDest = value.AllocL();
       
   479     }
       
   480 
       
   481 // -----------------------------------------------------------------------------
       
   482 // CSTUNSharedSecret::ErrorResponseReceivedL
       
   483 // If 5xx is received, wait a few seconds, then retry.
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 TBool CSTUNSharedSecret::ErrorResponseReceivedL( 
       
   487     const CNATFWUNSAFMessage& aResponse )
       
   488     {
       
   489     __STUNTURNCLIENT( "CSTUNSharedSecret::ErrorResponseReceivedL in" )
       
   490     __TEST_INVARIANT;
       
   491     __STUN_ASSERT_L(
       
   492         aResponse.Type() == CNATFWUNSAFMessage::ESharedSecretErrorResponse,
       
   493         KErrArgument );
       
   494 
       
   495     StopTimer();
       
   496 
       
   497     CNATFWUNSAFErrorCodeAttribute* errorCode =
       
   498         static_cast<CNATFWUNSAFErrorCodeAttribute*>(
       
   499             aResponse.Attribute( CNATFWUNSAFAttribute::EErrorCode ) );
       
   500     __STUN_ASSERT_L( errorCode, KErrCorrupt );
       
   501     
       
   502     TInt error( errorCode->ResponseCode() );
       
   503     
       
   504     __STUNTURNCLIENT_INT1( "CSTUNSharedSecret::ErrorResponseReceivedL:",
       
   505         error )
       
   506     
       
   507     iErrorBuffer.AppendL( error );
       
   508     TInt count( iErrorBuffer.Count() );
       
   509     TInt sameErrorCount(0);
       
   510     for ( TInt i(0); i < count; i++ )
       
   511         {
       
   512         if ( iErrorBuffer[i] == error )
       
   513             {
       
   514             sameErrorCount++;
       
   515             
       
   516             // if same error occurs "KMaxSameErrorCount" times,
       
   517             // it is time to quit retrying
       
   518             if ( KMaxSameErrorCount <= sameErrorCount )
       
   519                 {
       
   520                 return EFalse;
       
   521                 }
       
   522             }
       
   523         }
       
   524     
       
   525     if ( STUNUtils::Is5xxResponse( error ) )
       
   526         {
       
   527         delete iRequest;
       
   528         iRequest = NULL;
       
   529         StartTimer( STUNUtils::EWaitBeforeRetryDuration );        
       
   530         return ETrue;
       
   531         }
       
   532     
       
   533     if( IsExpectedError( error ) )
       
   534         {
       
   535         SaveRealmAndNonceL( aResponse );
       
   536                 
       
   537         iTlsTransport->ContinueListeningL();
       
   538         delete iRequest;
       
   539         iRequest = NULL;
       
   540         StartTimer( STUNUtils::ERetryImmediately );
       
   541         return ETrue;
       
   542         }
       
   543     
       
   544     return EFalse;
       
   545     }
       
   546 
       
   547 
       
   548 // -----------------------------------------------------------------------------
       
   549 // CSTUNSharedSecret::IsExpectedError
       
   550 // -----------------------------------------------------------------------------
       
   551 //
       
   552 TBool CSTUNSharedSecret::IsExpectedError( TInt aError )
       
   553     {
       
   554     __STUNTURNCLIENT( "CSTUNSharedSecret::IsExpectedError" )
       
   555     
       
   556     if ( E401Unauthorized == aError )
       
   557         {
       
   558         iAddUsernameAttr = ETrue;
       
   559         }
       
   560     
       
   561     return ( E401Unauthorized == aError || E435MissingNonce == aError || 
       
   562              E438StaleNonce == aError );
       
   563     }
       
   564 
       
   565 // -----------------------------------------------------------------------------
       
   566 // CSTUNSharedSecret::SaveRealmAndNonceL
       
   567 // -----------------------------------------------------------------------------
       
   568 //
       
   569 void CSTUNSharedSecret::SaveRealmAndNonceL( 
       
   570     const CNATFWUNSAFMessage& aResponse )
       
   571     {
       
   572     __STUNTURNCLIENT( "CSTUNSharedSecret::SaveRealmAndNonceL in" )
       
   573     
       
   574     CNATFWUNSAFAttribute* tmp = aResponse.Attribute(
       
   575         CNATFWUNSAFAttribute::ENonce );
       
   576     
       
   577     if ( tmp )
       
   578         {
       
   579         __STUNTURNCLIENT( "CSTUNSharedSecret::SaveRealmAndNonceL nonce found" )
       
   580         CNATFWUNSAFNonceAttribute* nonceAttrib =
       
   581             static_cast<CNATFWUNSAFNonceAttribute*>( tmp );
       
   582         
       
   583         delete iNonce;
       
   584         iNonce = NULL;
       
   585         iNonce = nonceAttrib->Value().AllocL();
       
   586         }
       
   587     
       
   588     
       
   589     CNATFWUNSAFAttribute* temp = aResponse.Attribute(
       
   590         CNATFWUNSAFAttribute::ERealm );
       
   591     
       
   592     if ( temp )
       
   593         {
       
   594         __STUNTURNCLIENT( "CSTUNSharedSecret::SaveRealmAndNonceL realm found" )
       
   595         CNATFWUNSAFRealmAttribute* realmAttrib =
       
   596             static_cast<CNATFWUNSAFRealmAttribute*>( temp );
       
   597         
       
   598         delete iRealm;
       
   599         iRealm = NULL;
       
   600         iRealm = realmAttrib->Value().AllocL();
       
   601         }
       
   602 
       
   603     __STUNTURNCLIENT( "CSTUNSharedSecret::SaveRealmAndNonceL out" )
       
   604     }
       
   605 
       
   606 // -----------------------------------------------------------------------------
       
   607 // CSTUNSharedSecret::__DbgTestInvariant
       
   608 // Both username and password (or neither) must exist.
       
   609 // -----------------------------------------------------------------------------
       
   610 //
       
   611 void CSTUNSharedSecret::__DbgTestInvariant() const
       
   612     {
       
   613 #if defined( _DEBUG )
       
   614     if ( !iConnecting || !iWaitResponse || !iWaitToRetry || !iActive ||
       
   615          ( iUsername && !iPassword ) || ( !iUsername && iPassword ) )
       
   616         {
       
   617         __STUNTURNCLIENT( "CSTUNSharedSecret::__DbgTestInvariant -> PANIC" )
       
   618         User::Invariant();
       
   619         }
       
   620 #endif
       
   621     }