Support multiple virtual IPs on peer_cfg and ike_sa classes
[strongswan.git] / src / libcharon / sa / ikev2 / tasks / child_create.c
1 /*
2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include "child_create.h"
19
20 #include <daemon.h>
21 #include <sa/ikev2/keymat_v2.h>
22 #include <crypto/diffie_hellman.h>
23 #include <credentials/certificates/x509.h>
24 #include <encoding/payloads/sa_payload.h>
25 #include <encoding/payloads/ke_payload.h>
26 #include <encoding/payloads/ts_payload.h>
27 #include <encoding/payloads/nonce_payload.h>
28 #include <encoding/payloads/notify_payload.h>
29 #include <processing/jobs/delete_ike_sa_job.h>
30 #include <processing/jobs/inactivity_job.h>
31
32
33 typedef struct private_child_create_t private_child_create_t;
34
35 /**
36 * Private members of a child_create_t task.
37 */
38 struct private_child_create_t {
39
40 /**
41 * Public methods and task_t interface.
42 */
43 child_create_t public;
44
45 /**
46 * Assigned IKE_SA.
47 */
48 ike_sa_t *ike_sa;
49
50 /**
51 * Are we the initiator?
52 */
53 bool initiator;
54
55 /**
56 * nonce chosen by us
57 */
58 chunk_t my_nonce;
59
60 /**
61 * nonce chosen by peer
62 */
63 chunk_t other_nonce;
64
65 /**
66 * config to create the CHILD_SA from
67 */
68 child_cfg_t *config;
69
70 /**
71 * list of proposal candidates
72 */
73 linked_list_t *proposals;
74
75 /**
76 * selected proposal to use for CHILD_SA
77 */
78 proposal_t *proposal;
79
80 /**
81 * traffic selectors for initiators side
82 */
83 linked_list_t *tsi;
84
85 /**
86 * traffic selectors for responders side
87 */
88 linked_list_t *tsr;
89
90 /**
91 * source of triggering packet
92 */
93 traffic_selector_t *packet_tsi;
94
95 /**
96 * destination of triggering packet
97 */
98 traffic_selector_t *packet_tsr;
99
100 /**
101 * optional diffie hellman exchange
102 */
103 diffie_hellman_t *dh;
104
105 /**
106 * group used for DH exchange
107 */
108 diffie_hellman_group_t dh_group;
109
110 /**
111 * IKE_SAs keymat
112 */
113 keymat_v2_t *keymat;
114
115 /**
116 * mode the new CHILD_SA uses (transport/tunnel/beet)
117 */
118 ipsec_mode_t mode;
119
120 /**
121 * peer accepts TFC padding for this SA
122 */
123 bool tfcv3;
124
125 /**
126 * IPComp transform to use
127 */
128 ipcomp_transform_t ipcomp;
129
130 /**
131 * IPComp transform proposed or accepted by the other peer
132 */
133 ipcomp_transform_t ipcomp_received;
134
135 /**
136 * Own allocated SPI
137 */
138 u_int32_t my_spi;
139
140 /**
141 * SPI received in proposal
142 */
143 u_int32_t other_spi;
144
145 /**
146 * Own allocated Compression Parameter Index (CPI)
147 */
148 u_int16_t my_cpi;
149
150 /**
151 * Other Compression Parameter Index (CPI), received via IPCOMP_SUPPORTED
152 */
153 u_int16_t other_cpi;
154
155 /**
156 * reqid to use if we are rekeying
157 */
158 u_int32_t reqid;
159
160 /**
161 * CHILD_SA which gets established
162 */
163 child_sa_t *child_sa;
164
165 /**
166 * successfully established the CHILD?
167 */
168 bool established;
169
170 /**
171 * whether the CHILD_SA rekeys an existing one
172 */
173 bool rekey;
174
175 /**
176 * whether we are retrying with another DH group
177 */
178 bool retry;
179 };
180
181 /**
182 * get the nonce from a message
183 */
184 static status_t get_nonce(message_t *message, chunk_t *nonce)
185 {
186 nonce_payload_t *payload;
187
188 payload = (nonce_payload_t*)message->get_payload(message, NONCE);
189 if (payload == NULL)
190 {
191 return FAILED;
192 }
193 *nonce = payload->get_nonce(payload);
194 return NEED_MORE;
195 }
196
197 /**
198 * generate a new nonce to include in a CREATE_CHILD_SA message
199 */
200 static status_t generate_nonce(private_child_create_t *this)
201 {
202 nonce_gen_t *nonceg;
203
204 nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
205 if (!nonceg)
206 {
207 DBG1(DBG_IKE, "no nonce generator found to create nonce");
208 return FAILED;
209 }
210 if (!nonceg->allocate_nonce(nonceg, NONCE_SIZE, &this->my_nonce))
211 {
212 DBG1(DBG_IKE, "nonce allocation failed");
213 nonceg->destroy(nonceg);
214 return FAILED;
215 }
216 nonceg->destroy(nonceg);
217
218 return SUCCESS;
219 }
220
221 /**
222 * Check a list of traffic selectors if any selector belongs to host
223 */
224 static bool ts_list_is_host(linked_list_t *list, host_t *host)
225 {
226 traffic_selector_t *ts;
227 bool is_host = TRUE;
228 enumerator_t *enumerator = list->create_enumerator(list);
229
230 while (is_host && enumerator->enumerate(enumerator, (void**)&ts))
231 {
232 is_host = is_host && ts->is_host(ts, host);
233 }
234 enumerator->destroy(enumerator);
235 return is_host;
236 }
237
238 /**
239 * Allocate SPIs and update proposals
240 */
241 static bool allocate_spi(private_child_create_t *this)
242 {
243 enumerator_t *enumerator;
244 proposal_t *proposal;
245
246 /* TODO: allocate additional SPI for AH if we have such proposals */
247 this->my_spi = this->child_sa->alloc_spi(this->child_sa, PROTO_ESP);
248 if (this->my_spi)
249 {
250 if (this->initiator)
251 {
252 enumerator = this->proposals->create_enumerator(this->proposals);
253 while (enumerator->enumerate(enumerator, &proposal))
254 {
255 proposal->set_spi(proposal, this->my_spi);
256 }
257 enumerator->destroy(enumerator);
258 }
259 else
260 {
261 this->proposal->set_spi(this->proposal, this->my_spi);
262 }
263 return TRUE;
264 }
265 return FALSE;
266 }
267
268 /**
269 * Schedule inactivity timeout for CHILD_SA with reqid, if enabled
270 */
271 static void schedule_inactivity_timeout(private_child_create_t *this)
272 {
273 u_int32_t timeout;
274 bool close_ike;
275
276 timeout = this->config->get_inactivity(this->config);
277 if (timeout)
278 {
279 close_ike = lib->settings->get_bool(lib->settings,
280 "%s.inactivity_close_ike", FALSE, charon->name);
281 lib->scheduler->schedule_job(lib->scheduler, (job_t*)
282 inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
283 timeout, close_ike), timeout);
284 }
285 }
286
287 /**
288 * Get host to use for dynamic traffic selectors
289 */
290 static host_t *get_dynamic_host(ike_sa_t *ike_sa, bool local)
291 {
292 enumerator_t *enumerator;
293 host_t *host;
294
295 enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, local);
296 if (!enumerator->enumerate(enumerator, &host))
297 {
298 if (local)
299 {
300 host = ike_sa->get_my_host(ike_sa);
301 }
302 else
303 {
304 host = ike_sa->get_other_host(ike_sa);
305 }
306 }
307 enumerator->destroy(enumerator);
308 return host;
309 }
310
311 /**
312 * Install a CHILD_SA for usage, return value:
313 * - FAILED: no acceptable proposal
314 * - INVALID_ARG: diffie hellman group inacceptable
315 * - NOT_FOUND: TS inacceptable
316 */
317 static status_t select_and_install(private_child_create_t *this,
318 bool no_dh, bool ike_auth)
319 {
320 status_t status, status_i, status_o;
321 chunk_t nonce_i, nonce_r;
322 chunk_t encr_i = chunk_empty, encr_r = chunk_empty;
323 chunk_t integ_i = chunk_empty, integ_r = chunk_empty;
324 linked_list_t *my_ts, *other_ts;
325 host_t *me, *other;
326 bool private;
327
328 if (this->proposals == NULL)
329 {
330 DBG1(DBG_IKE, "SA payload missing in message");
331 return FAILED;
332 }
333 if (this->tsi == NULL || this->tsr == NULL)
334 {
335 DBG1(DBG_IKE, "TS payloads missing in message");
336 return NOT_FOUND;
337 }
338
339 me = this->ike_sa->get_my_host(this->ike_sa);
340 other = this->ike_sa->get_other_host(this->ike_sa);
341
342 private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
343 this->proposal = this->config->select_proposal(this->config,
344 this->proposals, no_dh, private);
345 if (this->proposal == NULL)
346 {
347 DBG1(DBG_IKE, "no acceptable proposal found");
348 return FAILED;
349 }
350 this->other_spi = this->proposal->get_spi(this->proposal);
351
352 if (!this->initiator && !allocate_spi(this))
353 { /* responder has no SPI allocated yet */
354 DBG1(DBG_IKE, "allocating SPI failed");
355 return FAILED;
356 }
357 this->child_sa->set_proposal(this->child_sa, this->proposal);
358
359 if (!this->proposal->has_dh_group(this->proposal, this->dh_group))
360 {
361 u_int16_t group;
362
363 if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
364 &group, NULL))
365 {
366 DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N",
367 diffie_hellman_group_names, this->dh_group,
368 diffie_hellman_group_names, group);
369 this->dh_group = group;
370 return INVALID_ARG;
371 }
372 /* the selected proposal does not use a DH group */
373 DBG1(DBG_IKE, "ignoring KE exchange, agreed on a non-PFS proposal");
374 DESTROY_IF(this->dh);
375 this->dh = NULL;
376 this->dh_group = MODP_NONE;
377 }
378
379 if (this->initiator)
380 {
381 nonce_i = this->my_nonce;
382 nonce_r = this->other_nonce;
383 my_ts = this->tsi;
384 other_ts = this->tsr;
385 }
386 else
387 {
388 nonce_r = this->my_nonce;
389 nonce_i = this->other_nonce;
390 my_ts = this->tsr;
391 other_ts = this->tsi;
392 }
393 my_ts = this->config->get_traffic_selectors(this->config, TRUE, my_ts,
394 get_dynamic_host(this->ike_sa, TRUE));
395 other_ts = this->config->get_traffic_selectors(this->config, FALSE, other_ts,
396 get_dynamic_host(this->ike_sa, FALSE));
397
398 if (this->initiator)
399 {
400 if (ike_auth)
401 {
402 charon->bus->narrow(charon->bus, this->child_sa,
403 NARROW_INITIATOR_POST_NOAUTH, my_ts, other_ts);
404 }
405 else
406 {
407 charon->bus->narrow(charon->bus, this->child_sa,
408 NARROW_INITIATOR_POST_AUTH, my_ts, other_ts);
409 }
410 }
411 else
412 {
413 charon->bus->narrow(charon->bus, this->child_sa,
414 NARROW_RESPONDER, my_ts, other_ts);
415 }
416
417 if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0)
418 {
419 my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
420 other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
421 DBG1(DBG_IKE, "no acceptable traffic selectors found");
422 return NOT_FOUND;
423 }
424
425 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
426 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
427 if (this->initiator)
428 {
429 this->tsi = my_ts;
430 this->tsr = other_ts;
431 }
432 else
433 {
434 this->tsr = my_ts;
435 this->tsi = other_ts;
436 }
437
438 if (!this->initiator)
439 {
440 /* check if requested mode is acceptable, downgrade if required */
441 switch (this->mode)
442 {
443 case MODE_TRANSPORT:
444 if (!this->config->use_proxy_mode(this->config) &&
445 (!ts_list_is_host(this->tsi, other) ||
446 !ts_list_is_host(this->tsr, me))
447 )
448 {
449 this->mode = MODE_TUNNEL;
450 DBG1(DBG_IKE, "not using transport mode, not host-to-host");
451 }
452 else if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
453 {
454 this->mode = MODE_TUNNEL;
455 DBG1(DBG_IKE, "not using transport mode, connection NATed");
456 }
457 break;
458 case MODE_BEET:
459 if (!ts_list_is_host(this->tsi, NULL) ||
460 !ts_list_is_host(this->tsr, NULL))
461 {
462 this->mode = MODE_TUNNEL;
463 DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
464 }
465 break;
466 default:
467 break;
468 }
469 }
470
471 this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
472 this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
473 this->child_sa->set_mode(this->child_sa, this->mode);
474 this->child_sa->set_protocol(this->child_sa,
475 this->proposal->get_protocol(this->proposal));
476
477 if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
478 {
479 this->my_cpi = this->other_cpi = 0;
480 this->ipcomp = IPCOMP_NONE;
481 }
482 status_i = status_o = FAILED;
483 if (this->keymat->derive_child_keys(this->keymat, this->proposal,
484 this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
485 {
486 if (this->initiator)
487 {
488 status_i = this->child_sa->install(this->child_sa,
489 encr_r, integ_r, this->my_spi, this->my_cpi,
490 TRUE, this->tfcv3, my_ts, other_ts);
491 status_o = this->child_sa->install(this->child_sa,
492 encr_i, integ_i, this->other_spi, this->other_cpi,
493 FALSE, this->tfcv3, my_ts, other_ts);
494 }
495 else
496 {
497 status_i = this->child_sa->install(this->child_sa,
498 encr_i, integ_i, this->my_spi, this->my_cpi,
499 TRUE, this->tfcv3, my_ts, other_ts);
500 status_o = this->child_sa->install(this->child_sa,
501 encr_r, integ_r, this->other_spi, this->other_cpi,
502 FALSE, this->tfcv3, my_ts, other_ts);
503 }
504 }
505 chunk_clear(&integ_i);
506 chunk_clear(&integ_r);
507 chunk_clear(&encr_i);
508 chunk_clear(&encr_r);
509
510 if (status_i != SUCCESS || status_o != SUCCESS)
511 {
512 DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
513 (status_i != SUCCESS) ? "inbound " : "",
514 (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
515 (status_o != SUCCESS) ? "outbound " : "");
516 return FAILED;
517 }
518
519 status = this->child_sa->add_policies(this->child_sa, my_ts, other_ts);
520 if (status != SUCCESS)
521 {
522 DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
523 return NOT_FOUND;
524 }
525
526 charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
527 this->dh, nonce_i, nonce_r);
528
529 /* add to IKE_SA, and remove from task */
530 this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
531 this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
532 this->established = TRUE;
533
534 if (!this->rekey)
535 { /* a rekeyed SA uses the same reqid, no need for a new job */
536 schedule_inactivity_timeout(this);
537 }
538 return SUCCESS;
539 }
540
541 /**
542 * build the payloads for the message
543 */
544 static void build_payloads(private_child_create_t *this, message_t *message)
545 {
546 sa_payload_t *sa_payload;
547 nonce_payload_t *nonce_payload;
548 ke_payload_t *ke_payload;
549 ts_payload_t *ts_payload;
550
551 /* add SA payload */
552 if (this->initiator)
553 {
554 sa_payload = sa_payload_create_from_proposals_v2(this->proposals);
555 }
556 else
557 {
558 sa_payload = sa_payload_create_from_proposal_v2(this->proposal);
559 }
560 message->add_payload(message, (payload_t*)sa_payload);
561
562 /* add nonce payload if not in IKE_AUTH */
563 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
564 {
565 nonce_payload = nonce_payload_create(NONCE);
566 nonce_payload->set_nonce(nonce_payload, this->my_nonce);
567 message->add_payload(message, (payload_t*)nonce_payload);
568 }
569
570 /* diffie hellman exchange, if PFS enabled */
571 if (this->dh)
572 {
573 ke_payload = ke_payload_create_from_diffie_hellman(KEY_EXCHANGE,
574 this->dh);
575 message->add_payload(message, (payload_t*)ke_payload);
576 }
577
578 /* add TSi/TSr payloads */
579 ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
580 message->add_payload(message, (payload_t*)ts_payload);
581 ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
582 message->add_payload(message, (payload_t*)ts_payload);
583
584 /* add a notify if we are not in tunnel mode */
585 switch (this->mode)
586 {
587 case MODE_TRANSPORT:
588 message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
589 break;
590 case MODE_BEET:
591 message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
592 break;
593 default:
594 break;
595 }
596 }
597
598 /**
599 * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
600 */
601 static void add_ipcomp_notify(private_child_create_t *this,
602 message_t *message, u_int8_t ipcomp)
603 {
604 if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
605 {
606 DBG1(DBG_IKE, "IPComp is not supported if either peer is natted, "
607 "IPComp disabled");
608 return;
609 }
610
611 this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
612 if (this->my_cpi)
613 {
614 this->ipcomp = ipcomp;
615 message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
616 chunk_cata("cc", chunk_from_thing(this->my_cpi),
617 chunk_from_thing(ipcomp)));
618 }
619 else
620 {
621 DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
622 }
623 }
624
625 /**
626 * handle a received notify payload
627 */
628 static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
629 {
630 switch (notify->get_notify_type(notify))
631 {
632 case USE_TRANSPORT_MODE:
633 this->mode = MODE_TRANSPORT;
634 break;
635 case USE_BEET_MODE:
636 if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN))
637 { /* handle private use notify only if we know its meaning */
638 this->mode = MODE_BEET;
639 }
640 else
641 {
642 DBG1(DBG_IKE, "received a notify strongSwan uses for BEET "
643 "mode, but peer implementation unknown, skipped");
644 }
645 break;
646 case IPCOMP_SUPPORTED:
647 {
648 ipcomp_transform_t ipcomp;
649 u_int16_t cpi;
650 chunk_t data;
651
652 data = notify->get_notification_data(notify);
653 cpi = *(u_int16_t*)data.ptr;
654 ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
655 switch (ipcomp)
656 {
657 case IPCOMP_DEFLATE:
658 this->other_cpi = cpi;
659 this->ipcomp_received = ipcomp;
660 break;
661 case IPCOMP_LZS:
662 case IPCOMP_LZJH:
663 default:
664 DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
665 "transform ID we don't support %N",
666 ipcomp_transform_names, ipcomp);
667 break;
668 }
669 break;
670 }
671 case ESP_TFC_PADDING_NOT_SUPPORTED:
672 DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding",
673 notify_type_names, notify->get_notify_type(notify));
674 this->tfcv3 = FALSE;
675 break;
676 default:
677 break;
678 }
679 }
680
681 /**
682 * Read payloads from message
683 */
684 static void process_payloads(private_child_create_t *this, message_t *message)
685 {
686 enumerator_t *enumerator;
687 payload_t *payload;
688 sa_payload_t *sa_payload;
689 ke_payload_t *ke_payload;
690 ts_payload_t *ts_payload;
691
692 /* defaults to TUNNEL mode */
693 this->mode = MODE_TUNNEL;
694
695 enumerator = message->create_payload_enumerator(message);
696 while (enumerator->enumerate(enumerator, &payload))
697 {
698 switch (payload->get_type(payload))
699 {
700 case SECURITY_ASSOCIATION:
701 sa_payload = (sa_payload_t*)payload;
702 this->proposals = sa_payload->get_proposals(sa_payload);
703 break;
704 case KEY_EXCHANGE:
705 ke_payload = (ke_payload_t*)payload;
706 if (!this->initiator)
707 {
708 this->dh_group = ke_payload->get_dh_group_number(ke_payload);
709 this->dh = this->keymat->keymat.create_dh(
710 &this->keymat->keymat, this->dh_group);
711 }
712 if (this->dh)
713 {
714 this->dh->set_other_public_value(this->dh,
715 ke_payload->get_key_exchange_data(ke_payload));
716 }
717 break;
718 case TRAFFIC_SELECTOR_INITIATOR:
719 ts_payload = (ts_payload_t*)payload;
720 this->tsi = ts_payload->get_traffic_selectors(ts_payload);
721 break;
722 case TRAFFIC_SELECTOR_RESPONDER:
723 ts_payload = (ts_payload_t*)payload;
724 this->tsr = ts_payload->get_traffic_selectors(ts_payload);
725 break;
726 case NOTIFY:
727 handle_notify(this, (notify_payload_t*)payload);
728 break;
729 default:
730 break;
731 }
732 }
733 enumerator->destroy(enumerator);
734 }
735
736 METHOD(task_t, build_i, status_t,
737 private_child_create_t *this, message_t *message)
738 {
739 enumerator_t *enumerator;
740 host_t *vip;
741 peer_cfg_t *peer_cfg;
742
743 switch (message->get_exchange_type(message))
744 {
745 case IKE_SA_INIT:
746 return get_nonce(message, &this->my_nonce);
747 case CREATE_CHILD_SA:
748 if (generate_nonce(this) != SUCCESS)
749 {
750 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
751 return SUCCESS;
752 }
753 if (!this->retry)
754 {
755 this->dh_group = this->config->get_dh_group(this->config);
756 }
757 break;
758 case IKE_AUTH:
759 if (message->get_message_id(message) != 1)
760 {
761 /* send only in the first request, not in subsequent rounds */
762 return NEED_MORE;
763 }
764 break;
765 default:
766 break;
767 }
768
769 if (this->reqid)
770 {
771 DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
772 this->config->get_name(this->config), this->reqid);
773 }
774 else
775 {
776 DBG0(DBG_IKE, "establishing CHILD_SA %s",
777 this->config->get_name(this->config));
778 }
779
780 /* check if we want a virtual IP, but don't have one */
781 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
782 enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
783 if (!this->reqid && enumerator->enumerate(enumerator, &vip))
784 {
785 /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
786 vip = host_create_any(vip->get_family(vip));
787 this->tsi = this->config->get_traffic_selectors(this->config, TRUE,
788 NULL, vip);
789 vip->destroy(vip);
790 }
791 else
792 { /* but narrow it for host2host / if we already have a vip */
793 this->tsi = this->config->get_traffic_selectors(this->config, TRUE, NULL,
794 get_dynamic_host(this->ike_sa, TRUE));
795 }
796 enumerator->destroy(enumerator);
797 this->tsr = this->config->get_traffic_selectors(this->config, FALSE, NULL,
798 get_dynamic_host(this->ike_sa, FALSE));
799
800 if (this->packet_tsi)
801 {
802 this->tsi->insert_first(this->tsi,
803 this->packet_tsi->clone(this->packet_tsi));
804 }
805 if (this->packet_tsr)
806 {
807 this->tsr->insert_first(this->tsr,
808 this->packet_tsr->clone(this->packet_tsr));
809 }
810 this->proposals = this->config->get_proposals(this->config,
811 this->dh_group == MODP_NONE);
812 this->mode = this->config->get_mode(this->config);
813 if (this->mode == MODE_TRANSPORT &&
814 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY))
815 {
816 this->mode = MODE_TUNNEL;
817 DBG1(DBG_IKE, "not using transport mode, connection NATed");
818 }
819
820 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
821 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
822 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
823
824 if (!allocate_spi(this))
825 {
826 DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
827 return FAILED;
828 }
829
830 if (this->dh_group != MODP_NONE)
831 {
832 this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
833 this->dh_group);
834 }
835
836 if (this->config->use_ipcomp(this->config))
837 {
838 /* IPCOMP_DEFLATE is the only transform we support at the moment */
839 add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
840 }
841
842 if (message->get_exchange_type(message) == IKE_AUTH)
843 {
844 charon->bus->narrow(charon->bus, this->child_sa,
845 NARROW_INITIATOR_PRE_NOAUTH, this->tsi, this->tsr);
846 }
847 else
848 {
849 charon->bus->narrow(charon->bus, this->child_sa,
850 NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
851 }
852
853 build_payloads(this, message);
854
855 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
856 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
857 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
858 this->tsi = NULL;
859 this->tsr = NULL;
860 this->proposals = NULL;
861
862 return NEED_MORE;
863 }
864
865 METHOD(task_t, process_r, status_t,
866 private_child_create_t *this, message_t *message)
867 {
868 switch (message->get_exchange_type(message))
869 {
870 case IKE_SA_INIT:
871 return get_nonce(message, &this->other_nonce);
872 case CREATE_CHILD_SA:
873 get_nonce(message, &this->other_nonce);
874 break;
875 case IKE_AUTH:
876 if (message->get_message_id(message) != 1)
877 {
878 /* only handle first AUTH payload, not additional rounds */
879 return NEED_MORE;
880 }
881 default:
882 break;
883 }
884
885 process_payloads(this, message);
886
887 return NEED_MORE;
888 }
889
890 /**
891 * handle CHILD_SA setup failure
892 */
893 static void handle_child_sa_failure(private_child_create_t *this,
894 message_t *message)
895 {
896 if (message->get_exchange_type(message) == IKE_AUTH &&
897 lib->settings->get_bool(lib->settings,
898 "%s.close_ike_on_child_failure", FALSE, charon->name))
899 {
900 /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
901 * first */
902 DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
903 lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
904 delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
905 100);
906 }
907 else
908 {
909 DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
910 }
911 }
912
913 METHOD(task_t, build_r, status_t,
914 private_child_create_t *this, message_t *message)
915 {
916 peer_cfg_t *peer_cfg;
917 payload_t *payload;
918 enumerator_t *enumerator;
919 bool no_dh = TRUE, ike_auth = FALSE;
920
921 switch (message->get_exchange_type(message))
922 {
923 case IKE_SA_INIT:
924 return get_nonce(message, &this->my_nonce);
925 case CREATE_CHILD_SA:
926 if (generate_nonce(this) != SUCCESS)
927 {
928 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
929 chunk_empty);
930 return SUCCESS;
931 }
932 no_dh = FALSE;
933 break;
934 case IKE_AUTH:
935 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
936 { /* wait until all authentication round completed */
937 return NEED_MORE;
938 }
939 ike_auth = TRUE;
940 default:
941 break;
942 }
943
944 if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
945 {
946 DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA");
947 message->add_notify(message, TRUE, NO_ADDITIONAL_SAS, chunk_empty);
948 return SUCCESS;
949 }
950
951 peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
952 if (!this->config && peer_cfg && this->tsi && this->tsr)
953 {
954 this->config = peer_cfg->select_child_cfg(peer_cfg,
955 this->tsr, this->tsi,
956 get_dynamic_host(this->ike_sa, TRUE),
957 get_dynamic_host(this->ike_sa, FALSE));
958 }
959
960 if (this->config == NULL)
961 {
962 DBG1(DBG_IKE, "traffic selectors %#R=== %#R inacceptable",
963 this->tsr, this->tsi);
964 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
965 handle_child_sa_failure(this, message);
966 return SUCCESS;
967 }
968
969 /* check if ike_config_t included non-critical error notifies */
970 enumerator = message->create_payload_enumerator(message);
971 while (enumerator->enumerate(enumerator, &payload))
972 {
973 if (payload->get_type(payload) == NOTIFY)
974 {
975 notify_payload_t *notify = (notify_payload_t*)payload;
976
977 switch (notify->get_notify_type(notify))
978 {
979 case INTERNAL_ADDRESS_FAILURE:
980 case FAILED_CP_REQUIRED:
981 {
982 DBG1(DBG_IKE,"configuration payload negotiation "
983 "failed, no CHILD_SA built");
984 enumerator->destroy(enumerator);
985 handle_child_sa_failure(this, message);
986 return SUCCESS;
987 }
988 default:
989 break;
990 }
991 }
992 }
993 enumerator->destroy(enumerator);
994
995 this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
996 this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
997 this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY));
998
999 if (this->ipcomp_received != IPCOMP_NONE)
1000 {
1001 if (this->config->use_ipcomp(this->config))
1002 {
1003 add_ipcomp_notify(this, message, this->ipcomp_received);
1004 }
1005 else
1006 {
1007 DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
1008 notify_type_names, IPCOMP_SUPPORTED);
1009 }
1010 }
1011
1012 switch (select_and_install(this, no_dh, ike_auth))
1013 {
1014 case SUCCESS:
1015 break;
1016 case NOT_FOUND:
1017 message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1018 handle_child_sa_failure(this, message);
1019 return SUCCESS;
1020 case INVALID_ARG:
1021 {
1022 u_int16_t group = htons(this->dh_group);
1023 message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
1024 chunk_from_thing(group));
1025 handle_child_sa_failure(this, message);
1026 return SUCCESS;
1027 }
1028 case FAILED:
1029 default:
1030 message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1031 handle_child_sa_failure(this, message);
1032 return SUCCESS;
1033 }
1034
1035 build_payloads(this, message);
1036
1037 DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
1038 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
1039 this->child_sa->get_name(this->child_sa),
1040 this->child_sa->get_reqid(this->child_sa),
1041 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
1042 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
1043 this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
1044 this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
1045
1046 if (!this->rekey)
1047 { /* invoke the child_up() hook if we are not rekeying */
1048 charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1049 }
1050 return SUCCESS;
1051 }
1052
1053 METHOD(task_t, process_i, status_t,
1054 private_child_create_t *this, message_t *message)
1055 {
1056 enumerator_t *enumerator;
1057 payload_t *payload;
1058 bool no_dh = TRUE, ike_auth = FALSE;
1059
1060 switch (message->get_exchange_type(message))
1061 {
1062 case IKE_SA_INIT:
1063 return get_nonce(message, &this->other_nonce);
1064 case CREATE_CHILD_SA:
1065 get_nonce(message, &this->other_nonce);
1066 no_dh = FALSE;
1067 break;
1068 case IKE_AUTH:
1069 if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1070 { /* wait until all authentication round completed */
1071 return NEED_MORE;
1072 }
1073 ike_auth = TRUE;
1074 default:
1075 break;
1076 }
1077
1078 /* check for erronous notifies */
1079 enumerator = message->create_payload_enumerator(message);
1080 while (enumerator->enumerate(enumerator, &payload))
1081 {
1082 if (payload->get_type(payload) == NOTIFY)
1083 {
1084 notify_payload_t *notify = (notify_payload_t*)payload;
1085 notify_type_t type = notify->get_notify_type(notify);
1086
1087 switch (type)
1088 {
1089 /* handle notify errors related to CHILD_SA only */
1090 case NO_PROPOSAL_CHOSEN:
1091 case SINGLE_PAIR_REQUIRED:
1092 case NO_ADDITIONAL_SAS:
1093 case INTERNAL_ADDRESS_FAILURE:
1094 case FAILED_CP_REQUIRED:
1095 case TS_UNACCEPTABLE:
1096 case INVALID_SELECTORS:
1097 {
1098 DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
1099 notify_type_names, type);
1100 enumerator->destroy(enumerator);
1101 handle_child_sa_failure(this, message);
1102 /* an error in CHILD_SA creation is not critical */
1103 return SUCCESS;
1104 }
1105 case INVALID_KE_PAYLOAD:
1106 {
1107 chunk_t data;
1108 u_int16_t group = MODP_NONE;
1109
1110 data = notify->get_notification_data(notify);
1111 if (data.len == sizeof(group))
1112 {
1113 memcpy(&group, data.ptr, data.len);
1114 group = ntohs(group);
1115 }
1116 DBG1(DBG_IKE, "peer didn't accept DH group %N, "
1117 "it requested %N", diffie_hellman_group_names,
1118 this->dh_group, diffie_hellman_group_names, group);
1119 this->retry = TRUE;
1120 this->dh_group = group;
1121 this->public.task.migrate(&this->public.task, this->ike_sa);
1122 enumerator->destroy(enumerator);
1123 return NEED_MORE;
1124 }
1125 default:
1126 {
1127 if (message->get_exchange_type(message) == CREATE_CHILD_SA)
1128 { /* handle notifies if not handled in IKE_AUTH */
1129 if (type <= 16383)
1130 {
1131 DBG1(DBG_IKE, "received %N notify error",
1132 notify_type_names, type);
1133 enumerator->destroy(enumerator);
1134 return SUCCESS;
1135 }
1136 DBG2(DBG_IKE, "received %N notify",
1137 notify_type_names, type);
1138 }
1139 break;
1140 }
1141 }
1142 }
1143 }
1144 enumerator->destroy(enumerator);
1145
1146 process_payloads(this, message);
1147
1148 if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
1149 {
1150 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting"
1151 " one, no CHILD_SA built");
1152 handle_child_sa_failure(this, message);
1153 return SUCCESS;
1154 }
1155 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
1156 {
1157 DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
1158 "IPComp is disabled");
1159 this->ipcomp = IPCOMP_NONE;
1160 }
1161 else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
1162 {
1163 DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1164 "no CHILD_SA built");
1165 handle_child_sa_failure(this, message);
1166 return SUCCESS;
1167 }
1168
1169 if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
1170 {
1171 DBG0(DBG_IKE, "CHILD_SA %s{%d} established "
1172 "with SPIs %.8x_i %.8x_o and TS %#R=== %#R",
1173 this->child_sa->get_name(this->child_sa),
1174 this->child_sa->get_reqid(this->child_sa),
1175 ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
1176 ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
1177 this->child_sa->get_traffic_selectors(this->child_sa, TRUE),
1178 this->child_sa->get_traffic_selectors(this->child_sa, FALSE));
1179
1180 if (!this->rekey)
1181 { /* invoke the child_up() hook if we are not rekeying */
1182 charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1183 }
1184 }
1185 else
1186 {
1187 handle_child_sa_failure(this, message);
1188 }
1189 return SUCCESS;
1190 }
1191
1192 METHOD(child_create_t, use_reqid, void,
1193 private_child_create_t *this, u_int32_t reqid)
1194 {
1195 this->reqid = reqid;
1196 }
1197
1198 METHOD(child_create_t, get_child, child_sa_t*,
1199 private_child_create_t *this)
1200 {
1201 return this->child_sa;
1202 }
1203
1204 METHOD(child_create_t, set_config, void,
1205 private_child_create_t *this, child_cfg_t *cfg)
1206 {
1207 DESTROY_IF(this->config);
1208 this->config = cfg;
1209 }
1210
1211 METHOD(child_create_t, get_lower_nonce, chunk_t,
1212 private_child_create_t *this)
1213 {
1214 if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
1215 min(this->my_nonce.len, this->other_nonce.len)) < 0)
1216 {
1217 return this->my_nonce;
1218 }
1219 else
1220 {
1221 return this->other_nonce;
1222 }
1223 }
1224
1225 METHOD(task_t, get_type, task_type_t,
1226 private_child_create_t *this)
1227 {
1228 return TASK_CHILD_CREATE;
1229 }
1230
1231 METHOD(task_t, migrate, void,
1232 private_child_create_t *this, ike_sa_t *ike_sa)
1233 {
1234 chunk_free(&this->my_nonce);
1235 chunk_free(&this->other_nonce);
1236 if (this->tsr)
1237 {
1238 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1239 }
1240 if (this->tsi)
1241 {
1242 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1243 }
1244 DESTROY_IF(this->child_sa);
1245 DESTROY_IF(this->proposal);
1246 DESTROY_IF(this->dh);
1247 if (this->proposals)
1248 {
1249 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1250 }
1251
1252 this->ike_sa = ike_sa;
1253 this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
1254 this->proposal = NULL;
1255 this->proposals = NULL;
1256 this->tsi = NULL;
1257 this->tsr = NULL;
1258 this->dh = NULL;
1259 this->child_sa = NULL;
1260 this->mode = MODE_TUNNEL;
1261 this->ipcomp = IPCOMP_NONE;
1262 this->ipcomp_received = IPCOMP_NONE;
1263 this->other_cpi = 0;
1264 this->reqid = 0;
1265 this->established = FALSE;
1266 }
1267
1268 METHOD(task_t, destroy, void,
1269 private_child_create_t *this)
1270 {
1271 chunk_free(&this->my_nonce);
1272 chunk_free(&this->other_nonce);
1273 if (this->tsr)
1274 {
1275 this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1276 }
1277 if (this->tsi)
1278 {
1279 this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1280 }
1281 if (!this->established)
1282 {
1283 DESTROY_IF(this->child_sa);
1284 }
1285 DESTROY_IF(this->packet_tsi);
1286 DESTROY_IF(this->packet_tsr);
1287 DESTROY_IF(this->proposal);
1288 DESTROY_IF(this->dh);
1289 if (this->proposals)
1290 {
1291 this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1292 }
1293
1294 DESTROY_IF(this->config);
1295 free(this);
1296 }
1297
1298 /*
1299 * Described in header.
1300 */
1301 child_create_t *child_create_create(ike_sa_t *ike_sa,
1302 child_cfg_t *config, bool rekey,
1303 traffic_selector_t *tsi, traffic_selector_t *tsr)
1304 {
1305 private_child_create_t *this;
1306
1307 INIT(this,
1308 .public = {
1309 .get_child = _get_child,
1310 .set_config = _set_config,
1311 .get_lower_nonce = _get_lower_nonce,
1312 .use_reqid = _use_reqid,
1313 .task = {
1314 .get_type = _get_type,
1315 .migrate = _migrate,
1316 .destroy = _destroy,
1317 },
1318 },
1319 .ike_sa = ike_sa,
1320 .config = config,
1321 .packet_tsi = tsi ? tsi->clone(tsi) : NULL,
1322 .packet_tsr = tsr ? tsr->clone(tsr) : NULL,
1323 .dh_group = MODP_NONE,
1324 .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
1325 .mode = MODE_TUNNEL,
1326 .tfcv3 = TRUE,
1327 .ipcomp = IPCOMP_NONE,
1328 .ipcomp_received = IPCOMP_NONE,
1329 .rekey = rekey,
1330 .retry = FALSE,
1331 );
1332
1333 if (config)
1334 {
1335 this->public.task.build = _build_i;
1336 this->public.task.process = _process_i;
1337 this->initiator = TRUE;
1338 }
1339 else
1340 {
1341 this->public.task.build = _build_r;
1342 this->public.task.process = _process_r;
1343 this->initiator = FALSE;
1344 }
1345
1346 return &this->public;
1347 }