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