vpnengine/ikev1lib/src/ikev1pluginsession.cpp
changeset 0 33413c0669b9
child 12 68dc8923de26
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  IKEv1 plugin session
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <random.h>
       
    20 #include <vpnlogmessages.rsg>
       
    21 #include "ikev1plugin.h"
       
    22 #include "ikedebug.h"
       
    23 #include "ikev1negotiation.h"
       
    24 #include "ikev1isakmpstream.h"
       
    25 #include "pfkeymsg.h"
       
    26 #include "ikepolparser.h"
       
    27 #include "kmdapi.h"
       
    28 #include "ikev1crack.h"
       
    29 #include "ikev1infonegotiation.h"
       
    30 #include "ikev1SA.h"
       
    31 #include "ikev1sender.h"
       
    32 #include "ikesocketdefs.h"
       
    33 #include "ikedatainterface.h"
       
    34 #include "vpnaddrinfo.h"
       
    35 #include "ipsecsaspiretriever.h"
       
    36 
       
    37 // CLASS HEADER
       
    38 #include "ikev1pluginsession.h"
       
    39 
       
    40 // ======== MEMBER FUNCTIONS ========
       
    41 
       
    42 // ---------------------------------------------------------------------------
       
    43 // Two-phased constructor.
       
    44 // ---------------------------------------------------------------------------
       
    45 //
       
    46 CIkev1PluginSession* CIkev1PluginSession::NewL( TUint32 aVpnIapId,
       
    47                                                 TUint32 aVpnNetId,
       
    48                                                 TUint32 aVpnInterfaceIndex,
       
    49                                                 MIkeDataInterface& aDataInterface,
       
    50                                                 CIkev1Plugin& aPlugin,
       
    51                                                 CPFKeySocketIf& aPFKeySocketIf,
       
    52                                                 MIkeDebug& aDebug )
       
    53     {
       
    54     CIkev1PluginSession* self = new ( ELeave ) CIkev1PluginSession( aVpnIapId,
       
    55                                                                     aVpnNetId,
       
    56                                                                     aVpnInterfaceIndex,
       
    57                                                                     aDataInterface,
       
    58                                                                     aPlugin,
       
    59                                                                     aPFKeySocketIf,
       
    60                                                                     aDebug );
       
    61     CleanupStack::PushL( self );
       
    62     self->ConstructL();
       
    63     CleanupStack::Pop( self );
       
    64     return self;
       
    65     }
       
    66     
       
    67 // ---------------------------------------------------------------------------
       
    68 // Destructor.
       
    69 // ---------------------------------------------------------------------------
       
    70 //
       
    71 CIkev1PluginSession::~CIkev1PluginSession()
       
    72     {
       
    73     // Cancel client's requests.
       
    74     DoCompleteNegotiateWithHost( KErrCancel );
       
    75     DoCompleteDeleteSession( KErrCancel );
       
    76     DoCompleteNotifyError( KErrCancel );
       
    77     DoCompleteInternalAddressChanged( KErrCancel );    
       
    78     
       
    79     if ( iDialogWaitQueue )
       
    80         {
       
    81         CIkev1Dialog::PurgeDialogQueue( iDialogWaitQueue );
       
    82         }   
       
    83 
       
    84     CIkev1Negotiation* negotiation;    
       
    85     while ( iFirstNegotiation )
       
    86         {
       
    87         negotiation = iFirstNegotiation;
       
    88         delete negotiation; // destructor removes object from queue, too
       
    89         }
       
    90     
       
    91     DoEmptySendQueue();
       
    92     iSendQueue.Close();
       
    93     
       
    94     while ( iIkev1SAs.Count() )
       
    95         {
       
    96         CIkev1SA* ikev1SA = iIkev1SAs[0];
       
    97         iIkev1SAs.Remove(0);
       
    98         delete ikev1SA;
       
    99         }
       
   100     iIkev1SAs.Close();
       
   101     
       
   102     delete iReceiver;
       
   103     delete iSender;
       
   104     delete iIkeData;
       
   105     delete iInternalAddress;
       
   106     
       
   107     iPlugin.IkePluginSessionDeleted( this );
       
   108     }
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 // Constructor.
       
   112 // ---------------------------------------------------------------------------
       
   113 //
       
   114 CIkev1PluginSession::CIkev1PluginSession( TUint32 aVpnIapId,
       
   115                                           TUint32 aVpnNetId,
       
   116                                           TUint32 aVpnInterfaceIndex,
       
   117                                           MIkeDataInterface& aDataInterface,
       
   118                                           CIkev1Plugin& aPlugin,
       
   119                                           CPFKeySocketIf& aPFKeySocketIf,
       
   120                                           MIkeDebug& aDebug )
       
   121 : iVpnIapId( aVpnIapId ),
       
   122   iVpnNetId( aVpnNetId ),
       
   123   iVpnInterfaceIndex( aVpnInterfaceIndex ),
       
   124   iDataInterface( aDataInterface ),
       
   125   iPlugin( aPlugin ),
       
   126   iPFKeySocketIf( aPFKeySocketIf ),
       
   127   iDebug( aDebug )
       
   128     {
       
   129     }
       
   130 
       
   131 // ---------------------------------------------------------------------------
       
   132 // Second phase construction.
       
   133 // ---------------------------------------------------------------------------
       
   134 //
       
   135 void CIkev1PluginSession::ConstructL()
       
   136     {
       
   137     TPtr8 ptr( (TUint8*)&iSAIdSeed, sizeof(iSAIdSeed) );
       
   138     ptr.SetLength( sizeof(iSAIdSeed) );
       
   139     TRandom::RandomL( ptr );  
       
   140     iSAIdSeed &= 0x7fffffff;  // Reset the most significant bit    
       
   141 
       
   142     iReceiver = CIkev1Receiver::NewL( iDataInterface,
       
   143                                       *this );   
       
   144     iSender = CIkev1Sender::NewL( iDataInterface,
       
   145                                   *this,
       
   146                                   iDebug );    
       
   147     
       
   148     DEBUG_LOG1( _L("CIkev1PluginSession::ConstructL, SAId seed: %d"),
       
   149             iSAIdSeed );
       
   150     }    
       
   151 
       
   152 // ---------------------------------------------------------------------------
       
   153 // Handles IKE SA deletion request.
       
   154 // ---------------------------------------------------------------------------
       
   155 //
       
   156 TBool CIkev1PluginSession::DeleteIkeSA( TIkev1SAData* aIkev1SaData,
       
   157                                         TBool aSilentClose )
       
   158     {
       
   159     //
       
   160     // An IKE SA delete request received
       
   161     // Check first does there exists an ongoing negotiation on this IKE
       
   162     // SA deleted and delete this block. 
       
   163     // Allocate a new negotiation with TIkev1SAData and initiate IKE SA
       
   164     // deletion request
       
   165     //
       
   166     DEBUG_LOG1( _L("Deleting IKEv1 SA SAID =  %d"),
       
   167             aIkev1SaData->iSAId );
       
   168     
       
   169     CIkev1Negotiation* negotiation = FindNegotiation( aIkev1SaData->iSAId );
       
   170     while ( negotiation )
       
   171         {
       
   172         delete negotiation; // destructor removes object from queue, too
       
   173         negotiation = FindNegotiation( aIkev1SaData->iSAId );         
       
   174         }
       
   175 
       
   176     TBool started( EFalse );
       
   177 
       
   178     if ( !aSilentClose )
       
   179         {
       
   180         DeleteIpsecSAs( aIkev1SaData->iSAId );
       
   181         
       
   182         TRAPD( err, 
       
   183                 {
       
   184                 // Trap the SendDeleteL -- it can fail, but the failure won't be fatal 
       
   185                 // (delete payload just won't be sent)
       
   186                 negotiation = CIkev1Negotiation::NewL( this,
       
   187                                                        iPFKeySocketIf,
       
   188                                                        iDebug,
       
   189                                                        aIkev1SaData,
       
   190                                                        RESPONDER ); // Nevermind INITIATOR or RESPONDER
       
   191                 negotiation->SendDeleteL( PROTO_ISAKMP );
       
   192                 } );
       
   193                 
       
   194         delete negotiation;
       
   195         negotiation = NULL;
       
   196         
       
   197         if ( err == KErrNone ) 
       
   198             {
       
   199             // DELETE payload sent succesfully.
       
   200             DEBUG_LOG( _L("CIkev1PluginSession::DeleteIkeSAL() IKEv1 delete send OK") );            
       
   201             started = ETrue;
       
   202             }
       
   203         else 
       
   204             {
       
   205             DEBUG_LOG1( _L("CIkev1PluginSession::DeleteIkeSAL() IKEv1 delete send failed, err=%d"), err );
       
   206             }
       
   207         }
       
   208 #ifdef _DEBUG
       
   209     else
       
   210         {
       
   211         DEBUG_LOG( _L("Forced close, no delete payload(s) sent"));
       
   212         }
       
   213 #endif    
       
   214     ExpireIkev1SA( aIkev1SaData->iSAId );  // Set expired to delete IKE SA
       
   215     
       
   216     if ( FindIkev1SA() == NULL &&
       
   217          FirstNegotiation() == NULL )
       
   218         {
       
   219         // Set error status, when expired IKE SA was the only IKE SA and there
       
   220         // is no ongoing negotiation.        
       
   221         iErrorStatus = KKmdIkeNegotFailed;
       
   222         }
       
   223 
       
   224     return started;
       
   225     }
       
   226 
       
   227 // ---------------------------------------------------------------------------
       
   228 // Handles IKE SA rekeying request.
       
   229 // ---------------------------------------------------------------------------
       
   230 //
       
   231 void CIkev1PluginSession::RekeyIkeSAL( TIkev1SAData* aIkev1SaData,
       
   232                                        CSARekeyInfo* aSaRekeyInfo )
       
   233     {
       
   234     CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this,
       
   235                                                               iPFKeySocketIf,
       
   236                                                               iDebug,
       
   237                                                               aIkev1SaData->iRemoteAddr,
       
   238                                                               EFalse );
       
   239     CleanupStack::PushL( negotiation );
       
   240     negotiation->SetRekeyInfo( aSaRekeyInfo );                
       
   241     negotiation->InitNegotiationL();
       
   242     if ( negotiation->Finished() )
       
   243         {
       
   244         CleanupStack::PopAndDestroy( negotiation );
       
   245         }
       
   246     else 
       
   247         {
       
   248         CleanupStack::Pop( negotiation );  
       
   249         }
       
   250     }
       
   251 
       
   252 // ---------------------------------------------------------------------------
       
   253 // Handles IKE SA keepalive request.
       
   254 // ---------------------------------------------------------------------------
       
   255 //
       
   256 void CIkev1PluginSession::KeepAliveIkeSAL( TIkev1SAData* aIkev1SaData )
       
   257     {
       
   258     CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this,
       
   259                                                               iPFKeySocketIf,
       
   260                                                               iDebug,
       
   261                                                               aIkev1SaData,
       
   262                                                               RESPONDER );
       
   263     CleanupStack::PushL( negotiation );
       
   264     negotiation->SendKeepAliveMsgL( aIkev1SaData );
       
   265     if ( negotiation->Finished() )
       
   266         {
       
   267         CleanupStack::PopAndDestroy( negotiation );
       
   268         }
       
   269     else
       
   270         {
       
   271         CleanupStack::Pop( negotiation );  
       
   272         }
       
   273     }
       
   274 
       
   275 // ---------------------------------------------------------------------------
       
   276 // Creates IKE SA.
       
   277 // ---------------------------------------------------------------------------
       
   278 //
       
   279 void CIkev1PluginSession::CreateIkev1SAL( TIkev1SAData& aIkev1SaData,
       
   280                                           CSARekeyInfo* aSaRekey )
       
   281     {
       
   282     CIkev1SA* ikev1SA = CIkev1SA::NewL( *this,
       
   283                                         aIkev1SaData,
       
   284                                         aSaRekey,
       
   285                                         iDebug );
       
   286     
       
   287     if ( !aIkev1SaData.iInitiator )
       
   288         {
       
   289         // Move SPI list from previous IKE SA to new IKE SA
       
   290         for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   291             {
       
   292             CIkev1SA* previousSA = iIkev1SAs[i];
       
   293             if ( previousSA->iSPIList != NULL )
       
   294                 {
       
   295                 DEBUG_LOG(_L("Move SPI list to new IKE SA"));
       
   296                 delete ikev1SA->iSPIList;
       
   297                 ikev1SA->iSPIList = previousSA->iSPIList;
       
   298                 previousSA->iSPIList = new (ELeave) CIpsecSPIList(1);  // Dummy;
       
   299                 break;
       
   300                 }
       
   301             }        
       
   302         }        
       
   303     
       
   304     // Cancel IKE SA rekeying from other IKE SAs.
       
   305     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   306         {
       
   307         CIkev1SA* cancelSA = iIkev1SAs[i];
       
   308         cancelSA->CancelRekey();
       
   309         }
       
   310     
       
   311     CleanupStack::PushL( ikev1SA );
       
   312     iIkev1SAs.AppendL( ikev1SA );
       
   313     CleanupStack::Pop( ikev1SA );    
       
   314     }
       
   315 
       
   316 // ---------------------------------------------------------------------------
       
   317 // Updates IKE SA.
       
   318 // ---------------------------------------------------------------------------
       
   319 //
       
   320 void CIkev1PluginSession::UpdateIkev1SAL( TUint32 aSaId,
       
   321                                           TBool aExpired,
       
   322                                           TIkev1SAData* aIkev1SaData )
       
   323     {
       
   324     if ( !aExpired )
       
   325         {
       
   326         CIkev1SA* Ikev1SA = FindIkev1SAWithId( aSaId );
       
   327         if ( Ikev1SA )
       
   328             {
       
   329             Ikev1SA->UpdateSAL( aExpired, aIkev1SaData );
       
   330             }
       
   331         }
       
   332     else
       
   333         {
       
   334         ExpireIkev1SA( aSaId );
       
   335         }
       
   336     }
       
   337 
       
   338 // ---------------------------------------------------------------------------
       
   339 // Expires IKE SA.
       
   340 // ---------------------------------------------------------------------------
       
   341 //
       
   342 void CIkev1PluginSession::ExpireIkev1SA( TUint32 aSaId )
       
   343     {
       
   344     CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId );
       
   345     if ( ikev1SA )
       
   346         {
       
   347         ikev1SA->ExpireSA();
       
   348         }
       
   349     }
       
   350 
       
   351 // ---------------------------------------------------------------------------
       
   352 // Removes IKE SA.
       
   353 // ---------------------------------------------------------------------------
       
   354 //
       
   355 void CIkev1PluginSession::RemoveIkeSA( CIkev1SA* aIkev1Sa,
       
   356                                        TInt aStatus )
       
   357     {        
       
   358     TInt dpdRetryCount( 0 );
       
   359     
       
   360     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   361         {
       
   362         CIkev1SA* sa = iIkev1SAs[i]; 
       
   363         if ( aIkev1Sa == sa )
       
   364             {
       
   365             // Remove IKE SA from array.
       
   366             dpdRetryCount = sa->iHdr.iDPDRetry;
       
   367             iIkev1SAs.Remove(i);
       
   368             delete sa;
       
   369             break;
       
   370             }   
       
   371         }
       
   372     
       
   373     if ( (iErrorStatus == KErrNone) &&
       
   374          (dpdRetryCount > KMaxDpdRetryCount) &&
       
   375          (FindIkev1SA() == NULL) )
       
   376         {
       
   377         // If DPD retry count was reached for only IKE SA, set error status.
       
   378         iErrorStatus = KKmdIkeNoResponseErr;        
       
   379         }
       
   380         
       
   381     // If session deletion has been requested, complete session deletion
       
   382     // request.        
       
   383     DoCompleteDeleteSession( aStatus );
       
   384         
       
   385     // If fatal error has occured, complete error notification.    
       
   386     if ( iErrorStatus != KErrNone )
       
   387         {
       
   388         DoHandleError( iErrorStatus );
       
   389         }
       
   390     }
       
   391 
       
   392 // IKE SA find methods.
       
   393 
       
   394 CIkev1SA* CIkev1PluginSession::FindIkev1SA()
       
   395     {
       
   396     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   397         {
       
   398         CIkev1SA* sa = iIkev1SAs[i]; 
       
   399         if ( (!sa->IsExpired()) )
       
   400             {
       
   401             return sa;
       
   402             }   
       
   403         }
       
   404     return NULL;
       
   405     }
       
   406 
       
   407 CIkev1SA* CIkev1PluginSession::FindIkev1SA( const TCookie& aCookie_I,
       
   408                                             const TCookie& aCookie_R )
       
   409     {
       
   410     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   411         {
       
   412         CIkev1SA* sa = iIkev1SAs[i]; 
       
   413         if ( (sa->iHdr.iCookie_I ==  aCookie_I) &&
       
   414              (sa->iHdr.iCookie_R ==  aCookie_R) &&
       
   415              (!sa->IsExpired()) )
       
   416             {
       
   417             return sa;
       
   418             }   
       
   419         }
       
   420     return NULL;
       
   421     }
       
   422 
       
   423 CIkev1SA* CIkev1PluginSession::FindIkev1SAWithId( TUint32 aSaId )
       
   424     {
       
   425     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   426         {
       
   427         CIkev1SA* sa = iIkev1SAs[i]; 
       
   428         if ( (sa->iHdr.iSAId == aSaId) &&
       
   429              (!sa->IsExpired()) )
       
   430             {
       
   431             return sa;
       
   432             }   
       
   433         }
       
   434     return NULL;
       
   435     }
       
   436 
       
   437 CIkev1SA* CIkev1PluginSession::FindIkev1SA( const TInetAddr& aAddr )
       
   438     {
       
   439     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   440         {
       
   441         CIkev1SA* sa = iIkev1SAs[i]; 
       
   442         if (  sa->iHdr.iRemoteAddr.Match(aAddr) &&
       
   443               (!sa->IsExpired()) ) 
       
   444             {
       
   445             return sa;
       
   446             }   
       
   447         }
       
   448     return NULL;
       
   449     }
       
   450 
       
   451 CIkev1SA* CIkev1PluginSession::FindIkev1SA( const TInetAddr& aAddr,
       
   452                                             TUint32 aInboundSpi )
       
   453     {
       
   454     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
   455         {
       
   456         CIkev1SA* sa = iIkev1SAs[i]; 
       
   457         if (  sa->iHdr.iRemoteAddr.Match(aAddr) &&
       
   458               (!sa->IsExpired()) ) 
       
   459             {
       
   460             if ( sa->FindIpsecSPI(aInboundSpi, ETrue) )
       
   461                 {
       
   462                 return sa;
       
   463                 }
       
   464             }   
       
   465         }
       
   466     return NULL;
       
   467     }
       
   468 
       
   469 TIkev1SAData* CIkev1PluginSession::FindIkev1SAData()
       
   470     {
       
   471     TIkev1SAData* saData = NULL;        
       
   472     CIkev1SA* ikev1SA = FindIkev1SA();
       
   473     if ( ikev1SA )
       
   474         {
       
   475         saData = (TIkev1SAData*)&ikev1SA->iHdr;
       
   476         }
       
   477     return saData;
       
   478     }
       
   479 
       
   480 TIkev1SAData* CIkev1PluginSession::FindIkev1SAData( const TCookie& aCookie_I,
       
   481                                                     const TCookie& aCookie_R )
       
   482     {
       
   483     TIkev1SAData* saData = NULL;        
       
   484     CIkev1SA* ikev1SA = FindIkev1SA( aCookie_I, aCookie_R );
       
   485     if ( ikev1SA )
       
   486         {
       
   487         saData = (TIkev1SAData*)&ikev1SA->iHdr;
       
   488         }
       
   489     return saData;
       
   490     }
       
   491 
       
   492 TIkev1SAData* CIkev1PluginSession::FindIkev1SAData( TUint32 aSaId )
       
   493     {
       
   494     TIkev1SAData* saData = NULL;        
       
   495     CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId );
       
   496     if ( ikev1SA )
       
   497         {
       
   498         saData = (TIkev1SAData*)&ikev1SA->iHdr;
       
   499         }
       
   500     return saData;
       
   501     }
       
   502 
       
   503 TIkev1SAData* CIkev1PluginSession::FindIkev1SAData( const TInetAddr& aAddr,
       
   504                                                     TUint32 aInboundSpi )
       
   505     {
       
   506     TIkev1SAData* saData = NULL;        
       
   507     CIkev1SA* ikev1SA = FindIkev1SA( aAddr, aInboundSpi );
       
   508     if ( ikev1SA )
       
   509         {
       
   510         saData = (TIkev1SAData*)&ikev1SA->iHdr;
       
   511         }
       
   512     return saData;
       
   513     }    
       
   514 
       
   515 TIkev1SAData* CIkev1PluginSession::FindIkev1SADataWithAddr( const TInetAddr& aAddr )
       
   516     {
       
   517     TIkev1SAData* saData = NULL;        
       
   518     CIkev1SA* ikev1SA = FindIkev1SA( aAddr );
       
   519     if ( ikev1SA )
       
   520         {
       
   521         saData = (TIkev1SAData*)&ikev1SA->iHdr;
       
   522         }
       
   523     return saData;
       
   524     }    
       
   525 
       
   526 // ---------------------------------------------------------------------------
       
   527 // Handles IPsec SA deletion request.
       
   528 // ---------------------------------------------------------------------------
       
   529 //
       
   530 void CIkev1PluginSession::DeleteIpsecSAL( TIkev1SAData* aIkev1SaData,
       
   531                                           TIpsecSPI* aIpsecSpi )
       
   532     {
       
   533     //
       
   534     // Send a delete payload for specified IPSec SA 
       
   535     //
       
   536     CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this,
       
   537                                                               iPFKeySocketIf,
       
   538                                                               iDebug,                                                              
       
   539                                                               aIkev1SaData,
       
   540                                                               RESPONDER );
       
   541     CleanupStack::PushL( negotiation );
       
   542     negotiation->SendDeleteL( aIpsecSpi->iProtocol,
       
   543                               aIpsecSpi->iSPI );
       
   544     CleanupStack::PopAndDestroy( negotiation );
       
   545     }
       
   546 
       
   547 // ---------------------------------------------------------------------------
       
   548 // Deletes IPsec SAs.
       
   549 // ---------------------------------------------------------------------------
       
   550 //
       
   551 void CIkev1PluginSession::DeleteIpsecSAs( TUint32 aSaId )
       
   552     {
       
   553     CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId );
       
   554     if ( ikev1SA )
       
   555         {
       
   556         ikev1SA->DeleteIpsecSAs(); 
       
   557         }   
       
   558     }
       
   559 
       
   560 // ---------------------------------------------------------------------------
       
   561 // Deletes IPsec SPI.
       
   562 // ---------------------------------------------------------------------------
       
   563 //
       
   564 TBool CIkev1PluginSession::DeleteIpsecSpi( TUint32 aSaId,
       
   565                                            TUint32 aSpi,
       
   566                                            TBool aInbound )
       
   567     {
       
   568     TBool status = EFalse;
       
   569     CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId );
       
   570     if ( ikev1SA )
       
   571         {
       
   572         status = ikev1SA->DeleteIpsecSPI( aSpi, aInbound );
       
   573         }
       
   574     return status;
       
   575     }
       
   576 
       
   577 // ---------------------------------------------------------------------------
       
   578 // Adds IPsec SPI to IKE SA.
       
   579 // ---------------------------------------------------------------------------
       
   580 //
       
   581 void CIkev1PluginSession::AddIpsecSPIToSAL( TUint32 aSaId,
       
   582                                             TIpsecSPI& aIpsecSpi )
       
   583     {
       
   584     CIkev1SA* ikev1SA = FindIkev1SAWithId( aSaId );
       
   585     if ( ikev1SA )
       
   586         {
       
   587         ikev1SA->AddIpsecSPIL( aIpsecSpi );
       
   588         }
       
   589     }
       
   590 
       
   591 // ---------------------------------------------------------------------------
       
   592 // Returns dialog anchor.
       
   593 // ---------------------------------------------------------------------------
       
   594 //
       
   595 CIkev1Dialog** CIkev1PluginSession::DialogAnchor()
       
   596     {
       
   597     return &iDialogWaitQueue;
       
   598     }
       
   599 
       
   600 // ---------------------------------------------------------------------------
       
   601 // Returns debug trace interface.
       
   602 // ---------------------------------------------------------------------------
       
   603 //
       
   604 MIkeDebug& CIkev1PluginSession::Debug()
       
   605     {
       
   606     return iDebug;
       
   607     }
       
   608 
       
   609 // ---------------------------------------------------------------------------
       
   610 // Gets SA id.
       
   611 // ---------------------------------------------------------------------------
       
   612 //
       
   613 TUint32 CIkev1PluginSession::GetSAId()
       
   614     {
       
   615     iSAIdSeed++;
       
   616     return iSAIdSeed;
       
   617     }
       
   618 
       
   619 // ---------------------------------------------------------------------------
       
   620 // Deletes ISAKMP SAs.
       
   621 // ---------------------------------------------------------------------------
       
   622 //
       
   623 void CIkev1PluginSession::DeleteISAKMPSAsL( TDeleteISAKMP* aDeletePayload,
       
   624                                             const CIkev1Negotiation& aInfoNegotiation )
       
   625     {
       
   626     TCookie cookie_I, cookie_R;
       
   627 
       
   628     // It should always be only one.
       
   629     for ( TInt i=0; i < aDeletePayload->NumSPI(); i++ )
       
   630         {
       
   631         if ( aDeletePayload->SPISize() < 2 * ISAKMP_COOKIE_SIZE ) //The ISAKMPSA SPI is the union of both cookies
       
   632             {
       
   633             DEBUG_LOG( _L("Bad SPI Size for a ISAKMP SA. (SA Not deleted)") );
       
   634             return;
       
   635             }
       
   636         cookie_I.Copy( aDeletePayload->SPI(i), ISAKMP_COOKIE_SIZE );
       
   637         cookie_R.Copy( aDeletePayload->SPI(i) + ISAKMP_COOKIE_SIZE,
       
   638                        ISAKMP_COOKIE_SIZE);
       
   639 
       
   640         CIkev1Negotiation* neg = iFirstNegotiation;
       
   641         while ( neg )
       
   642             {
       
   643             CIkev1Negotiation* current = neg;
       
   644             neg = neg->iNext;
       
   645 
       
   646             // Delete any active negotiations with the same cookies.
       
   647             // Currently used negotiation is not deleted.
       
   648             if ( ( current != &aInfoNegotiation ) &&
       
   649                  ( current->iCookie_I == cookie_I ) &&
       
   650                  ( current->iCookie_R == cookie_R ) )
       
   651                 {
       
   652                 DEBUG_LOG( _L("Active negotiation deleted.") );
       
   653                 delete current;
       
   654                 current = NULL;
       
   655                 }
       
   656             }
       
   657         
       
   658         // Expire IKE SA.
       
   659         TIkev1SAData* sa = FindIkev1SAData( cookie_I, cookie_R );
       
   660         if ( sa )
       
   661             {
       
   662             UpdateIkev1SAL( sa->iSAId, ETrue );
       
   663             }
       
   664         }
       
   665     }
       
   666 
       
   667 // ---------------------------------------------------------------------------
       
   668 // Gets local IP address.
       
   669 // ---------------------------------------------------------------------------
       
   670 //
       
   671 TInt CIkev1PluginSession::GetLocalAddress( TInetAddr& aAddr )
       
   672     {
       
   673     TInt err( KErrNone );
       
   674     if ( iLocalAddr.IsUnspecified() )
       
   675         {
       
   676         err = iDataInterface.GetLocalAddress( iLocalAddr );
       
   677         }
       
   678     
       
   679     aAddr = iLocalAddr;
       
   680     return err;
       
   681     }
       
   682 
       
   683 // ---------------------------------------------------------------------------
       
   684 // Sends IKE message.
       
   685 // ---------------------------------------------------------------------------
       
   686 //    
       
   687 void CIkev1PluginSession::SendIkeMsgL( const TDesC8& aIkeMsg,
       
   688                                        TInetAddr& aDestAddr,
       
   689                                        TBool aUseNatPort )
       
   690     {
       
   691     // Construct buffer for storing IKE message data.
       
   692     TInt localPort = ( aUseNatPort ?
       
   693                        IkeSocket::KIkePort4500 :
       
   694                        IkeSocket::KIkePort500 );    
       
   695     TInt length = aIkeMsg.Length();    
       
   696     if ( localPort == IkeSocket::KIkePort4500 )
       
   697         {
       
   698         // Reserve space for <non-ESP marker>.
       
   699         length += NON_ESP_MARKER_SIZE;
       
   700         }    
       
   701     HBufC8* ikeMsg = HBufC8::NewL( length );    
       
   702     TPtr8 ptr = ikeMsg->Des();    
       
   703     if ( localPort == IkeSocket::KIkePort4500 )
       
   704         {    
       
   705         // Append <non-ESP marker> to the beginning of IKE message.
       
   706         TUint32 nonEspMarker = NON_ESP_MARKER;        
       
   707         TUint8* nonEspPtr = (TUint8*)&nonEspMarker;
       
   708         ptr.Append( nonEspPtr, NON_ESP_MARKER_SIZE );
       
   709         } 
       
   710     // Append IKE message data to descriptor.
       
   711     ptr.Append( aIkeMsg );    
       
   712     
       
   713     DoSendUdpDataL( ikeMsg, // Ownership transferred.
       
   714                     aDestAddr,
       
   715                     localPort,
       
   716                     0 );
       
   717     }
       
   718 
       
   719 // ---------------------------------------------------------------------------
       
   720 // Sends NAT keep-alive packet.
       
   721 // ---------------------------------------------------------------------------
       
   722 //    
       
   723 void CIkev1PluginSession::SendNatKeepAliveL( TInetAddr& aDestAddr,
       
   724                                              const TDesC8& aData,
       
   725                                              TUint8 aDscp )
       
   726     {
       
   727     DEBUG_LOG(_L("CIkev1PluginSession::SendNatKeepAliveL"));
       
   728     HBufC8* udpData = HBufC8::NewL( aData.Length() );
       
   729     *udpData = aData;
       
   730     TInt localPort = aDestAddr.Port();
       
   731     DoSendUdpDataL( udpData, // Ownership transferred.
       
   732                     aDestAddr,
       
   733                     localPort,
       
   734                     aDscp );
       
   735     }
       
   736 
       
   737 // ---------------------------------------------------------------------------
       
   738 // Sends Nokia NAT keep-alive packet.
       
   739 // ---------------------------------------------------------------------------
       
   740 //    
       
   741 void CIkev1PluginSession::SendNokiaNatKeepAliveL( TInetAddr& aDestAddr,
       
   742                                                   const TDesC8& aData,
       
   743                                                   TUint8 aDscp )    
       
   744     {
       
   745     DEBUG_LOG(_L("CIkev1PluginSession::SendNokiaNatKeepAliveL"));
       
   746     SendNatKeepAliveL( aDestAddr,
       
   747                        aData,
       
   748                        aDscp );
       
   749     }
       
   750 
       
   751 // ---------------------------------------------------------------------------
       
   752 // Handles completion of IKE SA establishment.
       
   753 // ---------------------------------------------------------------------------
       
   754 //    
       
   755 void CIkev1PluginSession::IkeSaCompleted( TInt aStatus,
       
   756                                           CInternalAddress* aInternalAddress )
       
   757     {
       
   758     delete iInternalAddress;
       
   759     iInternalAddress = aInternalAddress;
       
   760     
       
   761     DoCompleteNegotiateWithHost( aStatus );
       
   762     }
       
   763 
       
   764 // ---------------------------------------------------------------------------
       
   765 // Deletes negotiation object.
       
   766 // ---------------------------------------------------------------------------
       
   767 //    
       
   768 void CIkev1PluginSession::DeleteNegotiation( CIkev1Negotiation* aNegotiation )
       
   769     {
       
   770     TInt err = ErrorStatus();
       
   771     delete aNegotiation;        
       
   772     
       
   773     if ( err == KErrNone &&
       
   774          (iClientStatusNegotiate != NULL ||
       
   775           iClientStatusDelete != NULL) &&
       
   776          (FindIkev1SA() == NULL) )
       
   777         {
       
   778         // If negotiate or delete session request has been issued, and
       
   779         // there are no IKE SAs, client is completed with error.
       
   780         err = KKmdIkeNegotFailed;
       
   781         }
       
   782 
       
   783     DEBUG_LOG1(_L("IKEv1 negotiation deleted, status=%d"),
       
   784             err );
       
   785     
       
   786     if ( err != KErrNone )
       
   787         {
       
   788         //
       
   789         // IKE negotiation failed.
       
   790         //
       
   791         DoHandleError( err );
       
   792         }        
       
   793     }
       
   794 
       
   795 // Negotiation linking and find methods.
       
   796 
       
   797 void CIkev1PluginSession::LinkNegotiation( CIkev1Negotiation* aNegotiation )
       
   798     {  
       
   799     aNegotiation->iNext = iFirstNegotiation;  
       
   800     iFirstNegotiation = aNegotiation; 
       
   801     }    
       
   802     
       
   803 CIkev1Negotiation* CIkev1PluginSession::FirstNegotiation()
       
   804     {
       
   805     return iFirstNegotiation;
       
   806     }
       
   807 
       
   808 CIkev1Negotiation* CIkev1PluginSession::FindNegotiation( TCookie aInit,
       
   809                                                          TCookie aResp,
       
   810                                                          TUint8 aExchange,
       
   811                                                          TUint32 aMsgId )
       
   812     {
       
   813     CIkev1Negotiation* negotiation;
       
   814     TCookie NULL_COOKIE;
       
   815     NULL_COOKIE.FillZ(ISAKMP_COOKIE_SIZE);
       
   816 
       
   817     if ( aExchange == ISAKMP_EXCHANGE_INFO )
       
   818         {
       
   819         for ( negotiation = iFirstNegotiation;
       
   820               negotiation;
       
   821               negotiation = negotiation->iNext )
       
   822             {
       
   823             if ( (negotiation->iCookie_I.Compare(aInit) == 0 ) &&
       
   824                  ((negotiation->iCookie_R.Compare(aResp) == 0 ) ||
       
   825                    (negotiation->iCookie_R.Compare(NULL_COOKIE) == 0)) )
       
   826                 {   
       
   827                 return negotiation;
       
   828                 }   
       
   829             }
       
   830         
       
   831         }   
       
   832     else
       
   833         {
       
   834         for ( negotiation = iFirstNegotiation;
       
   835               negotiation;
       
   836               negotiation = negotiation->iNext )
       
   837             {            
       
   838             if ( negotiation->iCookie_I.Compare(aInit) == 0 )
       
   839                 {
       
   840                 if ( (negotiation->iMessageId == aMsgId) ||
       
   841                      (negotiation->iMessageId == 0) )
       
   842                     {
       
   843                     if ( (negotiation->iCookie_R.Compare(aResp) == 0 ) ||
       
   844                          (negotiation->iCookie_R.Compare(NULL_COOKIE) == 0) ||
       
   845                          (aResp.Compare(NULL_COOKIE) == 0) )
       
   846                         {
       
   847                         return negotiation;
       
   848                         }
       
   849                     }
       
   850                 }
       
   851             }           
       
   852         }   
       
   853 
       
   854     return NULL; // Not found
       
   855     }
       
   856 
       
   857 CIkev1Negotiation* CIkev1PluginSession::FindNegotiation( TUint32 aSaId )
       
   858     {
       
   859     //
       
   860     // Find IKEv1 negotiation object using SA id as search argument 
       
   861     //
       
   862     CIkev1Negotiation* negotiation = iFirstNegotiation;
       
   863     while ( negotiation )
       
   864         {
       
   865         if ( negotiation->SAId() == aSaId )
       
   866             {   
       
   867             break;
       
   868             }   
       
   869 
       
   870         negotiation = negotiation->iNext;
       
   871         }   
       
   872     return negotiation;     
       
   873     }
       
   874 
       
   875 void CIkev1PluginSession::RemoveNegotiation( CIkev1Negotiation* aNegotiation )
       
   876     {
       
   877     CIkev1Negotiation* prev = NULL;
       
   878     CIkev1Negotiation* negotiation  = iFirstNegotiation;
       
   879     
       
   880     while ( negotiation )
       
   881         {
       
   882         if ( negotiation == aNegotiation )
       
   883             {
       
   884             if ( prev )
       
   885                 {
       
   886                 prev->iNext = negotiation->iNext;
       
   887                }
       
   888            else 
       
   889                {
       
   890                iFirstNegotiation = negotiation->iNext;
       
   891                }
       
   892             break;  
       
   893             }
       
   894         prev = negotiation;
       
   895         negotiation = negotiation->iNext;
       
   896         }   
       
   897     }
       
   898 
       
   899 // ---------------------------------------------------------------------------
       
   900 // Handles completion of authentication dialog processing.
       
   901 // ---------------------------------------------------------------------------
       
   902 //    
       
   903 TInt CIkev1PluginSession::AuthDialogCompletedL( CAuthDialogInfo* aUserInfo )
       
   904     {
       
   905     CIkev1Negotiation* negotiation = FindNegotiation( aUserInfo->SAId() );
       
   906     if ( negotiation )
       
   907         {
       
   908         DEBUG_LOG1( _L("Dialog completed for SAID: %d"),
       
   909                 aUserInfo->SAId() );
       
   910         
       
   911         negotiation->AuthDialogCompletedL(aUserInfo);
       
   912         if ( negotiation->Finished() )
       
   913             {
       
   914             DeleteNegotiation( negotiation );
       
   915             }   
       
   916         return KErrNone;
       
   917         }   
       
   918     DEBUG_LOG1( _L("Dialog completed, no negotiation found for SAID: %d"),
       
   919             aUserInfo->SAId() );
       
   920     return KErrNotFound;
       
   921     }
       
   922 
       
   923 
       
   924 // ---------------------------------------------------------------------------
       
   925 // Handles change of internal address.
       
   926 // ---------------------------------------------------------------------------
       
   927 //    
       
   928 TBool CIkev1PluginSession::InternalAddressChangedL( const CInternalAddress& aInternalAddr )
       
   929     {
       
   930     TBool internalAddressChanged( ETrue );
       
   931     
       
   932     if ( iInternalAddress )
       
   933         {
       
   934         if ( iInternalAddress->iClientIntAddr.Match(aInternalAddr.iClientIntAddr) )                    
       
   935             {
       
   936             internalAddressChanged = EFalse;
       
   937             }
       
   938         }        
       
   939     
       
   940     delete iInternalAddress;
       
   941     iInternalAddress = NULL;
       
   942     iInternalAddress = CInternalAddress::NewL( aInternalAddr );
       
   943     
       
   944     if ( internalAddressChanged )
       
   945         {
       
   946         DoCompleteInternalAddressChanged( KErrNone );
       
   947         }
       
   948     
       
   949     return internalAddressChanged;
       
   950     }
       
   951 
       
   952 // ---------------------------------------------------------------------------
       
   953 // Gets acceptable IPsec policies for specified selectors.
       
   954 // ---------------------------------------------------------------------------
       
   955 //
       
   956 CIpsecSaSpecList* CIkev1PluginSession::GetIpseSaSpecListLC( const TInetAddr& aLocalAddr, const TInetAddr& aLocalMask, 
       
   957                                                             const TInetAddr& aRemoteAddr, const TInetAddr& aRemoteMask,
       
   958                                                             TInt aProtocol )
       
   959 
       
   960     {
       
   961     return iPlugin.GetIpseSaSpecListLC( aLocalAddr, aLocalMask, 
       
   962                                         aRemoteAddr, aRemoteMask,
       
   963                                         aProtocol, iVpnNetId );
       
   964     }
       
   965 
       
   966 // ---------------------------------------------------------------------------
       
   967 // Matches destination address to remote address in IKE policy data.
       
   968 // ---------------------------------------------------------------------------
       
   969 //
       
   970 TBool CIkev1PluginSession::MatchDestinationAddress( const TInetAddr& aDestAddr )
       
   971     {
       
   972     TBool match( EFalse );
       
   973     
       
   974     if ( iIkeData )
       
   975         {
       
   976         match = iIkeData->iAddr.Match( aDestAddr );
       
   977         }    
       
   978     return match;
       
   979     }
       
   980 
       
   981 // ---------------------------------------------------------------------------
       
   982 // Handles fatal error.
       
   983 // ---------------------------------------------------------------------------
       
   984 //
       
   985 void CIkev1PluginSession::HandleError( TInt aStatus )
       
   986     {
       
   987     DoHandleError( aStatus );
       
   988     }
       
   989 
       
   990 // ---------------------------------------------------------------------------
       
   991 // Returns error status.
       
   992 // ---------------------------------------------------------------------------
       
   993 //
       
   994 TInt CIkev1PluginSession::ErrorStatus()
       
   995     {
       
   996     return iErrorStatus;
       
   997     }
       
   998 
       
   999 // ---------------------------------------------------------------------------
       
  1000 // Sets error status.
       
  1001 // ---------------------------------------------------------------------------
       
  1002 //
       
  1003 void CIkev1PluginSession::SetErrorStatus( TInt aStatus )
       
  1004     {
       
  1005     if ( iErrorStatus == KErrNone )
       
  1006         {
       
  1007         iErrorStatus = aStatus;
       
  1008         }
       
  1009     }
       
  1010 
       
  1011 // ---------------------------------------------------------------------------
       
  1012 // Returns VPN IAP id.
       
  1013 // ---------------------------------------------------------------------------
       
  1014 //
       
  1015 TUint32 CIkev1PluginSession::VpnIapId()
       
  1016     {
       
  1017     return iVpnIapId;
       
  1018     }
       
  1019 
       
  1020 // ---------------------------------------------------------------------------
       
  1021 // Returns VPN interface index.
       
  1022 // ---------------------------------------------------------------------------
       
  1023 //
       
  1024 TUint32 CIkev1PluginSession::VpnInterfaceIndex()
       
  1025     {
       
  1026     return iVpnInterfaceIndex;
       
  1027     }
       
  1028 
       
  1029 // ---------------------------------------------------------------------------
       
  1030 // Returns IKE policy data.
       
  1031 // ---------------------------------------------------------------------------
       
  1032 //
       
  1033 CIkeData& CIkev1PluginSession::IkeData()
       
  1034     {
       
  1035     __ASSERT_DEBUG( iIkeData != NULL,
       
  1036                     User::Invariant() );
       
  1037     return *iIkeData;
       
  1038     }
       
  1039 
       
  1040 // ---------------------------------------------------------------------------
       
  1041 // Returns UID.
       
  1042 // ---------------------------------------------------------------------------
       
  1043 //
       
  1044 TUint32 CIkev1PluginSession::Uid()
       
  1045     {
       
  1046     return iPlugin.Uid();
       
  1047     }
       
  1048 
       
  1049 // ---------------------------------------------------------------------------
       
  1050 // Returns event logger interface.
       
  1051 // ---------------------------------------------------------------------------
       
  1052 //
       
  1053 MKmdEventLoggerIf& CIkev1PluginSession::EventLogger()
       
  1054     {
       
  1055     return iPlugin.EventLogger();
       
  1056     }      
       
  1057 
       
  1058 // ---------------------------------------------------------------------------
       
  1059 // Returns internal address (NULL if does not exist). 
       
  1060 // ---------------------------------------------------------------------------
       
  1061 //
       
  1062 CInternalAddress* CIkev1PluginSession::InternalAddressL()
       
  1063     {
       
  1064     DEBUG_LOG(_L("CIkev1PluginSession::InternalAddressL"));
       
  1065     
       
  1066     CInternalAddress* internalAddress = NULL;
       
  1067     if ( iInternalAddress != NULL )
       
  1068         {
       
  1069         internalAddress = CInternalAddress::NewL( *iInternalAddress );    
       
  1070         }
       
  1071     return internalAddress;            
       
  1072     }
       
  1073 
       
  1074 // ---------------------------------------------------------------------------
       
  1075 // From class MIkev1SenderCallback
       
  1076 // Handles completion of sending.
       
  1077 // ---------------------------------------------------------------------------
       
  1078 //
       
  1079 void CIkev1PluginSession::SendUdpDataCompleted( TInt aStatus )
       
  1080     {    
       
  1081     if ( iSendQueue.Count() != 0 )
       
  1082         {
       
  1083         // Send queue is not empty.
       
  1084         // Send next item from queue.
       
  1085         TIkeSendQueueItem item = iSendQueue[0];
       
  1086         HBufC8* udpData = item.UdpData();
       
  1087         TInetAddr destAddr = item.DestAddr();
       
  1088         TInt localPort = item.LocalPort();
       
  1089         TUint8 dscp = item.Dscp();
       
  1090         iSendQueue.Remove(0);
       
  1091         DoSendUdpData( udpData,
       
  1092                        destAddr,
       
  1093                        localPort,
       
  1094                        dscp );
       
  1095         
       
  1096         }
       
  1097     else
       
  1098         {
       
  1099         // IKE message send queue is empty.
       
  1100         // If session deletion has been requested, complete request.
       
  1101         DoCompleteDeleteSession( aStatus );
       
  1102         }
       
  1103     }
       
  1104 
       
  1105 // ---------------------------------------------------------------------------
       
  1106 // Handles PFKEY message.
       
  1107 // ---------------------------------------------------------------------------
       
  1108 //
       
  1109 void CIkev1PluginSession::PfkeyMessageReceived( const TPfkeyMessage& aPfkeyMessage )
       
  1110     {
       
  1111     TRAPD( err, DoPfkeyMessageReceivedL( aPfkeyMessage) );
       
  1112     err = err;
       
  1113     DEBUG_LOG1(_L("CIkev1PluginSession::PfkeyMessageReceivedL, err=%d"), err);
       
  1114     }
       
  1115 
       
  1116 // Methods to build and send PFKEY API primitives to IPsec
       
  1117 
       
  1118 void CIkev1PluginSession::AcquireSAError( TIpsecSAData& aSAData,
       
  1119                                           TInt aError )
       
  1120     {
       
  1121     iPlugin.AcquireSAError( aSAData, aError );
       
  1122     }
       
  1123 
       
  1124 void CIkev1PluginSession::UpdateSAL( TIpsecSAData& aSaData )
       
  1125     {
       
  1126     iPlugin.UpdateSAL( aSaData );
       
  1127     }
       
  1128 
       
  1129 void CIkev1PluginSession::AddSAL( TIpsecSAData& aSaData )
       
  1130     {
       
  1131     iPlugin.AddSAL( aSaData );
       
  1132     }
       
  1133 
       
  1134 void CIkev1PluginSession::DeleteIpsecSA( TIpsecSPI& aIpsecSpi )
       
  1135     {
       
  1136     iPlugin.DeleteIpsecSA( aIpsecSpi );
       
  1137     }
       
  1138 
       
  1139 void CIkev1PluginSession::DeleteIpsecSA( TUint32 aSPI,
       
  1140                                          TInetAddr& aSrc, 
       
  1141                                          TInetAddr& aDst,
       
  1142                                          TUint8 aProtocol )
       
  1143     {
       
  1144     iPlugin.DeleteIpsecSA( aSPI, aSrc, aDst, aProtocol );
       
  1145     }
       
  1146 
       
  1147 // ---------------------------------------------------------------------------
       
  1148 // From class MIkePluginSessionIf
       
  1149 // Starts negotiation with a peer. 
       
  1150 // ---------------------------------------------------------------------------
       
  1151 //
       
  1152 void CIkev1PluginSession::NegotiateWithHost( const CIkeData& aIkeData,
       
  1153                                              TVPNAddress& aInternalAddress,
       
  1154                                              TRequestStatus& aStatus )
       
  1155     {
       
  1156     DEBUG_LOG(_L("CIkev1PluginSession::NegotiateWithHost"));    
       
  1157     __ASSERT_DEBUG( iClientStatusNegotiate == NULL,
       
  1158                     User::Invariant() );
       
  1159     
       
  1160     // Store client's request status and internal address.
       
  1161     iClientStatusNegotiate = &aStatus;
       
  1162     *iClientStatusNegotiate = KRequestPending;
       
  1163     iClientIaNegotiate = &aInternalAddress;
       
  1164     
       
  1165     TRAPD( err, DoNegotiateWithHostL( aIkeData ) );
       
  1166     
       
  1167     if ( err != KErrNone )
       
  1168         {
       
  1169         DoCompleteNegotiateWithHost( err );
       
  1170         }
       
  1171     }
       
  1172 
       
  1173 // ---------------------------------------------------------------------------
       
  1174 // From class MIkePluginSessionIf
       
  1175 // Cancels negotiate request. 
       
  1176 // ---------------------------------------------------------------------------
       
  1177 //
       
  1178 void CIkev1PluginSession::CancelNegotiateWithHost()
       
  1179     {    
       
  1180     DEBUG_LOG(_L("CIkev1PluginSession::CancelNegotiateWithHost"));
       
  1181     
       
  1182     if ( iClientStatusNegotiate != NULL )
       
  1183         {
       
  1184         // Completion is enough as deletion of session is requested after
       
  1185         // cancellation.
       
  1186         DoCompleteNegotiateWithHost( KErrCancel );
       
  1187         }
       
  1188     }
       
  1189 
       
  1190 // ---------------------------------------------------------------------------
       
  1191 // From class MIkePluginSessionIf
       
  1192 // Deletes session. 
       
  1193 // ---------------------------------------------------------------------------
       
  1194 //
       
  1195 void CIkev1PluginSession::DeleteSession( const TBool aSilentClose,
       
  1196                                          TRequestStatus& aStatus )
       
  1197     {
       
  1198     DEBUG_LOG1(_L("CIkev1PluginSession::DeleteSession, silent=%d"),
       
  1199             aSilentClose);
       
  1200     
       
  1201     iClientStatusDelete = &aStatus;
       
  1202     *iClientStatusDelete = KRequestPending;
       
  1203     
       
  1204     TBool deactivatingStarted = DeleteSAsWithHost( aSilentClose );    
       
  1205     if ( !deactivatingStarted )
       
  1206         {
       
  1207         DoCompleteDeleteSession( KErrNone );
       
  1208         }
       
  1209     }
       
  1210 
       
  1211 // ---------------------------------------------------------------------------
       
  1212 // From class MIkePluginSessionIf
       
  1213 // Cancels deletion requests. 
       
  1214 // ---------------------------------------------------------------------------
       
  1215 //
       
  1216 void CIkev1PluginSession::CancelDeleteSession()
       
  1217     {
       
  1218     DEBUG_LOG(_L("CIkev1PluginSession::CancelDeleteSession"));
       
  1219 
       
  1220     if ( iClientStatusDelete != NULL )
       
  1221         {
       
  1222         // Delete SAs silently.
       
  1223         DeleteSAsWithHost( ETrue );
       
  1224         
       
  1225         DoCancelDataTransfer();
       
  1226         
       
  1227         User::RequestComplete( iClientStatusDelete, KErrCancel );
       
  1228         iClientStatusDelete = NULL;
       
  1229         }
       
  1230     }
       
  1231 
       
  1232 // ---------------------------------------------------------------------------
       
  1233 // From class MIkePluginSessionIf
       
  1234 // Requests notification about error condition. 
       
  1235 // ---------------------------------------------------------------------------
       
  1236 //
       
  1237 void CIkev1PluginSession::NotifyError( TRequestStatus& aStatus )
       
  1238     {
       
  1239     DEBUG_LOG(_L("CIkev1PluginSession::NotifyError"));
       
  1240     
       
  1241     iClientStatusNotifyError = &aStatus;
       
  1242     *iClientStatusNotifyError = KRequestPending;
       
  1243     }
       
  1244 
       
  1245 // ---------------------------------------------------------------------------
       
  1246 // From class MIkePluginSessionIf
       
  1247 // Cancels error notification request. 
       
  1248 // ---------------------------------------------------------------------------
       
  1249 //
       
  1250 void CIkev1PluginSession::CancelNotifyError()
       
  1251     {
       
  1252     DEBUG_LOG(_L("CIkev1PluginSession::CancelNotifyError"));
       
  1253     
       
  1254     if ( iClientStatusNotifyError != NULL )
       
  1255         {
       
  1256         User::RequestComplete( iClientStatusNotifyError, KErrCancel );
       
  1257         iClientStatusNotifyError = NULL;
       
  1258         }    
       
  1259     }
       
  1260 
       
  1261 // ---------------------------------------------------------------------------
       
  1262 // From class MIkePluginSessionIf
       
  1263 // Requests notification about change of internal address. 
       
  1264 // ---------------------------------------------------------------------------
       
  1265 //
       
  1266 void CIkev1PluginSession::NotifyInternalAddressChanged( TVPNAddress& aInternalAddress,
       
  1267                                                         TRequestStatus& aStatus )
       
  1268     {
       
  1269     DEBUG_LOG(_L("CIkev1PluginSession::NotifyInternalAddressChanged"));
       
  1270     __ASSERT_DEBUG( iClientStatusNotifyIaChange == NULL,
       
  1271                     User::Invariant() );
       
  1272     
       
  1273     iClientStatusNotifyIaChange = &aStatus;
       
  1274     *iClientStatusNotifyIaChange = KRequestPending;
       
  1275     iClientIaNotify = &aInternalAddress;    
       
  1276     }
       
  1277 
       
  1278 // ---------------------------------------------------------------------------
       
  1279 // From class MIkePluginSessionIf
       
  1280 // Cancels internal address change notification request. 
       
  1281 // ---------------------------------------------------------------------------
       
  1282 //
       
  1283 void CIkev1PluginSession::CancelNotifyInternalAddressChanged()
       
  1284     {    
       
  1285     DEBUG_LOG(_L("CIkev1PluginSession::CancelNotifyInternalAddressChanged"));
       
  1286     
       
  1287     if ( iClientStatusNotifyIaChange != NULL )
       
  1288         {
       
  1289         DoCompleteInternalAddressChanged( KErrCancel );
       
  1290         }
       
  1291     }
       
  1292 
       
  1293 // ---------------------------------------------------------------------------
       
  1294 // From class MIkev1ReceiverCallback
       
  1295 // Handles notification about received IKE message. 
       
  1296 // ---------------------------------------------------------------------------
       
  1297 //
       
  1298 void CIkev1PluginSession::IkeMsgReceivedL( const ThdrISAKMP& aIkeMsg,
       
  1299                                            const TInetAddr& aSrcAddr,
       
  1300                                            TInt aLocalPort )
       
  1301     {
       
  1302     CIkev1Negotiation* negotiation = NULL;
       
  1303     TIkev1SAData* sa = NULL;
       
  1304     
       
  1305     TUint8 exchange = aIkeMsg.GetExchange();
       
  1306     negotiation = FindNegotiation( aIkeMsg.GetCookieI(),
       
  1307                                    aIkeMsg.GetCookieR(),
       
  1308                                    exchange,
       
  1309                                    aIkeMsg.GetMessageId() );
       
  1310     
       
  1311     if ( exchange == ISAKMP_EXCHANGE_INFO || exchange == ISAKMP_EXCHANGE_TRANSACT )
       
  1312         {
       
  1313 #ifdef _DEBUG
       
  1314         if ( exchange == ISAKMP_EXCHANGE_INFO )
       
  1315             {
       
  1316             DEBUG_LOG( _L("---ISAKMP_EXCHANGE_INFO message received---") );
       
  1317             }
       
  1318         else 
       
  1319             {
       
  1320             DEBUG_LOG( _L("---ISAKMP_EXCHANGE_TRANSACTION message received---") );
       
  1321             }                
       
  1322 #endif
       
  1323         TBool inactive = EFalse;                 
       
  1324         if ( !negotiation ) 
       
  1325             {
       
  1326             if ( exchange == ISAKMP_EXCHANGE_INFO )
       
  1327                 {
       
  1328                 sa = FindIkev1SAData( aIkeMsg.GetCookieI(),
       
  1329                                       aIkeMsg.GetCookieR() );
       
  1330                 if ( sa )
       
  1331                     {
       
  1332                     negotiation = CIkev1Negotiation::NewL( this,
       
  1333                                                            iPFKeySocketIf,
       
  1334                                                            iDebug,
       
  1335                                                            sa,
       
  1336                                                            RESPONDER );
       
  1337                     }       
       
  1338                 }       
       
  1339             if ( !negotiation )
       
  1340                 {
       
  1341                 DEBUG_LOG( _L("Cannot find a matching negotiation") );
       
  1342 #ifdef _DEBUG                    
       
  1343                 const TPtrC8 ikeMsgPtr( (TUint8 *)&aIkeMsg, (TUint16)aIkeMsg.GetLength() );
       
  1344                 TInetAddr dstAddr;
       
  1345                 GetLocalAddress( dstAddr );
       
  1346                 dstAddr.SetPort( aLocalPort );
       
  1347                 TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr );
       
  1348 #endif // _DEBUG                    
       
  1349                 return; //Not found
       
  1350                 }
       
  1351             CleanupStack::PushL( negotiation );
       
  1352             inactive = ETrue;   //Not enqueued because not active. Only used to process the packet
       
  1353             }
       
  1354 
       
  1355         if ( exchange == ISAKMP_EXCHANGE_INFO )
       
  1356             {                   
       
  1357             CIkev1InfoNegotiation* info_neg = new (ELeave) CIkev1InfoNegotiation( *this,
       
  1358                                                                                   *negotiation,
       
  1359                                                                                   iDebug );
       
  1360             CleanupStack::PushL( info_neg );            
       
  1361             // Update the negotiation state
       
  1362             info_neg->ExecuteL( aIkeMsg,
       
  1363                                 aSrcAddr,
       
  1364                                 aLocalPort  );
       
  1365             CleanupStack::PopAndDestroy( info_neg );
       
  1366             
       
  1367             if ( inactive )
       
  1368                 {   
       
  1369                 CleanupStack::PopAndDestroy( negotiation );
       
  1370                 }
       
  1371             else
       
  1372                 {
       
  1373                 if ( negotiation->Finished() )
       
  1374                     {
       
  1375                     DeleteNegotiation( negotiation );
       
  1376                     }
       
  1377                 }   
       
  1378             }
       
  1379         else
       
  1380             { 
       
  1381             //
       
  1382             // An ISAKMP transaction exchange message received
       
  1383             // The handling of this requires that there exists a
       
  1384             // CTransNegotiation object pointer linked into current
       
  1385             // CIkev1Negotiation object 
       
  1386             //
       
  1387             if ( negotiation )
       
  1388                 {
       
  1389                 if ( negotiation->ExecuteTransactionL( aIkeMsg,
       
  1390                                                        aSrcAddr,
       
  1391                                                        aLocalPort ) )
       
  1392                     {
       
  1393                     if ( negotiation->Finished() )
       
  1394                         {
       
  1395                         DeleteNegotiation( negotiation );
       
  1396                         }
       
  1397                     }
       
  1398                 else
       
  1399                     {
       
  1400                     DEBUG_LOG( _L("Unexpected Transaction excange message") );
       
  1401 #ifdef _DEBUG   
       
  1402                     const TPtrC8 ikeMsgPtr( (TUint8 *)&aIkeMsg, (TUint16)aIkeMsg.GetLength() );
       
  1403                     TInetAddr dstAddr;
       
  1404                     GetLocalAddress( dstAddr );
       
  1405                     dstAddr.SetPort( aLocalPort );
       
  1406                     TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr );                        
       
  1407 #endif // _DEBUG                        
       
  1408                     }     
       
  1409                 }      
       
  1410             }   
       
  1411         return;
       
  1412         }
       
  1413 
       
  1414     //
       
  1415     // IKE Main, Aggressive and Quick mode exchanges
       
  1416     //
       
  1417     if ( negotiation )
       
  1418         {
       
  1419         negotiation->ExecuteL( aIkeMsg, aSrcAddr, aLocalPort );
       
  1420         if ( negotiation->Finished() )
       
  1421             {
       
  1422             DeleteNegotiation( negotiation );
       
  1423             }
       
  1424         return;
       
  1425         }   
       
  1426     DEBUG_LOG( _L("No active negotiation found...Searching existing PHASE_II") );
       
  1427 
       
  1428     TBool status;
       
  1429     sa = FindIkev1SAData( aIkeMsg.GetCookieI(),
       
  1430                           aIkeMsg.GetCookieR() );
       
  1431     if ( sa )
       
  1432         {
       
  1433         DEBUG_LOG( _L("Creating a NEW IKE Phase 2 Negotiation") );           
       
  1434         
       
  1435         TRAPD( err, negotiation = CIkev1Negotiation::NewL( this,
       
  1436                                                            iPFKeySocketIf,
       
  1437                                                            iDebug,
       
  1438                                                            sa,
       
  1439                                                            RESPONDER ) );
       
  1440         if ( err == KErrNone )
       
  1441             {
       
  1442             CleanupStack::PushL( negotiation );
       
  1443             status = negotiation->ExecutePhase2L( aIkeMsg, aSrcAddr, aLocalPort ); 
       
  1444             if ( status && !negotiation->Finished() )
       
  1445                {
       
  1446                //Negotiation OK
       
  1447                CleanupStack::Pop();    //negotiation safe
       
  1448                return;
       
  1449                }
       
  1450             CleanupStack::PopAndDestroy();
       
  1451             }            
       
  1452         return;
       
  1453         }
       
  1454     else
       
  1455         {
       
  1456         TCookie NULL_COOKIE;
       
  1457         NULL_COOKIE.FillZ(ISAKMP_COOKIE_SIZE);
       
  1458         if ( aIkeMsg.GetCookieR() == NULL_COOKIE )
       
  1459             {
       
  1460             //
       
  1461             // This is the initial opening message from a remote host
       
  1462             // Start a new negotiation
       
  1463             //
       
  1464             DEBUG_LOG( _L("Creating a NEW IKE Phase 1 Negotiation") );
       
  1465             TRAPD( err, negotiation = CIkev1Negotiation::NewL( this,
       
  1466                                                                iPFKeySocketIf,
       
  1467                                                                iDebug,
       
  1468                                                                aSrcAddr,
       
  1469                                                                aIkeMsg.GetCookieI(),
       
  1470                                                                EFalse ) );
       
  1471             
       
  1472             if ( err == KErrNone )
       
  1473                 {
       
  1474                 CleanupStack::PushL( negotiation );
       
  1475                 status = negotiation->ExecuteL( aIkeMsg, aSrcAddr, aLocalPort );                   
       
  1476                 if ( status && !negotiation->Finished() )
       
  1477                     {
       
  1478                     //Negotiation OK
       
  1479                     CleanupStack::Pop();    //negotiation safe
       
  1480                     return;
       
  1481                     }
       
  1482                 CleanupStack::PopAndDestroy( negotiation );
       
  1483                 }                
       
  1484             return;
       
  1485             }
       
  1486         }
       
  1487 
       
  1488     if ( !negotiation )
       
  1489         {
       
  1490         DEBUG_LOG( _L("Cannot find a matching negotiation") );
       
  1491 #ifdef _DEBUG
       
  1492         const TPtrC8 ikeMsgPtr((TUint8 *)&aIkeMsg, (TUint16)aIkeMsg.GetLength());
       
  1493         TInetAddr dstAddr;
       
  1494         GetLocalAddress( dstAddr );
       
  1495         dstAddr.SetPort( aLocalPort );
       
  1496         TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr );
       
  1497 #endif // _DEBUG            
       
  1498         return;
       
  1499         }
       
  1500     }
       
  1501 
       
  1502 // ---------------------------------------------------------------------------
       
  1503 // From class MIkev1ReceiverCallback
       
  1504 // Handles notification about receive error. 
       
  1505 // ---------------------------------------------------------------------------
       
  1506 //
       
  1507 void CIkev1PluginSession::ReceiveError( TInt aError )
       
  1508     {
       
  1509     HandleError( aError );
       
  1510     }
       
  1511 
       
  1512 // ---------------------------------------------------------------------------
       
  1513 // Requests sending of UDP data.
       
  1514 // ---------------------------------------------------------------------------
       
  1515 //    
       
  1516 void CIkev1PluginSession::DoSendUdpDataL( HBufC8* aUdpData,
       
  1517                                           const TInetAddr& aDestAddr,
       
  1518                                           TInt aLocalPort,
       
  1519                                           TUint8 aDscp )
       
  1520     {
       
  1521     if ( !iSender->IsActive() &&
       
  1522          iSendQueue.Count() == 0 )
       
  1523         {
       
  1524         // Sending is not in progress and send queue is empty.
       
  1525         // Start sending UDP data.
       
  1526         DoSendUdpData( aUdpData,
       
  1527                        aDestAddr,
       
  1528                        aLocalPort,
       
  1529                        aDscp );
       
  1530         }
       
  1531     else
       
  1532         {
       
  1533         // Store buffer into send queue for later sending.
       
  1534         TIkeSendQueueItem item = TIkeSendQueueItem( aUdpData,
       
  1535                                                     aDestAddr,
       
  1536                                                     aLocalPort,
       
  1537                                                     aDscp );
       
  1538         iSendQueue.Append( item );                
       
  1539         }        
       
  1540     }
       
  1541 
       
  1542 // ---------------------------------------------------------------------------
       
  1543 // Sends UDP data. 
       
  1544 // ---------------------------------------------------------------------------
       
  1545 //
       
  1546 void CIkev1PluginSession::DoSendUdpData( HBufC8* aUdpData,
       
  1547                                          const TInetAddr& aDestAddr,
       
  1548                                          TInt aLocalPort,
       
  1549                                          TUint8 aDscp )
       
  1550     {
       
  1551     __ASSERT_DEBUG( aUdpData != NULL,
       
  1552                     User::Invariant() );
       
  1553     
       
  1554     iSender->SendUdpData( aUdpData, aDestAddr, aLocalPort, aDscp );
       
  1555     }
       
  1556 
       
  1557 // ---------------------------------------------------------------------------
       
  1558 // Handles PFKEY message.
       
  1559 // ---------------------------------------------------------------------------
       
  1560 //
       
  1561 void CIkev1PluginSession::DoPfkeyMessageReceivedL( const TPfkeyMessage& aPfkeyMessage )
       
  1562     {
       
  1563     //
       
  1564     //  Process received PFKEY message according to message type
       
  1565     //
       
  1566 #ifdef _DEBUG    
       
  1567     TBuf<40> txt_addr;
       
  1568 #endif        
       
  1569             
       
  1570     TIkev1SAData* ikev1SAdata = NULL;
       
  1571     CIkev1Negotiation* negotiation = NULL;   
       
  1572     
       
  1573     switch ( aPfkeyMessage.iBase.iMsg->sadb_msg_type )
       
  1574         {
       
  1575         case SADB_ACQUIRE:
       
  1576              //
       
  1577              // A request to negotiate an IPSEC SA received
       
  1578              // Try to find an existing IKE SA with remote address 
       
  1579              //
       
  1580 #ifdef _DEBUG
       
  1581             aPfkeyMessage.iDstAddr.Address().OutputWithScope( txt_addr );
       
  1582 #endif                
       
  1583             ikev1SAdata = FindIkev1SADataWithAddr( aPfkeyMessage.iDstAddr.Address() );
       
  1584             if ( ikev1SAdata )
       
  1585                 {
       
  1586                 //
       
  1587                 // An IKE SA found for Acquire. Get a negotiation
       
  1588                 // object for IKE Quick mode SA exchange 
       
  1589                 //
       
  1590                 negotiation = CIkev1Negotiation::NewL( this,
       
  1591                                                        iPFKeySocketIf,
       
  1592                                                        iDebug,
       
  1593                                                        ikev1SAdata,
       
  1594                                                        INITIATOR,
       
  1595                                                        &aPfkeyMessage );                     
       
  1596                 CleanupStack::PushL( negotiation );                   
       
  1597                 negotiation->InitPhase2L();    //Because is initiator
       
  1598                 DEBUG_LOG1( _L("IKEv1 SA found for Acquire IP: %S"), &txt_addr );
       
  1599                 CleanupStack::Pop();                                                
       
  1600                 }
       
  1601             else
       
  1602                 {
       
  1603                 //
       
  1604                 // No IKE SA found for Acquire.
       
  1605                 //
       
  1606                 // If rekeying is in progress, IKE Quick mode SA exchange
       
  1607                 // is started after Phase I has completed.
       
  1608                 //
       
  1609                 CIkev1Negotiation* negotiation = iFirstNegotiation;
       
  1610                 while ( negotiation != NULL )
       
  1611                     {
       
  1612                     if ( negotiation->IsRekeyingIkeSa() )
       
  1613                         {                        
       
  1614                         break;
       
  1615                         }
       
  1616                     negotiation = negotiation->iNext;
       
  1617                     }                
       
  1618                 if ( negotiation != NULL )
       
  1619                     {
       
  1620                     negotiation->PreparePhase2L( aPfkeyMessage );                    
       
  1621                     DEBUG_LOG1( _L("Negotiation found for Acquire IP: %S"), &txt_addr );
       
  1622                     break;
       
  1623                     }                    
       
  1624                 
       
  1625                 //
       
  1626                 // Otherwise we shall start a new IKE SA negotiation to
       
  1627                 // defined destination address.
       
  1628                 //
       
  1629                 negotiation = CIkev1Negotiation::NewL( this,
       
  1630                                                        iPFKeySocketIf,
       
  1631                                                        iDebug,
       
  1632                                                        (TInetAddr&)aPfkeyMessage.iDstAddr.Address(),
       
  1633                                                        aPfkeyMessage );
       
  1634                 CleanupStack::PushL( negotiation );
       
  1635                 negotiation->InitNegotiationL();
       
  1636                 if ( negotiation->Finished() )
       
  1637                     {
       
  1638                     CleanupStack::PopAndDestroy();
       
  1639                     }
       
  1640                 else 
       
  1641                     {
       
  1642                     CleanupStack::Pop();                                              
       
  1643                     }
       
  1644                 DEBUG_LOG1( _L("Negotiate a new IKE SA for Acquire IP: %S"), &txt_addr );
       
  1645                 }
       
  1646             break;
       
  1647 
       
  1648         case SADB_EXPIRE:
       
  1649             //
       
  1650             // An IPSEC SA has been expired.
       
  1651             // Try to find an existing IKE SA with source address
       
  1652             // (= inbound SA destination address)
       
  1653             //
       
  1654 #ifdef _DEBUG                
       
  1655             aPfkeyMessage.iDstAddr.Address().OutputWithScope( txt_addr );
       
  1656 #endif                  
       
  1657             ikev1SAdata = FindIkev1SAData( aPfkeyMessage.iSrcAddr.Address(),
       
  1658                                            aPfkeyMessage.iSa.iExt->sadb_sa_spi );
       
  1659             if ( ikev1SAdata )
       
  1660                 {
       
  1661                 //
       
  1662                 // An IKE SA found for Expire. Get a negotiation
       
  1663                 // object for IKE Informational exchange 
       
  1664                 //
       
  1665                 if ( DeleteIpsecSpi(ikev1SAdata->iSAId,
       
  1666                                     aPfkeyMessage.iSa.iExt->sadb_sa_spi,
       
  1667                                     ETrue) )
       
  1668                     {
       
  1669                     negotiation = CIkev1Negotiation::NewL( this,
       
  1670                                                            iPFKeySocketIf,
       
  1671                                                            iDebug,
       
  1672                                                            ikev1SAdata,
       
  1673                                                            RESPONDER );
       
  1674                     CleanupStack::PushL( negotiation );
       
  1675                     negotiation->SendDeleteL( aPfkeyMessage.iBase.iMsg->sadb_msg_satype,
       
  1676                                               aPfkeyMessage.iSa.iExt->sadb_sa_spi );
       
  1677                     CleanupStack::PopAndDestroy();
       
  1678                     DEBUG_LOG3(_L("Notifying SGW, IPsec SA Expiration (addr = %S, spi = %x , proto = %d)"), &txt_addr,
       
  1679                             ByteOrder::Swap32(aPfkeyMessage.iSa.iExt->sadb_sa_spi), aPfkeyMessage.iDstAddr.iExt->sadb_address_proto);
       
  1680                     }       
       
  1681                 }
       
  1682             else
       
  1683                 {                       
       
  1684                 DEBUG_LOG1( _L("No IKE SA found Expire IP: %S"), &txt_addr );
       
  1685                 }                       
       
  1686             break;
       
  1687              
       
  1688         default:
       
  1689             break;
       
  1690             
       
  1691         }
       
  1692     }
       
  1693 
       
  1694 // ---------------------------------------------------------------------------
       
  1695 // Deletes IKE SAs. 
       
  1696 // ---------------------------------------------------------------------------
       
  1697 //
       
  1698 TBool CIkev1PluginSession::DeleteSAsWithHost( TBool aSilentClose )
       
  1699     {        
       
  1700     DEBUG_LOG( _L("Deactivating IKEv1 SA:s") );
       
  1701     
       
  1702     //
       
  1703     // For sure check if there is any ongoing negotiations for this
       
  1704     // and delete these negotiations immediatelly.
       
  1705     //
       
  1706     while ( iFirstNegotiation )
       
  1707         {
       
  1708         CIkev1Negotiation* negotiation = iFirstNegotiation;
       
  1709         iFirstNegotiation = negotiation->iNext;             
       
  1710         delete negotiation;
       
  1711         }
       
  1712     
       
  1713     TInt deactivatingStarted( EFalse );
       
  1714     for ( TInt i=0;i<iIkev1SAs.Count();i++ )
       
  1715         {
       
  1716         CIkev1SA* sa = iIkev1SAs[i]; 
       
  1717         if ( !sa->IsExpired() )
       
  1718             {
       
  1719             TIkev1SAData& ikeSaData = sa->iHdr;
       
  1720             deactivatingStarted = DeleteIkeSA( &ikeSaData, aSilentClose );
       
  1721             }   
       
  1722         }
       
  1723 
       
  1724     return deactivatingStarted;
       
  1725     }    
       
  1726 
       
  1727 // ---------------------------------------------------------------------------
       
  1728 // Handles starting of negotiation with a peer. 
       
  1729 // ---------------------------------------------------------------------------
       
  1730 //
       
  1731 void CIkev1PluginSession::DoNegotiateWithHostL( const CIkeData& aIkeData )
       
  1732     {
       
  1733     __ASSERT_DEBUG( iIkeData == NULL,
       
  1734                     User::Invariant() );    
       
  1735     
       
  1736     iIkeData = CIkeData::NewL( &aIkeData ); 
       
  1737 
       
  1738     // Start ISAKMP Phase 1 negotiation to the specified gateway immediately
       
  1739     // if the Internal VPN address feature is enabled in policy (= IA payload
       
  1740     // or CONFIG-MODE). Otherwise postpone negotiation.    
       
  1741     if ( !aIkeData.iUseInternalAddr &&
       
  1742          !aIkeData.iUseCfgMode )
       
  1743         {
       
  1744         DEBUG_LOG(_L("Negotiation postponed."));
       
  1745         User::RequestComplete( iClientStatusNegotiate, KErrNone );
       
  1746         iClientStatusNegotiate = NULL;
       
  1747         return;
       
  1748         }   
       
  1749     
       
  1750     CIkev1Negotiation* negotiation = CIkev1Negotiation::NewL( this,
       
  1751                                                               iPFKeySocketIf,
       
  1752                                                               iDebug,
       
  1753                                                               iIkeData->iAddr,
       
  1754                                                               ETrue );
       
  1755     CleanupStack::PushL( negotiation );
       
  1756     negotiation->InitNegotiationL();        
       
  1757     if ( negotiation->Finished() )
       
  1758         {
       
  1759         CleanupStack::PopAndDestroy( negotiation );
       
  1760         User::Leave( KKmdIkeNegotFailed );            
       
  1761         }
       
  1762     else
       
  1763         {           
       
  1764         CleanupStack::Pop( negotiation );
       
  1765         }   
       
  1766     }  
       
  1767 
       
  1768 // ---------------------------------------------------------------------------
       
  1769 // Handles fatal error.
       
  1770 // ---------------------------------------------------------------------------
       
  1771 //
       
  1772 void CIkev1PluginSession::DoHandleError( TInt aError )
       
  1773     {
       
  1774     DEBUG_LOG1(_L("CIkev1PluginSession::DoHandleError, err=%d"), aError);
       
  1775     
       
  1776     while ( iFirstNegotiation )
       
  1777         {
       
  1778         CIkev1Negotiation* negotiation = iFirstNegotiation;
       
  1779         iFirstNegotiation = negotiation->iNext;             
       
  1780         delete negotiation;
       
  1781         }
       
  1782     
       
  1783     while ( iIkev1SAs.Count() )
       
  1784         {
       
  1785         CIkev1SA* ikev1SA = iIkev1SAs[0];
       
  1786         iIkev1SAs.Remove(0);
       
  1787         delete ikev1SA;
       
  1788         }
       
  1789     
       
  1790     // Complete client's requests.
       
  1791     DoCompleteNegotiateWithHost( aError );
       
  1792     DoCompleteDeleteSession( aError );
       
  1793     DoCompleteNotifyError( aError );
       
  1794     }
       
  1795 
       
  1796 // ---------------------------------------------------------------------------
       
  1797 // Handles completion of client's negotiate request.
       
  1798 // ---------------------------------------------------------------------------
       
  1799 //
       
  1800 void CIkev1PluginSession::DoCompleteNegotiateWithHost( TInt aStatus )
       
  1801     {         
       
  1802     if ( iClientStatusNegotiate != NULL )
       
  1803         {
       
  1804         if ( aStatus == KErrNone )
       
  1805             {
       
  1806             if ( iInternalAddress != NULL )
       
  1807                 {
       
  1808                 __ASSERT_DEBUG( iIkeData != NULL,
       
  1809                                 User::Invariant() );
       
  1810                 // Build internal address for client.       
       
  1811                 VPNAddrInfo::BuildVPNAddrInfo( iInternalAddress,
       
  1812                                                iIkeData->iDnsServer,
       
  1813                                                *iClientIaNegotiate,
       
  1814                                                iDebug );
       
  1815                 }
       
  1816             }
       
  1817 
       
  1818         // Complete client's request.
       
  1819         DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteNegotiateWithHost, aStatus=%d"),
       
  1820                 aStatus);        
       
  1821         User::RequestComplete( iClientStatusNegotiate, aStatus );
       
  1822         iClientStatusNegotiate = NULL;
       
  1823         iClientIaNegotiate = NULL;
       
  1824         }
       
  1825     }
       
  1826 
       
  1827 // ---------------------------------------------------------------------------
       
  1828 // Handles completion of client's delete session request.
       
  1829 // ---------------------------------------------------------------------------
       
  1830 //
       
  1831 void CIkev1PluginSession::DoCompleteDeleteSession( TInt aStatus )
       
  1832     {       
       
  1833     if ( iClientStatusDelete != NULL )
       
  1834         {
       
  1835         DoCancelDataTransfer();
       
  1836         
       
  1837         DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteDeleteSession, aStatus=%d"),
       
  1838                 aStatus);
       
  1839         User::RequestComplete( iClientStatusDelete, aStatus );
       
  1840         iClientStatusDelete = NULL;
       
  1841         }    
       
  1842     }
       
  1843 
       
  1844 // ---------------------------------------------------------------------------
       
  1845 // Handles completion of client's notify error request.
       
  1846 // ---------------------------------------------------------------------------
       
  1847 //
       
  1848 void CIkev1PluginSession::DoCompleteNotifyError( TInt aStatus )
       
  1849     {   
       
  1850     if ( iClientStatusNotifyError != NULL )
       
  1851         {
       
  1852         DoCancelDataTransfer();
       
  1853 
       
  1854         DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteNotifyError, aStatus=%d"),
       
  1855                 aStatus);
       
  1856         User::RequestComplete( iClientStatusNotifyError, aStatus );
       
  1857         iClientStatusNotifyError = NULL;
       
  1858         }        
       
  1859     }
       
  1860 
       
  1861 // ---------------------------------------------------------------------------
       
  1862 // Handles completion of client's notify internal address change request.
       
  1863 // ---------------------------------------------------------------------------
       
  1864 //
       
  1865 void CIkev1PluginSession::DoCompleteInternalAddressChanged( TInt aStatus )
       
  1866     {
       
  1867     if ( iClientStatusNotifyIaChange != NULL )
       
  1868         {       
       
  1869         DEBUG_LOG1(_L("CIkev1PluginSession::DoCompleteInternalAddressChange, aStatus=%d"),
       
  1870                 aStatus);
       
  1871 
       
  1872         if ( aStatus == KErrNone )
       
  1873             {
       
  1874             if ( iInternalAddress != NULL )
       
  1875                 {
       
  1876                 // Build internal address for client.       
       
  1877                 VPNAddrInfo::BuildVPNAddrInfo( iInternalAddress,
       
  1878                                                iIkeData->iDnsServer,
       
  1879                                                *iClientIaNotify,
       
  1880                                                iDebug );            
       
  1881                 }
       
  1882             }
       
  1883         
       
  1884         if ( aStatus != KErrNone &&
       
  1885              aStatus != KErrCancel )
       
  1886             {
       
  1887             HandleError( aStatus);
       
  1888             return;
       
  1889             }
       
  1890         
       
  1891         User::RequestComplete( iClientStatusNotifyIaChange, aStatus );
       
  1892         iClientStatusNotifyIaChange = NULL;
       
  1893         iClientIaNotify = NULL;
       
  1894         }
       
  1895     }
       
  1896 
       
  1897 // ---------------------------------------------------------------------------
       
  1898 // Cancels data transfer.
       
  1899 // ---------------------------------------------------------------------------
       
  1900 //
       
  1901 void CIkev1PluginSession::DoCancelDataTransfer()
       
  1902     {
       
  1903     iReceiver->Cancel();
       
  1904     iDataInterface.StopReceive();
       
  1905     DoEmptySendQueue();
       
  1906     iSender->Cancel();
       
  1907     }
       
  1908 
       
  1909 // ---------------------------------------------------------------------------
       
  1910 // Empties send queue.
       
  1911 // ---------------------------------------------------------------------------
       
  1912 //
       
  1913 void CIkev1PluginSession::DoEmptySendQueue()
       
  1914     {
       
  1915     while ( iSendQueue.Count() )
       
  1916         {
       
  1917         TIkeSendQueueItem item = iSendQueue[0];
       
  1918         HBufC8* udpData = item.UdpData();
       
  1919         iSendQueue.Remove(0);
       
  1920         delete udpData;
       
  1921         udpData = NULL;
       
  1922         }    
       
  1923     }
       
  1924