Properly filter IKEv1 proposals consisting of multiple proposal payloads.

Since a proposal_t object is created for each transform contained in the
proposal payload, it does not work to simply remove the last proposal_t
object added to the list (there may be several other extracted from the
previous proposal payload).
This commit is contained in:
Tobias Brunner
2012-05-24 15:32:27 +02:00
parent fda9f104b4
commit 624bb24d12
+15 -9
View File
@@ -1,4 +1,5 @@
/* /*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter * Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil * Hochschule fuer Technik Rapperswil
@@ -292,20 +293,19 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
int ignore_struct_number = 0; int ignore_struct_number = 0;
enumerator_t *enumerator; enumerator_t *enumerator;
proposal_substructure_t *substruct; proposal_substructure_t *substruct;
proposal_t *proposal; linked_list_t *substructs, *list;
linked_list_t *list;
if (this->type == SECURITY_ASSOCIATION_V1) if (this->type == SECURITY_ASSOCIATION_V1)
{ /* IKEv1 proposals start with 0 */ { /* IKEv1 proposals start with 0 */
struct_number = ignore_struct_number = -1; struct_number = ignore_struct_number = -1;
} }
list = linked_list_create();
/* we do not support proposals split up to two proposal substructures, as /* we do not support proposals split up to two proposal substructures, as
* AH+ESP bundles are not supported in RFC4301 anymore. * AH+ESP bundles are not supported in RFC4301 anymore.
* To handle such structures safely, we just skip proposals with multiple * To handle such structures safely, we just skip proposals with multiple
* protocols. * protocols.
*/ */
substructs = linked_list_create();
enumerator = this->proposals->create_enumerator(this->proposals); enumerator = this->proposals->create_enumerator(this->proposals);
while (enumerator->enumerate(enumerator, &substruct)) while (enumerator->enumerate(enumerator, &substruct))
{ {
@@ -313,20 +313,26 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
if (substruct->get_proposal_number(substruct) == struct_number) if (substruct->get_proposal_number(substruct) == struct_number)
{ {
if (ignore_struct_number < struct_number) if (ignore_struct_number < struct_number)
{ { /* remove an already added, if first of series */
/* remove an already added, if first of series */ substructs->remove_last(substructs, (void**)&substruct);
if (list->remove_last(list, (void**)&proposal) == SUCCESS)
{
proposal->destroy(proposal);
}
ignore_struct_number = struct_number; ignore_struct_number = struct_number;
} }
continue; continue;
} }
struct_number++; struct_number++;
substructs->insert_last(substructs, substruct);
}
enumerator->destroy(enumerator);
/* generate proposals from substructs */
list = linked_list_create();
enumerator = substructs->create_enumerator(substructs);
while (enumerator->enumerate(enumerator, &substruct))
{
substruct->get_proposals(substruct, list); substruct->get_proposals(substruct, list);
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
substructs->destroy(substructs);
return list; return list;
} }