Use informational taks to send notify errors
This commit is contained in:
@@ -293,6 +293,11 @@ METHOD(task_manager_t, initiate, status_t,
|
|||||||
exchange = TRANSACTION;
|
exchange = TRANSACTION;
|
||||||
new_mid = TRUE;
|
new_mid = TRUE;
|
||||||
}
|
}
|
||||||
|
if (activate_task(this, TASK_INFORMATIONAL))
|
||||||
|
{
|
||||||
|
exchange = INFORMATIONAL_V1;
|
||||||
|
new_mid = TRUE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IKE_ESTABLISHED:
|
case IKE_ESTABLISHED:
|
||||||
if (activate_task(this, TASK_MODE_CONFIG))
|
if (activate_task(this, TASK_MODE_CONFIG))
|
||||||
@@ -307,6 +312,11 @@ METHOD(task_manager_t, initiate, status_t,
|
|||||||
new_mid = TRUE;
|
new_mid = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (activate_task(this, TASK_INFORMATIONAL))
|
||||||
|
{
|
||||||
|
exchange = INFORMATIONAL_V1;
|
||||||
|
new_mid = TRUE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <encoding/payloads/hash_payload.h>
|
#include <encoding/payloads/hash_payload.h>
|
||||||
#include <sa/tasks/xauth.h>
|
#include <sa/tasks/xauth.h>
|
||||||
#include <sa/tasks/mode_config.h>
|
#include <sa/tasks/mode_config.h>
|
||||||
|
#include <sa/tasks/informational.h>
|
||||||
|
|
||||||
typedef struct private_main_mode_t private_main_mode_t;
|
typedef struct private_main_mode_t private_main_mode_t;
|
||||||
|
|
||||||
@@ -123,16 +124,6 @@ struct private_main_mode_t {
|
|||||||
*/
|
*/
|
||||||
authenticator_t *authenticator;
|
authenticator_t *authenticator;
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify type in case of error
|
|
||||||
*/
|
|
||||||
notify_type_t notify_type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify data in case of error
|
|
||||||
*/
|
|
||||||
chunk_t notify_data;
|
|
||||||
|
|
||||||
/** states of main mode */
|
/** states of main mode */
|
||||||
enum {
|
enum {
|
||||||
MM_INIT,
|
MM_INIT,
|
||||||
@@ -386,7 +377,8 @@ static bool has_notify_errors(private_main_mode_t *this, message_t *message)
|
|||||||
* delete any existing IKE_SAs with that peer.
|
* delete any existing IKE_SAs with that peer.
|
||||||
* The delete takes place when the SA is checked in due
|
* The delete takes place when the SA is checked in due
|
||||||
* to other id not known until the 3rd message.*/
|
* to other id not known until the 3rd message.*/
|
||||||
this->ike_sa->set_condition(this->ike_sa, COND_INIT_CONTACT_SEEN, TRUE);
|
this->ike_sa->set_condition(this->ike_sa,
|
||||||
|
COND_INIT_CONTACT_SEEN, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -400,47 +392,30 @@ static bool has_notify_errors(private_main_mode_t *this, message_t *message)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_t, build_notify_error, status_t,
|
/**
|
||||||
private_main_mode_t *this, message_t *message)
|
* Queue a task sending a notify in an INFORMATIONAL exchange
|
||||||
|
*/
|
||||||
|
static status_t send_notify(private_main_mode_t *this,
|
||||||
|
notify_type_t type, chunk_t data)
|
||||||
{
|
{
|
||||||
notify_payload_t *notify;
|
notify_payload_t *notify;
|
||||||
ike_sa_id_t *ike_sa_id;
|
ike_sa_id_t *ike_sa_id;
|
||||||
chunk_t spi;
|
|
||||||
u_int64_t spi_i, spi_r;
|
u_int64_t spi_i, spi_r;
|
||||||
|
chunk_t spi;
|
||||||
|
|
||||||
notify = notify_payload_create_from_protocol_and_type(NOTIFY_V1,
|
notify = notify_payload_create_from_protocol_and_type(NOTIFY_V1,
|
||||||
PROTO_IKE, this->notify_type);
|
PROTO_IKE, type);
|
||||||
|
notify->set_notification_data(notify, data);
|
||||||
if (this->notify_data.ptr)
|
|
||||||
{
|
|
||||||
notify->set_notification_data(notify, this->notify_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
ike_sa_id = this->ike_sa->get_id(this->ike_sa);
|
ike_sa_id = this->ike_sa->get_id(this->ike_sa);
|
||||||
|
|
||||||
spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
|
spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
|
||||||
spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
|
spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
|
||||||
|
|
||||||
spi = chunk_cata("cc", chunk_from_thing(spi_i), chunk_from_thing(spi_r));
|
spi = chunk_cata("cc", chunk_from_thing(spi_i), chunk_from_thing(spi_r));
|
||||||
|
|
||||||
notify->set_spi_data(notify, spi);
|
notify->set_spi_data(notify, spi);
|
||||||
|
|
||||||
message->add_payload(message, (payload_t*)notify);
|
this->ike_sa->queue_task(this->ike_sa,
|
||||||
|
(task_t*)informational_create(this->ike_sa, notify));
|
||||||
return SUCCESS;
|
/* cancel all active/passive tasks in favour of informational */
|
||||||
}
|
return ALREADY_DONE;
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the task ready to build notify error message
|
|
||||||
*/
|
|
||||||
static status_t set_notify_error(private_main_mode_t *this,
|
|
||||||
notify_type_t type, chunk_t data)
|
|
||||||
{
|
|
||||||
this->notify_type = type;
|
|
||||||
this->notify_data = data;
|
|
||||||
/* The task will be destroyed after build */
|
|
||||||
this->public.task.build = _build_notify_error;
|
|
||||||
return FAILED_SEND_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(task_t, build_i, status_t,
|
METHOD(task_t, build_i, status_t,
|
||||||
@@ -600,7 +575,7 @@ METHOD(task_t, process_r, status_t,
|
|||||||
if (!this->proposal)
|
if (!this->proposal)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "no proposal found");
|
DBG1(DBG_IKE, "no proposal found");
|
||||||
return set_notify_error(this, NO_PROPOSAL_CHOSEN, chunk_empty);
|
return send_notify(this, NO_PROPOSAL_CHOSEN, chunk_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->auth_method = sa_payload->get_auth_method(sa_payload);
|
this->auth_method = sa_payload->get_auth_method(sa_payload);
|
||||||
@@ -654,7 +629,7 @@ METHOD(task_t, process_r, status_t,
|
|||||||
if (!this->peer_cfg)
|
if (!this->peer_cfg)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "no peer config found");
|
DBG1(DBG_IKE, "no peer config found");
|
||||||
return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
|
return send_notify(this, AUTHENTICATION_FAILED, chunk_empty);
|
||||||
}
|
}
|
||||||
this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
|
this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
|
||||||
|
|
||||||
@@ -663,13 +638,13 @@ METHOD(task_t, process_r, status_t,
|
|||||||
if (!this->my_auth || !this->other_auth)
|
if (!this->my_auth || !this->other_auth)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "auth config missing");
|
DBG1(DBG_IKE, "auth config missing");
|
||||||
return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
|
return send_notify(this, AUTHENTICATION_FAILED, chunk_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->authenticator->process(this->authenticator,
|
if (this->authenticator->process(this->authenticator,
|
||||||
message) != SUCCESS)
|
message) != SUCCESS)
|
||||||
{
|
{
|
||||||
return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
|
return send_notify(this, AUTHENTICATION_FAILED, chunk_empty);
|
||||||
}
|
}
|
||||||
this->state = MM_AUTH;
|
this->state = MM_AUTH;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user