ikev1: Get and set the lifetimes of the selected proposal/transform
[strongswan.git] / src / libcharon / sa / ikev1 / tasks / aggressive_mode.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * Copyright (C) 2012 Martin Willi
6 * Copyright (C) 2012 revosec AG
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include "aggressive_mode.h"
20
21 #include <string.h>
22
23 #include <daemon.h>
24 #include <sa/ikev1/phase1.h>
25 #include <encoding/payloads/sa_payload.h>
26 #include <encoding/payloads/id_payload.h>
27 #include <encoding/payloads/hash_payload.h>
28 #include <sa/ikev1/tasks/xauth.h>
29 #include <sa/ikev1/tasks/mode_config.h>
30 #include <sa/ikev1/tasks/informational.h>
31 #include <sa/ikev1/tasks/isakmp_delete.h>
32 #include <processing/jobs/adopt_children_job.h>
33 #include <processing/jobs/delete_ike_sa_job.h>
34
35 typedef struct private_aggressive_mode_t private_aggressive_mode_t;
36
37 /**
38 * Private members of a aggressive_mode_t task.
39 */
40 struct private_aggressive_mode_t {
41
42 /**
43 * Public methods and task_t interface.
44 */
45 aggressive_mode_t public;
46
47 /**
48 * Assigned IKE_SA.
49 */
50 ike_sa_t *ike_sa;
51
52 /**
53 * Are we the initiator?
54 */
55 bool initiator;
56
57 /**
58 * Common phase 1 helper class
59 */
60 phase1_t *ph1;
61
62 /**
63 * IKE config to establish
64 */
65 ike_cfg_t *ike_cfg;
66
67 /**
68 * Peer config to use
69 */
70 peer_cfg_t *peer_cfg;
71
72 /**
73 * selected IKE proposal
74 */
75 proposal_t *proposal;
76
77 /**
78 * Negotiated SA lifetime
79 */
80 uint32_t lifetime;
81
82 /**
83 * Negotiated authentication method
84 */
85 auth_method_t method;
86
87 /**
88 * Encoded ID payload, without fixed header
89 */
90 chunk_t id_data;
91
92 /** states of aggressive mode */
93 enum {
94 AM_INIT,
95 AM_AUTH,
96 } state;
97 };
98
99 /**
100 * Set IKE_SA to established state
101 */
102 static bool establish(private_aggressive_mode_t *this)
103 {
104 if (!charon->bus->authorize(charon->bus, TRUE))
105 {
106 DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
107 return FALSE;
108 }
109
110 DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%Y]...%H[%Y]",
111 this->ike_sa->get_name(this->ike_sa),
112 this->ike_sa->get_unique_id(this->ike_sa),
113 this->ike_sa->get_my_host(this->ike_sa),
114 this->ike_sa->get_my_id(this->ike_sa),
115 this->ike_sa->get_other_host(this->ike_sa),
116 this->ike_sa->get_other_id(this->ike_sa));
117
118 this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
119 charon->bus->ike_updown(charon->bus, this->ike_sa, TRUE);
120
121 return TRUE;
122 }
123
124 /**
125 * Check for notify errors, return TRUE if error found
126 */
127 static bool has_notify_errors(private_aggressive_mode_t *this, message_t *message)
128 {
129 enumerator_t *enumerator;
130 payload_t *payload;
131 bool err = FALSE;
132
133 enumerator = message->create_payload_enumerator(message);
134 while (enumerator->enumerate(enumerator, &payload))
135 {
136 if (payload->get_type(payload) == PLV1_NOTIFY)
137 {
138 notify_payload_t *notify;
139 notify_type_t type;
140
141 notify = (notify_payload_t*)payload;
142 type = notify->get_notify_type(notify);
143 if (type < 16384)
144 {
145 DBG1(DBG_IKE, "received %N error notify",
146 notify_type_names, type);
147 err = TRUE;
148 }
149 else
150 {
151 DBG1(DBG_IKE, "received %N notify", notify_type_names, type);
152 }
153 }
154 }
155 enumerator->destroy(enumerator);
156
157 return err;
158 }
159
160 /**
161 * Queue a task sending a notify in an INFORMATIONAL exchange
162 */
163 static status_t send_notify(private_aggressive_mode_t *this, notify_type_t type)
164 {
165 notify_payload_t *notify;
166 ike_sa_id_t *ike_sa_id;
167 uint64_t spi_i, spi_r;
168 chunk_t spi;
169
170 notify = notify_payload_create_from_protocol_and_type(PLV1_NOTIFY,
171 PROTO_IKE, type);
172 ike_sa_id = this->ike_sa->get_id(this->ike_sa);
173 spi_i = ike_sa_id->get_initiator_spi(ike_sa_id);
174 spi_r = ike_sa_id->get_responder_spi(ike_sa_id);
175 spi = chunk_cata("cc", chunk_from_thing(spi_i), chunk_from_thing(spi_r));
176 notify->set_spi_data(notify, spi);
177
178 this->ike_sa->queue_task(this->ike_sa,
179 (task_t*)informational_create(this->ike_sa, notify));
180 /* cancel all active/passive tasks in favour of informational */
181 this->ike_sa->flush_queue(this->ike_sa,
182 this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
183 return ALREADY_DONE;
184 }
185
186 /**
187 * Queue a delete task if authentication failed as initiator
188 */
189 static status_t send_delete(private_aggressive_mode_t *this)
190 {
191 this->ike_sa->queue_task(this->ike_sa,
192 (task_t*)isakmp_delete_create(this->ike_sa, TRUE));
193 /* cancel all active tasks in favour of informational */
194 this->ike_sa->flush_queue(this->ike_sa,
195 this->initiator ? TASK_QUEUE_ACTIVE : TASK_QUEUE_PASSIVE);
196 return ALREADY_DONE;
197 }
198
199 /**
200 * Schedule a timeout for the IKE_SA should it not establish
201 */
202 static void schedule_timeout(ike_sa_t *ike_sa)
203 {
204 job_t *job;
205
206 job = (job_t*)delete_ike_sa_job_create(ike_sa->get_id(ike_sa), FALSE);
207 lib->scheduler->schedule_job(lib->scheduler, job, HALF_OPEN_IKE_SA_TIMEOUT);
208 }
209
210 METHOD(task_t, build_i, status_t,
211 private_aggressive_mode_t *this, message_t *message)
212 {
213 switch (this->state)
214 {
215 case AM_INIT:
216 {
217 sa_payload_t *sa_payload;
218 id_payload_t *id_payload;
219 linked_list_t *proposals;
220 identification_t *id;
221 packet_t *packet;
222 uint16_t group;
223
224 DBG0(DBG_IKE, "initiating Aggressive Mode IKE_SA %s[%d] to %H",
225 this->ike_sa->get_name(this->ike_sa),
226 this->ike_sa->get_unique_id(this->ike_sa),
227 this->ike_sa->get_other_host(this->ike_sa));
228 this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
229
230 this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
231 this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
232 this->peer_cfg->get_ref(this->peer_cfg);
233
234 this->method = this->ph1->get_auth_method(this->ph1, this->peer_cfg);
235 if (this->method == AUTH_NONE)
236 {
237 DBG1(DBG_CFG, "configuration uses unsupported authentication");
238 return FAILED;
239 }
240 this->lifetime = this->peer_cfg->get_reauth_time(this->peer_cfg,
241 FALSE);
242 if (!this->lifetime)
243 { /* fall back to rekey time of no rekey time configured */
244 this->lifetime = this->peer_cfg->get_rekey_time(this->peer_cfg,
245 FALSE);
246 }
247 this->lifetime += this->peer_cfg->get_over_time(this->peer_cfg);
248 proposals = this->ike_cfg->get_proposals(this->ike_cfg);
249 sa_payload = sa_payload_create_from_proposals_v1(proposals,
250 this->lifetime, 0, this->method, MODE_NONE,
251 ENCAP_NONE, 0);
252 proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
253
254 message->add_payload(message, &sa_payload->payload_interface);
255
256 group = this->ike_cfg->get_dh_group(this->ike_cfg);
257 if (group == MODP_NONE)
258 {
259 DBG1(DBG_IKE, "DH group selection failed");
260 return FAILED;
261 }
262 if (!this->ph1->create_dh(this->ph1, group))
263 {
264 DBG1(DBG_IKE, "DH group %N not supported",
265 diffie_hellman_group_names, group);
266 return FAILED;
267 }
268 if (!this->ph1->add_nonce_ke(this->ph1, message))
269 {
270 return FAILED;
271 }
272 id = this->ph1->get_id(this->ph1, this->peer_cfg, TRUE);
273 this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
274 id_payload = id_payload_create_from_identification(PLV1_ID, id);
275 this->id_data = id_payload->get_encoded(id_payload);
276 message->add_payload(message, &id_payload->payload_interface);
277
278 /* pregenerate message to store SA payload */
279 if (this->ike_sa->generate_message(this->ike_sa, message,
280 &packet) != SUCCESS)
281 {
282 DBG1(DBG_IKE, "pregenerating SA payload failed");
283 return FAILED;
284 }
285 packet->destroy(packet);
286 if (!this->ph1->save_sa_payload(this->ph1, message))
287 {
288 DBG1(DBG_IKE, "SA payload invalid");
289 return FAILED;
290 }
291 this->state = AM_AUTH;
292 return NEED_MORE;
293 }
294 case AM_AUTH:
295 {
296 if (!this->ph1->build_auth(this->ph1, this->method, message,
297 this->id_data))
298 {
299 this->id_data = chunk_empty;
300 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
301 return send_notify(this, AUTHENTICATION_FAILED);
302 }
303 this->id_data = chunk_empty;
304
305 switch (this->method)
306 {
307 case AUTH_XAUTH_INIT_PSK:
308 case AUTH_XAUTH_INIT_RSA:
309 case AUTH_HYBRID_INIT_RSA:
310 /* wait for XAUTH request */
311 schedule_timeout(this->ike_sa);
312 break;
313 case AUTH_XAUTH_RESP_PSK:
314 case AUTH_XAUTH_RESP_RSA:
315 case AUTH_HYBRID_RESP_RSA:
316 this->ike_sa->queue_task(this->ike_sa,
317 (task_t*)xauth_create(this->ike_sa, TRUE));
318 break;
319 default:
320 if (charon->ike_sa_manager->check_uniqueness(
321 charon->ike_sa_manager, this->ike_sa, FALSE))
322 {
323 DBG1(DBG_IKE, "cancelling Aggressive Mode due to "
324 "uniqueness policy");
325 return send_notify(this, AUTHENTICATION_FAILED);
326 }
327 if (!establish(this))
328 {
329 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
330 return send_notify(this, AUTHENTICATION_FAILED);
331 }
332 break;
333 }
334 /* check for and prepare mode config push/pull */
335 if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
336 {
337 if (this->peer_cfg->use_pull_mode(this->peer_cfg))
338 {
339 this->ike_sa->queue_task(this->ike_sa,
340 (task_t*)mode_config_create(this->ike_sa, TRUE, TRUE));
341 }
342 else
343 {
344 schedule_timeout(this->ike_sa);
345 }
346 }
347 else if (this->ph1->has_pool(this->ph1, this->peer_cfg))
348 {
349 if (this->peer_cfg->use_pull_mode(this->peer_cfg))
350 {
351 schedule_timeout(this->ike_sa);
352 }
353 else
354 {
355 this->ike_sa->queue_task(this->ike_sa,
356 (task_t*)mode_config_create(this->ike_sa, TRUE, FALSE));
357 }
358 }
359 return SUCCESS;
360 }
361 default:
362 return FAILED;
363 }
364 }
365
366 METHOD(task_t, process_r, status_t,
367 private_aggressive_mode_t *this, message_t *message)
368 {
369 switch (this->state)
370 {
371 case AM_INIT:
372 {
373 sa_payload_t *sa_payload;
374 id_payload_t *id_payload;
375 identification_t *id;
376 linked_list_t *list;
377 proposal_selection_flag_t flags = PROPOSAL_SKIP_PRIVATE;
378 uint16_t group;
379
380 this->ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
381 DBG0(DBG_IKE, "%H is initiating a Aggressive Mode IKE_SA",
382 message->get_source(message));
383 this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
384
385 this->ike_sa->update_hosts(this->ike_sa,
386 message->get_destination(message),
387 message->get_source(message), TRUE);
388
389 sa_payload = (sa_payload_t*)message->get_payload(message,
390 PLV1_SECURITY_ASSOCIATION);
391 if (!sa_payload)
392 {
393 DBG1(DBG_IKE, "SA payload missing");
394 return send_notify(this, INVALID_PAYLOAD_TYPE);
395 }
396 if (!this->ph1->save_sa_payload(this->ph1, message))
397 {
398 return send_notify(this, INVALID_PAYLOAD_TYPE);
399 }
400
401 list = sa_payload->get_proposals(sa_payload);
402 if (!lib->settings->get_bool(lib->settings,
403 "%s.prefer_configured_proposals", TRUE, lib->ns))
404 {
405 flags = PROPOSAL_PREFER_SUPPLIED;
406 }
407 this->proposal = this->ike_cfg->select_proposal(this->ike_cfg, list,
408 flags);
409 list->destroy_offset(list, offsetof(proposal_t, destroy));
410 if (!this->proposal)
411 {
412 DBG1(DBG_IKE, "no proposal found");
413 return send_notify(this, NO_PROPOSAL_CHOSEN);
414 }
415 this->ike_sa->set_proposal(this->ike_sa, this->proposal);
416
417 this->method = sa_payload->get_auth_method(sa_payload);
418 this->lifetime = sa_payload->get_lifetime(sa_payload,
419 this->proposal);
420
421 switch (this->method)
422 {
423 case AUTH_XAUTH_INIT_PSK:
424 case AUTH_XAUTH_RESP_PSK:
425 case AUTH_PSK:
426 if (!lib->settings->get_bool(lib->settings, "%s.i_dont_care"
427 "_about_security_and_use_aggressive_mode_psk",
428 FALSE, lib->ns))
429 {
430 DBG1(DBG_IKE, "Aggressive Mode PSK disabled for "
431 "security reasons");
432 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
433 return send_notify(this, AUTHENTICATION_FAILED);
434 }
435 break;
436 default:
437 break;
438 }
439
440 if (!this->proposal->get_algorithm(this->proposal,
441 DIFFIE_HELLMAN_GROUP, &group, NULL))
442 {
443 DBG1(DBG_IKE, "DH group selection failed");
444 return send_notify(this, INVALID_KEY_INFORMATION);
445 }
446 if (!this->ph1->create_dh(this->ph1, group))
447 {
448 DBG1(DBG_IKE, "negotiated DH group not supported");
449 return send_notify(this, INVALID_KEY_INFORMATION);
450 }
451 if (!this->ph1->get_nonce_ke(this->ph1, message))
452 {
453 return send_notify(this, INVALID_PAYLOAD_TYPE);
454 }
455
456 id_payload = (id_payload_t*)message->get_payload(message, PLV1_ID);
457 if (!id_payload)
458 {
459 DBG1(DBG_IKE, "IDii payload missing");
460 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
461 return send_notify(this, INVALID_PAYLOAD_TYPE);
462 }
463
464 id = id_payload->get_identification(id_payload);
465 this->id_data = id_payload->get_encoded(id_payload);
466 this->ike_sa->set_other_id(this->ike_sa, id);
467 this->peer_cfg = this->ph1->select_config(this->ph1,
468 this->method, TRUE, id);
469 if (!this->peer_cfg)
470 {
471 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
472 return send_notify(this, AUTHENTICATION_FAILED);
473 }
474 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
475
476 this->state = AM_AUTH;
477 if (has_notify_errors(this, message))
478 {
479 return FAILED;
480 }
481 return NEED_MORE;
482 }
483 case AM_AUTH:
484 {
485 adopt_children_job_t *job = NULL;
486 xauth_t *xauth = NULL;
487
488 while (TRUE)
489 {
490 if (this->ph1->verify_auth(this->ph1, this->method, message,
491 chunk_clone(this->id_data)))
492 {
493 break;
494 }
495 this->peer_cfg->destroy(this->peer_cfg);
496 this->peer_cfg = this->ph1->select_config(this->ph1,
497 this->method, TRUE, NULL);
498 if (!this->peer_cfg)
499 {
500 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
501 return send_delete(this);
502 }
503 this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
504 }
505
506 if (!charon->bus->authorize(charon->bus, FALSE))
507 {
508 DBG1(DBG_IKE, "Aggressive Mode authorization hook forbids "
509 "IKE_SA, cancelling");
510 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
511 return send_delete(this);
512 }
513
514 switch (this->method)
515 {
516 case AUTH_XAUTH_INIT_PSK:
517 case AUTH_XAUTH_INIT_RSA:
518 case AUTH_HYBRID_INIT_RSA:
519 xauth = xauth_create(this->ike_sa, TRUE);
520 this->ike_sa->queue_task(this->ike_sa, (task_t*)xauth);
521 break;
522 case AUTH_XAUTH_RESP_PSK:
523 case AUTH_XAUTH_RESP_RSA:
524 case AUTH_HYBRID_RESP_RSA:
525 /* wait for XAUTH request */
526 break;
527 default:
528 if (charon->ike_sa_manager->check_uniqueness(
529 charon->ike_sa_manager, this->ike_sa, FALSE))
530 {
531 DBG1(DBG_IKE, "cancelling Aggressive Mode due to "
532 "uniqueness policy");
533 return send_delete(this);
534 }
535 if (!establish(this))
536 {
537 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
538 return send_delete(this);
539 }
540 job = adopt_children_job_create(
541 this->ike_sa->get_id(this->ike_sa));
542 break;
543 }
544 /* check for and prepare mode config push/pull */
545 if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
546 {
547 if (this->peer_cfg->use_pull_mode(this->peer_cfg))
548 {
549 this->ike_sa->queue_task(this->ike_sa,
550 (task_t*)mode_config_create(this->ike_sa, TRUE, TRUE));
551 }
552 }
553 else if (this->ph1->has_pool(this->ph1, this->peer_cfg))
554 {
555 if (!this->peer_cfg->use_pull_mode(this->peer_cfg))
556 {
557 if (job)
558 {
559 job->queue_task(job, (task_t*)
560 mode_config_create(this->ike_sa, TRUE, FALSE));
561 }
562 else if (xauth)
563 {
564 xauth->queue_mode_config_push(xauth);
565 }
566 else
567 {
568 this->ike_sa->queue_task(this->ike_sa, (task_t*)
569 mode_config_create(this->ike_sa, TRUE, FALSE));
570 }
571 }
572 }
573 if (job)
574 {
575 lib->processor->queue_job(lib->processor, (job_t*)job);
576 }
577 return SUCCESS;
578 }
579 default:
580 return FAILED;
581 }
582 }
583
584 METHOD(task_t, build_r, status_t,
585 private_aggressive_mode_t *this, message_t *message)
586 {
587 if (this->state == AM_AUTH)
588 {
589 sa_payload_t *sa_payload;
590 id_payload_t *id_payload;
591 identification_t *id;
592
593 sa_payload = sa_payload_create_from_proposal_v1(this->proposal,
594 this->lifetime, 0, this->method, MODE_NONE,
595 ENCAP_NONE, 0);
596 message->add_payload(message, &sa_payload->payload_interface);
597
598 if (!this->ph1->add_nonce_ke(this->ph1, message))
599 {
600 return send_notify(this, INVALID_KEY_INFORMATION);
601 }
602 if (!this->ph1->create_hasher(this->ph1))
603 {
604 return send_notify(this, NO_PROPOSAL_CHOSEN);
605 }
606 if (!this->ph1->derive_keys(this->ph1, this->peer_cfg, this->method))
607 {
608 return send_notify(this, INVALID_KEY_INFORMATION);
609 }
610
611 id = this->ph1->get_id(this->ph1, this->peer_cfg, TRUE);
612 this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
613
614 id_payload = id_payload_create_from_identification(PLV1_ID, id);
615 message->add_payload(message, &id_payload->payload_interface);
616
617 if (!this->ph1->build_auth(this->ph1, this->method, message,
618 id_payload->get_encoded(id_payload)))
619 {
620 charon->bus->alert(charon->bus, ALERT_LOCAL_AUTH_FAILED);
621 return send_notify(this, AUTHENTICATION_FAILED);
622 }
623 return NEED_MORE;
624 }
625 return FAILED;
626 }
627
628 METHOD(task_t, process_i, status_t,
629 private_aggressive_mode_t *this, message_t *message)
630 {
631 if (this->state == AM_AUTH)
632 {
633 auth_method_t method;
634 sa_payload_t *sa_payload;
635 id_payload_t *id_payload;
636 identification_t *id, *cid;
637 linked_list_t *list;
638 uint32_t lifetime;
639
640 sa_payload = (sa_payload_t*)message->get_payload(message,
641 PLV1_SECURITY_ASSOCIATION);
642 if (!sa_payload)
643 {
644 DBG1(DBG_IKE, "SA payload missing");
645 return send_notify(this, INVALID_PAYLOAD_TYPE);
646 }
647 list = sa_payload->get_proposals(sa_payload);
648 this->proposal = this->ike_cfg->select_proposal(this->ike_cfg, list, 0);
649 list->destroy_offset(list, offsetof(proposal_t, destroy));
650 if (!this->proposal)
651 {
652 DBG1(DBG_IKE, "no proposal found");
653 return send_notify(this, NO_PROPOSAL_CHOSEN);
654 }
655 this->ike_sa->set_proposal(this->ike_sa, this->proposal);
656
657 lifetime = sa_payload->get_lifetime(sa_payload, this->proposal);
658 if (lifetime != this->lifetime)
659 {
660 DBG1(DBG_IKE, "received lifetime %us does not match configured "
661 "lifetime %us", lifetime, this->lifetime);
662 }
663 this->lifetime = lifetime;
664 method = sa_payload->get_auth_method(sa_payload);
665 if (method != this->method)
666 {
667 DBG1(DBG_IKE, "received %N authentication, but configured %N, "
668 "continue with configured", auth_method_names, method,
669 auth_method_names, this->method);
670 }
671 if (!this->ph1->get_nonce_ke(this->ph1, message))
672 {
673 return send_notify(this, INVALID_PAYLOAD_TYPE);
674 }
675 if (!this->ph1->create_hasher(this->ph1))
676 {
677 return send_notify(this, NO_PROPOSAL_CHOSEN);
678 }
679
680 id_payload = (id_payload_t*)message->get_payload(message, PLV1_ID);
681 if (!id_payload)
682 {
683 DBG1(DBG_IKE, "IDir payload missing");
684 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
685 return send_delete(this);
686 }
687 id = id_payload->get_identification(id_payload);
688 cid = this->ph1->get_id(this->ph1, this->peer_cfg, FALSE);
689 if (cid && !id->matches(id, cid))
690 {
691 DBG1(DBG_IKE, "IDir '%Y' does not match to '%Y'", id, cid);
692 id->destroy(id);
693 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
694 return send_notify(this, INVALID_ID_INFORMATION);
695 }
696 this->ike_sa->set_other_id(this->ike_sa, id);
697
698 if (!this->ph1->derive_keys(this->ph1, this->peer_cfg, this->method))
699 {
700 return send_notify(this, INVALID_KEY_INFORMATION);
701 }
702 if (!this->ph1->verify_auth(this->ph1, this->method, message,
703 id_payload->get_encoded(id_payload)))
704 {
705 charon->bus->alert(charon->bus, ALERT_PEER_AUTH_FAILED);
706 return send_notify(this, AUTHENTICATION_FAILED);
707 }
708 if (!charon->bus->authorize(charon->bus, FALSE))
709 {
710 DBG1(DBG_IKE, "Aggressive Mode authorization hook forbids IKE_SA, "
711 "cancelling");
712 return send_notify(this, AUTHENTICATION_FAILED);
713 }
714
715 return NEED_MORE;
716 }
717 return FAILED;
718 }
719
720 METHOD(task_t, get_type, task_type_t,
721 private_aggressive_mode_t *this)
722 {
723 return TASK_AGGRESSIVE_MODE;
724 }
725
726 METHOD(task_t, migrate, void,
727 private_aggressive_mode_t *this, ike_sa_t *ike_sa)
728 {
729 DESTROY_IF(this->peer_cfg);
730 DESTROY_IF(this->proposal);
731 this->ph1->destroy(this->ph1);
732 chunk_free(&this->id_data);
733
734 this->ike_sa = ike_sa;
735 this->state = AM_INIT;
736 this->peer_cfg = NULL;
737 this->proposal = NULL;
738 this->ph1 = phase1_create(ike_sa, this->initiator);
739 }
740
741 METHOD(task_t, destroy, void,
742 private_aggressive_mode_t *this)
743 {
744 DESTROY_IF(this->peer_cfg);
745 DESTROY_IF(this->proposal);
746 this->ph1->destroy(this->ph1);
747 chunk_free(&this->id_data);
748 free(this);
749 }
750
751 /*
752 * Described in header.
753 */
754 aggressive_mode_t *aggressive_mode_create(ike_sa_t *ike_sa, bool initiator)
755 {
756 private_aggressive_mode_t *this;
757
758 INIT(this,
759 .public = {
760 .task = {
761 .get_type = _get_type,
762 .migrate = _migrate,
763 .destroy = _destroy,
764 },
765 },
766 .ike_sa = ike_sa,
767 .ph1 = phase1_create(ike_sa, initiator),
768 .initiator = initiator,
769 .state = AM_INIT,
770 );
771
772 if (initiator)
773 {
774 this->public.task.build = _build_i;
775 this->public.task.process = _process_i;
776 }
777 else
778 {
779 this->public.task.build = _build_r;
780 this->public.task.process = _process_r;
781 }
782
783 return &this->public;
784 }