diff options
-rw-r--r-- | src/libcharon/Makefile.am | 3 | ||||
-rw-r--r-- | src/libcharon/sa/ike_sa.c | 21 | ||||
-rwxr-xr-x | src/libcharon/sa/ike_sa.h | 13 | ||||
-rwxr-xr-x | src/libcharon/sa/task_manager_v1.c | 20 | ||||
-rwxr-xr-x | src/libcharon/sa/tasks/main_mode.c | 78 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/task.c | 8 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/task.h | 4 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/xauth.c | 117 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/xauth.h | 50 | ||||
-rwxr-xr-x | src/libcharon/sa/tasks/xauth_request.c | 770 | ||||
-rw-r--r-- | src/libcharon/sa/tasks/xauth_request.h | 37 | ||||
-rw-r--r-- | src/libstrongswan/xauth/xauth.h | 4 |
12 files changed, 241 insertions, 884 deletions
diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index bf409d26c..3bddf0e61 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -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/update_sa_job.c processing/jobs/update_sa_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/eap_authenticator.c sa/authenticators/eap_authenticator.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_v1.c sa/tasks/ike_vendor_v1.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/xauth_request.c sa/tasks/xauth_request.h \ sa/tasks/task.c sa/tasks/task.h diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 47aadc108..11e7b18d2 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -50,7 +50,6 @@ #include <sa/tasks/quick_mode.h> #include <sa/tasks/ike_natd_v1.h> #include <sa/tasks/ike_vendor_v1.h> -#include <sa/tasks/xauth_request.h> #include <processing/jobs/retransmit_job.h> #include <processing/jobs/delete_ike_sa_job.h> #include <processing/jobs/send_dpd_job.h> @@ -1021,18 +1020,6 @@ METHOD(ike_sa_t, initiate_mediated, status_t, } #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 */ @@ -1839,6 +1826,12 @@ METHOD(ike_sa_t, create_task_enumerator, enumerator_t*, 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, 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, .set_kmaddress = _set_kmaddress, .create_task_enumerator = _create_task_enumerator, + .queue_task = _queue_task, #ifdef ME .act_as_mediation_server = _act_as_mediation_server, .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, .respond = _respond, #endif /* ME */ - .initiate_xauth = _initiate_xauth, }, .ike_sa_id = ike_sa_id->clone(ike_sa_id), .version = version, diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 15fd35c25..cbb16ca4a 100755 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -37,6 +37,7 @@ typedef struct ike_sa_t ike_sa_t; #include <encoding/payloads/configuration_attribute.h> #include <sa/ike_sa_id.h> #include <sa/child_sa.h> +#include <sa/tasks/task.h> #include <sa/task_manager.h> #include <sa/keymat.h> #include <config/peer_cfg.h> @@ -952,6 +953,13 @@ struct ike_sa_t { 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. * * When rekeying is completed, all CHILD_SAs, the virtual IP and all @@ -971,11 +979,6 @@ struct ike_sa_t { * Destroys a ike_sa_t object. */ void (*destroy) (ike_sa_t *this); - - /** - * Initiate an XAuth authentication exchange. - */ - status_t (*initiate_xauth) (ike_sa_t *this, bool initiate); }; /** diff --git a/src/libcharon/sa/task_manager_v1.c b/src/libcharon/sa/task_manager_v1.c index d557d970e..c01229564 100755 --- a/src/libcharon/sa/task_manager_v1.c +++ b/src/libcharon/sa/task_manager_v1.c @@ -22,7 +22,7 @@ #include <sa/tasks/child_delete.h> #include <sa/tasks/main_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_natd_v1.h> #include <sa/tasks/ike_vendor_v1.h> @@ -280,7 +280,7 @@ METHOD(task_manager_t, initiate, status_t, } break; case IKE_CONNECTING: - if (activate_task(this, TASK_XAUTH_REQUEST)) + if (activate_task(this, TASK_XAUTH)) { exchange = TRANSACTION; new_mid = TRUE; @@ -313,7 +313,7 @@ METHOD(task_manager_t, initiate, status_t, case TASK_QUICK_MODE: exchange = QUICK_MODE; break; - case TASK_XAUTH_REQUEST: + case TASK_XAUTH: exchange = TRANSACTION; new_mid = TRUE; break; @@ -648,7 +648,7 @@ static status_t process_request(private_task_manager_t *this, enumerator->destroy(enumerator); break; 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); break; default: @@ -688,7 +688,17 @@ static status_t process_request(private_task_manager_t *this, 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; } diff --git a/src/libcharon/sa/tasks/main_mode.c b/src/libcharon/sa/tasks/main_mode.c index a5945a826..f54427cc8 100755 --- a/src/libcharon/sa/tasks/main_mode.c +++ b/src/libcharon/sa/tasks/main_mode.c @@ -28,7 +28,7 @@ #include <encoding/payloads/nonce_payload.h> #include <encoding/payloads/id_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; @@ -738,6 +738,21 @@ METHOD(task_t, build_r, status_t, 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]", this->ike_sa->get_name(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_id(this->ike_sa)); - switch (this->auth_method) - { - 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; - } - } + this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); + charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE); + return SUCCESS; } default: @@ -858,7 +855,20 @@ METHOD(task_t, process_i, status_t, 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]", this->ike_sa->get_name(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_id(this->ike_sa)); - switch (this->auth_method) - { - 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; - } - } + this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED); + charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE); return SUCCESS; } diff --git a/src/libcharon/sa/tasks/task.c b/src/libcharon/sa/tasks/task.c index 145a4d6e7..dc4bf5e97 100644 --- a/src/libcharon/sa/tasks/task.c +++ b/src/libcharon/sa/tasks/task.c @@ -17,7 +17,7 @@ #include "task.h" #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_NATD", "IKE_MOBIKE", @@ -36,15 +36,15 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_XAUTH_REQUEST, "CHILD_DELETE", "CHILD_REKEY", "MAIN_MODE", + "XAUTH", "QUICK_MODE", "VENDOR_V1", "IKE_NATD_V1", "IKE_CERT_PRE_V1", "IKE_CERT_POST_V1", - "XAUTH_REQUEST", ); #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_NATD", "IKE_MOBIKE", @@ -62,11 +62,11 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_XAUTH_REQUEST, "CHILD_DELETE", "CHILD_REKEY", "MAIN_MODE", + "XAUTH", "QUICK_MODE", "VENDOR_V1", "IKE_NATD_V1", "IKE_CERT_PRE_V1", "IKE_CERT_POST_V1", - "XAUTH_REQUEST", ); #endif /* ME */ diff --git a/src/libcharon/sa/tasks/task.h b/src/libcharon/sa/tasks/task.h index 6fb8144ec..9a5cb7c53 100644 --- a/src/libcharon/sa/tasks/task.h +++ b/src/libcharon/sa/tasks/task.h @@ -71,6 +71,8 @@ enum task_type_t { TASK_CHILD_REKEY, /** IKEv1 main mode */ TASK_MAIN_MODE, + /** IKEv1 XAUTH authentication */ + TASK_XAUTH, /** IKEv1 quick mode */ TASK_QUICK_MODE, /** IKEv1 vendor ID payload handling */ @@ -81,8 +83,6 @@ enum task_type_t { TASK_IKE_CERT_PRE_V1, /** IKEv1 post-authentication certificate handling */ TASK_IKE_CERT_POST_V1, - /** Request the user/pass with XAUTH */ - TASK_XAUTH_REQUEST, }; /** diff --git a/src/libcharon/sa/tasks/xauth.c b/src/libcharon/sa/tasks/xauth.c new file mode 100644 index 000000000..4d12e16e6 --- /dev/null +++ b/src/libcharon/sa/tasks/xauth.c @@ -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; +} diff --git a/src/libcharon/sa/tasks/xauth.h b/src/libcharon/sa/tasks/xauth.h new file mode 100644 index 000000000..6633f9e55 --- /dev/null +++ b/src/libcharon/sa/tasks/xauth.h @@ -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_ @}*/ diff --git a/src/libcharon/sa/tasks/xauth_request.c b/src/libcharon/sa/tasks/xauth_request.c deleted file mode 100755 index dbce6e514..000000000 --- a/src/libcharon/sa/tasks/xauth_request.c +++ /dev/null @@ -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; -} diff --git a/src/libcharon/sa/tasks/xauth_request.h b/src/libcharon/sa/tasks/xauth_request.h deleted file mode 100644 index 6324ca0de..000000000 --- a/src/libcharon/sa/tasks/xauth_request.h +++ /dev/null @@ -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_ @}*/ diff --git a/src/libstrongswan/xauth/xauth.h b/src/libstrongswan/xauth/xauth.h index 4554ee779..97008afcb 100644 --- a/src/libstrongswan/xauth/xauth.h +++ b/src/libstrongswan/xauth/xauth.h @@ -18,8 +18,8 @@ * @{ @ingroup libstrongswan */ -#ifndef XAUTH_H_ -#define XAUTH_H_ +#ifndef XAUTH_H__ +#define XAUTH_H__ typedef enum xauth_type_t xauth_type_t; |