vpnengine/ikev1lib/src/ikev1private.cpp
changeset 0 33413c0669b9
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: 
       
    15 * This module contains the private vendor specific extension of IKE.
       
    16 * All of the current private extensions are related to Nokia VPN gateway
       
    17 * and shall be used ONLY when the EPOC IKE is acting as a Nokia VPN remote
       
    18 * access client.
       
    19 * The following private extension are implemented:
       
    20 *
       
    21 * 1) Internal Address payload usage
       
    22 *    Internal address payload is used to the deliver a secure network
       
    23 *    adderess and secure network DNS address(es) from VPN gateway to a client.
       
    24 *    The Internal address payloads are used in the last two IKE main mode
       
    25 *    messages as follows:
       
    26 *
       
    27 *    Client (initiator)                           Gateway (responder)
       
    28 *    .. SA, KE ...             --->
       
    29 *                              <---               ..SA, KE ...
       
    30 *    HDR*, INT_ADDR            --->
       
    31 *                              <---               HDR*, INT_ADDR
       
    32 *
       
    33 *    Client sends an INT_ADDR payload with PRI_INTERNAL_ADDRESS attribute
       
    34 *    Attribute value is 0.0.0.0.
       
    35 *
       
    36 *    Gateway responds with an INT_ADDR payload with PRI_INTERNAL_ADDRESS
       
    37 *    attribute containing client internal address x.y.z.w
       
    38 *    Gateway INT_ADDR payload may also contain attributes PRI_INTERNAL_DNS and
       
    39 *    PRI_INTERNAL_WINS. PRI_INTERNAL_DNS contains a list of DNS IP addresses and
       
    40 *    PRI_INTERNAL_WINS a list of WINS IP addresses.
       
    41 *       
       
    42 *
       
    43 * 2) The NAT Traversal probing
       
    44 *    The expanded Vendor-Id payload usage for the NAT Traversal probing.
       
    45 *    The expanded Vendor-Id payloads contains the following information:
       
    46 *
       
    47 *    Client (initiator)                           Gateway (responder)
       
    48 *    VID(hash, ip_addr, port)  --->
       
    49 *                              <---               VID(hash, detected_ip_addr,
       
    50 *                                                           detected_port)
       
    51 *
       
    52 *    Client sends a expanded Vendor-Id payload containing the following information:
       
    53 *    hash    = Nokia VPN vendor specific hash data (used to recognize peer)
       
    54 *    ip_addr = Client IKE own IP address
       
    55 *    port    = Client IKE own port (=500)
       
    56 *
       
    57 *    Gateway responds with expanded Vendor-Id payload containing the following information:
       
    58 *    hash    = Nokia VPN vendor specific hash data (used to recognize peer)
       
    59 *    detected_ip_addr = Client IP address as detected in received IKE message
       
    60 *                       IP header (=source IP address)
       
    61 *    detected_port    = Client port as detected in received IKE message
       
    62 *                       UDP header (=source port)
       
    63 *
       
    64 *    Both client and gateway do the following examination
       
    65 *    if ( ip_addr != detected_ip_addr ) || ( port != detected_port )
       
    66 *    then NAT Traversal shall be used IPSEC ESP traffic between
       
    67 *    the client and gateway
       
    68 *
       
    69 *    Nokia VPN specific NAT Traversal means that IPSEC ESP traffic shall be
       
    70 *    capsulated with UDP header.
       
    71 *    The used UDP port for that purpose is 9872
       
    72 *
       
    73 */
       
    74 
       
    75 #include "ikev1private.h"
       
    76 #include "ikev1dialog.h"
       
    77 #include "ikev1negotiation.h"
       
    78 #include "ikev1isakmpstream.h"
       
    79 
       
    80 #include "ikepolparser.h"
       
    81 
       
    82 const TUint8  BASE_VID_DATA[16] = {0x06, 0x3d, 0xf4, 0x13, 0x91, 0xa9, 0x19, 0xa2,
       
    83                                    0x5a, 0x61, 0xa8, 0x7c, 0x45, 0x02, 0x5f, 0xaf};
       
    84 
       
    85 const TUint8  DPD_VID_DATA[16]  = {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9,
       
    86                                    0x6B, 0x86, 0x96, 0xFC, 0x77, 0x57, 0x01, 0x00};
       
    87 
       
    88 TInt BuildVendorIdHash(TUint8 *aICOOKIE, TUint8 *aRCOOKIE, TUint8 *hash_data)
       
    89 {
       
    90 /*--------------------------------------------------------------------------------
       
    91  *
       
    92  *  Build Vendor Id hash data
       
    93  *
       
    94  *------------------------------------------------------------------------*/
       
    95 //
       
    96 // base = MD5("Network Alchemy, Inc., Version 1.0"); /* ASCII-Z end null included)
       
    97 //
       
    98 TInt i;
       
    99   
       
   100     Mem::Copy(hash_data, &BASE_VID_DATA[0], 16);  /* Hash base (MD5) */
       
   101     
       
   102     for ( i = 0; i < (ISAKMP_COOKIE_SIZE * 2); i++ ) {
       
   103 
       
   104         if ( i < ISAKMP_COOKIE_SIZE ) 
       
   105              *(hash_data + i) ^= *(aICOOKIE + i);
       
   106         else *(hash_data + i) ^= *(aRCOOKIE + (i - ISAKMP_COOKIE_SIZE));
       
   107 
       
   108     }
       
   109     
       
   110     return 16;
       
   111 }   
       
   112 
       
   113 
       
   114 TInt ConstructVendorId(TBool  aNATProbe,
       
   115                        TUint8 *aICOOKIE,
       
   116                        TUint8 *aRCOOKIE,
       
   117                        TInetAddr &aLocalAddr,
       
   118                        TVendorISAKMP *aVendorPayload)
       
   119 {
       
   120 /*------------------------------------------------------------------------
       
   121  *
       
   122  *  This method constructs a Vendor ID payload. If aNATProbe is TRUE
       
   123  *  an expanded format Vendor ID is constructed.
       
   124  *  Both Vendor ID formats contains a Nokia VPN vendor specific hash data
       
   125  *  which constructed as follows:
       
   126  *  base = MD5("Network Alchemy, Inc., Version 1.0");  ASCII-Z end null included)
       
   127  *  base = BASE_VID_DATA;
       
   128  *  Then the Vendor ID hash is consructed xor:ing ISAKMP cookies to hash as follows:
       
   129  *
       
   130  *  for ( i = 0; i < (ISAKMP_COOKIE_SIZE * 2); i++ ) {
       
   131  *      if ( i < ISAKMP_COOKIE_SIZE ) 
       
   132  *           base[i] ^= ICOOKIE[i];
       
   133  *      else base[i] ^= RCOOKIE[i - ISAKMP_COOKIE_SIZE];
       
   134  *  }
       
   135  *
       
   136  *  The expanded vendor ID payload looks like so:
       
   137  *
       
   138  *  General payload header   (next payload is "real" next payload)
       
   139  *    General payload header (next payload is "VENDOR_OPTION_NAT_TRAVERSAL")
       
   140  *      option hash
       
   141  *    General payload header (next payload is "VENDOR_OPTION_VERSION")
       
   142  *      option VENDOR_OPTION_NAT_TRAVERSAL
       
   143  *    General payload header (next payload is "NULL")
       
   144  *      option VENDOR_OPTION_VERSION
       
   145  *
       
   146  *  Expanded vendor id format is format is as follows:
       
   147  *
       
   148  *                      1                   2                   3
       
   149  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
   150  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   151  *  ! Next Payload  !   RESERVED    !         Payload Length = 44   !
       
   152  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   153  *  ! OPTION_NAT_T  !   RESERVED    !  Hash_lth + 4 = 20            !
       
   154  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   155  *  !                Nokia VPN Vendor specific hash                 !
       
   156  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   157  *  ! OPTION_VERSION!   RESERVED    !  OPTION_NAT_T_LTH + 4 = 20    !
       
   158  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   159  *  !    sin_lth    !   sin_family  !           sin_port            !
       
   160  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   161  *  !                        sin_addr                               !
       
   162  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   163  *  !                                                               !
       
   164  *  .                     Zero * 2(?)                               .
       
   165  *  !                                                               ! 
       
   166  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   167  *  !       0       !   RESERVED    !  OPTION_VERSION + 4 = 8       !
       
   168  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   169  *  !        MAJOR VERSION          !         MINOR VERSION         !
       
   170  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   171  *
       
   172  *  
       
   173  *------------------------------------------------------------------------*/
       
   174     TVendorISAKMP  *nat_vendor_id;
       
   175     TVendorISAKMP  *ver_vendor_id;       
       
   176     TNATTOption    *nat_t_option;
       
   177     TVersionOption *version_option; 
       
   178     TUint8         *next_payload;
       
   179     TUint32        vid_lth;
       
   180     TInetAddr      own_addr = aLocalAddr;
       
   181 
       
   182     next_payload  = (TUint8 *)aVendorPayload;   
       
   183     *next_payload = ISAKMP_PAYLOAD_NONE;   /* zeroe next payload field for sure */
       
   184     
       
   185     if ( aNATProbe ) {
       
   186        /*------------------------------------------------------------
       
   187         *
       
   188         *  Build expanded Vendor Id payload
       
   189         *  Build first VENDOR_OPTION_NAT_TRAVERSAL payload
       
   190         *
       
   191         *-----------------------------------------------------------*/
       
   192        nat_vendor_id = (TVendorISAKMP*)((TUint8*)aVendorPayload +
       
   193                                          sizeof(TPayloadISAKMP) +
       
   194                                          sizeof(TPayloadISAKMP) + 16); //bypass hash
       
   195        next_payload  = (TUint8 *)nat_vendor_id;
       
   196        *next_payload = VENDOR_OPTION_VERSION;
       
   197        nat_vendor_id->SetReserved(0);
       
   198        nat_vendor_id->SetLength(sizeof(TPayloadISAKMP) + SIN_LTH);
       
   199        nat_t_option = (TNATTOption*)nat_vendor_id->VIDData();
       
   200        nat_t_option->InitOption();
       
   201        nat_t_option->SetPort(500);
       
   202        if ( own_addr.IsV4Mapped() )
       
   203           own_addr.ConvertToV4();
       
   204        nat_t_option->SetAddress(own_addr.Address());
       
   205        /*------------------------------------------------------------
       
   206         *
       
   207         *  Build next VENDOR_OPTION_VERSION payload
       
   208         *  Set major version X and minor Y.
       
   209         *
       
   210         *-----------------------------------------------------------*/
       
   211        ver_vendor_id = (TVendorISAKMP*)((TUint8*)nat_vendor_id  +
       
   212                                          sizeof(TPayloadISAKMP) + SIN_LTH); //bypass NAT-T 
       
   213        next_payload  = (TUint8 *)ver_vendor_id;
       
   214        *next_payload = ISAKMP_PAYLOAD_NONE;
       
   215        ver_vendor_id->SetReserved(0);
       
   216        ver_vendor_id->SetLength(sizeof(TPayloadISAKMP) + VERSION_LTH);
       
   217        version_option = (TVersionOption*)ver_vendor_id->VIDData();
       
   218        version_option->SetVersion(MAJOR_VERSION, MINOR_VERSION);
       
   219        
       
   220        /*------------------------------------------------------------
       
   221         *
       
   222         *  Build "upper" Vendor Id payload general header
       
   223         *
       
   224         *-----------------------------------------------------------*/
       
   225        vid_lth = sizeof(TPayloadISAKMP) +      /* "outer" Vendor ID payload */
       
   226                  sizeof(TPayloadISAKMP) + 16 + /* VENDOR_OPTION_HASH */
       
   227                  sizeof(TPayloadISAKMP) + SIN_LTH +   /* VENDOR_OPTION_NAT_TRAVERSAL */
       
   228                  sizeof(TPayloadISAKMP) + VERSION_LTH;/* VENDOR_OPTION_VERSION */      
       
   229        aVendorPayload->SetLength((TUint16)vid_lth);         
       
   230        aVendorPayload->SetReserved(0);
       
   231 
       
   232        aVendorPayload = (TVendorISAKMP*)((TUint8*)aVendorPayload + sizeof(TPayloadISAKMP));
       
   233        next_payload   = (TUint8 *)aVendorPayload;
       
   234        *next_payload  = VENDOR_OPTION_NAT_TRAVERSAL;
       
   235     }
       
   236     else {
       
   237        vid_lth = sizeof(TPayloadISAKMP) + 16;
       
   238     }   
       
   239    /*------------------------------------------------------------
       
   240     *
       
   241     *  Store Hash data into Vendor Id payload
       
   242     *
       
   243     *-----------------------------------------------------------*/
       
   244     aVendorPayload->SetReserved(0);
       
   245     aVendorPayload->SetLength((TUint16)sizeof(TPayloadISAKMP) + 16);
       
   246     
       
   247     BuildVendorIdHash(aICOOKIE, aRCOOKIE,
       
   248                       aVendorPayload->VIDData());
       
   249 
       
   250     return vid_lth;
       
   251     
       
   252 }
       
   253 
       
   254 
       
   255 TBool ProcessVendorId(TBool  *aFamiliarPeer,
       
   256                       TUint8 *aICOOKIE,
       
   257                       TUint8 *aRCOOKIE,
       
   258                       TInetAddr &aLocalAddr,
       
   259                       TVendorISAKMP *aVendorPayload)
       
   260 {
       
   261 /*-------------------------------------------------------------------------
       
   262  *
       
   263  *  Process Vendor Id payload received from peer.
       
   264  *  The following actions taken:
       
   265  *  -- Check if a Nokia VPN implementation i peer (recognize hash in Vendor Id)
       
   266  *  -- If Nokia VPN implementation detected process possible
       
   267  *     VENDOR_OPTION_NAT_TRAVERSAL in expanded Vendor Id payload
       
   268  *
       
   269  *------------------------------------------------------------------------*/
       
   270     TBool         nokia_vpn_peer = EFalse;
       
   271     TBool         nat_t_required = EFalse;
       
   272     TVendorISAKMP *option_payload;
       
   273     TNATTOption   *nat_t_option;    
       
   274     TInt          vid_lth;
       
   275     TInt          tmp_lth;  
       
   276     TInt          hash_lth;
       
   277     TUint16       ptype;
       
   278     TUint16       detected_port;
       
   279     TUint8        ref_hash[20];
       
   280     TInetAddr     detected_addr;
       
   281     TInetAddr     reference_addr = aLocalAddr;
       
   282 
       
   283     vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP);
       
   284     if ( vid_lth > 15 ) {
       
   285        /*-------------------------------------------------------
       
   286         *
       
   287         * Check if expanded Vendor Id format
       
   288         *
       
   289         *-------------------------------------------------------*/
       
   290        tmp_lth  = vid_lth;  
       
   291        ptype    = ISAKMP_PAYLOAD_NONE;      
       
   292        hash_lth = BuildVendorIdHash(aICOOKIE, aRCOOKIE, ref_hash);
       
   293        option_payload = aVendorPayload;        
       
   294        if ( vid_lth > hash_lth ) {
       
   295           /*---------------------------------------------------------------------
       
   296            *
       
   297            * An expanded format Vendor Id, bypass "outer" payload general header
       
   298            * And do sanity check for VENDOR_OPTION_HASH option payload
       
   299            *
       
   300            *--------------------------------------------------------------------*/
       
   301           option_payload = (TVendorISAKMP*)((TUint8*)option_payload + sizeof(TPayloadISAKMP));
       
   302           ptype   = option_payload->GetPayload();                     
       
   303           tmp_lth = option_payload->GetLength();                  
       
   304           if ( tmp_lth == (sizeof(TPayloadISAKMP) + 16 ) ) 
       
   305 //            &&
       
   306 //           ( option_payload->GetReserved() == 0 ) ) {  //Must be always 0
       
   307                tmp_lth -= sizeof(TPayloadISAKMP);
       
   308           else tmp_lth  = 0;
       
   309        }
       
   310        
       
   311        if ( tmp_lth == hash_lth ) {
       
   312           /*---------------------------------------------
       
   313            *
       
   314            *  Check that Vendor Id hash match
       
   315            * 
       
   316            *---------------------------------------------*/
       
   317            if ( Mem::Compare(option_payload->VIDData(), tmp_lth, ref_hash, hash_lth) == 0 ) {
       
   318               /*-----------------------------------------------------------
       
   319                *
       
   320                * Process other Vendor Id option payload(s)
       
   321                * In this phase only VENDOR_OPTION_NAT_TRAVERSAL is processed
       
   322                * other options are ignored 
       
   323                *
       
   324                *-----------------------------------------------------------*/
       
   325               nokia_vpn_peer = ETrue;              
       
   326               tmp_lth       += sizeof(TPayloadISAKMP); 
       
   327               option_payload = (TVendorISAKMP*)((TUint8*)option_payload + tmp_lth);
       
   328               
       
   329               while ( ptype != ISAKMP_PAYLOAD_NONE ) {
       
   330                   
       
   331                   if ( vid_lth <= tmp_lth ) {
       
   332                      break; 
       
   333                   }
       
   334                   hash_lth = option_payload->GetLength();
       
   335                   tmp_lth += hash_lth;                
       
   336                   if ( ( hash_lth < (MIN_ISAKMP_PAYLOAD_SIZE + SIN_LTH) ) ) {
       
   337 //                     &&
       
   338 //                     ( option_payload->GetReserved() != 0 ) ) } //Must be always 0
       
   339                      break; 
       
   340                   }   
       
   341                   if ( ptype == VENDOR_OPTION_NAT_TRAVERSAL ) {
       
   342                      if ( reference_addr.IsV4Mapped() )
       
   343                         reference_addr.ConvertToV4();
       
   344                      hash_lth -= sizeof(TPayloadISAKMP);   /* option data length */
       
   345                      nat_t_option = (TNATTOption*)((TUint8*)option_payload + sizeof(TPayloadISAKMP));
       
   346                      detected_port = nat_t_option->GetPort();
       
   347                      detected_addr.SetAddress(nat_t_option->GetAddress());
       
   348                      if ( (detected_port != 500)         /* Port changed */
       
   349                           ||
       
   350                           !(detected_addr.Match(reference_addr))) { /* address changed */
       
   351                         nat_t_required = ETrue; 
       
   352                      }   
       
   353                      break; 
       
   354                   }
       
   355 
       
   356                   ptype          = option_payload->GetPayload();  //Next payload                  
       
   357                   option_payload = (TVendorISAKMP*)((TUint8*)option_payload + hash_lth);
       
   358 
       
   359               }   
       
   360            }       
       
   361        }
       
   362            
       
   363     }   
       
   364 
       
   365     if ( aFamiliarPeer )
       
   366        *aFamiliarPeer = nokia_vpn_peer;
       
   367 
       
   368     return nat_t_required;
       
   369         
       
   370 }
       
   371 
       
   372 /**-------------------------------------------------------------------
       
   373  *
       
   374  * Function BuildDPDVendorId()
       
   375  * This method builds a Dead Peer Detection (DPD) related Vendor ID
       
   376  * payload  and adds it into the IKE message. The vendor id is
       
   377  * specified  in the draft <draft-ietf-ipsec-dpd-04.txt> and its
       
   378  * content is the following:
       
   379  *                       1 
       
   380  * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
       
   381  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   382  * !                           !M!M!  
       
   383  * !      HASHED_VENDOR_ID     !J!N! 
       
   384  * !                           !R!R! 
       
   385  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   386  *
       
   387  * Hash data is, 
       
   388  * {0xAF, 0xCA, 0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, 0x6B, 0x86, 0x96,
       
   389  * 0xFC, 0x77, 0x57}, and MJR and MNR
       
   390  * MJR = 1 and MNR = 0 
       
   391  *
       
   392  *--------------------------------------------------------------------*/
       
   393 void BuildDPDVendorId(TIkev1IsakmpStream &aMsg)
       
   394 {
       
   395 	TInetAddr DummyAddr;
       
   396 
       
   397 	aMsg.IsakmpVendorId(IETF_NATT_VENDOR_ID,
       
   398 					    NULL, NULL, DummyAddr, // These parameters has no relevance with IETF_NATT_VID_DATA
       
   399 						(TUint8*)DPD_VID_DATA,
       
   400 						sizeof(DPD_VID_DATA));
       
   401 }
       
   402 
       
   403 TBool CheckDPDVendorId(const TVendorISAKMP *aVendorPayload)
       
   404 {
       
   405 /**---------------------------------------------------------------------------------------
       
   406  *
       
   407  *  This method checks does the remote end support DPD draft <draft-ietf-ipsec-dpd-04.txt>
       
   408  *  
       
   409  *---------------------------------------------------------------------------------------*/
       
   410 	TInt vid_lth = aVendorPayload->GetLength() - sizeof(TPayloadISAKMP);
       
   411 	if ( vid_lth == sizeof(DPD_VID_DATA) )
       
   412 	{
       
   413 		if ( Mem::Compare(aVendorPayload->VIDData(), vid_lth, (TUint8*)DPD_VID_DATA, vid_lth) == 0 ) 
       
   414 			return ETrue;  // Remote end supports DPD draft
       
   415 	}
       
   416 	return EFalse;
       
   417 }
       
   418 
       
   419 TInt CheckCredentials(CIkeData *aHostData )
       
   420 {
       
   421 /*-------------------------------------------------------------------------
       
   422  *
       
   423  *  This function is called by CNegotiation::InitNegotiationL() method
       
   424  *  when the current IKE proposal defines aggresssive mode exchange with
       
   425  *  pre-shared key authentication.
       
   426  *  The following special actions are taken:
       
   427  *  -- If no pre-shared key data is defined, launch a dialog where
       
   428  *     user name and password information is asked from the user.
       
   429  *  -- User name information is store to current CIkeData iFQDN field
       
   430  *     (represent IKE identification)
       
   431  *  -- Password data shall be stored to current CIkeData iPresharedKey field
       
   432  *
       
   433  *  This functionality is related to Checkpoint gateway.
       
   434  *  To use Aggressive mode exchange and pre-shared key authentication like
       
   435  *  this implement kind of "legacy authentication method" for IKE where
       
   436  *  client (=initiator) authentication is based on user name/password pair.
       
   437  *  User name is sent from initiator (=client) to responder (=Checkpoint GW)
       
   438  *  in the IKE ID payload. However, the password data is NOT transmitted in
       
   439  *  any payload, but it is used as pre-shared key in both ends.
       
   440  *  (= Checkpoint gateway shall use user name data received in IKE ID payload
       
   441  *     as a reference to the correct pre-shared key)
       
   442  *
       
   443  *------------------------------------------------------------------------*/
       
   444     if ( !aHostData || aHostData->iPresharedKey.iKey.Length() )
       
   445        return KErrNone;
       
   446     
       
   447     aHostData->iPresharedKey.iFormat = STRING_KEY;
       
   448     aHostData->iFQDN.SetLength(0); // Override FQDN in host data with user name
       
   449     
       
   450     return CIkev1Dialog::GetSyncUNPWDialog(aHostData->iFQDN, aHostData->iPresharedKey.iKey);
       
   451 }
       
   452 
       
   453 
       
   454 CInternalAddress* ProcessIntNetL(TINTNETISAKMP *aIntNetpayload)
       
   455 {
       
   456 /*-------------------------------------------------------------------------
       
   457  *
       
   458  *  Process Internal address payload received (sanity check already done)
       
   459  *  Process payload attributes as follows:
       
   460  *  -- Parse PRI_INTERNAL_ADDRESS attribute and store value to aInternalAddr
       
   461  *  -- Parse PRI_INTERNAL_DNS attributes and build list of DNS addresses
       
   462  *     There exists an own attribute for all DNS addresses
       
   463  *  -- Ignore other attributes (=PRI_INTERNAL_WINS)
       
   464  *
       
   465  *  In this phase only IPv4 Internal addresses are supported by the
       
   466  *  Nokia VPN gateway
       
   467  *
       
   468  *------------------------------------------------------------------------*/
       
   469     TInt length = (TInt)aIntNetpayload->GetLength();
       
   470     if ( STATIC_CAST(TUint, length) < sizeof(TINTNETISAKMP) ) {
       
   471        return NULL;
       
   472     }
       
   473     
       
   474     length -= sizeof(TINTNETISAKMP);  /* Attribute data lengt in payload */
       
   475 
       
   476     TUint32   ipv4_addr;
       
   477     TBool     internal_address = EFalse;
       
   478     TInetAddr *dns_addr;
       
   479     CInternalAddress *InternalAddr = new (ELeave)CInternalAddress(1);
       
   480     CleanupStack::PushL(InternalAddr);    
       
   481     TDataISAKMP *attr  = aIntNetpayload->INTNETAttrib();
       
   482     
       
   483     while ( length > 0 ) {
       
   484         
       
   485         length = length - attr->Size();
       
   486         if ( length < 0 ) {
       
   487            CleanupStack::PopAndDestroy();  /* delete InternalAddr */
       
   488            return NULL;
       
   489         }
       
   490         switch ( attr->Type() ) {
       
   491 
       
   492            case PRI_INTERNAL_ADDRESS:
       
   493                 /*-----------------------------------------------------------
       
   494                  * Internal address received from gateway. If several
       
   495                  * Internal address attributes detected use the first address
       
   496                  *------------------------------------------------------------*/
       
   497                 if ( attr->IsBasic() || ( attr->Length() != 4) ) {
       
   498                    CleanupStack::PopAndDestroy();  /* delete InternalAddr */                    
       
   499                    return NULL;
       
   500                 }
       
   501                 if ( !internal_address ) {
       
   502                    internal_address = ETrue;                    
       
   503                    ipv4_addr = GET32(attr->VarValue()); 
       
   504                    ipv4_addr = ByteOrder::Swap32(ipv4_addr); //NOT IN NETWORK ORDER !!!!                   
       
   505                    InternalAddr->iClientIntAddr.SetAddress(ipv4_addr);
       
   506                 }   
       
   507                 break;
       
   508             
       
   509            case PRI_INTERNAL_DNS:
       
   510                 /*-----------------------------------------------------------
       
   511                  * Internal DNS address received from gateway 
       
   512                  *------------------------------------------------------------*/
       
   513                 if ( attr->IsBasic() || ( attr->Length() != 4 ) ) {
       
   514                    CleanupStack::PopAndDestroy();  /* delete InternalAddr */
       
   515                    return NULL;
       
   516                 }
       
   517                 ipv4_addr = GET32(attr->VarValue()); 
       
   518                 ipv4_addr = ByteOrder::Swap32(ipv4_addr); //NOT IN NETWORK ORDER !!!!
       
   519                 dns_addr   = new(ELeave)TInetAddr;
       
   520                 CleanupStack::PushL(dns_addr);                  
       
   521                 dns_addr->SetAddress(ipv4_addr);
       
   522                 InternalAddr->AppendL(dns_addr);
       
   523                 CleanupStack::Pop();  /* delete dns_addr */               
       
   524                 break;
       
   525         
       
   526            default:
       
   527                 /*-----------------------------------------------------------
       
   528                  * Other attributes (WINS address) are ignored
       
   529                  *------------------------------------------------------------*/
       
   530                 break; 
       
   531         }
       
   532         
       
   533         attr = attr->Next();
       
   534     }
       
   535 
       
   536     if ( !internal_address ) {
       
   537        /*-----------------------------------------------------
       
   538         * No client internal address defined.
       
   539         * Internal address negotiation failed
       
   540         *----------------------------------------------------*/
       
   541        delete InternalAddr;
       
   542        InternalAddr = NULL;
       
   543     }
       
   544     
       
   545     CleanupStack::Pop();  // Remove InternalAddr from cleanup stack
       
   546     
       
   547     return InternalAddr;
       
   548 }
       
   549 
       
   550