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