Replace xauth_request task with a new stub where we reimplement it
This commit is contained in:
@@ -57,7 +57,6 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \
|
|||||||
processing/jobs/roam_job.c processing/jobs/roam_job.h \
|
processing/jobs/roam_job.c processing/jobs/roam_job.h \
|
||||||
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
|
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
|
||||||
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
|
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
|
||||||
processing/jobs/initiate_xauth_job.c processing/jobs/initiate_xauth_job.h \
|
|
||||||
sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
|
sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
|
||||||
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
|
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
|
||||||
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
|
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
|
||||||
@@ -100,8 +99,8 @@ sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
|
|||||||
sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
|
sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
|
||||||
sa/tasks/ike_vendor_v1.c sa/tasks/ike_vendor_v1.h \
|
sa/tasks/ike_vendor_v1.c sa/tasks/ike_vendor_v1.h \
|
||||||
sa/tasks/main_mode.c sa/tasks/main_mode.h \
|
sa/tasks/main_mode.c sa/tasks/main_mode.h \
|
||||||
|
sa/tasks/xauth.c sa/tasks/xauth.h \
|
||||||
sa/tasks/quick_mode.c sa/tasks/quick_mode.h \
|
sa/tasks/quick_mode.c sa/tasks/quick_mode.h \
|
||||||
sa/tasks/xauth_request.c sa/tasks/xauth_request.h \
|
|
||||||
sa/tasks/task.c sa/tasks/task.h
|
sa/tasks/task.c sa/tasks/task.h
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
#include <sa/tasks/quick_mode.h>
|
#include <sa/tasks/quick_mode.h>
|
||||||
#include <sa/tasks/ike_natd_v1.h>
|
#include <sa/tasks/ike_natd_v1.h>
|
||||||
#include <sa/tasks/ike_vendor_v1.h>
|
#include <sa/tasks/ike_vendor_v1.h>
|
||||||
#include <sa/tasks/xauth_request.h>
|
|
||||||
#include <processing/jobs/retransmit_job.h>
|
#include <processing/jobs/retransmit_job.h>
|
||||||
#include <processing/jobs/delete_ike_sa_job.h>
|
#include <processing/jobs/delete_ike_sa_job.h>
|
||||||
#include <processing/jobs/send_dpd_job.h>
|
#include <processing/jobs/send_dpd_job.h>
|
||||||
@@ -1021,18 +1020,6 @@ METHOD(ike_sa_t, initiate_mediated, status_t,
|
|||||||
}
|
}
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
|
||||||
METHOD(ike_sa_t, initiate_xauth, status_t,
|
|
||||||
private_ike_sa_t *this, bool initiate)
|
|
||||||
{
|
|
||||||
xauth_request_t *task = xauth_request_create(&this->public, TRUE);
|
|
||||||
this->task_manager->queue_task(this->task_manager, (task_t*)task);
|
|
||||||
if(initiate)
|
|
||||||
{
|
|
||||||
return this->task_manager->initiate(this->task_manager);
|
|
||||||
}
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve DNS host in configuration
|
* Resolve DNS host in configuration
|
||||||
*/
|
*/
|
||||||
@@ -1839,6 +1826,12 @@ METHOD(ike_sa_t, create_task_enumerator, enumerator_t*,
|
|||||||
return this->task_manager->create_task_enumerator(this->task_manager, queue);
|
return this->task_manager->create_task_enumerator(this->task_manager, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(ike_sa_t, queue_task, void,
|
||||||
|
private_ike_sa_t *this, task_t *task)
|
||||||
|
{
|
||||||
|
this->task_manager->queue_task(this->task_manager, task);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_t, inherit, void,
|
METHOD(ike_sa_t, inherit, void,
|
||||||
private_ike_sa_t *this, ike_sa_t *other_public)
|
private_ike_sa_t *this, ike_sa_t *other_public)
|
||||||
{
|
{
|
||||||
@@ -2095,6 +2088,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
|||||||
.add_configuration_attribute = _add_configuration_attribute,
|
.add_configuration_attribute = _add_configuration_attribute,
|
||||||
.set_kmaddress = _set_kmaddress,
|
.set_kmaddress = _set_kmaddress,
|
||||||
.create_task_enumerator = _create_task_enumerator,
|
.create_task_enumerator = _create_task_enumerator,
|
||||||
|
.queue_task = _queue_task,
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
.act_as_mediation_server = _act_as_mediation_server,
|
.act_as_mediation_server = _act_as_mediation_server,
|
||||||
.get_server_reflexive_host = _get_server_reflexive_host,
|
.get_server_reflexive_host = _get_server_reflexive_host,
|
||||||
@@ -2106,7 +2100,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
|
|||||||
.callback = _callback,
|
.callback = _callback,
|
||||||
.respond = _respond,
|
.respond = _respond,
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
.initiate_xauth = _initiate_xauth,
|
|
||||||
},
|
},
|
||||||
.ike_sa_id = ike_sa_id->clone(ike_sa_id),
|
.ike_sa_id = ike_sa_id->clone(ike_sa_id),
|
||||||
.version = version,
|
.version = version,
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ typedef struct ike_sa_t ike_sa_t;
|
|||||||
#include <encoding/payloads/configuration_attribute.h>
|
#include <encoding/payloads/configuration_attribute.h>
|
||||||
#include <sa/ike_sa_id.h>
|
#include <sa/ike_sa_id.h>
|
||||||
#include <sa/child_sa.h>
|
#include <sa/child_sa.h>
|
||||||
|
#include <sa/tasks/task.h>
|
||||||
#include <sa/task_manager.h>
|
#include <sa/task_manager.h>
|
||||||
#include <sa/keymat.h>
|
#include <sa/keymat.h>
|
||||||
#include <config/peer_cfg.h>
|
#include <config/peer_cfg.h>
|
||||||
@@ -951,6 +952,13 @@ struct ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
enumerator_t* (*create_task_enumerator)(ike_sa_t *this, task_queue_t queue);
|
enumerator_t* (*create_task_enumerator)(ike_sa_t *this, task_queue_t queue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a task for initiaton to the task manager.
|
||||||
|
*
|
||||||
|
* @param task task to queue
|
||||||
|
*/
|
||||||
|
void (*queue_task)(ike_sa_t *this, task_t *task);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inherit all attributes of other to this after rekeying.
|
* Inherit all attributes of other to this after rekeying.
|
||||||
*
|
*
|
||||||
@@ -971,11 +979,6 @@ struct ike_sa_t {
|
|||||||
* Destroys a ike_sa_t object.
|
* Destroys a ike_sa_t object.
|
||||||
*/
|
*/
|
||||||
void (*destroy) (ike_sa_t *this);
|
void (*destroy) (ike_sa_t *this);
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiate an XAuth authentication exchange.
|
|
||||||
*/
|
|
||||||
status_t (*initiate_xauth) (ike_sa_t *this, bool initiate);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
#include <sa/tasks/child_delete.h>
|
#include <sa/tasks/child_delete.h>
|
||||||
#include <sa/tasks/main_mode.h>
|
#include <sa/tasks/main_mode.h>
|
||||||
#include <sa/tasks/quick_mode.h>
|
#include <sa/tasks/quick_mode.h>
|
||||||
#include <sa/tasks/xauth_request.h>
|
#include <sa/tasks/xauth.h>
|
||||||
#include <sa/tasks/ike_delete.h>
|
#include <sa/tasks/ike_delete.h>
|
||||||
#include <sa/tasks/ike_natd_v1.h>
|
#include <sa/tasks/ike_natd_v1.h>
|
||||||
#include <sa/tasks/ike_vendor_v1.h>
|
#include <sa/tasks/ike_vendor_v1.h>
|
||||||
@@ -280,7 +280,7 @@ METHOD(task_manager_t, initiate, status_t,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IKE_CONNECTING:
|
case IKE_CONNECTING:
|
||||||
if (activate_task(this, TASK_XAUTH_REQUEST))
|
if (activate_task(this, TASK_XAUTH))
|
||||||
{
|
{
|
||||||
exchange = TRANSACTION;
|
exchange = TRANSACTION;
|
||||||
new_mid = TRUE;
|
new_mid = TRUE;
|
||||||
@@ -313,7 +313,7 @@ METHOD(task_manager_t, initiate, status_t,
|
|||||||
case TASK_QUICK_MODE:
|
case TASK_QUICK_MODE:
|
||||||
exchange = QUICK_MODE;
|
exchange = QUICK_MODE;
|
||||||
break;
|
break;
|
||||||
case TASK_XAUTH_REQUEST:
|
case TASK_XAUTH:
|
||||||
exchange = TRANSACTION;
|
exchange = TRANSACTION;
|
||||||
new_mid = TRUE;
|
new_mid = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -648,7 +648,7 @@ static status_t process_request(private_task_manager_t *this,
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
break;
|
break;
|
||||||
case TRANSACTION:
|
case TRANSACTION:
|
||||||
task = (task_t *)xauth_request_create(this->ike_sa, FALSE);
|
task = (task_t *)xauth_create(this->ike_sa, FALSE);
|
||||||
this->passive_tasks->insert_last(this->passive_tasks, task);
|
this->passive_tasks->insert_last(this->passive_tasks, task);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -688,7 +688,17 @@ static status_t process_request(private_task_manager_t *this,
|
|||||||
|
|
||||||
if (send_response)
|
if (send_response)
|
||||||
{
|
{
|
||||||
return build_response(this, message);
|
if (build_response(this, message) != SUCCESS)
|
||||||
|
{
|
||||||
|
return DESTROY_ME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this->passive_tasks->get_count(this->passive_tasks) == 0 &&
|
||||||
|
this->queued_tasks->get_count(this->queued_tasks) > 0)
|
||||||
|
{
|
||||||
|
/* passive tasks completed, check if an active task has been queued,
|
||||||
|
* such as XAUTH or modeconfig push */
|
||||||
|
return initiate(this);
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
#include <encoding/payloads/nonce_payload.h>
|
#include <encoding/payloads/nonce_payload.h>
|
||||||
#include <encoding/payloads/id_payload.h>
|
#include <encoding/payloads/id_payload.h>
|
||||||
#include <encoding/payloads/hash_payload.h>
|
#include <encoding/payloads/hash_payload.h>
|
||||||
#include <processing/jobs/initiate_xauth_job.h>
|
#include <sa/tasks/xauth.h>
|
||||||
|
|
||||||
typedef struct private_main_mode_t private_main_mode_t;
|
typedef struct private_main_mode_t private_main_mode_t;
|
||||||
|
|
||||||
@@ -738,6 +738,21 @@ METHOD(task_t, build_r, status_t,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (this->auth_method)
|
||||||
|
{
|
||||||
|
case AUTH_XAUTH_INIT_PSK:
|
||||||
|
case AUTH_XAUTH_INIT_RSA:
|
||||||
|
this->ike_sa->queue_task(this->ike_sa,
|
||||||
|
(task_t*)xauth_create(this->ike_sa, TRUE));
|
||||||
|
return SUCCESS;
|
||||||
|
case AUTH_XAUTH_RESP_PSK:
|
||||||
|
case AUTH_XAUTH_RESP_RSA:
|
||||||
|
/* TODO-IKEv1: not yet supported */
|
||||||
|
return FAILED;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
|
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
|
||||||
this->ike_sa->get_name(this->ike_sa),
|
this->ike_sa->get_name(this->ike_sa),
|
||||||
this->ike_sa->get_unique_id(this->ike_sa),
|
this->ike_sa->get_unique_id(this->ike_sa),
|
||||||
@@ -746,27 +761,9 @@ METHOD(task_t, build_r, status_t,
|
|||||||
this->ike_sa->get_other_host(this->ike_sa),
|
this->ike_sa->get_other_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_id(this->ike_sa));
|
this->ike_sa->get_other_id(this->ike_sa));
|
||||||
|
|
||||||
switch (this->auth_method)
|
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
|
||||||
{
|
charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
|
||||||
case AUTH_XAUTH_INIT_PSK:
|
|
||||||
case AUTH_XAUTH_INIT_RSA: /* There should be more INIT cases here once added */
|
|
||||||
{
|
|
||||||
job_t *job = (job_t *) initiate_xauth_job_create(this->ike_sa->get_id(this->ike_sa));
|
|
||||||
lib->processor->queue_job(lib->processor, job);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AUTH_XAUTH_RESP_PSK:
|
|
||||||
case AUTH_XAUTH_RESP_RSA: /* There should be more RESP cases here once added */
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
|
|
||||||
charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -858,7 +855,20 @@ METHOD(task_t, process_i, status_t,
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO-IKEv1: check for XAUTH rounds, queue them */
|
switch (this->auth_method)
|
||||||
|
{
|
||||||
|
case AUTH_XAUTH_INIT_PSK:
|
||||||
|
case AUTH_XAUTH_INIT_RSA:
|
||||||
|
/* TODO-IKEv1: wait for XAUTH request */
|
||||||
|
return SUCCESS;
|
||||||
|
case AUTH_XAUTH_RESP_PSK:
|
||||||
|
case AUTH_XAUTH_RESP_RSA:
|
||||||
|
/* TODO-IKEv1: not yet */
|
||||||
|
return FAILED;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
|
DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
|
||||||
this->ike_sa->get_name(this->ike_sa),
|
this->ike_sa->get_name(this->ike_sa),
|
||||||
this->ike_sa->get_unique_id(this->ike_sa),
|
this->ike_sa->get_unique_id(this->ike_sa),
|
||||||
@@ -867,26 +877,8 @@ METHOD(task_t, process_i, status_t,
|
|||||||
this->ike_sa->get_other_host(this->ike_sa),
|
this->ike_sa->get_other_host(this->ike_sa),
|
||||||
this->ike_sa->get_other_id(this->ike_sa));
|
this->ike_sa->get_other_id(this->ike_sa));
|
||||||
|
|
||||||
switch (this->auth_method)
|
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
|
||||||
{
|
charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
|
||||||
case AUTH_XAUTH_RESP_PSK:
|
|
||||||
case AUTH_XAUTH_RESP_RSA: /* There should be more RESP cases here once added */
|
|
||||||
{
|
|
||||||
this->ike_sa->initiate_xauth(this->ike_sa, FALSE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AUTH_XAUTH_INIT_PSK:
|
|
||||||
case AUTH_XAUTH_INIT_RSA: /* There should be more INIT cases here once added */
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
|
|
||||||
charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
ENUM(task_type_names, TASK_IKE_INIT, TASK_XAUTH_REQUEST,
|
ENUM(task_type_names, TASK_IKE_INIT, TASK_IKE_CERT_POST_V1,
|
||||||
"IKE_INIT",
|
"IKE_INIT",
|
||||||
"IKE_NATD",
|
"IKE_NATD",
|
||||||
"IKE_MOBIKE",
|
"IKE_MOBIKE",
|
||||||
@@ -36,15 +36,15 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_XAUTH_REQUEST,
|
|||||||
"CHILD_DELETE",
|
"CHILD_DELETE",
|
||||||
"CHILD_REKEY",
|
"CHILD_REKEY",
|
||||||
"MAIN_MODE",
|
"MAIN_MODE",
|
||||||
|
"XAUTH",
|
||||||
"QUICK_MODE",
|
"QUICK_MODE",
|
||||||
"VENDOR_V1",
|
"VENDOR_V1",
|
||||||
"IKE_NATD_V1",
|
"IKE_NATD_V1",
|
||||||
"IKE_CERT_PRE_V1",
|
"IKE_CERT_PRE_V1",
|
||||||
"IKE_CERT_POST_V1",
|
"IKE_CERT_POST_V1",
|
||||||
"XAUTH_REQUEST",
|
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
ENUM(task_type_names, TASK_IKE_INIT, TASK_XAUTH_REQUEST,
|
ENUM(task_type_names, TASK_IKE_INIT, TASK_IKE_CERT_POST_V1,
|
||||||
"IKE_INIT",
|
"IKE_INIT",
|
||||||
"IKE_NATD",
|
"IKE_NATD",
|
||||||
"IKE_MOBIKE",
|
"IKE_MOBIKE",
|
||||||
@@ -62,11 +62,11 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_XAUTH_REQUEST,
|
|||||||
"CHILD_DELETE",
|
"CHILD_DELETE",
|
||||||
"CHILD_REKEY",
|
"CHILD_REKEY",
|
||||||
"MAIN_MODE",
|
"MAIN_MODE",
|
||||||
|
"XAUTH",
|
||||||
"QUICK_MODE",
|
"QUICK_MODE",
|
||||||
"VENDOR_V1",
|
"VENDOR_V1",
|
||||||
"IKE_NATD_V1",
|
"IKE_NATD_V1",
|
||||||
"IKE_CERT_PRE_V1",
|
"IKE_CERT_PRE_V1",
|
||||||
"IKE_CERT_POST_V1",
|
"IKE_CERT_POST_V1",
|
||||||
"XAUTH_REQUEST",
|
|
||||||
);
|
);
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ enum task_type_t {
|
|||||||
TASK_CHILD_REKEY,
|
TASK_CHILD_REKEY,
|
||||||
/** IKEv1 main mode */
|
/** IKEv1 main mode */
|
||||||
TASK_MAIN_MODE,
|
TASK_MAIN_MODE,
|
||||||
|
/** IKEv1 XAUTH authentication */
|
||||||
|
TASK_XAUTH,
|
||||||
/** IKEv1 quick mode */
|
/** IKEv1 quick mode */
|
||||||
TASK_QUICK_MODE,
|
TASK_QUICK_MODE,
|
||||||
/** IKEv1 vendor ID payload handling */
|
/** IKEv1 vendor ID payload handling */
|
||||||
@@ -81,8 +83,6 @@ enum task_type_t {
|
|||||||
TASK_IKE_CERT_PRE_V1,
|
TASK_IKE_CERT_PRE_V1,
|
||||||
/** IKEv1 post-authentication certificate handling */
|
/** IKEv1 post-authentication certificate handling */
|
||||||
TASK_IKE_CERT_POST_V1,
|
TASK_IKE_CERT_POST_V1,
|
||||||
/** Request the user/pass with XAUTH */
|
|
||||||
TASK_XAUTH_REQUEST,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Martin Willi
|
||||||
|
* Copyright (C) 2011 revosec AG
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xauth.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <hydra.h>
|
||||||
|
#include <encoding/payloads/cp_payload.h>
|
||||||
|
|
||||||
|
typedef struct private_xauth_t private_xauth_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private members of a xauth_t task.
|
||||||
|
*/
|
||||||
|
struct private_xauth_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public methods and task_t interface.
|
||||||
|
*/
|
||||||
|
xauth_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigned IKE_SA.
|
||||||
|
*/
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Are we the XAUTH initiator?
|
||||||
|
*/
|
||||||
|
bool initiator;
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(task_t, build_i, status_t,
|
||||||
|
private_xauth_t *this, message_t *message)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, process_r, status_t,
|
||||||
|
private_xauth_t *this, message_t *message)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, build_r, status_t,
|
||||||
|
private_xauth_t *this, message_t *message)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, process_i, status_t,
|
||||||
|
private_xauth_t *this, message_t *message)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, get_type, task_type_t,
|
||||||
|
private_xauth_t *this)
|
||||||
|
{
|
||||||
|
return TASK_XAUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, migrate, void,
|
||||||
|
private_xauth_t *this, ike_sa_t *ike_sa)
|
||||||
|
{
|
||||||
|
this->ike_sa = ike_sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(task_t, destroy, void,
|
||||||
|
private_xauth_t *this)
|
||||||
|
{
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
xauth_t *xauth_create(ike_sa_t *ike_sa, bool initiator)
|
||||||
|
{
|
||||||
|
private_xauth_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.task = {
|
||||||
|
.get_type = _get_type,
|
||||||
|
.migrate = _migrate,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.initiator = initiator,
|
||||||
|
.ike_sa = ike_sa,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (initiator)
|
||||||
|
{
|
||||||
|
this->public.task.build = _build_i;
|
||||||
|
this->public.task.process = _process_i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->public.task.build = _build_r;
|
||||||
|
this->public.task.process = _process_r;
|
||||||
|
}
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 Martin Willi
|
||||||
|
* Copyright (C) 2011 revosec AG
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup xauth xauth
|
||||||
|
* @{ @ingroup tasks
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XAUTH_H_
|
||||||
|
#define XAUTH_H_
|
||||||
|
|
||||||
|
typedef struct xauth_t xauth_t;
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
#include <sa/ike_sa.h>
|
||||||
|
#include <sa/tasks/task.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task of type TASK_XAUTH, additional authentication after main/aggressive mode.
|
||||||
|
*/
|
||||||
|
struct xauth_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the task_t interface
|
||||||
|
*/
|
||||||
|
task_t task;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new xauth task.
|
||||||
|
*
|
||||||
|
* @param ike_sa IKE_SA this task works for
|
||||||
|
* @param initiator TRUE for initiator
|
||||||
|
* @return xauth task to handle by the task_manager
|
||||||
|
*/
|
||||||
|
xauth_t *xauth_create(ike_sa_t *ike_sa, bool initiator);
|
||||||
|
|
||||||
|
#endif /** XAUTH_H_ @}*/
|
||||||
@@ -1,770 +0,0 @@
|
|||||||
|
|
||||||
#include "xauth_request.h"
|
|
||||||
|
|
||||||
#include <daemon.h>
|
|
||||||
#include <hydra.h>
|
|
||||||
#include <encoding/payloads/cp_payload.h>
|
|
||||||
#include <sa/authenticators/xauth_authenticator.h>
|
|
||||||
|
|
||||||
typedef struct private_xauth_request_t private_xauth_request_t;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
XAUTH_STATUS_FAIL = 0,
|
|
||||||
XAUTH_STATUS_OK = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private members of a xauth_request_t task.
|
|
||||||
*/
|
|
||||||
struct private_xauth_request_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Public methods and task_t interface.
|
|
||||||
*/
|
|
||||||
xauth_request_t public;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigned IKE_SA.
|
|
||||||
*/
|
|
||||||
ike_sa_t *ike_sa;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Are we the initiator?
|
|
||||||
*/
|
|
||||||
bool initiator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* virtual ip
|
|
||||||
*/
|
|
||||||
host_t *virtual_ip;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* list of attributes requested and its handler, entry_t
|
|
||||||
*/
|
|
||||||
linked_list_t *requested;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current and next state of the task
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
TASK_XAUTH_INIT,
|
|
||||||
TASK_XAUTH_PASS_VERIFY,
|
|
||||||
TASK_XAUTH_COMPLETE,
|
|
||||||
} state, next_state;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The status of the XAuth request
|
|
||||||
*/
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current auth config
|
|
||||||
*/
|
|
||||||
auth_cfg_t *auth_cfg;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The received XAuth Status
|
|
||||||
*/
|
|
||||||
u_int16_t xauth_status_data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The received XAuth user name
|
|
||||||
*/
|
|
||||||
chunk_t xauth_user_name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The received XAuth user pass
|
|
||||||
*/
|
|
||||||
chunk_t xauth_user_pass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the user name attribute was received
|
|
||||||
*/
|
|
||||||
bool xauth_user_name_recv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the user pass attribute was received
|
|
||||||
*/
|
|
||||||
bool xauth_user_pass_recv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the XAuth status attribute was received
|
|
||||||
*/
|
|
||||||
bool xauth_status_recv;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The XAuth authenticator_t object
|
|
||||||
*/
|
|
||||||
authenticator_t *xauth_authenticator;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entry for a requested attribute and the requesting handler
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
/** attribute requested */
|
|
||||||
configuration_attribute_type_t type;
|
|
||||||
/** handler requesting this attribute */
|
|
||||||
attribute_handler_t *handler;
|
|
||||||
} entry_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the first authentcation config from peer config
|
|
||||||
*/
|
|
||||||
static auth_cfg_t *get_auth_cfg(private_xauth_request_t *this, bool local)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
auth_cfg_t *cfg = NULL;
|
|
||||||
peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
|
||||||
|
|
||||||
enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg,
|
|
||||||
local);
|
|
||||||
enumerator->enumerate(enumerator, &cfg);
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* build INTERNAL_IPV4/6_ADDRESS attribute from virtual ip
|
|
||||||
*/
|
|
||||||
static configuration_attribute_t *build_vip(payload_type_t ca_type, host_t *vip)
|
|
||||||
{
|
|
||||||
configuration_attribute_type_t type;
|
|
||||||
chunk_t chunk, prefix;
|
|
||||||
|
|
||||||
if (vip->get_family(vip) == AF_INET)
|
|
||||||
{
|
|
||||||
type = INTERNAL_IP4_ADDRESS;
|
|
||||||
if (vip->is_anyaddr(vip))
|
|
||||||
{
|
|
||||||
chunk = chunk_empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
chunk = vip->get_address(vip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
type = INTERNAL_IP6_ADDRESS;
|
|
||||||
if (vip->is_anyaddr(vip))
|
|
||||||
{
|
|
||||||
chunk = chunk_empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prefix = chunk_alloca(1);
|
|
||||||
*prefix.ptr = 64;
|
|
||||||
chunk = vip->get_address(vip);
|
|
||||||
chunk = chunk_cata("cc", chunk, prefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return configuration_attribute_create_chunk(ca_type,
|
|
||||||
type, chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a received attribute as initiator
|
|
||||||
*/
|
|
||||||
static void handle_attribute(private_xauth_request_t *this,
|
|
||||||
configuration_attribute_t *ca)
|
|
||||||
{
|
|
||||||
attribute_handler_t *handler = NULL;
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
entry_t *entry;
|
|
||||||
|
|
||||||
/* find the handler which requested this attribute */
|
|
||||||
enumerator = this->requested->create_enumerator(this->requested);
|
|
||||||
while (enumerator->enumerate(enumerator, &entry))
|
|
||||||
{
|
|
||||||
if (entry->type == ca->get_type(ca))
|
|
||||||
{
|
|
||||||
handler = entry->handler;
|
|
||||||
this->requested->remove_at(this->requested, enumerator);
|
|
||||||
free(entry);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
/* and pass it to the handle function */
|
|
||||||
handler = hydra->attributes->handle(hydra->attributes,
|
|
||||||
this->ike_sa->get_other_id(this->ike_sa), handler,
|
|
||||||
ca->get_type(ca), ca->get_chunk(ca));
|
|
||||||
if (handler)
|
|
||||||
{
|
|
||||||
this->ike_sa->add_configuration_attribute(this->ike_sa,
|
|
||||||
handler, ca->get_type(ca), ca->get_chunk(ca));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* process a single configuration attribute
|
|
||||||
*/
|
|
||||||
static void process_attribute(private_xauth_request_t *this,
|
|
||||||
configuration_attribute_t *ca)
|
|
||||||
{
|
|
||||||
host_t *ip;
|
|
||||||
chunk_t addr;
|
|
||||||
int family = AF_INET6;
|
|
||||||
|
|
||||||
switch (ca->get_type(ca))
|
|
||||||
{
|
|
||||||
case XAUTH_USER_NAME:
|
|
||||||
this->xauth_user_name = ca->get_chunk(ca);
|
|
||||||
this->xauth_user_name_recv = TRUE;
|
|
||||||
break;
|
|
||||||
case XAUTH_USER_PASSWORD:
|
|
||||||
this->xauth_user_pass = ca->get_chunk(ca);
|
|
||||||
this->xauth_user_pass_recv = TRUE;
|
|
||||||
break;
|
|
||||||
case XAUTH_STATUS:
|
|
||||||
this->xauth_status_data = ca->get_value(ca);
|
|
||||||
this->xauth_status_recv = TRUE;
|
|
||||||
break;
|
|
||||||
case INTERNAL_IP4_ADDRESS:
|
|
||||||
family = AF_INET;
|
|
||||||
/* fall */
|
|
||||||
case INTERNAL_IP6_ADDRESS:
|
|
||||||
{
|
|
||||||
addr = ca->get_chunk(ca);
|
|
||||||
if (addr.len == 0)
|
|
||||||
{
|
|
||||||
ip = host_create_any(family);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* skip prefix byte in IPv6 payload*/
|
|
||||||
if (family == AF_INET6)
|
|
||||||
{
|
|
||||||
addr.len--;
|
|
||||||
}
|
|
||||||
ip = host_create_from_chunk(family, addr, 0);
|
|
||||||
}
|
|
||||||
if (ip)
|
|
||||||
{
|
|
||||||
DESTROY_IF(this->virtual_ip);
|
|
||||||
this->virtual_ip = ip;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INTERNAL_IP4_SERVER:
|
|
||||||
case INTERNAL_IP6_SERVER:
|
|
||||||
/* assume it's a Windows client if we see proprietary attributes */
|
|
||||||
this->ike_sa->enable_extension(this->ike_sa, EXT_MS_WINDOWS);
|
|
||||||
/* fall */
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
if (this->initiator)
|
|
||||||
{
|
|
||||||
handle_attribute(this, ca);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scan for configuration payloads and attributes
|
|
||||||
*/
|
|
||||||
static status_t process_payloads(private_xauth_request_t *this, message_t *message)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator, *attributes;
|
|
||||||
payload_t *payload;
|
|
||||||
|
|
||||||
enumerator = message->create_payload_enumerator(message);
|
|
||||||
while (enumerator->enumerate(enumerator, &payload))
|
|
||||||
{
|
|
||||||
switch(payload->get_type(payload))
|
|
||||||
{
|
|
||||||
case CONFIGURATION:
|
|
||||||
case CONFIGURATION_V1:
|
|
||||||
{
|
|
||||||
cp_payload_t *cp = (cp_payload_t*)payload;
|
|
||||||
configuration_attribute_t *ca;
|
|
||||||
|
|
||||||
switch (cp->get_type(cp))
|
|
||||||
{
|
|
||||||
case CFG_REQUEST:
|
|
||||||
case CFG_REPLY:
|
|
||||||
case CFG_SET:
|
|
||||||
case CFG_ACK:
|
|
||||||
{
|
|
||||||
attributes = cp->create_attribute_enumerator(cp);
|
|
||||||
while (attributes->enumerate(attributes, &ca))
|
|
||||||
{
|
|
||||||
DBG2(DBG_IKE, "processing %N attribute",
|
|
||||||
configuration_attribute_type_names, ca->get_type(ca));
|
|
||||||
process_attribute(this, ca);
|
|
||||||
}
|
|
||||||
attributes->destroy(attributes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
DBG1(DBG_IKE, "ignoring %N config payload",
|
|
||||||
config_type_names, cp->get_type(cp));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(this->state)
|
|
||||||
{
|
|
||||||
case TASK_XAUTH_INIT:
|
|
||||||
if(((cp->get_type(cp) != CFG_REQUEST) && (cp->get_type(cp) != CFG_REPLY)) ||
|
|
||||||
(this->xauth_user_name_recv != TRUE) ||
|
|
||||||
(this->xauth_user_pass_recv != TRUE))
|
|
||||||
{
|
|
||||||
/* Didn't get an XAuth message, assume we're a ConfigMode message, set state appropriately */
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
this->next_state = TASK_XAUTH_COMPLETE;
|
|
||||||
this->status = SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
this->next_state = TASK_XAUTH_PASS_VERIFY;
|
|
||||||
break;
|
|
||||||
case TASK_XAUTH_PASS_VERIFY:
|
|
||||||
if(((cp->get_type(cp) != CFG_SET) && (cp->get_type(cp) != CFG_ACK)) ||
|
|
||||||
(this->xauth_status_recv != TRUE))
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "Didn't receive XAuth status.");
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
/* Set the return status for the build call */
|
|
||||||
if(cp->get_type(cp) != CFG_ACK)
|
|
||||||
{
|
|
||||||
this->status = (this->xauth_status_data == XAUTH_STATUS_OK ? SUCCESS : FAILED);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->status = SUCCESS;
|
|
||||||
}
|
|
||||||
this->next_state = TASK_XAUTH_COMPLETE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this->next_state = TASK_XAUTH_COMPLETE;
|
|
||||||
this->status = SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
if(this->xauth_authenticator)
|
|
||||||
{
|
|
||||||
this->xauth_authenticator->process(this->xauth_authenticator, message);
|
|
||||||
}
|
|
||||||
return NEED_MORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, build_i, status_t,
|
|
||||||
private_xauth_request_t *this, message_t *message)
|
|
||||||
{
|
|
||||||
cp_payload_t *cp = NULL;
|
|
||||||
chunk_t chunk = chunk_empty;
|
|
||||||
ike_version_t version;
|
|
||||||
payload_type_t cp_type;
|
|
||||||
payload_type_t ca_type;
|
|
||||||
host_t *vip;
|
|
||||||
peer_cfg_t *config;
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
attribute_handler_t *handler;
|
|
||||||
configuration_attribute_type_t type;
|
|
||||||
chunk_t data;
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
version = this->ike_sa->get_version(this->ike_sa);
|
|
||||||
if(version == IKEV1)
|
|
||||||
{
|
|
||||||
if(!this->auth_cfg)
|
|
||||||
{
|
|
||||||
this->auth_cfg = get_auth_cfg(this, TRUE);
|
|
||||||
}
|
|
||||||
switch((uintptr_t)this->auth_cfg->get(this->auth_cfg, AUTH_RULE_AUTH_CLASS))
|
|
||||||
{
|
|
||||||
case AUTH_CLASS_XAUTH_PSK:
|
|
||||||
case AUTH_CLASS_XAUTH_PUBKEY:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* We aren't XAuth, so do nothing */
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
cp_type = CONFIGURATION_V1;
|
|
||||||
ca_type = CONFIGURATION_ATTRIBUTE_V1;
|
|
||||||
}
|
|
||||||
else /* IKEv2 */
|
|
||||||
{
|
|
||||||
/* IKEv2 does not support XAuth, skip those states. */
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
if (message->get_message_id(message) == 1)
|
|
||||||
{ /* in first IKE_AUTH only */
|
|
||||||
return NEED_MORE;
|
|
||||||
}
|
|
||||||
cp_type = CONFIGURATION;
|
|
||||||
ca_type = CONFIGURATION_ATTRIBUTE;
|
|
||||||
}
|
|
||||||
switch(this->state)
|
|
||||||
{
|
|
||||||
case TASK_XAUTH_INIT:
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_REQUEST);
|
|
||||||
cp->add_attribute(cp, configuration_attribute_create_chunk(
|
|
||||||
ca_type, XAUTH_USER_NAME, chunk));
|
|
||||||
cp->add_attribute(cp, configuration_attribute_create_chunk(
|
|
||||||
ca_type, XAUTH_USER_PASSWORD, chunk));
|
|
||||||
break;
|
|
||||||
case TASK_XAUTH_PASS_VERIFY:
|
|
||||||
status = this->xauth_authenticator->build(this->xauth_authenticator, message);
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_SET);
|
|
||||||
cp->add_attribute(cp, configuration_attribute_create_value(
|
|
||||||
XAUTH_STATUS,
|
|
||||||
(status == FAILED ? XAUTH_STATUS_FAIL : XAUTH_STATUS_OK)));
|
|
||||||
break;
|
|
||||||
case TASK_XAUTH_COMPLETE:
|
|
||||||
/* ConfigMode stuff */
|
|
||||||
/* reuse virtual IP if we already have one */
|
|
||||||
vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
|
|
||||||
if (!vip)
|
|
||||||
{
|
|
||||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
|
||||||
vip = config->get_virtual_ip(config);
|
|
||||||
}
|
|
||||||
if (vip)
|
|
||||||
{
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_REQUEST);
|
|
||||||
cp->add_attribute(cp, build_vip(ca_type, vip));
|
|
||||||
}
|
|
||||||
|
|
||||||
enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes,
|
|
||||||
this->ike_sa->get_other_id(this->ike_sa), vip);
|
|
||||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
|
||||||
{
|
|
||||||
configuration_attribute_t *ca;
|
|
||||||
entry_t *entry;
|
|
||||||
|
|
||||||
/* create configuration attribute */
|
|
||||||
DBG2(DBG_IKE, "building %N attribute",
|
|
||||||
configuration_attribute_type_names, type);
|
|
||||||
ca = configuration_attribute_create_chunk(ca_type,
|
|
||||||
type, data);
|
|
||||||
if (!cp)
|
|
||||||
{
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_REQUEST);
|
|
||||||
}
|
|
||||||
cp->add_attribute(cp, ca);
|
|
||||||
|
|
||||||
/* save handler along with requested type */
|
|
||||||
entry = malloc_thing(entry_t);
|
|
||||||
entry->type = type;
|
|
||||||
entry->handler = handler;
|
|
||||||
|
|
||||||
this->requested->insert_last(this->requested, entry);
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FAILED;
|
|
||||||
|
|
||||||
}
|
|
||||||
/* Add the payloads into the message */
|
|
||||||
if(cp)
|
|
||||||
{
|
|
||||||
message->add_payload(message, (payload_t *)cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NEED_MORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, process_r, status_t,
|
|
||||||
private_xauth_request_t *this, message_t *message)
|
|
||||||
{
|
|
||||||
ike_version_t version;
|
|
||||||
payload_type_t cp_type;
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
version = this->ike_sa->get_version(this->ike_sa);
|
|
||||||
if(version == IKEV1)
|
|
||||||
{
|
|
||||||
if(!this->auth_cfg)
|
|
||||||
{
|
|
||||||
this->auth_cfg = get_auth_cfg(this, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch((uintptr_t)this->auth_cfg->get(this->auth_cfg, AUTH_RULE_AUTH_CLASS))
|
|
||||||
{
|
|
||||||
case AUTH_CLASS_XAUTH_PSK:
|
|
||||||
case AUTH_CLASS_XAUTH_PUBKEY:
|
|
||||||
if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
|
|
||||||
{
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->state = TASK_XAUTH_INIT;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* We aren't XAuth, so do we should expect ConfigMode stuff */
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((this->xauth_authenticator == NULL) && (this->state == TASK_XAUTH_INIT))
|
|
||||||
{
|
|
||||||
this->xauth_authenticator = (authenticator_t *)xauth_authenticator_create_builder(this->ike_sa);
|
|
||||||
}
|
|
||||||
cp_type = CONFIGURATION_V1;
|
|
||||||
}
|
|
||||||
else /* IKEv2 */
|
|
||||||
{
|
|
||||||
/* IKEv2 does not support XAuth, skip those states. */
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
if (message->get_message_id(message) == 1)
|
|
||||||
{ /* in first IKE_AUTH only */
|
|
||||||
return NEED_MORE;
|
|
||||||
}
|
|
||||||
cp_type = CONFIGURATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = process_payloads(this, message);
|
|
||||||
if(this->xauth_authenticator != NULL)
|
|
||||||
{
|
|
||||||
status = this->xauth_authenticator->process(this->xauth_authenticator, message);
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, build_r, status_t,
|
|
||||||
private_xauth_request_t *this, message_t *message)
|
|
||||||
{
|
|
||||||
status_t status;
|
|
||||||
cp_payload_t *cp = NULL;
|
|
||||||
payload_type_t cp_type = CONFIGURATION;
|
|
||||||
payload_type_t ca_type = CONFIGURATION_ATTRIBUTE;
|
|
||||||
ike_version_t version;
|
|
||||||
identification_t *id;
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
configuration_attribute_type_t type;
|
|
||||||
chunk_t value;
|
|
||||||
host_t *vip = NULL;
|
|
||||||
peer_cfg_t *config;
|
|
||||||
|
|
||||||
version = this->ike_sa->get_version(this->ike_sa);
|
|
||||||
if ((version == IKEV2) && (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED))
|
|
||||||
{
|
|
||||||
return NEED_MORE;
|
|
||||||
}
|
|
||||||
if(version == IKEV1)
|
|
||||||
{
|
|
||||||
if(!this->auth_cfg)
|
|
||||||
{
|
|
||||||
this->auth_cfg = get_auth_cfg(this, TRUE);
|
|
||||||
}
|
|
||||||
switch((uintptr_t)this->auth_cfg->get(this->auth_cfg, AUTH_RULE_AUTH_CLASS))
|
|
||||||
{
|
|
||||||
case AUTH_CLASS_XAUTH_PSK:
|
|
||||||
case AUTH_CLASS_XAUTH_PUBKEY:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
cp_type = CONFIGURATION_V1;
|
|
||||||
ca_type = CONFIGURATION_ATTRIBUTE_V1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(this->state)
|
|
||||||
{
|
|
||||||
case TASK_XAUTH_INIT:
|
|
||||||
status = this->xauth_authenticator->build(this->xauth_authenticator, message);
|
|
||||||
this->state = TASK_XAUTH_PASS_VERIFY;
|
|
||||||
break;
|
|
||||||
case TASK_XAUTH_PASS_VERIFY:
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_ACK);
|
|
||||||
cp->add_attribute(cp, configuration_attribute_create_value(
|
|
||||||
XAUTH_STATUS, XAUTH_STATUS_OK));
|
|
||||||
status = this->status;
|
|
||||||
this->state = TASK_XAUTH_COMPLETE;
|
|
||||||
break;
|
|
||||||
case TASK_XAUTH_COMPLETE:
|
|
||||||
id = this->ike_sa->get_other_eap_id(this->ike_sa);
|
|
||||||
|
|
||||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
|
||||||
if (this->virtual_ip)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
|
|
||||||
if (config->get_pool(config))
|
|
||||||
{
|
|
||||||
vip = hydra->attributes->acquire_address(hydra->attributes,
|
|
||||||
config->get_pool(config), id, this->virtual_ip);
|
|
||||||
}
|
|
||||||
if (vip == NULL)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IKE, "no virtual IP found, sending %N",
|
|
||||||
notify_type_names, INTERNAL_ADDRESS_FAILURE);
|
|
||||||
message->add_notify(message, FALSE, INTERNAL_ADDRESS_FAILURE,
|
|
||||||
chunk_empty);
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
|
|
||||||
this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
|
|
||||||
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_REPLY);
|
|
||||||
cp->add_attribute(cp, build_vip(ca_type, vip));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* query registered providers for additional attributes to include */
|
|
||||||
enumerator = hydra->attributes->create_responder_enumerator(
|
|
||||||
hydra->attributes, config->get_pool(config), id, vip);
|
|
||||||
while (enumerator->enumerate(enumerator, &type, &value))
|
|
||||||
{
|
|
||||||
if (!cp)
|
|
||||||
{
|
|
||||||
cp = cp_payload_create_type(cp_type, CFG_REPLY);
|
|
||||||
}
|
|
||||||
DBG2(DBG_IKE, "building %N attribute",
|
|
||||||
configuration_attribute_type_names, type);
|
|
||||||
cp->add_attribute(cp,
|
|
||||||
configuration_attribute_create_chunk(ca_type,
|
|
||||||
type, value));
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
status = SUCCESS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if(cp != NULL)
|
|
||||||
{
|
|
||||||
message->add_payload(message, (payload_t *)cp);
|
|
||||||
}
|
|
||||||
if(status == SUCCESS)
|
|
||||||
{
|
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
|
|
||||||
charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, process_i, status_t,
|
|
||||||
private_xauth_request_t *this, message_t *message)
|
|
||||||
{
|
|
||||||
status_t status;
|
|
||||||
|
|
||||||
if (((this->ike_sa->get_version(this->ike_sa) == IKEV2) &&
|
|
||||||
(this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)) ||
|
|
||||||
(this->ike_sa->get_version(this->ike_sa) == IKEV1))
|
|
||||||
{ /* in last IKE_AUTH exchange */
|
|
||||||
|
|
||||||
if(this->xauth_authenticator == NULL)
|
|
||||||
{
|
|
||||||
this->xauth_authenticator = (authenticator_t *)xauth_authenticator_create_verifier(this->ike_sa);
|
|
||||||
}
|
|
||||||
status = process_payloads(this, message);
|
|
||||||
this->state = this->next_state;
|
|
||||||
|
|
||||||
if (this->virtual_ip)
|
|
||||||
{
|
|
||||||
this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
|
|
||||||
}
|
|
||||||
if(this->state == TASK_XAUTH_COMPLETE)
|
|
||||||
{
|
|
||||||
if(this->status == SUCCESS)
|
|
||||||
{
|
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
|
|
||||||
charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->status;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
return NEED_MORE;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, get_type, task_type_t,
|
|
||||||
private_xauth_request_t *this)
|
|
||||||
{
|
|
||||||
return TASK_XAUTH_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, migrate, void,
|
|
||||||
private_xauth_request_t *this, ike_sa_t *ike_sa)
|
|
||||||
{
|
|
||||||
DESTROY_IF(this->virtual_ip);
|
|
||||||
|
|
||||||
this->ike_sa = ike_sa;
|
|
||||||
this->virtual_ip = NULL;
|
|
||||||
this->requested->destroy_function(this->requested, free);
|
|
||||||
this->requested = linked_list_create();
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, destroy, void,
|
|
||||||
private_xauth_request_t *this)
|
|
||||||
{
|
|
||||||
DESTROY_IF(this->virtual_ip);
|
|
||||||
this->requested->destroy_function(this->requested, free);
|
|
||||||
DESTROY_IF(this->xauth_authenticator);
|
|
||||||
free(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(task_t, swap_initiator, void,
|
|
||||||
private_xauth_request_t *this)
|
|
||||||
{
|
|
||||||
if(this->initiator)
|
|
||||||
{
|
|
||||||
this->public.task.build = _build_r;
|
|
||||||
this->public.task.process = _process_r;
|
|
||||||
this->initiator = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->public.task.build = _build_i;
|
|
||||||
this->public.task.process = _process_i;
|
|
||||||
this->initiator = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Described in header.
|
|
||||||
*/
|
|
||||||
xauth_request_t *xauth_request_create(ike_sa_t *ike_sa, bool initiator)
|
|
||||||
{
|
|
||||||
private_xauth_request_t *this;
|
|
||||||
|
|
||||||
INIT(this,
|
|
||||||
.public = {
|
|
||||||
.task = {
|
|
||||||
.get_type = _get_type,
|
|
||||||
.migrate = _migrate,
|
|
||||||
.destroy = _destroy,
|
|
||||||
.swap_initiator = _swap_initiator,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.initiator = initiator,
|
|
||||||
.ike_sa = ike_sa,
|
|
||||||
.requested = linked_list_create(),
|
|
||||||
.state = TASK_XAUTH_INIT,
|
|
||||||
.next_state = TASK_XAUTH_INIT,
|
|
||||||
.xauth_status_data = XAUTH_STATUS_FAIL,
|
|
||||||
.xauth_user_name = chunk_empty,
|
|
||||||
.xauth_user_pass = chunk_empty,
|
|
||||||
.xauth_user_name_recv = FALSE,
|
|
||||||
.xauth_user_pass_recv = FALSE,
|
|
||||||
.xauth_status_recv = FALSE,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (initiator)
|
|
||||||
{
|
|
||||||
this->public.task.build = _build_i;
|
|
||||||
this->public.task.process = _process_i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->public.task.build = _build_r;
|
|
||||||
this->public.task.process = _process_r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return &this->public;
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
|
|
||||||
/**
|
|
||||||
* @defgroup xauth_request xauth_request
|
|
||||||
* @{ @ingroup tasks
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef XAUTH_REQUEST_H_
|
|
||||||
#define XAUTH_REQUEST_H_
|
|
||||||
|
|
||||||
typedef struct xauth_request_t xauth_request_t;
|
|
||||||
|
|
||||||
#include <library.h>
|
|
||||||
#include <sa/ike_sa.h>
|
|
||||||
#include <sa/tasks/task.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Task of type XAUTH_REQUEST, gets the username and password from the ISAKMP_SA
|
|
||||||
* initializer.
|
|
||||||
*/
|
|
||||||
struct xauth_request_t {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implements the task_t interface
|
|
||||||
*/
|
|
||||||
task_t task;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new xauth_request task.
|
|
||||||
*
|
|
||||||
* @param ike_sa IKE_SA this task works for
|
|
||||||
* @param initiator TRUE for initiator
|
|
||||||
* @return ike_config task to handle by the task_manager
|
|
||||||
*/
|
|
||||||
xauth_request_t *xauth_request_create(ike_sa_t *ike_sa, bool initiator);
|
|
||||||
|
|
||||||
#endif /** XAUTH_REQUEST_H_ @}*/
|
|
||||||
@@ -18,8 +18,8 @@
|
|||||||
* @{ @ingroup libstrongswan
|
* @{ @ingroup libstrongswan
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XAUTH_H_
|
#ifndef XAUTH_H__
|
||||||
#define XAUTH_H_
|
#define XAUTH_H__
|
||||||
|
|
||||||
typedef enum xauth_type_t xauth_type_t;
|
typedef enum xauth_type_t xauth_type_t;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user