591 lines
18 KiB
C
591 lines
18 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* 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 <joel.hortelis@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipmip4_config.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_hash.h>
|
|
#include <ipcom_inet.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_sock2.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_sysvar.h>
|
|
|
|
#include <ipmip.h>
|
|
|
|
#include "ipmip4_h.h"
|
|
#include <private/ipmip4_sysext.h>
|
|
#include <private/ipmip4_util.h>
|
|
#include <private/ipmip4_auth.h>
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 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
|
|
****************************************************************************
|
|
*/
|