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