child-create: Don't log CHILD_SA initiation until we know the unique ID
[strongswan.git] / src / libcharon / sa / ikev2 / tasks / child_create.c
1 /*
2 * Copyright (C) 2008-2017 Tobias Brunner
3 * Copyright (C) 2005-2008 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 "child_create.h"
19
20 #include <daemon.h>
21 #include <sa/ikev2/keymat_v2.h>
22 #include <crypto/diffie_hellman.h>
23 #include <credentials/certificates/x509.h>
24 #include <encoding/payloads/sa_payload.h>
25 #include <encoding/payloads/ke_payload.h>
26 #include <encoding/payloads/ts_payload.h>
27 #include <encoding/payloads/nonce_payload.h>
28 #include <encoding/payloads/notify_payload.h>
29 #include <encoding/payloads/delete_payload.h>
30 #include <processing/jobs/delete_ike_sa_job.h>
31 #include <processing/jobs/inactivity_job.h>
32 #include <processing/jobs/initiate_tasks_job.h>
33
34 typedef struct private_child_create_t private_child_create_t;
35
36 /**
37 * Private members of a child_create_t task.
38 */
39 struct private_child_create_t {
40
41 /**
42 * Public methods and task_t interface.
43 */
44 child_create_t public;
45
46 /**
47 * Assigned IKE_SA.
48 */
49 ike_sa_t *ike_sa;
50
51 /**
52 * Are we the initiator?
53 */
54 bool initiator;
55
56 /**
57 * nonce chosen by us
58 */
59 chunk_t my_nonce;
60
61 /**
62 * nonce chosen by peer
63 */
64 chunk_t other_nonce;
65
66 /**
67 * nonce generator
68 */
69 nonce_gen_t *nonceg;
70
71 /**
72 * config to create the CHILD_SA from
73 */
74 child_cfg_t *config;
75
76 /**
77 * list of proposal candidates
78 */
79 linked_list_t *proposals;
80
81 /**
82 * selected proposal to use for CHILD_SA
83 */
84 proposal_t *proposal;
85
86 /**
87 * traffic selectors for initiators side
88 */
89 linked_list_t *tsi;
90
91 /**
92 * traffic selectors for responders side
93 */
94 linked_list_t *tsr;
95
96 /**
97 * source of triggering packet
98 */
99 traffic_selector_t *packet_tsi;
100
101 /**
102 * destination of triggering packet
103 */
104 traffic_selector_t *packet_tsr;
105
106 /**
107 * optional diffie hellman exchange
108 */
109 diffie_hellman_t *dh;
110
111 /**
112 * Applying DH public value failed?
113 */
114 bool dh_failed;
115
116 /**
117 * group used for DH exchange
118 */
119 diffie_hellman_group_t dh_group;
120
121 /**
122 * IKE_SAs keymat
123 */
124 keymat_v2_t *keymat;
125
126 /**
127 * mode the new CHILD_SA uses (transport/tunnel/beet)
128 */
129 ipsec_mode_t mode;
130
131 /**
132 * peer accepts TFC padding for this SA
133 */
134 bool tfcv3;
135
136 /**
137 * IPComp transform to use
138 */
139 ipcomp_transform_t ipcomp;
140
141 /**
142 * IPComp transform proposed or accepted by the other peer
143 */
144 ipcomp_transform_t ipcomp_received;
145
146 /**
147 * IPsec protocol
148 */
149 protocol_id_t proto;
150
151 /**
152 * Own allocated SPI
153 */
154 uint32_t my_spi;
155
156 /**
157 * SPI received in proposal
158 */
159 uint32_t other_spi;
160
161 /**
162 * Own allocated Compression Parameter Index (CPI)
163 */
164 uint16_t my_cpi;
165
166 /**
167 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
168 */
169 uint16_t other_cpi;
170
171 /**
172 * reqid to use if we are rekeying
173 */
174 uint32_t reqid;
175
176 /**
177 * Explicit inbound mark value
178 */
179 u_int mark_in;
180
181 /**
182 * Explicit outbound mark value
183 */
184 u_int mark_out;
185
186 /**
187 * CHILD_SA which gets established
188 */
189 child_sa_t *child_sa;
190
191 /**
192 * successfully established the CHILD?
193 */
194 bool established;
195
196 /**
197 * whether the CHILD_SA rekeys an existing one
198 */
199 bool rekey;
200
201 /**
202 * whether we are retrying with another DH group
203 */
204 bool retry;
205 };
206
207 /**
208 * Schedule a retry if creating the CHILD_SA temporary failed
209 */
210 static void schedule_delayed_retry(private_child_create_t *this)
211 {
212 child_create_t *task;
213 uint32_t retry;
214
215 retry = RETRY_INTERVAL - (random() % RETRY_JITTER);
216
217 task = child_create_create(this->ike_sa,
218 this->config->get_ref(this->config), FALSE,
219 this->packet_tsi, this->packet_tsr);
220 task->use_reqid(task, this->reqid);
221 DBG1(DBG_IKE, "creating CHILD_SA failed, trying again in %d seconds",
222 retry);
223 this->ike_sa->queue_task_delayed(this->ike_sa, (task_t*)task, retry);
224 }
225
226 /**
227 * get the nonce from a message
228 */
229 static status_t get_nonce(message_t *message, chunk_t *nonce)
230 {
231 nonce_payload_t *payload;
232
233 payload = (nonce_payload_t*)message->get_payload(message, PLV2_NONCE);
234 if (payload == NULL)
235 {
236 return FAILED;
237 }
238 *nonce = payload->get_nonce(payload);
239 return NEED_MORE;
240 }
241
242 /**
243 * generate a new nonce to include in a CREATE_CHILD_SA message
244 */
245 static bool generate_nonce(private_child_create_t *this)
246 {
247 this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
248 if (!this->nonceg)
249 {
250 DBG1(DBG_IKE, "no nonce generator found to create nonce");
251 return FALSE;
252 }
253 if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
254 &this->my_nonce))
255 {
256 DBG1(DBG_IKE, "nonce allocation failed");
257 return FALSE;
258 }
259 return TRUE;
260 }
261
262 /**
263 * Check a list of traffic selectors if any selector belongs to host
264 */
265 static bool ts_list_is_host(linked_list_t *list, host_t *host)
266 {
267 traffic_selector_t *ts;
268 bool is_host = TRUE;
269 enumerator_t *enumerator = list->create_enumerator(list);
270
271 while (is_host && enumerator->enumerate(enumerator, (void**)&ts))
272 {
273 is_host = is_host && ts->is_host(ts, host);
274 }
275 enumerator->destroy(enumerator);
276 return is_host;
277 }
278
279 /**
280 * Allocate SPIs and update proposals
281 */
282 static bool allocate_spi(private_child_create_t *this)
283 {
284 enumerator_t *enumerator;
285 proposal_t *proposal;
286
287 if (this->initiator)
288 {
289 this->proto = PROTO_ESP;
290 /* we just get a SPI for the first protocol. TODO: If we ever support
291 * proposal lists with mixed protocols, we'd need multiple SPIs */
292 if (this->proposals->get_first(this->proposals,
293 (void**)&proposal) == SUCCESS)
294 {
295 this->proto = proposal->get_protocol(proposal);
296 }
297 }
298 else
299 {
300 this->proto = this->proposal->get_protocol(this->proposal);
301 }
302 this->my_spi = this->child_sa->alloc_spi(this->child_sa, this->proto);
303 if (this->my_spi)
304 {
305 if (this->initiator)
306 {
307 enumerator = this->proposals->create_enumerator(this->proposals);
308 while (enumerator->enumerate(enumerator, &proposal))
309 {
310 proposal->set_spi(proposal, this->my_spi);
311 }
312 enumerator->destroy(enumerator);
313 }
314 else
315 {
316 this->proposal->set_spi(this->proposal, this->my_spi);
317 }
318 return TRUE;
319 }
320 return FALSE;
321 }
322
323 /**
324 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
325 */
326 static void schedule_inactivity_timeout(private_child_create_t *this)
327 {
328 uint32_t timeout, id;
329 bool close_ike;
330
331 timeout = this->config->get_inactivity(this->config);
332 if (timeout)
333 {
334 close_ike = lib->settings->get_bool(lib->settings,
335 "%s.inactivity_close_ike", FALSE, lib->ns);
336 id = this->child_sa->get_unique_id(this->child_sa);
337 lib->scheduler->schedule_job(lib->scheduler, (job_t*)
338 inactivity_job_create(id, timeout, close_ike), timeout);
339 }
340 }
341
342 /**
343 * Check if we have a an address pool configured
344 */
345 static bool have_pool(ike_sa_t *ike_sa)
346 {
347 enumerator_t *enumerator;
348 peer_cfg_t *peer_cfg;
349 char *pool;
350 bool found = FALSE;
351
352 peer_cfg = ike_sa->get_peer_cfg(ike_sa);
353 if (peer_cfg)
354 {
355 enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
356 if (enumerator->enumerate(enumerator, &pool))
357 {
358 found = TRUE;
359 }
360 enumerator->destroy(enumerator);
361 }
362 return found;
363 }
364
365 /**
366 * Get hosts to use for dynamic traffic selectors
367 */
368 static linked_list_t *get_dynamic_hosts(ike_sa_t *ike_sa, bool local)
369 {
370 enumerator_t *enumerator;
371 linked_list_t *list;
372 host_t *host;
373
374 list = linked_list_create();
375 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
376 while (enumerator->enumerate(enumerator, &host))
377 {
378 list->insert_last(list, host);
379 }
380 enumerator->destroy(enumerator);
381
382 if (list->get_count(list) == 0)
383 { /* no virtual IPs assigned */
384 if (local)
385 {
386 host = ike_sa->get_my_host(ike_sa);
387 list->insert_last(list, host);
388 }
389 else if (!have_pool(ike_sa))
390 { /* use host only if we don't have a pool configured */
391 host = ike_sa->get_other_host(ike_sa);
392 list->insert_last(list, host);
393 }
394 }
395 return list;
396 }
397
398 /**
399 * Substitude any host address with NATed address in traffic selector
400 */
401 static linked_list_t* get_transport_nat_ts(private_child_create_t *this,
402 bool local, linked_list_t *in)
403 {
404 enumerator_t *enumerator;
405 linked_list_t *out;
406 traffic_selector_t *ts;
407 host_t *ike, *first = NULL;
408 uint8_t mask;
409
410 if (local)
411 {
412 ike = this->ike_sa->get_my_host(this->ike_sa);
413 }
414 else
415 {
416 ike = this->ike_sa->get_other_host(this->ike_sa);
417 }
418
419 out = linked_list_create();
420
421 enumerator = in->create_enumerator(in);
422 while (enumerator->enumerate(enumerator, &ts))
423 {
424 /* require that all selectors match the first "host" selector */
425 if (ts->is_host(ts, first))
426 {
427 if (!first)
428 {
429 ts->to_subnet(ts, &first, &mask);
430 }
431 ts = ts->clone(ts);
432 ts->set_address(ts, ike);
433 out->insert_last(out, ts);
434 }
435 }
436 enumerator->destroy(enumerator);
437 DESTROY_IF(first);
438
439 return out;
440 }
441
442 /**
443 * Narrow received traffic selectors with configuration
444 */
445 static linked_list_t* narrow_ts(private_child_create_t *this, bool local,
446 linked_list_t *in)
447 {
448 linked_list_t *hosts, *nat, *ts;
449 ike_condition_t cond;
450
451 cond = local ? COND_NAT_HERE : COND_NAT_THERE;
452 hosts = get_dynamic_hosts(this->ike_sa, local);
453
454 if (this->mode == MODE_TRANSPORT &&
455 this->ike_sa->has_condition(this->ike_sa, cond))
456 {
457 nat = get_transport_nat_ts(this, local, in);
458 ts = this->config->get_traffic_selectors(this->config, local, nat, hosts);
459 nat->destroy_offset(nat, offsetof(traffic_selector_t, destroy));
460 }
461 else
462 {
463 ts = this->config->get_traffic_selectors(this->config, local, in, hosts);
464 }
465
466 hosts->destroy(hosts);
467
468 return ts;
469 }
470
471 /**
472 * Install a CHILD_SA for usage, return value:
473 * - FAILED: no acceptable proposal
474 * - INVALID_ARG: diffie hellman group inacceptable
475 * - NOT_FOUND: TS inacceptable
476 */
477 static status_t select_and_install(private_child_create_t *this,
478 bool no_dh, bool ike_auth)
479 {
480 status_t status, status_i, status_o;
481 child_sa_outbound_state_t out_state;
482 chunk_t nonce_i, nonce_r;
483 chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
484 chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
485 linked_list_t *my_ts, *other_ts;
486 host_t *me, *other;
487 bool private, prefer_configured;
488
489 if (this->proposals == NULL)
490 {
491 DBG1(DBG_IKE, "SA payload missing in message");
492 return FAILED;
493 }
494 if (this->tsi == NULL || this->tsr == NULL)
495 {
496 DBG1(DBG_IKE, "TS payloads missing in message");
497 return NOT_FOUND;
498 }
499
500 me = this->ike_sa->get_my_host(this->ike_sa);
501 other = this->ike_sa->get_other_host(this->ike_sa);
502
503 private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
504 prefer_configured = lib->settings->get_bool(lib->settings,
505 "%s.prefer_configured_proposals", TRUE, lib->ns);
506 this->proposal = this->config->select_proposal(this->config,
507 this->proposals, no_dh, private, prefer_configured);
508 if (this->proposal == NULL)
509 {
510 DBG1(DBG_IKE, "no acceptable proposal found");
511 charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD,
512 this->proposals);
513 return FAILED;
514 }
515 this->other_spi = this->proposal->get_spi(this->proposal);
516
517 if (!this->initiator && !allocate_spi(this))
518 { /* responder has no SPI allocated yet */
519 DBG1(DBG_IKE, "allocating SPI failed");
520 return FAILED;
521 }
522 this->child_sa->set_proposal(this->child_sa, this->proposal);
523
524 if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
525 {
526 uint16_t group;
527
528 if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
529 &group, NULL))
530 {
531 DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N",
532 diffie_hellman_group_names, this->dh_group,
533 diffie_hellman_group_names, group);
534 this->dh_group = group;
535 return INVALID_ARG;
536 }
537 /* the selected proposal does not use a DH group */
538 DBG1(DBG_IKE, "ignoring KE exchange, agreed on a non-PFS proposal");
539 DESTROY_IF(this->dh);
540 this->dh = NULL;
541 this->dh_group = MODP_NONE;
542 }
543
544 if (this->initiator)
545 {
546 nonce_i = this->my_nonce;
547 nonce_r = this->other_nonce;
548 my_ts = narrow_ts(this, TRUE, this->tsi);
549 other_ts = narrow_ts(this, FALSE, this->tsr);
550 }
551 else
552 {
553 nonce_r = this->my_nonce;
554 nonce_i = this->other_nonce;
555 my_ts = narrow_ts(this, TRUE, this->tsr);
556 other_ts = narrow_ts(this, FALSE, this->tsi);
557 }
558
559 if (this->initiator)
560 {
561 if (ike_auth)
562 {
563 charon->bus->narrow(charon->bus, this->child_sa,
564 NARROW_INITIATOR_POST_NOAUTH, my_ts, other_ts);
565 }
566 else
567 {
568 charon->bus->narrow(charon->bus, this->child_sa,
569 NARROW_INITIATOR_POST_AUTH, my_ts, other_ts);
570 }
571 }
572 else
573 {
574 charon->bus->narrow(charon->bus, this->child_sa,
575 NARROW_RESPONDER, my_ts, other_ts);
576 }
577
578 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
579 {
580 charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
581 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
582 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
583 DBG1(DBG_IKE, "no acceptable traffic selectors found");
584 return NOT_FOUND;
585 }
586
587 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
588 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
589 if (this->initiator)
590 {
591 this->tsi = my_ts;
592 this->tsr = other_ts;
593 }
594 else
595 {
596 this->tsr = my_ts;
597 this->tsi = other_ts;
598 }
599
600 if (!this->initiator)
601 {
602 /* check if requested mode is acceptable, downgrade if required */
603 switch (this->mode)
604 {
605 case MODE_TRANSPORT:
606 if (!this->config->has_option(this->config, OPT_PROXY_MODE) &&
607 (!ts_list_is_host(this->tsi, other) ||
608 !ts_list_is_host(this->tsr, me))
609 )
610 {
611 this->mode = MODE_TUNNEL;
612 DBG1(DBG_IKE, "not using transport mode, not host-to-host");
613 }
614 if (this->config->get_mode(this->config) != MODE_TRANSPORT)
615 {
616 this->mode = MODE_TUNNEL;
617 }
618 break;
619 case MODE_BEET:
620 if (!ts_list_is_host(this->tsi, NULL) ||
621 !ts_list_is_host(this->tsr, NULL))
622 {
623 this->mode = MODE_TUNNEL;
624 DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
625 }
626 if (this->config->get_mode(this->config) != MODE_BEET)
627 {
628 this->mode = MODE_TUNNEL;
629 }
630 break;
631 default:
632 break;
633 }
634 /* use a copy of the traffic selectors, as the POST hook should not
635 * change payloads */
636 my_ts = this->tsr->clone_offset(this->tsr,
637 offsetof(traffic_selector_t, clone));
638 other_ts = this->tsi->clone_offset(this->tsi,
639 offsetof(traffic_selector_t, clone));
640 charon->bus->narrow(charon->bus, this->child_sa,
641 NARROW_RESPONDER_POST, my_ts, other_ts);
642
643 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
644 {
645 my_ts->destroy_offset(my_ts,
646 offsetof(traffic_selector_t, destroy));
647 other_ts->destroy_offset(other_ts,
648 offsetof(traffic_selector_t, destroy));
649 return NOT_FOUND;
650 }
651 }
652
653 this->child_sa->set_policies(this->child_sa, my_ts, other_ts);
654 if (!this->initiator)
655 {
656 my_ts->destroy_offset(my_ts,
657 offsetof(traffic_selector_t, destroy));
658 other_ts->destroy_offset(other_ts,
659 offsetof(traffic_selector_t, destroy));
660 }
661
662 this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
663 this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
664 this->child_sa->set_mode(this->child_sa, this->mode);
665 this->child_sa->set_protocol(this->child_sa,
666 this->proposal->get_protocol(this->proposal));
667
668 if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
669 {
670 this->my_cpi = this->other_cpi = 0;
671 this->ipcomp = IPCOMP_NONE;
672 }
673 status_i = status_o = FAILED;
674 if (this->keymat->derive_child_keys(this->keymat, this->proposal,
675 this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
676 {
677 if (this->initiator)
678 {
679 status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
680 this->my_spi, this->my_cpi, this->initiator,
681 TRUE, this->tfcv3);
682 }
683 else
684 {
685 status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
686 this->my_spi, this->my_cpi, this->initiator,
687 TRUE, this->tfcv3);
688 }
689 if (this->rekey)
690 { /* during rekeyings we install the outbound SA and/or policies
691 * separately: as responder when we receive the delete for the old
692 * SA, as initiator pretty much immediately in the ike-rekey task,
693 * unless there was a rekey collision that we lost */
694 if (this->initiator)
695 {
696 status_o = this->child_sa->register_outbound(this->child_sa,
697 encr_i, integ_i, this->other_spi, this->other_cpi,
698 this->tfcv3);
699 }
700 else
701 {
702 status_o = this->child_sa->register_outbound(this->child_sa,
703 encr_r, integ_r, this->other_spi, this->other_cpi,
704 this->tfcv3);
705 }
706 }
707 else if (this->initiator)
708 {
709 status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
710 this->other_spi, this->other_cpi, this->initiator,
711 FALSE, this->tfcv3);
712 }
713 else
714 {
715 status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
716 this->other_spi, this->other_cpi, this->initiator,
717 FALSE, this->tfcv3);
718 }
719 }
720
721 if (status_i != SUCCESS || status_o != SUCCESS)
722 {
723 DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
724 (status_i != SUCCESS) ? "inbound " : "",
725 (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
726 (status_o != SUCCESS) ? "outbound " : "");
727 charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED,
728 this->child_sa);
729 status = FAILED;
730 }
731 else
732 {
733 status = this->child_sa->install_policies(this->child_sa);
734
735 if (status != SUCCESS)
736 {
737 DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
738 charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_POLICY_FAILED,
739 this->child_sa);
740 status = NOT_FOUND;
741 }
742 else
743 {
744 charon->bus->child_derived_keys(charon->bus, this->child_sa,
745 this->initiator, encr_i, encr_r,
746 integ_i, integ_r);
747 }
748 }
749 chunk_clear(&integ_i);
750 chunk_clear(&integ_r);
751 chunk_clear(&encr_i);
752 chunk_clear(&encr_r);
753
754 if (status != SUCCESS)
755 {
756 return status;
757 }
758
759 charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
760 this->dh, nonce_i, nonce_r);
761
762 my_ts = linked_list_create_from_enumerator(
763 this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
764 other_ts = linked_list_create_from_enumerator(
765 this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
766 out_state = this->child_sa->get_outbound_state(this->child_sa);
767
768 DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established "
769 "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
770 (out_state == CHILD_OUTBOUND_INSTALLED) ? "" : "inbound ",
771 this->child_sa->get_name(this->child_sa),
772 this->child_sa->get_unique_id(this->child_sa),
773 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
774 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
775 my_ts, other_ts);
776
777 my_ts->destroy(my_ts);
778 other_ts->destroy(other_ts);
779
780 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
781 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
782 this->established = TRUE;
783
784 schedule_inactivity_timeout(this);
785 return SUCCESS;
786 }
787
788 /**
789 * build the payloads for the message
790 */
791 static bool build_payloads(private_child_create_t *this, message_t *message)
792 {
793 sa_payload_t *sa_payload;
794 nonce_payload_t *nonce_payload;
795 ke_payload_t *ke_payload;
796 ts_payload_t *ts_payload;
797 kernel_feature_t features;
798
799 /* add SA payload */
800 if (this->initiator)
801 {
802 sa_payload = sa_payload_create_from_proposals_v2(this->proposals);
803 }
804 else
805 {
806 sa_payload = sa_payload_create_from_proposal_v2(this->proposal);
807 }
808 message->add_payload(message, (payload_t*)sa_payload);
809
810 /* add nonce payload if not in IKE_AUTH */
811 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
812 {
813 nonce_payload = nonce_payload_create(PLV2_NONCE);
814 nonce_payload->set_nonce(nonce_payload, this->my_nonce);
815 message->add_payload(message, (payload_t*)nonce_payload);
816 }
817
818 /* diffie hellman exchange, if PFS enabled */
819 if (this->dh)
820 {
821 ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
822 this->dh);
823 if (!ke_payload)
824 {
825 DBG1(DBG_IKE, "creating KE payload failed");
826 return FALSE;
827 }
828 message->add_payload(message, (payload_t*)ke_payload);
829 }
830
831 /* add TSi/TSr payloads */
832 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
833 message->add_payload(message, (payload_t*)ts_payload);
834 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
835 message->add_payload(message, (payload_t*)ts_payload);
836
837 /* add a notify if we are not in tunnel mode */
838 switch (this->mode)
839 {
840 case MODE_TRANSPORT:
841 message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
842 break;
843 case MODE_BEET:
844 message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
845 break;
846 default:
847 break;
848 }
849
850 features = charon->kernel->get_features(charon->kernel);
851 if (!(features & KERNEL_ESP_V3_TFC))
852 {
853 message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED,
854 chunk_empty);
855 }
856 return TRUE;
857 }
858
859 /**
860 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
861 */
862 static void add_ipcomp_notify(private_child_create_t *this,
863 message_t *message, uint8_t ipcomp)
864 {
865 this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
866 if (this->my_cpi)
867 {
868 this->ipcomp = ipcomp;
869 message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
870 chunk_cata("cc", chunk_from_thing(this->my_cpi),
871 chunk_from_thing(ipcomp)));
872 }
873 else
874 {
875 DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
876 }
877 }
878
879 /**
880 * handle a received notify payload
881 */
882 static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
883 {
884 switch (notify->get_notify_type(notify))
885 {
886 case USE_TRANSPORT_MODE:
887 this->mode = MODE_TRANSPORT;
888 break;
889 case USE_BEET_MODE:
890 if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN))
891 { /* handle private use notify only if we know its meaning */
892 this->mode = MODE_BEET;
893 }
894 else
895 {
896 DBG1(DBG_IKE, "received a notify strongSwan uses for BEET "
897 "mode, but peer implementation unknown, skipped");
898 }
899 break;
900 case IPCOMP_SUPPORTED:
901 {
902 ipcomp_transform_t ipcomp;
903 uint16_t cpi;
904 chunk_t data;
905
906 data = notify->get_notification_data(notify);
907 cpi = *(uint16_t*)data.ptr;
908 ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
909 switch (ipcomp)
910 {
911 case IPCOMP_DEFLATE:
912 this->other_cpi = cpi;
913 this->ipcomp_received = ipcomp;
914 break;
915 case IPCOMP_LZS:
916 case IPCOMP_LZJH:
917 default:
918 DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
919 "transform ID we don't support %N",
920 ipcomp_transform_names, ipcomp);
921 break;
922 }
923 break;
924 }
925 case ESP_TFC_PADDING_NOT_SUPPORTED:
926 DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding",
927 notify_type_names, notify->get_notify_type(notify));
928 this->tfcv3 = FALSE;
929 break;
930 default:
931 break;
932 }
933 }
934
935 /**
936 * Read payloads from message
937 */
938 static void process_payloads(private_child_create_t *this, message_t *message)
939 {
940 enumerator_t *enumerator;
941 payload_t *payload;
942 sa_payload_t *sa_payload;
943 ke_payload_t *ke_payload;
944 ts_payload_t *ts_payload;
945
946 /* defaults to TUNNEL mode */
947 this->mode = MODE_TUNNEL;
948
949 enumerator = message->create_payload_enumerator(message);
950 while (enumerator->enumerate(enumerator, &payload))
951 {
952 switch (payload->get_type(payload))
953 {
954 case PLV2_SECURITY_ASSOCIATION:
955 sa_payload = (sa_payload_t*)payload;
956 this->proposals = sa_payload->get_proposals(sa_payload);
957 break;
958 case PLV2_KEY_EXCHANGE:
959 ke_payload = (ke_payload_t*)payload;
960 if (!this->initiator)
961 {
962 this->dh_group = ke_payload->get_dh_group_number(ke_payload);
963 this->dh = this->keymat->keymat.create_dh(
964 &this->keymat->keymat, this->dh_group);
965 }
966 if (this->dh)
967 {
968 this->dh_failed = !this->dh->set_other_public_value(this->dh,
969 ke_payload->get_key_exchange_data(ke_payload));
970 }
971 break;
972 case PLV2_TS_INITIATOR:
973 ts_payload = (ts_payload_t*)payload;
974 this->tsi = ts_payload->get_traffic_selectors(ts_payload);
975 break;
976 case PLV2_TS_RESPONDER:
977 ts_payload = (ts_payload_t*)payload;
978 this->tsr = ts_payload->get_traffic_selectors(ts_payload);
979 break;
980 case PLV2_NOTIFY:
981 handle_notify(this, (notify_payload_t*)payload);
982 break;
983 default:
984 break;
985 }
986 }
987 enumerator->destroy(enumerator);
988 }
989
990 METHOD(task_t, build_i, status_t,
991 private_child_create_t *this, message_t *message)
992 {
993 enumerator_t *enumerator;
994 host_t *vip;
995 peer_cfg_t *peer_cfg;
996 linked_list_t *list;
997
998 switch (message->get_exchange_type(message))
999 {
1000 case IKE_SA_INIT:
1001 return get_nonce(message, &this->my_nonce);
1002 case CREATE_CHILD_SA:
1003 if (!generate_nonce(this))
1004 {
1005 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1006 chunk_empty);
1007 return SUCCESS;
1008 }
1009 if (!this->retry)
1010 {
1011 this->dh_group = this->config->get_dh_group(this->config);
1012 }
1013 break;
1014 case IKE_AUTH:
1015 if (message->get_message_id(message) != 1)
1016 {
1017 /* send only in the first request, not in subsequent rounds */
1018 return NEED_MORE;
1019 }
1020 break;
1021 default:
1022 break;
1023 }
1024
1025 /* check if we want a virtual IP, but don't have one */
1026 list = linked_list_create();
1027 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1028 if (!this->rekey)
1029 {
1030 enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
1031 while (enumerator->enumerate(enumerator, &vip))
1032 {
1033 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
1034 vip = host_create_any(vip->get_family(vip));
1035 list->insert_last(list, vip);
1036 }
1037 enumerator->destroy(enumerator);
1038 }
1039 if (list->get_count(list))
1040 {
1041 this->tsi = this->config->get_traffic_selectors(this->config,
1042 TRUE, NULL, list);
1043 list->destroy_offset(list, offsetof(host_t, destroy));
1044 }
1045 else
1046 { /* no virtual IPs configured */
1047 list->destroy(list);
1048 list = get_dynamic_hosts(this->ike_sa, TRUE);
1049 this->tsi = this->config->get_traffic_selectors(this->config,
1050 TRUE, NULL, list);
1051 list->destroy(list);
1052 }
1053 list = get_dynamic_hosts(this->ike_sa, FALSE);
1054 this->tsr = this->config->get_traffic_selectors(this->config,
1055 FALSE, NULL, list);
1056 list->destroy(list);
1057
1058 if (this->packet_tsi)
1059 {
1060 this->tsi->insert_first(this->tsi,
1061 this->packet_tsi->clone(this->packet_tsi));
1062 }
1063 if (this->packet_tsr)
1064 {
1065 this->tsr->insert_first(this->tsr,
1066 this->packet_tsr->clone(this->packet_tsr));
1067 }
1068 this->proposals = this->config->get_proposals(this->config,
1069 this->dh_group == MODP_NONE);
1070 this->mode = this->config->get_mode(this->config);
1071
1072 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
1073 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
1074 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
1075 this->mark_in, this->mark_out);
1076
1077 if (this->reqid)
1078 {
1079 DBG0(DBG_IKE, "establishing CHILD_SA %s{%d} reqid %d",
1080 this->child_sa->get_name(this->child_sa),
1081 this->child_sa->get_unique_id(this->child_sa), this->reqid);
1082 }
1083 else
1084 {
1085 DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
1086 this->child_sa->get_name(this->child_sa),
1087 this->child_sa->get_unique_id(this->child_sa));
1088 }
1089
1090 if (!allocate_spi(this))
1091 {
1092 DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
1093 return FAILED;
1094 }
1095
1096 if (this->dh_group != MODP_NONE)
1097 {
1098 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
1099 this->dh_group);
1100 }
1101
1102 if (this->config->has_option(this->config, OPT_IPCOMP))
1103 {
1104 /* IPCOMP_DEFLATE is the only transform we support at the moment */
1105 add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
1106 }
1107
1108 if (message->get_exchange_type(message) == IKE_AUTH)
1109 {
1110 charon->bus->narrow(charon->bus, this->child_sa,
1111 NARROW_INITIATOR_PRE_NOAUTH, this->tsi, this->tsr);
1112 }
1113 else
1114 {
1115 charon->bus->narrow(charon->bus, this->child_sa,
1116 NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
1117 }
1118
1119 if (!build_payloads(this, message))
1120 {
1121 return FAILED;
1122 }
1123
1124 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1125 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1126 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1127 this->tsi = NULL;
1128 this->tsr = NULL;
1129 this->proposals = NULL;
1130
1131 return NEED_MORE;
1132 }
1133
1134 METHOD(task_t, process_r, status_t,
1135 private_child_create_t *this, message_t *message)
1136 {
1137 switch (message->get_exchange_type(message))
1138 {
1139 case IKE_SA_INIT:
1140 return get_nonce(message, &this->other_nonce);
1141 case CREATE_CHILD_SA:
1142 get_nonce(message, &this->other_nonce);
1143 break;
1144 case IKE_AUTH:
1145 if (message->get_message_id(message) != 1)
1146 {
1147 /* only handle first AUTH payload, not additional rounds */
1148 return NEED_MORE;
1149 }
1150 default:
1151 break;
1152 }
1153
1154 process_payloads(this, message);
1155
1156 return NEED_MORE;
1157 }
1158
1159 /**
1160 * handle CHILD_SA setup failure
1161 */
1162 static void handle_child_sa_failure(private_child_create_t *this,
1163 message_t *message)
1164 {
1165 bool is_first;
1166
1167 is_first = message->get_exchange_type(message) == IKE_AUTH;
1168 if (is_first &&
1169 lib->settings->get_bool(lib->settings,
1170 "%s.close_ike_on_child_failure", FALSE, lib->ns))
1171 {
1172 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
1173 * first */
1174 DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
1175 lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
1176 delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
1177 100);
1178 }
1179 else
1180 {
1181 DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
1182 charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
1183 is_first);
1184 }
1185 }
1186
1187 /**
1188 * Substitute transport mode NAT selectors, if applicable
1189 */
1190 static linked_list_t* get_ts_if_nat_transport(private_child_create_t *this,
1191 bool local, linked_list_t *in)
1192 {
1193 linked_list_t *out = NULL;
1194 ike_condition_t cond;
1195
1196 if (this->mode == MODE_TRANSPORT)
1197 {
1198 cond = local ? COND_NAT_HERE : COND_NAT_THERE;
1199 if (this->ike_sa->has_condition(this->ike_sa, cond))
1200 {
1201 out = get_transport_nat_ts(this, local, in);
1202 if (out->get_count(out) == 0)
1203 {
1204 out->destroy(out);
1205 out = NULL;
1206 }
1207 }
1208 }
1209 return out;
1210 }
1211
1212 /**
1213 * Select a matching CHILD config as responder
1214 */
1215 static child_cfg_t* select_child_cfg(private_child_create_t *this)
1216 {
1217 peer_cfg_t *peer_cfg;
1218 child_cfg_t *child_cfg = NULL;;
1219
1220 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1221 if (peer_cfg && this->tsi && this->tsr)
1222 {
1223 linked_list_t *listr, *listi, *tsr, *tsi;
1224
1225 tsr = get_ts_if_nat_transport(this, TRUE, this->tsr);
1226 tsi = get_ts_if_nat_transport(this, FALSE, this->tsi);
1227
1228 listr = get_dynamic_hosts(this->ike_sa, TRUE);
1229 listi = get_dynamic_hosts(this->ike_sa, FALSE);
1230 child_cfg = peer_cfg->select_child_cfg(peer_cfg,
1231 tsr ?: this->tsr, tsi ?: this->tsi,
1232 listr, listi);
1233 if ((tsi || tsr) && child_cfg &&
1234 child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
1235 {
1236 /* found a CHILD config, but it doesn't use transport mode */
1237 child_cfg->destroy(child_cfg);
1238 child_cfg = NULL;
1239 }
1240 if (!child_cfg && (tsi || tsr))
1241 {
1242 /* no match for the substituted NAT selectors, try it without */
1243 child_cfg = peer_cfg->select_child_cfg(peer_cfg,
1244 this->tsr, this->tsi, listr, listi);
1245 }
1246 listr->destroy(listr);
1247 listi->destroy(listi);
1248 DESTROY_OFFSET_IF(tsi, offsetof(traffic_selector_t, destroy));
1249 DESTROY_OFFSET_IF(tsr, offsetof(traffic_selector_t, destroy));
1250 }
1251
1252 return child_cfg;
1253 }
1254
1255 METHOD(task_t, build_r, status_t,
1256 private_child_create_t *this, message_t *message)
1257 {
1258 payload_t *payload;
1259 enumerator_t *enumerator;
1260 bool no_dh = TRUE, ike_auth = FALSE;
1261
1262 switch (message->get_exchange_type(message))
1263 {
1264 case IKE_SA_INIT:
1265 return get_nonce(message, &this->my_nonce);
1266 case CREATE_CHILD_SA:
1267 if (!generate_nonce(this))
1268 {
1269 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1270 chunk_empty);
1271 return SUCCESS;
1272 }
1273 if (this->dh_failed)
1274 {
1275 DBG1(DBG_IKE, "applying DH public value failed");
1276 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1277 chunk_empty);
1278 return SUCCESS;
1279 }
1280 no_dh = FALSE;
1281 break;
1282 case IKE_AUTH:
1283 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1284 { /* wait until all authentication round completed */
1285 return NEED_MORE;
1286 }
1287 if (this->ike_sa->has_condition(this->ike_sa, COND_REDIRECTED))
1288 { /* no CHILD_SA is created for redirected SAs */
1289 return SUCCESS;
1290 }
1291 ike_auth = TRUE;
1292 default:
1293 break;
1294 }
1295
1296 if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
1297 {
1298 DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA");
1299 message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
1300 return SUCCESS;
1301 }
1302 if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
1303 {
1304 DBG1(DBG_IKE, "unable to create CHILD_SA while deleting IKE_SA");
1305 message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
1306 return SUCCESS;
1307 }
1308
1309 if (this->config == NULL)
1310 {
1311 this->config = select_child_cfg(this);
1312 }
1313 if (this->config == NULL)
1314 {
1315 DBG1(DBG_IKE, "traffic selectors %#R === %#R inacceptable",
1316 this->tsr, this->tsi);
1317 charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
1318 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1319 handle_child_sa_failure(this, message);
1320 return SUCCESS;
1321 }
1322
1323 /* check if ike_config_t included non-critical error notifies */
1324 enumerator = message->create_payload_enumerator(message);
1325 while (enumerator->enumerate(enumerator, &payload))
1326 {
1327 if (payload->get_type(payload) == PLV2_NOTIFY)
1328 {
1329 notify_payload_t *notify = (notify_payload_t*)payload;
1330
1331 switch (notify->get_notify_type(notify))
1332 {
1333 case INTERNAL_ADDRESS_FAILURE:
1334 case FAILED_CP_REQUIRED:
1335 {
1336 DBG1(DBG_IKE,"configuration payload negotiation "
1337 "failed, no CHILD_SA built");
1338 enumerator->destroy(enumerator);
1339 handle_child_sa_failure(this, message);
1340 return SUCCESS;
1341 }
1342 default:
1343 break;
1344 }
1345 }
1346 }
1347 enumerator->destroy(enumerator);
1348
1349 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
1350 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
1351 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY),
1352 this->mark_in, this->mark_out);
1353
1354 if (this->ipcomp_received != IPCOMP_NONE)
1355 {
1356 if (this->config->has_option(this->config, OPT_IPCOMP))
1357 {
1358 add_ipcomp_notify(this, message, this->ipcomp_received);
1359 }
1360 else
1361 {
1362 DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
1363 notify_type_names, IPCOMP_SUPPORTED);
1364 }
1365 }
1366
1367 switch (select_and_install(this, no_dh, ike_auth))
1368 {
1369 case SUCCESS:
1370 break;
1371 case NOT_FOUND:
1372 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1373 handle_child_sa_failure(this, message);
1374 return SUCCESS;
1375 case INVALID_ARG:
1376 {
1377 uint16_t group = htons(this->dh_group);
1378 message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
1379 chunk_from_thing(group));
1380 handle_child_sa_failure(this, message);
1381 return SUCCESS;
1382 }
1383 case FAILED:
1384 default:
1385 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1386 handle_child_sa_failure(this, message);
1387 return SUCCESS;
1388 }
1389
1390 if (!build_payloads(this, message))
1391 {
1392 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1393 handle_child_sa_failure(this, message);
1394 return SUCCESS;
1395 }
1396
1397 if (!this->rekey)
1398 { /* invoke the child_up() hook if we are not rekeying */
1399 charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1400 }
1401 return SUCCESS;
1402 }
1403
1404 /**
1405 * Raise alerts for received notify errors
1406 */
1407 static void raise_alerts(private_child_create_t *this, notify_type_t type)
1408 {
1409 linked_list_t *list;
1410
1411 switch (type)
1412 {
1413 case NO_PROPOSAL_CHOSEN:
1414 list = this->config->get_proposals(this->config, FALSE);
1415 charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD, list);
1416 list->destroy_offset(list, offsetof(proposal_t, destroy));
1417 break;
1418 default:
1419 break;
1420 }
1421 }
1422
1423 METHOD(task_t, build_i_delete, status_t,
1424 private_child_create_t *this, message_t *message)
1425 {
1426 message->set_exchange_type(message, INFORMATIONAL);
1427 if (this->my_spi && this->proto)
1428 {
1429 delete_payload_t *del;
1430
1431 del = delete_payload_create(PLV2_DELETE, this->proto);
1432 del->add_spi(del, this->my_spi);
1433 message->add_payload(message, (payload_t*)del);
1434
1435 DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x",
1436 protocol_id_names, this->proto, ntohl(this->my_spi));
1437 }
1438 return NEED_MORE;
1439 }
1440
1441 /**
1442 * Change task to delete the failed CHILD_SA as initiator
1443 */
1444 static status_t delete_failed_sa(private_child_create_t *this)
1445 {
1446 if (this->my_spi && this->proto)
1447 {
1448 this->public.task.build = _build_i_delete;
1449 this->public.task.process = (void*)return_success;
1450 return NEED_MORE;
1451 }
1452 return SUCCESS;
1453 }
1454
1455 METHOD(task_t, process_i, status_t,
1456 private_child_create_t *this, message_t *message)
1457 {
1458 enumerator_t *enumerator;
1459 payload_t *payload;
1460 bool no_dh = TRUE, ike_auth = FALSE;
1461
1462 switch (message->get_exchange_type(message))
1463 {
1464 case IKE_SA_INIT:
1465 return get_nonce(message, &this->other_nonce);
1466 case CREATE_CHILD_SA:
1467 get_nonce(message, &this->other_nonce);
1468 no_dh = FALSE;
1469 break;
1470 case IKE_AUTH:
1471 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1472 { /* wait until all authentication round completed */
1473 return NEED_MORE;
1474 }
1475 ike_auth = TRUE;
1476 default:
1477 break;
1478 }
1479
1480 /* check for erroneous notifies */
1481 enumerator = message->create_payload_enumerator(message);
1482 while (enumerator->enumerate(enumerator, &payload))
1483 {
1484 if (payload->get_type(payload) == PLV2_NOTIFY)
1485 {
1486 notify_payload_t *notify = (notify_payload_t*)payload;
1487 notify_type_t type = notify->get_notify_type(notify);
1488
1489 switch (type)
1490 {
1491 /* handle notify errors related to CHILD_SA only */
1492 case NO_PROPOSAL_CHOSEN:
1493 case SINGLE_PAIR_REQUIRED:
1494 case NO_ADDITIONAL_SAS:
1495 case INTERNAL_ADDRESS_FAILURE:
1496 case FAILED_CP_REQUIRED:
1497 case TS_UNACCEPTABLE:
1498 case INVALID_SELECTORS:
1499 {
1500 DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
1501 notify_type_names, type);
1502 enumerator->destroy(enumerator);
1503 raise_alerts(this, type);
1504 handle_child_sa_failure(this, message);
1505 /* an error in CHILD_SA creation is not critical */
1506 return SUCCESS;
1507 }
1508 case TEMPORARY_FAILURE:
1509 {
1510 DBG1(DBG_IKE, "received %N notify, will retry later",
1511 notify_type_names, type);
1512 enumerator->destroy(enumerator);
1513 if (!this->rekey)
1514 { /* the rekey task will retry itself if necessary */
1515 schedule_delayed_retry(this);
1516 }
1517 return SUCCESS;
1518 }
1519 case INVALID_KE_PAYLOAD:
1520 {
1521 chunk_t data;
1522 uint16_t group = MODP_NONE;
1523
1524 data = notify->get_notification_data(notify);
1525 if (data.len == sizeof(group))
1526 {
1527 memcpy(&group, data.ptr, data.len);
1528 group = ntohs(group);
1529 }
1530 DBG1(DBG_IKE, "peer didn't accept DH group %N, "
1531 "it requested %N", diffie_hellman_group_names,
1532 this->dh_group, diffie_hellman_group_names, group);
1533 this->retry = TRUE;
1534 this->dh_group = group;
1535 this->child_sa->set_state(this->child_sa, CHILD_RETRYING);
1536 this->public.task.migrate(&this->public.task, this->ike_sa);
1537 enumerator->destroy(enumerator);
1538 return NEED_MORE;
1539 }
1540 default:
1541 {
1542 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
1543 { /* handle notifies if not handled in IKE_AUTH */
1544 if (type <= 16383)
1545 {
1546 DBG1(DBG_IKE, "received %N notify error",
1547 notify_type_names, type);
1548 enumerator->destroy(enumerator);
1549 return SUCCESS;
1550 }
1551 DBG2(DBG_IKE, "received %N notify",
1552 notify_type_names, type);
1553 }
1554 break;
1555 }
1556 }
1557 }
1558 }
1559 enumerator->destroy(enumerator);
1560
1561 process_payloads(this, message);
1562
1563 if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
1564 {
1565 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting"
1566 " one, no CHILD_SA built");
1567 handle_child_sa_failure(this, message);
1568 return delete_failed_sa(this);
1569 }
1570 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
1571 {
1572 DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
1573 "IPComp is disabled");
1574 this->ipcomp = IPCOMP_NONE;
1575 }
1576 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
1577 {
1578 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1579 "no CHILD_SA built");
1580 handle_child_sa_failure(this, message);
1581 return delete_failed_sa(this);
1582 }
1583
1584 if (this->dh_failed)
1585 {
1586 DBG1(DBG_IKE, "applying DH public value failed");
1587 handle_child_sa_failure(this, message);
1588 return delete_failed_sa(this);
1589 }
1590
1591 if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
1592 {
1593 if (!this->rekey)
1594 { /* invoke the child_up() hook if we are not rekeying */
1595 charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1596 }
1597 }
1598 else
1599 {
1600 handle_child_sa_failure(this, message);
1601 return delete_failed_sa(this);
1602 }
1603 return SUCCESS;
1604 }
1605
1606 METHOD(child_create_t, use_reqid, void,
1607 private_child_create_t *this, uint32_t reqid)
1608 {
1609 this->reqid = reqid;
1610 }
1611
1612 METHOD(child_create_t, use_marks, void,
1613 private_child_create_t *this, u_int in, u_int out)
1614 {
1615 this->mark_in = in;
1616 this->mark_out = out;
1617 }
1618
1619 METHOD(child_create_t, get_child, child_sa_t*,
1620 private_child_create_t *this)
1621 {
1622 return this->child_sa;
1623 }
1624
1625 METHOD(child_create_t, set_config, void,
1626 private_child_create_t *this, child_cfg_t *cfg)
1627 {
1628 DESTROY_IF(this->config);
1629 this->config = cfg;
1630 }
1631
1632 METHOD(child_create_t, get_lower_nonce, chunk_t,
1633 private_child_create_t *this)
1634 {
1635 if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
1636 min(this->my_nonce.len, this->other_nonce.len)) < 0)
1637 {
1638 return this->my_nonce;
1639 }
1640 else
1641 {
1642 return this->other_nonce;
1643 }
1644 }
1645
1646 METHOD(task_t, get_type, task_type_t,
1647 private_child_create_t *this)
1648 {
1649 return TASK_CHILD_CREATE;
1650 }
1651
1652 METHOD(task_t, migrate, void,
1653 private_child_create_t *this, ike_sa_t *ike_sa)
1654 {
1655 chunk_free(&this->my_nonce);
1656 chunk_free(&this->other_nonce);
1657 if (this->tsr)
1658 {
1659 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1660 }
1661 if (this->tsi)
1662 {
1663 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1664 }
1665 DESTROY_IF(this->child_sa);
1666 DESTROY_IF(this->proposal);
1667 DESTROY_IF(this->nonceg);
1668 DESTROY_IF(this->dh);
1669 this->dh_failed = FALSE;
1670 if (this->proposals)
1671 {
1672 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1673 }
1674
1675 this->ike_sa = ike_sa;
1676 this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
1677 this->proposal = NULL;
1678 this->proposals = NULL;
1679 this->tsi = NULL;
1680 this->tsr = NULL;
1681 this->dh = NULL;
1682 this->nonceg = NULL;
1683 this->child_sa = NULL;
1684 this->mode = MODE_TUNNEL;
1685 this->ipcomp = IPCOMP_NONE;
1686 this->ipcomp_received = IPCOMP_NONE;
1687 this->other_cpi = 0;
1688 this->reqid = 0;
1689 this->mark_in = 0;
1690 this->mark_out = 0;
1691 this->established = FALSE;
1692 }
1693
1694 METHOD(task_t, destroy, void,
1695 private_child_create_t *this)
1696 {
1697 chunk_free(&this->my_nonce);
1698 chunk_free(&this->other_nonce);
1699 if (this->tsr)
1700 {
1701 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1702 }
1703 if (this->tsi)
1704 {
1705 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1706 }
1707 if (!this->established)
1708 {
1709 DESTROY_IF(this->child_sa);
1710 }
1711 DESTROY_IF(this->packet_tsi);
1712 DESTROY_IF(this->packet_tsr);
1713 DESTROY_IF(this->proposal);
1714 DESTROY_IF(this->dh);
1715 if (this->proposals)
1716 {
1717 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1718 }
1719 DESTROY_IF(this->config);
1720 DESTROY_IF(this->nonceg);
1721 free(this);
1722 }
1723
1724 /*
1725 * Described in header.
1726 */
1727 child_create_t *child_create_create(ike_sa_t *ike_sa,
1728 child_cfg_t *config, bool rekey,
1729 traffic_selector_t *tsi, traffic_selector_t *tsr)
1730 {
1731 private_child_create_t *this;
1732
1733 INIT(this,
1734 .public = {
1735 .get_child = _get_child,
1736 .set_config = _set_config,
1737 .get_lower_nonce = _get_lower_nonce,
1738 .use_reqid = _use_reqid,
1739 .use_marks = _use_marks,
1740 .task = {
1741 .get_type = _get_type,
1742 .migrate = _migrate,
1743 .destroy = _destroy,
1744 },
1745 },
1746 .ike_sa = ike_sa,
1747 .config = config,
1748 .packet_tsi = tsi ? tsi->clone(tsi) : NULL,
1749 .packet_tsr = tsr ? tsr->clone(tsr) : NULL,
1750 .dh_group = MODP_NONE,
1751 .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
1752 .mode = MODE_TUNNEL,
1753 .tfcv3 = TRUE,
1754 .ipcomp = IPCOMP_NONE,
1755 .ipcomp_received = IPCOMP_NONE,
1756 .rekey = rekey,
1757 .retry = FALSE,
1758 );
1759
1760 if (config)
1761 {
1762 this->public.task.build = _build_i;
1763 this->public.task.process = _process_i;
1764 this->initiator = TRUE;
1765 }
1766 else
1767 {
1768 this->public.task.build = _build_r;
1769 this->public.task.process = _process_r;
1770 this->initiator = FALSE;
1771 }
1772 return &this->public;
1773 }