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