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;
/** attribute 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);
}
/**
* Data for attribute enumerator
*/
typedef struct {
rwlock_t *lock;
ike_version_t ike;
} enumerator_data_t;
/**
* 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)
{
*type = (*in)->type;
*value = (*in)->value;
return TRUE;
if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike)
{
*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*,
private_attr_provider_t *this, linked_list_t *pools,
ike_sa_t *ike_sa, linked_list_t *vips)
{
enumerator_data_t *data;
if (vips->get_count(vips))
{
INIT(data,
.lock = this->lock,
.ike = ike_sa->get_version(ike_sa),
);
this->lock->read_lock(this->lock);
return enumerator_create_filter(
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();
}
@@ -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);
if (host)
{
entry = malloc_thing(attribute_entry_t);
if (host->get_family(host) == AF_INET6)
{
switch (type)
@@ -132,8 +157,11 @@ static void add_legacy_entry(private_attr_provider_t *this, char *key, int nr,
break;
}
}
entry->type = type;
entry->value = chunk_clone(host->get_address(host));
INIT(entry,
.type = type,
.value = chunk_clone(host->get_address(host)),
.ike = IKE_ANY,
);
host->destroy(host);
DBG2(DBG_CFG, "loaded legacy entry attribute %N: %#B",
configuration_attribute_type_names, entry->type, &entry->value);
@@ -149,19 +177,20 @@ typedef struct {
char *name;
configuration_attribute_type_t v4;
configuration_attribute_type_t v6;
ike_version_t ike;
} attribute_type_key_t;
static attribute_type_key_t keys[] = {
{"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS},
{"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS},
{"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS},
{"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP},
{"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK},
{"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER},
{"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET},
{"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS},
{"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE},
{"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN},
{"address", INTERNAL_IP4_ADDRESS, INTERNAL_IP6_ADDRESS, IKE_ANY},
{"dns", INTERNAL_IP4_DNS, INTERNAL_IP6_DNS, IKE_ANY},
{"nbns", INTERNAL_IP4_NBNS, INTERNAL_IP6_NBNS, IKE_ANY},
{"dhcp", INTERNAL_IP4_DHCP, INTERNAL_IP6_DHCP, IKE_ANY},
{"netmask", INTERNAL_IP4_NETMASK, INTERNAL_IP6_NETMASK, IKE_ANY},
{"server", INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, IKE_ANY},
{"subnet", INTERNAL_IP4_SUBNET, INTERNAL_IP6_SUBNET, IKE_ANY},
{"p-cscf", P_CSCF_IP4_ADDRESS, P_CSCF_IP6_ADDRESS, IKEV2},
{"split-include", UNITY_SPLIT_INCLUDE, UNITY_SPLIT_INCLUDE, IKEV1},
{"split-exclude", UNITY_LOCAL_LAN, UNITY_LOCAL_LAN, IKEV1},
};
/**
@@ -276,6 +305,7 @@ static void load_entries(private_attr_provider_t *this)
INIT(entry,
.type = type,
.value = data,
.ike = mapped ? mapped->ike : IKE_ANY,
);
DBG2(DBG_CFG, "loaded attribute %N: %#B",
configuration_attribute_type_names, entry->type, &entry->value);