Added support for IKEv1 IPComp proposals in SA payload.
This commit is contained in:
parent
7a75cae856
commit
647cd741e8
|
@ -336,6 +336,60 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
|
|||
return list;
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*,
|
||||
private_sa_payload_t *this, u_int16_t *cpi)
|
||||
{
|
||||
int current_proposal = -1, unsupported_proposal = -1;
|
||||
enumerator_t *enumerator;
|
||||
proposal_substructure_t *substruct, *esp = NULL, *ipcomp = NULL;
|
||||
linked_list_t *list;
|
||||
|
||||
/* we currently only support the combination ESP+IPComp, find the first */
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
while (enumerator->enumerate(enumerator, &substruct))
|
||||
{
|
||||
u_int8_t proposal_number = substruct->get_proposal_number(substruct);
|
||||
u_int8_t protocol_id = substruct->get_protocol_id(substruct);
|
||||
|
||||
if (proposal_number == unsupported_proposal)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (protocol_id != PROTO_ESP && protocol_id != PROTO_IPCOMP)
|
||||
{ /* unsupported combination */
|
||||
esp = ipcomp = NULL;
|
||||
unsupported_proposal = current_proposal;
|
||||
continue;
|
||||
}
|
||||
if (proposal_number != current_proposal)
|
||||
{ /* start of a new proposal */
|
||||
if (esp && ipcomp)
|
||||
{ /* previous proposal is valid */
|
||||
break;
|
||||
}
|
||||
esp = ipcomp = NULL;
|
||||
current_proposal = proposal_number;
|
||||
}
|
||||
switch (protocol_id)
|
||||
{
|
||||
case PROTO_ESP:
|
||||
esp = substruct;
|
||||
break;
|
||||
case PROTO_IPCOMP:
|
||||
ipcomp = substruct;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
list = linked_list_create();
|
||||
if (esp && ipcomp && ipcomp->get_cpi(ipcomp, cpi))
|
||||
{
|
||||
esp->get_proposals(esp, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, create_substructure_enumerator, enumerator_t*,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
|
@ -438,6 +492,7 @@ sa_payload_t *sa_payload_create(payload_type_t type)
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.get_proposals = _get_proposals,
|
||||
.get_ipcomp_proposals = _get_ipcomp_proposals,
|
||||
.create_substructure_enumerator = _create_substructure_enumerator,
|
||||
.get_lifetime = _get_lifetime,
|
||||
.get_lifebytes = _get_lifebytes,
|
||||
|
@ -497,7 +552,8 @@ sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal)
|
|||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp)
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp,
|
||||
u_int16_t cpi)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
private_sa_payload_t *this;
|
||||
|
@ -505,11 +561,18 @@ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
|||
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION_V1);
|
||||
|
||||
/* IKEv1 encodes multiple proposals in a single substructure
|
||||
* TODO-IKEv1: Encode ESP+AH proposals in two different substructs */
|
||||
* TODO-IKEv1: Encode ESP+AH proposals in two substructs with same num */
|
||||
substruct = proposal_substructure_create_from_proposals_v1(proposals,
|
||||
lifetime, lifebytes, auth, mode, udp);
|
||||
substruct->set_is_last_proposal(substruct, TRUE);
|
||||
this->proposals->insert_last(this->proposals, substruct);
|
||||
substruct->set_is_last_proposal(substruct, FALSE);
|
||||
if (cpi)
|
||||
{
|
||||
substruct = proposal_substructure_create_for_ipcomp_v1(lifetime,
|
||||
lifebytes, cpi, substruct->get_proposal_number(substruct));
|
||||
this->proposals->insert_last(this->proposals, substruct);
|
||||
}
|
||||
substruct->set_is_last_proposal(substruct, TRUE);
|
||||
compute_length(this);
|
||||
|
||||
return &this->public;
|
||||
|
@ -520,7 +583,8 @@ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
|||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp)
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp,
|
||||
u_int16_t cpi)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
private_sa_payload_t *this;
|
||||
|
@ -529,8 +593,15 @@ sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
|
|||
|
||||
substruct = proposal_substructure_create_from_proposal_v1(proposal,
|
||||
lifetime, lifebytes, auth, mode, udp);
|
||||
substruct->set_is_last_proposal(substruct, TRUE);
|
||||
this->proposals->insert_last(this->proposals, substruct);
|
||||
substruct->set_is_last_proposal(substruct, FALSE);
|
||||
if (cpi)
|
||||
{
|
||||
substruct = proposal_substructure_create_for_ipcomp_v1(lifetime,
|
||||
lifebytes, cpi, substruct->get_proposal_number(substruct));
|
||||
this->proposals->insert_last(this->proposals, substruct);
|
||||
}
|
||||
substruct->set_is_last_proposal(substruct, TRUE);
|
||||
compute_length(this);
|
||||
|
||||
return &this->public;
|
||||
|
|
|
@ -46,10 +46,19 @@ struct sa_payload_t {
|
|||
/**
|
||||
* Gets the proposals in this payload as a list.
|
||||
*
|
||||
* @return a list containing proposal_t s
|
||||
* @return a list containing proposal_ts
|
||||
*/
|
||||
linked_list_t *(*get_proposals) (sa_payload_t *this);
|
||||
|
||||
/**
|
||||
* Gets the proposals from the first proposal in this payload with IPComp
|
||||
* enabled (IKEv1 only).
|
||||
*
|
||||
* @param cpi the CPI of the first IPComp (sub)proposal
|
||||
* @return a list containing proposal_ts
|
||||
*/
|
||||
linked_list_t *(*get_ipcomp_proposals) (sa_payload_t *this, u_int16_t *cpi);
|
||||
|
||||
/**
|
||||
* Get the (shortest) lifetime of a proposal (IKEv1 only).
|
||||
*
|
||||
|
@ -125,11 +134,13 @@ sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal);
|
|||
* @param auth authentication method to use, or AUTH_NONE
|
||||
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
|
||||
* @param udp TRUE to use UDP encapsulation
|
||||
* @param cpi CPI in case IPComp should be used
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp);
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp,
|
||||
u_int16_t cpi);
|
||||
|
||||
/**
|
||||
* Creates an IKEv1 sa_payload_t object from a single proposal.
|
||||
|
@ -140,10 +151,12 @@ sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
|||
* @param auth authentication method to use, or AUTH_NONE
|
||||
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
|
||||
* @param udp TRUE to use UDP encapsulation
|
||||
* @param cpi CPI in case IPComp should be used
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp);
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp,
|
||||
u_int16_t cpi);
|
||||
|
||||
#endif /** SA_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -235,7 +235,7 @@ METHOD(task_t, build_i, status_t,
|
|||
this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg);
|
||||
proposals = this->ike_cfg->get_proposals(this->ike_cfg);
|
||||
sa_payload = sa_payload_create_from_proposals_v1(proposals,
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE);
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE, 0);
|
||||
proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
|
||||
|
||||
message->add_payload(message, &sa_payload->payload_interface);
|
||||
|
@ -480,7 +480,7 @@ METHOD(task_t, build_r, status_t,
|
|||
identification_t *id;
|
||||
|
||||
sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE);
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE, 0);
|
||||
message->add_payload(message, &sa_payload->payload_interface);
|
||||
|
||||
if (!this->ph1->add_nonce_ke(this->ph1, message))
|
||||
|
|
|
@ -241,7 +241,7 @@ METHOD(task_t, build_i, status_t,
|
|||
this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg);
|
||||
proposals = this->ike_cfg->get_proposals(this->ike_cfg);
|
||||
sa_payload = sa_payload_create_from_proposals_v1(proposals,
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE);
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE, 0);
|
||||
proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
|
||||
|
||||
message->add_payload(message, &sa_payload->payload_interface);
|
||||
|
@ -455,7 +455,7 @@ METHOD(task_t, build_r, status_t,
|
|||
sa_payload_t *sa_payload;
|
||||
|
||||
sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE);
|
||||
this->lifetime, 0, this->method, MODE_NONE, FALSE, 0);
|
||||
message->add_payload(message, &sa_payload->payload_interface);
|
||||
|
||||
return NEED_MORE;
|
||||
|
|
|
@ -654,7 +654,7 @@ METHOD(task_t, build_i, status_t,
|
|||
get_lifetimes(this);
|
||||
sa_payload = sa_payload_create_from_proposals_v1(list,
|
||||
this->lifetime, this->lifebytes, AUTH_NONE,
|
||||
this->mode, this->udp);
|
||||
this->mode, this->udp, 0);
|
||||
list->destroy_offset(list, offsetof(proposal_t, destroy));
|
||||
message->add_payload(message, &sa_payload->payload_interface);
|
||||
|
||||
|
@ -933,7 +933,7 @@ METHOD(task_t, build_r, status_t,
|
|||
|
||||
sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
|
||||
this->lifetime, this->lifebytes, AUTH_NONE,
|
||||
this->mode, this->udp);
|
||||
this->mode, this->udp, 0);
|
||||
message->add_payload(message, &sa_payload->payload_interface);
|
||||
|
||||
if (!add_nonce(this, &this->nonce_r, message))
|
||||
|
|
Loading…
Reference in New Issue