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