350 lines
12 KiB
C
350 lines
12 KiB
C
/*
|
|
******************************************************************************
|
|
* SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipike_payload_delete.c,v $ $Revision: 1.30.16.3 $
|
|
* $Source: /home/interpeak/CVSRoot/ipike/src/ipike_payload_delete.c,v $
|
|
* $Author: zan $ $Date: 2013-06-18 11:20:06 $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/* Delete payload (RFC 2408, chapter 3.15) */
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipike_h.h"
|
|
#include "ipike_config.h"
|
|
#include "ipike_exchange_informational.h"
|
|
#include "ipike_payload_delete.h"
|
|
#include "ipike_payload_proposal.h"
|
|
#include "ipike_doi.h"
|
|
#include "ipike_util.h"
|
|
#include "ipike_ipsec_sadb.h"
|
|
#include "ipike_pfkeyv2.h"
|
|
#include "ipike_sadb.h"
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_syslog.h>
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_spi_data
|
|
*===========================================================================
|
|
* Description: Returns a pointer to the first SPI in the payload.
|
|
* Parameters: del - A delete payload.
|
|
* Returns: A pointer to the SPI data.
|
|
*
|
|
*/
|
|
IP_STATIC Ip_u8*
|
|
ipike_payload_delete_spi_data(Ipike_delete_payload* del);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_ike_sa
|
|
*===========================================================================
|
|
* Description: Marks all IKE SA that was in the message for deletion.
|
|
* Parameters: del - A delete payload.
|
|
* Returns: IPIKE_SUCCESS
|
|
*
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_payload_delete_ike_sa(Ipike_delete_payload* del);
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_ipsec_sa
|
|
*===========================================================================
|
|
* Description: Deletes all IPSec SAs that was in the message.
|
|
* Parameters: del - A delete payload.
|
|
* Returns: IPIKE_SUCCESS
|
|
*
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_payload_delete_ipsec_sa(
|
|
Ipike_sadb_entry* ike_sa,
|
|
Ipike_delete_payload* del);
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 LOCAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_spi_data
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ip_u8 *
|
|
ipike_payload_delete_spi_data(Ipike_delete_payload *del)
|
|
{
|
|
return (Ip_u8 *) del + IPIKE_DELETE_HEADER_LENGTH;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_ike_sa
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_payload_delete_ike_sa(Ipike_delete_payload *del)
|
|
{
|
|
Ipike_sadb_entry* ike_sa;
|
|
Ip_u8* initiator_cookie;
|
|
Ip_u8* responder_cookie;
|
|
int i;
|
|
|
|
if (del->spi_size % IPIKE_ISAKMP_COOKIE_SIZE * 2 != 0)
|
|
return IPIKE_INVALID_VALUE;
|
|
|
|
for (i = 0; i < ip_ntohs(del->spi_count); i++)
|
|
{
|
|
initiator_cookie = ipike_payload_delete_spi_data(del) + i * IPIKE_ISAKMP_COOKIE_SIZE * 2;
|
|
responder_cookie = initiator_cookie + IPIKE_ISAKMP_COOKIE_SIZE;
|
|
if (IPIKE_SUCCESS == ipike_sadb_get(initiator_cookie,
|
|
responder_cookie,
|
|
IPIKE_SA_ACTIVE,
|
|
&ike_sa))
|
|
{
|
|
(void)ipike_sadb_set_state(IP_NULL, ike_sa, IPIKE_SA_DYING);
|
|
ipike_sadb_release(ike_sa);
|
|
}
|
|
}
|
|
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_ipsec_sa
|
|
*===========================================================================
|
|
*/
|
|
IP_STATIC Ipike_error
|
|
ipike_payload_delete_ipsec_sa(
|
|
Ipike_sadb_entry* ike_sa,
|
|
Ipike_delete_payload* del)
|
|
{
|
|
Ipike_ipsec_sadb_entry* ipsec_sa, *nested_sa = IP_NULL;
|
|
Ip_u8* spi;
|
|
int i;
|
|
Ipike_value v;
|
|
|
|
if (ip_ntohs(del->spi_count) * 4 % del->spi_size != 0)
|
|
return IPIKE_INVALID_VALUE;
|
|
|
|
/* We should only receive delete on the peers inbound traffic. */
|
|
for (i = 0; i < ip_ntohs(del->spi_count); i++)
|
|
{
|
|
spi = ipike_payload_delete_spi_data(del) + i * 4;
|
|
if (IPIKE_SUCCESS == ipike_ipsec_sadb_hash_get(spi,
|
|
del->proto_id,
|
|
&ike_sa->peer_addr,
|
|
&ike_sa->local_addr,
|
|
&ipsec_sa))
|
|
{
|
|
if (ipsec_sa->nested != IP_NULL)
|
|
{
|
|
nested_sa = ipsec_sa->nested;
|
|
}
|
|
|
|
/* Report delete from our side. */
|
|
if (ipsec_sa->other != IP_NULL)
|
|
{
|
|
v.value = ipsec_sa->other->spi;
|
|
v.len = sizeof(ipsec_sa->other->spi);
|
|
ipike_informational_report_sa_delete(ike_sa, del->proto_id, &v);
|
|
ipike_ipsec_sadb_delete_sa(ipsec_sa->other);
|
|
}
|
|
|
|
/* Recheck if outbound SA delete caused a pfkeyv2 response
|
|
which invalidated the inbound SA.(for example triggered
|
|
by a keyadm flush */
|
|
if (IPIKE_SUCCESS == ipike_ipsec_sadb_hash_get(spi,
|
|
del->proto_id,
|
|
&ike_sa->peer_addr,
|
|
&ike_sa->local_addr,
|
|
&ipsec_sa))
|
|
{
|
|
ipike_ipsec_sadb_delete_sa(ipsec_sa);
|
|
/* remove any grouped SA's */
|
|
if(nested_sa != IP_NULL)
|
|
{
|
|
/* Delete internally! No report Vista style */
|
|
IPCOM_LOG0(DEBUG2,"ipike_payload_delete_ipsec_sa: Deleting grouped IPSEC SA");
|
|
ipike_ipsec_sadb_delete_sa(nested_sa->other);
|
|
ipike_ipsec_sadb_delete_sa(nested_sa);
|
|
nested_sa = IP_NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_new
|
|
*===========================================================================
|
|
*/
|
|
IP_GLOBAL Ipike_delete_payload*
|
|
ipike_payload_delete_new(
|
|
Ip_u32 doi,
|
|
Ip_u8 proto_id,
|
|
Ip_u8 spi_size,
|
|
Ip_u8* spi_data)
|
|
{
|
|
Ipike_delete_payload *ret;
|
|
|
|
ret = ipcom_calloc(1, IPIKE_DELETE_HEADER_LENGTH + spi_size);
|
|
if (IP_NULL == ret)
|
|
return IP_NULL;
|
|
|
|
ret->header.length = ip_htons(IPIKE_DELETE_HEADER_LENGTH + spi_size);
|
|
ret->header.next_payload = IPIKE_PAYLOAD_DELETE;
|
|
ret->doi = ip_htonl(doi);
|
|
ret->proto_id = proto_id;
|
|
ret->spi_size = spi_size;
|
|
ret->spi_count = ip_htons(1);
|
|
ipcom_memcpy(ipike_payload_delete_spi_data(ret), spi_data, ret->spi_size);
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_check
|
|
*===========================================================================
|
|
*/
|
|
IP_GLOBAL Ipike_error
|
|
ipike_payload_delete_check(Ipike_delete_payload* del)
|
|
{
|
|
if (ip_ntohs(del->header.length) != IPIKE_DELETE_HEADER_LENGTH +
|
|
(Ip_u32) ip_ntohs(del->spi_count) * (Ip_u32) del->spi_size)
|
|
return IPIKE_ISAKMP_PAYLOAD_LENGTH_ERROR;
|
|
if (del->spi_size == 0)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipike_payload_delete_check_payload: SPI size is 0");
|
|
return IPIKE_INVALID_VALUE;
|
|
}
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_process_message
|
|
*===========================================================================
|
|
*/
|
|
IP_GLOBAL Ipike_error
|
|
ipike_payload_delete_process_message(
|
|
Ipike_sadb_entry* ike_sa,
|
|
Ipike_delete_payload* payload)
|
|
{
|
|
if (ip_ntohl(payload->doi) != IPIKE_DOI_IPSEC)
|
|
return IPIKE_DOI_UNSUPPORTED;
|
|
/*RFC2408 5.15
|
|
Deletion of Security Associations MUST always be performed under the protection of an ISAKMP SA.*/
|
|
if(ike_sa->state != IPIKE_SA_ACTIVE)
|
|
{
|
|
return IPIKE_FAILED;
|
|
}
|
|
if (payload->proto_id == IPIKE_PROTO_ISAKMP)
|
|
return ipike_payload_delete_ike_sa(payload);
|
|
else if(payload->proto_id == IPIKE_PROTO_IPSEC_AH || payload->proto_id == IPIKE_PROTO_IPSEC_ESP)
|
|
return ipike_payload_delete_ipsec_sa(ike_sa, payload);
|
|
|
|
return IPIKE_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipike_payload_delete_print
|
|
*===========================================================================
|
|
*/
|
|
IP_GLOBAL void
|
|
ipike_payload_delete_print(Ipike_delete_payload* del)
|
|
{
|
|
int i;
|
|
|
|
IPCOM_LOG1(DEBUG2, " DOI: %s",
|
|
ipike_doi_to_string(ip_ntohl(del->doi)));
|
|
IPCOM_LOG1(DEBUG2, " protocol ID: %s",
|
|
ipike_proposal_proto_id_to_string(del->proto_id));
|
|
|
|
for (i = 0; i < ip_ntohs(del->spi_count); i++)
|
|
{
|
|
char* spi_hex;
|
|
spi_hex = ipike_memory_to_string(ipike_payload_delete_spi_data(del) + i * del->spi_size,
|
|
del->spi_size, 4);
|
|
if (IP_NULL == spi_hex)
|
|
{
|
|
IPCOM_LOG0(CRIT, "ipike_payload_delete_print_payload: out of memory");
|
|
return;
|
|
}
|
|
IPCOM_LOG2(DEBUG2, " SPI %d: %s",
|
|
i + 1,
|
|
spi_hex);
|
|
ipcom_free(spi_hex);
|
|
}
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|