vici: Add support for mediation extension
This commit is contained in:
parent
ed96fe72cf
commit
f927ba975b
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2014 Martin Willi
|
||||
* Copyright (C) 2014 revosec AG
|
||||
*
|
||||
* Copyright (C) 2015-2016 Tobias Brunner
|
||||
* Copyright (C) 2015-2017 Tobias Brunner
|
||||
* Copyright (C) 2015-2016 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -318,6 +318,11 @@ typedef struct {
|
|||
uint64_t over_time;
|
||||
uint64_t rand_time;
|
||||
uint8_t dscp;
|
||||
#ifdef ME
|
||||
bool mediation;
|
||||
char *mediated_by;
|
||||
identification_t *peer_id;
|
||||
#endif /* ME */
|
||||
} peer_data_t;
|
||||
|
||||
/**
|
||||
|
@ -405,6 +410,14 @@ static void log_peer_data(peer_data_t *data)
|
|||
DBG2(DBG_CFG, " over_time = %llu", data->over_time);
|
||||
DBG2(DBG_CFG, " rand_time = %llu", data->rand_time);
|
||||
DBG2(DBG_CFG, " proposals = %#P", data->proposals);
|
||||
#ifdef ME
|
||||
DBG2(DBG_CFG, " mediation = %u", data->mediation);
|
||||
if (data->mediated_by)
|
||||
{
|
||||
DBG2(DBG_CFG, " mediated_by = %s", data->mediated_by);
|
||||
DBG2(DBG_CFG, " mediation_peer = %Y", data->peer_id);
|
||||
}
|
||||
#endif /* ME */
|
||||
|
||||
if (data->vips->get_count(data->vips))
|
||||
{
|
||||
|
@ -449,6 +462,10 @@ static void free_peer_data(peer_data_t *data)
|
|||
free(data->pools);
|
||||
free(data->local_addrs);
|
||||
free(data->remote_addrs);
|
||||
#ifdef ME
|
||||
free(data->mediated_by);
|
||||
DESTROY_IF(data->peer_id);
|
||||
#endif /* ME */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1397,6 +1414,24 @@ CALLBACK(parse_hosts, bool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef ME
|
||||
/**
|
||||
* Parse peer ID
|
||||
*/
|
||||
CALLBACK(parse_peer_id, bool,
|
||||
identification_t **out, chunk_t v)
|
||||
{
|
||||
char buf[BUF_LEN];
|
||||
|
||||
if (!vici_stringify(v, buf, sizeof(buf)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*out = identification_create_from_string(buf);
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* ME */
|
||||
|
||||
CALLBACK(cert_kv, bool,
|
||||
cert_data_t *cert, vici_message_t *message, char *name, chunk_t value)
|
||||
{
|
||||
|
@ -1531,6 +1566,11 @@ CALLBACK(peer_kv, bool,
|
|||
{ "rekey_time", parse_time, &peer->rekey_time },
|
||||
{ "over_time", parse_time, &peer->over_time },
|
||||
{ "rand_time", parse_time, &peer->rand_time },
|
||||
#ifdef ME
|
||||
{ "mediation", parse_bool, &peer->mediation },
|
||||
{ "mediated_by", parse_string, &peer->mediated_by },
|
||||
{ "mediation_peer", parse_peer_id, &peer->peer_id },
|
||||
#endif /* ME */
|
||||
};
|
||||
|
||||
return parse_rules(rules, countof(rules), name, value,
|
||||
|
@ -2260,6 +2300,42 @@ CALLBACK(config_sn, bool,
|
|||
peer.rand_time = min(peer.over_time, peer.rand_time / 2);
|
||||
}
|
||||
|
||||
#ifdef ME
|
||||
if (peer.mediation && peer.mediated_by)
|
||||
{
|
||||
DBG1(DBG_CFG, "a mediation connection cannot be a mediated connection "
|
||||
"at the same time, config discarded");
|
||||
free_peer_data(&peer);
|
||||
return FALSE;
|
||||
}
|
||||
if (peer.mediation)
|
||||
{ /* force unique connections for mediation connections */
|
||||
peer.unique = UNIQUE_REPLACE;
|
||||
}
|
||||
else if (peer.mediated_by)
|
||||
{ /* fallback to remote identity of first auth round if peer_id is not
|
||||
* given explicitly */
|
||||
auth_cfg_t *cfg;
|
||||
|
||||
if (!peer.peer_id &&
|
||||
peer.remote->get_first(peer.remote, (void**)&cfg) == SUCCESS)
|
||||
{
|
||||
peer.peer_id = cfg->get(cfg, AUTH_RULE_IDENTITY);
|
||||
if (peer.peer_id)
|
||||
{
|
||||
peer.peer_id = peer.peer_id->clone(peer.peer_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_CFG, "mediation peer missing for mediated connection, "
|
||||
"config discarded");
|
||||
free_peer_data(&peer);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ME */
|
||||
|
||||
log_peer_data(&peer);
|
||||
|
||||
ike_cfg = ike_cfg_create(peer.version, peer.send_certreq, peer.encap,
|
||||
|
@ -2281,6 +2357,14 @@ CALLBACK(config_sn, bool,
|
|||
.dpd = peer.dpd_delay,
|
||||
.dpd_timeout = peer.dpd_timeout,
|
||||
};
|
||||
#ifdef ME
|
||||
cfg.mediation = peer.mediation;
|
||||
if (peer.mediated_by)
|
||||
{
|
||||
cfg.mediated_by = peer.mediated_by;
|
||||
cfg.peer_id = peer.peer_id->clone(peer.peer_id);
|
||||
}
|
||||
#endif /* ME */
|
||||
peer_cfg = peer_cfg_create(name, ike_cfg, &cfg);
|
||||
|
||||
while (peer.local->remove_first(peer.local,
|
||||
|
|
|
@ -264,6 +264,30 @@ connections.<conn>.pools =
|
|||
other configuration attributes from. Each name references a pool by name
|
||||
from either the **pools** section or an external pool.
|
||||
|
||||
connections.<conn>.mediation = no
|
||||
Whether this connection is a mediation connection.
|
||||
|
||||
Whether this connection is a mediation connection, that is, whether this
|
||||
connection is used to mediate other connections using the IKEv2 Mediation
|
||||
Extension. Mediation connections create no CHILD_SA.
|
||||
|
||||
connections.<conn>.mediated_by =
|
||||
The name of the connection to mediate this connection through.
|
||||
|
||||
The name of the connection to mediate this connection through. If given, the
|
||||
connection will be mediated through the named mediation connection.
|
||||
The mediation connection must have **mediation** enabled.
|
||||
|
||||
connections.<conn>.mediation_peer =
|
||||
Identity under which the peer is registered at the mediation server.
|
||||
|
||||
Identity under which the peer is registered at the mediation server, that
|
||||
is, the IKE identity the other end of this connection uses as its local
|
||||
identity on its connection to the mediation server. This is the identity we
|
||||
request the mediation server to mediate us with. Only relevant on
|
||||
connections that set **mediated_by**. If it is not given, the remote IKE
|
||||
identity of the first authentication round of this connection will be used.
|
||||
|
||||
connections.<conn>.local<suffix> {}
|
||||
Section for a local authentication round.
|
||||
|
||||
|
|
Loading…
Reference in New Issue