/* ****************************************************************************** * 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 ****************************************************************************** */ /* **************************************************************************** * 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 #include /* **************************************************************************** * 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 **************************************************************************** */