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