Parse proposal substructure with multiple IKEv1 transforms to multiple proposals

This commit is contained in:
Martin Willi
2012-03-20 17:30:49 +01:00
parent 62a27ba347
commit d50152a70b
3 changed files with 33 additions and 34 deletions
@@ -650,18 +650,35 @@ static void add_to_proposal_v1_esp(proposal_t *proposal,
transform->get_transform_id(transform), key_length); transform->get_transform_id(transform), key_length);
} }
METHOD(proposal_substructure_t, get_proposal, proposal_t*, METHOD(proposal_substructure_t, get_proposals, void,
private_proposal_substructure_t *this) private_proposal_substructure_t *this, linked_list_t *proposals)
{ {
transform_substructure_t *transform; transform_substructure_t *transform;
enumerator_t *enumerator; enumerator_t *enumerator;
proposal_t *proposal; proposal_t *proposal = NULL;
u_int64_t spi = 0;
proposal = proposal_create(this->protocol_id, this->proposal_number); switch (this->spi.len)
{
case 4:
spi = *((u_int32_t*)this->spi.ptr);
break;
case 8:
spi = *((u_int64_t*)this->spi.ptr);
break;
default:
break;
}
enumerator = this->transforms->create_enumerator(this->transforms); enumerator = this->transforms->create_enumerator(this->transforms);
while (enumerator->enumerate(enumerator, &transform)) while (enumerator->enumerate(enumerator, &transform))
{ {
if (!proposal)
{
proposal = proposal_create(this->protocol_id, this->proposal_number);
proposal->set_spi(proposal, spi);
proposals->insert_last(proposals, proposal);
}
if (this->type == PROPOSAL_SUBSTRUCTURE) if (this->type == PROPOSAL_SUBSTRUCTURE)
{ {
add_to_proposal_v2(proposal, transform); add_to_proposal_v2(proposal, transform);
@@ -679,27 +696,11 @@ METHOD(proposal_substructure_t, get_proposal, proposal_t*,
default: default:
break; break;
} }
/* TODO-IKEv1: We currently accept the first set of transforms /* create a new proposal for each transform in IKEv1 */
* in a substructure only. We need to return multiple proposals, proposal = NULL;
* but this messes up proposal numbering, as we don't support
* transform numbering. */
break;
} }
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
switch (this->spi.len)
{
case 4:
proposal->set_spi(proposal, *((u_int32_t*)this->spi.ptr));
break;
case 8:
proposal->set_spi(proposal, *((u_int64_t*)this->spi.ptr));
break;
default:
break;
}
return proposal;
} }
METHOD(proposal_substructure_t, create_substructure_enumerator, enumerator_t*, METHOD(proposal_substructure_t, create_substructure_enumerator, enumerator_t*,
@@ -741,7 +742,7 @@ proposal_substructure_t *proposal_substructure_create(payload_type_t type)
.set_protocol_id = _set_protocol_id, .set_protocol_id = _set_protocol_id,
.get_protocol_id = _get_protocol_id, .get_protocol_id = _get_protocol_id,
.set_is_last_proposal = _set_is_last_proposal, .set_is_last_proposal = _set_is_last_proposal,
.get_proposal = _get_proposal, .get_proposals = _get_proposals,
.create_substructure_enumerator = _create_substructure_enumerator, .create_substructure_enumerator = _create_substructure_enumerator,
.set_spi = _set_spi, .set_spi = _set_spi,
.get_spi = _get_spi, .get_spi = _get_spi,
@@ -96,11 +96,11 @@ struct proposal_substructure_t {
void (*set_spi) (proposal_substructure_t *this, chunk_t spi); void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
/** /**
* Get a proposal_t from the propsal_substructure_t. * Get proposals contained in a propsal_substructure_t.
* *
* @return proposal_t * @param list list to add created proposals to
*/ */
proposal_t * (*get_proposal) (proposal_substructure_t *this); void (*get_proposals) (proposal_substructure_t *this, linked_list_t *list);
/** /**
* Create an enumerator over transform substructures. * Create an enumerator over transform substructures.
+6 -8
View File
@@ -297,8 +297,8 @@ 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;
linked_list_t *list;
proposal_t *proposal; proposal_t *proposal;
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 */
@@ -320,18 +320,16 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
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 */
list->remove_last(list, (void**)&proposal); if (list->remove_last(list, (void**)&proposal) == SUCCESS)
proposal->destroy(proposal); {
proposal->destroy(proposal);
}
ignore_struct_number = struct_number; ignore_struct_number = struct_number;
} }
continue; continue;
} }
struct_number++; struct_number++;
proposal = substruct->get_proposal(substruct); substruct->get_proposals(substruct, list);
if (proposal)
{
list->insert_last(list, proposal);
}
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
return list; return list;