Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/tasks/ike_auth.c, revision 1.1.1.2
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: {
1.1.1.2 ! misho 1012: if (lib->settings->get_bool(lib->settings,
! 1013: "%s.force_eap_only_authentication", FALSE, lib->ns))
! 1014: {
! 1015: DBG1(DBG_IKE, "ignore missing %N notify and use EAP-only "
! 1016: "authentication", notify_type_names,
! 1017: EAP_ONLY_AUTHENTICATION);
! 1018: }
! 1019: else
! 1020: {
! 1021: DBG1(DBG_IKE, "configured EAP-only authentication, but "
! 1022: "peer does not support it");
! 1023: goto peer_auth_failed;
! 1024: }
1.1 misho 1025: }
1026: }
1027: else
1028: {
1029: /* build authentication data */
1030: this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
1031: this->other_nonce, this->my_nonce,
1032: this->other_packet->get_data(this->other_packet),
1033: this->my_packet->get_data(this->my_packet),
1034: this->reserved);
1035: if (!this->my_auth)
1036: {
1037: goto local_auth_failed;
1038: }
1039: }
1040: }
1041:
1042: if (this->other_auth)
1043: {
1044: switch (this->other_auth->build(this->other_auth, message))
1045: {
1046: case SUCCESS:
1047: this->other_auth->destroy(this->other_auth);
1048: this->other_auth = NULL;
1049: break;
1050: case NEED_MORE:
1051: break;
1052: default:
1053: if (message->get_payload(message, PLV2_EAP))
1054: { /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
1055: goto peer_auth_failed_no_notify;
1056: }
1057: goto peer_auth_failed;
1058: }
1059: }
1060: if (this->my_auth)
1061: {
1062: if (this->ppk.ptr && this->my_auth->use_ppk)
1063: {
1064: this->my_auth->use_ppk(this->my_auth, this->ppk, FALSE);
1065: }
1066: switch (this->my_auth->build(this->my_auth, message))
1067: {
1068: case SUCCESS:
1069: apply_auth_cfg(this, TRUE);
1070: this->my_auth->destroy(this->my_auth);
1071: this->my_auth = NULL;
1072: break;
1073: case NEED_MORE:
1074: break;
1075: default:
1076: goto local_auth_failed;
1077: }
1078: }
1079:
1080: /* add a PPK_IDENTITY notify and derive new keys and clear the PPK */
1081: if (this->ppk.ptr)
1082: {
1083: message->add_notify(message, FALSE, PPK_IDENTITY, chunk_empty);
1084: if (!apply_ppk(this))
1085: {
1086: goto local_auth_failed;
1087: }
1088: }
1089:
1090: /* check for additional authentication rounds */
1091: if (do_another_auth(this))
1092: {
1093: message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
1094: }
1095: else
1096: {
1097: this->do_another_auth = FALSE;
1098: }
1099: if (this->do_another_auth || this->expect_another_auth)
1100: {
1101: return NEED_MORE;
1102: }
1103:
1104: if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
1105: this->ike_sa, this->initial_contact))
1106: {
1107: DBG1(DBG_IKE, "cancelling IKE_SA setup due to uniqueness policy");
1108: charon->bus->alert(charon->bus, ALERT_UNIQUE_KEEP);
1109: message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
1110: chunk_empty);
1111: return FAILED;
1112: }
1113: if (!charon->bus->authorize(charon->bus, TRUE))
1114: {
1115: DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
1116: goto peer_auth_failed;
1117: }
1118: if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
1119: charon->redirect->redirect_on_auth(charon->redirect, this->ike_sa,
1120: &gateway))
1121: {
1122: delete_ike_sa_job_t *job;
1123: chunk_t data;
1124:
1125: DBG1(DBG_IKE, "redirecting peer to %Y", gateway);
1126: data = redirect_data_create(gateway, chunk_empty);
1127: message->add_notify(message, FALSE, REDIRECT, data);
1128: gateway->destroy(gateway);
1129: chunk_free(&data);
1130: /* we use this condition to prevent the CHILD_SA from getting created */
1131: this->ike_sa->set_condition(this->ike_sa, COND_REDIRECTED, TRUE);
1132: /* if the peer does not delete the SA we do so after a while */
1133: job = delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE);
1134: lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
1135: lib->settings->get_int(lib->settings,
1136: "%s.half_open_timeout", HALF_OPEN_IKE_SA_TIMEOUT,
1137: lib->ns));
1138: }
1139: DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1140: this->ike_sa->get_name(this->ike_sa),
1141: this->ike_sa->get_unique_id(this->ike_sa),
1142: this->ike_sa->get_my_host(this->ike_sa),
1143: this->ike_sa->get_my_id(this->ike_sa),
1144: this->ike_sa->get_other_host(this->ike_sa),
1145: this->ike_sa->get_other_id(this->ike_sa));
1146: this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1147: charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1148: return SUCCESS;
1149:
1150: peer_auth_failed:
1151: message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
1152: peer_auth_failed_no_notify:
1153: charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1154: return FAILED;
1155: local_auth_failed:
1156: message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
1157: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1158: return FAILED;
1159: }
1160:
1161: /**
1162: * Send an INFORMATIONAL message with an AUTH_FAILED before closing IKE_SA
1163: */
1164: static void send_auth_failed_informational(private_ike_auth_t *this,
1165: message_t *reply)
1166: {
1167: message_t *message;
1168: packet_t *packet;
1169: host_t *host;
1170:
1171: message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
1172: message->set_message_id(message, reply->get_message_id(reply) + 1);
1173: host = this->ike_sa->get_my_host(this->ike_sa);
1174: message->set_source(message, host->clone(host));
1175: host = this->ike_sa->get_other_host(this->ike_sa);
1176: message->set_destination(message, host->clone(host));
1177: message->set_exchange_type(message, INFORMATIONAL);
1178: message->add_notify(message, FALSE, AUTHENTICATION_FAILED, chunk_empty);
1179:
1180: if (this->ike_sa->generate_message(this->ike_sa, message,
1181: &packet) == SUCCESS)
1182: {
1183: charon->sender->send(charon->sender, packet);
1184: }
1185: message->destroy(message);
1186: }
1187:
1188: /**
1189: * Check if strict constraint fulfillment required to continue current auth
1190: */
1191: static bool require_strict(private_ike_auth_t *this, bool mutual_eap)
1192: {
1193: auth_cfg_t *cfg;
1194:
1195: if (this->eap_acceptable)
1196: {
1197: return FALSE;
1198: }
1199:
1200: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
1201: switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
1202: {
1203: case AUTH_CLASS_EAP:
1204: if (mutual_eap && this->my_auth)
1205: {
1206: this->eap_acceptable = TRUE;
1207: return !this->my_auth->is_mutual(this->my_auth);
1208: }
1209: return TRUE;
1210: case AUTH_CLASS_PSK:
1211: return TRUE;
1212: case AUTH_CLASS_PUBKEY:
1213: case AUTH_CLASS_ANY:
1214: default:
1215: return FALSE;
1216: }
1217: }
1218:
1219: METHOD(task_t, process_i, status_t,
1220: private_ike_auth_t *this, message_t *message)
1221: {
1222: enumerator_t *enumerator;
1223: payload_t *payload;
1224: auth_cfg_t *cfg;
1225: bool mutual_eap = FALSE, ppk_id_received = FALSE;
1226:
1227: if (message->get_exchange_type(message) == IKE_SA_INIT)
1228: {
1229: if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
1230: multiple_auth_enabled())
1231: {
1232: this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
1233: }
1234: return collect_other_init_data(this, message);
1235: }
1236:
1237: enumerator = message->create_payload_enumerator(message);
1238: while (enumerator->enumerate(enumerator, &payload))
1239: {
1240: if (payload->get_type(payload) == PLV2_NOTIFY)
1241: {
1242: notify_payload_t *notify = (notify_payload_t*)payload;
1243: notify_type_t type = notify->get_notify_type(notify);
1244:
1245: switch (type)
1246: {
1247: case NO_PROPOSAL_CHOSEN:
1248: case SINGLE_PAIR_REQUIRED:
1249: case NO_ADDITIONAL_SAS:
1250: case INTERNAL_ADDRESS_FAILURE:
1251: case FAILED_CP_REQUIRED:
1252: case TS_UNACCEPTABLE:
1253: case INVALID_SELECTORS:
1254: /* these are errors, but are not critical as only the
1255: * CHILD_SA won't get build, but IKE_SA establishes anyway */
1256: break;
1257: case MOBIKE_SUPPORTED:
1258: case ADDITIONAL_IP4_ADDRESS:
1259: case ADDITIONAL_IP6_ADDRESS:
1260: /* handled in ike_mobike task */
1261: break;
1262: case AUTH_LIFETIME:
1263: /* handled in ike_auth_lifetime task */
1264: break;
1265: case ME_ENDPOINT:
1266: /* handled in ike_me task */
1267: break;
1268: case REDIRECT:
1269: DESTROY_IF(this->redirect_to);
1270: this->redirect_to = redirect_data_parse(
1271: notify->get_notification_data(notify), NULL);
1272: if (!this->redirect_to)
1273: {
1274: DBG1(DBG_IKE, "received invalid REDIRECT notify");
1275: }
1276: break;
1277: case IKEV2_MESSAGE_ID_SYNC_SUPPORTED:
1278: this->ike_sa->enable_extension(this->ike_sa,
1279: EXT_IKE_MESSAGE_ID_SYNC);
1280: break;
1281: case PPK_IDENTITY:
1282: ppk_id_received = TRUE;
1283: break;
1284: default:
1285: {
1286: if (type <= 16383)
1287: {
1288: DBG1(DBG_IKE, "received %N notify error",
1289: notify_type_names, type);
1290: enumerator->destroy(enumerator);
1291: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1292: return FAILED;
1293: }
1294: DBG2(DBG_IKE, "received %N notify",
1295: notify_type_names, type);
1296: break;
1297: }
1298: }
1299: }
1300: }
1301: enumerator->destroy(enumerator);
1302:
1303: if (this->expect_another_auth)
1304: {
1305: if (!this->other_auth)
1306: {
1307: id_payload_t *id_payload;
1308: identification_t *id;
1309:
1310: /* handle IDr payload */
1311: id_payload = (id_payload_t*)message->get_payload(message,
1312: PLV2_ID_RESPONDER);
1313: if (!id_payload)
1314: {
1315: DBG1(DBG_IKE, "IDr payload missing");
1316: goto peer_auth_failed;
1317: }
1318: id = id_payload->get_identification(id_payload);
1319: get_reserved_id_bytes(this, id_payload);
1320: this->ike_sa->set_other_id(this->ike_sa, id);
1321: cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
1322: cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
1323:
1324: if (message->get_payload(message, PLV2_AUTH))
1325: {
1326: /* verify authentication data */
1327: this->other_auth = authenticator_create_verifier(this->ike_sa,
1328: message, this->other_nonce, this->my_nonce,
1329: this->other_packet->get_data(this->other_packet),
1330: this->my_packet->get_data(this->my_packet),
1331: this->reserved);
1332: if (!this->other_auth)
1333: {
1334: goto peer_auth_failed;
1335: }
1336: }
1337: else
1338: {
1339: /* responder omitted AUTH payload, indicating EAP-only */
1340: mutual_eap = TRUE;
1341: }
1342: }
1343: if (this->other_auth)
1344: {
1345: if (ppk_id_received && is_first_round(this, FALSE) &&
1346: this->other_auth->use_ppk)
1347: {
1348: this->other_auth->use_ppk(this->other_auth, this->ppk, FALSE);
1349: }
1350: switch (this->other_auth->process(this->other_auth, message))
1351: {
1352: case SUCCESS:
1353: break;
1354: case NEED_MORE:
1355: return NEED_MORE;
1356: default:
1357: goto peer_auth_failed;
1358: }
1359: this->other_auth->destroy(this->other_auth);
1360: this->other_auth = NULL;
1361: }
1362: /* another auth round done, invoke authorize hook */
1363: if (!charon->bus->authorize(charon->bus, FALSE))
1364: {
1365: DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
1366: goto peer_auth_failed;
1367: }
1368:
1369: if (!mutual_eap)
1370: {
1371: apply_auth_cfg(this, FALSE);
1372: }
1373: }
1374:
1375: if (require_strict(this, mutual_eap))
1376: {
1377: if (!update_cfg_candidates(this, TRUE))
1378: {
1379: goto peer_auth_failed;
1380: }
1381: }
1382:
1383: if (this->my_auth)
1384: {
1385: /* while we already set the PPK in build_i(), we MUST not use it if
1386: * the peer did not reply with a PPK_ID notify */
1387: if (this->ppk.ptr && this->my_auth->use_ppk)
1388: {
1389: this->my_auth->use_ppk(this->my_auth,
1390: ppk_id_received ? this->ppk : chunk_empty,
1391: FALSE);
1392: }
1393: switch (this->my_auth->process(this->my_auth, message))
1394: {
1395: case SUCCESS:
1396: apply_auth_cfg(this, TRUE);
1397: if (this->my_auth->is_mutual(this->my_auth))
1398: {
1399: apply_auth_cfg(this, FALSE);
1400: }
1401: this->my_auth->destroy(this->my_auth);
1402: this->my_auth = NULL;
1403: this->do_another_auth = do_another_auth(this);
1404: break;
1405: case NEED_MORE:
1406: break;
1407: default:
1408: goto local_auth_failed;
1409: }
1410: }
1411:
1412: /* change keys and clear PPK after we are done with our authentication, so
1413: * we only explicitly use it for the first round, afterwards we just use the
1414: * changed SK_p keys implicitly */
1415: if (!this->my_auth && this->ppk_id)
1416: {
1417: if (ppk_id_received)
1418: {
1419: if (!apply_ppk(this))
1420: {
1421: goto local_auth_failed;
1422: }
1423: }
1424: else
1425: {
1426: DBG1(DBG_CFG, "peer didn't use PPK for PPK_ID '%Y'", this->ppk_id);
1427: }
1428: clear_ppk(this);
1429: }
1430:
1431: if (mutual_eap)
1432: {
1433: if (!this->my_auth || !this->my_auth->is_mutual(this->my_auth))
1434: {
1435: DBG1(DBG_IKE, "do not allow non-mutual EAP-only authentication");
1436: goto peer_auth_failed;
1437: }
1438: DBG1(DBG_IKE, "allow mutual EAP-only authentication");
1439: }
1440:
1441: if (!message->get_notify(message, ANOTHER_AUTH_FOLLOWS))
1442: {
1443: this->expect_another_auth = FALSE;
1444: }
1445: if (this->expect_another_auth || this->do_another_auth || this->my_auth)
1446: {
1447: return NEED_MORE;
1448: }
1449: if (!update_cfg_candidates(this, TRUE))
1450: {
1451: goto peer_auth_failed;
1452: }
1453: if (!charon->bus->authorize(charon->bus, TRUE))
1454: {
1455: DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, "
1456: "cancelling");
1457: goto peer_auth_failed;
1458: }
1459: DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
1460: this->ike_sa->get_name(this->ike_sa),
1461: this->ike_sa->get_unique_id(this->ike_sa),
1462: this->ike_sa->get_my_host(this->ike_sa),
1463: this->ike_sa->get_my_id(this->ike_sa),
1464: this->ike_sa->get_other_host(this->ike_sa),
1465: this->ike_sa->get_other_id(this->ike_sa));
1466: this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
1467: charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
1468:
1469: if (this->redirect_to)
1470: {
1471: this->ike_sa->handle_redirect(this->ike_sa, this->redirect_to);
1472: }
1473: return SUCCESS;
1474:
1475: peer_auth_failed:
1476: charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
1477: send_auth_failed_informational(this, message);
1478: return FAILED;
1479: local_auth_failed:
1480: charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
1481: send_auth_failed_informational(this, message);
1482: return FAILED;
1483: }
1484:
1485: METHOD(task_t, get_type, task_type_t,
1486: private_ike_auth_t *this)
1487: {
1488: return TASK_IKE_AUTH;
1489: }
1490:
1491: METHOD(task_t, migrate, void,
1492: private_ike_auth_t *this, ike_sa_t *ike_sa)
1493: {
1494: clear_ppk(this);
1495: chunk_free(&this->my_nonce);
1496: chunk_free(&this->other_nonce);
1497: DESTROY_IF(this->my_packet);
1498: DESTROY_IF(this->other_packet);
1499: DESTROY_IF(this->peer_cfg);
1500: DESTROY_IF(this->my_auth);
1501: DESTROY_IF(this->other_auth);
1502: DESTROY_IF(this->redirect_to);
1503: this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1504:
1505: this->my_packet = NULL;
1506: this->other_packet = NULL;
1507: this->ike_sa = ike_sa;
1508: this->peer_cfg = NULL;
1509: this->my_auth = NULL;
1510: this->other_auth = NULL;
1511: this->redirect_to = NULL;
1512: this->do_another_auth = TRUE;
1513: this->expect_another_auth = TRUE;
1514: this->authentication_failed = FALSE;
1515: this->candidates = linked_list_create();
1516: }
1517:
1518: METHOD(task_t, destroy, void,
1519: private_ike_auth_t *this)
1520: {
1521: clear_ppk(this);
1522: chunk_free(&this->my_nonce);
1523: chunk_free(&this->other_nonce);
1524: DESTROY_IF(this->my_packet);
1525: DESTROY_IF(this->other_packet);
1526: DESTROY_IF(this->my_auth);
1527: DESTROY_IF(this->other_auth);
1528: DESTROY_IF(this->peer_cfg);
1529: DESTROY_IF(this->redirect_to);
1530: this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
1531: free(this);
1532: }
1533:
1534: /*
1535: * Described in header.
1536: */
1537: ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
1538: {
1539: private_ike_auth_t *this;
1540:
1541: INIT(this,
1542: .public = {
1543: .task = {
1544: .get_type = _get_type,
1545: .migrate = _migrate,
1546: .build = _build_r,
1547: .process = _process_r,
1548: .destroy = _destroy,
1549: },
1550: },
1551: .ike_sa = ike_sa,
1552: .initiator = initiator,
1553: .candidates = linked_list_create(),
1554: .do_another_auth = TRUE,
1555: .expect_another_auth = TRUE,
1556: );
1557: if (initiator)
1558: {
1559: this->public.task.build = _build_i;
1560: this->public.task.process = _process_i;
1561: }
1562: return &this->public;
1563: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>