- handle IKE_SA setup without a piggy-packed CHILD_SA

more IKEv2 conform
This commit is contained in:
Martin Willi 2006-05-24 09:05:21 +00:00
parent b82908b8b5
commit 3a13a78084
7 changed files with 78 additions and 48 deletions

View File

@ -39,19 +39,19 @@
- certificate exchange - certificate exchange
+ Apply -W's from Makefile.program to charon + Apply -W's from Makefile.program to charon
- do ipsec status via starter + do ipsec status via starter
- add more output to to up/down, somehow... - add more output to to up/down, somehow...
- stroke status should show configured connections + stroke status should show configured connections
- stroke loglevel update + stroke loglevel update
- stroke argument parsing via getopts/gperf? - stroke argument parsing via getopts/gperf?
- implement 3DES to load encrypted pem files - implement 3DES to load encrypted pem files
- ipsec.secrets parsing + ipsec.secrets parsing
- trapping - trapping
- delete notify, when to send? + proper delete messages
- notifys on connection setup failure - notifys on connection setup failure
- create child sa message/rekeying - create child sa message/rekeying
- new build environment (autotools?) + new build environment (autotools?)

View File

@ -44,7 +44,7 @@ mapping_t notify_message_type_m[] = {
{NO_ADDITIONAL_SAS, "NO_ADDITIONAL_SAS"}, {NO_ADDITIONAL_SAS, "NO_ADDITIONAL_SAS"},
{INTERNAL_ADDRESS_FAILURE, "INTERNAL_ADDRESS_FAILURE"}, {INTERNAL_ADDRESS_FAILURE, "INTERNAL_ADDRESS_FAILURE"},
{FAILED_CP_REQUIRED, "FAILED_CP_REQUIRED"}, {FAILED_CP_REQUIRED, "FAILED_CP_REQUIRED"},
{TS_UACCEPTABLE, "TS_UACCEPTABLE"}, {TS_UNACCEPTABLE, "TS_UNACCEPTABLE"},
{INVALID_SELECTORS, "INVALID_SELECTORS"}, {INVALID_SELECTORS, "INVALID_SELECTORS"},
{INITIAL_CONTACT, "INITIAL_CONTACT"}, {INITIAL_CONTACT, "INITIAL_CONTACT"},
{SET_WINDOW_SIZE, "SET_WINDOW_SIZE"}, {SET_WINDOW_SIZE, "SET_WINDOW_SIZE"},

View File

@ -60,7 +60,7 @@ enum notify_message_type_t {
NO_ADDITIONAL_SAS = 35, NO_ADDITIONAL_SAS = 35,
INTERNAL_ADDRESS_FAILURE = 36, INTERNAL_ADDRESS_FAILURE = 36,
FAILED_CP_REQUIRED = 37, FAILED_CP_REQUIRED = 37,
TS_UACCEPTABLE = 38, TS_UNACCEPTABLE = 38,
INVALID_SELECTORS = 39, INVALID_SELECTORS = 39,
INITIAL_CONTACT = 16384, INITIAL_CONTACT = 16384,

View File

@ -341,6 +341,7 @@ sa_payload_t *sa_payload_create()
/* public functions */ /* public functions */
this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator; this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator;
this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure; this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
this->public.add_proposal = (void (*) (sa_payload_t*,proposal_t*))add_proposal;
this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals; this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
this->public.destroy = (void (*) (sa_payload_t *)) destroy; this->public.destroy = (void (*) (sa_payload_t *)) destroy;

View File

@ -535,6 +535,20 @@ static status_t process_notify_payload(private_ike_auth_requested_t *this, notif
this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained a SINGLE_PAIR_REQUIRED notify. Deleting IKE_SA"); this->logger->log(this->logger, AUDIT, "IKE_AUTH reply contained a SINGLE_PAIR_REQUIRED notify. Deleting IKE_SA");
return DESTROY_ME; return DESTROY_ME;
} }
case TS_UNACCEPTABLE:
{
/* TODO: We currently check only the replied TS payloads, which should be empty. Should
* we interpret the notify additionaly? */
this->logger->log(this->logger, CONTROL, "IKE_AUTH reply contained a TS_UNACCEPTABLE notify. Ignored");
return SUCCESS;
}
case NO_PROPOSAL_CHOSEN:
{
/* TODO: We currently check only the replied SA payload, which should be empty. Should
* we interpret the notify additionaly? */
this->logger->log(this->logger, CONTROL, "IKE_AUTH reply contained a NO_PROPOSAL_CHOSEN notify. Ignored");
return SUCCESS;
}
default: default:
{ {
/* /*

View File

@ -436,19 +436,11 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
status_t status; status_t status;
connection_t *connection; connection_t *connection;
/* get proposals from request */ /* prepare reply */
proposal_list = request->get_proposals(request);
if (proposal_list->get_count(proposal_list) == 0)
{
/* if the other side did not offer any proposals, we do not create child sa's */
this->logger->log(this->logger, AUDIT, "IKE_AUH request did not contain any proposals. No CHILD_SA created");
sa_response = sa_payload_create(); sa_response = sa_payload_create();
response->add_payload(response, (payload_t*)sa_response);
proposal_list->destroy(proposal_list);
return SUCCESS;
}
/* now select a proposal */ /* get proposals from request, and select one with ours */
proposal_list = request->get_proposals(request);
this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:"); this->logger->log(this->logger, CONTROL|LEVEL1, "Selecting proposals:");
proposal = this->policy->select_proposal(this->policy, proposal_list); proposal = this->policy->select_proposal(this->policy, proposal_list);
/* list is not needed anymore */ /* list is not needed anymore */
@ -457,14 +449,18 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
proposal_tmp->destroy(proposal_tmp); proposal_tmp->destroy(proposal_tmp);
} }
proposal_list->destroy(proposal_list); proposal_list->destroy(proposal_list);
/* do we have a proposal */ /* do we have a proposal? */
if (proposal == NULL) if (proposal == NULL)
{ {
this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any proposals we accept. Deleting IKE_SA"); notify_payload_t *notify;
this->ike_sa->send_notify(this->ike_sa, IKE_AUTH, NO_PROPOSAL_CHOSEN, CHUNK_INITIALIZER); this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any proposals we accept. "
return DESTROY_ME; "Adding NO_PROPOSAL_CHOSEN notify");
/* add NO_PROPOSAL_CHOSEN and an empty SA payload */
notify = notify_payload_create_from_protocol_and_type(PROTO_IKE, NO_PROPOSAL_CHOSEN);
response->add_payload(response, (payload_t*)notify);
} }
else
{
/* set up child sa */ /* set up child sa */
seed = chunk_alloc(this->received_nonce.len + this->sent_nonce.len); seed = chunk_alloc(this->received_nonce.len + this->sent_nonce.len);
memcpy(seed.ptr, this->received_nonce.ptr, this->received_nonce.len); memcpy(seed.ptr, this->received_nonce.ptr, this->received_nonce.len);
@ -481,13 +477,17 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
if (status != SUCCESS) if (status != SUCCESS)
{ {
this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA"); this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
/* TODO: how do we handle this cleanly? */
sa_response->destroy(sa_response);
proposal->destroy(proposal);
return DESTROY_ME; return DESTROY_ME;
} }
/* create payload with selected propsal */ /* add proposal to sa payload */
sa_response = sa_payload_create_from_proposal(proposal); sa_response->add_proposal(sa_response, proposal);
response->add_payload(response, (payload_t*)sa_response);
proposal->destroy(proposal); proposal->destroy(proposal);
}
response->add_payload(response, (payload_t*)sa_response);
return SUCCESS; return SUCCESS;
} }
@ -550,6 +550,19 @@ static status_t build_ts_payload(private_ike_sa_init_responded_t *this, bool ts_
ts_response = ts_payload_create_from_traffic_selectors(ts_initiator, ts_selected); ts_response = ts_payload_create_from_traffic_selectors(ts_initiator, ts_selected);
response->add_payload(response, (payload_t*)ts_response); response->add_payload(response, (payload_t*)ts_response);
/* add notify if traffic selectors do not match */
if (!ts_initiator &&
(ts_selected->get_count(ts_selected) == 0 || this->other_ts->get_count(this->other_ts) == 0))
{
notify_payload_t *notify;
this->logger->log(this->logger, AUDIT, "IKE_AUTH request did not contain any traffic selectors we accept. "
"Adding TS_UNACCEPTABLE notify");
notify = notify_payload_create_from_protocol_and_type(0, TS_UNACCEPTABLE);
response->add_payload(response, (payload_t*)notify);
}
/* cleanup */ /* cleanup */
while (ts_received->remove_last(ts_received, (void**)&ts) == SUCCESS) while (ts_received->remove_last(ts_received, (void**)&ts) == SUCCESS)
{ {

View File

@ -332,6 +332,8 @@ static void stroke_initiate(private_stroke_t *this, stroke_msg_t *msg)
/* only initiate if it is an IKEv2 connection, ignore IKEv1 */ /* only initiate if it is an IKEv2 connection, ignore IKEv1 */
else if (connection->is_ikev2(connection)) else if (connection->is_ikev2(connection))
{ {
this->stroke_logger->log(this->stroke_logger, CONTROL, "initiating connection \"%s\" (see log)...", msg->initiate.name);
job = initiate_ike_sa_job_create(connection); job = initiate_ike_sa_job_create(connection);
charon->job_queue->add(charon->job_queue, (job_t*)job); charon->job_queue->add(charon->job_queue, (job_t*)job);
} }