Files
m241Neelima/components/ip_net2-6.9/ipike/src/ipike_configuration_file.c
T
2026-07-30 11:19:44 +05:30

2235 lines
80 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipike_configuration_file.c,v $ $Revision: 1.23.10.10 $
* $Source: /home/interpeak/CVSRoot/ipike/src/ipike_configuration_file.c,v $
* $Author: jsheng $ $Date: 2013-04-28 08:58:41 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Kenneth Jonsson <kenneth@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipike_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipike_h.h"
#include "ipike_configuration.h"
#include "ipike_configuration_api.h"
#include "ipike_configuration_file.h"
#include "ipike_configuration_parse.h"
#include "ipike_crypto.h"
#include "ipike_util.h"
#include <ipcom_clib.h>
#include <ipcom_syslog.h>
#include <ipcom_hash.h>
/*
****************************************************************************
* 4 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 5 DEFINES
****************************************************************************
*/
#define INVALID_LEN (Ip_size_t)(-1)
#define IPIKE_SA_LIFE_TIME_DEFAULT "8 hours"
/*
****************************************************************************
* 6 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 LOCAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipike_config_parse_proposal
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_proposal(
Ipike_config* config,
Ipike_config_api_proposal*** proposals)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
Ipike_config_api_proposal* proposal = IP_NULL;
if (IP_NULL == (proposal = ipcom_calloc(1, sizeof(*proposal))))
{
IP_PANIC();
err = IPIKE_OUT_OF_MEMORY;
}
while ((IPIKE_SUCCESS == err) &&
(entry = ipike_configuration_enum(config, entry)))
{
if (ipcom_strcasecmp(entry->name, "dh_group") == 0)
{
err = ipike_parse_string(entry->value, &proposal->dh_group);
}
else if (ipcom_strcasecmp(entry->name, "hash_algorithm") == 0)
{
err = ipike_parse_string(entry->value, &proposal->hash_alg);
}
else if (ipcom_strcasecmp(entry->name, "encryption_algorithm") == 0)
{
err = ipike_parse_string(entry->value, &proposal->encryption_alg);
}
else if (ipcom_strcasecmp(entry->name, "integrity_algorithm") == 0)
{
err = ipike_parse_string(entry->value, &proposal->integrity_alg);
}
else if (ipcom_strcasecmp(entry->name, "use_esn") == 0)
{
err = ipike_parse_string(entry->value, &proposal->use_esn);
}
else if (ipcom_strcasecmp(entry->name, "v1_lifetime") == 0)
{
err = ipike_parse_string(entry->value, &proposal->v1.lifetime);
}
else if (ipcom_strcasecmp(entry->name, "number") == 0)
{
err = ipike_parse_string(entry->value, &proposal->number);
}
else
{
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...", entry->name, config->name);
}
if (IPIKE_CONF_INVALID_VALUE == err)
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'", entry->value, entry->name, config->name);
}
if (IPIKE_SUCCESS == err)
{
ipike_to_lower_string((char*)proposal->dh_group);
ipike_to_lower_string((char*)proposal->hash_alg);
ipike_to_lower_string((char*)proposal->encryption_alg);
ipike_to_lower_string((char*)proposal->integrity_alg);
ipike_to_lower_string((char*)proposal->use_esn);
err = ipike_array_add((void***)proposals, proposal);
}
if (IPIKE_SUCCESS != err)
ipcom_free(proposal);
return err;
}
/*
*===========================================================================
* ipike_config_free_proposal
*===========================================================================
*/
IP_STATIC void
ipike_config_free_proposal(Ipike_config_api_proposal* proposal)
{
ipike_config_api_release_proposal(proposal);
ipcom_free(proposal);
}
/*
*===========================================================================
* ipike_config_free_proposals
*===========================================================================
*/
IP_STATIC void
ipike_config_free_proposals(Ipike_config_api_proposal*** proposals)
{
ipike_array_free((void**)*proposals, (void(*)(void*))ipike_config_free_proposal);
*proposals = IP_NULL;
}
/*
*===========================================================================
* ipike_config_free_rohc
*===========================================================================
*/
IP_STATIC void
ipike_config_free_rohc(Ipike_config_api_rohc ** rohc)
{
ip_assert(rohc != IP_NULL);
if ( *rohc == IP_NULL )
return;
ipike_parse_delete_string((*rohc)->max_cid);
ipike_parse_delete_string((*rohc)->mrru);
ipike_parse_delete_string((*rohc)->profiles);
ipike_parse_delete_string((*rohc)->icv_len);
ipike_parse_delete_string((*rohc)->integrity_alg);
ipcom_free(*rohc);
*rohc = IP_NULL;
}
/*
*===========================================================================
* ipike_config_parse_authentication
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_authentication(
Ipike_config* config,
Ipike_config_api_ike_sa* ike_sa)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
while ((IPIKE_SUCCESS == err) &&
(entry = ipike_configuration_enum(config, entry)))
{
if (ipcom_strcasecmp(entry->name, "method") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.method);
}
else if (ipcom_strcasecmp(entry->name, "psk_id") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.psk_id);
}
else if (ipcom_strcasecmp(entry->name, "shared_key") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.shared_key);
}
else if (ipcom_strcasecmp(entry->name, "certificate") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.certificate);
}
else if (ipcom_strcasecmp(entry->name, "send_certificate") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.send_certificate);
}
else if (ipcom_strcasecmp(entry->name, "request_certificate") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.request_certificate);
}
else if (ipcom_strcasecmp(entry->name, "ocsp_response") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.ocsp_response);
}
else if (ipcom_strcasecmp(entry->name, "remote_certificate") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.remote_certificate);
}
else if (ipcom_strcasecmp(entry->name, "key_id") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.key_id);
}
else if (ipcom_strcasecmp(entry->name, "private_key") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.private_key);
}
else if (ipcom_strcasecmp(entry->name, "private_key_password") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.private_key_password);
}
else if (ipcom_strcasecmp(entry->name, "trusted_ca_store") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.trusted_ca_store);
}
else if (ipcom_strcasecmp(entry->name, "crl_store") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.crl_store);
}
else if (ipcom_strcasecmp(entry->name, "intermediate_ca_store") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.intermediate_ca_store);
}
else if (ipcom_strcasecmp(entry->name, "identity") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.identity);
}
else if (ipcom_strcasecmp(entry->name, "certificate_uri") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->authentication.certificate_uri);
}
else
{
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...", entry->name, config->name);
}
if (IPIKE_CONF_INVALID_VALUE == err)
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'", entry->value, entry->name, config->name);
}
return err;
}
/*
*===========================================================================
* ipike_config_parse_radius
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_radius(
Ipike_config* config,
Ipike_config_api_ike_sa* ike_sa)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
while ((IPIKE_SUCCESS == err) &&
(entry = ipike_configuration_enum(config, entry)))
{
if (ipcom_strcasecmp(entry->name, "shared_secret") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->radius.shared_secret);
}
else if (ipcom_strcasecmp(entry->name, "server_address") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->radius.server_address);
}
else if (ipcom_strcasecmp(entry->name, "local_address") == 0)
{
err = ipike_parse_string(entry->value, &ike_sa->radius.local_address);
}
else
{
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...", entry->name, config->name);
}
if (IPIKE_CONF_INVALID_VALUE == err)
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'", entry->value, entry->name, config->name);
}
return err;
}
/*
*===========================================================================
* ipike_config_parse_ike_sa
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_ike_sa(
Ipike_config* config,
Ipike_config_api_ike_sa* sa,
Ipike_config_api_proposal*** proposals,
char** ike_id)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
Ip_u32 u_val = 0;
if (*config->value != 0)
err = ipike_parse_string(config->value, &sa->remote_address);
if (IPIKE_SUCCESS != err)
{
IPCOM_LOG1(ERR, "Invalid address for '%s'", config->name);
}
err = ipike_parse_string(IPIKE_SA_LIFE_TIME_DEFAULT, &sa->lifetime);
while ((IPIKE_SUCCESS == err) &&
(entry = ipike_configuration_enum(config, entry)))
{
if (ipcom_strcasecmp(entry->name, "ike_id") == 0)
{
if (IP_NULL != ike_id)
err = ipike_parse_string(entry->value, (const char**)ike_id);
}
else if (ipcom_strcasecmp(entry->name, "exchange_version") == 0)
{
err = ipike_parse_string(entry->value, &sa->version);
}
else if (ipcom_strcasecmp(entry->name, "exchange_mode") == 0)
{
err = ipike_parse_string(entry->value, &sa->mode);
}
else if (ipcom_strcasecmp(entry->name, "local_address") == 0)
{
err = ipike_parse_string(entry->value, &sa->local_address);
}
else if (ipcom_strcasecmp(entry->name, "passive") == 0)
{
err = ipike_parse_bool(entry->value, &sa->passive);
}
else if (ipcom_strcasecmp(entry->name, "initial_contact") == 0)
{
err = ipike_parse_bool(entry->value, &sa->initial_contact);
}
else if (ipcom_strcasecmp(entry->name, "reauth") == 0)
{
err = ipike_parse_bool(entry->value, &sa->reauth);
}
else if (ipcom_strcasecmp(entry->name, "liveness") == 0)
{
err = ipike_parse_number(entry->value, &u_val);
sa->liveness = (Ip_s32)u_val;
}
else if (ipcom_strcasecmp(entry->name, "local_identifier") == 0)
{
err = ipike_parse_string(entry->value, &sa->local_id);
}
else if (ipcom_strcasecmp(entry->name, "remote_identifier") == 0)
{
err = ipike_parse_string(entry->value, &sa->remote_id);
}
else if (ipcom_strcasecmp(entry->name, "lifetime") == 0)
{
err = ipike_parse_string(entry->value, &sa->lifetime);
}
else if (ipcom_strcasecmp(entry->name, "proposal") == 0)
{
err = ipike_config_parse_proposal(entry, proposals);
}
else if (ipcom_strcasecmp(entry->name, "authentication") == 0)
{
err = ipike_config_parse_authentication(entry, sa);
}
else if (ipcom_strcasecmp(entry->name, "radius") == 0)
{
err = ipike_config_parse_radius(entry, sa);
}
else
{
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...", entry->name, config->name);
}
if (IPIKE_CONF_INVALID_VALUE == err)
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'", entry->value, entry->name, config->name);
}
return err;
}
/*
*===========================================================================
* ipike_config_free_ike_sa
*===========================================================================
*/
IP_STATIC void
ipike_config_free_ike_sa(Ipike_config_api_ike_sa* sa)
{
ipike_config_api_release_ike_sa(sa);
return;
}
/*
*===========================================================================
* ipike_config_parse_flow
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_flow(Ipike_config* config, Ipike_config_api_ipsec_sa* sa)
{
Ipike_error err = IPIKE_SUCCESS;
Ip_bool pos = 0;
const char* psz;
char* psz2, *tmp;
/* Format: address <src addr> [<src port>] address <dst addr> [<dst port>] [<proto>] */
/* or range format. Masks should be ignored if ranges are used! */
/* Format: address <src addr>-<src2 addr> [<src port>-<src2 port>] address <dst addr>-<dst2 addr> [<dst port>-<dst2 port>] [<proto>] */
psz = config->value;
while ((IPIKE_SUCCESS == err) &&
(*psz != 0) &&
(ipike_parse_get_string(&psz, ' ', &psz2) == 0))
{
pos++;
if ((ipcom_strcasecmp(psz2, "address") == 0) ||
(ipcom_strcasecmp(psz2, "network") == 0))
{
if (pos == 3) /* src port not specified */
pos++;
}
else if ((ipcom_strncasecmp(psz2,"any", 3) == 0) ||
(ipcom_strncasecmp(psz2,"icmpv6", 6) == 0) ||
(ipcom_strncasecmp(psz2,"icmp", 4) == 0) ||
(ipcom_strncasecmp(psz2,"udp", 3) == 0) ||
(ipcom_strncasecmp(psz2,"tcp",3) == 0) ||
(ipcom_strncmp(psz2, "0x", 2) == 0))
{
err = ipike_parse_string(psz2, &sa->flow.protocol);
}
else if (pos == 2)
{
/* Address/port Range support */
tmp = psz2; /* Copy orig pointer */
err = ipike_parse_string(psz2, &sa->flow.src_address);
psz2 = tmp; /* Reset ptr */
}
else if (pos == 3)
{
tmp = psz2; /* Copy orig pointer */
err = ipike_parse_string(psz2, &sa->flow.src_port);
psz2 = tmp; /* Reset ptr */
}
else if (pos == 5)
{
tmp = psz2; /* Copy orig pointer */
err = ipike_parse_string(psz2, &sa->flow.dst_address);
psz2 = tmp; /* Reset ptr */
}
else if (pos == 6)
{
tmp = psz2; /* Copy orig pointer */
err = ipike_parse_string(psz2, &sa->flow.dst_port);
psz2 = tmp; /* Reset ptr */
}
else
{
IPCOM_LOG2(ERR, "Invalid flow parameter '%s' for '%s'", psz2, config->name);
}
ipcom_free(psz2);
}
return err;
}
/*
*===========================================================================
* ipike_config_parse_rohc
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_rohc(
Ipike_config* config,
Ipike_config_api_rohc** rohc)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
Ipike_config_api_rohc* r = IP_NULL;
r = ipcom_calloc(1, sizeof(Ipike_config_api_rohc));
if ( r == IP_NULL )
{
IP_PANIC();
err = IPIKE_OUT_OF_MEMORY;
goto errout;
}
while ( (entry = ipike_configuration_enum(config, entry)) )
{
if (ipcom_strcasecmp(entry->name, "max_cid") == 0)
err = ipike_parse_string(entry->value, &r->max_cid);
else if (ipcom_strcasecmp(entry->name, "profiles") == 0)
err = ipike_parse_string(entry->value, &r->profiles);
else if (ipcom_strcasecmp(entry->name, "mrru") == 0)
err = ipike_parse_string(entry->value, &r->mrru);
else if (ipcom_strcasecmp(entry->name, "integrity_algorithm") == 0)
err = ipike_parse_string(entry->value, &r->integrity_alg);
else if (ipcom_strcasecmp(entry->name, "icv_len") == 0)
err = ipike_parse_string(entry->value, &r->icv_len);
else
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...",
entry->name, config->name);
if (err != IPIKE_SUCCESS)
{
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'",
entry->value, entry->name, config->name);
goto errout;
}
}
ipike_to_lower_string((char*)r->max_cid);
ipike_to_lower_string((char*)r->profiles);
ipike_to_lower_string((char*)r->mrru);
ipike_to_lower_string((char*)r->integrity_alg);
ipike_to_lower_string((char*)r->icv_len);
*rohc = r;
errout:
if (err != IPIKE_SUCCESS)
ipcom_free(r);
return err;
}
/*
*===========================================================================
* ipike_config_parse_ipsec_sa
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_ipsec_sa(
Ipike_config *config,
Ipike_config_api_ipsec_sa *sa,
Ipike_config_api_proposal ***proposals,
Ipike_config_api_rohc **rohc,
char **ipsec_id)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
err = ipike_config_parse_flow(config, sa);
if (err != IPIKE_SUCCESS)
{
IPCOM_LOG1(ERR, "Invalid flow for '%s'", config->name);
return err;
}
while (err == IPIKE_SUCCESS
&& (entry = ipike_configuration_enum(config, entry)))
{
if (ipcom_strcasecmp(entry->name, "ipsec_id") == 0)
{
if (ipsec_id != IP_NULL)
err = ipike_parse_string(entry->value, (const char**)ipsec_id);
}
else if (ipcom_strcasecmp(entry->name, "ike_id") == 0)
{
err = ipike_parse_string(entry->value, &sa->ike_id);
}
else if (ipcom_strcasecmp(entry->name, "encapsulation_mode") == 0)
{
err = ipike_parse_string(entry->value, &sa->encap_mode);
}
else if (ipcom_strcasecmp(entry->name, "use_tfc") == 0)
{
err = ipike_parse_string(entry->value, &sa->use_tfc);
}
else if (ipcom_strcasecmp(entry->name, "use_ecn") == 0)
{
err = ipike_parse_string(entry->value, &sa->use_ecn);
}
else if (ipcom_strcasecmp(entry->name, "dynamic_address") == 0)
{
err = ipike_parse_string(entry->value, &sa->dynamic_address);
}
else if (ipcom_strcasecmp(entry->name, "lifetime") == 0)
{
err = ipike_parse_string(entry->value, &sa->lifetime);
}
else if (ipcom_strcasecmp(entry->name, "proposal") == 0)
{
err = ipike_config_parse_proposal(entry, proposals);
}
else if (ipcom_strcasecmp(entry->name, "flowtype") == 0)
{
err = ipike_parse_string(entry->value, &sa->flowtype);
}
else if (ipcom_strcasecmp(entry->name, "granularity") == 0)
{
err = ipike_parse_string(entry->value, &sa->granularity);
}
else if (ipcom_strcasecmp(entry->name, "replay_window") == 0)
{
err = ipike_parse_number(entry->value, &sa->replay_window);
}
else if (ipcom_strcasecmp(entry->name, "rohc") == 0)
{
err = ipike_config_parse_rohc(entry, rohc);
}
else
{
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...",
entry->name, config->name);
err = IPIKE_SUCCESS;
}
if (err == IPIKE_CONF_INVALID_VALUE)
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'",
entry->value, entry->name, config->name);
}
return err;
}
/*
*===========================================================================
* ipike_config_free_ipsec_sa
*===========================================================================
*/
IP_STATIC void
ipike_config_free_ipsec_sa(Ipike_config_api_ipsec_sa* sa)
{
ipike_config_api_release_ipsec_sa(sa);
}
/*
*===========================================================================
* ipike_config_parse_general
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_parse_general(
Ipike_config* config,
Ipike_config_api_general* general,
Ipike_config_api_ike_sa* def_ike_sa,
Ipike_config_api_proposal*** def_ike_proposals,
Ipike_config_api_ipsec_sa* def_ipsec_sa,
Ipike_config_api_proposal*** def_ipsec_proposals,
Ipike_config_api_rohc** def_ipsec_rohc)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* entry = IP_NULL;
/* Set all default that are non-zero */
general->spi_min = IPIKE_CONFIG_DEF_SPI_MIN;
general->spi_max = IPIKE_CONFIG_DEF_SPI_MAX;
general->retransmits = IPIKE_CONFIG_DEF_RETRANSMITS;
def_ike_sa->passive = IP_TRUE;
while ((IPIKE_SUCCESS == err) &&
(entry = ipike_configuration_enum(config, entry)))
{
if (ipcom_strcasecmp(entry->name, "listen") == 0)
{
err = ipike_parse_string(entry->value, &general->listen);
}
else if (ipcom_strcasecmp(entry->name, "retransmits") == 0)
{
err = ipike_parse_number(entry->value, &general->retransmits);
}
else if (ipcom_strcasecmp(entry->name, "exchange_max_time") == 0)
{
err = ipike_parse_number(entry->value, &general->exchange_max_time);
}
else if (ipcom_strcasecmp(entry->name, "spi_min") == 0)
{
err = ipike_parse_number(entry->value, &general->spi_min);
}
else if (ipcom_strcasecmp(entry->name, "spi_max") == 0)
{
err = ipike_parse_number(entry->value, &general->spi_max);
}
else if (ipcom_strcasecmp(entry->name, "default_ike_sa") == 0)
{
err = ipike_config_parse_ike_sa(entry, def_ike_sa, def_ike_proposals, IP_NULL);
}
else if (ipcom_strcasecmp(entry->name, "default_ipsec_sa") == 0)
{
err = ipike_config_parse_ipsec_sa(entry,
def_ipsec_sa,
def_ipsec_proposals,
def_ipsec_rohc,
IP_NULL);
}
else
{
IPCOM_LOG2(INFO, "Unknown '%s' entry for '%s', ignored...", entry->name, config->name);
}
if (IPIKE_SUCCESS != err)
IPCOM_LOG3(ERR, "Invalid value '%s' for '%s' at '%s'", entry->value, entry->name, config->name);
}
return err;
}
/*
*===========================================================================
* ipike_config_free_general
*===========================================================================
*/
IP_STATIC void
ipike_config_free_general(Ipike_config_api_general* general)
{
ipike_config_api_release_general(general);
return;
}
/*
*===========================================================================
* ipike_config_file_set_ike_sa
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_file_set_ike_sa(
void* config,
const char* ike_id,
Ipike_config_api_ike_sa* sa,
Ipike_config_api_proposal** proposals)
{
Ipike_error err = IPIKE_SUCCESS;
Ip_u32 i = 0;
int id = IPIKE_CONFIG_INVALID_VALUE;
err = ipike_config_api_set_ike_sa(config, ike_id, sa);
if ( IPIKE_SUCCESS != err )
return err;
if ( IP_NULL != proposals )
{
for ( i = 0; proposals[i] != IP_NULL; i++)
{
id = (Ip_u8)(1 + i);
err = ipike_config_api_set_ike_sa_proposal(config,
ike_id,
&id,
proposals[i]);
if (IPIKE_SUCCESS != err)
break;
}
}
return err;
}
/*
*===========================================================================
* ipike_config_file_set_ipsec_sa
*===========================================================================
*/
IP_STATIC Ipike_error
ipike_config_file_set_ipsec_sa(
void* config,
const char* ipsec_id,
Ipike_config_api_ipsec_sa* sa,
Ipike_config_api_proposal** proposals,
Ipike_config_api_rohc* rohc)
{
Ipike_error err = IPIKE_SUCCESS;
Ip_u32 i = 0;
int id = IPIKE_CONFIG_INVALID_VALUE;
err = ipike_config_api_set_ipsec_sa(config, ipsec_id, sa);
if ( IPIKE_SUCCESS != err)
return err;
if ( IP_NULL != proposals )
{
for ( i = 0; proposals[i] != IP_NULL; i++)
{
id = (Ip_u8)(1 + i);
err = ipike_config_api_set_ipsec_sa_proposal(config,
ipsec_id,
&id,
proposals[i]);
if (IPIKE_SUCCESS != err)
break;
}
}
if ( IP_NULL != rohc )
ipike_config_api_set_ipsec_sa_rohc(config, ipsec_id, rohc);
return err;
}
/*
*===========================================================================
* ipike_config_generate_ipsec_id
*===========================================================================
*/
IP_STATIC char*
ipike_config_generate_ipsec_id(
Ipike_config_ipsec_sa** sas,
const char* ike_id)
{
char* ipsec_id = IP_NULL;
Ip_u32 count = 0;
Ip_u32 i = 0;
/* We require that a IKE id is specfied. We will generate the unique id
* from ike_id and the number of times the ike is used. */
if (IP_NULL == ike_id)
{
IPCOM_LOG0(ERR, "No IKE SA id (ike_id) specified for IPSec SA");
}
else
{
/* Append ipsec "counter" to ike_id */
count = 0;
if (IP_NULL != sas)
{
while (IP_NULL != sas[i])
{
if (IP_NULL != sas[i]->ike_id)
if (!ipcom_strcmp(sas[i]->ike_id, ike_id))
count++;
i++;
}
}
ipsec_id = ipcom_malloc(ipcom_strlen(ike_id) + 8);
if (IP_NULL != ipsec_id)
ipcom_sprintf(ipsec_id, "%s_%d", ike_id, (int)count);
}
return ipsec_id;
}
/*
*===========================================================================
* ipike_config_export_lifetime
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_lifetime(
Ip_bool def,
Ip_bool v1,
const char* lifetime,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
if ((IP_NULL == lifetime) || (0 == lifetime[0]))
return 0;
/* Always require max length for buffer */
max_len = 32 + ipcom_strlen(lifetime);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
buf_len = 0;
if (def)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " ");
if (v1)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " v1_lifetime ");
else
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " lifetime ");
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s;\n", lifetime);
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_authentication
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_authentication(
Ip_bool def,
Ipike_config_api_ike_sa* ike_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
char off[5] = {0};
/* Always require max length for buffer */
max_len = 32*10;
if (IP_NULL != ike_sa->authentication.method)
max_len += ipcom_strlen(ike_sa->authentication.method);
if (IP_NULL != ike_sa->authentication.shared_key)
max_len += ipcom_strlen(ike_sa->authentication.shared_key);
if (IP_NULL != ike_sa->authentication.certificate)
max_len += ipcom_strlen(ike_sa->authentication.certificate);
if (IP_NULL != ike_sa->authentication.send_certificate)
max_len += ipcom_strlen(ike_sa->authentication.send_certificate);
if (IP_NULL != ike_sa->authentication.request_certificate)
max_len += ipcom_strlen(ike_sa->authentication.request_certificate);
if (IP_NULL != ike_sa->authentication.ocsp_response)
max_len += ipcom_strlen(ike_sa->authentication.ocsp_response);
if (IP_NULL != ike_sa->authentication.remote_certificate)
max_len += ipcom_strlen(ike_sa->authentication.remote_certificate);
if (IP_NULL != ike_sa->authentication.private_key)
max_len += ipcom_strlen(ike_sa->authentication.private_key);
if (IP_NULL != ike_sa->authentication.private_key_password)
max_len += ipcom_strlen(ike_sa->authentication.private_key_password);
if (IP_NULL != ike_sa->authentication.intermediate_ca_store)
max_len += ipcom_strlen(ike_sa->authentication.intermediate_ca_store);
if (IP_NULL != ike_sa->authentication.trusted_ca_store)
max_len += ipcom_strlen(ike_sa->authentication.trusted_ca_store);
if (IP_NULL != ike_sa->authentication.crl_store)
max_len += ipcom_strlen(ike_sa->authentication.crl_store);
if (IP_NULL != ike_sa->authentication.identity)
max_len += ipcom_strlen(ike_sa->authentication.identity);
if (IP_NULL != ike_sa->authentication.certificate_uri)
max_len += ipcom_strlen(ike_sa->authentication.certificate_uri);
if (max_len == 32*9)
return 0; /* Nothing to export */
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
if (def)
ipcom_strcpy(off, " ");
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " authentication {\n");
if (IP_NULL != ike_sa->authentication.method)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " method %s;\n",
ike_sa->authentication.method);
}
if (IP_NULL != ike_sa->authentication.shared_key)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " shared_key %s;\n",
ike_sa->authentication.shared_key);
}
if (IP_NULL != ike_sa->authentication.certificate)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " certificate %s;\n",
ike_sa->authentication.certificate);
}
if (IP_NULL != ike_sa->authentication.send_certificate)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " send_certificate %s;\n",
ike_sa->authentication.send_certificate);
}
if (IP_NULL != ike_sa->authentication.request_certificate)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " request_certificate %s;\n",
ike_sa->authentication.request_certificate);
}
if (IP_NULL != ike_sa->authentication.ocsp_response)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " ocsp_response %s;\n",
ike_sa->authentication.ocsp_response);
}
if (IP_NULL != ike_sa->authentication.remote_certificate)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " remote_certificate %s;\n",
ike_sa->authentication.remote_certificate);
}
if (IP_NULL != ike_sa->authentication.private_key)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " private_key %s;\n",
ike_sa->authentication.private_key);
}
if (IP_NULL != ike_sa->authentication.private_key_password)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " private_key_password %s;\n",
ike_sa->authentication.private_key_password);
}
if (IP_NULL != ike_sa->authentication.intermediate_ca_store)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " intermediate_ca_store %s;\n",
ike_sa->authentication.intermediate_ca_store);
}
if (IP_NULL != ike_sa->authentication.trusted_ca_store)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " trusted_ca_store %s;\n",
ike_sa->authentication.trusted_ca_store);
}
if (IP_NULL != ike_sa->authentication.crl_store)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " crl_store %s;\n",
ike_sa->authentication.crl_store);
}
if (IP_NULL != ike_sa->authentication.identity)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " identity %s;\n",
ike_sa->authentication.identity);
}
if (IP_NULL != ike_sa->authentication.certificate_uri)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " certificate_uri %s;\n",
ike_sa->authentication.certificate_uri);
}
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " }\n");
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_radius
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_radius(
Ip_bool def,
Ipike_config_api_ike_sa* ike_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
char off[5] = {0};
/* Always require max length for buffer */
max_len = 32*3;
if (IP_NULL != ike_sa->radius.shared_secret)
max_len += ipcom_strlen(ike_sa->radius.shared_secret);
if (IP_NULL != ike_sa->radius.local_address)
max_len += ipcom_strlen(ike_sa->radius.local_address);
if (IP_NULL != ike_sa->radius.server_address)
max_len += ipcom_strlen(ike_sa->radius.server_address);
if (max_len == 32*3)
return 0; /* Nothing to export */
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
if (def)
ipcom_strcpy(off, " ");
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " radius {\n");
if (IP_NULL != ike_sa->radius.shared_secret)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " shared_secret %s;\n",
ike_sa->radius.shared_secret);
}
if (IP_NULL != ike_sa->radius.local_address)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " local_address %s;\n",
ike_sa->radius.local_address);
}
if (IP_NULL != ike_sa->radius.server_address)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " server_address %s;\n",
ike_sa->radius.server_address);
}
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " }\n");
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_proposal
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_proposal(
Ip_bool def,
Ipike_config_api_proposal* prop,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
Ip_size_t len = 0;
char off[5] = {0};
/* Always require max length for buffer */
max_len = 6*32;
if (IP_NULL != prop->dh_group)
max_len += ipcom_strlen(prop->dh_group);
if (IP_NULL != prop->encryption_alg)
max_len += ipcom_strlen(prop->encryption_alg);
if (IP_NULL != prop->hash_alg)
max_len += ipcom_strlen(prop->hash_alg);
if (IP_NULL != prop->integrity_alg)
max_len += ipcom_strlen(prop->integrity_alg);
if (IP_NULL != prop->use_esn)
max_len += ipcom_strlen(prop->use_esn);
if (IP_NULL != prop->number)
max_len += ipcom_strlen(prop->number);
max_len += ipike_config_export_lifetime(def,
IP_TRUE,
prop->v1.lifetime,
IP_NULL,
0);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
if (def)
ipcom_strcpy(off, " ");
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " proposal {\n");
if (prop->number)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " number %s;\n",
prop->number);
}
if (IP_NULL != prop->dh_group)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " dh_group %s;\n",
prop->dh_group);
}
if (IP_NULL != prop->encryption_alg)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " encryption_algorithm %s;\n",
prop->encryption_alg);
}
if (IP_NULL != prop->hash_alg)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " hash_algorithm %s;\n",
prop->hash_alg);
}
if (IP_NULL != prop->integrity_alg)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " integrity_algorithm %s;\n",
prop->integrity_alg);
}
if (IP_NULL != prop->use_esn)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " use_esn %s;\n",
prop->use_esn);
}
len = ipike_config_export_lifetime(def,
IP_TRUE,
prop->v1.lifetime,
&buf[buf_len],
max_len - buf_len);
if (INVALID_LEN == len)
return INVALID_LEN;
buf_len += len;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " }\n");
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_flow
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_flow(
Ipike_config_api_ipsec_sa* ipsec_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
if ((IP_NULL == ipsec_sa->flow.src_address) ||
(IP_NULL == ipsec_sa->flow.dst_address))
return 0;
/* Always require max length for buffer */
max_len = 32;
max_len += ipcom_strlen(ipsec_sa->flow.src_address);
max_len += ipcom_strlen(ipsec_sa->flow.dst_address);
if (IP_NULL != ipsec_sa->flow.src_port)
max_len += ipcom_strlen(ipsec_sa->flow.src_port);
if (IP_NULL != ipsec_sa->flow.dst_port)
max_len += ipcom_strlen(ipsec_sa->flow.dst_port);
if (IP_NULL != ipsec_sa->flow.protocol)
max_len += ipcom_strlen(ipsec_sa->flow.protocol);
/* Address/port range support */
if (IP_NULL != ipsec_sa->flow_end.src_address)
max_len += (ipcom_strlen(ipsec_sa->flow_end.src_address) + 1);
if (IP_NULL != ipsec_sa->flow_end.dst_address)
max_len += (ipcom_strlen(ipsec_sa->flow_end.dst_address) + 1);
if (IP_NULL != ipsec_sa->flow_end.src_port)
max_len += (ipcom_strlen(ipsec_sa->flow_end.src_port) + 1);
if (IP_NULL != ipsec_sa->flow_end.dst_port)
max_len += (ipcom_strlen(ipsec_sa->flow_end.dst_port) + 1);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "address %s",
ipsec_sa->flow.src_address);
if (IP_NULL != ipsec_sa->flow_end.src_address)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "-%s",
ipsec_sa->flow_end.src_address);
if (IP_NULL != ipsec_sa->flow.src_port)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " %s",
ipsec_sa->flow.src_port);
if (IP_NULL != ipsec_sa->flow_end.src_port)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "-%s",
ipsec_sa->flow_end.src_port);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " address %s",
ipsec_sa->flow.dst_address);
if (IP_NULL != ipsec_sa->flow_end.dst_address)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "-%s",
ipsec_sa->flow_end.dst_address);
if (IP_NULL != ipsec_sa->flow.dst_port)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " %s",
ipsec_sa->flow.dst_port);
if (IP_NULL != ipsec_sa->flow_end.dst_port)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "-%s",
ipsec_sa->flow_end.dst_port);
if (IP_NULL != ipsec_sa->flow.protocol)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " %s",
ipsec_sa->flow.protocol);
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_rohc
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_rohc(
Ip_bool def,
Ipike_config_api_rohc * rohc,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
char off[5] = {0};
/* Nothing to export */
if ( IP_NULL == rohc )
return 0;
/* Always require max length for buffer */
max_len = 32*5;
if (IP_NULL != rohc)
{
if (IP_NULL != rohc->max_cid )
max_len += ipcom_strlen(rohc->max_cid);
if (IP_NULL != rohc->mrru )
max_len += ipcom_strlen(rohc->mrru);
if (IP_NULL != rohc->profiles )
max_len += ipcom_strlen(rohc->profiles);
if (IP_NULL != rohc->icv_len )
max_len += ipcom_strlen(rohc->icv_len);
if (IP_NULL != rohc->integrity_alg )
max_len += ipcom_strlen(rohc->integrity_alg);
}
if (IP_NULL == buf)
{
buf_len = max_len;
/* No buffer provided, just calculate the required buf_len and return */
return IPIKE_SUCCESS;
}
if ( buf_len < max_len )
return INVALID_LEN;
if (def)
ipcom_strcpy(off, " ");
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " rohc {\n");
if (IP_NULL != rohc->mrru )
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " mrru %s;\n",
rohc->mrru);
}
if (IP_NULL != rohc->profiles )
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " profiles %s;\n",
rohc->profiles);
}
if (IP_NULL != rohc->max_cid )
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " max_cid %s;\n",
rohc->max_cid);
}
if (IP_NULL != rohc->integrity_alg )
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " integrity_algorithm %s;\n",
rohc->integrity_alg);
}
if (IP_NULL != rohc->icv_len )
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " icv_len %s;\n",
rohc->icv_len);
}
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " }\n");
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_ike_sa
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_ike_sa(
const char* ike_id,
Ipike_config_api_ike_sa* ike_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
Ip_size_t len = 0;
char off[5] = {0};
if ((IP_NULL == ike_sa) || (IP_NULL == ike_id))
return 0;
/* Always require max length for buffer */
max_len = 256;
max_len += ipcom_strlen(ike_id);
max_len += ipike_config_export_authentication(IP_TRUE, ike_sa, IP_NULL, 0);
max_len += ipike_config_export_radius(IP_TRUE, ike_sa, IP_NULL, 0);
if (IP_NULL != ike_sa->version)
max_len += ipcom_strlen(ike_sa->version);
if (IP_NULL != ike_sa->local_address)
max_len += ipcom_strlen(ike_sa->local_address);
if (IP_NULL != ike_sa->remote_address)
max_len += ipcom_strlen(ike_sa->remote_address);
if (IP_NULL != ike_sa->local_id)
max_len += ipcom_strlen(ike_sa->local_id);
if (IP_NULL != ike_sa->remote_id)
max_len += ipcom_strlen(ike_sa->remote_id);
if (IP_NULL != ike_sa->lifetime)
max_len += ipcom_strlen(ike_sa->lifetime);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
return INVALID_LEN;
}
else
{
buf_len = 0;
if (0 == ike_id[0])
{
ipcom_strcpy(off, " ");
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " default_ike_sa {\n");
}
else
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "ike_sa address %s {\n", ike_sa->remote_address);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " ike_id %s;\n", ike_id);
}
if (IP_NULL != ike_sa->version)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " exchange_version %s;\n", ike_sa->version);
}
if (IP_NULL != ike_sa->mode)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " exchange_mode %s;\n", ike_sa->mode);
}
if (IP_NULL != ike_sa->local_address)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " local_address %s;\n", ike_sa->local_address);
}
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " passive %s;\n", ike_sa->passive ? "on" : "off");
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " initial_contact %s;\n", ike_sa->initial_contact ? "on" : "off");
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " reauth %s;\n", ike_sa->reauth ? "yes" : "no");
if (ike_sa->liveness >= 0)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " liveness %lu;\n", ike_sa->liveness);
}
if (IP_NULL != ike_sa->local_id)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " local_identifier %s;\n", ike_sa->local_id);
}
if (IP_NULL != ike_sa->remote_id)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " remote_identifier %s;\n", ike_sa->remote_id);
}
len = ipike_config_export_lifetime((0 == ike_id[0]),
IP_FALSE,
ike_sa->lifetime,
&buf[buf_len],
max_len - buf_len);
if (INVALID_LEN == len)
return INVALID_LEN;
buf_len += len;
len = ipike_config_export_authentication((0 == ike_id[0]),
ike_sa,
&buf[buf_len],
max_len - buf_len);
if (INVALID_LEN == len)
return INVALID_LEN;
buf_len += len;
len = ipike_config_export_radius((0 == ike_id[0]),
ike_sa,
&buf[buf_len],
max_len - buf_len);
if (INVALID_LEN == len)
return INVALID_LEN;
buf_len += len;
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_ipsec_sa
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_ipsec_sa(
const char* ipsec_id,
Ipike_config_api_ipsec_sa* ipsec_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
Ip_size_t len = 0;
char off[5] = {0};
if ((IP_NULL == ipsec_sa) || (IP_NULL == ipsec_id))
return 0;
/* Always require max length for buffer */
max_len = 128;
max_len += ipike_config_export_lifetime((ipsec_id[0] == IP_NULL),
IP_FALSE,
ipsec_sa->lifetime,
IP_NULL,
0);
max_len += ipike_config_export_flow(ipsec_sa,
IP_NULL,
0);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
return INVALID_LEN;
}
else
{
buf_len = 0;
if (ipsec_id[0] == 0)
{
ipcom_strcpy(off, " ");
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " default_ipsec_sa {\n");
}
else
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "ipsec_sa ");
len = ipike_config_export_flow(ipsec_sa,
&buf[buf_len],
max_len - buf_len);
if (INVALID_LEN == len)
return INVALID_LEN;
buf_len += len;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " {\n");
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " ipsec_id %s;\n", ipsec_id);
}
if (IP_NULL != ipsec_sa->ike_id)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " ike_id %s;\n", ipsec_sa->ike_id);
}
if (IP_NULL != ipsec_sa->encap_mode)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " encapsulation_mode %s;\n", ipsec_sa->encap_mode);
}
if (IP_NULL != ipsec_sa->use_tfc)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " use_tfc %s;\n", ipsec_sa->use_tfc);
}
if (IP_NULL != ipsec_sa->use_ecn)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " use_ecn %s;\n", ipsec_sa->use_ecn);
}
if (IP_NULL != ipsec_sa->dynamic_address)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " dynamic_address %s;\n", ipsec_sa->dynamic_address);
}
if (IP_NULL != ipsec_sa->flowtype)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " flowtype %s;\n", ipsec_sa->flowtype);
}
if (IP_NULL != ipsec_sa->granularity)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " granularity %s;\n", ipsec_sa->granularity);
}
if (0 != ipsec_sa->replay_window)
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s", off);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " replay_window %d;\n", ipsec_sa->replay_window);
}
len = ipike_config_export_lifetime((ipsec_id[0] == 0),
IP_FALSE,
ipsec_sa->lifetime,
&buf[buf_len],
max_len - buf_len);
if (INVALID_LEN == len)
return INVALID_LEN;
buf_len += len;
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_general
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_general(
Ipike_config_api_general* general,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
/* Always require max length for buffer */
max_len = 128;
if (IP_NULL != general->listen)
max_len += ipcom_strlen(general->listen);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "general {\n");
if (IP_NULL != general->listen)
buf_len += (Ip_size_t) ipcom_sprintf(&buf[buf_len], " listen %s;\n", general->listen);
if (general->retransmits != IPIKE_CONFIG_DEF_RETRANSMITS)
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " retransmits %lu;\n", general->retransmits);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " exchange_max_time %lu;\n", general->exchange_max_time);
if ((general->spi_min != IPIKE_CONFIG_DEF_SPI_MIN) ||
(general->spi_max != IPIKE_CONFIG_DEF_SPI_MAX))
{
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " spi_min %lu;\n", general->spi_min);
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], " spi_max %lu;\n", general->spi_max);
}
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_section_end
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_section_end(
const char* off,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
/* Always require max length for buffer */
max_len = 2;
max_len += ipcom_strlen(off);
if (IP_NULL == buf)
{
buf_len = max_len;
}
else if (buf_len < max_len)
{
buf_len = INVALID_LEN;
}
else
{
buf_len = 0;
buf_len += (Ip_size_t)ipcom_sprintf(&buf[buf_len], "%s}\n", off);
}
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_ike_sa_with_proposals
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_ike_sa_with_proposals(
void* ctx,
const char* ike_id,
Ipike_config_api_ike_sa* ike_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
Ip_size_t len = 0;
int id_prop = 0;
int pos_prop = 0;
Ipike_config_api_proposal proposal = {0};
max_len = buf_len;
buf_len = 0;
len = ipike_config_export_ike_sa(ike_id,
ike_sa,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
pos_prop = IPIKE_CONFIG_INVALID_VALUE;
while (IPIKE_SUCCESS == ipike_config_api_get_next_ike_sa_proposal(ctx,
ike_id,
&id_prop,
&proposal,
&pos_prop))
{
len = ipike_config_export_proposal((ike_id[0] == 0),
&proposal,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
ipike_config_api_release_proposal(&proposal);
}
len = ipike_config_export_section_end((ike_id[0] == 0) ? " " : "",
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_ipsec_sa_with_proposals
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_ipsec_sa_with_proposals(
void* ctx,
const char* ipsec_id,
Ipike_config_api_ipsec_sa* ipsec_sa,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
Ip_size_t len = 0;
int id_prop = 0;
int pos_prop = 0;
Ipike_config_api_proposal proposal = {0};
Ipike_config_api_rohc rohc = {0};
max_len = buf_len;
buf_len = 0;
len = ipike_config_export_ipsec_sa(ipsec_id,
ipsec_sa,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
if ( IPIKE_SUCCESS == ipike_config_api_get_ipsec_sa_rohc(ctx, ipsec_id, &rohc) )
{
len = ipike_config_export_rohc(ipsec_id[0] == 0,
&rohc,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
}
pos_prop = IPIKE_CONFIG_INVALID_VALUE;
while (IPIKE_SUCCESS == ipike_config_api_get_next_ipsec_sa_proposal(ctx,
ipsec_id,
&id_prop,
&proposal,
&pos_prop))
{
len = ipike_config_export_proposal((ipsec_id[0] == 0),
&proposal,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
ipike_config_api_release_proposal(&proposal);
}
len = ipike_config_export_section_end((ipsec_id[0] == 0) ? " " : "",
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
return buf_len;
}
/*
*===========================================================================
* ipike_config_export_general_with_default
*===========================================================================
*/
IP_STATIC Ip_size_t
ipike_config_export_general_with_default(
void* ctx,
Ipike_config_api_general* general,
char* buf,
Ip_size_t buf_len)
{
Ip_size_t max_len = 0;
Ip_size_t len = 0;
int pos = 0;
char id[IPIKE_CONFIG_MAX_ID_LEN] = {0};
Ipike_config_api_ike_sa ike_sa = {0};
Ipike_config_api_ipsec_sa ipsec_sa = {0};
max_len = buf_len;
buf_len = 0;
len = ipike_config_export_general(general, buf, max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
pos = IPIKE_CONFIG_INVALID_VALUE;
while (IPIKE_SUCCESS == ipike_config_api_get_next_ike_sa(ctx, id, &ike_sa, &pos))
{
if (id[0] == 0)
{
len = ipike_config_export_ike_sa_with_proposals(ctx,
id,
&ike_sa,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
ipike_config_api_release_ike_sa(&ike_sa);
/* Only one default entry */
break;
}
ipike_config_api_release_ike_sa(&ike_sa);
}
pos = IPIKE_CONFIG_INVALID_VALUE;
while (IPIKE_SUCCESS == ipike_config_api_get_next_ipsec_sa(ctx, id, &ipsec_sa, &pos))
{
if (id[0] == 0)
{
len = ipike_config_export_ipsec_sa_with_proposals(ctx,
id,
&ipsec_sa,
buf,
max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
ipike_config_api_release_ipsec_sa(&ipsec_sa);
/* Only one default entry */
break;
}
ipike_config_api_release_ipsec_sa(&ipsec_sa);
}
len = ipike_config_export_section_end("", buf, max_len - buf_len);
if (len == INVALID_LEN)
return INVALID_LEN;
buf_len += len;
if (IP_NULL != buf)
buf += len;
return buf_len;
}
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipike_config_file_import_content
*===========================================================================
*/
IP_GLOBAL Ipike_error
ipike_config_file_import_content(
Ipike_config_ike* config,
const char* buf,
Ip_size_t buf_len)
{
Ipike_error err = IPIKE_SUCCESS;
Ipike_config* content = IP_NULL;
Ipike_config* entry = IP_NULL;
Ipike_config_api_general general;
Ipike_config_api_ike_sa ike_sa;
Ipike_config_api_ipsec_sa ipsec_sa;
Ipike_config_api_proposal** ike_proposal = IP_NULL;
Ipike_config_api_proposal** ipsec_proposal = IP_NULL;
Ipike_config_api_rohc* ipsec_rohc = IP_NULL;
char* ike_id = IP_NULL;
char* ipsec_id = IP_NULL;
ipcom_memset(&general, 0, sizeof(Ipike_config_api_general));
ipcom_memset(&ike_sa, 0, sizeof(Ipike_config_api_ike_sa));
ipcom_memset(&ipsec_sa, 0, sizeof(Ipike_config_api_ipsec_sa));
err = ipike_configuration_new(buf, buf_len, &content);
if (IPIKE_SUCCESS != err)
{
IPCOM_LOG0(ERR, "Failed to parse the configuration");
goto errout;
}
while ( (entry = ipike_configuration_enum(content, entry)) != IP_NULL )
{
if (ipcom_strcasecmp(entry->name, "general") == 0)
{
err = ipike_config_parse_general(entry,
&general,
&ike_sa,
&ike_proposal,
&ipsec_sa,
&ipsec_proposal,
&ipsec_rohc);
if (IPIKE_SUCCESS == err)
err = ipike_config_api_set_general(config, &general);
if (IPIKE_SUCCESS == err)
err = ipike_config_file_set_ike_sa(config,
IP_NULL,
&ike_sa,
ike_proposal);
if (IPIKE_SUCCESS == err)
err = ipike_config_file_set_ipsec_sa(config,
IP_NULL,
&ipsec_sa,
ipsec_proposal,
ipsec_rohc);
ipike_config_free_general(&general);
ipike_config_free_ike_sa(&ike_sa);
ipike_config_free_ipsec_sa(&ipsec_sa);
ipike_config_free_proposals(&ike_proposal);
ipike_config_free_proposals(&ipsec_proposal);
ipike_config_free_rohc(&ipsec_rohc);
}
else if (ipcom_strcasecmp(entry->name, "ike_sa") == 0)
{
/* Set non string parameters as unspecified */
ike_sa.liveness = -1; /* Unassigned value now is -1 */
ike_sa.reauth = IPIKE_CONFIG_UNSPEC_BOOL;
ike_sa.passive = IPIKE_CONFIG_UNSPEC_BOOL;
ike_sa.initial_contact = IPIKE_CONFIG_UNSPEC_BOOL;
err = ipike_config_parse_ike_sa(entry,
&ike_sa,
&ike_proposal,
&ike_id);
if (IPIKE_SUCCESS == err)
err = ipike_config_file_set_ike_sa(config,
ike_id,
&ike_sa,
ike_proposal);
IPIKE_FREEP(ike_id);
ipike_config_free_ike_sa(&ike_sa);
ipike_config_free_proposals(&ike_proposal);
}
else if (ipcom_strcasecmp(entry->name, "ipsec_sa") == 0)
{
err = ipike_config_parse_ipsec_sa(entry,
&ipsec_sa,
&ipsec_proposal,
&ipsec_rohc,
&ipsec_id);
if (IP_NULL == ipsec_id)
ipsec_id = ipike_config_generate_ipsec_id(config->ipsec_sa,
ipsec_sa.ike_id);
if (IPIKE_SUCCESS == err)
err = ipike_config_file_set_ipsec_sa(config,
ipsec_id,
&ipsec_sa,
ipsec_proposal,
ipsec_rohc);
IPIKE_FREEP(ipsec_id);
ipike_config_free_ipsec_sa(&ipsec_sa);
ipike_config_free_proposals(&ipsec_proposal);
ipike_config_free_rohc(&ipsec_rohc);
}
else if (ipcom_strcasecmp(entry->name, "append_existing") == 0)
{
/* For shell command: "ike config load <file>". */
}
else
{
IPCOM_LOG1(INFO, "Unknown configuration entry '%s', ignored...",
entry->name);
}
}
errout:
ipike_configuration_free(content);
return err;
}
/*
*===========================================================================
* ipike_config_file_export_content
*===========================================================================
*/
IP_GLOBAL Ipike_error
ipike_config_file_export_content(
Ipike_config_ike* config,
char* buf,
Ip_size_t* buf_len)
{
Ipike_error err = IPIKE_SUCCESS;
Ip_size_t max_len = 0;
Ip_size_t len = 0;
char id[IPIKE_CONFIG_MAX_ID_LEN] = {0};
int pos = 0;
void* ctx = IP_NULL;
Ipike_config_api_general general = {0};
Ipike_config_api_ike_sa ike_sa = {0};
Ipike_config_api_ipsec_sa ipsec_sa = {0};
max_len = *buf_len;
*buf_len = 0;
ctx = ipike_config_api_from_config(config);
if (IP_NULL == ctx)
{
IP_PANIC();
return IPIKE_OUT_OF_MEMORY;
}
if (IPIKE_SUCCESS == ipike_config_api_get_general(ctx, &general))
{
len = ipike_config_export_general_with_default(ctx,
&general,
buf,
max_len - *buf_len);
if (len == INVALID_LEN)
{
err = IPIKE_BUFFER_TOO_SMALL;
}
else
{
*buf_len += len;
if (IP_NULL != buf)
buf += len;
}
ipike_config_api_release_general(&general);
}
pos = IPIKE_CONFIG_INVALID_VALUE;
while ((IPIKE_SUCCESS == err) &&
(IPIKE_SUCCESS == ipike_config_api_get_next_ike_sa(ctx,
id,
&ike_sa,
&pos)))
{
if (id[0] != 0)
{
len = ipike_config_export_ike_sa_with_proposals(ctx,
id,
&ike_sa,
buf,
max_len - *buf_len);
if (len == INVALID_LEN)
{
err = IPIKE_BUFFER_TOO_SMALL;
}
else
{
*buf_len += len;
if (IP_NULL != buf)
buf += len;
}
}
ipike_config_api_release_ike_sa(&ike_sa);
}
pos = IPIKE_CONFIG_INVALID_VALUE;
while ((IPIKE_SUCCESS == err) &&
(IPIKE_SUCCESS == ipike_config_api_get_next_ipsec_sa(ctx,
id,
&ipsec_sa,
&pos)))
{
if (id[0] != 0)
{
len = ipike_config_export_ipsec_sa_with_proposals(ctx,
id,
&ipsec_sa,
buf,
max_len - *buf_len);
if (len == INVALID_LEN)
{
err = IPIKE_BUFFER_TOO_SMALL;
}
else
{
*buf_len += len;
if (IP_NULL != buf)
buf += len;
}
}
ipike_config_api_release_ipsec_sa(&ipsec_sa);
}
ipike_config_api_free(ctx);
return err;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/