diff options
author | Martin Willi <martin@revosec.ch> | 2011-12-08 16:19:54 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-03-20 17:31:15 +0100 |
commit | 69adeb5bf25b9938a0aff34718ece9d2be4f32ef (patch) | |
tree | 941300cdb29ae0459ae697eb2ab933d62effc5b3 /src/libcharon/sa/tasks/xauth_request.c | |
parent | c6d0098c1b8ae90579458987b9a901178c897640 (diff) | |
download | strongswan-69adeb5bf25b9938a0aff34718ece9d2be4f32ef.tar.bz2 strongswan-69adeb5bf25b9938a0aff34718ece9d2be4f32ef.tar.xz |
Replace xauth_request task with a new stub where we reimplement it
Diffstat (limited to 'src/libcharon/sa/tasks/xauth_request.c')
-rwxr-xr-x | src/libcharon/sa/tasks/xauth_request.c | 770 |
1 files changed, 0 insertions, 770 deletions
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; -} |