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