Merge branch 'childless'
Adds support for childless initiation of IKE_SAs (RFC 6023) e.g. to force a separate DH exchange for all CHILD_SAs including the first one. Also allows the initiation of only the IKE_SA via swanctl --initiate if the peer supports this extension. Closes strongswan/strongswan#99.
This commit is contained in:
commit
f9e8f5a623
|
@ -142,9 +142,13 @@ static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this)
|
|||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
peer_cfg_t *peer_cfg;
|
||||
uint16_t local_port, remote_port = IKEV2_UDP_PORT;
|
||||
ike_version_t version = IKE_ANY;
|
||||
proposal_t *proposal;
|
||||
ike_cfg_create_t ike = {
|
||||
.local = "0.0.0.0",
|
||||
.remote = this->host,
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.fragmentation = FRAGMENTATION_YES,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_SEND_IF_ASKED,
|
||||
.unique = UNIQUE_REPLACE,
|
||||
|
@ -161,7 +165,7 @@ static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this)
|
|||
case PROF_V2_PUB:
|
||||
case PROF_V2_EAP:
|
||||
case PROF_V2_PUB_EAP:
|
||||
version = IKEV2;
|
||||
ike.version = IKEV2;
|
||||
break;
|
||||
case PROF_V1_PUB_AM:
|
||||
case PROF_V1_XAUTH_AM:
|
||||
|
@ -173,17 +177,16 @@ static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this)
|
|||
case PROF_V1_XAUTH:
|
||||
case PROF_V1_XAUTH_PSK:
|
||||
case PROF_V1_HYBRID:
|
||||
version = IKEV1;
|
||||
ike.version = IKEV1;
|
||||
break;
|
||||
}
|
||||
|
||||
local_port = charon->socket->get_port(charon->socket, FALSE);
|
||||
if (local_port != IKEV2_UDP_PORT)
|
||||
ike.local_port = charon->socket->get_port(charon->socket, FALSE);
|
||||
if (ike.local_port != IKEV2_UDP_PORT)
|
||||
{
|
||||
remote_port = IKEV2_NATT_PORT;
|
||||
ike.remote_port = IKEV2_NATT_PORT;
|
||||
}
|
||||
ike_cfg = ike_cfg_create(version, TRUE, FALSE, "0.0.0.0", local_port,
|
||||
this->host, remote_port, FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
if (this->ike_proposals->get_count(this->ike_proposals))
|
||||
{
|
||||
while (this->ike_proposals->remove_first(this->ike_proposals,
|
||||
|
|
|
@ -381,8 +381,8 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
|
|||
NMSettingVpn *vpn;
|
||||
enumerator_t *enumerator;
|
||||
identification_t *user = NULL, *gateway = NULL;
|
||||
const char *address, *str;
|
||||
bool virtual, encap, proposal;
|
||||
const char *str;
|
||||
bool virtual, proposal;
|
||||
proposal_t *prop;
|
||||
ike_cfg_t *ike_cfg;
|
||||
peer_cfg_t *peer_cfg;
|
||||
|
@ -394,6 +394,13 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
|
|||
certificate_t *cert = NULL;
|
||||
x509_t *x509;
|
||||
bool agent = FALSE, smartcard = FALSE, loose_gateway_id = FALSE;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "%any",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.fragmentation = FRAGMENTATION_YES,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_SEND_IF_ASKED,
|
||||
.unique = UNIQUE_REPLACE,
|
||||
|
@ -430,8 +437,8 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
|
|||
priv->name);
|
||||
DBG4(DBG_CFG, "%s",
|
||||
nm_setting_to_string(NM_SETTING(vpn)));
|
||||
address = nm_setting_vpn_get_data_item(vpn, "address");
|
||||
if (!address || !*address)
|
||||
ike.remote = (char*)nm_setting_vpn_get_data_item(vpn, "address");
|
||||
if (!ike.remote || !*ike.remote)
|
||||
{
|
||||
g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
|
||||
"Gateway address missing.");
|
||||
|
@ -440,7 +447,7 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
|
|||
str = nm_setting_vpn_get_data_item(vpn, "virtual");
|
||||
virtual = streq(str, "yes");
|
||||
str = nm_setting_vpn_get_data_item(vpn, "encap");
|
||||
encap = streq(str, "yes");
|
||||
ike.force_encap = streq(str, "yes");
|
||||
str = nm_setting_vpn_get_data_item(vpn, "ipcomp");
|
||||
child.options |= streq(str, "yes") ? OPT_IPCOMP : 0;
|
||||
str = nm_setting_vpn_get_data_item(vpn, "method");
|
||||
|
@ -503,7 +510,7 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
|
|||
* of the gateway as its identity. This identity will be used for
|
||||
* certificate lookup and requires the configured IP/DNS to be
|
||||
* included in the gateway certificate. */
|
||||
gateway = identification_create_from_string((char*)address);
|
||||
gateway = identification_create_from_string(ike.remote);
|
||||
DBG1(DBG_CFG, "using CA certificate, gateway identity '%Y'", gateway);
|
||||
loose_gateway_id = TRUE;
|
||||
}
|
||||
|
@ -634,10 +641,7 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection,
|
|||
/**
|
||||
* Set up configurations
|
||||
*/
|
||||
ike_cfg = ike_cfg_create(IKEV2, TRUE, encap, "%any",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
(char*)address, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_YES, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
|
||||
str = nm_setting_vpn_get_data_item(vpn, "proposal");
|
||||
proposal = streq(str, "yes");
|
||||
|
|
|
@ -107,14 +107,21 @@ static ike_cfg_t *load_ike_config(private_config_t *this,
|
|||
ike_cfg_t *ike_cfg;
|
||||
proposal_t *proposal;
|
||||
char *token;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = settings->get_str(settings, "configs.%s.lhost",
|
||||
"%any", config),
|
||||
.local_port = settings->get_int(settings, "configs.%s.lport",
|
||||
500, config),
|
||||
.remote = settings->get_str(settings, "configs.%s.rhost",
|
||||
"%any", config),
|
||||
.remote_port = settings->get_int(settings, "configs.%s.rport",
|
||||
500, config),
|
||||
.force_encap = settings->get_bool(settings, "configs.%s.fake_nat",
|
||||
FALSE, config),
|
||||
};
|
||||
|
||||
ike_cfg = ike_cfg_create(IKEV2, TRUE,
|
||||
settings->get_bool(settings, "configs.%s.fake_nat", FALSE, config),
|
||||
settings->get_str(settings, "configs.%s.lhost", "%any", config),
|
||||
settings->get_int(settings, "configs.%s.lport", 500, config),
|
||||
settings->get_str(settings, "configs.%s.rhost", "%any", config),
|
||||
settings->get_int(settings, "configs.%s.rport", 500, config),
|
||||
FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
token = settings->get_str(settings, "configs.%s.proposal", NULL, config);
|
||||
if (token)
|
||||
{
|
||||
|
|
|
@ -742,6 +742,13 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||
proposal_t *proposal;
|
||||
ike_sa_t *ike_sa;
|
||||
auth_cfg_t *auth;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.foce_encap = TRUE,
|
||||
.fragmentation = FRAGMENTATION_YES,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_ALWAYS_SEND,
|
||||
.unique = UNIQUE_REPLACE,
|
||||
|
@ -761,23 +768,20 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||
.dpd_action = ACTION_RESTART,
|
||||
.close_action = ACTION_RESTART,
|
||||
};
|
||||
char *type, *server, *remote_id;
|
||||
int port;
|
||||
bool certreq;
|
||||
char *type, *remote_id;
|
||||
|
||||
if (android_sdk_version >= ANDROID_LOLLIPOP)
|
||||
{ /* only try once and notify the GUI on Android 5+ where we have a blocking TUN device */
|
||||
peer.keyingtries = 1;
|
||||
}
|
||||
|
||||
server = this->settings->get_str(this->settings, "connection.server", NULL);
|
||||
port = this->settings->get_int(this->settings, "connection.port",
|
||||
IKEV2_UDP_PORT);
|
||||
certreq = this->settings->get_bool(this->settings, "connection.certreq",
|
||||
TRUE);
|
||||
ike_cfg = ike_cfg_create(IKEV2, certreq, TRUE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
server, port, FRAGMENTATION_YES, 0);
|
||||
ike.remote = this->settings->get_str(this->settings, "connection.server",
|
||||
NULL);
|
||||
ike.remote_port = this->settings->get_int(this->settings, "connection.port",
|
||||
IKEV2_UDP_PORT);
|
||||
ike.no_certreq = !this->settings->get_bool(this->settings,
|
||||
"connection.certreq", TRUE);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
proposal = parse_proposal(this, PROTO_IKE, "connection.ike_proposal");
|
||||
if (proposal)
|
||||
{
|
||||
|
|
|
@ -78,6 +78,14 @@ static peer_cfg_t* create_peer_cfg(char *name, char *host)
|
|||
ike_cfg_t *ike_cfg;
|
||||
peer_cfg_t *peer_cfg;
|
||||
uint16_t local_port, remote_port = IKEV2_UDP_PORT;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.remote = host,
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
.fragmentation = FRAGMENTATION_YES,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_SEND_IF_ASKED,
|
||||
.unique = UNIQUE_REPLACE,
|
||||
|
@ -88,13 +96,12 @@ static peer_cfg_t* create_peer_cfg(char *name, char *host)
|
|||
.dpd = 30,
|
||||
};
|
||||
|
||||
local_port = charon->socket->get_port(charon->socket, FALSE);
|
||||
if (local_port != IKEV2_UDP_PORT)
|
||||
ike.local_port = charon->socket->get_port(charon->socket, FALSE);
|
||||
if (ike.local_port != IKEV2_UDP_PORT)
|
||||
{
|
||||
remote_port = IKEV2_NATT_PORT;
|
||||
ike.remote_port = IKEV2_NATT_PORT;
|
||||
}
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0", local_port,
|
||||
host, remote_port, FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
|
||||
peer_cfg = peer_cfg_create(name, ike_cfg, &peer);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2018 Tobias Brunner
|
||||
* Copyright (C) 2012-2019 Tobias Brunner
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -101,10 +101,15 @@ struct private_ike_cfg_t {
|
|||
bool force_encap;
|
||||
|
||||
/**
|
||||
* use IKEv1 fragmentation
|
||||
* use IKE fragmentation
|
||||
*/
|
||||
fragmentation_t fragmentation;
|
||||
|
||||
/**
|
||||
* childless IKE_SAs
|
||||
*/
|
||||
childless_t childless;
|
||||
|
||||
/**
|
||||
* DSCP value to use on sent IKE packets
|
||||
*/
|
||||
|
@ -140,6 +145,12 @@ METHOD(ike_cfg_t, fragmentation, fragmentation_t,
|
|||
return this->fragmentation;
|
||||
}
|
||||
|
||||
METHOD(ike_cfg_t, childless, childless_t,
|
||||
private_ike_cfg_t *this)
|
||||
{
|
||||
return this->childless;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common function for resolve_me/other
|
||||
*/
|
||||
|
@ -424,6 +435,7 @@ METHOD(ike_cfg_t, equals, bool,
|
|||
this->certreq == other->certreq &&
|
||||
this->force_encap == other->force_encap &&
|
||||
this->fragmentation == other->fragmentation &&
|
||||
this->childless == other->childless &&
|
||||
streq(this->me, other->me) &&
|
||||
streq(this->other, other->other) &&
|
||||
this->my_port == other->my_port &&
|
||||
|
@ -609,13 +621,10 @@ bool ike_cfg_has_address(ike_cfg_t *cfg, host_t *addr, bool local)
|
|||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
|
||||
char *me, uint16_t my_port,
|
||||
char *other, uint16_t other_port,
|
||||
fragmentation_t fragmentation, uint8_t dscp)
|
||||
ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data)
|
||||
{
|
||||
private_ike_cfg_t *this;
|
||||
|
||||
|
@ -625,6 +634,7 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
|
|||
.send_certreq = _send_certreq,
|
||||
.force_encap = _force_encap_,
|
||||
.fragmentation = _fragmentation,
|
||||
.childless = _childless,
|
||||
.resolve_me = _resolve_me,
|
||||
.resolve_other = _resolve_other,
|
||||
.match_me = _match_me,
|
||||
|
@ -644,24 +654,25 @@ ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.refcount = 1,
|
||||
.version = version,
|
||||
.certreq = certreq,
|
||||
.force_encap = force_encap,
|
||||
.fragmentation = fragmentation,
|
||||
.me = strdup(me),
|
||||
.version = data->version,
|
||||
.certreq = !data->no_certreq,
|
||||
.force_encap = data->force_encap,
|
||||
.fragmentation = data->fragmentation,
|
||||
.childless = data->childless,
|
||||
.me = strdup(data->local),
|
||||
.my_ranges = linked_list_create(),
|
||||
.my_hosts = linked_list_create(),
|
||||
.other = strdup(other),
|
||||
.other = strdup(data->remote),
|
||||
.other_ranges = linked_list_create(),
|
||||
.other_hosts = linked_list_create(),
|
||||
.my_port = my_port,
|
||||
.other_port = other_port,
|
||||
.dscp = dscp,
|
||||
.my_port = data->local_port,
|
||||
.other_port = data->remote_port,
|
||||
.dscp = data->dscp,
|
||||
.proposals = linked_list_create(),
|
||||
);
|
||||
|
||||
parse_addresses(me, this->my_hosts, this->my_ranges);
|
||||
parse_addresses(other, this->other_hosts, this->other_ranges);
|
||||
parse_addresses(data->local, this->my_hosts, this->my_ranges);
|
||||
parse_addresses(data->remote, this->other_hosts, this->other_ranges);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2018 Tobias Brunner
|
||||
* Copyright (C) 2012-2019 Tobias Brunner
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -25,7 +25,9 @@
|
|||
|
||||
typedef enum ike_version_t ike_version_t;
|
||||
typedef enum fragmentation_t fragmentation_t;
|
||||
typedef enum childless_t childless_t;
|
||||
typedef struct ike_cfg_t ike_cfg_t;
|
||||
typedef struct ike_cfg_create_t ike_cfg_create_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <networking/host.h>
|
||||
|
@ -60,6 +62,18 @@ enum fragmentation_t {
|
|||
FRAGMENTATION_FORCE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Childless IKE_SAs (RFC 6023)
|
||||
*/
|
||||
enum childless_t {
|
||||
/** Allow childless IKE_SAs as responder, but initiate regular IKE_SAs */
|
||||
CHILDLESS_ALLOW,
|
||||
/** Don't accept childless IKE_SAs as responder, don't initiate them */
|
||||
CHILDLESS_NEVER,
|
||||
/** Only accept the creation of childless IKE_SAs (also as responder) */
|
||||
CHILDLESS_FORCE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum strings for ike_version_t
|
||||
*/
|
||||
|
@ -203,12 +217,19 @@ struct ike_cfg_t {
|
|||
bool (*force_encap) (ike_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Use proprietary IKEv1 fragmentation
|
||||
* Use IKE fragmentation
|
||||
*
|
||||
* @return TRUE to use fragmentation
|
||||
*/
|
||||
fragmentation_t (*fragmentation) (ike_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Whether to initiate/accept childless IKE_SAs
|
||||
*
|
||||
* @return initiate/accept childless IKE_SAs
|
||||
*/
|
||||
childless_t (*childless)(ike_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get the DH group to use for IKE_SA setup.
|
||||
*
|
||||
|
@ -241,30 +262,43 @@ struct ike_cfg_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates a ike_cfg_t object.
|
||||
* Data passed to the constructor of an ike_cfg_t object.
|
||||
*
|
||||
* Supplied hosts become owned by ike_cfg, strings get cloned.
|
||||
* local and remote are comma separated lists of IP addresses, DNS names,
|
||||
* IP ranges or subnets. When initiating, the first non-range/subnet address is
|
||||
* used as address. When responding, a match is performed against all items in
|
||||
* the list.
|
||||
*/
|
||||
struct ike_cfg_create_t {
|
||||
/** IKE major version to use for this config */
|
||||
ike_version_t version;
|
||||
/** Address/DNS name of local peer (cloned) */
|
||||
char *local;
|
||||
/** IKE port to use as source, 500 uses IKEv2 port floating */
|
||||
uint16_t local_port;
|
||||
/** Address/DNS name of remote peer (cloned) */
|
||||
char *remote;
|
||||
/** IKE port to use as dest, 500 uses IKEv2 port floating */
|
||||
uint16_t remote_port;
|
||||
/** TRUE to not send any certificate requests */
|
||||
bool no_certreq;
|
||||
/** Enforce UDP encapsulation by faking NATD notify */
|
||||
bool force_encap;
|
||||
/** Use IKE fragmentation */
|
||||
fragmentation_t fragmentation;
|
||||
/** Childless IKE_SA configuration */
|
||||
childless_t childless;
|
||||
/** DSCP value to send IKE packets with */
|
||||
uint8_t dscp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an ike_cfg_t object.
|
||||
*
|
||||
* me and other are comma separated lists of IP addresses, DNS names, IP ranges
|
||||
* or subnets. When initiating, the first non-range/subnet address is used
|
||||
* as address. When responding, a match is performed against all items in the
|
||||
* list.
|
||||
*
|
||||
* @param version IKE major version to use for this config
|
||||
* @param certreq TRUE to send a certificate request
|
||||
* @param force_encap enforce UDP encapsulation by faking NATD notify
|
||||
* @param me address/DNS name of local peer
|
||||
* @param my_port IKE port to use as source, 500 uses IKEv2 port floating
|
||||
* @param other address/DNS name of remote peer
|
||||
* @param other_port IKE port to use as dest, 500 uses IKEv2 port floating
|
||||
* @param fragmentation use IKEv1 fragmentation
|
||||
* @param dscp DSCP value to send IKE packets with
|
||||
* @param data data for this ike_cfg
|
||||
* @return ike_cfg_t object.
|
||||
*/
|
||||
ike_cfg_t *ike_cfg_create(ike_version_t version, bool certreq, bool force_encap,
|
||||
char *me, uint16_t my_port,
|
||||
char *other, uint16_t other_port,
|
||||
fragmentation_t fragmentation, uint8_t dscp);
|
||||
ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data);
|
||||
|
||||
/**
|
||||
* Determine the address family of the local or remote address(es). If multiple
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2015 Tobias Brunner
|
||||
* Copyright (C) 2011-2019 Tobias Brunner
|
||||
* Copyright (C) 2007-2011 Martin Willi
|
||||
* Copyright (C) 2011 revosec AG
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -265,19 +265,24 @@ METHOD(listener_t, ike_state_change, bool,
|
|||
{
|
||||
switch (state)
|
||||
{
|
||||
#ifdef ME
|
||||
case IKE_ESTABLISHED:
|
||||
{ /* mediation connections are complete without CHILD_SA */
|
||||
{
|
||||
#ifdef ME
|
||||
peer_cfg_t *peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
||||
|
||||
if (peer_cfg->is_mediation(peer_cfg))
|
||||
#endif /* ME */
|
||||
/* we're done if we didn't initiate a CHILD_SA */
|
||||
if (!this->child_cfg
|
||||
#ifdef ME
|
||||
/* the same is always true for mediation connections */
|
||||
|| peer_cfg->is_mediation(peer_cfg)
|
||||
#endif /* ME */
|
||||
)
|
||||
{
|
||||
this->status = SUCCESS;
|
||||
return listener_done(this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* ME */
|
||||
case IKE_DESTROYING:
|
||||
return listener_done(this);
|
||||
default:
|
||||
|
@ -414,7 +419,7 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||
peer_cfg);
|
||||
if (!ike_sa)
|
||||
{
|
||||
listener->child_cfg->destroy(listener->child_cfg);
|
||||
DESTROY_IF(listener->child_cfg);
|
||||
peer_cfg->destroy(peer_cfg);
|
||||
listener->status = FAILED;
|
||||
listener_done(listener);
|
||||
|
@ -446,7 +451,7 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||
"%d exceeds limit of %d", half_open, limit_half_open);
|
||||
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
||||
ike_sa);
|
||||
listener->child_cfg->destroy(listener->child_cfg);
|
||||
DESTROY_IF(listener->child_cfg);
|
||||
listener->status = INVALID_STATE;
|
||||
listener_done(listener);
|
||||
return JOB_REQUEUE_NONE;
|
||||
|
@ -465,7 +470,7 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||
"limit of %d", jobs, limit_job_load);
|
||||
charon->ike_sa_manager->checkin_and_destroy(
|
||||
charon->ike_sa_manager, ike_sa);
|
||||
listener->child_cfg->destroy(listener->child_cfg);
|
||||
DESTROY_IF(listener->child_cfg);
|
||||
listener->status = INVALID_STATE;
|
||||
listener_done(listener);
|
||||
return JOB_REQUEUE_NONE;
|
||||
|
|
|
@ -78,7 +78,7 @@ struct controller_t {
|
|||
* until the IKE_SA is established or failed.
|
||||
*
|
||||
* @param peer_cfg peer_cfg to use for IKE_SA setup
|
||||
* @param child_cfg child_cfg to set up CHILD_SA from
|
||||
* @param child_cfg optional child_cfg to set up CHILD_SA from
|
||||
* @param cb logging callback
|
||||
* @param param parameter to include in each call of cb
|
||||
* @param timeout timeout in ms to wait for callbacks, 0 to disable
|
||||
|
|
|
@ -190,6 +190,14 @@ static void setup_tunnel(private_ha_tunnel_t *this,
|
|||
auth_cfg_t *auth_cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
traffic_selector_t *ts;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = local,
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote = remote,
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_NEVER_SEND,
|
||||
.unique = UNIQUE_KEEP,
|
||||
|
@ -222,9 +230,7 @@ static void setup_tunnel(private_ha_tunnel_t *this,
|
|||
lib->credmgr->add_set(lib->credmgr, &this->creds.public);
|
||||
|
||||
/* create config and backend */
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
|
||||
peer_cfg = peer_cfg_create(HA_CFG_NAME, ike_cfg, &peer);
|
||||
|
|
|
@ -686,8 +686,12 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
|||
ike_cfg_t *ike_cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
peer_cfg_t *peer_cfg;
|
||||
char local[32], *remote;
|
||||
char local[32];
|
||||
host_t *addr;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = this->version,
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_SEND_IF_ASKED,
|
||||
.unique = UNIQUE_NO,
|
||||
|
@ -726,28 +730,25 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
|||
{
|
||||
snprintf(local, sizeof(local), "%s", this->initiator);
|
||||
}
|
||||
remote = this->responder;
|
||||
ike.remote = this->responder;
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(local, sizeof(local), "%s", this->responder);
|
||||
remote = this->initiator;
|
||||
ike.remote = this->initiator;
|
||||
}
|
||||
|
||||
ike.local = local;
|
||||
if (this->port && num)
|
||||
{
|
||||
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE,
|
||||
local, this->port + num - 1,
|
||||
remote, IKEV2_NATT_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
ike.local_port = this->port + num - 1;
|
||||
ike.remote_port = IKEV2_NATT_PORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ike_cfg = ike_cfg_create(this->version, TRUE, FALSE, local,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
ike.local_port = charon->socket->get_port(charon->socket, FALSE);
|
||||
}
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
|
||||
peer_cfg = peer_cfg_create("load-test", ike_cfg, &peer);
|
||||
|
||||
|
|
|
@ -87,9 +87,15 @@ static peer_cfg_t *build_mediation_config(private_medcli_config_t *this,
|
|||
auth_cfg_t *auth;
|
||||
ike_cfg_t *ike_cfg;
|
||||
peer_cfg_t *med_cfg;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
};
|
||||
peer_cfg_create_t peer = *defaults;
|
||||
chunk_t me, other;
|
||||
char *address;
|
||||
|
||||
/* query mediation server config:
|
||||
* - build ike_cfg/peer_cfg for mediation connection on-the-fly
|
||||
|
@ -98,14 +104,12 @@ static peer_cfg_t *build_mediation_config(private_medcli_config_t *this,
|
|||
"SELECT Address, ClientConfig.KeyId, MediationServerConfig.KeyId "
|
||||
"FROM MediationServerConfig JOIN ClientConfig",
|
||||
DB_TEXT, DB_BLOB, DB_BLOB);
|
||||
if (!e || !e->enumerate(e, &address, &me, &other))
|
||||
if (!e || !e->enumerate(e, &ike.remote, &me, &other))
|
||||
{
|
||||
DESTROY_IF(e);
|
||||
return NULL;
|
||||
}
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
address, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE));
|
||||
|
||||
|
@ -397,6 +401,14 @@ METHOD(medcli_config_t, destroy, void,
|
|||
medcli_config_t *medcli_config_create(database_t *db)
|
||||
{
|
||||
private_medcli_config_t *this;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote = "0.0.0.0",
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
};
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
|
@ -410,10 +422,7 @@ medcli_config_t *medcli_config_create(database_t *db)
|
|||
.db = db,
|
||||
.rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200),
|
||||
.dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300),
|
||||
.ike = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
"0.0.0.0", IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0),
|
||||
.ike = ike_cfg_create(&ike),
|
||||
);
|
||||
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
||||
this->ike->add_proposal(this->ike, proposal_create_default_aead(PROTO_IKE));
|
||||
|
|
|
@ -130,6 +130,14 @@ METHOD(medsrv_config_t, destroy, void,
|
|||
medsrv_config_t *medsrv_config_create(database_t *db)
|
||||
{
|
||||
private_medsrv_config_t *this;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote = "0.0.0.0",
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
};
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
|
@ -143,10 +151,7 @@ medsrv_config_t *medsrv_config_create(database_t *db)
|
|||
.db = db,
|
||||
.rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200),
|
||||
.dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300),
|
||||
.ike = ike_cfg_create(IKEV2, FALSE, FALSE, "0.0.0.0",
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
"0.0.0.0", IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0),
|
||||
.ike = ike_cfg_create(&ike),
|
||||
);
|
||||
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
||||
this->ike->add_proposal(this->ike, proposal_create_default_aead(PROTO_IKE));
|
||||
|
|
|
@ -272,10 +272,18 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
|
|||
while (e->enumerate(e, &id, &certreq, &force_encap, &local, &remote))
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = local,
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote = remote,
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = !certreq,
|
||||
.force_encap = force_encap,
|
||||
.fragmentation = FRAGMENTATION_YES,
|
||||
};
|
||||
|
||||
ike_cfg = ike_cfg_create(IKEV2, certreq, force_encap, local,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
add_ike_proposals(this, ike_cfg, id);
|
||||
return ike_cfg;
|
||||
}
|
||||
|
|
|
@ -260,36 +260,40 @@ static void swap_ends(stroke_msg_t *msg)
|
|||
*/
|
||||
static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
|
||||
{
|
||||
ike_cfg_create_t ike;
|
||||
ike_cfg_t *ike_cfg;
|
||||
uint16_t ikeport;
|
||||
char me[256], other[256];
|
||||
|
||||
swap_ends(msg);
|
||||
|
||||
ike = (ike_cfg_create_t){
|
||||
.version = msg->add_conn.version,
|
||||
.local = msg->add_conn.me.address,
|
||||
.local_port = msg->add_conn.me.ikeport,
|
||||
.remote = msg->add_conn.other.address,
|
||||
.remote_port = msg->add_conn.other.ikeport,
|
||||
.no_certreq = msg->add_conn.other.sendcert == CERT_NEVER_SEND,
|
||||
.force_encap = msg->add_conn.force_encap,
|
||||
.fragmentation = msg->add_conn.fragmentation,
|
||||
.dscp = msg->add_conn.ikedscp,
|
||||
};
|
||||
if (msg->add_conn.me.allow_any)
|
||||
{
|
||||
snprintf(me, sizeof(me), "%s,0.0.0.0/0,::/0",
|
||||
msg->add_conn.me.address);
|
||||
ike.local = me;
|
||||
}
|
||||
if (msg->add_conn.other.allow_any)
|
||||
{
|
||||
snprintf(other, sizeof(other), "%s,0.0.0.0/0,::/0",
|
||||
msg->add_conn.other.address);
|
||||
ike.remote = other;
|
||||
}
|
||||
ikeport = msg->add_conn.me.ikeport;
|
||||
ikeport = (ikeport == IKEV2_UDP_PORT) ?
|
||||
charon->socket->get_port(charon->socket, FALSE) : ikeport;
|
||||
ike_cfg = ike_cfg_create(msg->add_conn.version,
|
||||
msg->add_conn.other.sendcert != CERT_NEVER_SEND,
|
||||
msg->add_conn.force_encap,
|
||||
msg->add_conn.me.allow_any ?
|
||||
me : msg->add_conn.me.address,
|
||||
ikeport,
|
||||
msg->add_conn.other.allow_any ?
|
||||
other : msg->add_conn.other.address,
|
||||
msg->add_conn.other.ikeport,
|
||||
msg->add_conn.fragmentation,
|
||||
msg->add_conn.ikedscp);
|
||||
if (ike.local_port == IKEV2_UDP_PORT)
|
||||
{
|
||||
ike.local_port = charon->socket->get_port(charon->socket, FALSE);
|
||||
}
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
|
||||
if (!add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg,
|
||||
NULL, PROTO_IKE))
|
||||
|
|
|
@ -121,12 +121,19 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
|||
peer_enumerator_t *this, va_list args)
|
||||
{
|
||||
char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey;
|
||||
char *local_id, *local_addr, *local_net;
|
||||
char *remote_id, *remote_addr, *remote_net;
|
||||
char *local_id, *local_net, *remote_id, *remote_net;
|
||||
peer_cfg_t **cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
ike_cfg_t *ike_cfg;
|
||||
auth_cfg_t *auth;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote = "0.0.0.0",
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
};
|
||||
peer_cfg_create_t peer = {
|
||||
.cert_policy = CERT_SEND_IF_ASKED,
|
||||
.unique = UNIQUE_NO,
|
||||
|
@ -152,8 +159,6 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
|||
name = "unnamed";
|
||||
local_id = NULL;
|
||||
remote_id = NULL;
|
||||
local_addr = "0.0.0.0";
|
||||
remote_addr = "0.0.0.0";
|
||||
local_net = NULL;
|
||||
remote_net = NULL;
|
||||
ike_proposal = NULL;
|
||||
|
@ -162,14 +167,12 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
|||
esp_rekey = NULL;
|
||||
|
||||
if (this->inner->enumerate(this->inner, &name, &local_id, &remote_id,
|
||||
&local_addr, &remote_addr, &local_net, &remote_net,
|
||||
&ike.local, &ike.remote, &local_net, &remote_net,
|
||||
&ike_proposal, &esp_proposal, &ike_rekey, &esp_rekey))
|
||||
{
|
||||
|
||||
DESTROY_IF(this->peer_cfg);
|
||||
ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local_addr,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote_addr, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
|
||||
peer.rekey_time = create_rekey(ike_rekey);
|
||||
this->peer_cfg = peer_cfg_create(name, ike_cfg, &peer);
|
||||
|
@ -248,23 +251,26 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool,
|
|||
ike_enumerator_t *this, va_list args)
|
||||
{
|
||||
ike_cfg_t **cfg;
|
||||
char *local_addr, *remote_addr, *ike_proposal;
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "0.0.0.0",
|
||||
.local_port = charon->socket->get_port(charon->socket, FALSE),
|
||||
.remote = "0.0.0.0",
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
.no_certreq = TRUE,
|
||||
};
|
||||
char *ike_proposal;
|
||||
|
||||
VA_ARGS_VGET(args, cfg);
|
||||
|
||||
/* defaults */
|
||||
local_addr = "0.0.0.0";
|
||||
remote_addr = "0.0.0.0";
|
||||
ike_proposal = NULL;
|
||||
|
||||
if (this->inner->enumerate(this->inner, NULL,
|
||||
&local_addr, &remote_addr, &ike_proposal))
|
||||
&ike.local, &ike.remote, &ike_proposal))
|
||||
{
|
||||
DESTROY_IF(this->ike_cfg);
|
||||
this->ike_cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local_addr,
|
||||
charon->socket->get_port(charon->socket, FALSE),
|
||||
remote_addr, IKEV2_UDP_PORT,
|
||||
FRAGMENTATION_NO, 0);
|
||||
this->ike_cfg = ike_cfg_create(&ike);
|
||||
this->ike_cfg->add_proposal(this->ike_cfg,
|
||||
create_proposal(ike_proposal, PROTO_IKE));
|
||||
|
||||
|
|
|
@ -258,7 +258,7 @@ Initiates an SA while streaming _control-log_ events.
|
|||
|
||||
{
|
||||
child = <CHILD_SA configuration name to initiate>
|
||||
ike = <optional IKE_SA configuration name to find child under>
|
||||
ike = <IKE_SA configuration name to initiate or to find child under>
|
||||
timeout = <timeout in ms before returning>
|
||||
init-limits = <whether limits may prevent initiating the CHILD_SA>
|
||||
loglevel = <loglevel to issue "control-log" events for>
|
||||
|
|
|
@ -310,6 +310,7 @@ typedef struct {
|
|||
uint64_t dpd_delay;
|
||||
uint64_t dpd_timeout;
|
||||
fragmentation_t fragmentation;
|
||||
childless_t childless;
|
||||
unique_policy_t unique;
|
||||
uint32_t keyingtries;
|
||||
uint32_t local_port;
|
||||
|
@ -416,6 +417,7 @@ static void log_peer_data(peer_data_t *data)
|
|||
DBG2(DBG_CFG, " dpd_delay = %llu", data->dpd_delay);
|
||||
DBG2(DBG_CFG, " dpd_timeout = %llu", data->dpd_timeout);
|
||||
DBG2(DBG_CFG, " fragmentation = %u", data->fragmentation);
|
||||
DBG2(DBG_CFG, " childless = %u", data->childless);
|
||||
DBG2(DBG_CFG, " unique = %N", unique_policy_names, data->unique);
|
||||
DBG2(DBG_CFG, " keyingtries = %u", data->keyingtries);
|
||||
DBG2(DBG_CFG, " reauth_time = %llu", data->reauth_time);
|
||||
|
@ -1561,6 +1563,27 @@ CALLBACK(parse_frag, bool,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a childless_t
|
||||
*/
|
||||
CALLBACK(parse_childless, bool,
|
||||
childless_t *out, chunk_t v)
|
||||
{
|
||||
enum_map_t map[] = {
|
||||
{ "allow", CHILDLESS_ALLOW },
|
||||
{ "never", CHILDLESS_NEVER },
|
||||
{ "force", CHILDLESS_FORCE },
|
||||
};
|
||||
int d;
|
||||
|
||||
if (parse_map(map, countof(map), &d, v))
|
||||
{
|
||||
*out = d;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a cert_policy_t
|
||||
*/
|
||||
|
@ -1777,6 +1800,7 @@ CALLBACK(peer_kv, bool,
|
|||
{ "dpd_delay", parse_time, &peer->dpd_delay },
|
||||
{ "dpd_timeout", parse_time, &peer->dpd_timeout },
|
||||
{ "fragmentation", parse_frag, &peer->fragmentation },
|
||||
{ "childless", parse_childless, &peer->childless },
|
||||
{ "send_certreq", parse_bool, &peer->send_certreq },
|
||||
{ "send_cert", parse_send_cert, &peer->send_cert },
|
||||
{ "keyingtries", parse_uint32, &peer->keyingtries },
|
||||
|
@ -2382,6 +2406,7 @@ CALLBACK(config_sn, bool,
|
|||
enumerator_t *enumerator;
|
||||
peer_cfg_create_t cfg;
|
||||
peer_cfg_t *peer_cfg;
|
||||
ike_cfg_create_t ike;
|
||||
ike_cfg_t *ike_cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
auth_data_t *auth;
|
||||
|
@ -2509,10 +2534,19 @@ CALLBACK(config_sn, bool,
|
|||
|
||||
log_peer_data(&peer);
|
||||
|
||||
ike_cfg = ike_cfg_create(peer.version, peer.send_certreq, peer.encap,
|
||||
peer.local_addrs, peer.local_port,
|
||||
peer.remote_addrs, peer.remote_port,
|
||||
peer.fragmentation, peer.dscp);
|
||||
ike = (ike_cfg_create_t){
|
||||
.version = peer.version,
|
||||
.local = peer.local_addrs,
|
||||
.local_port = peer.local_port,
|
||||
.remote = peer.remote_addrs,
|
||||
.remote_port = peer.remote_port,
|
||||
.no_certreq = !peer.send_certreq,
|
||||
.force_encap = peer.encap,
|
||||
.fragmentation = peer.fragmentation,
|
||||
.childless = peer.childless,
|
||||
.dscp = peer.dscp,
|
||||
};
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
|
||||
cfg = (peer_cfg_create_t){
|
||||
.cert_policy = peer.send_cert,
|
||||
|
|
|
@ -138,7 +138,7 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
|
|||
}
|
||||
|
||||
/**
|
||||
* Find a peer/child config from a child config name
|
||||
* Find a peer/child config from a config name
|
||||
*/
|
||||
static child_cfg_t* find_child_cfg(char *name, char *pname, peer_cfg_t **out)
|
||||
{
|
||||
|
@ -154,6 +154,11 @@ static child_cfg_t* find_child_cfg(char *name, char *pname, peer_cfg_t **out)
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (!name)
|
||||
{
|
||||
*out = peer_cfg->get_ref(peer_cfg);
|
||||
break;
|
||||
}
|
||||
child_cfg = get_child_from_peer(peer_cfg, name);
|
||||
if (child_cfg)
|
||||
{
|
||||
|
@ -169,9 +174,9 @@ static child_cfg_t* find_child_cfg(char *name, char *pname, peer_cfg_t **out)
|
|||
CALLBACK(initiate, vici_message_t*,
|
||||
private_vici_control_t *this, char *name, u_int id, vici_message_t *request)
|
||||
{
|
||||
child_cfg_t *child_cfg = NULL;
|
||||
peer_cfg_t *peer_cfg;
|
||||
char *child, *ike;
|
||||
peer_cfg_t *peer_cfg = NULL;
|
||||
child_cfg_t *child_cfg;
|
||||
char *child, *ike, *type, *sa;
|
||||
int timeout;
|
||||
bool limits;
|
||||
controller_cb_t log_cb = NULL;
|
||||
|
@ -186,7 +191,7 @@ CALLBACK(initiate, vici_message_t*,
|
|||
limits = request->get_bool(request, FALSE, "init-limits");
|
||||
log.level = request->get_int(request, 1, "loglevel");
|
||||
|
||||
if (!child)
|
||||
if (!child && !ike)
|
||||
{
|
||||
return send_reply(this, "missing configuration name");
|
||||
}
|
||||
|
@ -195,12 +200,15 @@ CALLBACK(initiate, vici_message_t*,
|
|||
log_cb = (controller_cb_t)log_vici;
|
||||
}
|
||||
|
||||
DBG1(DBG_CFG, "vici initiate '%s'", child);
|
||||
type = child ? "CHILD_SA" : "IKE_SA";
|
||||
sa = child ?: ike;
|
||||
|
||||
child_cfg = find_child_cfg(child, ike, &peer_cfg);
|
||||
if (!child_cfg)
|
||||
|
||||
DBG1(DBG_CFG, "vici initiate %s '%s'", type, sa);
|
||||
if (!peer_cfg)
|
||||
{
|
||||
return send_reply(this, "CHILD_SA config '%s' not found", child);
|
||||
return send_reply(this, "%s config '%s' not found", type, sa);
|
||||
}
|
||||
switch (charon->controller->initiate(charon->controller, peer_cfg,
|
||||
child_cfg, log_cb, &log, timeout, limits))
|
||||
|
@ -208,14 +216,14 @@ CALLBACK(initiate, vici_message_t*,
|
|||
case SUCCESS:
|
||||
return send_reply(this, NULL);
|
||||
case OUT_OF_RES:
|
||||
return send_reply(this, "CHILD_SA '%s' not established after %dms",
|
||||
child, timeout);
|
||||
return send_reply(this, "%s '%s' not established after %dms", type,
|
||||
sa, timeout);
|
||||
case INVALID_STATE:
|
||||
return send_reply(this, "establishing CHILD_SA '%s' not possible "
|
||||
"at the moment due to limits", child);
|
||||
return send_reply(this, "establishing %s '%s' not possible at the "
|
||||
"moment due to limits", type, sa);
|
||||
case FAILED:
|
||||
default:
|
||||
return send_reply(this, "establishing CHILD_SA '%s' failed", child);
|
||||
return send_reply(this, "establishing %s '%s' failed", type, sa);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -161,6 +161,11 @@ enum ike_extension_t {
|
|||
* Postquantum Preshared Keys, draft-ietf-ipsecme-qr-ikev2
|
||||
*/
|
||||
EXT_PPK = (1<<15),
|
||||
|
||||
/**
|
||||
* Responder accepts childless IKE_SAs, RFC 6023
|
||||
*/
|
||||
EXT_IKE_CHILDLESS = (1<<16),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1037,6 +1037,31 @@ static void process_payloads(private_child_create_t *this, message_t *message)
|
|||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we should defer the creation of this CHILD_SA until after the
|
||||
* IKE_SA has been established childless.
|
||||
*/
|
||||
static status_t defer_child_sa(private_child_create_t *this)
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
|
||||
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
|
||||
|
||||
if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_CHILDLESS))
|
||||
{
|
||||
if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
|
||||
{
|
||||
return NEED_MORE;
|
||||
}
|
||||
}
|
||||
else if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
|
||||
{
|
||||
DBG1(DBG_IKE, "peer does not support childless IKE_SA initiation");
|
||||
return DESTROY_ME;
|
||||
}
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
METHOD(task_t, build_i, status_t,
|
||||
private_child_create_t *this, message_t *message)
|
||||
{
|
||||
|
@ -1067,6 +1092,19 @@ METHOD(task_t, build_i, status_t,
|
|||
/* send only in the first request, not in subsequent rounds */
|
||||
return NEED_MORE;
|
||||
}
|
||||
switch (defer_child_sa(this))
|
||||
{
|
||||
case DESTROY_ME:
|
||||
/* config mismatch */
|
||||
return DESTROY_ME;
|
||||
case NEED_MORE:
|
||||
/* defer until after IKE_SA has been established */
|
||||
chunk_free(&this->my_nonce);
|
||||
return NEED_MORE;
|
||||
default:
|
||||
/* just continue to establish the CHILD_SA */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1312,6 +1350,37 @@ static child_cfg_t* select_child_cfg(private_child_create_t *this)
|
|||
return child_cfg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check how to handle a possibly childless IKE_SA
|
||||
*/
|
||||
static status_t handle_childless(private_child_create_t *this)
|
||||
{
|
||||
ike_cfg_t *ike_cfg;
|
||||
|
||||
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
|
||||
|
||||
if (!this->proposals && !this->tsi && !this->tsr)
|
||||
{
|
||||
/* looks like a childless IKE_SA, check if we allow it */
|
||||
if (ike_cfg->childless(ike_cfg) == CHILDLESS_NEVER)
|
||||
{
|
||||
/* we don't allow childless initiation */
|
||||
DBG1(DBG_IKE, "peer tried to initiate a childless IKE_SA");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* the peer apparently wants to create a regular IKE_SA */
|
||||
if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
|
||||
{
|
||||
/* reject it if we only allow childless initiation */
|
||||
DBG1(DBG_IKE, "peer did not initiate a childless IKE_SA");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
METHOD(task_t, build_r, status_t,
|
||||
private_child_create_t *this, message_t *message)
|
||||
{
|
||||
|
@ -1348,6 +1417,19 @@ METHOD(task_t, build_r, status_t,
|
|||
{ /* no CHILD_SA is created for redirected SAs */
|
||||
return SUCCESS;
|
||||
}
|
||||
switch (handle_childless(this))
|
||||
{
|
||||
case SUCCESS:
|
||||
/* no CHILD_SA built */
|
||||
return SUCCESS;
|
||||
case INVALID_STATE:
|
||||
message->add_notify(message, FALSE, INVALID_SYNTAX,
|
||||
chunk_empty);
|
||||
return FAILED;
|
||||
default:
|
||||
/* continue with regular initiation */
|
||||
break;
|
||||
}
|
||||
ike_auth = TRUE;
|
||||
default:
|
||||
break;
|
||||
|
@ -1533,6 +1615,11 @@ METHOD(task_t, process_i, status_t,
|
|||
{ /* wait until all authentication round completed */
|
||||
return NEED_MORE;
|
||||
}
|
||||
if (defer_child_sa(this) == NEED_MORE)
|
||||
{ /* defer until after IKE_SA has been established */
|
||||
chunk_free(&this->other_nonce);
|
||||
return NEED_MORE;
|
||||
}
|
||||
ike_auth = TRUE;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2008-2018 Tobias Brunner
|
||||
* Copyright (C) 2008-2019 Tobias Brunner
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
|
@ -433,6 +433,13 @@ static bool build_payloads(private_ike_init_t *this, message_t *message)
|
|||
{
|
||||
message->add_notify(message, FALSE, USE_PPK, chunk_empty);
|
||||
}
|
||||
/* notify the peer if we accept childless IKE_SAs */
|
||||
if (!this->old_sa && !this->initiator &&
|
||||
ike_cfg->childless(ike_cfg) != CHILDLESS_NEVER)
|
||||
{
|
||||
message->add_notify(message, FALSE, CHILDLESS_IKEV2_SUPPORTED,
|
||||
chunk_empty);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -578,6 +585,13 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
|
|||
EXT_IKE_REDIRECTION);
|
||||
}
|
||||
break;
|
||||
case CHILDLESS_IKEV2_SUPPORTED:
|
||||
if (this->initiator && !this->old_sa)
|
||||
{
|
||||
this->ike_sa->enable_extension(this->ike_sa,
|
||||
EXT_IKE_CHILDLESS);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other notifies are handled elsewhere */
|
||||
break;
|
||||
|
|
|
@ -31,6 +31,7 @@ exchange_tests_SOURCES = \
|
|||
suites/test_ike_delete.c \
|
||||
suites/test_ike_mid_sync.c \
|
||||
suites/test_ike_rekey.c \
|
||||
suites/test_childless.c \
|
||||
utils/exchange_test_asserts.h utils/exchange_test_asserts.c \
|
||||
utils/exchange_test_helper.h utils/exchange_test_helper.c \
|
||||
utils/job_asserts.h \
|
||||
|
|
|
@ -19,3 +19,4 @@ TEST_SUITE(ike_rekey_suite_create)
|
|||
TEST_SUITE(child_create_suite_create)
|
||||
TEST_SUITE(child_delete_suite_create)
|
||||
TEST_SUITE(child_rekey_suite_create)
|
||||
TEST_SUITE(childless_suite_create)
|
||||
|
|
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Tobias Brunner
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "test_suite.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <tests/utils/exchange_test_helper.h>
|
||||
#include <tests/utils/exchange_test_asserts.h>
|
||||
#include <tests/utils/sa_asserts.h>
|
||||
|
||||
/**
|
||||
* Childless initiation of the IKE_SA. The first CHILD_SA is automatically
|
||||
* initiated in a separate CREATE_CHILD_SA exchange including DH.
|
||||
*/
|
||||
START_TEST(test_regular)
|
||||
{
|
||||
exchange_test_sa_conf_t conf = {
|
||||
.initiator = {
|
||||
.childless = CHILDLESS_FORCE,
|
||||
.esp = "aes128-sha256-modp3072",
|
||||
},
|
||||
.responder = {
|
||||
.esp = "aes128-sha256-modp3072",
|
||||
},
|
||||
};
|
||||
ike_sa_t *a, *b;
|
||||
ike_sa_id_t *id_a, *id_b;
|
||||
child_cfg_t *child_cfg;
|
||||
|
||||
child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b,
|
||||
&conf);
|
||||
id_a = a->get_id(a);
|
||||
id_b = b->get_id(b);
|
||||
|
||||
call_ikesa(a, initiate, child_cfg, 0, NULL, NULL);
|
||||
|
||||
/* IKE_SA_INIT --> */
|
||||
id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a));
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
/* <-- IKE_SA_INIT */
|
||||
assert_notify(IN, CHILDLESS_IKEV2_SUPPORTED);
|
||||
id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b));
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
|
||||
/* IKE_AUTH --> */
|
||||
assert_hook_not_called(child_updown);
|
||||
assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION);
|
||||
assert_no_payload(IN, PLV2_TS_INITIATOR);
|
||||
assert_no_payload(IN, PLV2_TS_RESPONDER);
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
|
||||
/* <-- IKE_AUTH */
|
||||
assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION);
|
||||
assert_no_payload(IN, PLV2_TS_INITIATOR);
|
||||
assert_no_payload(IN, PLV2_TS_RESPONDER);
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
assert_child_sa_count(a, 0);
|
||||
assert_child_sa_count(b, 0);
|
||||
assert_hook();
|
||||
|
||||
/* CREATE_CHILD_SA { SA, Ni, KEi, TSi, TSr } --> */
|
||||
assert_hook_called(child_updown);
|
||||
assert_payload(IN, PLV2_KEY_EXCHANGE);
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
assert_child_sa_count(b, 1);
|
||||
assert_hook();
|
||||
|
||||
/* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
|
||||
assert_hook_called(child_updown);
|
||||
assert_payload(IN, PLV2_KEY_EXCHANGE);
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
assert_child_sa_count(a, 1);
|
||||
assert_hook();
|
||||
|
||||
assert_sa_idle(a);
|
||||
assert_sa_idle(b);
|
||||
|
||||
call_ikesa(a, destroy);
|
||||
call_ikesa(b, destroy);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
* Childless initiation of the IKE_SA, no CHILD_SA created automatically.
|
||||
* It's created with a separate initiation and exchange afterwards.
|
||||
*/
|
||||
START_TEST(test_regular_manual)
|
||||
{
|
||||
exchange_test_sa_conf_t conf = {
|
||||
.initiator = {
|
||||
.esp = "aes128-sha256-modp3072",
|
||||
},
|
||||
.responder = {
|
||||
.esp = "aes128-sha256-modp3072",
|
||||
},
|
||||
};
|
||||
ike_sa_t *a, *b;
|
||||
ike_sa_id_t *id_a, *id_b;
|
||||
child_cfg_t *child_cfg;
|
||||
|
||||
child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b,
|
||||
&conf);
|
||||
id_a = a->get_id(a);
|
||||
id_b = b->get_id(b);
|
||||
|
||||
call_ikesa(a, initiate, NULL, 0, NULL, NULL);
|
||||
|
||||
/* IKE_SA_INIT --> */
|
||||
id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a));
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
/* <-- IKE_SA_INIT */
|
||||
assert_notify(IN, CHILDLESS_IKEV2_SUPPORTED);
|
||||
id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b));
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
|
||||
/* IKE_AUTH --> */
|
||||
assert_hook_not_called(child_updown);
|
||||
assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION);
|
||||
assert_no_payload(IN, PLV2_TS_INITIATOR);
|
||||
assert_no_payload(IN, PLV2_TS_RESPONDER);
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
|
||||
/* <-- IKE_AUTH */
|
||||
assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION);
|
||||
assert_no_payload(IN, PLV2_TS_INITIATOR);
|
||||
assert_no_payload(IN, PLV2_TS_RESPONDER);
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
assert_child_sa_count(a, 0);
|
||||
assert_child_sa_count(b, 0);
|
||||
assert_hook();
|
||||
|
||||
assert_sa_idle(a);
|
||||
assert_sa_idle(b);
|
||||
|
||||
call_ikesa(a, initiate, child_cfg, 0, NULL, NULL);
|
||||
|
||||
/* CREATE_CHILD_SA { SA, Ni, KEi, TSi, TSr } --> */
|
||||
assert_hook_called(child_updown);
|
||||
assert_payload(IN, PLV2_KEY_EXCHANGE);
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
assert_child_sa_count(b, 1);
|
||||
assert_hook();
|
||||
|
||||
/* <-- CREATE_CHILD_SA { SA, Ni, KEi } */
|
||||
assert_hook_called(child_updown);
|
||||
assert_payload(IN, PLV2_KEY_EXCHANGE);
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
assert_child_sa_count(a, 1);
|
||||
assert_hook();
|
||||
|
||||
assert_sa_idle(a);
|
||||
assert_sa_idle(b);
|
||||
|
||||
call_ikesa(a, destroy);
|
||||
call_ikesa(b, destroy);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
* The initiator aborts the initiation once it notices the responder does not
|
||||
* support childless IKE_SAs.
|
||||
*/
|
||||
START_TEST(test_failure_init)
|
||||
{
|
||||
exchange_test_sa_conf_t conf = {
|
||||
.initiator = {
|
||||
.childless = CHILDLESS_FORCE,
|
||||
},
|
||||
.responder = {
|
||||
.childless = CHILDLESS_NEVER,
|
||||
},
|
||||
};
|
||||
ike_sa_t *a, *b;
|
||||
ike_sa_id_t *id_a, *id_b;
|
||||
child_cfg_t *child_cfg;
|
||||
status_t status;
|
||||
|
||||
child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b,
|
||||
&conf);
|
||||
id_a = a->get_id(a);
|
||||
id_b = b->get_id(b);
|
||||
|
||||
call_ikesa(a, initiate, child_cfg, 0, NULL, NULL);
|
||||
|
||||
/* IKE_SA_INIT --> */
|
||||
id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a));
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
/* <-- IKE_SA_INIT */
|
||||
assert_no_notify(IN, CHILDLESS_IKEV2_SUPPORTED);
|
||||
id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b));
|
||||
status = exchange_test_helper->process_message(exchange_test_helper, a,
|
||||
NULL);
|
||||
ck_assert_int_eq(DESTROY_ME, status);
|
||||
|
||||
call_ikesa(a, destroy);
|
||||
call_ikesa(b, destroy);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
* The responder aborts the initiation once it notices the initiator does not
|
||||
* create a childless IKE_SA.
|
||||
*/
|
||||
START_TEST(test_failure_resp)
|
||||
{
|
||||
exchange_test_sa_conf_t conf = {
|
||||
.initiator = {
|
||||
.childless = CHILDLESS_NEVER,
|
||||
},
|
||||
.responder = {
|
||||
.childless = CHILDLESS_FORCE,
|
||||
},
|
||||
};
|
||||
ike_sa_t *a, *b;
|
||||
ike_sa_id_t *id_a, *id_b;
|
||||
child_cfg_t *child_cfg;
|
||||
status_t status;
|
||||
|
||||
child_cfg = exchange_test_helper->create_sa(exchange_test_helper, &a, &b,
|
||||
&conf);
|
||||
id_a = a->get_id(a);
|
||||
id_b = b->get_id(b);
|
||||
|
||||
call_ikesa(a, initiate, child_cfg, 0, NULL, NULL);
|
||||
|
||||
/* IKE_SA_INIT --> */
|
||||
id_b->set_initiator_spi(id_b, id_a->get_initiator_spi(id_a));
|
||||
exchange_test_helper->process_message(exchange_test_helper, b, NULL);
|
||||
/* <-- IKE_SA_INIT */
|
||||
assert_notify(IN, CHILDLESS_IKEV2_SUPPORTED);
|
||||
id_a->set_responder_spi(id_a, id_b->get_responder_spi(id_b));
|
||||
exchange_test_helper->process_message(exchange_test_helper, a, NULL);
|
||||
|
||||
/* IKE_AUTH --> */
|
||||
assert_hook_not_called(child_updown);
|
||||
assert_payload(IN, PLV2_SECURITY_ASSOCIATION);
|
||||
assert_payload(IN, PLV2_TS_INITIATOR);
|
||||
assert_payload(IN, PLV2_TS_RESPONDER);
|
||||
status = exchange_test_helper->process_message(exchange_test_helper, b,
|
||||
NULL);
|
||||
ck_assert_int_eq(DESTROY_ME, status);
|
||||
assert_hook();
|
||||
|
||||
/* <-- IKE_AUTH */
|
||||
assert_hook_not_called(child_updown);
|
||||
assert_no_payload(IN, PLV2_SECURITY_ASSOCIATION);
|
||||
assert_no_payload(IN, PLV2_TS_INITIATOR);
|
||||
assert_no_payload(IN, PLV2_TS_RESPONDER);
|
||||
assert_notify(IN, INVALID_SYNTAX);
|
||||
status = exchange_test_helper->process_message(exchange_test_helper, a,
|
||||
NULL);
|
||||
ck_assert_int_eq(DESTROY_ME, status);
|
||||
assert_hook();
|
||||
|
||||
assert_sa_idle(a);
|
||||
assert_sa_idle(b);
|
||||
|
||||
call_ikesa(a, destroy);
|
||||
call_ikesa(b, destroy);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *childless_suite_create()
|
||||
{
|
||||
Suite *s;
|
||||
TCase *tc;
|
||||
|
||||
s = suite_create("childless");
|
||||
|
||||
tc = tcase_create("initiation");
|
||||
tcase_add_test(tc, test_regular);
|
||||
tcase_add_test(tc, test_regular_manual);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("failure");
|
||||
tcase_add_test(tc, test_failure_init);
|
||||
tcase_add_test(tc, test_failure_resp);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
|
@ -19,11 +19,17 @@
|
|||
|
||||
static void assert_family(int expected, char *addr, bool local)
|
||||
{
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = local ? addr : "%any",
|
||||
.local_port = 500,
|
||||
.remote = local ? "%any" : addr,
|
||||
.remote_port = 500,
|
||||
};
|
||||
ike_cfg_t *cfg;
|
||||
int family;
|
||||
|
||||
cfg = ike_cfg_create(IKEV2, FALSE, FALSE, local ? addr : "%any", 500,
|
||||
local ? "%any" : addr, 500, FRAGMENTATION_NO, 0);
|
||||
cfg = ike_cfg_create(&ike);
|
||||
family = ike_cfg_get_family(cfg, local);
|
||||
ck_assert_msg(expected == family, "expected family %d != %d (addr: '%s')",
|
||||
expected, family, addr);
|
||||
|
|
|
@ -23,8 +23,14 @@
|
|||
*/
|
||||
static ike_cfg_t *create_ike_cfg()
|
||||
{
|
||||
return ike_cfg_create(IKEV2, TRUE, FALSE, "127.0.0.1", 500,
|
||||
"127.0.0.1", 500, FRAGMENTATION_NO, 0);
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "127.0.0.1",
|
||||
.local_port = 500,
|
||||
.remote = "127.0.0.1",
|
||||
.remote_port = 500,
|
||||
};
|
||||
return ike_cfg_create(&ike);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -297,6 +297,26 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa,
|
|||
#define assert_single_payload(dir, expected) \
|
||||
_assert_payload(#dir, 1, { TRUE, expected, 0 })
|
||||
|
||||
/**
|
||||
* Assert that the next in- or outbound plaintext message contains a payload
|
||||
* of the given type.
|
||||
*
|
||||
* @param dir IN or OUT to check the next in- or outbound message
|
||||
* @param expected expected payload type
|
||||
*/
|
||||
#define assert_payload(dir, expected) \
|
||||
_assert_payload(#dir, -1, { TRUE, expected, 0 })
|
||||
|
||||
/**
|
||||
* Assert that the next in- or outbound plaintext message contains no payload
|
||||
* of the given type.
|
||||
*
|
||||
* @param dir IN or OUT to check the next in- or outbound message
|
||||
* @param unexpected not expected payload type
|
||||
*/
|
||||
#define assert_no_payload(dir, unexpected) \
|
||||
_assert_payload(#dir, -1, { FALSE, unexpected, 0 })
|
||||
|
||||
/**
|
||||
* Assert that the next in- or outbound plaintext message contains exactly
|
||||
* one notify of the given type.
|
||||
|
|
|
@ -49,6 +49,11 @@ struct private_exchange_test_helper_t {
|
|||
* List of registered listeners
|
||||
*/
|
||||
array_t *listeners;
|
||||
|
||||
/**
|
||||
* Config backend
|
||||
*/
|
||||
private_backend_t *backend;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -85,15 +90,24 @@ exchange_test_helper_t *exchange_test_helper;
|
|||
|
||||
static ike_cfg_t *create_ike_cfg(bool initiator, exchange_test_sa_conf_t *conf)
|
||||
{
|
||||
ike_cfg_create_t ike = {
|
||||
.version = IKEV2,
|
||||
.local = "127.0.0.1",
|
||||
.local_port = IKEV2_UDP_PORT,
|
||||
.remote = "127.0.0.1",
|
||||
.remote_port = IKEV2_UDP_PORT,
|
||||
};
|
||||
ike_cfg_t *ike_cfg;
|
||||
char *proposal = NULL;
|
||||
|
||||
ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "127.0.0.1", IKEV2_UDP_PORT,
|
||||
"127.0.0.1", IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
if (conf)
|
||||
{
|
||||
ike.childless = initiator ? conf->initiator.childless
|
||||
: conf->responder.childless;
|
||||
proposal = initiator ? conf->initiator.ike : conf->responder.ike;
|
||||
}
|
||||
|
||||
ike_cfg = ike_cfg_create(&ike);
|
||||
if (proposal)
|
||||
{
|
||||
ike_cfg->add_proposal(ike_cfg,
|
||||
|
@ -180,6 +194,18 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
return enumerator_create_single(this->peer_cfg, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config objects provided by the backend
|
||||
*/
|
||||
static void set_config(private_backend_t *this, ike_cfg_t *ike,
|
||||
peer_cfg_t *peer)
|
||||
{
|
||||
DESTROY_IF(this->ike_cfg);
|
||||
this->ike_cfg = ike;
|
||||
DESTROY_IF(this->peer_cfg);
|
||||
this->peer_cfg = peer;
|
||||
}
|
||||
|
||||
METHOD(exchange_test_helper_t, process_message, status_t,
|
||||
private_exchange_test_helper_t *this, ike_sa_t *ike_sa, message_t *message)
|
||||
{
|
||||
|
@ -204,43 +230,50 @@ METHOD(exchange_test_helper_t, process_message, status_t,
|
|||
return status;
|
||||
}
|
||||
|
||||
METHOD(exchange_test_helper_t, establish_sa, void,
|
||||
METHOD(exchange_test_helper_t, create_sa, child_cfg_t*,
|
||||
private_exchange_test_helper_t *this, ike_sa_t **init, ike_sa_t **resp,
|
||||
exchange_test_sa_conf_t *conf)
|
||||
{
|
||||
private_backend_t backend = {
|
||||
.public = {
|
||||
.create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
|
||||
.create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
|
||||
.get_peer_cfg_by_name = (void*)return_null,
|
||||
},
|
||||
};
|
||||
ike_sa_id_t *id_i, *id_r;
|
||||
ike_sa_t *sa_i, *sa_r;
|
||||
peer_cfg_t *peer_cfg;
|
||||
child_cfg_t *child_cfg;
|
||||
|
||||
sa_i = *init = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
||||
IKEV2, TRUE);
|
||||
id_i = sa_i->get_id(sa_i);
|
||||
*init = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
||||
IKEV2, TRUE);
|
||||
|
||||
sa_r = *resp = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
||||
IKEV2, FALSE);
|
||||
id_r = sa_r->get_id(sa_r);
|
||||
*resp = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager,
|
||||
IKEV2, FALSE);
|
||||
|
||||
peer_cfg = create_peer_cfg(FALSE, conf);
|
||||
child_cfg = create_child_cfg(FALSE, conf);
|
||||
peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
|
||||
child_cfg->destroy(child_cfg);
|
||||
set_config(this->backend, create_ike_cfg(FALSE, conf), peer_cfg);
|
||||
|
||||
peer_cfg = create_peer_cfg(TRUE, conf);
|
||||
child_cfg = create_child_cfg(TRUE, conf);
|
||||
peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
|
||||
sa_i->set_peer_cfg(sa_i, peer_cfg);
|
||||
(*init)->set_peer_cfg(*init, peer_cfg);
|
||||
peer_cfg->destroy(peer_cfg);
|
||||
call_ikesa(sa_i, initiate, child_cfg, 0, NULL, NULL);
|
||||
return child_cfg;
|
||||
}
|
||||
|
||||
backend.ike_cfg = create_ike_cfg(FALSE, conf);
|
||||
peer_cfg = backend.peer_cfg = create_peer_cfg(FALSE, conf);
|
||||
child_cfg = create_child_cfg(FALSE, conf);
|
||||
peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
|
||||
child_cfg->destroy(child_cfg);
|
||||
charon->backends->add_backend(charon->backends, &backend.public);
|
||||
METHOD(exchange_test_helper_t, establish_sa, void,
|
||||
private_exchange_test_helper_t *this, ike_sa_t **init, ike_sa_t **resp,
|
||||
exchange_test_sa_conf_t *conf)
|
||||
{
|
||||
ike_sa_id_t *id_i, *id_r;
|
||||
ike_sa_t *sa_i, *sa_r;
|
||||
child_cfg_t *child_i;
|
||||
|
||||
child_i = create_sa(this, init, resp, conf);
|
||||
|
||||
sa_i = *init;
|
||||
sa_r = *resp;
|
||||
|
||||
id_i = sa_i->get_id(sa_i);
|
||||
id_r = sa_r->get_id(sa_r);
|
||||
|
||||
call_ikesa(sa_i, initiate, child_i, 0, NULL, NULL);
|
||||
|
||||
/* IKE_SA_INIT --> */
|
||||
id_r->set_initiator_spi(id_r, id_i->get_initiator_spi(id_i));
|
||||
|
@ -252,10 +285,6 @@ METHOD(exchange_test_helper_t, establish_sa, void,
|
|||
process_message(this, sa_r, NULL);
|
||||
/* <-- IKE_AUTH */
|
||||
process_message(this, sa_i, NULL);
|
||||
|
||||
charon->backends->remove_backend(charon->backends, &backend.public);
|
||||
DESTROY_IF(backend.peer_cfg);
|
||||
DESTROY_IF(backend.ike_cfg);
|
||||
}
|
||||
|
||||
METHOD(exchange_test_helper_t, add_listener, void,
|
||||
|
@ -300,6 +329,7 @@ static nonce_gen_t *create_nonce_gen()
|
|||
void exchange_test_helper_init(char *plugins)
|
||||
{
|
||||
private_exchange_test_helper_t *this;
|
||||
private_backend_t *backend;
|
||||
plugin_feature_t features[] = {
|
||||
PLUGIN_REGISTER(DH, mock_dh_create),
|
||||
/* we only need to support a limited number of DH groups */
|
||||
|
@ -311,14 +341,24 @@ void exchange_test_helper_init(char *plugins)
|
|||
PLUGIN_DEPENDS(RNG, RNG_WEAK),
|
||||
};
|
||||
|
||||
INIT(backend,
|
||||
.public = {
|
||||
.create_ike_cfg_enumerator = _create_ike_cfg_enumerator,
|
||||
.create_peer_cfg_enumerator = _create_peer_cfg_enumerator,
|
||||
.get_peer_cfg_by_name = (void*)return_null,
|
||||
},
|
||||
);
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.sender = mock_sender_create(),
|
||||
.establish_sa = _establish_sa,
|
||||
.create_sa = _create_sa,
|
||||
.process_message = _process_message,
|
||||
.add_listener = _add_listener,
|
||||
},
|
||||
.creds = mem_cred_create(),
|
||||
.backend = backend,
|
||||
);
|
||||
|
||||
initialize_logging();
|
||||
|
@ -339,6 +379,8 @@ void exchange_test_helper_init(char *plugins)
|
|||
charon->ike_sa_manager->set_spi_cb(charon->ike_sa_manager, get_ike_spi,
|
||||
this);
|
||||
|
||||
charon->backends->add_backend(charon->backends, &backend->public);
|
||||
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||
|
||||
this->creds->add_shared(this->creds,
|
||||
|
@ -362,6 +404,9 @@ void exchange_test_helper_deinit()
|
|||
{
|
||||
charon->bus->remove_listener(charon->bus, listener);
|
||||
}
|
||||
charon->backends->remove_backend(charon->backends, &this->backend->public);
|
||||
set_config(this->backend, NULL, NULL);
|
||||
free(this->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->creds->destroy(this->creds);
|
||||
/* flush SAs before destroying the sender (in case of test failures) */
|
||||
|
|
|
@ -57,6 +57,23 @@ struct exchange_test_helper_t {
|
|||
void (*establish_sa)(exchange_test_helper_t *this, ike_sa_t **init,
|
||||
ike_sa_t **resp, exchange_test_sa_conf_t *conf);
|
||||
|
||||
/**
|
||||
* Similar to establish_sa() but does only create the SA and config
|
||||
* objects, no exchanges are initiated/handled. The returned child_cfg
|
||||
* object is that created for the initiator to be used for a call to
|
||||
* initiate(). The config objects for the responder are managed and
|
||||
* provided by an internal config backend.
|
||||
*
|
||||
* Note that the responder SPIs are not yet set.
|
||||
*
|
||||
* @param[out] init IKE_SA of the initiator
|
||||
* @param[out] resp IKE_SA of the responder
|
||||
* @param conf configuration for SAs
|
||||
* @return child_cfg for the initiator
|
||||
*/
|
||||
child_cfg_t *(*create_sa)(exchange_test_helper_t *this, ike_sa_t **init,
|
||||
ike_sa_t **resp, exchange_test_sa_conf_t *conf);
|
||||
|
||||
/**
|
||||
* Pass a message to the given IKE_SA for processing, setting the IKE_SA on
|
||||
* the bus while processing the message.
|
||||
|
@ -92,6 +109,8 @@ struct exchange_test_sa_conf_t {
|
|||
char *ike;
|
||||
/** ESP proposal */
|
||||
char *esp;
|
||||
/** Support for childless IKE_SAs */
|
||||
childless_t childless;
|
||||
} initiator, responder;
|
||||
};
|
||||
|
||||
|
|
|
@ -128,11 +128,11 @@ static void __attribute__ ((constructor))reg()
|
|||
{
|
||||
command_register((command_t) {
|
||||
initiate, 'i', "initiate", "initiate a connection",
|
||||
{"--child <name> [--ike <name>] [--timeout <s>] [--raw|--pretty]"},
|
||||
{"[--child <name>] [--ike <name>] [--timeout <s>] [--raw|--pretty]"},
|
||||
{
|
||||
{"help", 'h', 0, "show usage information"},
|
||||
{"child", 'c', 1, "initiate a CHILD_SA configuration"},
|
||||
{"ike", 'i', 1, "name of the connection to which the child belongs"},
|
||||
{"ike", 'i', 1, "initiate an IKE_SA, or name of child's parent"},
|
||||
{"timeout", 't', 1, "timeout in seconds before detaching"},
|
||||
{"raw", 'r', 0, "dump raw response message"},
|
||||
{"pretty", 'P', 0, "dump raw response message in pretty print"},
|
||||
|
|
|
@ -154,7 +154,7 @@ connections.<conn>.dpd_timeout = 0s
|
|||
specified; this option has no effect on connections using IKE2.
|
||||
|
||||
connections.<conn>.fragmentation = yes
|
||||
Use IKE UDP datagram fragmentation. (_yes_, _accept_, _no_ or _force_).
|
||||
Use IKE UDP datagram fragmentation (_yes_, _accept_, _no_ or _force_).
|
||||
|
||||
Use IKE fragmentation (proprietary IKEv1 extension or RFC 7383 IKEv2
|
||||
fragmentation). Acceptable values are _yes_ (the default), _accept_,
|
||||
|
@ -168,6 +168,21 @@ connections.<conn>.fragmentation = yes
|
|||
Note that fragmented IKE messages sent by a peer are always accepted
|
||||
irrespective of the value of this option (even when set to _no_).
|
||||
|
||||
connections.<conn>.childless = allow
|
||||
Use childless IKE_SA initiation (_allow_, _force_ or _never_).
|
||||
|
||||
Use childless IKE_SA initiation (RFC 6023) for IKEv2. Acceptable values
|
||||
are _allow_ (the default), _force_ and _never_. If set to _allow_,
|
||||
responders will accept childless IKE_SAs (as indicated via notify in the
|
||||
IKE_SA_INIT response) while initiators continue to create regular IKE_SAs
|
||||
with the first CHILD_SA created during IKE_AUTH, unless the IKE_SA is
|
||||
initiated explicitly without any children (which will fail if the responder
|
||||
does not support or has disabled this extension). If set to _force_, only
|
||||
childless initiation is accepted and the first CHILD_SA is created with a
|
||||
separate CREATE_CHILD_SA exchange (e.g. to use an independent DH exchange
|
||||
for all CHILD_SAs). Finally, setting the option to _never_ disables support
|
||||
for childless IKE_SAs as responder.
|
||||
|
||||
connections.<conn>.send_certreq = yes
|
||||
Send certificate requests payloads (_yes_ or _no_).
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b>
|
||||
is set up using childless initiation of IKEv2 SAs (RFC 6023).
|
||||
<p/>
|
||||
The IKE_SA is established without CHILD_SA during IKE_AUTH. Instead, the
|
||||
CHILD_SA is created right afterwards with a CREATE_CHILD_SA exchange, allowing
|
||||
the use of a separate DH exchange for the first CHILD_SA, which is not possible
|
||||
if it is created during IKE_AUTH.
|
||||
<p/>
|
||||
The authentication is based on <b>X.509 certificates</b>. Upon the successful
|
||||
establishment of the IPsec tunnel, the updown script automatically
|
||||
inserts iptables-based firewall rules that let pass the tunneled traffic.
|
||||
In order to test both tunnel and firewall, client <b>alice</b> behind gateway
|
||||
<b>moon</b> pings client <b>bob</b> located behind gateway <b>sun</b>.
|
|
@ -0,0 +1,7 @@
|
|||
moon::swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=500 local-id=moon.strongswan.org remote-host=192.168.0.2 remote-port=500 remote-id=sun.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net-net.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128 dh-group=CURVE_25519.*local-ts=\[10.1.0.0/16] remote-ts=\[10.2.0.0/16]::YES
|
||||
sun:: swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.2 local-port=500 local-id=sun.strongswan.org remote-host=192.168.0.1 remote-port=500 remote-id=moon.strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=CURVE_25519.*child-sas.*net-net.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128 dh-group=CURVE_25519.*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.0/16]::YES
|
||||
moon::cat /var/log/daemon.log::generating CREATE_CHILD_SA request 2.*KE::YES
|
||||
moon::cat /var/log/daemon.log::parsed CREATE_CHILD_SA response 2.*KE::YES
|
||||
alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=1::YES
|
||||
sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
|
||||
sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
|
|
@ -0,0 +1,9 @@
|
|||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
swanctl {
|
||||
load = pem pkcs1 x509 revocation constraints pubkey openssl random
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 hmac pem pkcs1 x509 revocation curve25519 gmp curl kernel-netlink socket-default updown vici
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
connections {
|
||||
|
||||
gw-gw {
|
||||
local_addrs = 192.168.0.1
|
||||
remote_addrs = 192.168.0.2
|
||||
|
||||
childless = force
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = moonCert.pem
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = sun.strongswan.org
|
||||
}
|
||||
children {
|
||||
net-net {
|
||||
local_ts = 10.1.0.0/16
|
||||
remote_ts = 10.2.0.0/16
|
||||
|
||||
updown = /usr/local/libexec/ipsec/_updown iptables
|
||||
rekey_time = 5400
|
||||
rekey_bytes = 500000000
|
||||
rekey_packets = 1000000
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
mobike = no
|
||||
reauth_time = 10800
|
||||
proposals = aes128-sha256-x25519
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
# /etc/strongswan.conf - strongSwan configuration file
|
||||
|
||||
swanctl {
|
||||
load = pem pkcs1 x509 revocation constraints pubkey openssl random
|
||||
}
|
||||
|
||||
charon-systemd {
|
||||
load = random nonce aes sha1 sha2 hmac pem pkcs1 x509 revocation curve25519 gmp curl kernel-netlink socket-default updown vici
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
connections {
|
||||
|
||||
gw-gw {
|
||||
local_addrs = 192.168.0.2
|
||||
remote_addrs = 192.168.0.1
|
||||
|
||||
local {
|
||||
auth = pubkey
|
||||
certs = sunCert.pem
|
||||
id = sun.strongswan.org
|
||||
}
|
||||
remote {
|
||||
auth = pubkey
|
||||
id = moon.strongswan.org
|
||||
}
|
||||
children {
|
||||
net-net {
|
||||
local_ts = 10.2.0.0/16
|
||||
remote_ts = 10.1.0.0/16
|
||||
|
||||
updown = /usr/local/libexec/ipsec/_updown iptables
|
||||
rekey_time = 5400
|
||||
rekey_bytes = 500000000
|
||||
rekey_packets = 1000000
|
||||
esp_proposals = aes128gcm128-x25519
|
||||
}
|
||||
}
|
||||
version = 2
|
||||
mobike = no
|
||||
reauth_time = 10800
|
||||
proposals = aes128-sha256-x25519
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
moon::swanctl --terminate --ike gw-gw 2> /dev/null
|
||||
moon::systemctl stop strongswan-swanctl
|
||||
sun::systemctl stop strongswan-swanctl
|
||||
moon::iptables-restore < /etc/iptables.flush
|
||||
sun::iptables-restore < /etc/iptables.flush
|
|
@ -0,0 +1,7 @@
|
|||
moon::iptables-restore < /etc/iptables.rules
|
||||
sun::iptables-restore < /etc/iptables.rules
|
||||
moon::systemctl start strongswan-swanctl
|
||||
sun::systemctl start strongswan-swanctl
|
||||
moon::expect-connection gw-gw
|
||||
sun::expect-connection gw-gw
|
||||
moon::swanctl --initiate --child net-net 2> /dev/null
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This configuration file provides information on the
|
||||
# guest instances used for this test
|
||||
|
||||
# All guest instances that are required for this test
|
||||
#
|
||||
VIRTHOSTS="alice moon winnetou sun bob"
|
||||
|
||||
# Corresponding block diagram
|
||||
#
|
||||
DIAGRAM="a-m-w-s-b.png"
|
||||
|
||||
# Guest instances on which tcpdump is to be started
|
||||
#
|
||||
TCPDUMPHOSTS="sun"
|
||||
|
||||
# Guest instances on which IPsec is started
|
||||
# Used for IPsec logging purposes
|
||||
#
|
||||
IPSECHOSTS="moon sun"
|
||||
|
||||
# charon controlled by swanctl
|
||||
#
|
||||
SWANCTL=1
|
Loading…
Reference in New Issue