Merge branch 'multi-vip'
Brings support for multiple virtual IPs and multiple pools in left/rigthsourceip definitions. Also introduces the new left/rightdns options to configure requested DNS server address family and respond with multiple connection specific servers.
This commit is contained in:
@@ -29,6 +29,20 @@ strongswan-5.0.1
|
||||
The plugin initially requests the first registered method or the first method
|
||||
configured with charon.plugins.eap-dynamic.preferred.
|
||||
|
||||
- The new left/rightdns options specify connection specific DNS servers to
|
||||
request/respond in IKEv2 configuration payloads or IKEv2 mode config. leftdns
|
||||
can be any (comma separated) combination of %config4 and %config6 to request
|
||||
multiple servers, both for IPv4 and IPv6. rightdns takes a list of DNS server
|
||||
IP addresses to return.
|
||||
|
||||
- The left/rightsourceip options now accept multiple addresses or pools.
|
||||
leftsourceip can be any (comma separated) combination of %config4, %config6
|
||||
or fixed IP addresses to request. rightsourceip accepts multiple explicitly
|
||||
specified or referenced named pools.
|
||||
|
||||
- Multiple connections can now share a single address pool when they use the
|
||||
same definition in one of the rightsourceip pools.
|
||||
|
||||
- The autotools build has been migrated to use a config.h header. strongSwan
|
||||
development headers will get installed during "make install" if
|
||||
--with-dev-headers has been passed to ./configure.
|
||||
|
||||
+16
-6
@@ -586,6 +586,16 @@ Comma separated list of certificate policy OIDs the peer's certificate must
|
||||
have.
|
||||
OIDs are specified using the numerical dotted representation.
|
||||
.TP
|
||||
.BR leftdns " = <servers>"
|
||||
Comma separated list of DNS server addresses to exchange as configuration
|
||||
attributes. On the initiator, a server is a fixed IPv4 / IPv6 address, or
|
||||
.B %config4
|
||||
/
|
||||
.B %config6
|
||||
to request attributes without an address. On the responder,
|
||||
only fixed IPv4 /IPv6 addresses are allowed and define DNS servers assigned
|
||||
to the client.
|
||||
.TP
|
||||
.BR leftfirewall " = yes | " no
|
||||
whether the left participant is doing forwarding-firewalling
|
||||
(including masquerading) using iptables for traffic from \fIleftsubnet\fR,
|
||||
@@ -691,19 +701,19 @@ and
|
||||
the latter meaning that the peer must send a certificate request payload in
|
||||
order to get a certificate in return.
|
||||
.TP
|
||||
.BR leftsourceip " = %config | %cfg | %modeconfig | %modecfg | <ip address>"
|
||||
The internal source IP to use in a tunnel, also known as virtual IP. If the
|
||||
value is one of the synonyms
|
||||
.BR leftsourceip " = %config4 | %config6 | <ip address>"
|
||||
Comma separated list of internal source IPs to use in a tunnel, also known as
|
||||
virtual IP. If the value is one of the synonyms
|
||||
.BR %config ,
|
||||
.BR %cfg ,
|
||||
.BR %modeconfig ,
|
||||
or
|
||||
.BR %modecfg ,
|
||||
an address is requested from the peer.
|
||||
an address (from the tunnel address family) is requested from the peer.
|
||||
.TP
|
||||
.BR rightsourceip " = %config | <network>/<netmask> | %poolname"
|
||||
The internal source IP to use in a tunnel for the remote peer. If the
|
||||
value is
|
||||
Comma separated list of internal source IPs to use in a tunnel for the remote
|
||||
peer. If the value is
|
||||
.B %config
|
||||
on the responder side, the initiator must propose an address which is then
|
||||
echoed back. Also supported are address pools expressed as
|
||||
|
||||
+12
-2
@@ -73,8 +73,12 @@
|
||||
# just the host, this will be 255.255.255.255.
|
||||
#
|
||||
# PLUTO_MY_SOURCEIP
|
||||
# if non-empty, then the source address for the route will be
|
||||
# set to this IP address.
|
||||
# PLUTO_MY_SOURCEIP4_$i
|
||||
# PLUTO_MY_SOURCEIP6_$i
|
||||
# contains IPv4/IPv6 virtual IP received from a responder,
|
||||
# $i enumerates from 1 to the number of IP per address family.
|
||||
# PLUTO_MY_SOURCEIP is a legacy variable and equals to the first
|
||||
# virtual IP, IPv4 or IPv6.
|
||||
#
|
||||
# PLUTO_MY_PROTOCOL
|
||||
# is the IP protocol that will be transported.
|
||||
@@ -128,6 +132,12 @@
|
||||
# contains the remote UDP port in the case of ESP_IN_UDP
|
||||
# encapsulation
|
||||
#
|
||||
# PLUTO_DNS4_$i
|
||||
# PLUTO_DNS6_$i
|
||||
# contains IPv4/IPv6 DNS server attribute received from a
|
||||
# responder, $i enumerates from 1 to the number of servers per
|
||||
# address family.
|
||||
#
|
||||
|
||||
# define a minimum PATH environment in case it is not set
|
||||
PATH="/sbin:/bin:/usr/sbin:/usr/bin:@sbindir@"
|
||||
|
||||
@@ -92,15 +92,17 @@ static bool enumerate_dns(enumerator_t *this,
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_nm_handler_t *this, identification_t *server, host_t *vip)
|
||||
private_nm_handler_t *this, identification_t *server, linked_list_t *vips)
|
||||
{
|
||||
if (vip && vip->get_family(vip) == AF_INET)
|
||||
{ /* no IPv6 attributes yet */
|
||||
enumerator_t *enumerator = malloc_thing(enumerator_t);
|
||||
/* enumerate DNS attribute first ... */
|
||||
enumerator->enumerate = (void*)enumerate_dns;
|
||||
enumerator->destroy = (void*)free;
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
||||
INIT(enumerator,
|
||||
/* enumerate DNS attribute first ... */
|
||||
.enumerate = (void*)enumerate_dns,
|
||||
.destroy = (void*)free,
|
||||
);
|
||||
return enumerator;
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
|
||||
@@ -507,8 +507,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
virtual ? host_create_from_string("0.0.0.0", 0) : NULL,
|
||||
NULL, FALSE, NULL, NULL); /* pool, mediation */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
if (virtual)
|
||||
{
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
}
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_class);
|
||||
auth->add(auth, AUTH_RULE_IDENTITY, user);
|
||||
|
||||
@@ -253,7 +253,7 @@ static peer_cfg_t *load_peer_config(private_config_t *this,
|
||||
ike_cfg = load_ike_config(this, settings, config);
|
||||
peer_cfg = peer_cfg_create(config, IKEV2, ike_cfg, CERT_ALWAYS_SEND,
|
||||
UNIQUE_NO, 1, 0, 0, 0, 0, FALSE, FALSE, 0, 0,
|
||||
NULL, NULL, FALSE, NULL, NULL);
|
||||
FALSE, NULL, NULL);
|
||||
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
|
||||
|
||||
@@ -80,7 +80,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_android_attr_t *this, identification_t *server, host_t *vip)
|
||||
private_android_attr_t *this, identification_t *server, linked_list_t *vips)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
||||
|
||||
@@ -235,21 +235,36 @@ static bool setup_tun_device(private_android_service_t *this,
|
||||
ike_sa_t *ike_sa, child_sa_t *child_sa)
|
||||
{
|
||||
vpnservice_builder_t *builder;
|
||||
enumerator_t *enumerator;
|
||||
bool vip_found = FALSE;
|
||||
host_t *vip;
|
||||
int tunfd;
|
||||
|
||||
DBG1(DBG_DMN, "setting up TUN device for CHILD_SA %s{%u}",
|
||||
child_sa->get_name(child_sa), child_sa->get_reqid(child_sa));
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
|
||||
if (!vip || vip->is_anyaddr(vip))
|
||||
|
||||
builder = charonservice->get_vpnservice_builder(charonservice);
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &vip))
|
||||
{
|
||||
if (!vip->is_anyaddr(vip))
|
||||
{
|
||||
if (!builder->add_address(builder, vip))
|
||||
{
|
||||
break;
|
||||
}
|
||||
vip_found = TRUE;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!vip_found)
|
||||
{
|
||||
DBG1(DBG_DMN, "setting up TUN device failed, no virtual IP found");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
builder = charonservice->get_vpnservice_builder(charonservice);
|
||||
if (!builder->add_address(builder, vip) ||
|
||||
!add_routes(builder, child_sa) ||
|
||||
if (!add_routes(builder, child_sa) ||
|
||||
!builder->set_mtu(builder, TUN_DEFAULT_MTU))
|
||||
{
|
||||
return FALSE;
|
||||
@@ -427,9 +442,8 @@ static job_requeue_t initiate(private_android_service_t *this)
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
host_create_from_string("0.0.0.0", 0) /* virt */,
|
||||
NULL, FALSE, NULL, NULL); /* pool, mediation */
|
||||
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
|
||||
|
||||
@@ -141,14 +141,14 @@ struct private_peer_cfg_t {
|
||||
u_int32_t dpd_timeout;
|
||||
|
||||
/**
|
||||
* virtual IP to use locally
|
||||
* List of virtual IPs (host_t*) to request
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
linked_list_t *vips;
|
||||
|
||||
/**
|
||||
* pool to acquire configuration attributes from
|
||||
* List of pool names to use for virtual IP lookup
|
||||
*/
|
||||
char *pool;
|
||||
linked_list_t *pools;
|
||||
|
||||
/**
|
||||
* local authentication configs (rulesets)
|
||||
@@ -409,16 +409,28 @@ METHOD(peer_cfg_t, get_dpd_timeout, u_int32_t,
|
||||
return this->dpd_timeout;
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_virtual_ip, host_t*,
|
||||
private_peer_cfg_t *this)
|
||||
METHOD(peer_cfg_t, add_virtual_ip, void,
|
||||
private_peer_cfg_t *this, host_t *vip)
|
||||
{
|
||||
return this->virtual_ip;
|
||||
this->vips->insert_last(this->vips, vip);
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_pool, char*,
|
||||
METHOD(peer_cfg_t, create_virtual_ip_enumerator, enumerator_t*,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
return this->pool;
|
||||
return this->vips->create_enumerator(this->vips);
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, add_pool, void,
|
||||
private_peer_cfg_t *this, char *name)
|
||||
{
|
||||
this->pools->insert_last(this->pools, strdup(name));
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, create_pool_enumerator, enumerator_t*,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
return this->pools->create_enumerator(this->pools);
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, add_auth_cfg, void,
|
||||
@@ -521,6 +533,10 @@ static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
|
||||
METHOD(peer_cfg_t, equals, bool,
|
||||
private_peer_cfg_t *this, private_peer_cfg_t *other)
|
||||
{
|
||||
enumerator_t *e1, *e2;
|
||||
host_t *vip1, *vip2;
|
||||
char *pool1, *pool2;
|
||||
|
||||
if (this == other)
|
||||
{
|
||||
return TRUE;
|
||||
@@ -530,6 +546,43 @@ METHOD(peer_cfg_t, equals, bool,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (this->vips->get_count(this->vips) != other->vips->get_count(other->vips))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
e1 = create_virtual_ip_enumerator(this);
|
||||
e2 = create_virtual_ip_enumerator(other);
|
||||
if (e1->enumerate(e1, &vip1) && e2->enumerate(e2, &vip2))
|
||||
{
|
||||
if (!vip1->ip_equals(vip1, vip2))
|
||||
{
|
||||
e1->destroy(e1);
|
||||
e2->destroy(e2);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
e1->destroy(e1);
|
||||
e2->destroy(e2);
|
||||
|
||||
if (this->pools->get_count(this->pools) !=
|
||||
other->pools->get_count(other->pools))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
e1 = create_pool_enumerator(this);
|
||||
e2 = create_pool_enumerator(other);
|
||||
if (e1->enumerate(e1, &pool1) && e2->enumerate(e2, &pool2))
|
||||
{
|
||||
if (!streq(pool1, pool2))
|
||||
{
|
||||
e1->destroy(e1);
|
||||
e2->destroy(e2);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
e1->destroy(e1);
|
||||
e2->destroy(e2);
|
||||
|
||||
return (
|
||||
this->ike_version == other->ike_version &&
|
||||
this->cert_policy == other->cert_policy &&
|
||||
@@ -541,11 +594,6 @@ METHOD(peer_cfg_t, equals, bool,
|
||||
this->jitter_time == other->jitter_time &&
|
||||
this->over_time == other->over_time &&
|
||||
this->dpd == other->dpd &&
|
||||
(this->virtual_ip == other->virtual_ip ||
|
||||
(this->virtual_ip && other->virtual_ip &&
|
||||
this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
|
||||
(this->pool == other->pool ||
|
||||
(this->pool && other->pool && streq(this->pool, other->pool))) &&
|
||||
auth_cfg_equal(this, other)
|
||||
#ifdef ME
|
||||
&& this->mediation == other->mediation &&
|
||||
@@ -572,18 +620,18 @@ METHOD(peer_cfg_t, destroy, void,
|
||||
this->ike_cfg->destroy(this->ike_cfg);
|
||||
this->child_cfgs->destroy_offset(this->child_cfgs,
|
||||
offsetof(child_cfg_t, destroy));
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->local_auth->destroy_offset(this->local_auth,
|
||||
offsetof(auth_cfg_t, destroy));
|
||||
this->remote_auth->destroy_offset(this->remote_auth,
|
||||
offsetof(auth_cfg_t, destroy));
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->pools->destroy_function(this->pools, free);
|
||||
#ifdef ME
|
||||
DESTROY_IF(this->mediated_by);
|
||||
DESTROY_IF(this->peer_id);
|
||||
#endif /* ME */
|
||||
this->mutex->destroy(this->mutex);
|
||||
free(this->name);
|
||||
free(this->pool);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
@@ -597,8 +645,8 @@ peer_cfg_t *peer_cfg_create(char *name, ike_version_t ike_version,
|
||||
u_int32_t rekey_time, u_int32_t reauth_time,
|
||||
u_int32_t jitter_time, u_int32_t over_time,
|
||||
bool mobike, bool aggressive, u_int32_t dpd,
|
||||
u_int32_t dpd_timeout, host_t *virtual_ip,
|
||||
char *pool, bool mediation, peer_cfg_t *mediated_by,
|
||||
u_int32_t dpd_timeout,
|
||||
bool mediation, peer_cfg_t *mediated_by,
|
||||
identification_t *peer_id)
|
||||
{
|
||||
private_peer_cfg_t *this;
|
||||
@@ -631,8 +679,10 @@ peer_cfg_t *peer_cfg_create(char *name, ike_version_t ike_version,
|
||||
.use_aggressive = _use_aggressive,
|
||||
.get_dpd = _get_dpd,
|
||||
.get_dpd_timeout = _get_dpd_timeout,
|
||||
.get_virtual_ip = _get_virtual_ip,
|
||||
.get_pool = _get_pool,
|
||||
.add_virtual_ip = _add_virtual_ip,
|
||||
.create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
|
||||
.add_pool = _add_pool,
|
||||
.create_pool_enumerator = _create_pool_enumerator,
|
||||
.add_auth_cfg = _add_auth_cfg,
|
||||
.create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
|
||||
.equals = (void*)_equals,
|
||||
@@ -660,8 +710,8 @@ peer_cfg_t *peer_cfg_create(char *name, ike_version_t ike_version,
|
||||
.aggressive = aggressive,
|
||||
.dpd = dpd,
|
||||
.dpd_timeout = dpd_timeout,
|
||||
.virtual_ip = virtual_ip,
|
||||
.pool = strdupnull(pool),
|
||||
.vips = linked_list_create(),
|
||||
.pools = linked_list_create(),
|
||||
.local_auth = linked_list_create(),
|
||||
.remote_auth = linked_list_create(),
|
||||
.refcount = 1,
|
||||
|
||||
@@ -278,23 +278,34 @@ struct peer_cfg_t {
|
||||
u_int32_t (*get_dpd_timeout) (peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get a virtual IP for the local peer.
|
||||
* Add a virtual IP to request as initiator.
|
||||
*
|
||||
* If no virtual IP should be used, NULL is returned. %any means to request
|
||||
* a virtual IP using configuration payloads. A specific address is also
|
||||
* used for a request and may be changed by the server.
|
||||
*
|
||||
* @param suggestion NULL, %any or specific
|
||||
* @return virtual IP, %any or NULL
|
||||
* @param vip virtual IP to request, may be %any or %any6
|
||||
*/
|
||||
host_t* (*get_virtual_ip) (peer_cfg_t *this);
|
||||
void (*add_virtual_ip)(peer_cfg_t *this, host_t *vip);
|
||||
|
||||
/**
|
||||
* Get the name of the pool to acquire configuration attributes from.
|
||||
* Create an enumerator over virtual IPs to request.
|
||||
*
|
||||
* @return pool name, NULL if none defined
|
||||
* The returned enumerator enumerates over IPs added with add_virtual_ip().
|
||||
*
|
||||
* @return enumerator over host_t*
|
||||
*/
|
||||
char* (*get_pool)(peer_cfg_t *this);
|
||||
enumerator_t* (*create_virtual_ip_enumerator)(peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Add a pool name this configuration uses to select virtual IPs.
|
||||
*
|
||||
* @param name pool name to use for virtual IP lookup
|
||||
*/
|
||||
void (*add_pool)(peer_cfg_t *this, char *name);
|
||||
|
||||
/**
|
||||
* Create an enumerator over pool names of this config.
|
||||
*
|
||||
* @return enumerator over char*
|
||||
*/
|
||||
enumerator_t* (*create_pool_enumerator)(peer_cfg_t *this);
|
||||
|
||||
#ifdef ME
|
||||
/**
|
||||
@@ -374,8 +385,6 @@ struct peer_cfg_t {
|
||||
* @param aggressive use/accept aggressive mode with IKEv1
|
||||
* @param dpd DPD check interval, 0 to disable
|
||||
* @param dpd_timeout DPD timeout interval (IKEv1 only), if 0 default applies
|
||||
* @param virtual_ip virtual IP for local host, or NULL
|
||||
* @param pool pool name to get configuration attributes from, or NULL
|
||||
* @param mediation TRUE if this is a mediation connection
|
||||
* @param mediated_by peer_cfg_t of the mediation connection to mediate through
|
||||
* @param peer_id ID that identifies our peer at the mediation server
|
||||
@@ -387,8 +396,8 @@ peer_cfg_t *peer_cfg_create(char *name, ike_version_t ike_version,
|
||||
u_int32_t rekey_time, u_int32_t reauth_time,
|
||||
u_int32_t jitter_time, u_int32_t over_time,
|
||||
bool mobike, bool aggressive, u_int32_t dpd,
|
||||
u_int32_t dpd_timeout, host_t *virtual_ip,
|
||||
char *pool, bool mediation, peer_cfg_t *mediated_by,
|
||||
u_int32_t dpd_timeout,
|
||||
bool mediation, peer_cfg_t *mediated_by,
|
||||
identification_t *peer_id);
|
||||
|
||||
#endif /** PEER_CFG_H_ @}*/
|
||||
|
||||
@@ -196,7 +196,7 @@ METHOD(enumerator_t, enumerate_dns, bool,
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *,
|
||||
android_handler_t *this, identification_t *id, host_t *vip)
|
||||
android_handler_t *this, identification_t *id, linked_list_t *vips)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
||||
|
||||
@@ -275,8 +275,8 @@ static job_requeue_t initiate(private_android_service_t *this)
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
host_create_from_string("0.0.0.0", 0) /* virt */,
|
||||
NULL, FALSE, NULL, NULL); /* pool, mediation */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
|
||||
|
||||
@@ -84,7 +84,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
|
||||
private_dhcp_provider_t *this, char *pool,
|
||||
identification_t *id, host_t *requested)
|
||||
{
|
||||
if (streq(pool, "dhcp"))
|
||||
if (streq(pool, "dhcp") && requested->get_family(requested) == AF_INET)
|
||||
{
|
||||
dhcp_transaction_t *transaction, *old;
|
||||
host_t *vip;
|
||||
@@ -110,7 +110,7 @@ METHOD(attribute_provider_t, release_address, bool,
|
||||
private_dhcp_provider_t *this, char *pool,
|
||||
host_t *address, identification_t *id)
|
||||
{
|
||||
if (streq(pool, "dhcp"))
|
||||
if (streq(pool, "dhcp") && address->get_family(address) == AF_INET)
|
||||
{
|
||||
dhcp_transaction_t *transaction;
|
||||
|
||||
@@ -129,18 +129,25 @@ METHOD(attribute_provider_t, release_address, bool,
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_dhcp_provider_t *this, char *pool, identification_t *id,
|
||||
host_t *vip)
|
||||
private_dhcp_provider_t *this, linked_list_t *pools, identification_t *id,
|
||||
linked_list_t *vips)
|
||||
{
|
||||
dhcp_transaction_t *transaction;
|
||||
dhcp_transaction_t *transaction = NULL;
|
||||
enumerator_t *enumerator;
|
||||
host_t *vip;
|
||||
|
||||
if (!vip)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
this->mutex->lock(this->mutex);
|
||||
transaction = this->transactions->get(this->transactions,
|
||||
(void*)hash_id_host(id, vip));
|
||||
enumerator = vips->create_enumerator(vips);
|
||||
while (enumerator->enumerate(enumerator, &vip))
|
||||
{
|
||||
transaction = this->transactions->get(this->transactions,
|
||||
(void*)hash_id_host(id, vip));
|
||||
if (transaction)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!transaction)
|
||||
{
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
@@ -149,6 +149,7 @@ static bool send_message(private_eap_radius_accounting_t *this,
|
||||
*/
|
||||
static void add_ike_sa_parameters(radius_message_t *message, ike_sa_t *ike_sa)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *vip;
|
||||
char buf[64];
|
||||
chunk_t data;
|
||||
@@ -157,17 +158,25 @@ static void add_ike_sa_parameters(radius_message_t *message, ike_sa_t *ike_sa)
|
||||
message->add(message, RAT_USER_NAME, chunk_create(buf, strlen(buf)));
|
||||
snprintf(buf, sizeof(buf), "%#H", ike_sa->get_other_host(ike_sa));
|
||||
message->add(message, RAT_CALLING_STATION_ID, chunk_create(buf, strlen(buf)));
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
|
||||
if (vip && vip->get_family(vip) == AF_INET)
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &vip))
|
||||
{
|
||||
message->add(message, RAT_FRAMED_IP_ADDRESS, vip->get_address(vip));
|
||||
}
|
||||
if (vip && vip->get_family(vip) == AF_INET6)
|
||||
{
|
||||
/* we currently assign /128 prefixes, only (reserved, length) */
|
||||
data = chunk_from_chars(0, 128);
|
||||
data = chunk_cata("cc", data, vip->get_address(vip));
|
||||
message->add(message, RAT_FRAMED_IPV6_PREFIX, data);
|
||||
switch (vip->get_family(vip))
|
||||
{
|
||||
case AF_INET:
|
||||
message->add(message, RAT_FRAMED_IP_ADDRESS,
|
||||
vip->get_address(vip));
|
||||
break;
|
||||
case AF_INET6:
|
||||
/* we currently assign /128 prefixes, only (reserved, length) */
|
||||
data = chunk_from_chars(0, 128);
|
||||
data = chunk_cata("cc", data, vip->get_address(vip));
|
||||
message->add(message, RAT_FRAMED_IPV6_PREFIX, data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -181,6 +181,12 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
|
||||
pool = get_pool(this, name);
|
||||
if (pool)
|
||||
{
|
||||
if (pool->base->get_family(pool->base) !=
|
||||
requested->get_family(requested))
|
||||
{
|
||||
this->mutex->unlock(this->mutex);
|
||||
return NULL;
|
||||
}
|
||||
for (byte = 0; byte < pool->size / 8; byte++)
|
||||
{
|
||||
if (pool->mask[byte] != 0xFF)
|
||||
|
||||
@@ -344,10 +344,10 @@ static void process_ike_update(private_ha_dispatcher_t *this,
|
||||
ike_sa->set_other_host(ike_sa, value.host->clone(value.host));
|
||||
break;
|
||||
case HA_LOCAL_VIP:
|
||||
ike_sa->set_virtual_ip(ike_sa, TRUE, value.host);
|
||||
ike_sa->add_virtual_ip(ike_sa, TRUE, value.host);
|
||||
break;
|
||||
case HA_REMOTE_VIP:
|
||||
ike_sa->set_virtual_ip(ike_sa, FALSE, value.host);
|
||||
ike_sa->add_virtual_ip(ike_sa, FALSE, value.host);
|
||||
received_vip = TRUE;
|
||||
break;
|
||||
case HA_PEER_ADDR:
|
||||
@@ -413,18 +413,24 @@ static void process_ike_update(private_ha_dispatcher_t *this,
|
||||
}
|
||||
if (received_vip)
|
||||
{
|
||||
enumerator_t *pools, *vips;
|
||||
host_t *vip;
|
||||
char *pool;
|
||||
|
||||
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
|
||||
if (peer_cfg && vip)
|
||||
if (peer_cfg)
|
||||
{
|
||||
pool = peer_cfg->get_pool(peer_cfg);
|
||||
if (pool)
|
||||
pools = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
while (pools->enumerate(pools, &pool))
|
||||
{
|
||||
this->attr->reserve(this->attr, pool, vip);
|
||||
vips = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
|
||||
while (vips->enumerate(vips, &vip))
|
||||
{
|
||||
this->attr->reserve(this->attr, pool, vip);
|
||||
}
|
||||
vips->destroy(vips);
|
||||
}
|
||||
pools->destroy(pools);
|
||||
}
|
||||
}
|
||||
if (ike_sa->get_version(ike_sa) == IKEV1)
|
||||
|
||||
@@ -241,6 +241,34 @@ METHOD(listener_t, ike_state_change, bool,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a virtual IP sync message for remote VIPs
|
||||
*/
|
||||
static void sync_vips(private_ha_ike_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
ha_message_t *m = NULL;
|
||||
enumerator_t *enumerator;
|
||||
host_t *vip;
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
|
||||
while (enumerator->enumerate(enumerator, &vip))
|
||||
{
|
||||
if (!m)
|
||||
{
|
||||
m = ha_message_create(HA_IKE_UPDATE);
|
||||
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
||||
}
|
||||
m->add_attribute(m, HA_REMOTE_VIP, vip);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (m)
|
||||
{
|
||||
this->socket->push(this->socket, m);
|
||||
this->cache->cache(this->cache, ike_sa, m);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(listener_t, message_hook, bool,
|
||||
private_ha_ike_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming, bool plain)
|
||||
@@ -276,18 +304,7 @@ METHOD(listener_t, message_hook, bool,
|
||||
{ /* After IKE_SA has been established, sync peers virtual IP.
|
||||
* We cannot sync it in the state_change hook, it is installed later.
|
||||
* TODO: where to sync local VIP? */
|
||||
ha_message_t *m;
|
||||
host_t *vip;
|
||||
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
|
||||
if (vip)
|
||||
{
|
||||
m = ha_message_create(HA_IKE_UPDATE);
|
||||
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
||||
m->add_attribute(m, HA_REMOTE_VIP, vip);
|
||||
this->socket->push(this->socket, m);
|
||||
this->cache->cache(this->cache, ike_sa, m);
|
||||
}
|
||||
sync_vips(this, ike_sa);
|
||||
}
|
||||
}
|
||||
if (!plain && ike_sa->get_version(ike_sa) == IKEV1)
|
||||
@@ -296,7 +313,6 @@ METHOD(listener_t, message_hook, bool,
|
||||
keymat_v1_t *keymat;
|
||||
u_int32_t mid;
|
||||
chunk_t iv;
|
||||
host_t *vip;
|
||||
|
||||
mid = message->get_message_id(message);
|
||||
if (mid == 0)
|
||||
@@ -313,15 +329,7 @@ METHOD(listener_t, message_hook, bool,
|
||||
}
|
||||
if (!incoming && message->get_exchange_type(message) == TRANSACTION)
|
||||
{
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
|
||||
if (vip)
|
||||
{
|
||||
m = ha_message_create(HA_IKE_UPDATE);
|
||||
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
||||
m->add_attribute(m, HA_REMOTE_VIP, vip);
|
||||
this->socket->push(this->socket, m);
|
||||
this->cache->cache(this->cache, ike_sa, m);
|
||||
}
|
||||
sync_vips(this, ike_sa);
|
||||
}
|
||||
}
|
||||
if (plain && ike_sa->get_version(ike_sa) == IKEV1 &&
|
||||
|
||||
@@ -209,7 +209,7 @@ static void setup_tunnel(private_ha_tunnel_t *this,
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
peer_cfg = peer_cfg_create("ha", IKEV2, ike_cfg, CERT_NEVER_SEND,
|
||||
UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE, 30,
|
||||
0, NULL, NULL, FALSE, NULL, NULL);
|
||||
0, FALSE, NULL, NULL);
|
||||
|
||||
auth_cfg = auth_cfg_create();
|
||||
auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
|
||||
|
||||
@@ -268,8 +268,15 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
||||
FALSE, FALSE, /* mobike, aggressive mode */
|
||||
this->dpd_delay, /* dpd_delay */
|
||||
this->dpd_timeout, /* dpd_timeout */
|
||||
this->vip ? this->vip->clone(this->vip) : NULL,
|
||||
this->pool, FALSE, NULL, NULL);
|
||||
FALSE, NULL, NULL);
|
||||
if (this->vip)
|
||||
{
|
||||
peer_cfg->add_virtual_ip(peer_cfg, this->vip->clone(this->vip));
|
||||
}
|
||||
if (this->pool)
|
||||
{
|
||||
peer_cfg->add_pool(peer_cfg, this->pool);
|
||||
}
|
||||
if (num)
|
||||
{ /* initiator */
|
||||
generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num);
|
||||
|
||||
@@ -335,8 +335,8 @@ static gboolean initiate_connection(private_maemo_service_t *this,
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
host_create_from_string("0.0.0.0", 0) /* virt */,
|
||||
NULL, FALSE, NULL, NULL); /* pool, mediation */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
|
||||
|
||||
@@ -129,7 +129,6 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
NULL, NULL, /* vip, pool */
|
||||
TRUE, NULL, NULL); /* mediation, med by, peer id */
|
||||
e->destroy(e);
|
||||
|
||||
@@ -167,7 +166,6 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
NULL, NULL, /* vip, pool */
|
||||
FALSE, med_cfg, /* mediation, med by */
|
||||
identification_create_from_encoding(ID_KEY_ID, other));
|
||||
|
||||
@@ -243,7 +241,6 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
NULL, NULL, /* vip, pool */
|
||||
FALSE, NULL, NULL); /* mediation, med by, peer id */
|
||||
|
||||
auth = auth_cfg_create();
|
||||
|
||||
@@ -94,7 +94,6 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressiv */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
NULL, NULL, /* vip, pool */
|
||||
TRUE, NULL, NULL); /* mediation, med by, peer id */
|
||||
e->destroy(e);
|
||||
|
||||
|
||||
@@ -333,6 +333,7 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
|
||||
mediation, mediated_by, p_type;
|
||||
chunk_t l_data, r_data, p_data;
|
||||
char *name, *virtual, *pool;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
while (e->enumerate(e,
|
||||
&id, &name, &ike_cfg, &l_type, &l_data, &r_type, &r_data,
|
||||
@@ -371,8 +372,23 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
|
||||
peer_cfg = peer_cfg_create(
|
||||
name, IKEV2, ike, cert_policy, uniqueid,
|
||||
keyingtries, rekeytime, reauthtime, jitter, overtime,
|
||||
mobike, FALSE, dpd_delay, 0, vip, pool,
|
||||
mobike, FALSE, dpd_delay, 0,
|
||||
mediation, mediated_cfg, peer_id);
|
||||
if (vip)
|
||||
{
|
||||
peer_cfg->add_virtual_ip(peer_cfg, vip);
|
||||
}
|
||||
if (pool)
|
||||
{
|
||||
/* attr-sql used comma separated pools, but we now completely
|
||||
* support multiple pools directly. Support old SQL configs: */
|
||||
enumerator = enumerator_create_token(pool, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &pool))
|
||||
{
|
||||
peer_cfg->add_pool(peer_cfg, pool);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
|
||||
auth->add(auth, AUTH_RULE_IDENTITY, local_id);
|
||||
|
||||
@@ -21,6 +21,7 @@ libstrongswan_stroke_la_SOURCES = \
|
||||
stroke_cred.h stroke_cred.c \
|
||||
stroke_ca.h stroke_ca.c \
|
||||
stroke_attribute.h stroke_attribute.c \
|
||||
stroke_handler.h stroke_handler.c \
|
||||
stroke_list.h stroke_list.c
|
||||
|
||||
libstrongswan_stroke_la_LDFLAGS = -module -avoid-version
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "stroke_attribute.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <attributes/mem_pool.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <threading/rwlock.h>
|
||||
|
||||
@@ -38,12 +37,37 @@ struct private_stroke_attribute_t {
|
||||
*/
|
||||
linked_list_t *pools;
|
||||
|
||||
/**
|
||||
* List of connection specific attributes, as attributes_t
|
||||
*/
|
||||
linked_list_t *attrs;
|
||||
|
||||
/**
|
||||
* rwlock to lock access to pools
|
||||
*/
|
||||
rwlock_t *lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attributes assigned to a connection
|
||||
*/
|
||||
typedef struct {
|
||||
/** name of the connection */
|
||||
char *name;
|
||||
/** list of DNS attributes, as host_t */
|
||||
linked_list_t *dns;
|
||||
} attributes_t;
|
||||
|
||||
/**
|
||||
* Destroy an attributes_t entry
|
||||
*/
|
||||
static void attributes_destroy(attributes_t *this)
|
||||
{
|
||||
this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
|
||||
free(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* find a pool by name
|
||||
*/
|
||||
@@ -66,11 +90,12 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name)
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, acquire_address, host_t*,
|
||||
private_stroke_attribute_t *this, char *name, identification_t *id,
|
||||
host_t *requested)
|
||||
private_stroke_attribute_t *this, char *name, identification_t *id,
|
||||
host_t *requested)
|
||||
{
|
||||
mem_pool_t *pool;
|
||||
host_t *addr = NULL;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
pool = find_pool(this, name);
|
||||
if (pool)
|
||||
@@ -82,11 +107,12 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, release_address, bool,
|
||||
private_stroke_attribute_t *this, char *name, host_t *address,
|
||||
identification_t *id)
|
||||
private_stroke_attribute_t *this, char *name, host_t *address,
|
||||
identification_t *id)
|
||||
{
|
||||
mem_pool_t *pool;
|
||||
bool found = FALSE;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
pool = find_pool(this, name);
|
||||
if (pool)
|
||||
@@ -97,56 +123,162 @@ METHOD(attribute_provider_t, release_address, bool,
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, add_pool, void,
|
||||
private_stroke_attribute_t *this, stroke_msg_t *msg)
|
||||
/**
|
||||
* Filter function to convert host to DNS configuration attributes
|
||||
*/
|
||||
static bool attr_filter(void *lock, host_t **in,
|
||||
configuration_attribute_type_t *type,
|
||||
void *dummy, chunk_t *data)
|
||||
{
|
||||
if (msg->add_conn.other.sourceip_mask)
|
||||
host_t *host = *in;
|
||||
|
||||
switch (host->get_family(host))
|
||||
{
|
||||
mem_pool_t *pool;
|
||||
host_t *base = NULL;
|
||||
u_int32_t bits = 0;
|
||||
|
||||
/* if %config, add an empty pool, otherwise */
|
||||
if (msg->add_conn.other.sourceip)
|
||||
{
|
||||
DBG1(DBG_CFG, "adding virtual IP address pool '%s': %s/%d",
|
||||
msg->add_conn.name, msg->add_conn.other.sourceip,
|
||||
msg->add_conn.other.sourceip_mask);
|
||||
base = host_create_from_string(msg->add_conn.other.sourceip, 0);
|
||||
if (!base)
|
||||
{
|
||||
DBG1(DBG_CFG, "virtual IP address invalid, discarded");
|
||||
return;
|
||||
}
|
||||
bits = msg->add_conn.other.sourceip_mask;
|
||||
}
|
||||
pool = mem_pool_create(msg->add_conn.name, base, bits);
|
||||
DESTROY_IF(base);
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
this->pools->insert_last(this->pools, pool);
|
||||
this->lock->unlock(this->lock);
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
*data = host->get_address(host);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, del_pool, void,
|
||||
private_stroke_attribute_t *this, stroke_msg_t *msg)
|
||||
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_stroke_attribute_t *this, linked_list_t *pools,
|
||||
identification_t *id, linked_list_t *vips)
|
||||
{
|
||||
ike_sa_t *ike_sa;
|
||||
peer_cfg_t *peer_cfg;
|
||||
enumerator_t *enumerator;
|
||||
attributes_t *attr;
|
||||
|
||||
ike_sa = charon->bus->get_sa(charon->bus);
|
||||
if (ike_sa)
|
||||
{
|
||||
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
if (streq(attr->name, peer_cfg->get_name(peer_cfg)))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
return enumerator_create_filter(
|
||||
attr->dns->create_enumerator(attr->dns),
|
||||
(void*)attr_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, add_pool, void,
|
||||
private_stroke_attribute_t *this, mem_pool_t *pool)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
mem_pool_t *pool;
|
||||
mem_pool_t *current;
|
||||
host_t *base;
|
||||
int size;
|
||||
|
||||
base = pool->get_base(pool);
|
||||
size = pool->get_size(pool);
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
|
||||
enumerator = this->pools->create_enumerator(this->pools);
|
||||
while (enumerator->enumerate(enumerator, &pool))
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
if (streq(msg->del_conn.name, pool->get_name(pool)))
|
||||
if (base && current->get_base(current) &&
|
||||
base->ip_equals(base, current->get_base(current)) &&
|
||||
size == current->get_size(current))
|
||||
{
|
||||
this->pools->remove_at(this->pools, enumerator);
|
||||
pool->destroy(pool);
|
||||
pool = NULL;
|
||||
DBG1(DBG_CFG, "reusing virtual IP address pool %H/%d", base, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (pool)
|
||||
{
|
||||
if (base)
|
||||
{
|
||||
DBG1(DBG_CFG, "adding virtual IP address pool %H/%d", base, size);
|
||||
}
|
||||
this->pools->insert_last(this->pools, pool);
|
||||
}
|
||||
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, add_dns, void,
|
||||
private_stroke_attribute_t *this, stroke_msg_t *msg)
|
||||
{
|
||||
if (msg->add_conn.other.dns)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
attributes_t *attr = NULL;
|
||||
host_t *host;
|
||||
char *token;
|
||||
|
||||
enumerator = enumerator_create_token(msg->add_conn.other.dns, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
host = host_create_from_string(token, 0);
|
||||
if (host)
|
||||
{
|
||||
if (!attr)
|
||||
{
|
||||
INIT(attr,
|
||||
.name = strdup(msg->add_conn.name),
|
||||
.dns = linked_list_create(),
|
||||
);
|
||||
}
|
||||
attr->dns->insert_last(attr->dns, host);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_CFG, "ignoring invalid DNS address '%s'", token);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (attr)
|
||||
{
|
||||
this->lock->write_lock(this->lock);
|
||||
this->attrs->insert_last(this->attrs, attr);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, del_dns, void,
|
||||
private_stroke_attribute_t *this, stroke_msg_t *msg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
attributes_t *attr;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
if (streq(msg->del_conn.name, attr->name))
|
||||
{
|
||||
this->attrs->remove_at(this->attrs, enumerator);
|
||||
attributes_destroy(attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
@@ -158,6 +290,11 @@ static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name,
|
||||
void *d3, u_int *offline)
|
||||
{
|
||||
mem_pool_t *pool = *poolp;
|
||||
|
||||
if (pool->get_size(pool) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*name = pool->get_name(pool);
|
||||
*size = pool->get_size(pool);
|
||||
*online = pool->get_online(pool);
|
||||
@@ -166,7 +303,7 @@ static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name,
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*,
|
||||
private_stroke_attribute_t *this)
|
||||
private_stroke_attribute_t *this)
|
||||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(this->pools->create_enumerator(this->pools),
|
||||
@@ -175,7 +312,7 @@ METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*,
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, create_lease_enumerator, enumerator_t*,
|
||||
private_stroke_attribute_t *this, char *name)
|
||||
private_stroke_attribute_t *this, char *name)
|
||||
{
|
||||
mem_pool_t *pool;
|
||||
this->lock->read_lock(this->lock);
|
||||
@@ -190,10 +327,11 @@ METHOD(stroke_attribute_t, create_lease_enumerator, enumerator_t*,
|
||||
}
|
||||
|
||||
METHOD(stroke_attribute_t, destroy, void,
|
||||
private_stroke_attribute_t *this)
|
||||
private_stroke_attribute_t *this)
|
||||
{
|
||||
this->lock->destroy(this->lock);
|
||||
this->pools->destroy_offset(this->pools, offsetof(mem_pool_t, destroy));
|
||||
this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -209,15 +347,17 @@ stroke_attribute_t *stroke_attribute_create()
|
||||
.provider = {
|
||||
.acquire_address = _acquire_address,
|
||||
.release_address = _release_address,
|
||||
.create_attribute_enumerator = enumerator_create_empty,
|
||||
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||
},
|
||||
.add_pool = _add_pool,
|
||||
.del_pool = _del_pool,
|
||||
.add_dns = _add_dns,
|
||||
.del_dns = _del_dns,
|
||||
.create_pool_enumerator = _create_pool_enumerator,
|
||||
.create_lease_enumerator = _create_lease_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.pools = linked_list_create(),
|
||||
.attrs = linked_list_create(),
|
||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <stroke_msg.h>
|
||||
#include <attributes/attribute_provider.h>
|
||||
#include <attributes/mem_pool.h>
|
||||
|
||||
typedef struct stroke_attribute_t stroke_attribute_t;
|
||||
|
||||
@@ -37,18 +38,28 @@ struct stroke_attribute_t {
|
||||
attribute_provider_t provider;
|
||||
|
||||
/**
|
||||
* Add a virtual IP address pool.
|
||||
* Add a memory pool to this virtual IP backend.
|
||||
*
|
||||
* @param msg stroke message
|
||||
* The pool gets owned by the provider, or destroyed if such a pool
|
||||
* is already registered.
|
||||
*
|
||||
* @param pool virtual IP pool to add
|
||||
*/
|
||||
void (*add_pool)(stroke_attribute_t *this, stroke_msg_t *msg);
|
||||
void (*add_pool)(stroke_attribute_t *this, mem_pool_t *pool);
|
||||
|
||||
/**
|
||||
* Remove a virtual IP address pool.
|
||||
* Add connection specific DNS servers.
|
||||
*
|
||||
* @param msg stroke message
|
||||
* @param msg stroke add message
|
||||
*/
|
||||
void (*del_pool)(stroke_attribute_t *this, stroke_msg_t *msg);
|
||||
void (*add_dns)(stroke_attribute_t *this, stroke_msg_t *msg);
|
||||
|
||||
/**
|
||||
* Remove connection specific DNS servers.
|
||||
*
|
||||
* @param msg stroke del message
|
||||
*/
|
||||
void (*del_dns)(stroke_attribute_t *this, stroke_msg_t *msg);
|
||||
|
||||
/**
|
||||
* Create an enumerator over installed pools.
|
||||
|
||||
@@ -52,6 +52,11 @@ struct private_stroke_config_t {
|
||||
* credentials
|
||||
*/
|
||||
stroke_cred_t *cred;
|
||||
|
||||
/**
|
||||
* Virtual IP pool / DNS backend
|
||||
*/
|
||||
stroke_attribute_t *attributes;
|
||||
};
|
||||
|
||||
METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
||||
@@ -618,7 +623,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
||||
{
|
||||
identification_t *peer_id = NULL;
|
||||
peer_cfg_t *mediated_by = NULL;
|
||||
host_t *vip = NULL;
|
||||
unique_policy_t unique;
|
||||
u_int32_t rekey = 0, reauth = 0, over, jitter;
|
||||
peer_cfg_t *peer_cfg;
|
||||
@@ -677,49 +681,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
||||
{
|
||||
rekey = msg->add_conn.rekey.ike_lifetime - over;
|
||||
}
|
||||
if (msg->add_conn.me.sourceip_mask)
|
||||
{
|
||||
if (msg->add_conn.me.sourceip)
|
||||
{
|
||||
vip = host_create_from_string(msg->add_conn.me.sourceip, 0);
|
||||
}
|
||||
if (!vip)
|
||||
{ /* if it is set to something like %poolname, request an address */
|
||||
if (msg->add_conn.me.subnets)
|
||||
{ /* use the same family as in local subnet, if any */
|
||||
if (strchr(msg->add_conn.me.subnets, '.'))
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
}
|
||||
else if (msg->add_conn.other.subnets)
|
||||
{ /* use the same family as in remote subnet, if any */
|
||||
if (strchr(msg->add_conn.other.subnets, '.'))
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strchr(ike_cfg->get_my_addr(ike_cfg, NULL), ':'))
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (msg->add_conn.unique)
|
||||
{
|
||||
case 1: /* yes */
|
||||
@@ -747,10 +708,126 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
||||
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
|
||||
msg->add_conn.mobike, msg->add_conn.aggressive,
|
||||
msg->add_conn.dpd.delay, msg->add_conn.dpd.timeout,
|
||||
vip, msg->add_conn.other.sourceip_mask ?
|
||||
msg->add_conn.name : msg->add_conn.other.sourceip,
|
||||
msg->add_conn.ikeme.mediation, mediated_by, peer_id);
|
||||
|
||||
if (msg->add_conn.other.sourceip)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
char *token;
|
||||
|
||||
enumerator = enumerator_create_token(msg->add_conn.other.sourceip,
|
||||
",", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
if (streq(token, "%modeconfig") || streq(token, "%modecfg") ||
|
||||
streq(token, "%config") || streq(token, "%cfg") ||
|
||||
streq(token, "%config4") || streq(token, "%config6"))
|
||||
{
|
||||
/* empty pool, uses connection name */
|
||||
this->attributes->add_pool(this->attributes,
|
||||
mem_pool_create(msg->add_conn.name, NULL, 0));
|
||||
peer_cfg->add_pool(peer_cfg, msg->add_conn.name);
|
||||
}
|
||||
else if (*token == '%')
|
||||
{
|
||||
/* external named pool */
|
||||
peer_cfg->add_pool(peer_cfg, token + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* in-memory pool, named using CIDR notation */
|
||||
host_t *base;
|
||||
int bits;
|
||||
|
||||
base = host_create_from_subnet(token, &bits);
|
||||
if (base)
|
||||
{
|
||||
this->attributes->add_pool(this->attributes,
|
||||
mem_pool_create(token, base, bits));
|
||||
peer_cfg->add_pool(peer_cfg, token);
|
||||
base->destroy(base);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_CFG, "IP pool %s invalid, ignored", token);
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
if (msg->add_conn.me.sourceip)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
char *token;
|
||||
|
||||
enumerator = enumerator_create_token(msg->add_conn.me.sourceip, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
host_t *vip = NULL;
|
||||
|
||||
if (streq(token, "%modeconfig") || streq(token, "%modecfg") ||
|
||||
streq(token, "%config") || streq(token, "%cfg"))
|
||||
{ /* try to deduce an address family */
|
||||
if (msg->add_conn.me.subnets)
|
||||
{ /* use the same family as in local subnet, if any */
|
||||
if (strchr(msg->add_conn.me.subnets, '.'))
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
}
|
||||
else if (msg->add_conn.other.subnets)
|
||||
{ /* use the same family as in remote subnet, if any */
|
||||
if (strchr(msg->add_conn.other.subnets, '.'))
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strchr(ike_cfg->get_my_addr(ike_cfg, NULL), ':'))
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (streq(token, "%config4"))
|
||||
{
|
||||
vip = host_create_any(AF_INET);
|
||||
}
|
||||
else if (streq(token, "%config6"))
|
||||
{
|
||||
vip = host_create_any(AF_INET6);
|
||||
}
|
||||
else
|
||||
{
|
||||
vip = host_create_from_string(token, 0);
|
||||
if (vip)
|
||||
{
|
||||
DBG1(DBG_CFG, "ignored invalid subnet token: %s", token);
|
||||
}
|
||||
}
|
||||
|
||||
if (vip)
|
||||
{
|
||||
peer_cfg->add_virtual_ip(peer_cfg, vip);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/* build leftauth= */
|
||||
auth_cfg = build_auth_cfg(this, msg, TRUE, TRUE);
|
||||
if (auth_cfg)
|
||||
@@ -1209,7 +1286,8 @@ METHOD(stroke_config_t, destroy, void,
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
|
||||
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred,
|
||||
stroke_attribute_t *attributes)
|
||||
{
|
||||
private_stroke_config_t *this;
|
||||
|
||||
@@ -1229,6 +1307,7 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
|
||||
.mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
|
||||
.ca = ca,
|
||||
.cred = cred,
|
||||
.attributes = attributes,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stroke_msg.h>
|
||||
#include "stroke_ca.h"
|
||||
#include "stroke_cred.h"
|
||||
#include "stroke_attribute.h"
|
||||
|
||||
typedef struct stroke_config_t stroke_config_t;
|
||||
|
||||
@@ -71,6 +72,7 @@ struct stroke_config_t {
|
||||
/**
|
||||
* Create a stroke_config instance.
|
||||
*/
|
||||
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred);
|
||||
stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred,
|
||||
stroke_attribute_t *attributes);
|
||||
|
||||
#endif /** STROKE_CONFIG_H_ @}*/
|
||||
|
||||
@@ -407,10 +407,10 @@ METHOD(stroke_control_t, rekey, void,
|
||||
METHOD(stroke_control_t, terminate_srcip, void,
|
||||
private_stroke_control_t *this, stroke_msg_t *msg, FILE *out)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
enumerator_t *enumerator, *vips;
|
||||
ike_sa_t *ike_sa;
|
||||
host_t *start = NULL, *end = NULL, *vip;
|
||||
chunk_t chunk_start, chunk_end = chunk_empty, chunk_vip;
|
||||
chunk_t chunk_start, chunk_end = chunk_empty, chunk;
|
||||
|
||||
if (msg->terminate_srcip.start)
|
||||
{
|
||||
@@ -438,33 +438,40 @@ METHOD(stroke_control_t, terminate_srcip, void,
|
||||
charon->controller, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &ike_sa))
|
||||
{
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
|
||||
if (!vip)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!end)
|
||||
{
|
||||
if (!vip->ip_equals(vip, start))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk_vip = vip->get_address(vip);
|
||||
if (chunk_vip.len != chunk_start.len ||
|
||||
chunk_vip.len != chunk_end.len ||
|
||||
memcmp(chunk_vip.ptr, chunk_start.ptr, chunk_vip.len) < 0 ||
|
||||
memcmp(chunk_vip.ptr, chunk_end.ptr, chunk_vip.len) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
bool match = FALSE;
|
||||
|
||||
/* schedule delete asynchronously */
|
||||
lib->processor->queue_job(lib->processor, (job_t*)
|
||||
vips = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
|
||||
while (vips->enumerate(vips, &vip))
|
||||
{
|
||||
if (!end)
|
||||
{
|
||||
if (vip->ip_equals(vip, start))
|
||||
{
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk = vip->get_address(vip);
|
||||
if (chunk.len == chunk_start.len &&
|
||||
chunk.len == chunk_end.len &&
|
||||
memcmp(chunk.ptr, chunk_start.ptr, chunk.len) >= 0 &&
|
||||
memcmp(chunk.ptr, chunk_end.ptr, chunk.len) <= 0)
|
||||
{
|
||||
match = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
vips->destroy(vips);
|
||||
|
||||
if (match)
|
||||
{
|
||||
/* schedule delete asynchronously */
|
||||
lib->processor->queue_job(lib->processor, (job_t*)
|
||||
delete_ike_sa_job_create(ike_sa->get_id(ike_sa), TRUE));
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
start->destroy(start);
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Martin Willi
|
||||
* Copyright (C) 2012 revosec AG
|
||||
*
|
||||
* 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 "stroke_handler.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <threading/rwlock.h>
|
||||
|
||||
typedef struct private_stroke_handler_t private_stroke_handler_t;
|
||||
|
||||
/**
|
||||
* Private data of an stroke_handler_t object.
|
||||
*/
|
||||
struct private_stroke_handler_t {
|
||||
|
||||
/**
|
||||
* Public stroke_handler_t interface.
|
||||
*/
|
||||
stroke_handler_t public;
|
||||
|
||||
/**
|
||||
* List of connection specific attributes, as attributes_t
|
||||
*/
|
||||
linked_list_t *attrs;
|
||||
|
||||
/**
|
||||
* rwlock to lock access to pools
|
||||
*/
|
||||
rwlock_t *lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attributes assigned to a connection
|
||||
*/
|
||||
typedef struct {
|
||||
/** name of the connection */
|
||||
char *name;
|
||||
/** list of DNS attributes, as host_t */
|
||||
linked_list_t *dns;
|
||||
} attributes_t;
|
||||
|
||||
/**
|
||||
* Destroy an attributes_t entry
|
||||
*/
|
||||
static void attributes_destroy(attributes_t *this)
|
||||
{
|
||||
this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
|
||||
free(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter function to convert host to DNS configuration attributes
|
||||
*/
|
||||
static bool attr_filter(void *lock, host_t **in,
|
||||
configuration_attribute_type_t *type,
|
||||
void *dummy, chunk_t *data)
|
||||
{
|
||||
host_t *host = *in;
|
||||
|
||||
switch (host->get_family(host))
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
if (host->is_anyaddr(host))
|
||||
{
|
||||
*data = chunk_empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
*data = host->get_address(host);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_stroke_handler_t *this, identification_t *server,
|
||||
linked_list_t *vips)
|
||||
{
|
||||
ike_sa_t *ike_sa;
|
||||
peer_cfg_t *peer_cfg;
|
||||
enumerator_t *enumerator;
|
||||
attributes_t *attr;
|
||||
|
||||
ike_sa = charon->bus->get_sa(charon->bus);
|
||||
if (ike_sa)
|
||||
{
|
||||
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
if (streq(attr->name, peer_cfg->get_name(peer_cfg)))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
return enumerator_create_filter(
|
||||
attr->dns->create_enumerator(attr->dns),
|
||||
(void*)attr_filter, this->lock,
|
||||
(void*)this->lock->unlock);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
METHOD(stroke_handler_t, add_attributes, void,
|
||||
private_stroke_handler_t *this, stroke_msg_t *msg)
|
||||
{
|
||||
if (msg->add_conn.me.dns)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
attributes_t *attr = NULL;
|
||||
host_t *host;
|
||||
char *token;
|
||||
|
||||
enumerator = enumerator_create_token(msg->add_conn.me.dns, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
if (streq(token, "%config") || streq(token, "%config4"))
|
||||
{
|
||||
host = host_create_any(AF_INET);
|
||||
}
|
||||
else if (streq(token, "%config6"))
|
||||
{
|
||||
host = host_create_any(AF_INET6);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = host_create_from_string(token, 0);
|
||||
}
|
||||
if (host)
|
||||
{
|
||||
if (!attr)
|
||||
{
|
||||
INIT(attr,
|
||||
.name = strdup(msg->add_conn.name),
|
||||
.dns = linked_list_create(),
|
||||
);
|
||||
}
|
||||
attr->dns->insert_last(attr->dns, host);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_CFG, "ignoring invalid DNS address '%s'", token);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (attr)
|
||||
{
|
||||
this->lock->write_lock(this->lock);
|
||||
this->attrs->insert_last(this->attrs, attr);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(stroke_handler_t, del_attributes, void,
|
||||
private_stroke_handler_t *this, stroke_msg_t *msg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
attributes_t *attr;
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
if (streq(msg->del_conn.name, attr->name))
|
||||
{
|
||||
this->attrs->remove_at(this->attrs, enumerator);
|
||||
attributes_destroy(attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
|
||||
METHOD(stroke_handler_t, destroy, void,
|
||||
private_stroke_handler_t *this)
|
||||
{
|
||||
this->lock->destroy(this->lock);
|
||||
this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
stroke_handler_t *stroke_handler_create()
|
||||
{
|
||||
private_stroke_handler_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.handler = {
|
||||
.handle = (void*)return_false,
|
||||
.release = (void*)return_false,
|
||||
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||
},
|
||||
.add_attributes = _add_attributes,
|
||||
.del_attributes = _del_attributes,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.attrs = linked_list_create(),
|
||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Martin Willi
|
||||
* Copyright (C) 2012 revosec AG
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup stroke_handler stroke_handler
|
||||
* @{ @ingroup stroke
|
||||
*/
|
||||
|
||||
#ifndef STROKE_HANDLER_H_
|
||||
#define STROKE_HANDLER_H_
|
||||
|
||||
#include <stroke_msg.h>
|
||||
#include <attributes/attribute_handler.h>
|
||||
|
||||
typedef struct stroke_handler_t stroke_handler_t;
|
||||
|
||||
/**
|
||||
* Handler requesting DNS attributes as defined with leftdns option.
|
||||
*/
|
||||
struct stroke_handler_t {
|
||||
|
||||
/**
|
||||
* Implements the attribute_handler_t interface
|
||||
*/
|
||||
attribute_handler_t handler;
|
||||
|
||||
/**
|
||||
* Add connection specific configuration attributes.
|
||||
*
|
||||
* @param msg stroke message
|
||||
*/
|
||||
void (*add_attributes)(stroke_handler_t *this, stroke_msg_t *msg);
|
||||
|
||||
/**
|
||||
* Remove connection specific configuration attributes.
|
||||
*
|
||||
* @param msg stroke message
|
||||
*/
|
||||
void (*del_attributes)(stroke_handler_t *this, stroke_msg_t *msg);
|
||||
|
||||
/**
|
||||
* Destroy a stroke_handler_t.
|
||||
*/
|
||||
void (*destroy)(stroke_handler_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a stroke_handler instance.
|
||||
*/
|
||||
stroke_handler_t *stroke_handler_create();
|
||||
|
||||
#endif /** STROKE_HANDLER_H_ @}*/
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "stroke_cred.h"
|
||||
#include "stroke_ca.h"
|
||||
#include "stroke_attribute.h"
|
||||
#include "stroke_handler.h"
|
||||
#include "stroke_list.h"
|
||||
|
||||
/**
|
||||
@@ -98,6 +99,11 @@ struct private_stroke_socket_t {
|
||||
*/
|
||||
stroke_attribute_t *attribute;
|
||||
|
||||
/**
|
||||
* attribute handler (requests only)
|
||||
*/
|
||||
stroke_handler_t *handler;
|
||||
|
||||
/**
|
||||
* controller to control daemon
|
||||
*/
|
||||
@@ -171,6 +177,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
|
||||
pop_string(msg, &end->address);
|
||||
pop_string(msg, &end->subnets);
|
||||
pop_string(msg, &end->sourceip);
|
||||
pop_string(msg, &end->dns);
|
||||
pop_string(msg, &end->auth);
|
||||
pop_string(msg, &end->auth2);
|
||||
pop_string(msg, &end->id);
|
||||
@@ -188,6 +195,7 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
|
||||
DBG2(DBG_CFG, " %s=%s", label, end->address);
|
||||
DBG2(DBG_CFG, " %ssubnet=%s", label, end->subnets);
|
||||
DBG2(DBG_CFG, " %ssourceip=%s", label, end->sourceip);
|
||||
DBG2(DBG_CFG, " %sdns=%s", label, end->dns);
|
||||
DBG2(DBG_CFG, " %sauth=%s", label, end->auth);
|
||||
DBG2(DBG_CFG, " %sauth2=%s", label, end->auth2);
|
||||
DBG2(DBG_CFG, " %sid=%s", label, end->id);
|
||||
@@ -235,7 +243,8 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
|
||||
DBG2(DBG_CFG, " keyexchange=ikev%u", msg->add_conn.version);
|
||||
|
||||
this->config->add(this->config, msg);
|
||||
this->attribute->add_pool(this->attribute, msg);
|
||||
this->attribute->add_dns(this->attribute, msg);
|
||||
this->handler->add_attributes(this->handler, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,7 +256,8 @@ static void stroke_del_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
|
||||
DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);
|
||||
|
||||
this->config->del(this->config, msg);
|
||||
this->attribute->del_pool(this->attribute, msg);
|
||||
this->attribute->del_dns(this->attribute, msg);
|
||||
this->handler->del_attributes(this->handler, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -787,10 +797,12 @@ METHOD(stroke_socket_t, destroy, void,
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider);
|
||||
hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
|
||||
this->cred->destroy(this->cred);
|
||||
this->ca->destroy(this->ca);
|
||||
this->config->destroy(this->config);
|
||||
this->attribute->destroy(this->attribute);
|
||||
this->handler->destroy(this->handler);
|
||||
this->control->destroy(this->control);
|
||||
this->list->destroy(this->list);
|
||||
free(this);
|
||||
@@ -817,8 +829,9 @@ stroke_socket_t *stroke_socket_create()
|
||||
|
||||
this->cred = stroke_cred_create();
|
||||
this->attribute = stroke_attribute_create();
|
||||
this->handler = stroke_handler_create();
|
||||
this->ca = stroke_ca_create(this->cred);
|
||||
this->config = stroke_config_create(this->ca, this->cred);
|
||||
this->config = stroke_config_create(this->ca, this->cred, this->attribute);
|
||||
this->control = stroke_control_create();
|
||||
this->list = stroke_list_create(this->attribute);
|
||||
|
||||
@@ -833,6 +846,7 @@ stroke_socket_t *stroke_socket_create()
|
||||
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
|
||||
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
||||
|
||||
lib->processor->queue_job(lib->processor,
|
||||
(job_t*)callback_job_create_with_prio((callback_job_cb_t)receive, this,
|
||||
|
||||
@@ -178,7 +178,6 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
1800, 900, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
60, 0, /* DPD delay, timeout */
|
||||
NULL, NULL, /* vip, pool */
|
||||
FALSE, NULL, NULL); /* mediation, med by, peer id */
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
|
||||
|
||||
@@ -12,6 +12,7 @@ endif
|
||||
|
||||
libstrongswan_updown_la_SOURCES = \
|
||||
updown_plugin.h updown_plugin.c \
|
||||
updown_handler.h updown_handler.c \
|
||||
updown_listener.h updown_listener.c
|
||||
|
||||
libstrongswan_updown_la_LDFLAGS = -module -avoid-version
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Martin Willi
|
||||
* Copyright (C) 2012 revosec AG
|
||||
*
|
||||
* 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 "updown_handler.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <threading/rwlock.h>
|
||||
|
||||
typedef struct private_updown_handler_t private_updown_handler_t;
|
||||
|
||||
/**
|
||||
* Private data of an updown_handler_t object.
|
||||
*/
|
||||
struct private_updown_handler_t {
|
||||
|
||||
/**
|
||||
* Public updown_handler_t interface.
|
||||
*/
|
||||
updown_handler_t public;
|
||||
|
||||
/**
|
||||
* List of connection specific attributes, as attributes_t
|
||||
*/
|
||||
linked_list_t *attrs;
|
||||
|
||||
/**
|
||||
* rwlock to lock access to pools
|
||||
*/
|
||||
rwlock_t *lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attributes assigned to an IKE_SA
|
||||
*/
|
||||
typedef struct {
|
||||
/** unique IKE_SA identifier */
|
||||
u_int id;
|
||||
/** list of DNS attributes, as host_t */
|
||||
linked_list_t *dns;
|
||||
} attributes_t;
|
||||
|
||||
/**
|
||||
* Destroy an attributes_t entry
|
||||
*/
|
||||
static void attributes_destroy(attributes_t *this)
|
||||
{
|
||||
this->dns->destroy_offset(this->dns, offsetof(host_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, handle, bool,
|
||||
private_updown_handler_t *this, identification_t *server,
|
||||
configuration_attribute_type_t type, chunk_t data)
|
||||
{
|
||||
attributes_t *current, *attr = NULL;
|
||||
enumerator_t *enumerator;
|
||||
ike_sa_t *ike_sa;
|
||||
host_t *host;
|
||||
|
||||
ike_sa = charon->bus->get_sa(charon->bus);
|
||||
if (!ike_sa)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case INTERNAL_IP4_DNS:
|
||||
host = host_create_from_chunk(AF_INET, data, 0);
|
||||
break;
|
||||
case INTERNAL_IP6_DNS:
|
||||
host = host_create_from_chunk(AF_INET6, data, 0);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
if (!host)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
if (current->id == ike_sa->get_unique_id(ike_sa))
|
||||
{
|
||||
attr = current;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!attr)
|
||||
{
|
||||
INIT(attr,
|
||||
.id = ike_sa->get_unique_id(ike_sa),
|
||||
.dns = linked_list_create(),
|
||||
);
|
||||
this->attrs->insert_last(this->attrs, attr);
|
||||
}
|
||||
attr->dns->insert_last(attr->dns, host);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, release, void,
|
||||
private_updown_handler_t *this, identification_t *server,
|
||||
configuration_attribute_type_t type, chunk_t data)
|
||||
{
|
||||
attributes_t *attr;
|
||||
enumerator_t *enumerator, *servers;
|
||||
ike_sa_t *ike_sa;
|
||||
host_t *host;
|
||||
bool found = FALSE;
|
||||
int family;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INTERNAL_IP4_DNS:
|
||||
family = AF_INET;
|
||||
break;
|
||||
case INTERNAL_IP6_DNS:
|
||||
family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
ike_sa = charon->bus->get_sa(charon->bus);
|
||||
if (ike_sa)
|
||||
{
|
||||
this->lock->write_lock(this->lock);
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
if (attr->id == ike_sa->get_unique_id(ike_sa))
|
||||
{
|
||||
servers = attr->dns->create_enumerator(attr->dns);
|
||||
while (servers->enumerate(servers, &host))
|
||||
{
|
||||
if (host->get_family(host) == family &&
|
||||
chunk_equals(data, host->get_address(host)))
|
||||
{
|
||||
attr->dns->remove_at(attr->dns, servers);
|
||||
host->destroy(host);
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
servers->destroy(servers);
|
||||
if (attr->dns->get_count(attr->dns) == 0)
|
||||
{
|
||||
this->attrs->remove_at(this->attrs, enumerator);
|
||||
attributes_destroy(attr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*,
|
||||
private_updown_handler_t *this, u_int id)
|
||||
{
|
||||
attributes_t *attr;
|
||||
enumerator_t *enumerator;
|
||||
ike_sa_t *ike_sa;
|
||||
|
||||
ike_sa = charon->bus->get_sa(charon->bus);
|
||||
if (!ike_sa)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator = this->attrs->create_enumerator(this->attrs);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
{
|
||||
if (attr->id == ike_sa->get_unique_id(ike_sa))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
return enumerator_create_cleaner(
|
||||
attr->dns->create_enumerator(attr->dns),
|
||||
(void*)this->lock->unlock, this->lock);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
|
||||
METHOD(updown_handler_t, destroy, void,
|
||||
private_updown_handler_t *this)
|
||||
{
|
||||
this->lock->destroy(this->lock);
|
||||
this->attrs->destroy_function(this->attrs, (void*)attributes_destroy);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
updown_handler_t *updown_handler_create()
|
||||
{
|
||||
private_updown_handler_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.handler = {
|
||||
.handle = _handle,
|
||||
.release = _release,
|
||||
.create_attribute_enumerator = enumerator_create_empty,
|
||||
},
|
||||
.create_dns_enumerator = _create_dns_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.attrs = linked_list_create(),
|
||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Martin Willi
|
||||
* Copyright (C) 2012 revosec AG
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup updown_handler updown_handler
|
||||
* @{ @ingroup updown
|
||||
*/
|
||||
|
||||
#ifndef UPDOWN_HANDLER_H_
|
||||
#define UPDOWN_HANDLER_H_
|
||||
|
||||
#include <attributes/attribute_handler.h>
|
||||
|
||||
typedef struct updown_handler_t updown_handler_t;
|
||||
|
||||
/**
|
||||
* Handler storing configuration attributes to pass to updown script.
|
||||
*/
|
||||
struct updown_handler_t {
|
||||
|
||||
/**
|
||||
* Implements the attribute_handler_t interface
|
||||
*/
|
||||
attribute_handler_t handler;
|
||||
|
||||
/**
|
||||
* Create an enumerator over received DNS servers.
|
||||
*
|
||||
* @param id unique IKE_SA identifier to get attributes for
|
||||
* @return enumerator over host_t*
|
||||
*/
|
||||
enumerator_t* (*create_dns_enumerator)(updown_handler_t *this, u_int id);
|
||||
|
||||
/**
|
||||
* Destroy a updown_handler_t.
|
||||
*/
|
||||
void (*destroy)(updown_handler_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a updown_handler instance.
|
||||
*/
|
||||
updown_handler_t *updown_handler_create();
|
||||
|
||||
#endif /** UPDOWN_HANDLER_H_ @}*/
|
||||
@@ -38,6 +38,11 @@ struct private_updown_listener_t {
|
||||
* List of cached interface names
|
||||
*/
|
||||
linked_list_t *iface_cache;
|
||||
|
||||
/**
|
||||
* DNS attribute handler
|
||||
*/
|
||||
updown_handler_t *handler;
|
||||
};
|
||||
|
||||
typedef struct cache_entry_t cache_entry_t;
|
||||
@@ -90,6 +95,85 @@ static char* uncache_iface(private_updown_listener_t *this, u_int32_t reqid)
|
||||
return iface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create variables for handled DNS attributes
|
||||
*/
|
||||
static char *make_dns_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
int v4 = 0, v6 = 0;
|
||||
char total[512] = "", current[64];
|
||||
|
||||
if (!this->handler)
|
||||
{
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
enumerator = this->handler->create_dns_enumerator(this->handler,
|
||||
ike_sa->get_unique_id(ike_sa));
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
switch (host->get_family(host))
|
||||
{
|
||||
case AF_INET:
|
||||
snprintf(current, sizeof(current),
|
||||
"PLUTO_DNS4_%d='%H' ", ++v4, host);
|
||||
break;
|
||||
case AF_INET6:
|
||||
snprintf(current, sizeof(current),
|
||||
"PLUTO_DNS6_%d='%H' ", ++v6, host);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
strncat(total, current, sizeof(total) - strlen(total) - 1);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return strdup(total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create variables for local virtual IPs
|
||||
*/
|
||||
static char *make_vip_vars(private_updown_listener_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
int v4 = 0, v6 = 0;
|
||||
char total[512] = "", current[64];
|
||||
bool first = TRUE;
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (first)
|
||||
{ /* legacy variable for first VIP */
|
||||
snprintf(current, sizeof(current),
|
||||
"PLUTO_MY_SOURCEIP='%H' ", host);
|
||||
strncat(total, current, sizeof(total) - strlen(total) - 1);
|
||||
}
|
||||
switch (host->get_family(host))
|
||||
{
|
||||
case AF_INET:
|
||||
snprintf(current, sizeof(current),
|
||||
"PLUTO_MY_SOURCEIP4_%d='%H' ", ++v4, host);
|
||||
break;
|
||||
case AF_INET6:
|
||||
snprintf(current, sizeof(current),
|
||||
"PLUTO_MY_SOURCEIP6_%d='%H' ", ++v6, host);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
strncat(total, current, sizeof(total) - strlen(total) - 1);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return strdup(total);
|
||||
}
|
||||
|
||||
METHOD(listener_t, child_updown, bool,
|
||||
private_updown_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
|
||||
bool up)
|
||||
@@ -97,11 +181,10 @@ METHOD(listener_t, child_updown, bool,
|
||||
traffic_selector_t *my_ts, *other_ts;
|
||||
enumerator_t *enumerator;
|
||||
child_cfg_t *config;
|
||||
host_t *vip, *me, *other;
|
||||
host_t *me, *other;
|
||||
char *script;
|
||||
|
||||
config = child_sa->get_config(child_sa);
|
||||
vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
|
||||
script = config->get_updown(config);
|
||||
me = ike_sa->get_my_host(ike_sa);
|
||||
other = ike_sa->get_other_host(ike_sa);
|
||||
@@ -117,7 +200,7 @@ METHOD(listener_t, child_updown, bool,
|
||||
char command[1024];
|
||||
host_t *my_client, *other_client;
|
||||
u_int8_t my_client_mask, other_client_mask;
|
||||
char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc;
|
||||
char *virtual_ip, *iface, *mark_in, *mark_out, *udp_enc, *dns;
|
||||
mark_t mark;
|
||||
bool is_host, is_ipv6;
|
||||
FILE *shell;
|
||||
@@ -125,20 +208,7 @@ METHOD(listener_t, child_updown, bool,
|
||||
my_ts->to_subnet(my_ts, &my_client, &my_client_mask);
|
||||
other_ts->to_subnet(other_ts, &other_client, &other_client_mask);
|
||||
|
||||
if (vip)
|
||||
{
|
||||
if (asprintf(&virtual_ip, "PLUTO_MY_SOURCEIP='%H' ", vip) < 0)
|
||||
{
|
||||
virtual_ip = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (asprintf(&virtual_ip, "") < 0)
|
||||
{
|
||||
virtual_ip = NULL;
|
||||
}
|
||||
}
|
||||
virtual_ip = make_vip_vars(this, ike_sa);
|
||||
|
||||
/* check for the presence of an inbound mark */
|
||||
mark = config->get_mark(config, TRUE);
|
||||
@@ -209,6 +279,8 @@ METHOD(listener_t, child_updown, bool,
|
||||
iface = uncache_iface(this, child_sa->get_reqid(child_sa));
|
||||
}
|
||||
|
||||
dns = make_dns_vars(this, ike_sa);
|
||||
|
||||
/* determine IPv4/IPv6 and client/host situation */
|
||||
is_host = my_ts->is_host(my_ts, me);
|
||||
is_ipv6 = is_host ? (me->get_family(me) == AF_INET6) :
|
||||
@@ -239,6 +311,7 @@ METHOD(listener_t, child_updown, bool,
|
||||
"%s"
|
||||
"%s"
|
||||
"%s"
|
||||
"%s"
|
||||
"%s",
|
||||
up ? "up" : "down",
|
||||
is_host ? "-host" : "-client",
|
||||
@@ -259,6 +332,7 @@ METHOD(listener_t, child_updown, bool,
|
||||
mark_out,
|
||||
udp_enc,
|
||||
config->get_hostaccess(config) ? "PLUTO_HOST_ACCESS='1' " : "",
|
||||
dns,
|
||||
script);
|
||||
my_client->destroy(my_client);
|
||||
other_client->destroy(other_client);
|
||||
@@ -266,6 +340,7 @@ METHOD(listener_t, child_updown, bool,
|
||||
free(mark_in);
|
||||
free(mark_out);
|
||||
free(udp_enc);
|
||||
free(dns);
|
||||
free(iface);
|
||||
|
||||
DBG3(DBG_CHD, "running updown script: %s", command);
|
||||
@@ -315,7 +390,7 @@ METHOD(updown_listener_t, destroy, void,
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
updown_listener_t *updown_listener_create()
|
||||
updown_listener_t *updown_listener_create(updown_handler_t *handler)
|
||||
{
|
||||
private_updown_listener_t *this;
|
||||
|
||||
@@ -327,6 +402,7 @@ updown_listener_t *updown_listener_create()
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.iface_cache = linked_list_create(),
|
||||
.handler = handler,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <bus/bus.h>
|
||||
|
||||
#include "updown_handler.h"
|
||||
|
||||
typedef struct updown_listener_t updown_listener_t;
|
||||
|
||||
/**
|
||||
@@ -44,6 +46,6 @@ struct updown_listener_t {
|
||||
/**
|
||||
* Create a updown_listener instance.
|
||||
*/
|
||||
updown_listener_t *updown_listener_create();
|
||||
updown_listener_t *updown_listener_create(updown_handler_t *handler);
|
||||
|
||||
#endif /** UPDOWN_LISTENER_H_ @}*/
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
|
||||
#include "updown_plugin.h"
|
||||
#include "updown_listener.h"
|
||||
#include "updown_handler.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <hydra.h>
|
||||
|
||||
typedef struct private_updown_plugin_t private_updown_plugin_t;
|
||||
|
||||
@@ -34,6 +36,11 @@ struct private_updown_plugin_t {
|
||||
* Listener interface, listens to CHILD_SA state changes
|
||||
*/
|
||||
updown_listener_t *listener;
|
||||
|
||||
/**
|
||||
* Attribute handler, to pass DNS servers to updown
|
||||
*/
|
||||
updown_handler_t *handler;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
@@ -47,6 +54,12 @@ METHOD(plugin_t, destroy, void,
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
if (this->handler)
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
this->handler->destroy(this->handler);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -65,9 +78,16 @@ plugin_t *updown_plugin_create()
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.listener = updown_listener_create(),
|
||||
);
|
||||
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"charon.plugins.updown.dns_handler", FALSE))
|
||||
{
|
||||
this->handler = updown_handler_create();
|
||||
hydra->attributes->add_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
this->listener = updown_listener_create(this->handler);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
|
||||
@@ -79,9 +79,10 @@ METHOD(job_t, execute, job_requeue_t,
|
||||
}
|
||||
if (ike_sa)
|
||||
{
|
||||
enumerator_t *children;
|
||||
enumerator_t *children, *enumerator;
|
||||
child_sa_t *child_sa;
|
||||
host_t *host;
|
||||
linked_list_t *vips;
|
||||
|
||||
children = ike_sa->create_child_sa_enumerator(ike_sa);
|
||||
while (children->enumerate(children, (void**)&child_sa))
|
||||
@@ -104,14 +105,22 @@ METHOD(job_t, execute, job_requeue_t,
|
||||
host->set_port(host, IKEV2_UDP_PORT);
|
||||
ike_sa->set_other_host(ike_sa, host);
|
||||
|
||||
if (child_sa->update(child_sa, this->local, this->remote,
|
||||
ike_sa->get_virtual_ip(ike_sa, TRUE),
|
||||
vips = linked_list_create();
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (child_sa->update(child_sa, this->local, this->remote, vips,
|
||||
ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
|
||||
{
|
||||
ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa),
|
||||
child_sa->get_spi(child_sa, TRUE));
|
||||
}
|
||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||
vips->destroy(vips);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -819,9 +819,18 @@ METHOD(child_sa_t, add_policies, status_t,
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to reinstall a virtual IP
|
||||
*/
|
||||
static void reinstall_vip(host_t *vip, host_t *me)
|
||||
{
|
||||
hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
|
||||
hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, me);
|
||||
}
|
||||
|
||||
METHOD(child_sa_t, update, status_t,
|
||||
private_child_sa_t *this, host_t *me, host_t *other, host_t *vip,
|
||||
bool encap)
|
||||
private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
|
||||
bool encap)
|
||||
{
|
||||
child_sa_state_t old;
|
||||
bool transport_proxy_mode;
|
||||
@@ -927,13 +936,7 @@ METHOD(child_sa_t, update, status_t,
|
||||
|
||||
/* we reinstall the virtual IP to handle interface roaming
|
||||
* correctly */
|
||||
if (vip)
|
||||
{
|
||||
hydra->kernel_interface->del_ip(hydra->kernel_interface,
|
||||
vip);
|
||||
hydra->kernel_interface->add_ip(hydra->kernel_interface,
|
||||
vip, me);
|
||||
}
|
||||
vips->invoke_function(vips, (void*)reinstall_vip, me);
|
||||
|
||||
/* reinstall updated policies */
|
||||
install_policies_internal(this, me, other, my_ts, other_ts,
|
||||
|
||||
@@ -346,12 +346,12 @@ struct child_sa_t {
|
||||
*
|
||||
* @param me the new local host
|
||||
* @param other the new remote host
|
||||
* @param vip virtual IP, if any
|
||||
* @param vips list of local virtual IPs
|
||||
* @param TRUE to use UDP encapsulation for NAT traversal
|
||||
* @return SUCCESS or FAILED
|
||||
*/
|
||||
status_t (*update)(child_sa_t *this, host_t *me, host_t *other,
|
||||
host_t *vip, bool encap);
|
||||
linked_list_t *vips, bool encap);
|
||||
/**
|
||||
* Destroys a child_sa.
|
||||
*/
|
||||
|
||||
+52
-48
@@ -182,14 +182,14 @@ struct private_ike_sa_t {
|
||||
keymat_t *keymat;
|
||||
|
||||
/**
|
||||
* Virtual IP on local host, if any
|
||||
* Virtual IPs on local host
|
||||
*/
|
||||
host_t *my_virtual_ip;
|
||||
linked_list_t *my_vips;
|
||||
|
||||
/**
|
||||
* Virtual IP on remote host, if any
|
||||
* Virtual IPs on remote host
|
||||
*/
|
||||
host_t *other_virtual_ip;
|
||||
linked_list_t *other_vips;
|
||||
|
||||
/**
|
||||
* List of configuration attributes (attribute_entry_t)
|
||||
@@ -735,7 +735,7 @@ METHOD(ike_sa_t, get_keymat, keymat_t*,
|
||||
return this->keymat;
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, set_virtual_ip, void,
|
||||
METHOD(ike_sa_t, add_virtual_ip, void,
|
||||
private_ike_sa_t *this, bool local, host_t *ip)
|
||||
{
|
||||
if (local)
|
||||
@@ -744,39 +744,27 @@ METHOD(ike_sa_t, set_virtual_ip, void,
|
||||
if (hydra->kernel_interface->add_ip(hydra->kernel_interface, ip,
|
||||
this->my_host) == SUCCESS)
|
||||
{
|
||||
if (this->my_virtual_ip)
|
||||
{
|
||||
DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
|
||||
hydra->kernel_interface->del_ip(hydra->kernel_interface,
|
||||
this->my_virtual_ip);
|
||||
}
|
||||
DESTROY_IF(this->my_virtual_ip);
|
||||
this->my_virtual_ip = ip->clone(ip);
|
||||
this->my_vips->insert_last(this->my_vips, ip->clone(ip));
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "installing virtual IP %H failed", ip);
|
||||
this->my_virtual_ip = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DESTROY_IF(this->other_virtual_ip);
|
||||
this->other_virtual_ip = ip->clone(ip);
|
||||
this->other_vips->insert_last(this->other_vips, ip->clone(ip));
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, get_virtual_ip, host_t*,
|
||||
METHOD(ike_sa_t, create_virtual_ip_enumerator, enumerator_t*,
|
||||
private_ike_sa_t *this, bool local)
|
||||
{
|
||||
if (local)
|
||||
{
|
||||
return this->my_virtual_ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this->other_virtual_ip;
|
||||
return this->my_vips->create_enumerator(this->my_vips);
|
||||
}
|
||||
return this->other_vips->create_enumerator(this->other_vips);
|
||||
}
|
||||
|
||||
METHOD(ike_sa_t, add_peer_address, void,
|
||||
@@ -909,7 +897,7 @@ METHOD(ike_sa_t, update_hosts, void,
|
||||
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
||||
{
|
||||
if (child_sa->update(child_sa, this->my_host,
|
||||
this->other_host, this->my_virtual_ip,
|
||||
this->other_host, this->my_vips,
|
||||
has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED)
|
||||
{
|
||||
this->public.rekey_child_sa(&this->public,
|
||||
@@ -1458,7 +1446,7 @@ METHOD(ike_sa_t, reauth, status_t,
|
||||
if (!has_condition(this, COND_ORIGINAL_INITIATOR))
|
||||
{
|
||||
DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
|
||||
if (this->other_virtual_ip != NULL ||
|
||||
if (this->other_vips->get_count(this->other_vips) != 0 ||
|
||||
has_condition(this, COND_XAUTH_AUTHENTICATED) ||
|
||||
has_condition(this, COND_EAP_AUTHENTICATED)
|
||||
#ifdef ME
|
||||
@@ -1562,7 +1550,7 @@ METHOD(ike_sa_t, reestablish, status_t,
|
||||
|
||||
/* check if we are able to reestablish this IKE_SA */
|
||||
if (!has_condition(this, COND_ORIGINAL_INITIATOR) &&
|
||||
(this->other_virtual_ip != NULL ||
|
||||
(this->other_vips->get_count(this->other_vips) != 0 ||
|
||||
has_condition(this, COND_EAP_AUTHENTICATED)
|
||||
#ifdef ME
|
||||
|| this->is_mediation_server
|
||||
@@ -1585,11 +1573,12 @@ METHOD(ike_sa_t, reestablish, status_t,
|
||||
host = this->my_host;
|
||||
new->set_my_host(new, host->clone(host));
|
||||
/* if we already have a virtual IP, we reuse it */
|
||||
host = this->my_virtual_ip;
|
||||
if (host)
|
||||
enumerator = this->my_vips->create_enumerator(this->my_vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
new->set_virtual_ip(new, TRUE, host);
|
||||
new->add_virtual_ip(new, TRUE, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
#ifdef ME
|
||||
if (this->peer_cfg->is_mediation(this->peer_cfg))
|
||||
@@ -1732,7 +1721,7 @@ METHOD(ike_sa_t, set_auth_lifetime, status_t,
|
||||
* We send the notify in IKE_AUTH if not yet ESTABLISHED. */
|
||||
send_update = this->state == IKE_ESTABLISHED && this->version == IKEV2 &&
|
||||
!has_condition(this, COND_ORIGINAL_INITIATOR) &&
|
||||
(this->other_virtual_ip != NULL ||
|
||||
(this->other_vips->get_count(this->other_vips) != 0 ||
|
||||
has_condition(this, COND_EAP_AUTHENTICATED));
|
||||
|
||||
if (lifetime < diff)
|
||||
@@ -1937,6 +1926,7 @@ METHOD(ike_sa_t, inherit, void,
|
||||
attribute_entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
auth_cfg_t *cfg;
|
||||
host_t *vip;
|
||||
|
||||
/* apply hosts and ids */
|
||||
this->my_host->destroy(this->my_host);
|
||||
@@ -1948,16 +1938,15 @@ METHOD(ike_sa_t, inherit, void,
|
||||
this->my_id = other->my_id->clone(other->my_id);
|
||||
this->other_id = other->other_id->clone(other->other_id);
|
||||
|
||||
/* apply virtual assigned IPs... */
|
||||
if (other->my_virtual_ip)
|
||||
/* apply assigned virtual IPs... */
|
||||
while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS)
|
||||
{
|
||||
this->my_virtual_ip = other->my_virtual_ip;
|
||||
other->my_virtual_ip = NULL;
|
||||
other->my_vips->insert_first(other->my_vips, vip);
|
||||
}
|
||||
if (other->other_virtual_ip)
|
||||
while (this->other_vips->remove_last(this->other_vips,
|
||||
(void**)&vip) == SUCCESS)
|
||||
{
|
||||
this->other_virtual_ip = other->other_virtual_ip;
|
||||
other->other_virtual_ip = NULL;
|
||||
other->other_vips->insert_first(other->other_vips, vip);
|
||||
}
|
||||
|
||||
/* authentication information */
|
||||
@@ -2032,6 +2021,7 @@ METHOD(ike_sa_t, destroy, void,
|
||||
private_ike_sa_t *this)
|
||||
{
|
||||
attribute_entry_t *entry;
|
||||
host_t *vip;
|
||||
|
||||
charon->bus->set_sa(charon->bus, &this->public);
|
||||
|
||||
@@ -2056,22 +2046,34 @@ METHOD(ike_sa_t, destroy, void,
|
||||
|
||||
DESTROY_IF(this->keymat);
|
||||
|
||||
if (this->my_virtual_ip)
|
||||
while (this->my_vips->remove_last(this->my_vips, (void**)&vip) == SUCCESS)
|
||||
{
|
||||
hydra->kernel_interface->del_ip(hydra->kernel_interface,
|
||||
this->my_virtual_ip);
|
||||
this->my_virtual_ip->destroy(this->my_virtual_ip);
|
||||
hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
|
||||
vip->destroy(vip);
|
||||
}
|
||||
if (this->other_virtual_ip)
|
||||
this->my_vips->destroy(this->my_vips);
|
||||
while (this->other_vips->remove_last(this->other_vips,
|
||||
(void**)&vip) == SUCCESS)
|
||||
{
|
||||
if (this->peer_cfg && this->peer_cfg->get_pool(this->peer_cfg))
|
||||
if (this->peer_cfg)
|
||||
{
|
||||
hydra->attributes->release_address(hydra->attributes,
|
||||
this->peer_cfg->get_pool(this->peer_cfg),
|
||||
this->other_virtual_ip, get_other_eap_id(this));
|
||||
enumerator_t *enumerator;
|
||||
char *pool;
|
||||
|
||||
enumerator = this->peer_cfg->create_pool_enumerator(this->peer_cfg);
|
||||
while (enumerator->enumerate(enumerator, &pool))
|
||||
{
|
||||
if (hydra->attributes->release_address(hydra->attributes, pool,
|
||||
vip, get_other_eap_id(this)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
this->other_virtual_ip->destroy(this->other_virtual_ip);
|
||||
vip->destroy(vip);
|
||||
}
|
||||
this->other_vips->destroy(this->other_vips);
|
||||
this->peer_addresses->destroy_offset(this->peer_addresses,
|
||||
offsetof(host_t, destroy));
|
||||
#ifdef ME
|
||||
@@ -2190,8 +2192,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
||||
.generate_message = _generate_message,
|
||||
.reset = _reset,
|
||||
.get_unique_id = _get_unique_id,
|
||||
.set_virtual_ip = _set_virtual_ip,
|
||||
.get_virtual_ip = _get_virtual_ip,
|
||||
.add_virtual_ip = _add_virtual_ip,
|
||||
.create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
|
||||
.add_configuration_attribute = _add_configuration_attribute,
|
||||
.set_kmaddress = _set_kmaddress,
|
||||
.create_task_enumerator = _create_task_enumerator,
|
||||
@@ -2226,6 +2228,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
||||
.other_auths = linked_list_create(),
|
||||
.unique_id = ++unique_id,
|
||||
.peer_addresses = linked_list_create(),
|
||||
.my_vips = linked_list_create(),
|
||||
.other_vips = linked_list_create(),
|
||||
.attributes = linked_list_create(),
|
||||
.keepalive_interval = lib->settings->get_time(lib->settings,
|
||||
"%s.keep_alive", KEEPALIVE_INTERVAL, charon->name),
|
||||
|
||||
@@ -931,7 +931,7 @@ struct ike_sa_t {
|
||||
status_t (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
|
||||
|
||||
/**
|
||||
* Set the virtual IP to use for this IKE_SA and its children.
|
||||
* Add a virtual IP to use for this IKE_SA and its children.
|
||||
*
|
||||
* The virtual IP is assigned per IKE_SA, not per CHILD_SA. It has the same
|
||||
* lifetime as the IKE_SA.
|
||||
@@ -939,15 +939,15 @@ struct ike_sa_t {
|
||||
* @param local TRUE to set local address, FALSE for remote
|
||||
* @param ip IP to set as virtual IP
|
||||
*/
|
||||
void (*set_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
|
||||
void (*add_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
|
||||
|
||||
/**
|
||||
* Get the virtual IP configured.
|
||||
* Create an enumerator over virtual IPs.
|
||||
*
|
||||
* @param local TRUE to get local virtual IP, FALSE for remote
|
||||
* @return host_t *virtual IP
|
||||
* @return enumerator over host_t*
|
||||
*/
|
||||
host_t* (*get_virtual_ip) (ike_sa_t *this, bool local);
|
||||
enumerator_t* (*create_virtual_ip_enumerator) (ike_sa_t *this, bool local);
|
||||
|
||||
/**
|
||||
* Register a configuration attribute to the IKE_SA.
|
||||
|
||||
@@ -609,6 +609,34 @@ METHOD(phase1_t, get_id, identification_t*,
|
||||
return id;
|
||||
}
|
||||
|
||||
METHOD(phase1_t, has_virtual_ip, bool,
|
||||
private_phase1_t *this, peer_cfg_t *peer_cfg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
bool found = FALSE;
|
||||
host_t *host;
|
||||
|
||||
enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
|
||||
found = enumerator->enumerate(enumerator, &host);
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(phase1_t, has_pool, bool,
|
||||
private_phase1_t *this, peer_cfg_t *peer_cfg)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
bool found = FALSE;
|
||||
char *pool;
|
||||
|
||||
enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
found = enumerator->enumerate(enumerator, &pool);
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(phase1_t, save_sa_payload, bool,
|
||||
private_phase1_t *this, message_t *message)
|
||||
{
|
||||
@@ -748,6 +776,8 @@ phase1_t *phase1_create(ike_sa_t *ike_sa, bool initiator)
|
||||
.get_auth_method = _get_auth_method,
|
||||
.get_id = _get_id,
|
||||
.select_config = _select_config,
|
||||
.has_virtual_ip = _has_virtual_ip,
|
||||
.has_pool = _has_pool,
|
||||
.verify_auth = _verify_auth,
|
||||
.build_auth = _build_auth,
|
||||
.save_sa_payload = _save_sa_payload,
|
||||
|
||||
@@ -108,6 +108,22 @@ struct phase1_t {
|
||||
*/
|
||||
identification_t* (*get_id)(phase1_t *this, peer_cfg_t *peer_cfg, bool local);
|
||||
|
||||
/**
|
||||
* Check if peer config has virtual IPs pool assigned.
|
||||
*
|
||||
* @param peer_cfg peer_config to check
|
||||
* @return TRUE if peer config contains at least one pool
|
||||
*/
|
||||
bool (*has_pool)(phase1_t *this, peer_cfg_t *peer_cfg);
|
||||
|
||||
/**
|
||||
* Check if peer config has virtual IPs to request
|
||||
*
|
||||
* @param peer_cfg peer_config to check
|
||||
* @return TRUE if peer config contains at least one virtual IP
|
||||
*/
|
||||
bool (*has_virtual_ip)(phase1_t *this, peer_cfg_t *peer_cfg);
|
||||
|
||||
/**
|
||||
* Extract and store SA payload bytes from encoded message.
|
||||
*
|
||||
|
||||
@@ -346,15 +346,30 @@ METHOD(task_manager_t, retransmit, status_t,
|
||||
*/
|
||||
static bool mode_config_expected(private_task_manager_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
peer_cfg_t *peer_cfg;
|
||||
char *pool;
|
||||
host_t *host;
|
||||
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (peer_cfg && peer_cfg->get_pool(peer_cfg))
|
||||
if (peer_cfg)
|
||||
{
|
||||
if (!this->ike_sa->get_virtual_ip(this->ike_sa, FALSE))
|
||||
{
|
||||
enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
if (!enumerator->enumerate(enumerator, &pool))
|
||||
{ /* no pool configured */
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
|
||||
FALSE);
|
||||
if (!enumerator->enumerate(enumerator, &host))
|
||||
{ /* have a pool, but no VIP assigned yet */
|
||||
enumerator->destroy(enumerator);
|
||||
return TRUE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1309,11 +1324,12 @@ METHOD(task_manager_t, queue_ike_reauth, void,
|
||||
new->set_other_host(new, host->clone(host));
|
||||
host = this->ike_sa->get_my_host(this->ike_sa);
|
||||
new->set_my_host(new, host->clone(host));
|
||||
host = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
if (host)
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
new->set_virtual_ip(new, TRUE, host);
|
||||
new->add_virtual_ip(new, TRUE, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
|
||||
while (enumerator->enumerate(enumerator, &child_sa))
|
||||
|
||||
@@ -320,7 +320,7 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (this->peer_cfg->get_virtual_ip(this->peer_cfg))
|
||||
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
@@ -497,8 +497,8 @@ METHOD(task_t, process_r, status_t,
|
||||
this->ike_sa->get_id(this->ike_sa)));
|
||||
break;
|
||||
}
|
||||
if (this->peer_cfg->get_pool(this->peer_cfg) == NULL &&
|
||||
this->peer_cfg->get_virtual_ip(this->peer_cfg))
|
||||
if (!this->ph1->has_pool(this->ph1, this->peer_cfg) &&
|
||||
this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
|
||||
@@ -524,8 +524,8 @@ METHOD(task_t, build_r, status_t,
|
||||
this->ike_sa->get_id(this->ike_sa)));
|
||||
break;
|
||||
}
|
||||
if (this->peer_cfg->get_pool(this->peer_cfg) == NULL &&
|
||||
this->peer_cfg->get_virtual_ip(this->peer_cfg))
|
||||
if (!this->ph1->has_pool(this->ph1, this->peer_cfg) &&
|
||||
this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
@@ -658,7 +658,7 @@ METHOD(task_t, process_i, status_t,
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (this->peer_cfg->get_virtual_ip(this->peer_cfg))
|
||||
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
|
||||
@@ -42,9 +42,9 @@ struct private_mode_config_t {
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* virtual ip
|
||||
* Received list of virtual IPs, host_t*
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
linked_list_t *vips;
|
||||
|
||||
/**
|
||||
* list of attributes requested and its handler, entry_t
|
||||
@@ -174,8 +174,7 @@ static void process_attribute(private_mode_config_t *this,
|
||||
}
|
||||
if (ip)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->virtual_ip = ip;
|
||||
this->vips->insert_last(this->vips, ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -239,23 +238,44 @@ METHOD(task_t, build_i, status_t,
|
||||
peer_cfg_t *config;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t data;
|
||||
host_t *vip;
|
||||
linked_list_t *vips;
|
||||
host_t *host;
|
||||
|
||||
vips = linked_list_create();
|
||||
|
||||
/* reuse virtual IP if we already have one */
|
||||
vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
if (!vip)
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (vips->get_count(vips) == 0)
|
||||
{
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
vip = config->get_virtual_ip(config);
|
||||
}
|
||||
if (vip)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
enumerator = config->create_virtual_ip_enumerator(config);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vip);
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
|
||||
enumerator = vips->create_enumerator(vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
cp->add_attribute(cp, build_vip(host));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(
|
||||
hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vips);
|
||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
||||
{
|
||||
configuration_attribute_t *ca;
|
||||
@@ -279,6 +299,8 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
vips->destroy(vips);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
@@ -299,37 +321,64 @@ METHOD(task_t, build_r, status_t,
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t value;
|
||||
host_t *vip = NULL;
|
||||
cp_payload_t *cp = NULL;
|
||||
peer_cfg_t *config;
|
||||
identification_t *id;
|
||||
linked_list_t *vips, *pools;
|
||||
host_t *requested;
|
||||
|
||||
id = this->ike_sa->get_other_eap_id(this->ike_sa);
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (this->virtual_ip)
|
||||
vips = linked_list_create();
|
||||
pools = linked_list_create();
|
||||
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &requested))
|
||||
{
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
||||
if (config->get_pool(config))
|
||||
enumerator_t *poolenum;
|
||||
char *pool;
|
||||
host_t *found = NULL;
|
||||
|
||||
/* query all pools until we get an address */
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
|
||||
|
||||
poolenum = config->create_pool_enumerator(config);
|
||||
while (poolenum->enumerate(poolenum, &pool))
|
||||
{
|
||||
vip = hydra->attributes->acquire_address(hydra->attributes,
|
||||
config->get_pool(config), id, this->virtual_ip);
|
||||
found = hydra->attributes->acquire_address(hydra->attributes,
|
||||
pool, id, requested);
|
||||
if (!found)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
|
||||
if (!cp)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY);
|
||||
}
|
||||
cp->add_attribute(cp, build_vip(found));
|
||||
/* use pool to request other attributes */
|
||||
if (pools->find_first(pools, NULL, (void**)&pool) == NOT_FOUND)
|
||||
{
|
||||
pools->insert_last(pools, pool);
|
||||
}
|
||||
vips->insert_last(vips, found);
|
||||
break;
|
||||
}
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY);
|
||||
if (vip)
|
||||
poolenum->destroy(poolenum);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found, sending empty config payload");
|
||||
DBG1(DBG_IKE, "no virtual IP found for %H requested by '%Y'",
|
||||
requested, id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* query registered providers for additional attributes to include */
|
||||
enumerator = hydra->attributes->create_responder_enumerator(
|
||||
hydra->attributes, config->get_pool(config), id, vip);
|
||||
hydra->attributes, pools, id, vips);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
if (!cp)
|
||||
@@ -343,25 +392,35 @@ METHOD(task_t, build_r, status_t,
|
||||
type, value));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
vips->destroy_offset(vips, offsetof(host_t, destroy));
|
||||
vips->destroy(vips);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
cp->set_identifier(cp, this->identifier);
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
}
|
||||
DESTROY_IF(vip);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(task_t, process_i, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
process_payloads(this, message);
|
||||
|
||||
if (this->virtual_ip)
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
||||
if (!host->is_anyaddr(host))
|
||||
{
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, host);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -374,10 +433,9 @@ METHOD(task_t, get_type, task_type_t,
|
||||
METHOD(task_t, migrate, void,
|
||||
private_mode_config_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
|
||||
this->ike_sa = ike_sa;
|
||||
this->virtual_ip = NULL;
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->vips = linked_list_create();
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->requested = linked_list_create();
|
||||
}
|
||||
@@ -385,7 +443,7 @@ METHOD(task_t, migrate, void,
|
||||
METHOD(task_t, destroy, void,
|
||||
private_mode_config_t *this)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
free(this);
|
||||
}
|
||||
@@ -408,6 +466,7 @@ mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator)
|
||||
.initiator = initiator,
|
||||
.ike_sa = ike_sa,
|
||||
.requested = linked_list_create(),
|
||||
.vips = linked_list_create(),
|
||||
);
|
||||
|
||||
if (initiator)
|
||||
|
||||
@@ -398,11 +398,12 @@ static traffic_selector_t* select_ts(private_quick_mode_t *this, bool local,
|
||||
linked_list_t *supplied)
|
||||
{
|
||||
traffic_selector_t *ts;
|
||||
enumerator_t *enumerator;
|
||||
linked_list_t *list;
|
||||
host_t *host;
|
||||
|
||||
host = this->ike_sa->get_virtual_ip(this->ike_sa, local);
|
||||
if (!host)
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, local);
|
||||
if (!enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (local)
|
||||
{
|
||||
@@ -413,6 +414,7 @@ static traffic_selector_t* select_ts(private_quick_mode_t *this, bool local,
|
||||
host = this->ike_sa->get_other_host(this->ike_sa);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
list = this->config->get_traffic_selectors(this->config, local,
|
||||
supplied, host);
|
||||
if (list->get_first(list, (void**)&ts) == SUCCESS)
|
||||
@@ -831,6 +833,30 @@ static void check_for_rekeyed_child(private_quick_mode_t *this)
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get host to use for dynamic traffic selectors
|
||||
*/
|
||||
static host_t *get_dynamic_host(ike_sa_t *ike_sa, bool local)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
|
||||
if (!enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (local)
|
||||
{
|
||||
host = ike_sa->get_my_host(ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = ike_sa->get_other_host(ike_sa);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return host;
|
||||
}
|
||||
|
||||
METHOD(task_t, process_r, status_t,
|
||||
private_quick_mode_t *this, message_t *message)
|
||||
{
|
||||
@@ -841,7 +867,6 @@ METHOD(task_t, process_r, status_t,
|
||||
sa_payload_t *sa_payload;
|
||||
linked_list_t *tsi, *tsr, *list = NULL;
|
||||
peer_cfg_t *peer_cfg;
|
||||
host_t *me, *other;
|
||||
u_int16_t group;
|
||||
bool private;
|
||||
|
||||
@@ -849,16 +874,6 @@ METHOD(task_t, process_r, status_t,
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
if (!me)
|
||||
{
|
||||
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||
}
|
||||
other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
|
||||
if (!other)
|
||||
{
|
||||
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||
}
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
tsi = linked_list_create();
|
||||
tsr = linked_list_create();
|
||||
@@ -866,7 +881,8 @@ METHOD(task_t, process_r, status_t,
|
||||
tsr->insert_last(tsr, this->tsr);
|
||||
this->tsi = this->tsr = NULL;
|
||||
this->config = peer_cfg->select_child_cfg(peer_cfg, tsr, tsi,
|
||||
me, other);
|
||||
get_dynamic_host(this->ike_sa, TRUE),
|
||||
get_dynamic_host(this->ike_sa, FALSE));
|
||||
if (this->config)
|
||||
{
|
||||
this->tsi = select_ts(this, FALSE, tsi);
|
||||
|
||||
@@ -284,6 +284,30 @@ static void schedule_inactivity_timeout(private_child_create_t *this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get host to use for dynamic traffic selectors
|
||||
*/
|
||||
static host_t *get_dynamic_host(ike_sa_t *ike_sa, bool local)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
|
||||
if (!enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (local)
|
||||
{
|
||||
host = ike_sa->get_my_host(ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
host = ike_sa->get_other_host(ike_sa);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a CHILD_SA for usage, return value:
|
||||
* - FAILED: no acceptable proposal
|
||||
@@ -298,7 +322,7 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
|
||||
chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
|
||||
linked_list_t *my_ts, *other_ts;
|
||||
host_t *me, *other, *other_vip, *my_vip;
|
||||
host_t *me, *other;
|
||||
bool private;
|
||||
|
||||
if (this->proposals == NULL)
|
||||
@@ -314,8 +338,6 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
|
||||
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||
my_vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
other_vip = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
|
||||
|
||||
private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
|
||||
this->proposal = this->config->select_proposal(this->config,
|
||||
@@ -354,15 +376,6 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
this->dh_group = MODP_NONE;
|
||||
}
|
||||
|
||||
if (my_vip == NULL)
|
||||
{
|
||||
my_vip = me;
|
||||
}
|
||||
if (other_vip == NULL)
|
||||
{
|
||||
other_vip = other;
|
||||
}
|
||||
|
||||
if (this->initiator)
|
||||
{
|
||||
nonce_i = this->my_nonce;
|
||||
@@ -378,9 +391,9 @@ static status_t select_and_install(private_child_create_t *this,
|
||||
other_ts = this->tsi;
|
||||
}
|
||||
my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts,
|
||||
my_vip);
|
||||
get_dynamic_host(this->ike_sa, TRUE));
|
||||
other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts,
|
||||
other_vip);
|
||||
get_dynamic_host(this->ike_sa, FALSE));
|
||||
|
||||
if (this->initiator)
|
||||
{
|
||||
@@ -723,7 +736,8 @@ static void process_payloads(private_child_create_t *this, message_t *message)
|
||||
METHOD(task_t, build_i, status_t,
|
||||
private_child_create_t *this, message_t *message)
|
||||
{
|
||||
host_t *me, *other, *vip;
|
||||
enumerator_t *enumerator;
|
||||
host_t *vip;
|
||||
peer_cfg_t *peer_cfg;
|
||||
|
||||
switch (message->get_exchange_type(message))
|
||||
@@ -763,22 +777,10 @@ METHOD(task_t, build_i, status_t,
|
||||
this->config->get_name(this->config));
|
||||
}
|
||||
|
||||
/* reuse virtual IP if we already have one */
|
||||
me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
if (me == NULL)
|
||||
{
|
||||
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||
}
|
||||
other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
|
||||
if (other == NULL)
|
||||
{
|
||||
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||
}
|
||||
|
||||
/* check if we want a virtual IP, but don't have one */
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
vip = peer_cfg->get_virtual_ip(peer_cfg);
|
||||
if (!this->reqid && vip)
|
||||
enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
|
||||
if (!this->reqid && enumerator->enumerate(enumerator, &vip))
|
||||
{
|
||||
/* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
|
||||
vip = host_create_any(vip->get_family(vip));
|
||||
@@ -788,11 +790,12 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
else
|
||||
{ /* but narrow it for host2host / if we already have a vip */
|
||||
this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
|
||||
NULL, me);
|
||||
this->tsi = this->config->get_traffic_selectors(this->config, TRUE, NULL,
|
||||
get_dynamic_host(this->ike_sa, TRUE));
|
||||
}
|
||||
this->tsr = this->config->get_traffic_selectors(this->config, FALSE,
|
||||
NULL, other);
|
||||
enumerator->destroy(enumerator);
|
||||
this->tsr = this->config->get_traffic_selectors(this->config, FALSE, NULL,
|
||||
get_dynamic_host(this->ike_sa, FALSE));
|
||||
|
||||
if (this->packet_tsi)
|
||||
{
|
||||
@@ -948,20 +951,10 @@ METHOD(task_t, build_r, status_t,
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (!this->config && peer_cfg && this->tsi && this->tsr)
|
||||
{
|
||||
host_t *me, *other;
|
||||
|
||||
me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
if (me == NULL)
|
||||
{
|
||||
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||
}
|
||||
other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
|
||||
if (other == NULL)
|
||||
{
|
||||
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||
}
|
||||
this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
|
||||
this->tsi, me, other);
|
||||
this->config = peer_cfg->select_child_cfg(peer_cfg,
|
||||
this->tsr, this->tsi,
|
||||
get_dynamic_host(this->ike_sa, TRUE),
|
||||
get_dynamic_host(this->ike_sa, FALSE));
|
||||
}
|
||||
|
||||
if (this->config == NULL)
|
||||
|
||||
@@ -43,9 +43,9 @@ struct private_ike_config_t {
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* virtual ip
|
||||
* Received list of virtual IPs, host_t*
|
||||
*/
|
||||
host_t *virtual_ip;
|
||||
linked_list_t *vips;
|
||||
|
||||
/**
|
||||
* list of attributes requested and its handler, entry_t
|
||||
@@ -170,8 +170,7 @@ static void process_attribute(private_ike_config_t *this,
|
||||
}
|
||||
if (ip)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->virtual_ip = ip;
|
||||
this->vips->insert_last(this->vips, ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -242,23 +241,45 @@ METHOD(task_t, build_i, status_t,
|
||||
peer_cfg_t *config;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t data;
|
||||
host_t *vip;
|
||||
linked_list_t *vips;
|
||||
host_t *host;
|
||||
|
||||
vips = linked_list_create();
|
||||
|
||||
/* reuse virtual IP if we already have one */
|
||||
vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
||||
if (!vip)
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
|
||||
TRUE);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (vips->get_count(vips) == 0)
|
||||
{
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
vip = config->get_virtual_ip(config);
|
||||
}
|
||||
if (vip)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
enumerator = config->create_virtual_ip_enumerator(config);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vip);
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REQUEST);
|
||||
enumerator = vips->create_enumerator(vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
cp->add_attribute(cp, build_vip(host));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
enumerator = hydra->attributes->create_initiator_enumerator(
|
||||
hydra->attributes,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vips);
|
||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
||||
{
|
||||
configuration_attribute_t *ca;
|
||||
@@ -284,6 +305,8 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
vips->destroy(vips);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
@@ -310,40 +333,75 @@ METHOD(task_t, build_r, status_t,
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t value;
|
||||
host_t *vip = NULL;
|
||||
cp_payload_t *cp = NULL;
|
||||
peer_cfg_t *config;
|
||||
identification_t *id;
|
||||
linked_list_t *vips, *pools;
|
||||
host_t *requested;
|
||||
|
||||
id = this->ike_sa->get_other_eap_id(this->ike_sa);
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (this->virtual_ip)
|
||||
{
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
||||
if (config->get_pool(config))
|
||||
{
|
||||
vip = hydra->attributes->acquire_address(hydra->attributes,
|
||||
config->get_pool(config), id, this->virtual_ip);
|
||||
}
|
||||
if (vip == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found, sending %N",
|
||||
notify_type_names, INTERNAL_ADDRESS_FAILURE);
|
||||
message->add_notify(message, FALSE, INTERNAL_ADDRESS_FAILURE,
|
||||
chunk_empty);
|
||||
return SUCCESS;
|
||||
}
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
|
||||
vips = linked_list_create();
|
||||
pools = linked_list_create();
|
||||
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REPLY);
|
||||
cp->add_attribute(cp, build_vip(vip));
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &requested))
|
||||
{
|
||||
enumerator_t *poolenum;
|
||||
char *pool;
|
||||
host_t *found = NULL;
|
||||
|
||||
/* query all pools until we get an address */
|
||||
DBG1(DBG_IKE, "peer requested virtual IP %H", requested);
|
||||
|
||||
poolenum = config->create_pool_enumerator(config);
|
||||
while (poolenum->enumerate(poolenum, &pool))
|
||||
{
|
||||
found = hydra->attributes->acquire_address(hydra->attributes,
|
||||
pool, id, requested);
|
||||
if (!found)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
|
||||
if (!cp)
|
||||
{
|
||||
cp = cp_payload_create_type(CONFIGURATION, CFG_REPLY);
|
||||
}
|
||||
cp->add_attribute(cp, build_vip(found));
|
||||
/* use pool to request other attributes */
|
||||
if (pools->find_first(pools, NULL, (void**)&pool) == NOT_FOUND)
|
||||
{
|
||||
pools->insert_last(pools, pool);
|
||||
}
|
||||
vips->insert_last(vips, found);
|
||||
break;
|
||||
}
|
||||
poolenum->destroy(poolenum);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found for %H requested by '%Y'",
|
||||
requested, id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (this->vips->get_count(this->vips) && !vips->get_count(vips))
|
||||
{
|
||||
DBG1(DBG_IKE, "no virtual IP found, sending %N",
|
||||
notify_type_names, INTERNAL_ADDRESS_FAILURE);
|
||||
message->add_notify(message, FALSE, INTERNAL_ADDRESS_FAILURE,
|
||||
chunk_empty);
|
||||
vips->destroy_offset(vips, offsetof(host_t, destroy));
|
||||
pools->destroy(pools);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* query registered providers for additional attributes to include */
|
||||
enumerator = hydra->attributes->create_responder_enumerator(
|
||||
hydra->attributes, config->get_pool(config), id, vip);
|
||||
hydra->attributes, pools, id, vips);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
if (!cp)
|
||||
@@ -357,12 +415,13 @@ METHOD(task_t, build_r, status_t,
|
||||
type, value));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
vips->destroy_offset(vips, offsetof(host_t, destroy));
|
||||
pools->destroy(pools);
|
||||
|
||||
if (cp)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
}
|
||||
DESTROY_IF(vip);
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
@@ -373,14 +432,20 @@ METHOD(task_t, process_i, status_t,
|
||||
{
|
||||
if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
|
||||
{ /* in last IKE_AUTH exchange */
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
process_payloads(this, message);
|
||||
|
||||
if (this->virtual_ip &&
|
||||
!this->virtual_ip->is_anyaddr(this->virtual_ip))
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
||||
if (!host->is_anyaddr(host))
|
||||
{
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, host);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return SUCCESS;
|
||||
}
|
||||
return NEED_MORE;
|
||||
@@ -395,10 +460,9 @@ METHOD(task_t, get_type, task_type_t,
|
||||
METHOD(task_t, migrate, void,
|
||||
private_ike_config_t *this, ike_sa_t *ike_sa)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
|
||||
this->ike_sa = ike_sa;
|
||||
this->virtual_ip = NULL;
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->vips = linked_list_create();
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->requested = linked_list_create();
|
||||
}
|
||||
@@ -406,7 +470,7 @@ METHOD(task_t, migrate, void,
|
||||
METHOD(task_t, destroy, void,
|
||||
private_ike_config_t *this)
|
||||
{
|
||||
DESTROY_IF(this->virtual_ip);
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
free(this);
|
||||
}
|
||||
@@ -428,6 +492,7 @@ ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator)
|
||||
},
|
||||
.initiator = initiator,
|
||||
.ike_sa = ike_sa,
|
||||
.vips = linked_list_create(),
|
||||
.requested = linked_list_create(),
|
||||
);
|
||||
|
||||
|
||||
@@ -250,15 +250,26 @@ static void update_children(private_ike_mobike_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
child_sa_t *child_sa;
|
||||
linked_list_t *vips;
|
||||
host_t *host;
|
||||
|
||||
vips = linked_list_create();
|
||||
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
vips->insert_last(vips, host);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa);
|
||||
while (enumerator->enumerate(enumerator, (void**)&child_sa))
|
||||
{
|
||||
if (child_sa->update(child_sa,
|
||||
this->ike_sa->get_my_host(this->ike_sa),
|
||||
this->ike_sa->get_other_host(this->ike_sa),
|
||||
this->ike_sa->get_virtual_ip(this->ike_sa, TRUE),
|
||||
this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED)
|
||||
this->ike_sa->get_other_host(this->ike_sa), vips,
|
||||
this->ike_sa->has_condition(this->ike_sa,
|
||||
COND_NAT_ANY)) == NOT_SUPPORTED)
|
||||
{
|
||||
this->ike_sa->rekey_child_sa(this->ike_sa,
|
||||
child_sa->get_protocol(child_sa),
|
||||
@@ -266,6 +277,8 @@ static void update_children(private_ike_mobike_t *this)
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
vips->destroy(vips);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#define ATTRIBUTE_HANDLER_H_
|
||||
|
||||
#include <chunk.h>
|
||||
#include <utils/host.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
#include "attributes.h"
|
||||
|
||||
@@ -62,11 +62,11 @@ struct attribute_handler_t {
|
||||
* Enumerate attributes to request from a server.
|
||||
*
|
||||
* @param server server identity to request attributes from
|
||||
* @param vip virtual IP we are requesting, if any
|
||||
* @param vips list of virtual IPs (host_t*) we are requesting
|
||||
* @return enumerator (configuration_attribute_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this,
|
||||
identification_t *server, host_t *vip);
|
||||
identification_t *server, linked_list_t *vips);
|
||||
};
|
||||
|
||||
#endif /** ATTRIBUTE_HANDLER_H_ @}*/
|
||||
|
||||
@@ -51,12 +51,12 @@ struct private_attribute_manager_t {
|
||||
* Data to pass to enumerator filters
|
||||
*/
|
||||
typedef struct {
|
||||
/** attribute group pool */
|
||||
char *pool;
|
||||
/** attribute group pools */
|
||||
linked_list_t *pools;
|
||||
/** server/peer identity */
|
||||
identification_t *id;
|
||||
/** requesting/assigned virtual IP */
|
||||
host_t *vip;
|
||||
/** requesting/assigned virtual IPs */
|
||||
linked_list_t *vips;
|
||||
} enum_data_t;
|
||||
|
||||
METHOD(attribute_manager_t, acquire_address, host_t*,
|
||||
@@ -80,14 +80,10 @@ METHOD(attribute_manager_t, acquire_address, host_t*,
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
if (!host)
|
||||
{
|
||||
DBG1(DBG_CFG, "acquiring address from pool '%s' failed", pool);
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
METHOD(attribute_manager_t, release_address, void,
|
||||
METHOD(attribute_manager_t, release_address, bool,
|
||||
private_attribute_manager_t *this, char *pool, host_t *address,
|
||||
identification_t *id)
|
||||
{
|
||||
@@ -108,10 +104,7 @@ METHOD(attribute_manager_t, release_address, void,
|
||||
enumerator->destroy(enumerator);
|
||||
this->lock->unlock(this->lock);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DBG1(DBG_CFG, "releasing address to pool '%s' failed", pool);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,19 +113,21 @@ METHOD(attribute_manager_t, release_address, void,
|
||||
static enumerator_t *responder_enum_create(attribute_provider_t *provider,
|
||||
enum_data_t *data)
|
||||
{
|
||||
return provider->create_attribute_enumerator(provider, data->pool,
|
||||
data->id, data->vip);
|
||||
return provider->create_attribute_enumerator(provider, data->pools,
|
||||
data->id, data->vips);
|
||||
}
|
||||
|
||||
METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*,
|
||||
private_attribute_manager_t *this, char *pool, identification_t *id,
|
||||
host_t *vip)
|
||||
private_attribute_manager_t *this, linked_list_t *pools,
|
||||
identification_t *id, linked_list_t *vips)
|
||||
{
|
||||
enum_data_t *data = malloc_thing(enum_data_t);
|
||||
enum_data_t *data;
|
||||
|
||||
data->pool = pool;
|
||||
data->id = id;
|
||||
data->vip = vip;
|
||||
INIT(data,
|
||||
.pools = pools,
|
||||
.id = id,
|
||||
.vips = vips,
|
||||
);
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_cleaner(
|
||||
enumerator_create_nested(
|
||||
@@ -238,8 +233,8 @@ typedef struct {
|
||||
enumerator_t *inner;
|
||||
/** server ID we want attributes for */
|
||||
identification_t *id;
|
||||
/** virtual IP we are requesting along with attriubutes */
|
||||
host_t *vip;
|
||||
/** virtual IPs we are requesting along with attriubutes */
|
||||
linked_list_t *vips;
|
||||
} initiator_enumerator_t;
|
||||
|
||||
/**
|
||||
@@ -259,7 +254,7 @@ static bool initiator_enumerate(initiator_enumerator_t *this,
|
||||
}
|
||||
DESTROY_IF(this->inner);
|
||||
this->inner = this->handler->create_attribute_enumerator(this->handler,
|
||||
this->id, this->vip);
|
||||
this->id, this->vips);
|
||||
}
|
||||
/* inject the handler as additional attribute */
|
||||
*handler = this->handler;
|
||||
@@ -278,20 +273,22 @@ static void initiator_destroy(initiator_enumerator_t *this)
|
||||
}
|
||||
|
||||
METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*,
|
||||
private_attribute_manager_t *this, identification_t *id, host_t *vip)
|
||||
private_attribute_manager_t *this, identification_t *id, linked_list_t *vips)
|
||||
{
|
||||
initiator_enumerator_t *enumerator = malloc_thing(initiator_enumerator_t);
|
||||
initiator_enumerator_t *enumerator;
|
||||
|
||||
this->lock->read_lock(this->lock);
|
||||
enumerator->public.enumerate = (void*)initiator_enumerate;
|
||||
enumerator->public.destroy = (void*)initiator_destroy;
|
||||
enumerator->this = this;
|
||||
enumerator->id = id;
|
||||
enumerator->vip = vip;
|
||||
enumerator->outer = this->handlers->create_enumerator(this->handlers);
|
||||
enumerator->inner = NULL;
|
||||
enumerator->handler = NULL;
|
||||
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)initiator_enumerate,
|
||||
.destroy = (void*)initiator_destroy,
|
||||
},
|
||||
.this = this,
|
||||
.id = id,
|
||||
.vips = vips,
|
||||
.outer = this->handlers->create_enumerator(this->handlers),
|
||||
);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,20 +54,22 @@ struct attribute_manager_t {
|
||||
* @param pool pool name from which the address was acquired
|
||||
* @param address address to release
|
||||
* @param id peer identity to get address for
|
||||
* @return TRUE if address released to pool
|
||||
*/
|
||||
void (*release_address)(attribute_manager_t *this,
|
||||
bool (*release_address)(attribute_manager_t *this,
|
||||
char *pool, host_t *address, identification_t *id);
|
||||
|
||||
/**
|
||||
* Create an enumerator over attributes to hand out to a peer.
|
||||
*
|
||||
* @param pool pool name to get attributes from
|
||||
* @param pool list of pools names (char*) to query attributes from
|
||||
* @param id peer identity to hand out attributes to
|
||||
* @param vip virtual IP to assign to peer, if any
|
||||
* @param vip list of virtual IPs (host_t*) to assign to peer
|
||||
* @return enumerator (configuration_attribute_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this,
|
||||
char *pool, identification_t *id, host_t *vip);
|
||||
linked_list_t *pool, identification_t *id,
|
||||
linked_list_t *vips);
|
||||
|
||||
/**
|
||||
* Register an attribute provider to the manager.
|
||||
@@ -114,11 +116,11 @@ struct attribute_manager_t {
|
||||
* Create an enumerator over attributes to request from server.
|
||||
*
|
||||
* @param id server identity to hand out attributes to
|
||||
* @param vip virtual IP going to request, if any
|
||||
* @param vip list of virtual IPs (host_t*) going to request
|
||||
* @return enumerator (attribute_handler_t, ca_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this,
|
||||
identification_t *id, host_t *vip);
|
||||
identification_t *id, linked_list_t *vips);
|
||||
|
||||
/**
|
||||
* Register an attribute handler to the manager.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include <utils/host.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
typedef struct attribute_provider_t attribute_provider_t;
|
||||
|
||||
@@ -56,13 +57,14 @@ struct attribute_provider_t {
|
||||
/**
|
||||
* Create an enumerator over attributes to hand out to a peer.
|
||||
*
|
||||
* @param pool pool name to get attributes from
|
||||
* @param pool list of pools names (char*) to query attributes from
|
||||
* @param id peer ID
|
||||
* @param vip virtual IP to assign to peer, if any
|
||||
* @param vip list of virtual IPs (host_t*) to assign to peer
|
||||
* @return enumerator (configuration_attribute_type_t, chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this,
|
||||
char *pool, identification_t *id, host_t *vip);
|
||||
linked_list_t *pools, identification_t *id,
|
||||
linked_list_t *vips);
|
||||
};
|
||||
|
||||
#endif /** ATTRIBUTE_PROVIDER_H_ @}*/
|
||||
|
||||
@@ -162,6 +162,12 @@ METHOD(mem_pool_t, get_name, const char*,
|
||||
return this->name;
|
||||
}
|
||||
|
||||
METHOD(mem_pool_t, get_base, host_t*,
|
||||
private_mem_pool_t *this)
|
||||
{
|
||||
return this->base;
|
||||
}
|
||||
|
||||
METHOD(mem_pool_t, get_size, u_int,
|
||||
private_mem_pool_t *this)
|
||||
{
|
||||
@@ -220,11 +226,9 @@ METHOD(mem_pool_t, acquire_address, host_t*,
|
||||
return requested->clone(requested);
|
||||
}
|
||||
|
||||
if (!requested->is_anyaddr(requested) &&
|
||||
requested->get_family(requested) !=
|
||||
if (requested->get_family(requested) !=
|
||||
this->base->get_family(this->base))
|
||||
{
|
||||
DBG1(DBG_CFG, "IP pool address family mismatch");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -463,6 +467,7 @@ mem_pool_t *mem_pool_create(char *name, host_t *base, int bits)
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_name = _get_name,
|
||||
.get_base = _get_base,
|
||||
.get_size = _get_size,
|
||||
.get_online = _get_online,
|
||||
.get_offline = _get_offline,
|
||||
|
||||
@@ -38,6 +38,13 @@ struct mem_pool_t {
|
||||
*/
|
||||
const char* (*get_name)(mem_pool_t *this);
|
||||
|
||||
/**
|
||||
* Get the base (first) address of this pool.
|
||||
*
|
||||
* @return base address, internal host
|
||||
*/
|
||||
host_t* (*get_base)(mem_pool_t *this);
|
||||
|
||||
/**
|
||||
* Get the size (i.e. number of addresses) of this pool.
|
||||
*
|
||||
|
||||
@@ -77,10 +77,10 @@ static bool attr_enum_filter(void *null, attribute_entry_t **in,
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_attr_provider_t *this, char *pool,
|
||||
identification_t *id, host_t *vip)
|
||||
private_attr_provider_t *this, linked_list_t *pools,
|
||||
identification_t *id, linked_list_t *vips)
|
||||
{
|
||||
if (vip)
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
this->lock->read_lock(this->lock);
|
||||
return enumerator_create_filter(
|
||||
|
||||
@@ -233,7 +233,7 @@ static host_t* get_lease(private_sql_attribute_t *this, char *name,
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, acquire_address, host_t*,
|
||||
private_sql_attribute_t *this, char *names, identification_t *id,
|
||||
private_sql_attribute_t *this, char *name, identification_t *id,
|
||||
host_t *requested)
|
||||
{
|
||||
host_t *address = NULL;
|
||||
@@ -242,59 +242,17 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
|
||||
identity = get_identity(this, id);
|
||||
if (identity)
|
||||
{
|
||||
/* check for a single pool first (no concatenation and enumeration) */
|
||||
if (strchr(names, ',') == NULL)
|
||||
pool = get_pool(this, name, &timeout);
|
||||
if (pool)
|
||||
{
|
||||
pool = get_pool(this, names, &timeout);
|
||||
if (pool)
|
||||
/* check for an existing lease */
|
||||
address = check_lease(this, name, pool, identity);
|
||||
if (address == NULL)
|
||||
{
|
||||
/* check for an existing lease */
|
||||
address = check_lease(this, names, pool, identity);
|
||||
if (address == NULL)
|
||||
{
|
||||
/* get an unallocated address or expired lease */
|
||||
address = get_lease(this, names, pool, timeout, identity);
|
||||
}
|
||||
/* get an unallocated address or expired lease */
|
||||
address = get_lease(this, name, pool, timeout, identity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
char *name;
|
||||
|
||||
/* in a first step check for an existing lease over all pools */
|
||||
enumerator = enumerator_create_token(names, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &name))
|
||||
{
|
||||
pool = get_pool(this, name, &timeout);
|
||||
if (pool)
|
||||
{
|
||||
address = check_lease(this, name, pool, identity);
|
||||
if (address)
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
return address;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* in a second step get an unallocated address or expired lease */
|
||||
enumerator = enumerator_create_token(names, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &name))
|
||||
{
|
||||
pool = get_pool(this, name, &timeout);
|
||||
if (pool)
|
||||
{
|
||||
address = get_lease(this, name, pool, timeout, identity);
|
||||
if (address)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
@@ -303,50 +261,41 @@ METHOD(attribute_provider_t, release_address, bool,
|
||||
private_sql_attribute_t *this, char *name, host_t *address,
|
||||
identification_t *id)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
bool found = FALSE;
|
||||
u_int pool, timeout;
|
||||
time_t now = time(NULL);
|
||||
|
||||
enumerator = enumerator_create_token(name, ",", " ");
|
||||
while (enumerator->enumerate(enumerator, &name))
|
||||
pool = get_pool(this, name, &timeout);
|
||||
if (pool)
|
||||
{
|
||||
u_int pool, timeout;
|
||||
|
||||
pool = get_pool(this, name, &timeout);
|
||||
if (pool)
|
||||
if (this->history)
|
||||
{
|
||||
if (this->history)
|
||||
{
|
||||
this->db->execute(this->db, NULL,
|
||||
"INSERT INTO leases (address, identity, acquired, released)"
|
||||
" SELECT id, identity, acquired, ? FROM addresses "
|
||||
" WHERE pool = ? AND address = ?",
|
||||
DB_UINT, now, DB_UINT, pool,
|
||||
DB_BLOB, address->get_address(address));
|
||||
}
|
||||
if (this->db->execute(this->db, NULL,
|
||||
"UPDATE addresses SET released = ? WHERE "
|
||||
"pool = ? AND address = ?", DB_UINT, time(NULL),
|
||||
DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
this->db->execute(this->db, NULL,
|
||||
"INSERT INTO leases (address, identity, acquired, released)"
|
||||
" SELECT id, identity, acquired, ? FROM addresses "
|
||||
" WHERE pool = ? AND address = ?",
|
||||
DB_UINT, now, DB_UINT, pool,
|
||||
DB_BLOB, address->get_address(address));
|
||||
}
|
||||
if (this->db->execute(this->db, NULL,
|
||||
"UPDATE addresses SET released = ? WHERE "
|
||||
"pool = ? AND address = ?", DB_UINT, time(NULL),
|
||||
DB_UINT, pool, DB_BLOB, address->get_address(address)) > 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return found;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_sql_attribute_t *this, char *names, identification_t *id,
|
||||
host_t *vip)
|
||||
private_sql_attribute_t *this, linked_list_t *pools, identification_t *id,
|
||||
linked_list_t *vips)
|
||||
{
|
||||
enumerator_t *attr_enumerator = NULL;
|
||||
|
||||
if (vip)
|
||||
if (vips->get_count(vips))
|
||||
{
|
||||
enumerator_t *names_enumerator;
|
||||
enumerator_t *pool_enumerator;
|
||||
u_int count;
|
||||
char *name;
|
||||
|
||||
@@ -357,8 +306,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
{
|
||||
u_int identity = get_identity(this, id);
|
||||
|
||||
names_enumerator = enumerator_create_token(names, ",", " ");
|
||||
while (names_enumerator->enumerate(names_enumerator, &name))
|
||||
pool_enumerator = pools->create_enumerator(pools);
|
||||
while (pool_enumerator->enumerate(pool_enumerator, &name))
|
||||
{
|
||||
u_int attr_pool = get_attr_pool(this, name);
|
||||
if (!attr_pool)
|
||||
@@ -385,14 +334,14 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
DESTROY_IF(attr_enumerator);
|
||||
attr_enumerator = NULL;
|
||||
}
|
||||
names_enumerator->destroy(names_enumerator);
|
||||
pool_enumerator->destroy(pool_enumerator);
|
||||
}
|
||||
|
||||
/* in a second step check for attributes that match name */
|
||||
if (!attr_enumerator)
|
||||
{
|
||||
names_enumerator = enumerator_create_token(names, ",", " ");
|
||||
while (names_enumerator->enumerate(names_enumerator, &name))
|
||||
pool_enumerator = pools->create_enumerator(pools);
|
||||
while (pool_enumerator->enumerate(pool_enumerator, &name))
|
||||
{
|
||||
u_int attr_pool = get_attr_pool(this, name);
|
||||
if (!attr_pool)
|
||||
@@ -419,7 +368,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
|
||||
DESTROY_IF(attr_enumerator);
|
||||
attr_enumerator = NULL;
|
||||
}
|
||||
names_enumerator->destroy(names_enumerator);
|
||||
pool_enumerator->destroy(pool_enumerator);
|
||||
}
|
||||
|
||||
this->db->execute(this->db, NULL, "END TRANSACTION");
|
||||
|
||||
@@ -267,46 +267,71 @@ METHOD(attribute_handler_t, release, void,
|
||||
typedef struct {
|
||||
/** implements enumerator_t interface */
|
||||
enumerator_t public;
|
||||
/** virtual IP we are requesting */
|
||||
host_t *vip;
|
||||
/** request IPv4 DNS? */
|
||||
bool v4;
|
||||
/** request IPv6 DNS? */
|
||||
bool v6;
|
||||
} attribute_enumerator_t;
|
||||
|
||||
static bool attribute_enumerate(attribute_enumerator_t *this,
|
||||
configuration_attribute_type_t *type,
|
||||
chunk_t *data)
|
||||
{
|
||||
switch (this->vip->get_family(this->vip))
|
||||
if (this->v4)
|
||||
{
|
||||
case AF_INET:
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
break;
|
||||
case AF_INET6:
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
*type = INTERNAL_IP4_DNS;
|
||||
*data = chunk_empty;
|
||||
this->v4 = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
*data = chunk_empty;
|
||||
/* enumerate only once */
|
||||
this->public.enumerate = (void*)return_false;
|
||||
return TRUE;
|
||||
if (this->v6)
|
||||
{
|
||||
*type = INTERNAL_IP6_DNS;
|
||||
*data = chunk_empty;
|
||||
this->v6 = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a list has a host of given family
|
||||
*/
|
||||
static bool has_host_family(linked_list_t *list, int family)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
bool found = FALSE;
|
||||
|
||||
enumerator = list->create_enumerator(list);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (host->get_family(host) == family)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_resolve_handler_t *this, identification_t *server, host_t *vip)
|
||||
private_resolve_handler_t *this, identification_t *server,
|
||||
linked_list_t *vips)
|
||||
{
|
||||
if (vip)
|
||||
{
|
||||
attribute_enumerator_t *enumerator;
|
||||
attribute_enumerator_t *enumerator;
|
||||
|
||||
enumerator = malloc_thing(attribute_enumerator_t);
|
||||
enumerator->public.enumerate = (void*)attribute_enumerate;
|
||||
enumerator->public.destroy = (void*)free;
|
||||
enumerator->vip = vip;
|
||||
|
||||
return &enumerator->public;
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)attribute_enumerate,
|
||||
.destroy = (void*)free,
|
||||
},
|
||||
.v4 = has_host_family(vips, AF_INET),
|
||||
.v6 = has_host_family(vips, AF_INET6),
|
||||
);
|
||||
return &enumerator->public;
|
||||
}
|
||||
|
||||
METHOD(resolve_handler_t, destroy, void,
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ static const token_info_t token_info[] =
|
||||
{ ARG_STR, offsetof(starter_end_t, subnet), NULL },
|
||||
{ ARG_MISC, 0, NULL /* KW_PROTOPORT */ },
|
||||
{ ARG_STR, offsetof(starter_end_t, sourceip), NULL },
|
||||
{ ARG_MISC, 0, NULL /* KW_NATIP */ },
|
||||
{ ARG_STR, offsetof(starter_end_t, dns), NULL },
|
||||
{ ARG_ENUM, offsetof(starter_end_t, firewall), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool },
|
||||
{ ARG_ENUM, offsetof(starter_end_t, allow_any), LST_bool },
|
||||
|
||||
@@ -26,7 +26,6 @@ static bool starter_cmp_end(starter_end_t *c1, starter_end_t *c2)
|
||||
if ((c1 == NULL) || (c2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
VARCMP(has_natip);
|
||||
VARCMP(modecfg);
|
||||
VARCMP(port);
|
||||
VARCMP(protocol);
|
||||
|
||||
@@ -231,64 +231,6 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
|
||||
end->host = strdupnull(value);
|
||||
break;
|
||||
case KW_SOURCEIP:
|
||||
if (end->has_natip)
|
||||
{
|
||||
DBG1(DBG_APP, "# natip and sourceip cannot be defined at the same time");
|
||||
goto err;
|
||||
}
|
||||
if (value[0] == '%')
|
||||
{
|
||||
if (streq(value, "%modeconfig") || streq(value, "%modecfg") ||
|
||||
streq(value, "%config") || streq(value, "%cfg"))
|
||||
{
|
||||
/* request ip via config payload */
|
||||
free(end->sourceip);
|
||||
end->sourceip = NULL;
|
||||
end->sourceip_mask = 1;
|
||||
}
|
||||
else
|
||||
{ /* %poolname, strip %, serve ip requests */
|
||||
free(end->sourceip);
|
||||
end->sourceip = strdupnull(value+1);
|
||||
end->sourceip_mask = 0;
|
||||
}
|
||||
end->modecfg = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
host_t *host;
|
||||
char *sep;
|
||||
|
||||
sep = strchr(value, '/');
|
||||
if (sep)
|
||||
{ /* CIDR notation, address pool */
|
||||
*sep = '\0';
|
||||
host = host_create_from_string(value, 0);
|
||||
if (!host)
|
||||
{
|
||||
DBG1(DBG_APP, "# bad subnet: %s=%s", name, value);
|
||||
goto err;
|
||||
}
|
||||
host->destroy(host);
|
||||
free(end->sourceip);
|
||||
end->sourceip = strdupnull(value);
|
||||
end->sourceip_mask = atoi(sep + 1);
|
||||
/* restore the original text in case also= is used */
|
||||
*sep = '/';
|
||||
}
|
||||
else
|
||||
{ /* fixed srcip */
|
||||
host = host_create_from_string(value, 0);
|
||||
if (!host)
|
||||
{
|
||||
DBG1(DBG_APP, "# bad addr: %s=%s", name, value);
|
||||
goto err;
|
||||
}
|
||||
end->sourceip_mask = (host->get_family(host) == AF_INET) ?
|
||||
32 : 128;
|
||||
host->destroy(host);
|
||||
}
|
||||
}
|
||||
conn->mode = MODE_TUNNEL;
|
||||
conn->proxy_mode = FALSE;
|
||||
break;
|
||||
@@ -370,27 +312,6 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KW_NATIP:
|
||||
{
|
||||
host_t *host;
|
||||
if (end->sourceip)
|
||||
{
|
||||
DBG1(DBG_APP, "# natip and sourceip cannot be defined at the same time");
|
||||
goto err;
|
||||
}
|
||||
host = host_create_from_string(value, 0);
|
||||
if (!host)
|
||||
{
|
||||
DBG1(DBG_APP, "# bad addr: %s=%s", name, value);
|
||||
goto err;
|
||||
}
|
||||
host->destroy(host);
|
||||
end->sourceip = strdupnull(value);
|
||||
end->has_natip = TRUE;
|
||||
conn->mode = MODE_TUNNEL;
|
||||
conn->proxy_mode = FALSE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -102,7 +102,6 @@ struct starter_end {
|
||||
char *host;
|
||||
u_int ikeport;
|
||||
char *subnet;
|
||||
bool has_natip;
|
||||
bool modecfg;
|
||||
certpolicy_t sendcert;
|
||||
bool firewall;
|
||||
@@ -112,7 +111,7 @@ struct starter_end {
|
||||
u_int16_t port;
|
||||
u_int8_t protocol;
|
||||
char *sourceip;
|
||||
int sourceip_mask;
|
||||
char *dns;
|
||||
};
|
||||
|
||||
typedef struct also also_t;
|
||||
|
||||
@@ -97,7 +97,7 @@ typedef enum {
|
||||
KW_SUBNET,
|
||||
KW_PROTOPORT,
|
||||
KW_SOURCEIP,
|
||||
KW_NATIP,
|
||||
KW_DNS,
|
||||
KW_FIREWALL,
|
||||
KW_HOSTACCESS,
|
||||
KW_ALLOWANY,
|
||||
@@ -126,7 +126,7 @@ typedef enum {
|
||||
KW_LEFTSUBNET,
|
||||
KW_LEFTPROTOPORT,
|
||||
KW_LEFTSOURCEIP,
|
||||
KW_LEFTNATIP,
|
||||
KW_LEFTDNS,
|
||||
KW_LEFTFIREWALL,
|
||||
KW_LEFTHOSTACCESS,
|
||||
KW_LEFTALLOWANY,
|
||||
@@ -155,7 +155,7 @@ typedef enum {
|
||||
KW_RIGHTSUBNET,
|
||||
KW_RIGHTPROTOPORT,
|
||||
KW_RIGHTSOURCEIP,
|
||||
KW_RIGHTNATIP,
|
||||
KW_RIGHTDNS,
|
||||
KW_RIGHTFIREWALL,
|
||||
KW_RIGHTHOSTACCESS,
|
||||
KW_RIGHTALLOWANY,
|
||||
|
||||
@@ -85,7 +85,7 @@ leftsubnet, KW_LEFTSUBNET
|
||||
leftsubnetwithin, KW_LEFTSUBNET
|
||||
leftprotoport, KW_LEFTPROTOPORT
|
||||
leftsourceip, KW_LEFTSOURCEIP
|
||||
leftnatip, KW_LEFTNATIP
|
||||
leftdns, KW_LEFTDNS
|
||||
leftfirewall, KW_LEFTFIREWALL
|
||||
lefthostaccess, KW_LEFTHOSTACCESS
|
||||
leftallowany, KW_LEFTALLOWANY
|
||||
@@ -109,7 +109,7 @@ rightsubnet, KW_RIGHTSUBNET
|
||||
rightsubnetwithin, KW_RIGHTSUBNET
|
||||
rightprotoport, KW_RIGHTPROTOPORT
|
||||
rightsourceip, KW_RIGHTSOURCEIP
|
||||
rightnatip, KW_RIGHTNATIP
|
||||
rightdns, KW_RIGHTDNS
|
||||
rightfirewall, KW_RIGHTFIREWALL
|
||||
righthostaccess, KW_RIGHTHOSTACCESS
|
||||
rightallowany, KW_RIGHTALLOWANY
|
||||
|
||||
@@ -140,7 +140,7 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
|
||||
msg_end->ikeport = conn_end->ikeport;
|
||||
msg_end->subnets = push_string(msg, conn_end->subnet);
|
||||
msg_end->sourceip = push_string(msg, conn_end->sourceip);
|
||||
msg_end->sourceip_mask = conn_end->sourceip_mask;
|
||||
msg_end->dns = push_string(msg, conn_end->dns);
|
||||
msg_end->sendcert = conn_end->sendcert;
|
||||
msg_end->hostaccess = conn_end->hostaccess;
|
||||
msg_end->tohost = !conn_end->subnet;
|
||||
|
||||
@@ -158,7 +158,7 @@ struct stroke_end_t {
|
||||
char *address;
|
||||
u_int16_t ikeport;
|
||||
char *sourceip;
|
||||
int sourceip_mask;
|
||||
char *dns;
|
||||
char *subnets;
|
||||
int sendcert;
|
||||
int hostaccess;
|
||||
|
||||
Reference in New Issue
Block a user