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