2 #include "xauth_request.h"
6 #include <encoding/payloads/cp_payload.h>
8 typedef struct private_xauth_request_t private_xauth_request_t
;
11 XAUTH_STATUS_FAIL
= 0,
16 * Private members of a xauth_request_t task.
18 struct private_xauth_request_t
{
21 * Public methods and task_t interface.
23 xauth_request_t
public;
31 * Are we the initiator?
41 * list of attributes requested and its handler, entry_t
43 linked_list_t
*requested
;
46 * The current and next state of the task
50 TASK_XAUTH_PASS_VERIFY
,
55 * The status of the XAuth request
60 * The current auth config
65 * The received XAuth Status
67 u_int16_t xauth_status_data
;
70 * The received XAuth user name
72 chunk_t xauth_user_name
;
75 * The received XAuth user pass
77 chunk_t xauth_user_pass
;
80 * Whether the user name attribute was received
82 bool xauth_user_name_recv
;
85 * Whether the user pass attribute was received
87 bool xauth_user_pass_recv
;
90 * Whether the XAuth status attribute was received
92 bool xauth_status_recv
;
96 * Entry for a requested attribute and the requesting handler
99 /** attribute requested */
100 configuration_attribute_type_t type
;
101 /** handler requesting this attribute */
102 attribute_handler_t
*handler
;
106 * Get the first authentcation config from peer config
108 static auth_cfg_t
*get_auth_cfg(private_xauth_request_t
*this, bool local
)
110 enumerator_t
*enumerator
;
111 auth_cfg_t
*cfg
= NULL
;
112 peer_cfg_t
*peer_cfg
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
114 enumerator
= peer_cfg
->create_auth_cfg_enumerator(peer_cfg
,
116 enumerator
->enumerate(enumerator
, &cfg
);
117 enumerator
->destroy(enumerator
);
122 * build INTERNAL_IPV4/6_ADDRESS attribute from virtual ip
124 static configuration_attribute_t
*build_vip(host_t
*vip
)
126 configuration_attribute_type_t type
;
127 chunk_t chunk
, prefix
;
129 if (vip
->get_family(vip
) == AF_INET
)
131 type
= INTERNAL_IP4_ADDRESS
;
132 if (vip
->is_anyaddr(vip
))
138 chunk
= vip
->get_address(vip
);
143 type
= INTERNAL_IP6_ADDRESS
;
144 if (vip
->is_anyaddr(vip
))
150 prefix
= chunk_alloca(1);
152 chunk
= vip
->get_address(vip
);
153 chunk
= chunk_cata("cc", chunk
, prefix
);
156 return configuration_attribute_create_chunk(CONFIGURATION_ATTRIBUTE
,
161 * Handle a received attribute as initiator
163 static void handle_attribute(private_xauth_request_t
*this,
164 configuration_attribute_t
*ca
)
166 attribute_handler_t
*handler
= NULL
;
167 enumerator_t
*enumerator
;
170 /* find the handler which requested this attribute */
171 enumerator
= this->requested
->create_enumerator(this->requested
);
172 while (enumerator
->enumerate(enumerator
, &entry
))
174 if (entry
->type
== ca
->get_type(ca
))
176 handler
= entry
->handler
;
177 this->requested
->remove_at(this->requested
, enumerator
);
182 enumerator
->destroy(enumerator
);
184 /* and pass it to the handle function */
185 handler
= hydra
->attributes
->handle(hydra
->attributes
,
186 this->ike_sa
->get_other_id(this->ike_sa
), handler
,
187 ca
->get_type(ca
), ca
->get_chunk(ca
));
190 this->ike_sa
->add_configuration_attribute(this->ike_sa
,
191 handler
, ca
->get_type(ca
), ca
->get_chunk(ca
));
196 * process a single configuration attribute
198 static void process_attribute(private_xauth_request_t
*this,
199 configuration_attribute_t
*ca
)
203 int family
= AF_INET6
;
205 switch (ca
->get_type(ca
))
207 case XAUTH_USER_NAME
:
208 this->xauth_user_name
= ca
->get_chunk(ca
);
209 this->xauth_user_name_recv
= TRUE
;
211 case XAUTH_USER_PASSWORD
:
212 this->xauth_user_pass
= ca
->get_chunk(ca
);
213 this->xauth_user_pass_recv
= TRUE
;
216 this->xauth_status_data
= ca
->get_value(ca
);
217 this->xauth_status_recv
= TRUE
;
219 case INTERNAL_IP4_ADDRESS
:
222 case INTERNAL_IP6_ADDRESS
:
224 addr
= ca
->get_chunk(ca
);
227 ip
= host_create_any(family
);
231 /* skip prefix byte in IPv6 payload*/
232 if (family
== AF_INET6
)
236 ip
= host_create_from_chunk(family
, addr
, 0);
240 DESTROY_IF(this->virtual_ip
);
241 this->virtual_ip
= ip
;
245 case INTERNAL_IP4_SERVER
:
246 case INTERNAL_IP6_SERVER
:
247 /* assume it's a Windows client if we see proprietary attributes */
248 this->ike_sa
->enable_extension(this->ike_sa
, EXT_MS_WINDOWS
);
254 handle_attribute(this, ca
);
261 * Scan for configuration payloads and attributes
263 static status_t
process_payloads(private_xauth_request_t
*this, message_t
*message
)
265 enumerator_t
*enumerator
, *attributes
;
268 enumerator
= message
->create_payload_enumerator(message
);
269 while (enumerator
->enumerate(enumerator
, &payload
))
271 switch(payload
->get_type(payload
))
274 case CONFIGURATION_V1
:
276 cp_payload_t
*cp
= (cp_payload_t
*)payload
;
277 configuration_attribute_t
*ca
;
279 switch (cp
->get_type(cp
))
286 attributes
= cp
->create_attribute_enumerator(cp
);
287 while (attributes
->enumerate(attributes
, &ca
))
289 DBG2(DBG_IKE
, "processing %N attribute",
290 configuration_attribute_type_names
, ca
->get_type(ca
));
291 process_attribute(this, ca
);
293 attributes
->destroy(attributes
);
297 DBG1(DBG_IKE
, "ignoring %N config payload",
298 config_type_names
, cp
->get_type(cp
));
304 case TASK_XAUTH_INIT
:
305 if(((cp
->get_type(cp
) != CFG_REQUEST
) && (cp
->get_type(cp
) != CFG_REPLY
)) ||
306 (this->xauth_user_name_recv
!= TRUE
) ||
307 (this->xauth_user_pass_recv
!= TRUE
))
309 /* Didn't get an XAuth message, assume we're a ConfigMode message, set state appropriately */
310 this->state
= TASK_XAUTH_COMPLETE
;
311 this->next_state
= TASK_XAUTH_COMPLETE
;
312 this->status
= SUCCESS
;
315 this->next_state
= TASK_XAUTH_PASS_VERIFY
;
317 case TASK_XAUTH_PASS_VERIFY
:
318 if(((cp
->get_type(cp
) != CFG_SET
) && (cp
->get_type(cp
) != CFG_ACK
)) ||
319 (this->xauth_status_recv
!= TRUE
))
321 DBG1(DBG_IKE
, "Didn't receive XAuth status.");
324 /* Set the return status for the build call */
325 if(cp
->get_type(cp
) != CFG_ACK
)
327 this->status
= (this->xauth_status_data
== XAUTH_STATUS_OK ? SUCCESS
: FAILED
);
331 this->status
= SUCCESS
;
333 this->next_state
= TASK_XAUTH_COMPLETE
;
336 this->next_state
= TASK_XAUTH_COMPLETE
;
337 this->status
= SUCCESS
;
345 enumerator
->destroy(enumerator
);
349 METHOD(task_t
, build_i
, status_t
,
350 private_xauth_request_t
*this, message_t
*message
)
352 cp_payload_t
*cp
= NULL
;
353 chunk_t chunk
= chunk_empty
;
354 ike_version_t version
;
355 payload_type_t cp_type
;
356 payload_type_t ca_type
;
359 enumerator_t
*enumerator
;
360 attribute_handler_t
*handler
;
361 configuration_attribute_type_t type
;
364 DBG1(DBG_IKE
, "%s: state %d", __func__
, this->state
);
366 version
= this->ike_sa
->get_version(this->ike_sa
);
369 if(this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
371 DBG1(DBG_IKE
, "!!!!!!!!!!!!!!!!!!!!!!!!!NEED_MORE!!!!!!!!!!!!!!!!!!!!!");
377 this->auth_cfg
= get_auth_cfg(this, TRUE
);
379 switch((uintptr_t)this->auth_cfg
->get(this->auth_cfg
, AUTH_RULE_AUTH_CLASS
))
381 case AUTH_CLASS_XAUTH_PSK
:
382 case AUTH_CLASS_XAUTH_PUBKEY
:
385 /* We aren't XAuth, so do nothing */
386 DBG1(DBG_IKE
, "!!!!!!!!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!!");
389 cp_type
= CONFIGURATION_V1
;
390 ca_type
= CONFIGURATION_ATTRIBUTE_V1
;
394 /* IKEv2 does not support XAuth, skip those states. */
395 this->state
= TASK_XAUTH_COMPLETE
;
396 if (message
->get_message_id(message
) == 1)
397 { /* in first IKE_AUTH only */
398 DBG1(DBG_IKE
, "!!!!!!!!!!!!!!!!!!!!!!!!!NEED_MORE!!!!!!!!!!!!!!!!!!!!!");
401 cp_type
= CONFIGURATION
;
402 ca_type
= CONFIGURATION_ATTRIBUTE
;
406 case TASK_XAUTH_INIT
:
407 cp
= cp_payload_create_type(cp_type
, CFG_REQUEST
);
408 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
409 ca_type
, XAUTH_USER_NAME
, chunk
));
410 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
411 ca_type
, XAUTH_USER_PASSWORD
, chunk
));
413 case TASK_XAUTH_PASS_VERIFY
:
414 cp
= cp_payload_create_type(cp_type
, CFG_SET
);
415 cp
->add_attribute(cp
, configuration_attribute_create_value(
417 (this->status
== FAILED ? XAUTH_STATUS_FAIL
: XAUTH_STATUS_OK
)));
419 case TASK_XAUTH_COMPLETE
:
420 /* ConfigMode stuff */
421 /* reuse virtual IP if we already have one */
422 vip
= this->ike_sa
->get_virtual_ip(this->ike_sa
, TRUE
);
425 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
426 vip
= config
->get_virtual_ip(config
);
430 cp
= cp_payload_create_type(cp_type
, CFG_REQUEST
);
431 cp
->add_attribute(cp
, build_vip(vip
));
434 enumerator
= hydra
->attributes
->create_initiator_enumerator(hydra
->attributes
,
435 this->ike_sa
->get_other_id(this->ike_sa
), vip
);
436 while (enumerator
->enumerate(enumerator
, &handler
, &type
, &data
))
438 configuration_attribute_t
*ca
;
441 /* create configuration attribute */
442 DBG2(DBG_IKE
, "building %N attribute",
443 configuration_attribute_type_names
, type
);
444 ca
= configuration_attribute_create_chunk(ca_type
,
448 cp
= cp_payload_create_type(cp_type
, CFG_REQUEST
);
450 cp
->add_attribute(cp
, ca
);
452 /* save handler along with requested type */
453 entry
= malloc_thing(entry_t
);
455 entry
->handler
= handler
;
457 this->requested
->insert_last(this->requested
, entry
);
459 enumerator
->destroy(enumerator
);
463 DBG1(DBG_IKE
, "!!!!!!!!!!!!!!!!!!!!!!!!!FAILED!!!!!!!!!!!!!!!!!!!!!");
467 /* Add the payloads into the message */
470 message
->add_payload(message
, (payload_t
*)cp
);
473 DBG1(DBG_IKE
, "!!!!!!!!!!!!!!!!!!!!!!!!!NEED_MORE!!!!!!!!!!!!!!!!!!!!!");
477 METHOD(task_t
, process_r
, status_t
,
478 private_xauth_request_t
*this, message_t
*message
)
480 ike_version_t version
;
481 payload_type_t cp_type
;
482 DBG1(DBG_IKE
, "%s: state %d", __func__
, this->state
);
484 version
= this->ike_sa
->get_version(this->ike_sa
);
487 if(this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
493 this->auth_cfg
= get_auth_cfg(this, TRUE
);
495 switch((uintptr_t)this->auth_cfg
->get(this->auth_cfg
, AUTH_RULE_AUTH_CLASS
))
497 case AUTH_CLASS_XAUTH_PSK
:
498 case AUTH_CLASS_XAUTH_PUBKEY
:
501 /* We aren't XAuth, so do we should expect ConfigMode stuff */
504 cp_type
= CONFIGURATION_V1
;
508 /* IKEv2 does not support XAuth, skip those states. */
509 this->state
= TASK_XAUTH_COMPLETE
;
510 if (message
->get_message_id(message
) == 1)
511 { /* in first IKE_AUTH only */
514 cp_type
= CONFIGURATION
;
517 return process_payloads(this, message
);
520 METHOD(task_t
, build_r
, status_t
,
521 private_xauth_request_t
*this, message_t
*message
)
523 chunk_t user_name
= chunk_from_chars('j', 'o', 's', 't');
524 chunk_t user_pass
= chunk_from_chars('j', 'o', 's', 't');
526 cp_payload_t
*cp
= NULL
;
527 payload_type_t cp_type
= CONFIGURATION
;
528 payload_type_t ca_type
= CONFIGURATION_ATTRIBUTE
;
529 ike_version_t version
;
530 identification_t
*id
;
531 enumerator_t
*enumerator
;
532 configuration_attribute_type_t type
;
537 DBG1(DBG_IKE
, "%s: state %d", __func__
, this->state
);
538 if(this->ike_sa
->get_state(this->ike_sa
) != IKE_ESTABLISHED
)
542 version
= this->ike_sa
->get_version(this->ike_sa
);
547 this->auth_cfg
= get_auth_cfg(this, TRUE
);
549 switch((uintptr_t)this->auth_cfg
->get(this->auth_cfg
, AUTH_RULE_AUTH_CLASS
))
551 case AUTH_CLASS_XAUTH_PSK
:
552 case AUTH_CLASS_XAUTH_PUBKEY
:
555 this->state
= TASK_XAUTH_COMPLETE
;
558 cp_type
= CONFIGURATION_V1
;
559 ca_type
= CONFIGURATION_ATTRIBUTE_V1
;
564 case TASK_XAUTH_INIT
:
565 /* TODO-IKEv1: Fetch the user/pass from an authenticator */
566 cp
= cp_payload_create_type(cp_type
, CFG_REPLY
);
567 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
568 ca_type
, XAUTH_USER_NAME
, user_name
));
569 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
570 ca_type
, XAUTH_USER_PASSWORD
, user_pass
));
571 chunk_clear(&user_name
);
572 chunk_clear(&user_pass
);
574 this->state
= TASK_XAUTH_PASS_VERIFY
;
577 case TASK_XAUTH_PASS_VERIFY
:
578 cp
= cp_payload_create_type(cp_type
, CFG_ACK
);
579 cp
->add_attribute(cp
, configuration_attribute_create_value(
580 XAUTH_STATUS
, XAUTH_STATUS_OK
));
581 status
= this->status
;
582 this->state
= TASK_XAUTH_COMPLETE
;
584 case TASK_XAUTH_COMPLETE
:
585 id
= this->ike_sa
->get_other_eap_id(this->ike_sa
);
587 config
= this->ike_sa
->get_peer_cfg(this->ike_sa
);
588 if (this->virtual_ip
)
590 DBG1(DBG_IKE
, "peer requested virtual IP %H", this->virtual_ip
);
591 if (config
->get_pool(config
))
593 vip
= hydra
->attributes
->acquire_address(hydra
->attributes
,
594 config
->get_pool(config
), id
, this->virtual_ip
);
598 DBG1(DBG_IKE
, "no virtual IP found, sending %N",
599 notify_type_names
, INTERNAL_ADDRESS_FAILURE
);
600 message
->add_notify(message
, FALSE
, INTERNAL_ADDRESS_FAILURE
,
604 DBG1(DBG_IKE
, "assigning virtual IP %H to peer '%Y'", vip
, id
);
605 this->ike_sa
->set_virtual_ip(this->ike_sa
, FALSE
, vip
);
607 cp
= cp_payload_create_type(cp_type
, CFG_REPLY
);
608 cp
->add_attribute(cp
, build_vip(vip
));
611 /* query registered providers for additional attributes to include */
612 enumerator
= hydra
->attributes
->create_responder_enumerator(
613 hydra
->attributes
, config
->get_pool(config
), id
, vip
);
614 while (enumerator
->enumerate(enumerator
, &type
, &value
))
618 cp
= cp_payload_create_type(cp_type
, CFG_REPLY
);
620 DBG2(DBG_IKE
, "building %N attribute",
621 configuration_attribute_type_names
, type
);
622 cp
->add_attribute(cp
,
623 configuration_attribute_create_chunk(ca_type
,
626 enumerator
->destroy(enumerator
);
635 METHOD(task_t
, process_i
, status_t
,
636 private_xauth_request_t
*this, message_t
*message
)
639 DBG1(DBG_IKE
, "%s: state %d", __func__
, this->state
);
640 if (this->ike_sa
->get_state(this->ike_sa
) == IKE_ESTABLISHED
)
641 { /* in last IKE_AUTH exchange */
643 status
= process_payloads(this, message
);
644 this->state
= this->next_state
;
646 DBG1(DBG_IKE
, "state %d, complete state %d", this->state
, TASK_XAUTH_COMPLETE
);
647 DBG1(DBG_IKE
, "status %d SUCCESS %d", this->status
, SUCCESS
);
649 if (this->virtual_ip
)
651 this->ike_sa
->set_virtual_ip(this->ike_sa
, TRUE
, this->virtual_ip
);
653 if(this->state
== TASK_XAUTH_COMPLETE
)
661 METHOD(task_t
, get_type
, task_type_t
,
662 private_xauth_request_t
*this)
664 return TASK_XAUTH_REQUEST
;
667 METHOD(task_t
, migrate
, void,
668 private_xauth_request_t
*this, ike_sa_t
*ike_sa
)
670 DESTROY_IF(this->virtual_ip
);
672 this->ike_sa
= ike_sa
;
673 this->virtual_ip
= NULL
;
674 this->requested
->destroy_function(this->requested
, free
);
675 this->requested
= linked_list_create();
678 METHOD(task_t
, destroy
, void,
679 private_xauth_request_t
*this)
681 DESTROY_IF(this->virtual_ip
);
682 this->requested
->destroy_function(this->requested
, free
);
686 METHOD(task_t
, swap_initiator
, void,
687 private_xauth_request_t
*this)
691 this->public.task
.build
= _build_r
;
692 this->public.task
.process
= _process_r
;
693 this->initiator
= FALSE
;
697 this->public.task
.build
= _build_i
;
698 this->public.task
.process
= _process_i
;
699 this->initiator
= TRUE
;
704 * Described in header.
706 xauth_request_t
*xauth_request_create(ike_sa_t
*ike_sa
, bool initiator
)
708 private_xauth_request_t
*this;
713 .get_type
= _get_type
,
716 .swap_initiator
= _swap_initiator
,
719 .initiator
= initiator
,
721 .requested
= linked_list_create(),
722 .state
= TASK_XAUTH_INIT
,
723 .next_state
= TASK_XAUTH_INIT
,
724 .xauth_status_data
= XAUTH_STATUS_FAIL
,
725 .xauth_user_name
= chunk_empty
,
726 .xauth_user_pass
= chunk_empty
,
727 .xauth_user_name_recv
= FALSE
,
728 .xauth_user_pass_recv
= FALSE
,
729 .xauth_status_recv
= FALSE
,
734 this->public.task
.build
= _build_i
;
735 this->public.task
.process
= _process_i
;
739 this->public.task
.build
= _build_r
;
740 this->public.task
.process
= _process_r
;
743 return &this->public;