2235 lines
80 KiB
C
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
|
|
****************************************************************************
|
|
*/
|