Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/tasks/child_create.c, revision 1.1.1.1
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:
710: this->child_sa->set_policies(this->child_sa, my_ts, other_ts);
711: if (!this->initiator)
712: {
713: my_ts->destroy_offset(my_ts,
714: offsetof(traffic_selector_t, destroy));
715: other_ts->destroy_offset(other_ts,
716: offsetof(traffic_selector_t, destroy));
717: }
718:
719: this->child_sa->set_state(this->child_sa, CHILD_INSTALLING);
720: this->child_sa->set_ipcomp(this->child_sa, this->ipcomp);
721: this->child_sa->set_mode(this->child_sa, this->mode);
722: this->child_sa->set_protocol(this->child_sa,
723: this->proposal->get_protocol(this->proposal));
724:
725: if (this->my_cpi == 0 || this->other_cpi == 0 || this->ipcomp == IPCOMP_NONE)
726: {
727: this->my_cpi = this->other_cpi = 0;
728: this->ipcomp = IPCOMP_NONE;
729: }
730: status_i = status_o = FAILED;
731: if (this->keymat->derive_child_keys(this->keymat, this->proposal,
732: this->dh, nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r))
733: {
734: if (this->initiator)
735: {
736: status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
737: this->my_spi, this->my_cpi, this->initiator,
738: TRUE, this->tfcv3);
739: }
740: else
741: {
742: status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
743: this->my_spi, this->my_cpi, this->initiator,
744: TRUE, this->tfcv3);
745: }
746: if (this->rekey)
747: { /* during rekeyings we install the outbound SA and/or policies
748: * separately: as responder when we receive the delete for the old
749: * SA, as initiator pretty much immediately in the ike-rekey task,
750: * unless there was a rekey collision that we lost */
751: if (this->initiator)
752: {
753: status_o = this->child_sa->register_outbound(this->child_sa,
754: encr_i, integ_i, this->other_spi, this->other_cpi,
755: this->tfcv3);
756: }
757: else
758: {
759: status_o = this->child_sa->register_outbound(this->child_sa,
760: encr_r, integ_r, this->other_spi, this->other_cpi,
761: this->tfcv3);
762: }
763: }
764: else if (this->initiator)
765: {
766: status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
767: this->other_spi, this->other_cpi, this->initiator,
768: FALSE, this->tfcv3);
769: }
770: else
771: {
772: status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
773: this->other_spi, this->other_cpi, this->initiator,
774: FALSE, this->tfcv3);
775: }
776: }
777:
778: if (status_i != SUCCESS || status_o != SUCCESS)
779: {
780: DBG1(DBG_IKE, "unable to install %s%s%sIPsec SA (SAD) in kernel",
781: (status_i != SUCCESS) ? "inbound " : "",
782: (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "",
783: (status_o != SUCCESS) ? "outbound " : "");
784: charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED,
785: this->child_sa);
786: status = FAILED;
787: }
788: else
789: {
790: status = this->child_sa->install_policies(this->child_sa);
791:
792: if (status != SUCCESS)
793: {
794: DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel");
795: charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_POLICY_FAILED,
796: this->child_sa);
797: status = NOT_FOUND;
798: }
799: else
800: {
801: charon->bus->child_derived_keys(charon->bus, this->child_sa,
802: this->initiator, encr_i, encr_r,
803: integ_i, integ_r);
804: }
805: }
806: chunk_clear(&integ_i);
807: chunk_clear(&integ_r);
808: chunk_clear(&encr_i);
809: chunk_clear(&encr_r);
810:
811: if (status != SUCCESS)
812: {
813: return status;
814: }
815:
816: charon->bus->child_keys(charon->bus, this->child_sa, this->initiator,
817: this->dh, nonce_i, nonce_r);
818:
819: my_ts = linked_list_create_from_enumerator(
820: this->child_sa->create_ts_enumerator(this->child_sa, TRUE));
821: other_ts = linked_list_create_from_enumerator(
822: this->child_sa->create_ts_enumerator(this->child_sa, FALSE));
823: out_state = this->child_sa->get_outbound_state(this->child_sa);
824:
825: DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established "
826: "with SPIs %.8x_i %.8x_o and TS %#R === %#R",
827: (out_state == CHILD_OUTBOUND_INSTALLED) ? "" : "inbound ",
828: this->child_sa->get_name(this->child_sa),
829: this->child_sa->get_unique_id(this->child_sa),
830: ntohl(this->child_sa->get_spi(this->child_sa, TRUE)),
831: ntohl(this->child_sa->get_spi(this->child_sa, FALSE)),
832: my_ts, other_ts);
833:
834: my_ts->destroy(my_ts);
835: other_ts->destroy(other_ts);
836:
837: this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
838: this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
839: this->established = TRUE;
840:
841: schedule_inactivity_timeout(this);
842: return SUCCESS;
843: }
844:
845: /**
846: * build the payloads for the message
847: */
848: static bool build_payloads(private_child_create_t *this, message_t *message)
849: {
850: sa_payload_t *sa_payload;
851: nonce_payload_t *nonce_payload;
852: ke_payload_t *ke_payload;
853: ts_payload_t *ts_payload;
854: kernel_feature_t features;
855:
856: /* add SA payload */
857: if (this->initiator)
858: {
859: sa_payload = sa_payload_create_from_proposals_v2(this->proposals);
860: }
861: else
862: {
863: sa_payload = sa_payload_create_from_proposal_v2(this->proposal);
864: }
865: message->add_payload(message, (payload_t*)sa_payload);
866:
867: /* add nonce payload if not in IKE_AUTH */
868: if (message->get_exchange_type(message) == CREATE_CHILD_SA)
869: {
870: nonce_payload = nonce_payload_create(PLV2_NONCE);
871: nonce_payload->set_nonce(nonce_payload, this->my_nonce);
872: message->add_payload(message, (payload_t*)nonce_payload);
873: }
874:
875: /* diffie hellman exchange, if PFS enabled */
876: if (this->dh)
877: {
878: ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
879: this->dh);
880: if (!ke_payload)
881: {
882: DBG1(DBG_IKE, "creating KE payload failed");
883: return FALSE;
884: }
885: message->add_payload(message, (payload_t*)ke_payload);
886: }
887:
888: /* add TSi/TSr payloads */
889: ts_payload = ts_payload_create_from_traffic_selectors(TRUE, this->tsi);
890: message->add_payload(message, (payload_t*)ts_payload);
891: ts_payload = ts_payload_create_from_traffic_selectors(FALSE, this->tsr);
892: message->add_payload(message, (payload_t*)ts_payload);
893:
894: /* add a notify if we are not in tunnel mode */
895: switch (this->mode)
896: {
897: case MODE_TRANSPORT:
898: message->add_notify(message, FALSE, USE_TRANSPORT_MODE, chunk_empty);
899: break;
900: case MODE_BEET:
901: message->add_notify(message, FALSE, USE_BEET_MODE, chunk_empty);
902: break;
903: default:
904: break;
905: }
906:
907: features = charon->kernel->get_features(charon->kernel);
908: if (!(features & KERNEL_ESP_V3_TFC))
909: {
910: message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED,
911: chunk_empty);
912: }
913: return TRUE;
914: }
915:
916: /**
917: * Adds an IPCOMP_SUPPORTED notify to the message, allocating a CPI
918: */
919: static void add_ipcomp_notify(private_child_create_t *this,
920: message_t *message, uint8_t ipcomp)
921: {
922: this->my_cpi = this->child_sa->alloc_cpi(this->child_sa);
923: if (this->my_cpi)
924: {
925: this->ipcomp = ipcomp;
926: message->add_notify(message, FALSE, IPCOMP_SUPPORTED,
927: chunk_cata("cc", chunk_from_thing(this->my_cpi),
928: chunk_from_thing(ipcomp)));
929: }
930: else
931: {
932: DBG1(DBG_IKE, "unable to allocate a CPI from kernel, IPComp disabled");
933: }
934: }
935:
936: /**
937: * handle a received notify payload
938: */
939: static void handle_notify(private_child_create_t *this, notify_payload_t *notify)
940: {
941: switch (notify->get_notify_type(notify))
942: {
943: case USE_TRANSPORT_MODE:
944: this->mode = MODE_TRANSPORT;
945: break;
946: case USE_BEET_MODE:
947: if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN))
948: { /* handle private use notify only if we know its meaning */
949: this->mode = MODE_BEET;
950: }
951: else
952: {
953: DBG1(DBG_IKE, "received a notify strongSwan uses for BEET "
954: "mode, but peer implementation unknown, skipped");
955: }
956: break;
957: case IPCOMP_SUPPORTED:
958: {
959: ipcomp_transform_t ipcomp;
960: uint16_t cpi;
961: chunk_t data;
962:
963: data = notify->get_notification_data(notify);
964: cpi = *(uint16_t*)data.ptr;
965: ipcomp = (ipcomp_transform_t)(*(data.ptr + 2));
966: switch (ipcomp)
967: {
968: case IPCOMP_DEFLATE:
969: this->other_cpi = cpi;
970: this->ipcomp_received = ipcomp;
971: break;
972: case IPCOMP_LZS:
973: case IPCOMP_LZJH:
974: default:
975: DBG1(DBG_IKE, "received IPCOMP_SUPPORTED notify with a "
976: "transform ID we don't support %N",
977: ipcomp_transform_names, ipcomp);
978: break;
979: }
980: break;
981: }
982: case ESP_TFC_PADDING_NOT_SUPPORTED:
983: DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding",
984: notify_type_names, notify->get_notify_type(notify));
985: this->tfcv3 = FALSE;
986: break;
987: default:
988: break;
989: }
990: }
991:
992: /**
993: * Read payloads from message
994: */
995: static void process_payloads(private_child_create_t *this, message_t *message)
996: {
997: enumerator_t *enumerator;
998: payload_t *payload;
999: sa_payload_t *sa_payload;
1000: ke_payload_t *ke_payload;
1001: ts_payload_t *ts_payload;
1002:
1003: /* defaults to TUNNEL mode */
1004: this->mode = MODE_TUNNEL;
1005:
1006: enumerator = message->create_payload_enumerator(message);
1007: while (enumerator->enumerate(enumerator, &payload))
1008: {
1009: switch (payload->get_type(payload))
1010: {
1011: case PLV2_SECURITY_ASSOCIATION:
1012: sa_payload = (sa_payload_t*)payload;
1013: this->proposals = sa_payload->get_proposals(sa_payload);
1014: break;
1015: case PLV2_KEY_EXCHANGE:
1016: ke_payload = (ke_payload_t*)payload;
1017: if (!this->initiator)
1018: {
1019: this->dh_group = ke_payload->get_dh_group_number(ke_payload);
1020: this->dh = this->keymat->keymat.create_dh(
1021: &this->keymat->keymat, this->dh_group);
1022: }
1023: else if (this->dh)
1024: {
1025: this->dh_failed = this->dh->get_dh_group(this->dh) !=
1026: ke_payload->get_dh_group_number(ke_payload);
1027: }
1028: if (this->dh && !this->dh_failed)
1029: {
1030: this->dh_failed = !this->dh->set_other_public_value(this->dh,
1031: ke_payload->get_key_exchange_data(ke_payload));
1032: }
1033: break;
1034: case PLV2_TS_INITIATOR:
1035: ts_payload = (ts_payload_t*)payload;
1036: this->tsi = ts_payload->get_traffic_selectors(ts_payload);
1037: break;
1038: case PLV2_TS_RESPONDER:
1039: ts_payload = (ts_payload_t*)payload;
1040: this->tsr = ts_payload->get_traffic_selectors(ts_payload);
1041: break;
1042: case PLV2_NOTIFY:
1043: handle_notify(this, (notify_payload_t*)payload);
1044: break;
1045: default:
1046: break;
1047: }
1048: }
1049: enumerator->destroy(enumerator);
1050: }
1051:
1052: /**
1053: * Check if we should defer the creation of this CHILD_SA until after the
1054: * IKE_SA has been established childless.
1055: */
1056: static status_t defer_child_sa(private_child_create_t *this)
1057: {
1058: ike_cfg_t *ike_cfg;
1059:
1060: ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
1061:
1062: if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_CHILDLESS))
1063: {
1064: if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
1065: {
1066: return NEED_MORE;
1067: }
1068: }
1069: else if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
1070: {
1071: DBG1(DBG_IKE, "peer does not support childless IKE_SA initiation");
1072: return DESTROY_ME;
1073: }
1074: return NOT_SUPPORTED;
1075: }
1076:
1077: METHOD(task_t, build_i, status_t,
1078: private_child_create_t *this, message_t *message)
1079: {
1080: enumerator_t *enumerator;
1081: host_t *vip;
1082: peer_cfg_t *peer_cfg;
1083: linked_list_t *list;
1084:
1085: switch (message->get_exchange_type(message))
1086: {
1087: case IKE_SA_INIT:
1088: return get_nonce(message, &this->my_nonce);
1089: case CREATE_CHILD_SA:
1090: if (!generate_nonce(this))
1091: {
1092: message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1093: chunk_empty);
1094: return SUCCESS;
1095: }
1096: if (!this->retry && this->dh_group == MODP_NONE)
1097: { /* during a rekeying the group might already be set */
1098: this->dh_group = this->config->get_dh_group(this->config);
1099: }
1100: break;
1101: case IKE_AUTH:
1102: if (message->get_message_id(message) != 1)
1103: {
1104: /* send only in the first request, not in subsequent rounds */
1105: return NEED_MORE;
1106: }
1107: switch (defer_child_sa(this))
1108: {
1109: case DESTROY_ME:
1110: /* config mismatch */
1111: return DESTROY_ME;
1112: case NEED_MORE:
1113: /* defer until after IKE_SA has been established */
1114: chunk_free(&this->my_nonce);
1115: return NEED_MORE;
1116: default:
1117: /* just continue to establish the CHILD_SA */
1118: break;
1119: }
1120: break;
1121: default:
1122: break;
1123: }
1124:
1125: /* check if we want a virtual IP, but don't have one */
1126: list = linked_list_create();
1127: peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1128: if (!this->rekey)
1129: {
1130: enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
1131: while (enumerator->enumerate(enumerator, &vip))
1132: {
1133: /* propose a 0.0.0.0/0 or ::/0 subnet when we use virtual ip */
1134: vip = host_create_any(vip->get_family(vip));
1135: list->insert_last(list, vip);
1136: }
1137: enumerator->destroy(enumerator);
1138: }
1139: if (list->get_count(list))
1140: {
1141: this->tsi = this->config->get_traffic_selectors(this->config,
1142: TRUE, NULL, list, TRUE);
1143: list->destroy_offset(list, offsetof(host_t, destroy));
1144: }
1145: else
1146: { /* no virtual IPs configured */
1147: list->destroy(list);
1148: list = get_dynamic_hosts(this->ike_sa, TRUE);
1149: this->tsi = this->config->get_traffic_selectors(this->config,
1150: TRUE, NULL, list, TRUE);
1151: list->destroy(list);
1152: }
1153: list = get_dynamic_hosts(this->ike_sa, FALSE);
1154: this->tsr = this->config->get_traffic_selectors(this->config,
1155: FALSE, NULL, list, TRUE);
1156: list->destroy(list);
1157:
1158: if (this->packet_tsi)
1159: {
1160: this->tsi->insert_first(this->tsi,
1161: this->packet_tsi->clone(this->packet_tsi));
1162: }
1163: if (this->packet_tsr)
1164: {
1165: this->tsr->insert_first(this->tsr,
1166: this->packet_tsr->clone(this->packet_tsr));
1167: }
1168: this->proposals = this->config->get_proposals(this->config,
1169: this->dh_group == MODP_NONE);
1170: this->mode = this->config->get_mode(this->config);
1171:
1172: this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa, TRUE);
1173: this->child.if_id_out_def = this->ike_sa->get_if_id(this->ike_sa, FALSE);
1174: this->child.encap = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY);
1175: this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
1176: this->ike_sa->get_other_host(this->ike_sa),
1177: this->config, &this->child);
1178:
1179: if (this->child.reqid)
1180: {
1181: DBG0(DBG_IKE, "establishing CHILD_SA %s{%d} reqid %d",
1182: this->child_sa->get_name(this->child_sa),
1183: this->child_sa->get_unique_id(this->child_sa), this->child.reqid);
1184: }
1185: else
1186: {
1187: DBG0(DBG_IKE, "establishing CHILD_SA %s{%d}",
1188: this->child_sa->get_name(this->child_sa),
1189: this->child_sa->get_unique_id(this->child_sa));
1190: }
1191:
1192: if (!allocate_spi(this))
1193: {
1194: DBG1(DBG_IKE, "unable to allocate SPIs from kernel");
1195: return FAILED;
1196: }
1197:
1198: if (!update_and_check_proposals(this))
1199: {
1200: DBG1(DBG_IKE, "requested DH group %N not contained in any of our "
1201: "proposals",
1202: diffie_hellman_group_names, this->dh_group);
1203: return FAILED;
1204: }
1205:
1206: if (this->dh_group != MODP_NONE)
1207: {
1208: this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
1209: this->dh_group);
1210: }
1211:
1212: if (this->config->has_option(this->config, OPT_IPCOMP))
1213: {
1214: /* IPCOMP_DEFLATE is the only transform we support at the moment */
1215: add_ipcomp_notify(this, message, IPCOMP_DEFLATE);
1216: }
1217:
1218: if (message->get_exchange_type(message) == IKE_AUTH)
1219: {
1220: charon->bus->narrow(charon->bus, this->child_sa,
1221: NARROW_INITIATOR_PRE_NOAUTH, this->tsi, this->tsr);
1222: }
1223: else
1224: {
1225: charon->bus->narrow(charon->bus, this->child_sa,
1226: NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr);
1227: }
1228:
1229: if (!build_payloads(this, message))
1230: {
1231: return FAILED;
1232: }
1233:
1234: this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1235: this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1236: this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1237: this->tsi = NULL;
1238: this->tsr = NULL;
1239: this->proposals = NULL;
1240:
1241: return NEED_MORE;
1242: }
1243:
1244: METHOD(task_t, process_r, status_t,
1245: private_child_create_t *this, message_t *message)
1246: {
1247: switch (message->get_exchange_type(message))
1248: {
1249: case IKE_SA_INIT:
1250: return get_nonce(message, &this->other_nonce);
1251: case CREATE_CHILD_SA:
1252: get_nonce(message, &this->other_nonce);
1253: break;
1254: case IKE_AUTH:
1255: if (message->get_message_id(message) != 1)
1256: {
1257: /* only handle first AUTH payload, not additional rounds */
1258: return NEED_MORE;
1259: }
1260: default:
1261: break;
1262: }
1263:
1264: process_payloads(this, message);
1265:
1266: return NEED_MORE;
1267: }
1268:
1269: /**
1270: * handle CHILD_SA setup failure
1271: */
1272: static void handle_child_sa_failure(private_child_create_t *this,
1273: message_t *message)
1274: {
1275: bool is_first;
1276:
1277: is_first = message->get_exchange_type(message) == IKE_AUTH;
1278: if (is_first &&
1279: lib->settings->get_bool(lib->settings,
1280: "%s.close_ike_on_child_failure", FALSE, lib->ns))
1281: {
1282: /* we delay the delete for 100ms, as the IKE_AUTH response must arrive
1283: * first */
1284: DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
1285: lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
1286: delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
1287: 100);
1288: }
1289: else
1290: {
1291: DBG1(DBG_IKE, "failed to establish CHILD_SA, keeping IKE_SA");
1292: charon->bus->alert(charon->bus, ALERT_KEEP_ON_CHILD_SA_FAILURE,
1293: is_first);
1294: }
1295: }
1296:
1297: /**
1298: * Substitute transport mode NAT selectors, if applicable
1299: */
1300: static linked_list_t* get_ts_if_nat_transport(private_child_create_t *this,
1301: bool local, linked_list_t *in)
1302: {
1303: linked_list_t *out = NULL;
1304: ike_condition_t cond;
1305:
1306: if (this->mode == MODE_TRANSPORT)
1307: {
1308: cond = local ? COND_NAT_HERE : COND_NAT_THERE;
1309: if (this->ike_sa->has_condition(this->ike_sa, cond))
1310: {
1311: out = get_transport_nat_ts(this, local, in);
1312: if (out->get_count(out) == 0)
1313: {
1314: out->destroy(out);
1315: out = NULL;
1316: }
1317: }
1318: }
1319: return out;
1320: }
1321:
1322: /**
1323: * Select a matching CHILD config as responder
1324: */
1325: static child_cfg_t* select_child_cfg(private_child_create_t *this)
1326: {
1327: peer_cfg_t *peer_cfg;
1328: child_cfg_t *child_cfg = NULL;;
1329:
1330: peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
1331: if (peer_cfg && this->tsi && this->tsr)
1332: {
1333: linked_list_t *listr, *listi, *tsr, *tsi;
1334:
1335: tsr = get_ts_if_nat_transport(this, TRUE, this->tsr);
1336: tsi = get_ts_if_nat_transport(this, FALSE, this->tsi);
1337:
1338: listr = get_dynamic_hosts(this->ike_sa, TRUE);
1339: listi = get_dynamic_hosts(this->ike_sa, FALSE);
1340: child_cfg = peer_cfg->select_child_cfg(peer_cfg,
1341: tsr ?: this->tsr, tsi ?: this->tsi,
1342: listr, listi);
1343: if ((tsi || tsr) && child_cfg &&
1344: child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
1345: {
1346: /* found a CHILD config, but it doesn't use transport mode */
1347: child_cfg->destroy(child_cfg);
1348: child_cfg = NULL;
1349: }
1350: if (!child_cfg && (tsi || tsr))
1351: {
1352: /* no match for the substituted NAT selectors, try it without */
1353: child_cfg = peer_cfg->select_child_cfg(peer_cfg,
1354: this->tsr, this->tsi, listr, listi);
1355: }
1356: listr->destroy(listr);
1357: listi->destroy(listi);
1358: DESTROY_OFFSET_IF(tsi, offsetof(traffic_selector_t, destroy));
1359: DESTROY_OFFSET_IF(tsr, offsetof(traffic_selector_t, destroy));
1360: }
1361:
1362: return child_cfg;
1363: }
1364:
1365: /**
1366: * Check how to handle a possibly childless IKE_SA
1367: */
1368: static status_t handle_childless(private_child_create_t *this)
1369: {
1370: ike_cfg_t *ike_cfg;
1371:
1372: ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
1373:
1374: if (!this->proposals && !this->tsi && !this->tsr)
1375: {
1376: /* looks like a childless IKE_SA, check if we allow it */
1377: if (ike_cfg->childless(ike_cfg) == CHILDLESS_NEVER)
1378: {
1379: /* we don't allow childless initiation */
1380: DBG1(DBG_IKE, "peer tried to initiate a childless IKE_SA");
1381: return INVALID_STATE;
1382: }
1383: return SUCCESS;
1384: }
1385:
1386: /* the peer apparently wants to create a regular IKE_SA */
1387: if (ike_cfg->childless(ike_cfg) == CHILDLESS_FORCE)
1388: {
1389: /* reject it if we only allow childless initiation */
1390: DBG1(DBG_IKE, "peer did not initiate a childless IKE_SA");
1391: return INVALID_STATE;
1392: }
1393: return NOT_SUPPORTED;
1394: }
1395:
1396: METHOD(task_t, build_r, status_t,
1397: private_child_create_t *this, message_t *message)
1398: {
1399: payload_t *payload;
1400: enumerator_t *enumerator;
1401: bool no_dh = TRUE, ike_auth = FALSE;
1402:
1403: switch (message->get_exchange_type(message))
1404: {
1405: case IKE_SA_INIT:
1406: return get_nonce(message, &this->my_nonce);
1407: case CREATE_CHILD_SA:
1408: if (!generate_nonce(this))
1409: {
1410: message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1411: chunk_empty);
1412: return SUCCESS;
1413: }
1414: if (this->dh_failed)
1415: {
1416: DBG1(DBG_IKE, "applying DH public value failed");
1417: message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN,
1418: chunk_empty);
1419: return SUCCESS;
1420: }
1421: no_dh = FALSE;
1422: break;
1423: case IKE_AUTH:
1424: if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1425: { /* wait until all authentication round completed */
1426: return NEED_MORE;
1427: }
1428: if (this->ike_sa->has_condition(this->ike_sa, COND_REDIRECTED))
1429: { /* no CHILD_SA is created for redirected SAs */
1430: return SUCCESS;
1431: }
1432: switch (handle_childless(this))
1433: {
1434: case SUCCESS:
1435: /* no CHILD_SA built */
1436: return SUCCESS;
1437: case INVALID_STATE:
1438: message->add_notify(message, FALSE, INVALID_SYNTAX,
1439: chunk_empty);
1440: return FAILED;
1441: default:
1442: /* continue with regular initiation */
1443: break;
1444: }
1445: ike_auth = TRUE;
1446: default:
1447: break;
1448: }
1449:
1450: if (this->ike_sa->get_state(this->ike_sa) == IKE_REKEYING)
1451: {
1452: DBG1(DBG_IKE, "unable to create CHILD_SA while rekeying IKE_SA");
1453: message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
1454: return SUCCESS;
1455: }
1456: if (this->ike_sa->get_state(this->ike_sa) == IKE_DELETING)
1457: {
1458: DBG1(DBG_IKE, "unable to create CHILD_SA while deleting IKE_SA");
1459: message->add_notify(message, TRUE, TEMPORARY_FAILURE, chunk_empty);
1460: return SUCCESS;
1461: }
1462:
1463: if (this->config == NULL)
1464: {
1465: this->config = select_child_cfg(this);
1466: }
1467: if (this->config == NULL)
1468: {
1469: DBG1(DBG_IKE, "traffic selectors %#R === %#R unacceptable",
1470: this->tsr, this->tsi);
1471: charon->bus->alert(charon->bus, ALERT_TS_MISMATCH, this->tsi, this->tsr);
1472: message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1473: handle_child_sa_failure(this, message);
1474: return SUCCESS;
1475: }
1476:
1477: /* check if ike_config_t included non-critical error notifies */
1478: enumerator = message->create_payload_enumerator(message);
1479: while (enumerator->enumerate(enumerator, &payload))
1480: {
1481: if (payload->get_type(payload) == PLV2_NOTIFY)
1482: {
1483: notify_payload_t *notify = (notify_payload_t*)payload;
1484:
1485: switch (notify->get_notify_type(notify))
1486: {
1487: case INTERNAL_ADDRESS_FAILURE:
1488: case FAILED_CP_REQUIRED:
1489: {
1490: DBG1(DBG_IKE,"configuration payload negotiation "
1491: "failed, no CHILD_SA built");
1492: enumerator->destroy(enumerator);
1493: handle_child_sa_failure(this, message);
1494: return SUCCESS;
1495: }
1496: default:
1497: break;
1498: }
1499: }
1500: }
1501: enumerator->destroy(enumerator);
1502:
1503: this->child.if_id_in_def = this->ike_sa->get_if_id(this->ike_sa, TRUE);
1504: this->child.if_id_out_def = this->ike_sa->get_if_id(this->ike_sa, FALSE);
1505: this->child.encap = this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY);
1506: this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
1507: this->ike_sa->get_other_host(this->ike_sa),
1508: this->config, &this->child);
1509:
1510: if (this->ipcomp_received != IPCOMP_NONE)
1511: {
1512: if (this->config->has_option(this->config, OPT_IPCOMP))
1513: {
1514: add_ipcomp_notify(this, message, this->ipcomp_received);
1515: }
1516: else
1517: {
1518: DBG1(DBG_IKE, "received %N notify but IPComp is disabled, ignoring",
1519: notify_type_names, IPCOMP_SUPPORTED);
1520: }
1521: }
1522:
1523: switch (select_and_install(this, no_dh, ike_auth))
1524: {
1525: case SUCCESS:
1526: break;
1527: case NOT_FOUND:
1528: message->add_notify(message, FALSE, TS_UNACCEPTABLE, chunk_empty);
1529: handle_child_sa_failure(this, message);
1530: return SUCCESS;
1531: case INVALID_ARG:
1532: {
1533: uint16_t group = htons(this->dh_group);
1534: message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
1535: chunk_from_thing(group));
1536: return SUCCESS;
1537: }
1538: case FAILED:
1539: default:
1540: message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1541: handle_child_sa_failure(this, message);
1542: return SUCCESS;
1543: }
1544:
1545: if (!build_payloads(this, message))
1546: {
1547: message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty);
1548: handle_child_sa_failure(this, message);
1549: return SUCCESS;
1550: }
1551:
1552: if (!this->rekey)
1553: { /* invoke the child_up() hook if we are not rekeying */
1554: charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1555: }
1556: return SUCCESS;
1557: }
1558:
1559: /**
1560: * Raise alerts for received notify errors
1561: */
1562: static void raise_alerts(private_child_create_t *this, notify_type_t type)
1563: {
1564: linked_list_t *list;
1565:
1566: switch (type)
1567: {
1568: case NO_PROPOSAL_CHOSEN:
1569: list = this->config->get_proposals(this->config, FALSE);
1570: charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_CHILD, list);
1571: list->destroy_offset(list, offsetof(proposal_t, destroy));
1572: break;
1573: default:
1574: break;
1575: }
1576: }
1577:
1578: METHOD(task_t, build_i_delete, status_t,
1579: private_child_create_t *this, message_t *message)
1580: {
1581: message->set_exchange_type(message, INFORMATIONAL);
1582: if (this->my_spi && this->proto)
1583: {
1584: delete_payload_t *del;
1585:
1586: del = delete_payload_create(PLV2_DELETE, this->proto);
1587: del->add_spi(del, this->my_spi);
1588: message->add_payload(message, (payload_t*)del);
1589:
1590: DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x",
1591: protocol_id_names, this->proto, ntohl(this->my_spi));
1592: }
1593: return NEED_MORE;
1594: }
1595:
1596: /**
1597: * Change task to delete the failed CHILD_SA as initiator
1598: */
1599: static status_t delete_failed_sa(private_child_create_t *this)
1600: {
1601: if (this->my_spi && this->proto)
1602: {
1603: this->public.task.build = _build_i_delete;
1604: this->public.task.process = (void*)return_success;
1605: return NEED_MORE;
1606: }
1607: return SUCCESS;
1608: }
1609:
1610: METHOD(task_t, process_i, status_t,
1611: private_child_create_t *this, message_t *message)
1612: {
1613: enumerator_t *enumerator;
1614: payload_t *payload;
1615: bool no_dh = TRUE, ike_auth = FALSE;
1616:
1617: switch (message->get_exchange_type(message))
1618: {
1619: case IKE_SA_INIT:
1620: return get_nonce(message, &this->other_nonce);
1621: case CREATE_CHILD_SA:
1622: get_nonce(message, &this->other_nonce);
1623: no_dh = FALSE;
1624: break;
1625: case IKE_AUTH:
1626: if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
1627: { /* wait until all authentication round completed */
1628: return NEED_MORE;
1629: }
1630: if (defer_child_sa(this) == NEED_MORE)
1631: { /* defer until after IKE_SA has been established */
1632: chunk_free(&this->other_nonce);
1633: return NEED_MORE;
1634: }
1635: ike_auth = TRUE;
1636: default:
1637: break;
1638: }
1639:
1640: /* check for erroneous notifies */
1641: enumerator = message->create_payload_enumerator(message);
1642: while (enumerator->enumerate(enumerator, &payload))
1643: {
1644: if (payload->get_type(payload) == PLV2_NOTIFY)
1645: {
1646: notify_payload_t *notify = (notify_payload_t*)payload;
1647: notify_type_t type = notify->get_notify_type(notify);
1648:
1649: switch (type)
1650: {
1651: /* handle notify errors related to CHILD_SA only */
1652: case NO_PROPOSAL_CHOSEN:
1653: case SINGLE_PAIR_REQUIRED:
1654: case NO_ADDITIONAL_SAS:
1655: case INTERNAL_ADDRESS_FAILURE:
1656: case FAILED_CP_REQUIRED:
1657: case TS_UNACCEPTABLE:
1658: case INVALID_SELECTORS:
1659: {
1660: DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
1661: notify_type_names, type);
1662: enumerator->destroy(enumerator);
1663: raise_alerts(this, type);
1664: handle_child_sa_failure(this, message);
1665: /* an error in CHILD_SA creation is not critical */
1666: return SUCCESS;
1667: }
1668: case TEMPORARY_FAILURE:
1669: {
1670: DBG1(DBG_IKE, "received %N notify, will retry later",
1671: notify_type_names, type);
1672: enumerator->destroy(enumerator);
1673: if (!this->rekey)
1674: { /* the rekey task will retry itself if necessary */
1675: schedule_delayed_retry(this);
1676: }
1677: return SUCCESS;
1678: }
1679: case INVALID_KE_PAYLOAD:
1680: {
1681: chunk_t data;
1682: uint16_t group = MODP_NONE;
1683:
1684: data = notify->get_notification_data(notify);
1685: if (data.len == sizeof(group))
1686: {
1687: memcpy(&group, data.ptr, data.len);
1688: group = ntohs(group);
1689: }
1690: if (this->retry)
1691: {
1692: DBG1(DBG_IKE, "already retried with DH group %N, "
1693: "ignore requested %N", diffie_hellman_group_names,
1694: this->dh_group, diffie_hellman_group_names, group);
1695: handle_child_sa_failure(this, message);
1696: /* an error in CHILD_SA creation is not critical */
1697: return SUCCESS;
1698: }
1699: DBG1(DBG_IKE, "peer didn't accept DH group %N, "
1700: "it requested %N", diffie_hellman_group_names,
1701: this->dh_group, diffie_hellman_group_names, group);
1702: this->retry = TRUE;
1703: this->dh_group = group;
1704: this->child_sa->set_state(this->child_sa, CHILD_RETRYING);
1705: this->public.task.migrate(&this->public.task, this->ike_sa);
1706: enumerator->destroy(enumerator);
1707: return NEED_MORE;
1708: }
1709: default:
1710: {
1711: if (message->get_exchange_type(message) == CREATE_CHILD_SA)
1712: { /* handle notifies if not handled in IKE_AUTH */
1713: if (type <= 16383)
1714: {
1715: DBG1(DBG_IKE, "received %N notify error",
1716: notify_type_names, type);
1717: enumerator->destroy(enumerator);
1718: return SUCCESS;
1719: }
1720: DBG2(DBG_IKE, "received %N notify",
1721: notify_type_names, type);
1722: }
1723: break;
1724: }
1725: }
1726: }
1727: }
1728: enumerator->destroy(enumerator);
1729:
1730: process_payloads(this, message);
1731:
1732: if (this->ipcomp == IPCOMP_NONE && this->ipcomp_received != IPCOMP_NONE)
1733: {
1734: DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify without requesting"
1735: " one, no CHILD_SA built");
1736: handle_child_sa_failure(this, message);
1737: return delete_failed_sa(this);
1738: }
1739: else if (this->ipcomp != IPCOMP_NONE && this->ipcomp_received == IPCOMP_NONE)
1740: {
1741: DBG1(DBG_IKE, "peer didn't accept our proposed IPComp transforms, "
1742: "IPComp is disabled");
1743: this->ipcomp = IPCOMP_NONE;
1744: }
1745: else if (this->ipcomp != IPCOMP_NONE && this->ipcomp != this->ipcomp_received)
1746: {
1747: DBG1(DBG_IKE, "received an IPCOMP_SUPPORTED notify we didn't propose, "
1748: "no CHILD_SA built");
1749: handle_child_sa_failure(this, message);
1750: return delete_failed_sa(this);
1751: }
1752:
1753: if (this->dh_failed)
1754: {
1755: DBG1(DBG_IKE, "applying DH public value failed");
1756: handle_child_sa_failure(this, message);
1757: return delete_failed_sa(this);
1758: }
1759:
1760: if (select_and_install(this, no_dh, ike_auth) == SUCCESS)
1761: {
1762: if (!this->rekey)
1763: { /* invoke the child_up() hook if we are not rekeying */
1764: charon->bus->child_updown(charon->bus, this->child_sa, TRUE);
1765: }
1766: }
1767: else
1768: {
1769: handle_child_sa_failure(this, message);
1770: return delete_failed_sa(this);
1771: }
1772: return SUCCESS;
1773: }
1774:
1775: METHOD(child_create_t, use_reqid, void,
1776: private_child_create_t *this, uint32_t reqid)
1777: {
1778: this->child.reqid = reqid;
1779: }
1780:
1781: METHOD(child_create_t, use_marks, void,
1782: private_child_create_t *this, uint32_t in, uint32_t out)
1783: {
1784: this->child.mark_in = in;
1785: this->child.mark_out = out;
1786: }
1787:
1788: METHOD(child_create_t, use_if_ids, void,
1789: private_child_create_t *this, uint32_t in, uint32_t out)
1790: {
1791: this->child.if_id_in = in;
1792: this->child.if_id_out = out;
1793: }
1794:
1795: METHOD(child_create_t, use_dh_group, void,
1796: private_child_create_t *this, diffie_hellman_group_t dh_group)
1797: {
1798: this->dh_group = dh_group;
1799: }
1800:
1801: METHOD(child_create_t, get_child, child_sa_t*,
1802: private_child_create_t *this)
1803: {
1804: return this->child_sa;
1805: }
1806:
1807: METHOD(child_create_t, set_config, void,
1808: private_child_create_t *this, child_cfg_t *cfg)
1809: {
1810: DESTROY_IF(this->config);
1811: this->config = cfg;
1812: }
1813:
1814: METHOD(child_create_t, get_lower_nonce, chunk_t,
1815: private_child_create_t *this)
1816: {
1817: if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
1818: min(this->my_nonce.len, this->other_nonce.len)) < 0)
1819: {
1820: return this->my_nonce;
1821: }
1822: else
1823: {
1824: return this->other_nonce;
1825: }
1826: }
1827:
1828: METHOD(task_t, get_type, task_type_t,
1829: private_child_create_t *this)
1830: {
1831: return TASK_CHILD_CREATE;
1832: }
1833:
1834: METHOD(task_t, migrate, void,
1835: private_child_create_t *this, ike_sa_t *ike_sa)
1836: {
1837: chunk_free(&this->my_nonce);
1838: chunk_free(&this->other_nonce);
1839: if (this->tsr)
1840: {
1841: this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1842: }
1843: if (this->tsi)
1844: {
1845: this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1846: }
1847: DESTROY_IF(this->child_sa);
1848: DESTROY_IF(this->proposal);
1849: DESTROY_IF(this->nonceg);
1850: DESTROY_IF(this->dh);
1851: this->dh_failed = FALSE;
1852: if (this->proposals)
1853: {
1854: this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1855: }
1856:
1857: this->ike_sa = ike_sa;
1858: this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
1859: this->proposal = NULL;
1860: this->proposals = NULL;
1861: this->tsi = NULL;
1862: this->tsr = NULL;
1863: this->dh = NULL;
1864: this->nonceg = NULL;
1865: this->child_sa = NULL;
1866: this->mode = MODE_TUNNEL;
1867: this->ipcomp = IPCOMP_NONE;
1868: this->ipcomp_received = IPCOMP_NONE;
1869: this->other_cpi = 0;
1870: this->established = FALSE;
1871: this->child = (child_sa_create_t){};
1872: }
1873:
1874: METHOD(task_t, destroy, void,
1875: private_child_create_t *this)
1876: {
1877: chunk_free(&this->my_nonce);
1878: chunk_free(&this->other_nonce);
1879: if (this->tsr)
1880: {
1881: this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy));
1882: }
1883: if (this->tsi)
1884: {
1885: this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy));
1886: }
1887: if (!this->established)
1888: {
1889: DESTROY_IF(this->child_sa);
1890: }
1891: DESTROY_IF(this->packet_tsi);
1892: DESTROY_IF(this->packet_tsr);
1893: DESTROY_IF(this->proposal);
1894: DESTROY_IF(this->dh);
1895: if (this->proposals)
1896: {
1897: this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy));
1898: }
1899: DESTROY_IF(this->config);
1900: DESTROY_IF(this->nonceg);
1901: free(this);
1902: }
1903:
1904: /*
1905: * Described in header.
1906: */
1907: child_create_t *child_create_create(ike_sa_t *ike_sa,
1908: child_cfg_t *config, bool rekey,
1909: traffic_selector_t *tsi, traffic_selector_t *tsr)
1910: {
1911: private_child_create_t *this;
1912:
1913: INIT(this,
1914: .public = {
1915: .get_child = _get_child,
1916: .set_config = _set_config,
1917: .get_lower_nonce = _get_lower_nonce,
1918: .use_reqid = _use_reqid,
1919: .use_marks = _use_marks,
1920: .use_if_ids = _use_if_ids,
1921: .use_dh_group = _use_dh_group,
1922: .task = {
1923: .get_type = _get_type,
1924: .migrate = _migrate,
1925: .destroy = _destroy,
1926: },
1927: },
1928: .ike_sa = ike_sa,
1929: .config = config,
1930: .packet_tsi = tsi ? tsi->clone(tsi) : NULL,
1931: .packet_tsr = tsr ? tsr->clone(tsr) : NULL,
1932: .dh_group = MODP_NONE,
1933: .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
1934: .mode = MODE_TUNNEL,
1935: .tfcv3 = TRUE,
1936: .ipcomp = IPCOMP_NONE,
1937: .ipcomp_received = IPCOMP_NONE,
1938: .rekey = rekey,
1939: .retry = FALSE,
1940: );
1941:
1942: if (config)
1943: {
1944: this->public.task.build = _build_i;
1945: this->public.task.process = _process_i;
1946: this->initiator = TRUE;
1947: }
1948: else
1949: {
1950: this->public.task.build = _build_r;
1951: this->public.task.process = _process_r;
1952: this->initiator = FALSE;
1953: }
1954: return &this->public;
1955: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>