Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/tasks/ike_auth.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012-2018 Tobias Brunner
3: * Copyright (C) 2005-2009 Martin Willi
4: * Copyright (C) 2005 Jan Hutter
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #include "ike_auth.h"
19:
20: #include <string.h>
21:
22: #include <daemon.h>
23: #include <encoding/payloads/id_payload.h>
24: #include <encoding/payloads/auth_payload.h>
25: #include <encoding/payloads/eap_payload.h>
26: #include <encoding/payloads/nonce_payload.h>
27: #include <sa/ikev2/keymat_v2.h>
28: #include <sa/ikev2/authenticators/eap_authenticator.h>
29: #include <processing/jobs/delete_ike_sa_job.h>
30:
31: typedef struct private_ike_auth_t private_ike_auth_t;
32:
33: /**
34: * Private members of a ike_auth_t task.
35: */
36: struct private_ike_auth_t {
37:
38: /**
39: * Public methods and task_t interface.
40: */
41: ike_auth_t public;
42:
43: /**
44: * Assigned IKE_SA.
45: */
46: ike_sa_t *ike_sa;
47:
48: /**
49: * Are we the initiator?
50: */
51: bool initiator;
52:
53: /**
54: * Nonce chosen by us in ike_init
55: */
56: chunk_t my_nonce;
57:
58: /**
59: * Nonce chosen by peer in ike_init
60: */
61: chunk_t other_nonce;
62:
63: /**
64: * PPK_ID sent or received
65: */
66: identification_t *ppk_id;
67:
68: /**
69: * Optional PPK to use
70: */
71: chunk_t ppk;
72:
73: /**
74: * IKE_SA_INIT message sent by us
75: */
76: packet_t *my_packet;
77:
78: /**
79: * IKE_SA_INIT message sent by peer
80: */
81: packet_t *other_packet;
82:
83: /**
84: * Reserved bytes of ID payload
85: */
86: char reserved[3];
87:
88: /**
89: * currently active authenticator, to authenticate us
90: */
91: authenticator_t *my_auth;
92:
93: /**
94: * currently active authenticator, to authenticate peer
95: */
96: authenticator_t *other_auth;
97:
98: /**
99: * peer_cfg candidates, ordered by priority
100: */
101: linked_list_t *candidates;
102:
103: /**
104: * selected peer config (might change when using multiple authentications)
105: */
106: peer_cfg_t *peer_cfg;
107:
108: /**
109: * have we planned an(other) authentication exchange?
110: */
111: bool do_another_auth;
112:
113: /**
114: * has the peer announced another authentication exchange?
115: */
116: bool expect_another_auth;
117:
118: /**
119: * should we send a AUTHENTICATION_FAILED notify?
120: */
121: bool authentication_failed;
122:
123: /**
124: * received an INITIAL_CONTACT?
125: */
126: bool initial_contact;
127:
128: /**
129: * Is EAP acceptable, did we strictly authenticate peer?
130: */
131: bool eap_acceptable;
132:
133: /**
134: * Gateway ID if redirected
135: */
136: identification_t *redirect_to;
137: };
138:
139: /**
140: * check if multiple authentication extension is enabled, configuration-wise
141: */
142: static bool multiple_auth_enabled()
143: {
144: return lib->settings->get_bool(lib->settings,
145: "%s.multiple_authentication", TRUE, lib->ns);
146: }
147:
148: /**
149: * collect the needed information in the IKE_SA_INIT exchange from our message
150: */
151: static status_t collect_my_init_data(private_ike_auth_t *this,
152: message_t *message)
153: {
154: nonce_payload_t *nonce;
155:
156: /* get the nonce that was generated in ike_init */
157: nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
158: if (!nonce)
159: {
160: return FAILED;
161: }
162: this->my_nonce = nonce->get_nonce(nonce);
163:
164: /* pre-generate the message, keep a copy */
165: if (this->ike_sa->generate_message(this->ike_sa, message,
166: &this->my_packet) != SUCCESS)
167: {
168: return FAILED;
169: }
170: return NEED_MORE;
171: }
172:
173: /**
174: * collect the needed information in the IKE_SA_INIT exchange from others message
175: */
176: static status_t collect_other_init_data(private_ike_auth_t *this,
177: message_t *message)
178: {
179: /* we collect the needed information in the IKE_SA_INIT exchange */
180: nonce_payload_t *nonce;
181:
182: /* get the nonce that was generated in ike_init */
183: nonce = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
184: if (!nonce)
185: {
186: return FAILED;
187: }
188: this->other_nonce = nonce->get_nonce(nonce);
189:
190: /* keep a copy of the received packet */
191: this->other_packet = message->get_packet(message);
192: return NEED_MORE;
193: }
194:
195: /**
196: * Get and store reserved bytes of id_payload, required for AUTH payload
197: */
198: static void get_reserved_id_bytes(private_ike_auth_t *this, id_payload_t *id)
199: {
200: uint8_t *byte;
201: int i;
202:
203: for (i = 0; i < countof(this->reserved); i++)
204: {
205: byte = payload_get_field(&id->payload_interface, RESERVED_BYTE, i);
206: if (byte)
207: {
208: this->reserved[i] = *byte;
209: }
210: }
211: }
212:
213: /**
214: * Get the next authentication configuration
215: */
216: static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
217: {
218: enumerator_t *e1, *e2;
219: auth_cfg_t *c1, *c2, *next = NULL;
220:
221: /* find an available config not already done */
222: e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, local);
223: while (e1->enumerate(e1, &c1))
224: {
225: bool found = FALSE;
226:
227: e2 = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, local);
228: while (e2->enumerate(e2, &c2))
229: {
230: if (c2->complies(c2, c1, FALSE))
231: {
232: found = TRUE;
233: break;
234: }
235: }
236: e2->destroy(e2);
237: if (!found)
238: {
239: next = c1;
240: break;
241: }
242: }
243: e1->destroy(e1);
244: return next;
245: }
246:
247: /**
248: * Move the currently active auth config to the auth configs completed
249: */
250: static void apply_auth_cfg(private_ike_auth_t *this, bool local)
251: {
252: auth_cfg_t *cfg;
253:
254: cfg = auth_cfg_create();
255: cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
256: this->ike_sa->add_auth_cfg(this->ike_sa, local, cfg);
257: }
258:
259: /**
260: * Check if we have should initiate another authentication round
261: */
262: static bool do_another_auth(private_ike_auth_t *this)
263: {
264: bool do_another = FALSE;
265: enumerator_t *done, *todo;
266: auth_cfg_t *done_cfg, *todo_cfg;
267:
268: if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
269: {
270: return FALSE;
271: }
272:
273: done = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, TRUE);
274: todo = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, TRUE);
275: while (todo->enumerate(todo, &todo_cfg))
276: {
277: if (!done->enumerate(done, &done_cfg))
278: {
279: done_cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
280: }
281: if (!done_cfg->complies(done_cfg, todo_cfg, FALSE))
282: {
283: do_another = TRUE;
284: break;
285: }
286: }
287: done->destroy(done);
288: todo->destroy(todo);
289: return do_another;
290: }
291:
292: /**
293: * Check if this is the first authentication round
294: */
295: static bool is_first_round(private_ike_auth_t *this, bool local)
296: {
297: enumerator_t *done;
298: auth_cfg_t *cfg;
299:
300: if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
301: {
302: return TRUE;
303: }
304:
305: done = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, local);
306: if (done->enumerate(done, &cfg))
307: {
308: done->destroy(done);
309: return FALSE;
310: }
311: done->destroy(done);
312: return TRUE;
313: }
314:
315: /**
316: * Get peer configuration candidates from backends
317: */
318: static bool load_cfg_candidates(private_ike_auth_t *this)
319: {
320: enumerator_t *enumerator;
321: peer_cfg_t *peer_cfg;
322: ike_cfg_t *ike_cfg;
323: host_t *me, *other;
324: identification_t *my_id, *other_id;
325: proposal_t *ike_proposal;
326: bool private;
327:
328: me = this->ike_sa->get_my_host(this->ike_sa);
329: other = this->ike_sa->get_other_host(this->ike_sa);
330: my_id = this->ike_sa->get_my_id(this->ike_sa);
331: other_id = this->ike_sa->get_other_id(this->ike_sa);
332: ike_proposal = this->ike_sa->get_proposal(this->ike_sa);
333: private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) ||
334: lib->settings->get_bool(lib->settings, "%s.accept_private_algs",
335: FALSE, lib->ns);
336:
337: DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
338: me, my_id, other, other_id);
339: enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
340: me, other, my_id, other_id, IKEV2);
341: while (enumerator->enumerate(enumerator, &peer_cfg))
342: {
343: /* ignore all configs that have no matching IKE proposal */
344: ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
345: if (!ike_cfg->has_proposal(ike_cfg, ike_proposal, private))
346: {
347: DBG2(DBG_CFG, "ignore candidate '%s' without matching IKE proposal",
348: peer_cfg->get_name(peer_cfg));
349: continue;
350: }
351: peer_cfg->get_ref(peer_cfg);
352: if (!this->peer_cfg)
353: { /* best match */
354: this->peer_cfg = peer_cfg;
355: }
356: else
357: {
358: this->candidates->insert_last(this->candidates, peer_cfg);
359: }
360: }
361: enumerator->destroy(enumerator);
362: if (this->peer_cfg)
363: {
364: this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
365: DBG1(DBG_CFG, "selected peer config '%s'",
366: this->peer_cfg->get_name(this->peer_cfg));
367: return TRUE;
368: }
369: DBG1(DBG_CFG, "no matching peer config found");
370: return FALSE;
371: }
372:
373: /**
374: * update the current peer candidate if necessary, using candidates
375: */
376: static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
377: {
378: do
379: {
380: if (this->peer_cfg)
381: {
382: char *comply_error = NULL;
383: enumerator_t *e1, *e2, *tmp;
384: auth_cfg_t *c1, *c2;
385:
386: e1 = this->ike_sa->create_auth_cfg_enumerator(this->ike_sa, FALSE);
387: e2 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
388:
389: if (strict)
390: { /* swap lists in strict mode: all configured rounds must be
391: * fulfilled. If !strict, we check only the rounds done so far. */
392: tmp = e1;
393: e1 = e2;
394: e2 = tmp;
395: }
396: while (e1->enumerate(e1, &c1))
397: {
398: /* check if done authentications comply to configured ones */
399: if (!e2->enumerate(e2, &c2))
400: {
401: comply_error = "insufficient authentication rounds";
402: break;
403: }
404: if (!strict && !c1->complies(c1, c2, TRUE))
405: {
406: comply_error = "non-matching authentication done";
407: break;
408: }
409: if (strict && !c2->complies(c2, c1, TRUE))
410: {
411: comply_error = "constraint checking failed";
412: break;
413: }
414: }
415: e1->destroy(e1);
416: e2->destroy(e2);
417: if (!comply_error)
418: {
419: break;
420: }
421: DBG1(DBG_CFG, "selected peer config '%s' unacceptable: %s",
422: this->peer_cfg->get_name(this->peer_cfg), comply_error);
423: this->peer_cfg->destroy(this->peer_cfg);
424: }
425: if (this->candidates->remove_first(this->candidates,
426: (void**)&this->peer_cfg) != SUCCESS)
427: {
428: DBG1(DBG_CFG, "no alternative config found");
429: this->peer_cfg = NULL;
430: }
431: else
432: {
433: DBG1(DBG_CFG, "switching to peer config '%s'",
434: this->peer_cfg->get_name(this->peer_cfg));
435: this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
436: }
437: }
438: while (this->peer_cfg);
439:
440: return this->peer_cfg != NULL;
441: }
442:
443: /**
444: * Currently defined PPK_ID types
445: */
446: #define PPK_ID_OPAQUE 1
447: #define PPK_ID_FIXED 2
448:
449: /**
450: * Parse the payload data of the given PPK_IDENTITY notify
451: */
452: static bool parse_ppk_identity(notify_payload_t *notify, identification_t **id)
453: {
454: chunk_t data;
455:
456: data = notify->get_notification_data(notify);
457: if (data.len < 2)
458: {
459: return FALSE;
460: }
461: switch (data.ptr[0])
462: {
463: case PPK_ID_FIXED:
464: data = chunk_skip(data, 1);
465: break;
466: default:
467: return FALSE;
468: }
469: *id = identification_create_from_data(data);
470: return TRUE;
471: }
472:
473: /**
474: * Add a PPK_IDENTITY with the given PPK_ID to the given message
475: */
476: static void add_ppk_identity(identification_t *id, message_t *msg)
477: {
478: chunk_t data;
479: uint8_t type = PPK_ID_FIXED;
480:
481: /* we currently only support one type */
482: data = chunk_cata("cc", chunk_from_thing(type), id->get_encoding(id));
483: msg->add_notify(msg, FALSE, PPK_IDENTITY, data);
484: }
485:
486: /**
487: * Use the given PPK_ID to find a PPK and store it and the ID in the task
488: */
489: static bool get_ppk(private_ike_auth_t *this, identification_t *ppk_id)
490: {
491: shared_key_t *key;
492:
493: key = lib->credmgr->get_shared(lib->credmgr, SHARED_PPK, ppk_id, NULL);
494: if (!key)
495: {
496: if (this->peer_cfg->ppk_required(this->peer_cfg))
497: {
498: DBG1(DBG_CFG, "PPK required but no PPK found for '%Y'", ppk_id);
499: return FALSE;
500: }
501: DBG1(DBG_CFG, "no PPK for '%Y' found, ignored because PPK is not "
502: "required", ppk_id);
503: return TRUE;
504: }
505: this->ppk = chunk_clone(key->get_key(key));
506: this->ppk_id = ppk_id->clone(ppk_id);
507: key->destroy(key);
508: return TRUE;
509: }
510:
511: /**
512: * Check if we have a PPK available and, if not, whether we require one as
513: * initiator
514: */
515: static bool get_ppk_i(private_ike_auth_t *this)
516: {
517: identification_t *ppk_id;
518:
519: if (!this->ike_sa->supports_extension(this->ike_sa, EXT_PPK))
520: {
521: if (this->peer_cfg->ppk_required(this->peer_cfg))
522: {
523: DBG1(DBG_CFG, "PPK required but peer does not support PPK");
524: return FALSE;
525: }
526: return TRUE;
527: }
528:
529: ppk_id = this->peer_cfg->get_ppk_id(this->peer_cfg);
530: if (!ppk_id)
531: {
532: if (this->peer_cfg->ppk_required(this->peer_cfg))
533: {
534: DBG1(DBG_CFG, "PPK required but no PPK_ID configured");
535: return FALSE;
536: }
537: return TRUE;
538: }
539: return get_ppk(this, ppk_id);
540: }
541:
542: /**
543: * Check if we have a PPK available and if not whether we require one as
544: * responder
545: */
546: static bool get_ppk_r(private_ike_auth_t *this, message_t *msg)
547: {
548: notify_payload_t *notify;
549: identification_t *ppk_id, *ppk_id_cfg;
550: bool result;
551:
552: if (!this->ike_sa->supports_extension(this->ike_sa, EXT_PPK))
553: {
554: if (this->peer_cfg->ppk_required(this->peer_cfg))
555: {
556: DBG1(DBG_CFG, "PPK required but peer does not support PPK");
557: return FALSE;
558: }
559: return TRUE;
560: }
561:
562: notify = msg->get_notify(msg, PPK_IDENTITY);
563: if (!notify || !parse_ppk_identity(notify, &ppk_id))
564: {
565: if (this->peer_cfg->ppk_required(this->peer_cfg))
566: {
567: DBG1(DBG_CFG, "PPK required but no PPK_IDENTITY received");
568: return FALSE;
569: }
570: return TRUE;
571: }
572:
573: ppk_id_cfg = this->peer_cfg->get_ppk_id(this->peer_cfg);
574: if (ppk_id_cfg && !ppk_id->matches(ppk_id, ppk_id_cfg))
575: {
576: DBG1(DBG_CFG, "received PPK_ID '%Y', but require '%Y'", ppk_id,
577: ppk_id_cfg);
578: ppk_id->destroy(ppk_id);
579: return FALSE;
580: }
581: result = get_ppk(this, ppk_id);
582: ppk_id->destroy(ppk_id);
583: return result;
584: }
585:
586: METHOD(task_t, build_i, status_t,
587: private_ike_auth_t *this, message_t *message)
588: {
589: auth_cfg_t *cfg;
590:
591: if (message->get_exchange_type(message) == IKE_SA_INIT)
592: {
593: return collect_my_init_data(this, message);
594: }
595:
596: if (!this->peer_cfg)
597: {
598: this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
599: this->peer_cfg->get_ref(this->peer_cfg);
600: }
601:
602: if (message->get_message_id(message) == 1)
603: { /* in the first IKE_AUTH ... */
604: if (this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
605: { /* indicate support for multiple authentication */
606: message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
607: chunk_empty);
608: }
609: /* indicate support for EAP-only authentication */
610: message->add_notify(message, FALSE, EAP_ONLY_AUTHENTICATION,
611: chunk_empty);
612: /* indicate support for RFC 6311 Message ID synchronization */
613: message->add_notify(message, FALSE, IKEV2_MESSAGE_ID_SYNC_SUPPORTED,
614: chunk_empty);
615: /* only use a PPK in the first round */
616: if (!get_ppk_i(this))
617: {
618: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
619: return FAILED;
620: }
621: }
622:
623: if (!this->do_another_auth && !this->my_auth)
624: { /* we have done our rounds */
625: return NEED_MORE;
626: }
627:
628: /* check if an authenticator is in progress */
629: if (!this->my_auth)
630: {
631: identification_t *idi, *idr = NULL;
632: id_payload_t *id_payload;
633:
634: /* clean up authentication config from a previous round */
635: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
636: cfg->purge(cfg, TRUE);
637:
638: /* add (optional) IDr */
639: cfg = get_auth_cfg(this, FALSE);
640: if (cfg)
641: {
642: idr = cfg->get(cfg, AUTH_RULE_IDENTITY);
643: if (!cfg->get(cfg, AUTH_RULE_IDENTITY_LOOSE) && idr &&
644: !idr->contains_wildcards(idr))
645: {
646: this->ike_sa->set_other_id(this->ike_sa, idr->clone(idr));
647: id_payload = id_payload_create_from_identification(
648: PLV2_ID_RESPONDER, idr);
649: message->add_payload(message, (payload_t*)id_payload);
650: }
651: }
652: /* add IDi */
653: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
654: cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
655: idi = cfg->get(cfg, AUTH_RULE_IDENTITY);
656: if (!idi || idi->get_type(idi) == ID_ANY)
657: { /* ID_ANY is invalid as IDi, use local IP address instead */
658: host_t *me;
659:
660: DBG1(DBG_CFG, "no IDi configured, fall back on IP address");
661: me = this->ike_sa->get_my_host(this->ike_sa);
662: idi = identification_create_from_sockaddr(me->get_sockaddr(me));
663: cfg->add(cfg, AUTH_RULE_IDENTITY, idi);
664: }
665: this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi));
666: id_payload = id_payload_create_from_identification(PLV2_ID_INITIATOR, idi);
667: get_reserved_id_bytes(this, id_payload);
668: message->add_payload(message, (payload_t*)id_payload);
669:
670: if (idr && !idr->contains_wildcards(idr) &&
671: message->get_message_id(message) == 1 &&
672: this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER)
673: {
674: host_t *host;
675:
676: host = this->ike_sa->get_other_host(this->ike_sa);
677: if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager,
678: idi, idr, host->get_family(host)))
679: {
680: message->add_notify(message, FALSE, INITIAL_CONTACT, chunk_empty);
681: }
682: }
683:
684: /* build authentication data */
685: this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
686: this->other_nonce, this->my_nonce,
687: this->other_packet->get_data(this->other_packet),
688: this->my_packet->get_data(this->my_packet),
689: this->reserved);
690: if (!this->my_auth)
691: {
692: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
693: return FAILED;
694: }
695: }
696: /* for authentication methods that return NEED_MORE, the PPK will be reset
697: * in process_i() for messages without PPK_ID notify, so we always set it
698: * during the first round (afterwards the PPK won't be available) */
699: if (this->ppk.ptr && this->my_auth->use_ppk)
700: {
701: this->my_auth->use_ppk(this->my_auth, this->ppk,
702: !this->peer_cfg->ppk_required(this->peer_cfg));
703: }
704: switch (this->my_auth->build(this->my_auth, message))
705: {
706: case SUCCESS:
707: apply_auth_cfg(this, TRUE);
708: this->my_auth->destroy(this->my_auth);
709: this->my_auth = NULL;
710: break;
711: case NEED_MORE:
712: break;
713: default:
714: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
715: return FAILED;
716: }
717:
718: /* add a PPK_IDENTITY notify to the message that contains AUTH */
719: if (this->ppk_id && message->get_payload(message, PLV2_AUTH))
720: {
721: add_ppk_identity(this->ppk_id, message);
722: }
723:
724: /* check for additional authentication rounds */
725: if (do_another_auth(this))
726: {
727: if (message->get_payload(message, PLV2_AUTH))
728: {
729: message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
730: }
731: }
732: else
733: {
734: this->do_another_auth = FALSE;
735: }
736: return NEED_MORE;
737: }
738:
739: METHOD(task_t, process_r, status_t,
740: private_ike_auth_t *this, message_t *message)
741: {
742: auth_cfg_t *cfg, *cand;
743: id_payload_t *id_payload;
744: identification_t *id;
745:
746: if (message->get_exchange_type(message) == IKE_SA_INIT)
747: {
748: return collect_other_init_data(this, message);
749: }
750:
751: if (!this->my_auth && this->do_another_auth)
752: {
753: /* handle (optional) IDr payload, apply proposed identity */
754: id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_RESPONDER);
755: if (id_payload)
756: {
757: id = id_payload->get_identification(id_payload);
758: }
759: else
760: {
761: id = identification_create_from_encoding(ID_ANY, chunk_empty);
762: }
763: this->ike_sa->set_my_id(this->ike_sa, id);
764: }
765:
766: if (!this->expect_another_auth)
767: {
768: return NEED_MORE;
769: }
770:
771: if (message->get_message_id(message) == 1)
772: { /* check for extensions in the first IKE_AUTH */
773: if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED))
774: {
775: this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
776: }
777: if (message->get_notify(message, EAP_ONLY_AUTHENTICATION))
778: {
779: this->ike_sa->enable_extension(this->ike_sa,
780: EXT_EAP_ONLY_AUTHENTICATION);
781: }
782: if (message->get_notify(message, INITIAL_CONTACT))
783: {
784: this->initial_contact = TRUE;
785: }
786: }
787:
788: if (!this->other_auth)
789: {
790: /* handle IDi payload */
791: id_payload = (id_payload_t*)message->get_payload(message, PLV2_ID_INITIATOR);
792: if (!id_payload)
793: {
794: DBG1(DBG_IKE, "IDi payload missing");
795: return FAILED;
796: }
797: id = id_payload->get_identification(id_payload);
798: get_reserved_id_bytes(this, id_payload);
799: this->ike_sa->set_other_id(this->ike_sa, id);
800: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
801: cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
802:
803: if (!this->peer_cfg)
804: {
805: if (!load_cfg_candidates(this))
806: {
807: this->authentication_failed = TRUE;
808: return NEED_MORE;
809: }
810: }
811: if (!message->get_payload(message, PLV2_AUTH))
812: { /* before authenticating with EAP, we need a EAP config */
813: cand = get_auth_cfg(this, FALSE);
814: while (!cand || (
815: (uintptr_t)cand->get(cand, AUTH_RULE_EAP_TYPE) == EAP_NAK &&
816: (uintptr_t)cand->get(cand, AUTH_RULE_EAP_VENDOR) == 0))
817: { /* peer requested EAP, but current config does not match */
818: DBG1(DBG_IKE, "peer requested EAP, config unacceptable");
819: this->peer_cfg->destroy(this->peer_cfg);
820: this->peer_cfg = NULL;
821: if (!update_cfg_candidates(this, FALSE))
822: {
823: this->authentication_failed = TRUE;
824: return NEED_MORE;
825: }
826: cand = get_auth_cfg(this, FALSE);
827: }
828: /* copy over the EAP specific rules for authentication */
829: cfg->add(cfg, AUTH_RULE_EAP_TYPE,
830: cand->get(cand, AUTH_RULE_EAP_TYPE));
831: cfg->add(cfg, AUTH_RULE_EAP_VENDOR,
832: cand->get(cand, AUTH_RULE_EAP_VENDOR));
833: id = (identification_t*)cand->get(cand, AUTH_RULE_EAP_IDENTITY);
834: if (id)
835: {
836: cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
837: }
838: id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY);
839: if (id)
840: {
841: cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id));
842: }
843: }
844:
845: /* verify authentication data */
846: this->other_auth = authenticator_create_verifier(this->ike_sa,
847: message, this->other_nonce, this->my_nonce,
848: this->other_packet->get_data(this->other_packet),
849: this->my_packet->get_data(this->my_packet),
850: this->reserved);
851: if (!this->other_auth)
852: {
853: this->authentication_failed = TRUE;
854: return NEED_MORE;
855: }
856: }
857: if (message->get_payload(message, PLV2_AUTH) &&
858: is_first_round(this, FALSE))
859: {
860: if (!get_ppk_r(this, message))
861: {
862: this->authentication_failed = TRUE;
863: return NEED_MORE;
864: }
865: else if (this->ppk.ptr && this->other_auth->use_ppk)
866: {
867: this->other_auth->use_ppk(this->other_auth, this->ppk, FALSE);
868: }
869: }
870: switch (this->other_auth->process(this->other_auth, message))
871: {
872: case SUCCESS:
873: this->other_auth->destroy(this->other_auth);
874: this->other_auth = NULL;
875: break;
876: case NEED_MORE:
877: if (message->get_payload(message, PLV2_AUTH))
878: { /* AUTH verification successful, but another build() needed */
879: break;
880: }
881: return NEED_MORE;
882: default:
883: this->authentication_failed = TRUE;
884: return NEED_MORE;
885: }
886:
887: /* another auth round done, invoke authorize hook */
888: if (!charon->bus->authorize(charon->bus, FALSE))
889: {
890: DBG1(DBG_IKE, "authorization hook forbids IKE_SA, cancelling");
891: this->authentication_failed = TRUE;
892: return NEED_MORE;
893: }
894:
895: apply_auth_cfg(this, FALSE);
896:
897: if (!update_cfg_candidates(this, FALSE))
898: {
899: this->authentication_failed = TRUE;
900: return NEED_MORE;
901: }
902:
903: if (!message->get_notify(message, ANOTHER_AUTH_FOLLOWS))
904: {
905: this->expect_another_auth = FALSE;
906: if (!update_cfg_candidates(this, TRUE))
907: {
908: this->authentication_failed = TRUE;
909: return NEED_MORE;
910: }
911: }
912: return NEED_MORE;
913: }
914:
915: /**
916: * Clear the PPK and PPK_ID
917: */
918: static void clear_ppk(private_ike_auth_t *this)
919: {
920: DESTROY_IF(this->ppk_id);
921: this->ppk_id = NULL;
922: chunk_clear(&this->ppk);
923: }
924:
925: /**
926: * Derive new keys and clear the PPK
927: */
928: static bool apply_ppk(private_ike_auth_t *this)
929: {
930: keymat_v2_t *keymat;
931:
932: if (this->ppk.ptr)
933: {
934: keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
935: if (!keymat->derive_ike_keys_ppk(keymat, this->ppk))
936: {
937: return FALSE;
938: }
939: DBG1(DBG_CFG, "using PPK for PPK_ID '%Y'", this->ppk_id);
940: this->ike_sa->set_condition(this->ike_sa, COND_PPK, TRUE);
941: }
942: clear_ppk(this);
943: return TRUE;
944: }
945:
946: METHOD(task_t, build_r, status_t,
947: private_ike_auth_t *this, message_t *message)
948: {
949: identification_t *gateway;
950: auth_cfg_t *cfg;
951:
952: if (message->get_exchange_type(message) == IKE_SA_INIT)
953: {
954: if (multiple_auth_enabled())
955: {
956: message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
957: chunk_empty);
958: }
959: return collect_my_init_data(this, message);
960: }
961:
962: if (this->authentication_failed || !this->peer_cfg)
963: {
964: goto peer_auth_failed;
965: }
966:
967: if (!this->my_auth && this->do_another_auth)
968: {
969: identification_t *id, *id_cfg;
970: id_payload_t *id_payload;
971:
972: /* add IDr */
973: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
974: cfg->purge(cfg, TRUE);
975: cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
976:
977: id_cfg = cfg->get(cfg, AUTH_RULE_IDENTITY);
978: id = this->ike_sa->get_my_id(this->ike_sa);
979: if (id->get_type(id) == ID_ANY)
980: { /* no IDr received, apply configured ID */
981: if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
982: { /* no ID configured, use local IP address */
983: host_t *me;
984:
985: DBG1(DBG_CFG, "no IDr configured, fall back on IP address");
986: me = this->ike_sa->get_my_host(this->ike_sa);
987: id_cfg = identification_create_from_sockaddr(
988: me->get_sockaddr(me));
989: cfg->add(cfg, AUTH_RULE_IDENTITY, id_cfg);
990: }
991: this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
992: id = id_cfg;
993: }
994: else
995: { /* IDr received, check if it matches configuration */
996: if (id_cfg && !id->matches(id, id_cfg))
997: {
998: DBG1(DBG_CFG, "received IDr %Y, but require %Y", id, id_cfg);
999: goto peer_auth_failed;
1000: }
1001: }
1002:
1003: id_payload = id_payload_create_from_identification(PLV2_ID_RESPONDER, id);
1004: get_reserved_id_bytes(this, id_payload);
1005: message->add_payload(message, (payload_t*)id_payload);
1006:
1007: if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
1008: { /* EAP-only authentication */
1009: if (!this->ike_sa->supports_extension(this->ike_sa,
1010: EXT_EAP_ONLY_AUTHENTICATION))
1011: {
1012: DBG1(DBG_IKE, "configured EAP-only authentication, but peer "
1013: "does not support it");
1014: goto peer_auth_failed;
1015: }
1016: }
1017: else
1018: {
1019: /* build authentication data */
1020: this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
1021: this->other_nonce, this->my_nonce,
1022: this->other_packet->get_data(this->other_packet),
1023: this->my_packet->get_data(this->my_packet),
1024: this->reserved);
1025: if (!this->my_auth)
1026: {
1027: goto local_auth_failed;
1028: }
1029: }
1030: }
1031:
1032: if (this->other_auth)
1033: {
1034: switch (this->other_auth->build(this->other_auth, message))
1035: {
1036: case SUCCESS:
1037: this->other_auth->destroy(this->other_auth);
1038: this->other_auth = NULL;
1039: break;
1040: case NEED_MORE:
1041: break;
1042: default:
1043: if (message->get_payload(message, PLV2_EAP))
1044: { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
1045: goto peer_auth_failed_no_notify;
1046: }
1047: goto peer_auth_failed;
1048: }
1049: }
1050: if (this->my_auth)
1051: {
1052: if (this->ppk.ptr && this->my_auth->use_ppk)
1053: {
1054: this->my_auth->use_ppk(this->my_auth, this->ppk, FALSE);
1055: }
1056: switch (this->my_auth->build(this->my_auth, message))
1057: {
1058: case SUCCESS:
1059: apply_auth_cfg(this, TRUE);
1060: this->my_auth->destroy(this->my_auth);
1061: this->my_auth = NULL;
1062: break;
1063: case NEED_MORE:
1064: break;
1065: default:
1066: goto local_auth_failed;
1067: }
1068: }
1069:
1070: /* add a PPK_IDENTITY notify and derive new keys and clear the PPK */
1071: if (this->ppk.ptr)
1072: {
1073: message->add_notify(message, FALSE, PPK_IDENTITY, chunk_empty);
1074: if (!apply_ppk(this))
1075: {
1076: goto local_auth_failed;
1077: }
1078: }
1079:
1080: /* check for additional authentication rounds */
1081: if (do_another_auth(this))
1082: {
1083: message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
1084: }
1085: else
1086: {
1087: this->do_another_auth = FALSE;
1088: }
1089: if (this->do_another_auth || this->expect_another_auth)
1090: {
1091: return NEED_MORE;
1092: }
1093:
1094: if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
1095: this->ike_sa, this->initial_contact))
1096: {
1097: DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
1098: charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
1099: message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
1100: chunk_empty);
1101: return FAILED;
1102: }
1103: if (!charon->bus->authorize(charon->bus, TRUE))
1104: {
1105: DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
1106: goto peer_auth_failed;
1107: }
1108: if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
1109: charon->redirect->redirect_on_auth(charon->redirect, this->ike_sa,
1110: &gateway))
1111: {
1112: delete_ike_sa_job_t *job;
1113: chunk_t data;
1114:
1115: DBG1(DBG_IKE, "redirecting peer to %Y", gateway);
1116: data = redirect_data_create(gateway, chunk_empty);
1117: message->add_notify(message, FALSE, REDIRECT, data);
1118: gateway->destroy(gateway);
1119: chunk_free(&data);
1120: /* we use this condition to prevent the CHILD_SA from getting created */
1121: this->ike_sa->set_condition(this->ike_sa, COND_REDIRECTED, TRUE);
1122: /* if the peer does not delete the SA we do so after a while */
1123: job = delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE);
1124: lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
1125: lib->settings->get_int(lib->settings,
1126: "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
1127: lib->ns));
1128: }
1129: DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1130: this->ike_sa->get_name(this->ike_sa),
1131: this->ike_sa->get_unique_id(this->ike_sa),
1132: this->ike_sa->get_my_host(this->ike_sa),
1133: this->ike_sa->get_my_id(this->ike_sa),
1134: this->ike_sa->get_other_host(this->ike_sa),
1135: this->ike_sa->get_other_id(this->ike_sa));
1136: this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1137: charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1138: return SUCCESS;
1139:
1140: peer_auth_failed:
1141: message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
1142: peer_auth_failed_no_notify:
1143: charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1144: return FAILED;
1145: local_auth_failed:
1146: message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
1147: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1148: return FAILED;
1149: }
1150:
1151: /**
1152: * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
1153: */
1154: static void send_auth_failed_informational(private_ike_auth_t *this,
1155: message_t *reply)
1156: {
1157: message_t *message;
1158: packet_t *packet;
1159: host_t *host;
1160:
1161: message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
1162: message->set_message_id(message, reply->get_message_id(reply) + 1);
1163: host = this->ike_sa->get_my_host(this->ike_sa);
1164: message->set_source(message, host->clone(host));
1165: host = this->ike_sa->get_other_host(this->ike_sa);
1166: message->set_destination(message, host->clone(host));
1167: message->set_exchange_type(message, INFORMATIONAL);
1168: message->add_notify(message, FALSE, AUTHENTICATION_FAILED, chunk_empty);
1169:
1170: if (this->ike_sa->generate_message(this->ike_sa, message,
1171: &packet) == SUCCESS)
1172: {
1173: charon->sender->send(charon->sender, packet);
1174: }
1175: message->destroy(message);
1176: }
1177:
1178: /**
1179: * Check if strict constraint fulfillment required to continue current auth
1180: */
1181: static bool require_strict(private_ike_auth_t *this, bool mutual_eap)
1182: {
1183: auth_cfg_t *cfg;
1184:
1185: if (this->eap_acceptable)
1186: {
1187: return FALSE;
1188: }
1189:
1190: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
1191: switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
1192: {
1193: case AUTH_CLASS_EAP:
1194: if (mutual_eap && this->my_auth)
1195: {
1196: this->eap_acceptable = TRUE;
1197: return !this->my_auth->is_mutual(this->my_auth);
1198: }
1199: return TRUE;
1200: case AUTH_CLASS_PSK:
1201: return TRUE;
1202: case AUTH_CLASS_PUBKEY:
1203: case AUTH_CLASS_ANY:
1204: default:
1205: return FALSE;
1206: }
1207: }
1208:
1209: METHOD(task_t, process_i, status_t,
1210: private_ike_auth_t *this, message_t *message)
1211: {
1212: enumerator_t *enumerator;
1213: payload_t *payload;
1214: auth_cfg_t *cfg;
1215: bool mutual_eap = FALSE, ppk_id_received = FALSE;
1216:
1217: if (message->get_exchange_type(message) == IKE_SA_INIT)
1218: {
1219: if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
1220: multiple_auth_enabled())
1221: {
1222: this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
1223: }
1224: return collect_other_init_data(this, message);
1225: }
1226:
1227: enumerator = message->create_payload_enumerator(message);
1228: while (enumerator->enumerate(enumerator, &payload))
1229: {
1230: if (payload->get_type(payload) == PLV2_NOTIFY)
1231: {
1232: notify_payload_t *notify = (notify_payload_t*)payload;
1233: notify_type_t type = notify->get_notify_type(notify);
1234:
1235: switch (type)
1236: {
1237: case NO_PROPOSAL_CHOSEN:
1238: case SINGLE_PAIR_REQUIRED:
1239: case NO_ADDITIONAL_SAS:
1240: case INTERNAL_ADDRESS_FAILURE:
1241: case FAILED_CP_REQUIRED:
1242: case TS_UNACCEPTABLE:
1243: case INVALID_SELECTORS:
1244: /* these are errors, but are not critical as only the
1245: * CHILD_SA won't get build, but IKE_SA establishes anyway */
1246: break;
1247: case MOBIKE_SUPPORTED:
1248: case ADDITIONAL_IP4_ADDRESS:
1249: case ADDITIONAL_IP6_ADDRESS:
1250: /* handled in ike_mobike task */
1251: break;
1252: case AUTH_LIFETIME:
1253: /* handled in ike_auth_lifetime task */
1254: break;
1255: case ME_ENDPOINT:
1256: /* handled in ike_me task */
1257: break;
1258: case REDIRECT:
1259: DESTROY_IF(this->redirect_to);
1260: this->redirect_to = redirect_data_parse(
1261: notify->get_notification_data(notify), NULL);
1262: if (!this->redirect_to)
1263: {
1264: DBG1(DBG_IKE, "received invalid REDIRECT notify");
1265: }
1266: break;
1267: case IKEV2_MESSAGE_ID_SYNC_SUPPORTED:
1268: this->ike_sa->enable_extension(this->ike_sa,
1269: EXT_IKE_MESSAGE_ID_SYNC);
1270: break;
1271: case PPK_IDENTITY:
1272: ppk_id_received = TRUE;
1273: break;
1274: default:
1275: {
1276: if (type <= 16383)
1277: {
1278: DBG1(DBG_IKE, "received %N notify error",
1279: notify_type_names, type);
1280: enumerator->destroy(enumerator);
1281: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1282: return FAILED;
1283: }
1284: DBG2(DBG_IKE, "received %N notify",
1285: notify_type_names, type);
1286: break;
1287: }
1288: }
1289: }
1290: }
1291: enumerator->destroy(enumerator);
1292:
1293: if (this->expect_another_auth)
1294: {
1295: if (!this->other_auth)
1296: {
1297: id_payload_t *id_payload;
1298: identification_t *id;
1299:
1300: /* handle IDr payload */
1301: id_payload = (id_payload_t*)message->get_payload(message,
1302: PLV2_ID_RESPONDER);
1303: if (!id_payload)
1304: {
1305: DBG1(DBG_IKE, "IDr payload missing");
1306: goto peer_auth_failed;
1307: }
1308: id = id_payload->get_identification(id_payload);
1309: get_reserved_id_bytes(this, id_payload);
1310: this->ike_sa->set_other_id(this->ike_sa, id);
1311: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
1312: cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
1313:
1314: if (message->get_payload(message, PLV2_AUTH))
1315: {
1316: /* verify authentication data */
1317: this->other_auth = authenticator_create_verifier(this->ike_sa,
1318: message, this->other_nonce, this->my_nonce,
1319: this->other_packet->get_data(this->other_packet),
1320: this->my_packet->get_data(this->my_packet),
1321: this->reserved);
1322: if (!this->other_auth)
1323: {
1324: goto peer_auth_failed;
1325: }
1326: }
1327: else
1328: {
1329: /* responder omitted AUTH payload, indicating EAP-only */
1330: mutual_eap = TRUE;
1331: }
1332: }
1333: if (this->other_auth)
1334: {
1335: if (ppk_id_received && is_first_round(this, FALSE) &&
1336: this->other_auth->use_ppk)
1337: {
1338: this->other_auth->use_ppk(this->other_auth, this->ppk, FALSE);
1339: }
1340: switch (this->other_auth->process(this->other_auth, message))
1341: {
1342: case SUCCESS:
1343: break;
1344: case NEED_MORE:
1345: return NEED_MORE;
1346: default:
1347: goto peer_auth_failed;
1348: }
1349: this->other_auth->destroy(this->other_auth);
1350: this->other_auth = NULL;
1351: }
1352: /* another auth round done, invoke authorize hook */
1353: if (!charon->bus->authorize(charon->bus, FALSE))
1354: {
1355: DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
1356: goto peer_auth_failed;
1357: }
1358:
1359: if (!mutual_eap)
1360: {
1361: apply_auth_cfg(this, FALSE);
1362: }
1363: }
1364:
1365: if (require_strict(this, mutual_eap))
1366: {
1367: if (!update_cfg_candidates(this, TRUE))
1368: {
1369: goto peer_auth_failed;
1370: }
1371: }
1372:
1373: if (this->my_auth)
1374: {
1375: /* while we already set the PPK in build_i(), we MUST not use it if
1376: * the peer did not reply with a PPK_ID notify */
1377: if (this->ppk.ptr && this->my_auth->use_ppk)
1378: {
1379: this->my_auth->use_ppk(this->my_auth,
1380: ppk_id_received ? this->ppk : chunk_empty,
1381: FALSE);
1382: }
1383: switch (this->my_auth->process(this->my_auth, message))
1384: {
1385: case SUCCESS:
1386: apply_auth_cfg(this, TRUE);
1387: if (this->my_auth->is_mutual(this->my_auth))
1388: {
1389: apply_auth_cfg(this, FALSE);
1390: }
1391: this->my_auth->destroy(this->my_auth);
1392: this->my_auth = NULL;
1393: this->do_another_auth = do_another_auth(this);
1394: break;
1395: case NEED_MORE:
1396: break;
1397: default:
1398: goto local_auth_failed;
1399: }
1400: }
1401:
1402: /* change keys and clear PPK after we are done with our authentication, so
1403: * we only explicitly use it for the first round, afterwards we just use the
1404: * changed SK_p keys implicitly */
1405: if (!this->my_auth && this->ppk_id)
1406: {
1407: if (ppk_id_received)
1408: {
1409: if (!apply_ppk(this))
1410: {
1411: goto local_auth_failed;
1412: }
1413: }
1414: else
1415: {
1416: DBG1(DBG_CFG, "peer didn't use PPK for PPK_ID '%Y'", this->ppk_id);
1417: }
1418: clear_ppk(this);
1419: }
1420:
1421: if (mutual_eap)
1422: {
1423: if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth))
1424: {
1425: DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication");
1426: goto peer_auth_failed;
1427: }
1428: DBG1(DBG_IKE, "allow mutual EAP-only authentication");
1429: }
1430:
1431: if (!message->get_notify(message, ANOTHER_AUTH_FOLLOWS))
1432: {
1433: this->expect_another_auth = FALSE;
1434: }
1435: if (this->expect_another_auth || this->do_another_auth || this->my_auth)
1436: {
1437: return NEED_MORE;
1438: }
1439: if (!update_cfg_candidates(this, TRUE))
1440: {
1441: goto peer_auth_failed;
1442: }
1443: if (!charon->bus->authorize(charon->bus, TRUE))
1444: {
1445: DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
1446: "cancelling");
1447: goto peer_auth_failed;
1448: }
1449: DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1450: this->ike_sa->get_name(this->ike_sa),
1451: this->ike_sa->get_unique_id(this->ike_sa),
1452: this->ike_sa->get_my_host(this->ike_sa),
1453: this->ike_sa->get_my_id(this->ike_sa),
1454: this->ike_sa->get_other_host(this->ike_sa),
1455: this->ike_sa->get_other_id(this->ike_sa));
1456: this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1457: charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1458:
1459: if (this->redirect_to)
1460: {
1461: this->ike_sa->handle_redirect(this->ike_sa, this->redirect_to);
1462: }
1463: return SUCCESS;
1464:
1465: peer_auth_failed:
1466: charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1467: send_auth_failed_informational(this, message);
1468: return FAILED;
1469: local_auth_failed:
1470: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1471: send_auth_failed_informational(this, message);
1472: return FAILED;
1473: }
1474:
1475: METHOD(task_t, get_type, task_type_t,
1476: private_ike_auth_t *this)
1477: {
1478: return TASK_IKE_AUTH;
1479: }
1480:
1481: METHOD(task_t, migrate, void,
1482: private_ike_auth_t *this, ike_sa_t *ike_sa)
1483: {
1484: clear_ppk(this);
1485: chunk_free(&this->my_nonce);
1486: chunk_free(&this->other_nonce);
1487: DESTROY_IF(this->my_packet);
1488: DESTROY_IF(this->other_packet);
1489: DESTROY_IF(this->peer_cfg);
1490: DESTROY_IF(this->my_auth);
1491: DESTROY_IF(this->other_auth);
1492: DESTROY_IF(this->redirect_to);
1493: this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1494:
1495: this->my_packet = NULL;
1496: this->other_packet = NULL;
1497: this->ike_sa = ike_sa;
1498: this->peer_cfg = NULL;
1499: this->my_auth = NULL;
1500: this->other_auth = NULL;
1501: this->redirect_to = NULL;
1502: this->do_another_auth = TRUE;
1503: this->expect_another_auth = TRUE;
1504: this->authentication_failed = FALSE;
1505: this->candidates = linked_list_create();
1506: }
1507:
1508: METHOD(task_t, destroy, void,
1509: private_ike_auth_t *this)
1510: {
1511: clear_ppk(this);
1512: chunk_free(&this->my_nonce);
1513: chunk_free(&this->other_nonce);
1514: DESTROY_IF(this->my_packet);
1515: DESTROY_IF(this->other_packet);
1516: DESTROY_IF(this->my_auth);
1517: DESTROY_IF(this->other_auth);
1518: DESTROY_IF(this->peer_cfg);
1519: DESTROY_IF(this->redirect_to);
1520: this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1521: free(this);
1522: }
1523:
1524: /*
1525: * Described in header.
1526: */
1527: ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
1528: {
1529: private_ike_auth_t *this;
1530:
1531: INIT(this,
1532: .public = {
1533: .task = {
1534: .get_type = _get_type,
1535: .migrate = _migrate,
1536: .build = _build_r,
1537: .process = _process_r,
1538: .destroy = _destroy,
1539: },
1540: },
1541: .ike_sa = ike_sa,
1542: .initiator = initiator,
1543: .candidates = linked_list_create(),
1544: .do_another_auth = TRUE,
1545: .expect_another_auth = TRUE,
1546: );
1547: if (initiator)
1548: {
1549: this->public.task.build = _build_i;
1550: this->public.task.process = _process_i;
1551: }
1552: return &this->public;
1553: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>