vpnengine/ikev2lib/src/ikev2acquire.cpp
changeset 0 33413c0669b9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vpnengine/ikev2lib/src/ikev2acquire.cpp	Thu Dec 17 09:14:51 2009 +0200
@@ -0,0 +1,531 @@
+/*
+* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  IKEv2 Acquire definition
+*                Class CIkev2Acquire is a IKEv2 specific data structure
+*                containing information needed, when establishing a new 
+*                IPsec SA
+*/
+
+#include <ipsecpolapi.h>
+
+#include "ikev2acquire.h"
+#include "pfkeymsg.h"
+#include "ipsecproposal.h"
+#include "ipsecselectors.h"
+#include "ikev2payloads.h"
+#include "ikev2ipsecsarekeydata.h"
+
+_LIT8(KZeroDesc, "");
+//
+//
+//  CIkev2Acquire
+//
+//  This class is used to handle PFKEY Acquire primitives received from
+//  Ipsec plug-in. 
+//  
+//
+CIkev2Acquire::CIkev2Acquire(TInt aId) 
+:iId(aId), iSPIIn(0), iSPIOut(0), iSPIToBeRekeyed(0), iDHGroup(0), 
+ iTransport(EFalse), iResponse(EFalse), iSrcSpecific(ETrue), iForVirtualIp(EFalse), 
+ iReplayWindow(0), iProtocol(SADB_SATYPE_ESP), iPfKeyPid(0), iPfKeySeq(0), 
+ iHard(0,0,0,0), iSoft(0,0,0,0),
+ iSA(0), iTS_i(0), iTS_r(0), iLocalId(0), iRemoteId(0), iNext(0) 
+    {    
+    }      
+
+
+CIkev2Acquire::~CIkev2Acquire()
+{
+    delete iSA;
+    iSA = NULL;
+    delete iTS_i;
+    iTS_i = NULL;
+    delete iTS_r;
+    iTS_r = NULL;
+    delete iLocalId;
+    iLocalId = NULL;
+    delete iRemoteId;   
+    iRemoteId = NULL;
+}
+
+void CIkev2Acquire::ConstructL(const TPfkeyMessage& aReq, const TInetAddr& aLocalAddr, 
+                          TUint16 aDHGroup, TBool aImplicitSa, 
+                          const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData)
+{
+    SetIpsecProtocol(aReq.iBase.iMsg->sadb_msg_satype); 
+    SetPid(aReq.iBase.iMsg->sadb_msg_pid);
+    SetSeq(aReq.iBase.iMsg->sadb_msg_seq);
+    iSrcSpecific = !(aReq.iSrcAddr.iAddr->IsUnspecified());
+
+    if (!aRekeyData)
+        {
+        // SADB_ACQUIRE was received
+        if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_PFS )
+            {
+            iDHGroup = (TUint32)aDHGroup;
+            }
+    
+        if ( aReq.iProposal.iComb->sadb_comb_flags & SADB_SAFLAGS_TUNNEL )
+            {
+            iTransport = EFalse;        
+            }
+        else 
+            {
+            iTransport = ETrue;
+            }
+
+        iHard.iAllocations = aReq.iProposal.iComb->sadb_comb_hard_allocations;
+        iHard.iBytes = aReq.iProposal.iComb->sadb_comb_hard_bytes;
+        iHard.iAddtime = aReq.iProposal.iComb->sadb_comb_hard_addtime;
+        iHard.iUsetime = aReq.iProposal.iComb->sadb_comb_hard_usetime;
+    
+        iSoft.iAllocations = aReq.iProposal.iComb->sadb_comb_soft_allocations;
+        iSoft.iBytes = aReq.iProposal.iComb->sadb_comb_soft_bytes;
+        iSoft.iAddtime = aReq.iProposal.iComb->sadb_comb_soft_addtime;
+        iSoft.iUsetime = aReq.iProposal.iComb->sadb_comb_soft_usetime;
+
+        SetReplayWindow(aReq.iProposal.iExt->sadb_prop_replay);
+
+        //
+        //  Build SA payload (including Proposal and Transform payload)
+        //  using parameters in TPfkeyMessage
+        //
+        if ( aImplicitSa )
+            {
+            aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined   
+            }
+        iSA = IpsecProposal::BuildIpsecSaRequestL(aReq, aDHGroup);
+    
+        //
+        //  Build Traffic selectors using parameters in TPfkeyMessage.
+        //  For some reason the selectors are build using identity 
+        //  fields.
+        //  
+        IpsecSelectors::BuildTrafficSelectorsL(this, aLocalAddr,
+                                               aReq.iSrcIdent, aReq.iDstIdent,
+                                               aReq.iDstAddr.iExt->sadb_address_proto);
+        //
+        //  Store identity information from TPfkeyMessage to Acquire
+        //
+        if ( aReq.iSrcIdent.iExt )
+            {            
+            iLocalId = HBufC8::NewL(aReq.iSrcIdent.iData.Length());
+            iLocalId->Des().Copy(aReq.iSrcIdent.iData);
+            }
+        else
+            {
+            iLocalId = KZeroDesc().AllocL();
+            }
+
+        if ( aReq.iDstIdent.iExt )
+            {            
+            iRemoteId = HBufC8::NewL(aReq.iDstIdent.iData.Length());
+            iRemoteId->Des().Copy(aReq.iDstIdent.iData);
+            }
+        else
+            {
+            iRemoteId = KZeroDesc().AllocL();
+            }
+        }
+    else
+        {
+        // SADB_EXPIRE was received due to soft lifetime expiration
+        TUint16 flags = (TUint16)(aReq.iSa.iExt->sadb_sa_flags | (aSaSpec->iTransportMode ? 0 : SADB_SAFLAGS_TUNNEL));
+        if ( flags & SADB_SAFLAGS_PFS )
+            {
+            iDHGroup = (TUint32)aDHGroup;
+            }
+    
+        if ( flags & SADB_SAFLAGS_TUNNEL )
+            {
+            iTransport = EFalse;        
+            }
+        else 
+            {
+            iTransport = ETrue;
+            }
+                    
+        if ( aImplicitSa )
+            {
+            aDHGroup = 0; // No D-H group used with ipmplicit SA although PFS defined   
+            } 
+        
+        iSA = IpsecProposal::BuildIpsecSaRequestL(iProtocol, 
+                                                  aSaSpec->iEalg, aSaSpec->iEalgLen, aSaSpec->iAalg, 
+                                                  flags, aDHGroup);
+                                                    
+        iReplayWindow = aRekeyData->ReplayWindow();
+        iHard = aRekeyData->HardLifetime();
+        iSoft = aRekeyData->SoftLifetime();
+        
+        iTS_i = aRekeyData->TsIL();
+        iTS_r = aRekeyData->TsRL();
+
+        
+        iLocalId = aRekeyData->LocalId().AllocL();
+        iRemoteId = aRekeyData->RemoteId().AllocL();
+
+        iResponse = EFalse;
+        }
+}
+
+
+CIkev2Acquire* CIkev2Acquire::NewL(const TPfkeyMessage& aPfkeyMessage, TUint32 aId, 
+                         const TInetAddr& aLocalAddr, TUint16 aDHGroup, TBool aImplicitSa,
+                         const TIpsecSaSpec* aSaSpec, const CIpsecSARekeyData* aRekeyData)
+{
+    CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId);
+    CleanupStack::PushL(Acquire);
+    Acquire->ConstructL(aPfkeyMessage, aLocalAddr, aDHGroup, aImplicitSa, aSaSpec, aRekeyData);
+    CleanupStack::Pop(Acquire);     
+    return Acquire;
+}
+
+
+void CIkev2Acquire::AddIpsecSpiToSa(const TDesC8& aSpi)
+    {
+    __ASSERT_DEBUG(aSpi.Length() == 4, User::Invariant());
+
+    TUint8* saBuffer = const_cast<TUint8*>(iSA->Ptr());
+    TProposalIkev2* Prop = TProposalIkev2::Cast(saBuffer);
+
+    while ( Prop )
+        {
+        TUint32 spiValue = 0;
+        TPtr8 spiValueDesc(reinterpret_cast<TUint8*>(&spiValue), sizeof(spiValue));
+        spiValueDesc = aSpi;
+        Prop->SetIpsecSPI(spiValue);
+        if ( !Prop->Last() )
+            {
+            Prop = TProposalIkev2::Cast(TPayloadIkev2::Cast(Prop)->Next());
+            }  
+        else
+            {
+            Prop = NULL;
+            }
+        }       
+    }
+
+
+CIkev2Acquire* CIkev2Acquire::NewL(TUint32 aId, HBufC8* aSa, 
+                         CArrayFix<TIkeV2TrafficSelector>* aTS_i, 
+                         CArrayFix<TIkeV2TrafficSelector>* aTS_r )
+{
+    CIkev2Acquire* Acquire = new (ELeave)CIkev2Acquire(aId);
+    Acquire->iSA   = aSa;
+    Acquire->iTS_i = aTS_i;
+    Acquire->iTS_r = aTS_r;     
+    return Acquire;
+}
+
+void CIkev2Acquire::Link(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor)
+{
+    ASSERT(aAcquire && aAnchor);
+    aAcquire->iNext = NULL;
+    CIkev2Acquire* Last  = *aAnchor;
+    if ( Last )
+    {   
+        while ( Last->iNext )
+        {
+            Last = Last->iNext;
+        }
+        Last->iNext = aAcquire;
+    }
+    else *aAnchor = aAcquire;   
+}
+
+CIkev2Acquire* CIkev2Acquire::Find(TUint32 aId, CIkev2Acquire** aAnchor, TBool aRemove)
+{
+    ASSERT(aAnchor);
+    CIkev2Acquire* Prev = NULL;
+    CIkev2Acquire* Elem = *aAnchor;
+    while ( Elem )
+    {
+        if ( Elem->iId == aId )
+        {
+           if ( aRemove )
+           {
+              if ( Prev )
+                   Prev->iNext = Elem->iNext;
+              else *aAnchor = Elem->iNext;
+           }       
+           break;
+        }
+        Prev = Elem;
+        Elem = Elem->iNext;
+    }
+    return Elem;
+}
+
+CIkev2Acquire* CIkev2Acquire::GetNext(CIkev2Acquire** aAnchor, TBool aResponse)
+{
+    ASSERT(aAnchor);
+    CIkev2Acquire* Elem = *aAnchor;
+    while ( Elem )
+    {
+        if ( Elem->SPI_In().Length() > 0 && (Elem->Response() == aResponse) )
+        {
+            RemoveFromQue(Elem->Id(), aAnchor);
+            break;
+        }
+        Elem = Elem->iNext;
+    }
+    return Elem;
+}
+
+TBool CIkev2Acquire::Responding(CIkev2Acquire** aAnchor)
+{
+    ASSERT(aAnchor);
+    CIkev2Acquire* Elem = *aAnchor;
+    while ( Elem )
+    {
+        if ( Elem->Response() )
+        {
+            return ETrue;
+        }
+        Elem = Elem->iNext;
+    }
+    return EFalse;
+}
+
+
+void CIkev2Acquire::PurgeQue(CIkev2Acquire** aAnchor)
+{
+    ASSERT(aAnchor);
+    CIkev2Acquire* Elem = *aAnchor;
+    while ( Elem )
+    {
+        RemoveFromQue(Elem->Id(), aAnchor);
+        delete Elem;
+        Elem = *aAnchor;
+    }   
+}
+
+void CIkev2Acquire::SetFirst(CIkev2Acquire* aAcquire, CIkev2Acquire** aAnchor)
+    { 
+    ASSERT(aAcquire && aAnchor); 
+    aAcquire->iNext = *aAnchor; 
+    *aAnchor = aAcquire; 
+    }
+
+CIkev2Acquire* CIkev2Acquire::PeekFirst(CIkev2Acquire** aAnchor) 
+    { 
+    return *aAnchor; 
+    }
+
+CIkev2Acquire* CIkev2Acquire::RemoveFromQue(TUint32 aId, CIkev2Acquire** aAnchor)
+    { 
+    return CIkev2Acquire::Find(aId, aAnchor, ETrue);
+    }
+
+TUint32 CIkev2Acquire::Id() 
+    { 
+    return iId;
+    }
+
+TPtrC8 CIkev2Acquire::SPI_In() 
+    { 
+    return iSPIIn;
+    }
+
+TPtrC8 CIkev2Acquire::SPI_Out() 
+    { 
+    return iSPIOut;
+    }          
+
+TPtrC8 CIkev2Acquire::SPI_ToBeRekeyed() 
+    { 
+    return iSPIToBeRekeyed;
+    }
+
+void CIkev2Acquire::SetSPI_In(const TDesC8& aSPI) 
+    { 
+    iSPIIn = aSPI;
+    }
+
+void CIkev2Acquire::SetSPI_Out(const TDesC8& aSPI) 
+    { 
+    iSPIOut = aSPI;
+    }
+
+void CIkev2Acquire::SetSPI_ToBeRekeyed(const TDesC8& aSPI) 
+    { 
+    iSPIToBeRekeyed = aSPI;
+    }
+
+TUint16 CIkev2Acquire::DHGroup() 
+    { 
+    return (TUint16)iDHGroup;
+    }
+
+void CIkev2Acquire::DHGroup(TUint16 aDHGroup) 
+    { 
+    iDHGroup = aDHGroup;
+    }
+
+TBool CIkev2Acquire::Transport() 
+    { 
+    return iTransport;
+    }
+
+void CIkev2Acquire::SetTransport() 
+    { 
+    iTransport = ETrue;
+    }       
+
+TBool CIkev2Acquire::Response() 
+    { 
+    return iResponse;
+    }
+
+void CIkev2Acquire::SetResponse() 
+    { 
+    iResponse = ETrue;
+    }
+
+void CIkev2Acquire::SetHardLifetime(const TIpsecSALifetime& aHard ) 
+    { 
+    iHard = aHard;
+    }
+
+TIpsecSALifetime* CIkev2Acquire::HardLifetime() 
+    { 
+    return &iHard;
+    }
+
+void CIkev2Acquire::SetSoftLifetime(const TIpsecSALifetime& aSoft ) 
+    { 
+    iSoft = aSoft;
+    }
+
+TIpsecSALifetime* CIkev2Acquire::SoftLifetime() 
+    { 
+    return &iSoft;
+    }
+
+TUint8 CIkev2Acquire::ReplayWindow() 
+    { 
+    return (TUint8)iReplayWindow;
+    }
+
+void CIkev2Acquire::SetReplayWindow(TUint8 aReplayWindow) 
+    { 
+    iReplayWindow = (TInt)aReplayWindow;
+    }
+
+TUint32 CIkev2Acquire::Pid() 
+    { 
+    return iPfKeyPid;
+    }
+
+void CIkev2Acquire::SetPid(TUint32 aPfKeyPid) 
+    { 
+    iPfKeyPid = aPfKeyPid;
+    }
+
+TUint32 CIkev2Acquire::Seq() 
+    { 
+    return iPfKeySeq;
+    }
+
+void CIkev2Acquire::SetSeq(TUint32 aPfKeySeq) 
+    { 
+    iPfKeySeq = aPfKeySeq;
+    }
+
+void CIkev2Acquire::SetVirtualIp() 
+    { 
+    iForVirtualIp = ETrue; 
+    }
+
+TBool CIkev2Acquire::ForVirtualIp() 
+    { 
+    return iForVirtualIp; 
+    }
+
+TBool CIkev2Acquire::SrcSpecific() 
+    { 
+    return iSrcSpecific;
+    }
+
+void CIkev2Acquire::SetSrcSpecific(TBool aSrcSpecific) 
+    { 
+    iSrcSpecific = aSrcSpecific;
+    }
+
+TUint8 CIkev2Acquire::IpsecProtocol() 
+    { 
+    return (TUint8)iProtocol;
+    }
+
+void CIkev2Acquire::SetIpsecProtocol(TUint8 aProtocol) 
+    { 
+    iProtocol = (TInt)aProtocol;
+    }                      
+
+HBufC8* CIkev2Acquire::LocalId() 
+    { 
+    return iLocalId;
+    }
+
+HBufC8* CIkev2Acquire::RemoteId() 
+    { 
+    return iRemoteId;
+    }
+
+HBufC8* CIkev2Acquire::SA()const 
+    { 
+    return iSA;
+    }
+
+const CArrayFix<TIkeV2TrafficSelector>& CIkev2Acquire::TS_i() 
+    { 
+    return *iTS_i;
+    }
+
+const CArrayFix<TIkeV2TrafficSelector>& CIkev2Acquire::TS_r() 
+    { 
+    return *iTS_r;
+    }
+
+void CIkev2Acquire::ReplaceSA(HBufC8* aSA) 
+    { 
+    delete iSA; 
+    iSA = aSA; 
+    }
+
+void CIkev2Acquire::ReplaceTS_i(CArrayFix<TIkeV2TrafficSelector>* aTS) 
+    { 
+    delete iTS_i; 
+    iTS_i = aTS; 
+    }
+
+void CIkev2Acquire::ReplaceTS_r(CArrayFix<TIkeV2TrafficSelector>* aTS) 
+    { 
+    delete iTS_r; 
+    iTS_r = aTS; 
+    }
+
+void CIkev2Acquire::ReplaceLocalId(HBufC8* aId) 
+    { 
+    delete iLocalId; 
+    iLocalId = aId; 
+    }
+
+void CIkev2Acquire::ReplaceRemoteId(HBufC8* aId) 
+    { 
+    delete iRemoteId; 
+    iRemoteId = aId; 
+    }
+