attr: Only enumerate attributes matching the IKE version of the current IKE_SA

Numerically configured attributes are currently sent for both versions.
This commit is contained in:
Tobias Brunner
2016-03-10 11:57:39 +01:00
parent 98a3ba8a5a
commit 7e854f4d51
+49 -19
View File
@@ -54,6 +54,8 @@ struct attribute_entry_t {
configuration_attribute_type_t type; configuration_attribute_type_t type;
/** attribute value */ /** attribute value */
chunk_t value; chunk_t value;
/** associated IKE version */
ike_version_t ike;
}; };
/** /**
@@ -65,27 +67,52 @@ static void attribute_destroy(attribute_entry_t *this)
free(this); free(this);
} }
/**
* Data for attribute enumerator
*/
typedef struct {
rwlock_t *lock;
ike_version_t ike;
} enumerator_data_t;
/** /**
* convert enumerator value from attribute_entry * convert enumerator value from attribute_entry
*/ */
static bool attr_enum_filter(void *null, attribute_entry_t **in, static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in,
configuration_attribute_type_t *type, void* none, chunk_t *value) configuration_attribute_type_t *type, void* none, chunk_t *value)
{ {
*type = (*in)->type; if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike)
*value = (*in)->value; {
return TRUE; *type = (*in)->type;
*value = (*in)->value;
return TRUE;
}
return FALSE;
}
CALLBACK(attr_enum_destroy, void,
enumerator_data_t *data)
{
data->lock->unlock(data->lock);
free(data);
} }
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_attr_provider_t *this, linked_list_t *pools, private_attr_provider_t *this, linked_list_t *pools,
ike_sa_t *ike_sa, linked_list_t *vips) ike_sa_t *ike_sa, linked_list_t *vips)
{ {
enumerator_data_t *data;
if (vips->get_count(vips)) if (vips->get_count(vips))
{ {
INIT(data,
.lock = this->lock,
.ike = ike_sa->get_version(ike_sa),
);
this->lock->read_lock(this->lock); this->lock->read_lock(this->lock);
return enumerator_create_filter( return enumerator_create_filter(
this->attributes->create_enumerator(this->attributes), this->attributes->create_enumerator(this->attributes),
(void*)attr_enum_filter, this->lock, (void*)this->lock->unlock); (void*)attr_enum_filter, data, attr_enum_destroy);
} }
return enumerator_create_empty(); return enumerator_create_empty();
} }
@@ -116,8 +143,6 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
host = host_create_from_string(str, 0); host = host_create_from_string(str, 0);
if (host) if (host)
{ {
entry = malloc_thing(attribute_entry_t);
if (host->get_family(host) == AF_INET6) if (host->get_family(host) == AF_INET6)
{ {
switch (type) switch (type)
@@ -132,8 +157,11 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
break; break;
} }
} }
entry->type = type; INIT(entry,
entry->value = chunk_clone(host->get_address(host)); .type = type,
.value = chunk_clone(host->get_address(host)),
.ike = IKE_ANY,
);
host->destroy(host); host->destroy(host);
DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B", DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
configuration_attribute_type_names, entry->type, &entry->value); configuration_attribute_type_names, entry->type, &entry->value);
@@ -149,19 +177,20 @@ typedef struct {
char *name; char *name;
configuration_attribute_type_t v4; configuration_attribute_type_t v4;
configuration_attribute_type_t v6; configuration_attribute_type_t v6;
ike_version_t ike;
} attribute_type_key_t; } attribute_type_key_t;
static attribute_type_key_t keys[] = { static attribute_type_key_t keys[] = {
{"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS}, {"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, IKE_ANY},
{"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS}, {"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS, IKE_ANY},
{"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS}, {"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS, IKE_ANY},
{"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP}, {"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP, IKE_ANY},
{"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK}, {"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK, IKE_ANY},
{"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER}, {"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, IKE_ANY},
{"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET}, {"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET, IKE_ANY},
{"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS}, {"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, IKEV2},
{"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE}, {"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE, IKEV1},
{"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN}, {"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN, IKEV1},
}; };
/** /**
@@ -276,6 +305,7 @@ static void load_entries(private_attr_provider_t *this)
INIT(entry, INIT(entry,
.type = type, .type = type,
.value = data, .value = data,
.ike = mapped ? mapped->ike : IKE_ANY,
); );
DBG2(DBG_CFG, "loaded attribute %N: %#B", DBG2(DBG_CFG, "loaded attribute %N: %#B",
configuration_attribute_type_names, entry->type, &entry->value); configuration_attribute_type_names, entry->type, &entry->value);