/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip4_sysext.c,v $ $Revision: 1.19 $ * $Source: /home/interpeak/CVSRoot/ipmip4/src/ipmip4_sysext.c,v $ * $Author: jhorteli $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip4_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include "ipmip4_h.h" #include #include #include /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ Ipmip_sysvar_key_map_t ipmip4_sysext_spi_method[] = { { IPMIP4_AUTH_METHOD_MD5_HMAC, "md5-hmac" }, { IPMIP4_AUTH_METHOD_MD5_HMAC, "hmac-md5" }, { IPMIP4_AUTH_METHOD_MD5_HMAC, "md5" }, { IPMIP4_AUTH_METHOD_CHAP, "chap" }, { IPMIP4_AUTH_METHOD_KEYGEN, "keygen" }, { 0, 0 } }; /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* *=========================================================================== * ipmip4_sysext_nvse_alloc *=========================================================================== * Description: Create an NVSE extension based on vendor, subtype and data * Parameters: vendor - Vendor ID * subtype - Vendor NVSE subtype * value - The vendor value * size - The size of value * Returns: * */ IP_GLOBAL Ipmip4_msgext_uhdr_t * ipmip4_sysext_nvse_alloc(Ip_u32 vendor, Ip_u16 subtype, void *data, Ip_size_t size) { Ip_u8 *vse = ipcom_calloc(1, 10 + size); if (vse) { vse[0] = IPMIP4_EXT_TYPE_NVSE; vse[1] = (Ip_u8) (10 + size - 2); IP_SET_HTONL(&vse[4], vendor); IP_SET_HTONS(&vse[8], subtype); ipcom_memcpy(&vse[10], data, size); } return (Ipmip4_msgext_uhdr_t *) vse; } /* *=========================================================================== * ipmip4_sysext_cvse_alloc *=========================================================================== * Description: Create an CVSE extension based on vendor, subtype and data * Parameters: vendor - Vendor ID * subtype - Vendor CVSE subtype * value - The vendor value * size - The size of value * Returns: * */ IP_GLOBAL Ipmip4_msgext_uhdr_t * ipmip4_sysext_cvse_alloc(Ip_u32 vendor, Ip_u16 subtype, void *data, Ip_size_t size) { Ip_u8 *vse = ipcom_calloc(1, 10 + size); if (vse) { vse[0] = IPMIP4_EXT_TYPE_CVSE; IP_SET_HTONS(&vse[2], (10 + size - 4)); IP_SET_HTONL(&vse[4], vendor); IP_SET_HTONS(&vse[8], subtype); ipcom_memcpy(&vse[10], data, size); } return (Ipmip4_msgext_uhdr_t *) vse; } /* *=========================================================================== * ipmip4_sysext_spi_parse *=========================================================================== * Description: * Parameters: * Returns: * */ IP_GLOBAL Ipmip4_auth_spi_t * ipmip4_sysext_spi_parse(struct Ipmip_proc *proc, Ip_u32 defspi, Ip_u32 spival, const char *secret, const char *delim, const char *format, ...) { va_list ap; char *spec; va_start(ap, format); spec = ipmip_util_vstrdup(format, ap); va_end(ap); if (spec) { Ipmip4_auth_spi_t *spi; char *vsecret = (char *)secret; int method; if (spival == 0) spival = ipmip_sysvar_ulong(defspi, "%s%sspi", spec, delim); if (spival == 0) { ipcom_free(spec); return IP_NULL; } /**/ method = ipmip_sysvar_key(spival == IPMIP4_AUTH_SPI_CHAP_SPI? IPMIP4_AUTH_METHOD_CHAP : IPMIP4_AUTH_METHOD_MD5_HMAC, ipmip4_sysext_spi_method, "%s%smethod", spec, delim); /* Try read the secret */ if (vsecret == IP_NULL) { vsecret = ipmip_sysvar("%s%ssecret", spec, delim); if (vsecret == IP_NULL) vsecret = ipmip_sysvar(spec); } if (vsecret == IP_NULL) { ipcom_free(spec); return IP_NULL; } /* Create the SPI */ spi = ipmip4_auth_spi_create(proc, spival, vsecret, ipcom_strlen(vsecret), method); /* Free memory */ ipcom_free(spec); if (vsecret != IP_NULL && vsecret != secret) ipcom_free(vsecret); return spi; } return IP_NULL; } /*=========================================================================== * ipmip4_sysext_foreach_spi *=========================================================================== * Description: Parse the configured SPI's * Parameters: proc - Current process * name - Name of the sysvar key * subkey - The matched subkey * value - The SPI value * spictx - The spi context * Returns: * */ IP_GLOBAL void ipmip4_sysext_foreach_spi(struct Ipmip_proc *proc, char *name, char *subkey, const char *value, Ipmip4_auth_context_t *spictx) { /* Dont care about subkeys */ char *dot; IPMIP_UNUSED_PARAMETER(name); IPMIP_UNUSED_PARAMETER(proc); if ((dot = ipcom_strchr(subkey, '.')) == IP_NULL || ipcom_strcasecmp(dot, ".secret") == 0) { Ip_u32 spival = ipcom_strtoul(subkey, IP_NULL, 10); Ipmip4_auth_spi_t *spi; if (spival < 256) return; /**/ spi = ipmip4_sysext_spi_parse(proc, 0, spival, value, ".", dot? ipmip_ntop_strn(proc, name, dot - name) : name); if (spi) ipmip4_auth_spi_add(spictx, spi); } } /*=========================================================================== * ipmip4_sysext_foreach_spiroute *=========================================================================== * Description: Parse the configured SPI lookup definitions * Parameters: proc - Current process * name - Name of the sysvar key * subkey - The matched subkey * value - The SPI value * rtab - The route table * Returns: * */ IP_GLOBAL void ipmip4_sysext_foreach_spiroute(struct Ipmip_proc *proc, char *name, char *subkey, const char *value, Ipmip4_auth_spi_table_t *rtab) { Ip_u32 addr; Ip_u32 plen; IPMIP_UNUSED_PARAMETER(name); /* Dont care about subkeys */ if (ipcom_strcasecmp(subkey, "any") == 0) { /* Wildcard match */ addr = 0; plen = 0; } else { if (ipmip_util_inet(subkey, &addr, &plen) == IP_FALSE) { IPCOM_LOG1(ERR, "SPI key '%s' is not a valid address", subkey); return; } } IPCOM_LOG3(DEBUG2, "Route SPI lookup %s/%d for SPI %s", ipmip_ntop_inet(proc, addr), plen, subkey); /* Add the SPI route */ ipmip4_auth_spi_table_add(rtab, addr, plen, ipcom_strtoul(value, IP_NULL, 10)); } /*=========================================================================== * ipmip4_sysext_foreach_spiroute *=========================================================================== * Description: Parse the configured SPI lookup definitions * Parameters: proc - Current process * name - Name of the sysvar key * subkey - The matched subkey * value - The SPI value * htable - The spi hash table * Returns: * */ IP_GLOBAL void ipmip4_sysext_foreach_spihash(struct Ipmip_proc *proc, char *name, char *subkey, const char *value, Ipmip4_auth_spi_hash_t *htable) { IPMIP_UNUSED_PARAMETER(proc); IPMIP_UNUSED_PARAMETER(name); /* Add the SPI route */ IPCOM_LOG3(DEBUG2, "NAI SPI lookup %s (%d) for SPI %d", subkey, ipcom_strlen(subkey), ipcom_strtoul(value, IP_NULL, 10)); if (!ipmip4_auth_spi_hash_add(htable, subkey, ipcom_strlen(subkey), ipcom_strtoul(value, IP_NULL, 10))) { IPCOM_LOG2(WARNING, "FAILED: NAI SPI lookup %s for SPI %d", subkey, ipcom_strtoul(value, IP_NULL, 10)); } } /* *=========================================================================== * ipmip4_sysext_nai_aaah *=========================================================================== * Description: Parse and create a NAI AAAH from a sysvar * Parameters: format - The sysvar format key. * ... - Optional arguments * Returns: * */ IP_GLOBAL Ipmip4_msgext_shdr_t * ipmip4_sysext_nai_aaah(const char *format, /* args */ ...) { va_list ap; char *nai; Ipmip4_msgext_shdr_t *aaah_nai = IP_NULL; va_start(ap, format); nai = ipmip_vsysvar(format, ap); va_end(ap); if (nai != IP_NULL) { aaah_nai = ipmip4_sysext_nai_aaah_create((Ip_u8 *)nai, ipcom_strlen(nai)); ipcom_free(nai); } return aaah_nai; } /* *=========================================================================== * ipmip4_sysext_nai_ha *=========================================================================== * Description: Parse and create a NAI HA from a sysvar * Parameters: format - The sysvar format key. * ... - Optional arguments * Returns: * */ IP_GLOBAL Ipmip4_msgext_shdr_t * ipmip4_sysext_nai_ha(const char *format, /* args */ ...) { va_list ap; char *nai; Ipmip4_msgext_shdr_t *ha_nai = IP_NULL; va_start(ap, format); nai = ipmip_vsysvar(format, ap); va_end(ap); if (nai != IP_NULL) { Ip_size_t nai_len = ipcom_strlen(nai); if (nai_len >= 3) { Ip_u8 *nai_ext = ipcom_calloc(1, nai_len + 3); /* */ if (nai_ext != IP_NULL) { nai_ext[0] = IPMIP4_EXT_TYPE_NAI_AGENT; nai_ext[1] = (Ip_u8) (nai_len + 1); nai_ext[2] = IPMIP4_NAI_SUBTYPE_HA; ipcom_strncpy((char *)&nai_ext[3], nai, nai_len); /* Store the NAI */ ha_nai = (void*) nai_ext; } } else if (nai_len) { IPCOM_LOG0(WARNING, "Too short HA NAI. Syntax is hostname@domain"); } ipcom_free(nai); } return ha_nai; } /* *=========================================================================== * ipmip4_sysext_nai_mn *=========================================================================== * Description: Parse and create a NAI MN from a sysvar * Parameters: format - The sysvar format key. * ... - Optional arguments * Returns: * */ IP_GLOBAL Ipmip4_msgext_shdr_t * ipmip4_sysext_nai_mn(const char *format, /* args */ ...) { va_list ap; char *nai; Ipmip4_msgext_shdr_t *mn_nai = IP_NULL; va_start(ap, format); nai = ipmip_vsysvar(format, ap); va_end(ap); if (nai) mn_nai = ipmip4_msgext_nai_mn(IP_NULL, nai, ipcom_strlen(nai)); if (nai != IP_NULL) ipcom_free(nai); return mn_nai; } /* *=========================================================================== * ipmip4_sysext_tunnel_type *=========================================================================== * Description: Interpret a tunnel protocol to its tunnel type index * Parameters: deftype - Default type index * format - The sysvar format string * ... - The optional arguments * Returns: -1 on error, deftype on none, tunnel type index otherwise * */ IP_GLOBAL int ipmip4_sysext_tunnel_type(int deftype, const char *format, /* args */ ...) { va_list ap; char *proto; static Ipmip_sysvar_key_map_t ttypes[] = { { IPMIP_TUNNELTYPE_IPIP, "ipip" }, { IPMIP_TUNNELTYPE_GRE, "gre" }, { IPMIP_TUNNELTYPE_MINENC, "min" }, { IPMIP_TUNNELTYPE_IP6IP6, "ip6ip6" }, { IPMIP_TUNNELTYPE_GRE6, "gre6" }, { 0, 0 } }; va_start(ap, format); proto = ipmip_vsysvar(format, ap); va_end(ap); if (proto != IP_NULL) { deftype = ipmip_sysvar_cmd_str_to_key(ttypes, proto); if (deftype == -1) { IPCOM_LOG1(ERR, "invalid tunnel type configuration (%s)", proto); } ipcom_free(proto); } return deftype; } /* *=========================================================================== * ipmip4_sysext_nai_aaah_create *=========================================================================== * Description: Create a AAAH nai based on provided data * Parameters: data - The data * data_length - The length of data * Returns: The AAAH Nai. * */ IP_GLOBAL Ipmip4_msgext_shdr_t * ipmip4_sysext_nai_aaah_create(Ip_u8 *data, Ip_size_t data_length) { Ipmip4_msgext_shdr_t *aaah_nai = IP_NULL; if (data != IP_NULL) { if (data_length >= 3) { Ip_u8 *nai_ext = ipcom_calloc(1, data_length + 4); /* */ if (nai_ext != IP_NULL) { nai_ext[0] = IPMIP4_EXT_TYPE_NAI_AGENT; nai_ext[1] = (Ip_u8) (data_length + 1); nai_ext[2] = IPMIP4_NAI_SUBTYPE_AAAH; ipcom_memcpy((char *)&nai_ext[3], data, data_length); /* Store the NAI */ aaah_nai = (void*) nai_ext; } } else if (data_length) { IPCOM_LOG0(WARNING, "Too short AAAH NAI. Syntax is hostname@domain"); } } return aaah_nai; } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * END OF FILE **************************************************************************** */