vpnengine/ikev1lib/src/ikev1trans.cpp
changeset 0 33413c0669b9
child 22 9f4e37332ce5
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2005-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: IKE transaction exchange implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 /**-------------------------------------------------------------------
       
    19  *
       
    20  * Class CTransNegotiation
       
    21  * This class is used to handle ISAKMP Transaction exchange messages.
       
    22  * Transaction exchange has been defined in the IETF draft which specifies
       
    23  * The ISAKMP Configuration Method <draft-dukes-ike-mode-cfg-01.txt>.
       
    24  * This same two message configuration transaction is also used in IETF draft
       
    25  * Extended Authentication within IKE (XAUTH) <draft-beaulieu-ike-xauth-02.txt>.
       
    26  * CTransNegotiation class implements these IETF drafts, too.
       
    27  *
       
    28  *--------------------------------------------------------------------*/
       
    29 
       
    30 #include "ikev1trans.h"
       
    31 #include "ikedebug.h"
       
    32 #include "ikev1pluginsession.h"
       
    33 #include "ikev1negotiation.h"
       
    34 #include "ikev1payload.h"
       
    35 #include "ikev1timeout.h"
       
    36 #include "ikev1crack.h"
       
    37 #include "ikev1isakmpstream.h"
       
    38 #include "ikev1crypto.h"
       
    39 
       
    40 const TUint8  XAUTH_VID_DATA[8] = {0x09, 0x00, 0x26, 0x89, 0xdf, 0xd6, 0xb7, 0x12};
       
    41 const TUint8  CISCO_UNITY_VID_DATA[16] = {0x12, 0xf5, 0xf2, 0x8c, 0x45, 0x71, 0x68, 0xa9,
       
    42                                           0x70, 0x2d, 0x9f, 0xe2, 0x74, 0xcc, 0x01, 0x00};
       
    43                                           
       
    44                                           
       
    45 CTransNegotiation::CTransNegotiation( TInt aGranularity,
       
    46                                       TBool aUseXauth,
       
    47                                       TBool aUseCfgMode, 
       
    48                                       CIkev1PluginSession* aPluginSession,
       
    49                                       CIkev1Negotiation* aNegotiation,
       
    50                                       MIkeDebug& aDebug ) 
       
    51     :CArrayFixFlat<TTransExchange*>(aGranularity),
       
    52      iPluginSession(aPluginSession),
       
    53      iNegotiation(aNegotiation),
       
    54      iUseXauth(aUseXauth),
       
    55      iUseCfgMode(aUseCfgMode),
       
    56      iDebug(aDebug)
       
    57 {
       
    58 }
       
    59                                           
       
    60                                           
       
    61 /**-------------------------------------------------------------------
       
    62  *
       
    63  * Method New()
       
    64  * Creates an instance of CTransNegotiation class if either 
       
    65  * usage of XAUTH or CFG-MODE has been requested.
       
    66  *
       
    67  *--------------------------------------------------------------------*/
       
    68 CTransNegotiation* CTransNegotiation::NewL(TBool aUseXauth, TBool aUseCfgMode,
       
    69                                            CIkev1PluginSession* aPluginSession, 
       
    70                                            CIkev1Negotiation* aNegotiation,
       
    71                                            MIkeDebug& aDebug )
       
    72 {    
       
    73     CTransNegotiation* Neg = new (ELeave) CTransNegotiation( 1,
       
    74                                                              aUseXauth,
       
    75                                                              aUseCfgMode,
       
    76                                                              aPluginSession,
       
    77                                                              aNegotiation,
       
    78                                                              aDebug );
       
    79     CleanupStack::PushL(Neg);
       
    80     Neg->ConstructL();
       
    81     CleanupStack::Pop(Neg);
       
    82     return Neg;        
       
    83 }
       
    84 /**-------------------------------------------------------------------
       
    85  *
       
    86  * Deconstruct method
       
    87  *
       
    88  *--------------------------------------------------------------------*/
       
    89 CTransNegotiation::~CTransNegotiation()
       
    90 {
       
    91     DEBUG_LOG(_L("Transaction exchange object deleted"));  
       
    92         
       
    93     delete iInternalAddr;
       
    94     delete iDialog;
       
    95     delete iDialogInfo;
       
    96 	delete iUserName; 	
       
    97             
       
    98     for ( TInt i = 0; i < Count(); i++ )
       
    99     {
       
   100         delete At(i);
       
   101     }
       
   102 }
       
   103 
       
   104 /**-------------------------------------------------------------------
       
   105  *
       
   106  * Method ConstructL()
       
   107  * -- Links CKmdEngine- and CNegotiation object pointers to CTransNegotiation
       
   108  * -- If only CONFIG-MODE requested, start corresponding transaction exchange.
       
   109  *
       
   110  *--------------------------------------------------------------------*/
       
   111 void CTransNegotiation::ConstructL()
       
   112 {
       
   113     if ( !iPluginSession || !iNegotiation || (!iUseXauth && !iUseCfgMode)) 
       
   114     {
       
   115         User::Leave(KErrArgument);   
       
   116     }
       
   117        
       
   118     DEBUG_LOG(_L("Transaction exchange object constructed"));  
       
   119     if ( !iUseXauth ) 
       
   120     {
       
   121        iXauthCompleted = ETrue;
       
   122        iNegotiation->iTimer->Cancel();  // Stop retransmission timer   
       
   123     }
       
   124     else 
       
   125     {
       
   126        if ( !iUseCfgMode ) 
       
   127            iCfgModeCompleted = ETrue;
       
   128        DEBUG_LOG(_L("Starting to Wait XAUTH request"));  
       
   129     }    
       
   130 }
       
   131 
       
   132 /**-------------------------------------------------------------------
       
   133  *
       
   134  * Method GetAuthMethod()
       
   135  * This static method converts the authentication method value from
       
   136  * "normal" IKE attribute value (specified in RFC2409) to the attribute
       
   137  * value indicate XAUTH usage after IKE phase 1. This conversion is done
       
   138  * into the opposite direction when call parameter (aAuthMethod) have
       
   139  * already value indicating Xauth usage.
       
   140  *
       
   141  *--------------------------------------------------------------------*/
       
   142 TUint16 CTransNegotiation::GetAuthMethod(TUint16 aAuthMethod, TBool aXauthUsed, TInt aRole)
       
   143 {
       
   144     if ( aXauthUsed ) {
       
   145        if ( aAuthMethod >= XAUTHInitPreShared && aAuthMethod <= XAUTHRespRSARevisedEncr) {
       
   146           aAuthMethod -= XAUTHMethodBase;
       
   147           aAuthMethod = (TUint16)((aAuthMethod >> XAUTHScaler) | XAUTHScaler);
       
   148        }
       
   149        else {
       
   150           if ( aAuthMethod >= PRE_SHARED && aAuthMethod <= RSA_REV_ENCR ) {
       
   151              aAuthMethod = (TUint16)((aAuthMethod << XAUTHScaler) + XAUTHMethodBase);
       
   152              if ( aRole == INITIATOR )
       
   153                 aAuthMethod -= XAUTHScaler;
       
   154           }
       
   155        }       
       
   156     }
       
   157     return aAuthMethod;
       
   158 }   
       
   159 
       
   160 /**-------------------------------------------------------------------
       
   161  *
       
   162  * Method BuildXauthVendorId()
       
   163  * This method builds a XAUTH related Vendor ID payload and adds it into 
       
   164  * the IKE message. The vendor id is specified in the draft
       
   165  * <draft-beaulieu-ike-xauth-02.txt> and its content is the following:
       
   166  * ["0x09002689DFD6B712"])
       
   167  * Both ISAKMP mode-cfg and extended authentication (XAUTH) can be
       
   168  * implemented in some VPN SGWs according to the older mode-cfg and
       
   169  * xauth drafts:
       
   170  * <draft-ietf-ipsec-isakmp-mode-cfg-04.txt> and
       
   171  * <draft-ietf-ipsec-isakmp-xauth-04.txt>
       
   172  *
       
   173  *--------------------------------------------------------------------*/
       
   174 void CTransNegotiation::BuildXauthVendorId(TIkev1IsakmpStream &aMsg)
       
   175 {
       
   176     TInetAddr DummyAddr;
       
   177     
       
   178     aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID,
       
   179                         NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA
       
   180                         (TUint8*)XAUTH_VID_DATA, sizeof(XAUTH_VID_DATA));
       
   181 	
       
   182 	aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID,
       
   183 						NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA
       
   184 						(TUint8*)CISCO_UNITY_VID_DATA,
       
   185 						sizeof(CISCO_UNITY_VID_DATA));
       
   186 }
       
   187 
       
   188 /**-------------------------------------------------------------------
       
   189  *
       
   190  * Method GetIV()
       
   191  * Get IV for transaction exchange specified with message id parameter:
       
   192  * Find corresponding exchange structure and copy IV to caller
       
   193  * If no exchange found, return EFALSE status to indicate error.    
       
   194  *
       
   195  *--------------------------------------------------------------------*/
       
   196 TBool CTransNegotiation::GetIV(TUint32 aMsgId, TDes8& aIV)
       
   197 {
       
   198     TBool status = ETrue;
       
   199     TTransExchange *exchange = FindExchange(aMsgId);
       
   200     if ( exchange )
       
   201          aIV.Copy(exchange->iIV);
       
   202     else status = EFalse;
       
   203 
       
   204     return status;
       
   205 }   
       
   206 
       
   207 /**-------------------------------------------------------------------
       
   208  *
       
   209  * Method SetIV()
       
   210  * Set IV for transaction exchange specified with message id parameter:
       
   211  * Find corresponding exchange structure and store specified IV to
       
   212  * exchange structure
       
   213  * If no exchange found, return EFALSE status to indicate error.    
       
   214  *
       
   215  *--------------------------------------------------------------------*/
       
   216 TBool CTransNegotiation::SetIV(TUint32 aMsgId, TDes8& aIV)
       
   217 {
       
   218     TBool status = ETrue;
       
   219     TTransExchange *exchange = FindExchange(aMsgId);
       
   220     if ( exchange )
       
   221          exchange->iIV.Copy(aIV);
       
   222     else status = EFalse;
       
   223 
       
   224     return status;
       
   225 }   
       
   226 
       
   227 /**-------------------------------------------------------------------
       
   228  *
       
   229  * Method ProcessUserResponseL()
       
   230  * ProcessUserResponseL() builds a XAUTH reply message from authentication
       
   231  * credentials linked into the current CAuthDialogInfo object.
       
   232  *
       
   233  *--------------------------------------------------------------------*/
       
   234 TInt CTransNegotiation::ProcessUserResponseL(CAuthDialogInfo *aDialogInfo )
       
   235 {
       
   236     //
       
   237     // Find a transaction exchange structure for current message 
       
   238     //
       
   239     TInt lth = 0;
       
   240     iCurrExchange = FindExchange(aDialogInfo->GetMsgId());
       
   241     
       
   242     if ( iCurrExchange && iRequestFlags ) {
       
   243        //
       
   244        // Allocate a buffer for Attribute payload.
       
   245        // Calculate first required buffer length
       
   246        //
       
   247        if ( aDialogInfo->iUsername )    
       
   248           lth += (aDialogInfo->iUsername->Length() + 4);
       
   249        if ( aDialogInfo->iSecret )  
       
   250           lth += (aDialogInfo->iSecret->Length() + 4);
       
   251        
       
   252        HBufC8 *attributes = HBufC8::NewL(lth + 4);
       
   253        CleanupStack::PushL(attributes);
       
   254        TPtr8 attr_ptr(attributes->Des());
       
   255 	   TUint16 AttrType;
       
   256        
       
   257        if ( iRequestFlags & (1 << (ATTR_PASSWORD - ATTR_XAUTH_TYPE)) ) {
       
   258           //
       
   259           // Add Xauth type attribute. Value is taken from current exchange structure
       
   260           //
       
   261 		  if ( iUseOlderPIXXauth )
       
   262 			   AttrType = ATTR_PIX_XAUTH_TYPE;
       
   263           else AttrType = ATTR_XAUTH_TYPE;						 
       
   264           AddAttributeData(attr_ptr, AttrType, 2, (TUint8*)&iCurrExchange->iXauthType);
       
   265        }
       
   266        
       
   267        if ( aDialogInfo->iUsername ) {
       
   268           //
       
   269           // Add user name attribute. 
       
   270           //
       
   271 	      if ( iUseOlderPIXXauth )
       
   272 			   AttrType = ATTR_PIX_USER_NAME;
       
   273 		  else AttrType = ATTR_USER_NAME;						 
       
   274 		  
       
   275           AddAttributeData(attr_ptr, AttrType, aDialogInfo->iUsername->Length(),
       
   276                            (TUint8*)aDialogInfo->iUsername->Ptr());
       
   277           //
       
   278 	      // Take a copy of user name buffer in dialog info. This user name
       
   279 	      // is cached into user name file if current CRACK negotiation is
       
   280 	      // succeeded
       
   281 	      //
       
   282 		  delete iUserName; // Delete old user name buffer for sure
       
   283   	      iUserName = HBufC8::New(aDialogInfo->iUsername->Length() + 16); // 16 bytes space for padding
       
   284 		  if ( iUserName ) {
       
   285 		     iUserName->Des().Copy(aDialogInfo->iUsername->Des()); 
       
   286 		  } 	   
       
   287        }
       
   288 
       
   289        if ( aDialogInfo->iSecret ) {
       
   290           //
       
   291           // Add either password, passcode or next pin attribute.
       
   292           // Check from iRequestFlags which one was requested by the gateway
       
   293           //
       
   294 	      if ( iUseOlderPIXXauth )
       
   295 			   AttrType = ATTR_PIX_PASSWORD; // default;
       
   296 		  else AttrType = ATTR_PASSWORD; // default
       
   297 
       
   298           switch ( iRequestFlags ) {
       
   299 
       
   300               case (1 << (ATTR_PASSCODE - ATTR_XAUTH_TYPE)):
       
   301 				  if ( iUseOlderPIXXauth )
       
   302 					   AttrType = ATTR_PIX_PASSCODE;
       
   303 				  else AttrType = ATTR_PASSCODE;
       
   304                   break;
       
   305 
       
   306               case (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE)):
       
   307                   AttrType = ATTR_NEXT_PIN;
       
   308                   break;
       
   309 
       
   310               default:
       
   311                   break;
       
   312                    
       
   313           }   
       
   314           AddAttributeData(attr_ptr, AttrType, aDialogInfo->iSecret->Length(),
       
   315                           (TUint8*)aDialogInfo->iSecret->Ptr());           
       
   316        }
       
   317        
       
   318        BuildAndSendMessageL(attr_ptr, ISAKMP_CFG_REPLY);
       
   319        
       
   320        CleanupStack::PopAndDestroy(); //attributes 
       
   321        
       
   322        iRequestFlags = 0;
       
   323 
       
   324     }
       
   325     
       
   326     delete iDialog;  // delete dialog object
       
   327     delete aDialogInfo;  // release dialog info object  
       
   328     iDialog = NULL;
       
   329     iDialogInfo = NULL;  
       
   330      
       
   331     return TRANSACTION_CONTINUE;
       
   332 }   
       
   333 
       
   334 /**-------------------------------------------------------------------
       
   335  *
       
   336  * Method TransactionFailedL()
       
   337  * TransactionFailedL() is called when a notificatio/delete payload 
       
   338  * has been received in the middle of a transaction exchange.
       
   339  *
       
   340  *--------------------------------------------------------------------*/
       
   341 TInt CTransNegotiation::TransactionFailedL(const TNotificationISAKMP *aNotifPayload)
       
   342 {
       
   343 
       
   344     (void)aNotifPayload;
       
   345     iNegotiation->iTimer->Cancel();   //Cancel timer because authentication failed
       
   346     DEBUG_LOG(_L("Transaction exchange stopped by the gateway!"));
       
   347     // 
       
   348     // Dialog object shall be delete in Dialog->RunL when dialog completed
       
   349     //
       
   350     CIkev1Dialog* Dialog  = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);
       
   351     Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL);
       
   352     
       
   353     return TRANSACTION_FAILED;
       
   354 }
       
   355 
       
   356 /**-------------------------------------------------------------------
       
   357  *
       
   358  * Method ExecuteL()
       
   359  * Processes a received ISAKMP transaction exchange message.
       
   360  * The received message MUST be an encrypted transaction exchange message
       
   361  * otherwise it is silently discarded.
       
   362  * Current TTransExchange structure is found, IV value calculated and
       
   363  * ISAKMP message decrypted.
       
   364  * TransactionExchangeL() method returns to the caller the following status codes:
       
   365  * (Corresponding CRACK status codes  defined in ike_crack.h)
       
   366  * -- TRANSACTION_SUCCESS (0) =
       
   367  *    Transaction exchange(s) has been succesfully completed.
       
   368  *    Normal operation can continue and CTransNegotiation object can be deleted.
       
   369  * -- TRANSACTION_CONTINUE (1) =
       
   370  *    Received message succesfully processed.
       
   371  *    Transaction exchange(s) shall still continue. 
       
   372  * -- TRANSACTION_IGNORE   (2) =
       
   373  *    Received message ignored. Transaction exchange(s) shall still continue. 
       
   374  * -- TRANSACTION_FAILED   (4) =
       
   375  *    Transaction exchange(s) has been failed (either CONFIG-MODE or XAUTH).
       
   376  *    Current CNegotiation object as well as CTransNegotiation object can
       
   377  *    be deleted. (= corresponding ISAKMP phase 1 negotiation shall be deleted).
       
   378  *
       
   379  *--------------------------------------------------------------------*/
       
   380 #ifdef _DEBUG
       
   381 TInt CTransNegotiation::ExecuteL( const ThdrISAKMP& aHdr,
       
   382                                   const TInetAddr& aSrcAddr,
       
   383                                   TInt aLocalPort )
       
   384 #else
       
   385 TInt CTransNegotiation::ExecuteL( const ThdrISAKMP& aHdr,
       
   386                                   const TInetAddr& /*aSrcAddr*/,
       
   387                                   TInt /*aLocalPort*/ )
       
   388 #endif
       
   389 {
       
   390     DEBUG_LOG(_L("Received message (encr)."));
       
   391     
       
   392     TLastIKEMsg msg_info(aHdr); //For retransmitted IKE msg detection
       
   393     if ( iLastTransMsgInfo.IsReTransmit(msg_info) ) {
       
   394        DEBUG_LOG(_L("Retransmitted Transaction message received, silently discarded !"));
       
   395        return TRANSACTION_IGNORE;              
       
   396     }
       
   397     TUint32 status = TRANSACTION_IGNORE; // default
       
   398     TUint32 msg_id;
       
   399     TBuf8<IV_LTH> tmp_IV;   //Temporal IV. Used to update the real one if the msg OK    
       
   400     const ThdrISAKMP *hdr = NULL;
       
   401     TUint8 *msg = NULL;
       
   402     msg_id = aHdr.GetMessageId();   //Saves the ID to compute IV and hash
       
   403     
       
   404     if (aHdr.GetFlags() & ISAKMP_HDR_EFLAG) //if encrypted
       
   405     {
       
   406         msg = new (ELeave) TUint8[aHdr.GetLength()];    //to place the new msg
       
   407 		CleanupStack::PushL(msg);
       
   408 		
       
   409         Mem::Copy(msg, (TUint8 *)&aHdr, sizeof(aHdr));  //The header is not encrypted
       
   410 
       
   411 #ifdef _DEBUG        
       
   412         DEBUG_LOG(_L("Message ID recv:"));        
       
   413         TUint32 swap_id = ByteOrder::Swap32(msg_id);
       
   414         DEBUG_LOG_ARRAY((TUint8 *)&swap_id, sizeof(msg_id));
       
   415         DEBUG_LOG(_L("Transaction IV:"));
       
   416 #endif // _DEBUG        
       
   417         //
       
   418         // Find a transaction exchange structure for current message 
       
   419         //
       
   420         iCurrExchange = FindExchange(msg_id);
       
   421         if ( !iCurrExchange )
       
   422            iCurrExchange = AddExchangeL(msg_id, RESPONDER); // Add a new transaction exchange
       
   423         //
       
   424         // Adjust IV value for transaction exchange.
       
   425         // There is now two situations:
       
   426         // 1) There already exists an IV in exchange structure
       
   427         //    (received message is a reply for an earlier sent request)
       
   428         // 2) There is no IV in exchange structure
       
   429         //    (received message is a new request/set message from peer)
       
   430         //    A new IV is built from CNegotiation.iLastIV and current message ID
       
   431         //
       
   432         if ( iCurrExchange->iIV.Length() == 0 ) {
       
   433            iCurrExchange->iIV.Copy(iNegotiation->iLastIV);          
       
   434            iNegotiation->ComputeIVL(iCurrExchange->iIV, msg_id);        
       
   435         }
       
   436         tmp_IV.Copy(iCurrExchange->iIV); // Make a copy of current IV                       
       
   437 
       
   438         DEBUG_LOG(_L("Decrypting..."));
       
   439 
       
   440         DecryptL((TUint8 *)aHdr.Next(),&msg[sizeof(aHdr)], (aHdr.GetLength()-sizeof(aHdr)),
       
   441                  iCurrExchange->iIV, iNegotiation->iSKEYID_e,
       
   442                  iNegotiation->iChosenProposal_I.iAttrList->iEncrAlg);
       
   443         hdr = (ThdrISAKMP *)msg;  //decrypted msg
       
   444 
       
   445 #ifdef _DEBUG   
       
   446         const TPtrC8 ikeMsgPtr( (TUint8*)hdr,(TUint16)hdr->GetLength() );
       
   447         TInetAddr dstAddr;
       
   448         iPluginSession->GetLocalAddress( dstAddr );
       
   449         dstAddr.SetPort( aLocalPort );
       
   450         TRACE_MSG_IKEV1( ikeMsgPtr, aSrcAddr, dstAddr );                        
       
   451 #endif // _DEBUG                        
       
   452         
       
   453         status = TransactionExchangeL(*hdr);
       
   454 
       
   455         if ( status == TRANSACTION_IGNORE ) {
       
   456            //
       
   457            // Current message ignored, restore saved IV to exchange structure
       
   458            //   
       
   459            iCurrExchange->iIV.Copy(tmp_IV);
       
   460         }
       
   461     }
       
   462     else
       
   463         hdr = &aHdr;
       
   464 
       
   465     if (msg)    //If used erase it (when encryption)
       
   466         CleanupStack::PopAndDestroy();
       
   467 	
       
   468     if ( status == TRANSACTION_CONTINUE )
       
   469        msg_info.Store(iLastTransMsgInfo); // store new last received IKE message info
       
   470     
       
   471     return status;
       
   472 }
       
   473 
       
   474 /**-------------------------------------------------------------------
       
   475  *
       
   476  * Method TransactionExchangeL()
       
   477  * The ISAKMP transaction exchange message MUST be the following format:
       
   478  * HDR*, HASH, ATTR
       
   479  * Where the HASH payload contains the prf output, using SKEYID_a as
       
   480  * the key, and the M-ID (ISAKMP header Message ID) unique to this
       
   481  * exchange concatenated with all of the payloads after the HASH
       
   482  * payload. In other words, the hash for the above exchange is:
       
   483  * HASH = prf( SKEYID_a, M-ID | ATTR )
       
   484  * Multiple ATTR payloads MAY NOT be present in the Transaction Exchange.
       
   485  *
       
   486  *--------------------------------------------------------------------*/
       
   487 TInt CTransNegotiation::TransactionExchangeL(const ThdrISAKMP &aHdr)
       
   488 {
       
   489     TUint32 status;
       
   490 	iNegotiation->iLengthLeft = aHdr.GetLength(); //Used to check the size in the payload are OK
       
   491 	
       
   492 	CIkev1Payloads* payload = CIkev1Payloads::NewL(aHdr, *iNegotiation, iDebug);
       
   493 	if (!payload)
       
   494 	{	
       
   495 		return TRANSACTION_FAILED;    
       
   496 	}
       
   497 	CleanupStack::PushL(payload);
       
   498 
       
   499 	if ( payload->iHash && payload->iAttr )
       
   500 	{
       
   501 	   // 
       
   502 	   // Check if the hash value is OK. 
       
   503 	   // 
       
   504 	   if (!iNegotiation->VerifyInformationalHashL(payload->iHash, payload->iAttr,
       
   505 		                                           iCurrExchange->iMessageId))
       
   506 	   {	   
       
   507 	      DEBUG_LOG(_L("AUTHENTICATION_FAILED (Transaction hash)"));
       
   508 		  CleanupStack::PopAndDestroy();  //payload					  
       
   509 		  return TRANSACTION_FAILED;                    
       
   510    	   }
       
   511 	   status = ProcessAttributesL(payload->iAttr);
       
   512 	   CleanupStack::PopAndDestroy();  //payload
       
   513 	   return status;
       
   514 	}
       
   515 	CleanupStack::PopAndDestroy();  //payload    	
       
   516    	DEBUG_LOG(_L("Erroneous Transaction Exchange message received"));		
       
   517 	return TRANSACTION_FAILED;    
       
   518 }
       
   519 
       
   520 /**-------------------------------------------------------------------
       
   521  *
       
   522  * Method ProcessAttributesL()
       
   523  * ProcessAttributesL() method parses the data attributes in received
       
   524  * attribute payload. If the iRole data member of current exchange structure
       
   525  * contains value INITIATOR, attribute payload is a CONFIG-MODE Reply
       
   526  * which should contain CONFIG-MODE attributes.
       
   527  * If the iRole data member of current exchange structure
       
   528  * contains value RESPONDER, attribute payload is either a XAUTH Request or Set.
       
   529  * These primitives should contain XAUTH attributes.
       
   530  *
       
   531  *--------------------------------------------------------------------*/
       
   532 TInt CTransNegotiation::ProcessAttributesL(const TAttributeISAKMP *aAttr)
       
   533 {
       
   534     TInt length = (TInt)aAttr->GetLength();
       
   535     if ( STATIC_CAST(TUint, length) < sizeof(TAttributeISAKMP) ) {
       
   536        return TRANSACTION_FAILED; 
       
   537     }
       
   538 
       
   539     TInt status;
       
   540     TUint8  cfg_msg_type = aAttr->CfgMsgType(); 
       
   541     TUint16 identifier   = aAttr->Identifier();
       
   542     
       
   543     if ( iCurrExchange->iRole == INITIATOR ) {
       
   544        //
       
   545        // Config mode transaction. The current message should be a reply.
       
   546        // Identifier value must also match to value in current exchange structure.
       
   547        //
       
   548        if ( cfg_msg_type != ISAKMP_CFG_REPLY ) {
       
   549 //          ||
       
   550 //          ( iCurrExchange->iIdentifier != identifier ) ) { 
       
   551           return TRANSACTION_FAILED; 
       
   552        }       
       
   553        status = ProcessCfgModeAttrsL(aAttr->AttrData(), aAttr->AttrDataLen());
       
   554     }
       
   555     else {
       
   556        //
       
   557        // XAUTH mode transaction. The current message should be either request
       
   558        // or set.
       
   559        //
       
   560        if ( (cfg_msg_type != ISAKMP_CFG_REQUEST) && (cfg_msg_type != ISAKMP_CFG_SET) ) {
       
   561           return TRANSACTION_FAILED; 
       
   562        }
       
   563        iCurrExchange->iIdentifier = identifier;
       
   564        if ( cfg_msg_type == ISAKMP_CFG_REQUEST ) 
       
   565             status = ProcessXauthRequestL(aAttr->AttrData(), aAttr->AttrDataLen());
       
   566        else status = ProcessXauthStatusL(aAttr->AttrData(), aAttr->AttrDataLen());    
       
   567     }
       
   568 
       
   569     return CheckTransactionStatusL(status);
       
   570     
       
   571 }   
       
   572 
       
   573 /**-------------------------------------------------------------------
       
   574  *
       
   575  * Method ProcessCfgModeAttrs()
       
   576  * ProcessCfgModeAttrs parses  CONFIG-MODE reply message attributes 
       
   577  * received from gateway. In this phase the following attributes are used:
       
   578  * -- INTERNAL_IP4_ADDRESS  = Client virtual IPv4 address in secure network
       
   579  * -- INTERNAL_IP6_ADDRESS  = Client virtual IPv6 address in secure network
       
   580  * -- INTERNAL_IP4_DNS      = DNS address(es) in secure network
       
   581  *
       
   582  * All other attributes are silently discarded
       
   583  *
       
   584  *--------------------------------------------------------------------*/
       
   585 TInt CTransNegotiation::ProcessCfgModeAttrsL(TDataISAKMP* aAttr, TInt aLth)
       
   586 {
       
   587     
       
   588     TBool   ia_received = EFalse;
       
   589     TUint32  ipv4_addr; 
       
   590     TIp6Addr ipv6_addr;    //IPV6 raw address
       
   591     TInetAddr *dns_addr;
       
   592     
       
   593     delete iInternalAddr;  // delete old CInternalAddress for sure
       
   594     iInternalAddr = NULL;
       
   595     CInternalAddress *InternalAddr = new (ELeave)CInternalAddress(1);   
       
   596     CleanupStack::PushL(InternalAddr);
       
   597     
       
   598     while ( aLth > 0 ) {
       
   599         
       
   600         aLth = aLth - aAttr->Size();
       
   601         if ( aLth < 0 ) {
       
   602            DEBUG_LOG(_L("CONFIG-MODE REPLY ERROR (Length mismatch in the attibutes)"));
       
   603            CleanupStack::PopAndDestroy(); // InternalAddr
       
   604            return TRANSACTION_FAILED;
       
   605         }
       
   606         switch ( aAttr->Type() ) {
       
   607 
       
   608            case ATTR_INTERNAL_IP4_ADDR:
       
   609                 //
       
   610                 // A Virtual IPv4 address received.
       
   611                 // Store value to CInternalAddress object
       
   612                 // 
       
   613                 if ( !aAttr->IsBasic() && (aAttr->Length() == 4) ) {
       
   614                    if ( !ia_received ) {
       
   615                       ia_received = ETrue;                    
       
   616                       ipv4_addr = GET32(aAttr->VarValue()); 
       
   617                       InternalAddr->iClientIntAddr.SetAddress(ipv4_addr);
       
   618                    }   
       
   619                 }
       
   620                 break;
       
   621 
       
   622            case ATTR_INTERNAL_IP6_ADDR:
       
   623                 //
       
   624                 // A Virtual IPv6 address received.
       
   625                 // Store value to CInternalAddress object
       
   626                 // 
       
   627                 if ( !aAttr->IsBasic() && (aAttr->Length() == 16) ) {
       
   628                    if ( !ia_received ) {
       
   629                       ia_received = ETrue;
       
   630                       Mem::Copy(&ipv6_addr.u.iAddr8, aAttr->VarValue(), sizeof(ipv6_addr.u.iAddr8));
       
   631                       InternalAddr->iClientIntAddr.SetAddress(ipv6_addr);
       
   632                    }   
       
   633                 }
       
   634                 break;
       
   635 
       
   636            case ATTR_INTERNAL_IP4_DNS:
       
   637                 //
       
   638                 // Internal DNS address received.
       
   639                 // Add value to CInternalAddress object
       
   640                 // 
       
   641                 if ( !aAttr->IsBasic() && (aAttr->Length() == 4) ) {
       
   642                    ipv4_addr = GET32(aAttr->VarValue());
       
   643                    dns_addr  = new(ELeave)TInetAddr;
       
   644                    CleanupStack::PushL(dns_addr);                  
       
   645                    dns_addr->SetAddress(ipv4_addr);
       
   646                    InternalAddr->AppendL(dns_addr);
       
   647                    CleanupStack::Pop();  // dns_addr
       
   648                 }
       
   649                 break;
       
   650             
       
   651            default:
       
   652                 break;
       
   653         }
       
   654         
       
   655         aAttr = aAttr->Next();
       
   656     }
       
   657     
       
   658     CleanupStack::Pop(); // InternalAddr
       
   659     iInternalAddr = InternalAddr;   
       
   660 
       
   661     iCfgModeCompleted = ETrue;
       
   662 
       
   663     DEBUG_LOG(_L("CONFIG-MODE completed, reply received!"));       
       
   664     
       
   665     return TRANSACTION_SUCCESS;
       
   666 }
       
   667 
       
   668 /**-------------------------------------------------------------------
       
   669  *
       
   670  * Method ProcessXauthRequest()
       
   671  * ProcessXauthRequest parses XAUTH request message attributes 
       
   672  * received from gateway. 
       
   673  *
       
   674  *--------------------------------------------------------------------*/
       
   675 TInt CTransNegotiation::ProcessXauthRequestL(TDataISAKMP* aAttr, TInt aLth)
       
   676 {
       
   677     TInt     status        = TRANSACTION_CONTINUE;
       
   678     TUint16  xauth_type    = ATTR_XAUTH_GENERIC;
       
   679     TUint32  request_flags = 0;
       
   680     TPtr8    challenge(NULL, 0);
       
   681 	TUint16  attr_type;
       
   682 	
       
   683     while ( aLth > 0 ) {
       
   684         
       
   685         aLth = aLth - aAttr->Size();
       
   686         if ( aLth < 0 ) {
       
   687            DEBUG_LOG(_L("XAUTH REQUEST ERROR (Length mismatch in the attibutes)"));
       
   688            return TRANSACTION_FAILED;
       
   689         }
       
   690 		attr_type = aAttr->Type();
       
   691 		//
       
   692 		// Check does the VPN gateway support older XAUTH draft version
       
   693 		// draft-ietf-ipsec-isakmp-xauth-04.txt.
       
   694 		// The check is based on attribute type values. In the older
       
   695 		// draft attribute values are defined in range (13-20) and in the newer
       
   696 		// "de-facto" draft-beaulieu-ike-xauth-02.txt the same
       
   697 		// attribute values are in "private use" range (16520-16529)
       
   698 		//
       
   699 		if ( attr_type < ATTR_XAUTH_TYPE )
       
   700 			iUseOlderPIXXauth = ETrue;	
       
   701  
       
   702         switch ( attr_type ) {
       
   703 
       
   704            case ATTR_XAUTH_TYPE:
       
   705 		   case ATTR_PIX_XAUTH_TYPE:			   
       
   706                 //
       
   707                 // Extended authentication type requested
       
   708                 //
       
   709                 if ( aAttr->IsBasic() ) { // Basic attribute
       
   710                    request_flags |= (1 << (ATTR_XAUTH_TYPE - ATTR_XAUTH_TYPE));                 
       
   711                    iCurrExchange->iXauthType = aAttr->Value();
       
   712                 }
       
   713                 break;
       
   714 
       
   715            case ATTR_USER_NAME:
       
   716            case ATTR_PASSWORD:                         
       
   717            case ATTR_PASSCODE:
       
   718 		   case ATTR_PIX_USER_NAME:
       
   719 		   case ATTR_PIX_PASSWORD:
       
   720 		   case ATTR_PIX_PASSCODE:
       
   721                 //
       
   722                 // Handles the following attribute values:
       
   723                 // -- User name
       
   724                 // -- Password
       
   725                 // -- Passcode
       
   726                 // Set a corresponding bit request flags. Parameter contents has
       
   727                 // no meaning in request
       
   728                 // 
       
   729                 if ( !aAttr->IsBasic() ) {  // Variable length
       
   730 				   if ( attr_type < ATTR_USER_NAME )
       
   731 					    request_flags |= (1 << (attr_type - ATTR_PIX_XAUTH_TYPE)); 					   
       
   732                    else request_flags |= (1 << (attr_type - ATTR_XAUTH_TYPE)); 
       
   733                 }
       
   734                 break;
       
   735 
       
   736            case ATTR_MESSAGE:
       
   737 		   case ATTR_PIX_MESSAGE:
       
   738                 //
       
   739                 // Message data attribute (NOT USED IN THIS PHASE)
       
   740                 // 
       
   741                 break;
       
   742 
       
   743            case ATTR_CHALLENGE:
       
   744 		   case ATTR_PIX_CHALLENGE:
       
   745                 //
       
   746                 // Challenge data attribute
       
   747                 //
       
   748                 if ( !aAttr->IsBasic() && aAttr->Length() ) {
       
   749                    request_flags |= (1 << (ATTR_CHALLENGE - ATTR_XAUTH_TYPE));
       
   750                    challenge.Set(aAttr->VarValue(), aAttr->Length(), aAttr->Length());    
       
   751                 }
       
   752                 break;
       
   753 
       
   754            case ATTR_DOMAIN:
       
   755 		   case ATTR_STATUS:
       
   756 		   case ATTR_PIX_DOMAIN:			   
       
   757 		   case ATTR_PIX_STATUS:
       
   758                 //
       
   759                 // Domain and status attributes (NOT USED IN THIS PHASE)
       
   760                 // 
       
   761                 break;
       
   762 
       
   763            case ATTR_NEXT_PIN:                          
       
   764                 if ( !aAttr->IsBasic() ) {  // Variable length
       
   765                    request_flags |= (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE)); 
       
   766                 }
       
   767                 break;
       
   768 
       
   769            case ATTR_ANSWER:
       
   770                 //
       
   771                 // Answer data attribute (NOT USED IN THIS PHASE)
       
   772                 // 
       
   773                 break;
       
   774             
       
   775            default:
       
   776                 break;
       
   777         }
       
   778         
       
   779         aAttr = aAttr->Next();
       
   780     }
       
   781 
       
   782     //
       
   783     // Check if there already exist a authentication credentials request active
       
   784     // (= iRequestFlags are not zero). If there is ignore current message.
       
   785     //
       
   786     if ( iRequestFlags == 0 ) {
       
   787        iRequestFlags = request_flags;
       
   788     }    
       
   789     else {
       
   790        request_flags = 0;
       
   791        status        = TRANSACTION_IGNORE;
       
   792     }   
       
   793     //
       
   794     // Examine request_flags and show appropriate dialog to get requested
       
   795     // authentication credentials from user
       
   796     //
       
   797     switch ( request_flags & ~(1 << (ATTR_XAUTH_TYPE - ATTR_XAUTH_TYPE)) ) {
       
   798 
       
   799         case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_PASSWORD - ATTR_XAUTH_TYPE))):
       
   800             //
       
   801             //  User name/Password authentication required
       
   802             //
       
   803 			iDialog     = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);			
       
   804             iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId);
       
   805             iDialog->GetAsyncUNPWDialogL(iDialogInfo, (MIkeDialogComplete*)this);          
       
   806             break;
       
   807 
       
   808         case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_PASSCODE - ATTR_XAUTH_TYPE))):
       
   809             //
       
   810             //  User name/Secure ID authentication required
       
   811             //
       
   812             iDialog     = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);
       
   813             iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId);
       
   814             iDialog->GetAsyncSecureidDialogL(iDialogInfo, (MIkeDialogComplete*)this);          
       
   815             break;
       
   816 
       
   817         case ( (1 << (ATTR_USER_NAME - ATTR_XAUTH_TYPE)) | (1 << (ATTR_NEXT_PIN - ATTR_XAUTH_TYPE))):
       
   818             //
       
   819             //  User name/Secure ID next pin required
       
   820             //
       
   821 			iDialog     = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);			
       
   822 			iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId);
       
   823             iDialog->GetAsyncSecureNextPinDialogL(iDialogInfo, (MIkeDialogComplete*)this);
       
   824             break;
       
   825 
       
   826         case ( (1 << (ATTR_CHALLENGE - ATTR_XAUTH_TYPE)) ):
       
   827             //
       
   828             //  User Challenge response dialog
       
   829             //
       
   830             if ( xauth_type == ATTR_XAUTH_RADIUS_CHAP )
       
   831 			{
       
   832 				iDialog     = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);			
       
   833 				iDialogInfo = new(ELeave) CAuthDialogInfo(iPluginSession, XAUTH_DIALOG_ID, iNegotiation->SAId(), iCurrExchange->iMessageId);
       
   834                 iDialog->GetAsyncRespDialog(challenge, iDialogInfo, (MIkeDialogComplete*)this);
       
   835             }   
       
   836             break;
       
   837 
       
   838         default:
       
   839             break;
       
   840 
       
   841     }   
       
   842     
       
   843     return status;
       
   844 
       
   845 }
       
   846 
       
   847 /**-------------------------------------------------------------------
       
   848  *
       
   849  * Method ProcessXauthStatus()
       
   850  * ProcessXauthStatus parses XAUTH Set message attributes received from gateway.
       
   851  * Only Status attribute has any relevance in Set message.
       
   852  *
       
   853  *--------------------------------------------------------------------*/
       
   854 TInt CTransNegotiation::ProcessXauthStatusL(TDataISAKMP* aAttr, TInt aLth)
       
   855 {
       
   856     TBuf8<16> attributes;    
       
   857     TInt      status = TRANSACTION_CONTINUE;
       
   858     TInt16    attr_status;
       
   859     
       
   860     while ( aLth > 0 ) {
       
   861         
       
   862         aLth = aLth - aAttr->Size();
       
   863         if ( aLth < 0 ) {
       
   864            DEBUG_LOG(_L("XAUTH SET ERROR (Length mismatch in the attibutes)"));
       
   865            return TRANSACTION_FAILED;
       
   866         }
       
   867 
       
   868         switch ( aAttr->Type() ) {
       
   869 
       
   870            case ATTR_STATUS:
       
   871 		   case ATTR_PIX_STATUS:			   
       
   872                 //
       
   873                 // Status code from gateway
       
   874                 // 
       
   875                 if ( aAttr->IsBasic() ) { // Basic attribute
       
   876                    attr_status = aAttr->Value();    
       
   877                    if ( attr_status == ATTR_STATUS_OK )
       
   878                         status = TRANSACTION_SUCCESS;
       
   879                    else status = TRANSACTION_FAILED;   
       
   880                 }
       
   881                 break;
       
   882             
       
   883            default:
       
   884                 break;
       
   885         }
       
   886         
       
   887         aAttr = aAttr->Next();
       
   888     }
       
   889     
       
   890     if ( status != TRANSACTION_CONTINUE ) {
       
   891        //
       
   892        // Send Transaction exchange ACK
       
   893        //
       
   894 	   TUint16 AttrType;
       
   895 	   if ( iUseOlderPIXXauth )
       
   896 		    AttrType = ATTR_PIX_STATUS;
       
   897 	   else AttrType = ATTR_STATUS;
       
   898 	   
       
   899        AddAttributeData(attributes, AttrType, 2, (TUint8*)&attr_status);
       
   900        BuildAndSendMessageL(attributes, ISAKMP_CFG_ACK);
       
   901        if ( status == TRANSACTION_SUCCESS ) {
       
   902           DEBUG_LOG(_L("XAUTH authentication succeeded!"));
       
   903           iXauthCompleted = ETrue;
       
   904 		  if ( iUserName ) {
       
   905 		     //
       
   906     		 // Cache user name into user name file
       
   907 			 //
       
   908 		     CIkev1Dialog* Dialog = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);
       
   909              CleanupStack::PushL(Dialog);
       
   910 			 TInt err(KErrNone);
       
   911 			 TRAP(err, Dialog->StoreUserNameL(iUserName->Des()));
       
   912 #ifdef _DEBUG			 
       
   913 			 if (err == KErrNone)
       
   914 			     DEBUG_LOG(_L("User Name caching succeeded"));
       
   915 			 else DEBUG_LOG(_L("User Name caching failed"));
       
   916 #endif // _DEBUG			 
       
   917 			 CleanupStack::PopAndDestroy();					 
       
   918 		  }	   
       
   919        }            
       
   920        else {
       
   921           DEBUG_LOG(_L("XAUTH authentication failed!"));
       
   922 	   // Dialog object shall be delete in Dialog->RunL when dialog completed				  
       
   923           CIkev1Dialog* Dialog  = CIkev1Dialog::NewL(iPluginSession, iPluginSession->DialogAnchor(), iDebug);		  
       
   924           Dialog->ShowErrorDialogL(TVpnNoteDialog::EKmdAuthenticationFailed, NULL, NULL);
       
   925        }
       
   926     }
       
   927     
       
   928     return status;
       
   929 }
       
   930 
       
   931 /**--------------------------------------------------------------------------------
       
   932  *
       
   933  * Method CheckTransactionStatusL()
       
   934  * CheckTransactionStatus is after an incoming ISAKMP transaction exchange message
       
   935  * has been processed. This method decides the actions shall be taken next:
       
   936  * -- If current status (= call parameter) is continue, ignore or failed
       
   937  *    ==> Same status is returned
       
   938  * -- If current status is success and XAUTH completed.     
       
   939  *    ==> CONFIG MODE actions are started (= Config mode request is transmitted)
       
   940  * -- If current status is success and CONFIG MODE completed.     
       
   941  *    ==> XAUTH actions are started. (= We shall just wait for XAUTH request)
       
   942  * -- If current status is success and both CONFIG-MODE and XAUTH completed
       
   943  *    ==> TRANSACTION_SUCCESS status is returned
       
   944  *
       
   945  *--------------------------------------------------------------------*/
       
   946 TInt CTransNegotiation::CheckTransactionStatusL(TInt aStatus)
       
   947 {
       
   948     if ( aStatus == TRANSACTION_SUCCESS || aStatus == TRANSACTION_CONTINUE ) {
       
   949        //
       
   950        // Stop retransmission timer 
       
   951        //
       
   952        iNegotiation->iTimer->Cancel();
       
   953        
       
   954        if ( aStatus == TRANSACTION_SUCCESS ) {
       
   955           if ( iXauthCompleted ) {
       
   956              if ( !iCfgModeCompleted ) {
       
   957                 aStatus = BuildConfigRequestL();
       
   958              }    
       
   959           }
       
   960           else {
       
   961              if ( !iXauthCompleted ) {
       
   962                 aStatus = TRANSACTION_CONTINUE;
       
   963              }    
       
   964           }    
       
   965        }
       
   966     }
       
   967     
       
   968     return aStatus;
       
   969 }   
       
   970 
       
   971 /**-------------------------------------------------------------------
       
   972  *
       
   973  * Method BuildConfigRequestL()
       
   974  * BuildConfigRequestL() builds the CONFIG-MODE request message. 
       
   975  * In this phase requests the following parameters from gateway:
       
   976  * -- Client virtual IP in secure network = INTERNAL_IP4_ADDRESS, INTERNAL_IP4_NETMASK
       
   977  *                                         (INTERNAL_IP6_ADDRESS, INTERNAL_IP6_NETMASK)
       
   978  * -- DNS address(es) in secure network   = INTERNAL_IP4_DNS  
       
   979  *
       
   980  *--------------------------------------------------------------------*/
       
   981 TInt CTransNegotiation::BuildConfigRequestL()
       
   982 {
       
   983 
       
   984     TBuf8<16> attributes;
       
   985     
       
   986     TUint32  message_id = iNegotiation->RandomMessageId();
       
   987 
       
   988     iCurrExchange = AddExchangeL(message_id, INITIATOR); //Add a new transaction exchange
       
   989     iCurrExchange->iIdentifier = GetIdentifier();
       
   990     
       
   991     iCurrExchange->iIV.Copy(iNegotiation->iLastIV);      // Calculate base IV for ..
       
   992     iNegotiation->ComputeIVL(iCurrExchange->iIV, message_id); // transaction message
       
   993 
       
   994     AddAttributeData(attributes, ATTR_INTERNAL_IP4_ADDR, 0, NULL);
       
   995     AddAttributeData(attributes, ATTR_INTERNAL_IP4_DNS, 0, NULL);
       
   996 	
       
   997     BuildAndSendMessageL(attributes, ISAKMP_CFG_REQUEST);
       
   998     DEBUG_LOG(_L("CONFIG-MODE started, request xmitted!")); 
       
   999 
       
  1000     return TRANSACTION_CONTINUE;
       
  1001 
       
  1002     
       
  1003 }
       
  1004 
       
  1005 /**-------------------------------------------------------------------
       
  1006  *
       
  1007  * Method AddAttributeData()
       
  1008  * AddAttributeData() method adds one attribute data to an attribute buffer
       
  1009  *
       
  1010  *--------------------------------------------------------------------*/
       
  1011 void CTransNegotiation::AddAttributeData(TDes8& aAttrBfr, TInt aType, TInt aLth, TUint8* aData)
       
  1012 {
       
  1013     TDataISAKMP attr;
       
  1014     if ( aType == ATTR_STATUS     || aType == ATTR_XAUTH_TYPE ||
       
  1015 		 aType == ATTR_PIX_STATUS || aType == ATTR_PIX_XAUTH_TYPE) {
       
  1016        //
       
  1017        // Add a basic length attribute
       
  1018        //
       
  1019        attr.SetBasic(ETrue);
       
  1020        attr.SetType((TUint16)aType);
       
  1021        if ( aData ) 
       
  1022           attr.SetValue(*(TUint16*)aData);
       
  1023        aAttrBfr.Append((TUint8 *)&attr, sizeof(attr));
       
  1024     }
       
  1025     else {
       
  1026        //
       
  1027        // Add a variable length attribute
       
  1028        //
       
  1029        attr.SetBasic(EFalse);
       
  1030        attr.SetType((TUint16)aType);
       
  1031        attr.SetLength((TUint16)(aLth));
       
  1032        aAttrBfr.Append((TUint8 *)&attr, sizeof(attr));
       
  1033        if ( aLth ) 
       
  1034           aAttrBfr.Append(aData, aLth);       
       
  1035     }   
       
  1036 }
       
  1037 
       
  1038 /**-------------------------------------------------------------------
       
  1039  *
       
  1040  * Method BuildAndSendMessageL()
       
  1041  * BuildAndSendMessage() method builds ISAKMP transaction exchange message
       
  1042  * and transmits it using CNegotiation class send() method.
       
  1043  * The payload format of a transaction exchange message is the following:
       
  1044  * HDR*, HASH, ATTR
       
  1045  * Where the HASH payload contains the prf output, using SKEYID_a as
       
  1046  * the key, and the M-ID (ISAKMP header Message ID) unique to this
       
  1047  * exchange concatenated with all of the payloads after the HASH
       
  1048  * payload. In other words, the hash for the above exchange is:
       
  1049  * HASH = prf( SKEYID_a, M-ID | ATTR )
       
  1050  *
       
  1051  *--------------------------------------------------------------------*/
       
  1052 void CTransNegotiation::BuildAndSendMessageL(TDesC8& aAttrBfr, TUint8 aMsgType)
       
  1053 {
       
  1054 	TIkev1IsakmpStream* msg = iNegotiation->SaveIkeMsgBfr( new (ELeave) TIkev1IsakmpStream(iDebug) );
       
  1055 	
       
  1056     TUint32 saved_msg_id     = iNegotiation->iMessageId;
       
  1057     TUint8  saved_exchange   = iNegotiation->iExchange;
       
  1058     iNegotiation->iMessageId = iCurrExchange->iMessageId; // used in method Isakmp_INIT()
       
  1059     iNegotiation->iExchange  = ISAKMP_EXCHANGE_TRANSACT;  // used in method Isakmp_INIT()
       
  1060     
       
  1061     msg->IsakmpInit(iNegotiation);
       
  1062     msg->IsakmpHashL();
       
  1063     msg->IsakmpAttributes(aMsgType, iCurrExchange->iIdentifier, aAttrBfr);  
       
  1064     msg->IsakmpHashContL();
       
  1065     
       
  1066     iNegotiation->SendL(*msg);
       
  1067 
       
  1068     iNegotiation->iMessageId = saved_msg_id;
       
  1069     iNegotiation->iExchange  = saved_exchange;
       
  1070     
       
  1071 }
       
  1072 
       
  1073 /**-------------------------------------------------------------------
       
  1074  *
       
  1075  * Method FindExchange()
       
  1076  * FindExchange() method finds a exchange strcuture for a specified message id 
       
  1077  *
       
  1078  *--------------------------------------------------------------------*/
       
  1079 TTransExchange* CTransNegotiation::FindExchange(TUint32 aMsgId)
       
  1080 {
       
  1081     TTransExchange *exchange;
       
  1082     TInt i = 0;
       
  1083 
       
  1084     while ( i < Count() )
       
  1085     {
       
  1086         exchange = At(i);
       
  1087         if ( exchange->iMessageId == aMsgId )
       
  1088            return exchange;
       
  1089         i ++;
       
  1090     }   
       
  1091 
       
  1092     return NULL;
       
  1093 }
       
  1094 
       
  1095 /**-------------------------------------------------------------------
       
  1096  *
       
  1097  * Method AddExchangeL()
       
  1098  * AddExchangeL() method allocates a new exchange structure and adds it
       
  1099  * to exchange array. 
       
  1100  *
       
  1101  *--------------------------------------------------------------------*/
       
  1102 TTransExchange* CTransNegotiation::AddExchangeL(TUint32 aMsgId, TUint8 aRole )
       
  1103 {
       
  1104     
       
  1105     TTransExchange *exchange =  new(ELeave)TTransExchange;
       
  1106     exchange->iMessageId     = aMsgId;
       
  1107     exchange->iRole          = aRole;
       
  1108     exchange->iIV.SetLength(0);
       
  1109     AppendL(exchange);
       
  1110     
       
  1111     return exchange;
       
  1112 }
       
  1113 
       
  1114 //
       
  1115 // The implementation for class MIkeDialogComplete virtual function
       
  1116 //
       
  1117 TInt CTransNegotiation::DialogCompleteL(CIkev1Dialog* /*aDialog*/, TAny* aUserInfo,
       
  1118 								        HBufC8* aUsername, HBufC8* aSecret, HBufC8* aDomain)
       
  1119 {
       
  1120 /*---------------------------------------------------------------------------
       
  1121  *  
       
  1122  *  A response received from client user (through asynchronous dialog)
       
  1123  *  This method is introduced as a TUserCallback for CGetIKEPassword dialog
       
  1124  *  object is created. When the dialog is completed this callback function
       
  1125  *  is called to deliver Credentials data for CHRE payload attributes.
       
  1126  *  Store credential buffers to CAuthDialogInfo object and call engine
       
  1127  *  entry  
       
  1128  *  
       
  1129  *-------------------------------------------------------------------------*/
       
  1130 	TUint32 obj_id = 1;
       
  1131 	CAuthDialogInfo* info = (CAuthDialogInfo*)aUserInfo;
       
  1132 	DEBUG_LOG1(_L("CIKECRACKNegotiation::DialogCompleteL(), aUserInfo =  %x"), aUserInfo);
       
  1133 
       
  1134 	if ( info )
       
  1135 	{
       
  1136 		obj_id = info->GetObjId();
       
  1137 		DEBUG_LOG1(_L("Preparing to call AuthDialogCompletedL(), ObjId = %x"), obj_id);
       
  1138 		if ( obj_id == XAUTH_DIALOG_ID )
       
  1139 		{
       
  1140 			info->iUsername = aUsername;
       
  1141 			info->iSecret   = aSecret;
       
  1142 			info->iDomain   = aDomain;
       
  1143 			obj_id = info->PluginSession()->AuthDialogCompletedL(info);
       
  1144 		}   
       
  1145 	}
       
  1146 
       
  1147 	return obj_id;
       
  1148 }