XAUTH additions for certificates.
[strongswan.git] / src / libcharon / sa / tasks / xauth_request.c
1
2 #include "xauth_request.h"
3
4 #include <daemon.h>
5 #include <hydra.h>
6 #include <encoding/payloads/cp_payload.h>
7 #include <sa/authenticators/xauth_authenticator.h>
8
9 typedef struct private_xauth_request_t private_xauth_request_t;
10
11 enum {
12 XAUTH_STATUS_FAIL = 0,
13 XAUTH_STATUS_OK = 1,
14 };
15
16 /**
17 * Private members of a xauth_request_t task.
18 */
19 struct private_xauth_request_t {
20
21 /**
22 * Public methods and task_t interface.
23 */
24 xauth_request_t public;
25
26 /**
27 * Assigned IKE_SA.
28 */
29 ike_sa_t *ike_sa;
30
31 /**
32 * Are we the initiator?
33 */
34 bool initiator;
35
36 /**
37 * virtual ip
38 */
39 host_t *virtual_ip;
40
41 /**
42 * list of attributes requested and its handler, entry_t
43 */
44 linked_list_t *requested;
45
46 /**
47 * The current and next state of the task
48 */
49 enum {
50 TASK_XAUTH_INIT,
51 TASK_XAUTH_PASS_VERIFY,
52 TASK_XAUTH_COMPLETE,
53 } state, next_state;
54
55 /**
56 * The status of the XAuth request
57 */
58 status_t status;
59
60 /**
61 * The current auth config
62 */
63 auth_cfg_t *auth_cfg;
64
65 /**
66 * The received XAuth Status
67 */
68 u_int16_t xauth_status_data;
69
70 /**
71 * The received XAuth user name
72 */
73 chunk_t xauth_user_name;
74
75 /**
76 * The received XAuth user pass
77 */
78 chunk_t xauth_user_pass;
79
80 /**
81 * Whether the user name attribute was received
82 */
83 bool xauth_user_name_recv;
84
85 /**
86 * Whether the user pass attribute was received
87 */
88 bool xauth_user_pass_recv;
89
90 /**
91 * Whether the XAuth status attribute was received
92 */
93 bool xauth_status_recv;
94
95 /**
96 * The XAuth authenticator_t object
97 */
98 authenticator_t *xauth_authenticator;
99 };
100
101 /**
102 * Entry for a requested attribute and the requesting handler
103 */
104 typedef struct {
105 /** attribute requested */
106 configuration_attribute_type_t type;
107 /** handler requesting this attribute */
108 attribute_handler_t *handler;
109 } entry_t;
110
111 /**
112 * Get the first authentcation config from peer config
113 */
114 static auth_cfg_t *get_auth_cfg(private_xauth_request_t *this, bool local)
115 {
116 enumerator_t *enumerator;
117 auth_cfg_t *cfg = NULL;
118 peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
119
120 enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg,
121 local);
122 enumerator->enumerate(enumerator, &cfg);
123 enumerator->destroy(enumerator);
124 return cfg;
125 }
126
127 /**
128 * build INTERNAL_IPV4/6_ADDRESS attribute from virtual ip
129 */
130 static configuration_attribute_t *build_vip(payload_type_t ca_type, host_t *vip)
131 {
132 configuration_attribute_type_t type;
133 chunk_t chunk, prefix;
134
135 if (vip->get_family(vip) == AF_INET)
136 {
137 type = INTERNAL_IP4_ADDRESS;
138 if (vip->is_anyaddr(vip))
139 {
140 chunk = chunk_empty;
141 }
142 else
143 {
144 chunk = vip->get_address(vip);
145 }
146 }
147 else
148 {
149 type = INTERNAL_IP6_ADDRESS;
150 if (vip->is_anyaddr(vip))
151 {
152 chunk = chunk_empty;
153 }
154 else
155 {
156 prefix = chunk_alloca(1);
157 *prefix.ptr = 64;
158 chunk = vip->get_address(vip);
159 chunk = chunk_cata("cc", chunk, prefix);
160 }
161 }
162 return configuration_attribute_create_chunk(ca_type,
163 type, chunk);
164 }
165
166 /**
167 * Handle a received attribute as initiator
168 */
169 static void handle_attribute(private_xauth_request_t *this,
170 configuration_attribute_t *ca)
171 {
172 attribute_handler_t *handler = NULL;
173 enumerator_t *enumerator;
174 entry_t *entry;
175
176 /* find the handler which requested this attribute */
177 enumerator = this->requested->create_enumerator(this->requested);
178 while (enumerator->enumerate(enumerator, &entry))
179 {
180 if (entry->type == ca->get_type(ca))
181 {
182 handler = entry->handler;
183 this->requested->remove_at(this->requested, enumerator);
184 free(entry);
185 break;
186 }
187 }
188 enumerator->destroy(enumerator);
189
190 /* and pass it to the handle function */
191 handler = hydra->attributes->handle(hydra->attributes,
192 this->ike_sa->get_other_id(this->ike_sa), handler,
193 ca->get_type(ca), ca->get_chunk(ca));
194 if (handler)
195 {
196 this->ike_sa->add_configuration_attribute(this->ike_sa,
197 handler, ca->get_type(ca), ca->get_chunk(ca));
198 }
199 }
200
201 /**
202 * process a single configuration attribute
203 */
204 static void process_attribute(private_xauth_request_t *this,
205 configuration_attribute_t *ca)
206 {
207 host_t *ip;
208 chunk_t addr;
209 int family = AF_INET6;
210
211 switch (ca->get_type(ca))
212 {
213 case XAUTH_USER_NAME:
214 this->xauth_user_name = ca->get_chunk(ca);
215 this->xauth_user_name_recv = TRUE;
216 break;
217 case XAUTH_USER_PASSWORD:
218 this->xauth_user_pass = ca->get_chunk(ca);
219 this->xauth_user_pass_recv = TRUE;
220 break;
221 case XAUTH_STATUS:
222 this->xauth_status_data = ca->get_value(ca);
223 this->xauth_status_recv = TRUE;
224 break;
225 case INTERNAL_IP4_ADDRESS:
226 family = AF_INET;
227 /* fall */
228 case INTERNAL_IP6_ADDRESS:
229 {
230 addr = ca->get_chunk(ca);
231 if (addr.len == 0)
232 {
233 ip = host_create_any(family);
234 }
235 else
236 {
237 /* skip prefix byte in IPv6 payload*/
238 if (family == AF_INET6)
239 {
240 addr.len--;
241 }
242 ip = host_create_from_chunk(family, addr, 0);
243 }
244 if (ip)
245 {
246 DESTROY_IF(this->virtual_ip);
247 this->virtual_ip = ip;
248 }
249 break;
250 }
251 case INTERNAL_IP4_SERVER:
252 case INTERNAL_IP6_SERVER:
253 /* assume it's a Windows client if we see proprietary attributes */
254 this->ike_sa->enable_extension(this->ike_sa, EXT_MS_WINDOWS);
255 /* fall */
256 default:
257 {
258 if (this->initiator)
259 {
260 handle_attribute(this, ca);
261 }
262 }
263 }
264 }
265
266 /**
267 * Scan for configuration payloads and attributes
268 */
269 static status_t process_payloads(private_xauth_request_t *this, message_t *message)
270 {
271 enumerator_t *enumerator, *attributes;
272 payload_t *payload;
273
274 enumerator = message->create_payload_enumerator(message);
275 while (enumerator->enumerate(enumerator, &payload))
276 {
277 switch(payload->get_type(payload))
278 {
279 case CONFIGURATION:
280 case CONFIGURATION_V1:
281 {
282 cp_payload_t *cp = (cp_payload_t*)payload;
283 configuration_attribute_t *ca;
284
285 switch (cp->get_type(cp))
286 {
287 case CFG_REQUEST:
288 case CFG_REPLY:
289 case CFG_SET:
290 case CFG_ACK:
291 {
292 attributes = cp->create_attribute_enumerator(cp);
293 while (attributes->enumerate(attributes, &ca))
294 {
295 DBG2(DBG_IKE, "processing %N attribute",
296 configuration_attribute_type_names, ca->get_type(ca));
297 process_attribute(this, ca);
298 }
299 attributes->destroy(attributes);
300 break;
301 }
302 default:
303 DBG1(DBG_IKE, "ignoring %N config payload",
304 config_type_names, cp->get_type(cp));
305 break;
306 }
307
308 switch(this->state)
309 {
310 case TASK_XAUTH_INIT:
311 if(((cp->get_type(cp) != CFG_REQUEST) && (cp->get_type(cp) != CFG_REPLY)) ||
312 (this->xauth_user_name_recv != TRUE) ||
313 (this->xauth_user_pass_recv != TRUE))
314 {
315 /* Didn't get an XAuth message, assume we're a ConfigMode message, set state appropriately */
316 this->state = TASK_XAUTH_COMPLETE;
317 this->next_state = TASK_XAUTH_COMPLETE;
318 this->status = SUCCESS;
319 break;
320 }
321 this->next_state = TASK_XAUTH_PASS_VERIFY;
322 break;
323 case TASK_XAUTH_PASS_VERIFY:
324 if(((cp->get_type(cp) != CFG_SET) && (cp->get_type(cp) != CFG_ACK)) ||
325 (this->xauth_status_recv != TRUE))
326 {
327 DBG1(DBG_IKE, "Didn't receive XAuth status.");
328 return FAILED;
329 }
330 /* Set the return status for the build call */
331 if(cp->get_type(cp) != CFG_ACK)
332 {
333 this->status = (this->xauth_status_data == XAUTH_STATUS_OK ? SUCCESS : FAILED);
334 }
335 else
336 {
337 this->status = SUCCESS;
338 }
339 this->next_state = TASK_XAUTH_COMPLETE;
340 break;
341 default:
342 this->next_state = TASK_XAUTH_COMPLETE;
343 this->status = SUCCESS;
344 break;
345 }
346 }
347 default:
348 break;
349 }
350 }
351 enumerator->destroy(enumerator);
352
353 if(this->xauth_authenticator)
354 {
355 this->xauth_authenticator->process(this->xauth_authenticator, message);
356 }
357 return NEED_MORE;
358 }
359
360 METHOD(task_t, build_i, status_t,
361 private_xauth_request_t *this, message_t *message)
362 {
363 cp_payload_t *cp = NULL;
364 chunk_t chunk = chunk_empty;
365 ike_version_t version;
366 payload_type_t cp_type;
367 payload_type_t ca_type;
368 host_t *vip;
369 peer_cfg_t *config;
370 enumerator_t *enumerator;
371 attribute_handler_t *handler;
372 configuration_attribute_type_t type;
373 chunk_t data;
374 status_t status;
375
376 version = this->ike_sa->get_version(this->ike_sa);
377 if(version == IKEV1)
378 {
379 if(!this->auth_cfg)
380 {
381 this->auth_cfg = get_auth_cfg(this, TRUE);
382 }
383 switch((uintptr_t)this->auth_cfg->get(this->auth_cfg, AUTH_RULE_AUTH_CLASS))
384 {
385 case AUTH_CLASS_XAUTH_PSK:
386 case AUTH_CLASS_XAUTH_PUBKEY:
387 break;
388 default:
389 /* We aren't XAuth, so do nothing */
390 return SUCCESS;
391 }
392 cp_type = CONFIGURATION_V1;
393 ca_type = CONFIGURATION_ATTRIBUTE_V1;
394 }
395 else /* IKEv2 */
396 {
397 /* IKEv2 does not support XAuth, skip those states. */
398 this->state = TASK_XAUTH_COMPLETE;
399 if (message->get_message_id(message) == 1)
400 { /* in first IKE_AUTH only */
401 return NEED_MORE;
402 }
403 cp_type = CONFIGURATION;
404 ca_type = CONFIGURATION_ATTRIBUTE;
405 }
406 switch(this->state)
407 {
408 case TASK_XAUTH_INIT:
409 cp = cp_payload_create_type(cp_type, CFG_REQUEST);
410 cp->add_attribute(cp, configuration_attribute_create_chunk(
411 ca_type, XAUTH_USER_NAME, chunk));
412 cp->add_attribute(cp, configuration_attribute_create_chunk(
413 ca_type, XAUTH_USER_PASSWORD, chunk));
414 break;
415 case TASK_XAUTH_PASS_VERIFY:
416 status = this->xauth_authenticator->build(this->xauth_authenticator, message);
417 cp = cp_payload_create_type(cp_type, CFG_SET);
418 cp->add_attribute(cp, configuration_attribute_create_value(
419 XAUTH_STATUS,
420 (status == FAILED ? XAUTH_STATUS_FAIL : XAUTH_STATUS_OK)));
421 break;
422 case TASK_XAUTH_COMPLETE:
423 /* ConfigMode stuff */
424 /* reuse virtual IP if we already have one */
425 vip = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
426 if (!vip)
427 {
428 config = this->ike_sa->get_peer_cfg(this->ike_sa);
429 vip = config->get_virtual_ip(config);
430 }
431 if (vip)
432 {
433 cp = cp_payload_create_type(cp_type, CFG_REQUEST);
434 cp->add_attribute(cp, build_vip(ca_type, vip));
435 }
436
437 enumerator = hydra->attributes->create_initiator_enumerator(hydra->attributes,
438 this->ike_sa->get_other_id(this->ike_sa), vip);
439 while (enumerator->enumerate(enumerator, &handler, &type, &data))
440 {
441 configuration_attribute_t *ca;
442 entry_t *entry;
443
444 /* create configuration attribute */
445 DBG2(DBG_IKE, "building %N attribute",
446 configuration_attribute_type_names, type);
447 ca = configuration_attribute_create_chunk(ca_type,
448 type, data);
449 if (!cp)
450 {
451 cp = cp_payload_create_type(cp_type, CFG_REQUEST);
452 }
453 cp->add_attribute(cp, ca);
454
455 /* save handler along with requested type */
456 entry = malloc_thing(entry_t);
457 entry->type = type;
458 entry->handler = handler;
459
460 this->requested->insert_last(this->requested, entry);
461 }
462 enumerator->destroy(enumerator);
463
464 break;
465 default:
466 return FAILED;
467
468 }
469 /* Add the payloads into the message */
470 if(cp)
471 {
472 message->add_payload(message, (payload_t *)cp);
473 }
474
475 return NEED_MORE;
476 }
477
478 METHOD(task_t, process_r, status_t,
479 private_xauth_request_t *this, message_t *message)
480 {
481 ike_version_t version;
482 payload_type_t cp_type;
483 status_t status;
484
485 version = this->ike_sa->get_version(this->ike_sa);
486 if(version == IKEV1)
487 {
488 if(!this->auth_cfg)
489 {
490 this->auth_cfg = get_auth_cfg(this, TRUE);
491 }
492
493 switch((uintptr_t)this->auth_cfg->get(this->auth_cfg, AUTH_RULE_AUTH_CLASS))
494 {
495 case AUTH_CLASS_XAUTH_PSK:
496 case AUTH_CLASS_XAUTH_PUBKEY:
497 if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
498 {
499 this->state = TASK_XAUTH_COMPLETE;
500 }
501 else
502 {
503 this->state = TASK_XAUTH_INIT;
504 }
505 break;
506 default:
507 /* We aren't XAuth, so do we should expect ConfigMode stuff */
508 this->state = TASK_XAUTH_COMPLETE;
509 }
510
511 if((this->xauth_authenticator == NULL) && (this->state == TASK_XAUTH_INIT))
512 {
513 this->xauth_authenticator = (authenticator_t *)xauth_authenticator_create_builder(this->ike_sa);
514 }
515 cp_type = CONFIGURATION_V1;
516 }
517 else /* IKEv2 */
518 {
519 /* IKEv2 does not support XAuth, skip those states. */
520 this->state = TASK_XAUTH_COMPLETE;
521 if (message->get_message_id(message) == 1)
522 { /* in first IKE_AUTH only */
523 return NEED_MORE;
524 }
525 cp_type = CONFIGURATION;
526 }
527
528 status = process_payloads(this, message);
529 if(this->xauth_authenticator != NULL)
530 {
531 status = this->xauth_authenticator->process(this->xauth_authenticator, message);
532 }
533 return status;
534 }
535
536 METHOD(task_t, build_r, status_t,
537 private_xauth_request_t *this, message_t *message)
538 {
539 status_t status;
540 cp_payload_t *cp = NULL;
541 payload_type_t cp_type = CONFIGURATION;
542 payload_type_t ca_type = CONFIGURATION_ATTRIBUTE;
543 ike_version_t version;
544 identification_t *id;
545 enumerator_t *enumerator;
546 configuration_attribute_type_t type;
547 chunk_t value;
548 host_t *vip = NULL;
549 peer_cfg_t *config;
550
551 version = this->ike_sa->get_version(this->ike_sa);
552 if ((version == IKEV2) && (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED))
553 {
554 return NEED_MORE;
555 }
556 if(version == IKEV1)
557 {
558 if(!this->auth_cfg)
559 {
560 this->auth_cfg = get_auth_cfg(this, TRUE);
561 }
562 switch((uintptr_t)this->auth_cfg->get(this->auth_cfg, AUTH_RULE_AUTH_CLASS))
563 {
564 case AUTH_CLASS_XAUTH_PSK:
565 case AUTH_CLASS_XAUTH_PUBKEY:
566 break;
567 default:
568
569 this->state = TASK_XAUTH_COMPLETE;
570 return SUCCESS;
571 }
572 cp_type = CONFIGURATION_V1;
573 ca_type = CONFIGURATION_ATTRIBUTE_V1;
574 }
575
576 switch(this->state)
577 {
578 case TASK_XAUTH_INIT:
579 status = this->xauth_authenticator->build(this->xauth_authenticator, message);
580 this->state = TASK_XAUTH_PASS_VERIFY;
581 break;
582 case TASK_XAUTH_PASS_VERIFY:
583 cp = cp_payload_create_type(cp_type, CFG_ACK);
584 cp->add_attribute(cp, configuration_attribute_create_value(
585 XAUTH_STATUS, XAUTH_STATUS_OK));
586 status = this->status;
587 this->state = TASK_XAUTH_COMPLETE;
588 break;
589 case TASK_XAUTH_COMPLETE:
590 id = this->ike_sa->get_other_eap_id(this->ike_sa);
591
592 config = this->ike_sa->get_peer_cfg(this->ike_sa);
593 if (this->virtual_ip)
594 {
595 DBG1(DBG_IKE, "peer requested virtual IP %H", this->virtual_ip);
596 if (config->get_pool(config))
597 {
598 vip = hydra->attributes->acquire_address(hydra->attributes,
599 config->get_pool(config), id, this->virtual_ip);
600 }
601 if (vip == NULL)
602 {
603 DBG1(DBG_IKE, "no virtual IP found, sending %N",
604 notify_type_names, INTERNAL_ADDRESS_FAILURE);
605 message->add_notify(message, FALSE, INTERNAL_ADDRESS_FAILURE,
606 chunk_empty);
607 return SUCCESS;
608 }
609 DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", vip, id);
610 this->ike_sa->set_virtual_ip(this->ike_sa, FALSE, vip);
611
612 cp = cp_payload_create_type(cp_type, CFG_REPLY);
613 cp->add_attribute(cp, build_vip(ca_type, vip));
614 }
615
616 /* query registered providers for additional attributes to include */
617 enumerator = hydra->attributes->create_responder_enumerator(
618 hydra->attributes, config->get_pool(config), id, vip);
619 while (enumerator->enumerate(enumerator, &type, &value))
620 {
621 if (!cp)
622 {
623 cp = cp_payload_create_type(cp_type, CFG_REPLY);
624 }
625 DBG2(DBG_IKE, "building %N attribute",
626 configuration_attribute_type_names, type);
627 cp->add_attribute(cp,
628 configuration_attribute_create_chunk(ca_type,
629 type, value));
630 }
631 enumerator->destroy(enumerator);
632 status = SUCCESS;
633 break;
634 default:
635 return FAILED;
636 }
637 if(cp != NULL)
638 {
639 message->add_payload(message, (payload_t *)cp);
640 }
641 if(status == SUCCESS)
642 {
643 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
644 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
645 }
646 return status;
647 }
648
649 METHOD(task_t, process_i, status_t,
650 private_xauth_request_t *this, message_t *message)
651 {
652 status_t status;
653
654 if (((this->ike_sa->get_version(this->ike_sa) == IKEV2) &&
655 (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)) ||
656 (this->ike_sa->get_version(this->ike_sa) == IKEV1))
657 { /* in last IKE_AUTH exchange */
658
659 if(this->xauth_authenticator == NULL)
660 {
661 this->xauth_authenticator = (authenticator_t *)xauth_authenticator_create_verifier(this->ike_sa);
662 }
663 status = process_payloads(this, message);
664 this->state = this->next_state;
665
666 if (this->virtual_ip)
667 {
668 this->ike_sa->set_virtual_ip(this->ike_sa, TRUE, this->virtual_ip);
669 }
670 if(this->state == TASK_XAUTH_COMPLETE)
671 {
672 if(this->status == SUCCESS)
673 {
674 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
675 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
676 }
677
678 return this->status;
679 }
680 return status;
681 }
682 return NEED_MORE;
683
684 }
685
686 METHOD(task_t, get_type, task_type_t,
687 private_xauth_request_t *this)
688 {
689 return TASK_XAUTH_REQUEST;
690 }
691
692 METHOD(task_t, migrate, void,
693 private_xauth_request_t *this, ike_sa_t *ike_sa)
694 {
695 DESTROY_IF(this->virtual_ip);
696
697 this->ike_sa = ike_sa;
698 this->virtual_ip = NULL;
699 this->requested->destroy_function(this->requested, free);
700 this->requested = linked_list_create();
701 }
702
703 METHOD(task_t, destroy, void,
704 private_xauth_request_t *this)
705 {
706 DESTROY_IF(this->virtual_ip);
707 this->requested->destroy_function(this->requested, free);
708 DESTROY_IF(this->xauth_authenticator);
709 free(this);
710 }
711
712 METHOD(task_t, swap_initiator, void,
713 private_xauth_request_t *this)
714 {
715 if(this->initiator)
716 {
717 this->public.task.build = _build_r;
718 this->public.task.process = _process_r;
719 this->initiator = FALSE;
720 }
721 else
722 {
723 this->public.task.build = _build_i;
724 this->public.task.process = _process_i;
725 this->initiator = TRUE;
726 }
727 }
728
729 /*
730 * Described in header.
731 */
732 xauth_request_t *xauth_request_create(ike_sa_t *ike_sa, bool initiator)
733 {
734 private_xauth_request_t *this;
735
736 INIT(this,
737 .public = {
738 .task = {
739 .get_type = _get_type,
740 .migrate = _migrate,
741 .destroy = _destroy,
742 .swap_initiator = _swap_initiator,
743 },
744 },
745 .initiator = initiator,
746 .ike_sa = ike_sa,
747 .requested = linked_list_create(),
748 .state = TASK_XAUTH_INIT,
749 .next_state = TASK_XAUTH_INIT,
750 .xauth_status_data = XAUTH_STATUS_FAIL,
751 .xauth_user_name = chunk_empty,
752 .xauth_user_pass = chunk_empty,
753 .xauth_user_name_recv = FALSE,
754 .xauth_user_pass_recv = FALSE,
755 .xauth_status_recv = FALSE,
756 );
757
758 if (initiator)
759 {
760 this->public.task.build = _build_i;
761 this->public.task.process = _process_i;
762 }
763 else
764 {
765 this->public.task.build = _build_r;
766 this->public.task.process = _process_r;
767 }
768
769 return &this->public;
770 }