child-cfg: Optionally use 96-bit truncation for HMAC-SHA-256
[strongswan.git] / src / libcharon / sa / child_sa.c
1 /*
2 * Copyright (C) 2006-2017 Tobias Brunner
3 * Copyright (C) 2016 Andreas Steffen
4 * Copyright (C) 2005-2008 Martin Willi
5 * Copyright (C) 2006 Daniel Roethlisberger
6 * Copyright (C) 2005 Jan Hutter
7 * HSR Hochschule fuer Technik Rapperswil
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 */
19
20 #define _GNU_SOURCE
21 #include "child_sa.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
26
27 #include <daemon.h>
28 #include <collections/array.h>
29
30 ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
31 "CREATED",
32 "ROUTED",
33 "INSTALLING",
34 "INSTALLED",
35 "UPDATING",
36 "REKEYING",
37 "REKEYED",
38 "RETRYING",
39 "DELETING",
40 "DESTROYING",
41 );
42
43 ENUM(child_sa_outbound_state_names, CHILD_OUTBOUND_NONE, CHILD_OUTBOUND_INSTALLED,
44 "NONE",
45 "REGISTERED",
46 "INSTALLED",
47 );
48
49 typedef struct private_child_sa_t private_child_sa_t;
50
51 /**
52 * Private data of a child_sa_t object.
53 */
54 struct private_child_sa_t {
55 /**
56 * Public interface of child_sa_t.
57 */
58 child_sa_t public;
59
60 /**
61 * address of us
62 */
63 host_t *my_addr;
64
65 /**
66 * address of remote
67 */
68 host_t *other_addr;
69
70 /**
71 * our actually used SPI, 0 if unused
72 */
73 uint32_t my_spi;
74
75 /**
76 * others used SPI, 0 if unused
77 */
78 uint32_t other_spi;
79
80 /**
81 * our Compression Parameter Index (CPI) used, 0 if unused
82 */
83 uint16_t my_cpi;
84
85 /**
86 * others Compression Parameter Index (CPI) used, 0 if unused
87 */
88 uint16_t other_cpi;
89
90 /**
91 * Array for local traffic selectors
92 */
93 array_t *my_ts;
94
95 /**
96 * Array for remote traffic selectors
97 */
98 array_t *other_ts;
99
100 /**
101 * Outbound encryption key cached during a rekeying
102 */
103 chunk_t encr_r;
104
105 /**
106 * Outbound integrity key cached during a rekeying
107 */
108 chunk_t integ_r;
109
110 /**
111 * Whether the outbound SA has only been registered yet during a rekeying
112 */
113 child_sa_outbound_state_t outbound_state;
114
115 /**
116 * Whether the peer supports TFCv3
117 */
118 bool tfcv3;
119
120 /**
121 * The outbound SPI of the CHILD_SA that replaced this one during a rekeying
122 */
123 uint32_t rekey_spi;
124
125 /**
126 * Protocol used to protect this SA, ESP|AH
127 */
128 protocol_id_t protocol;
129
130 /**
131 * reqid used for this child_sa
132 */
133 uint32_t reqid;
134
135 /**
136 * Did we allocate/confirm and must release the reqid?
137 */
138 bool reqid_allocated;
139
140 /**
141 * Is the reqid statically configured
142 */
143 bool static_reqid;
144
145 /**
146 * Unique CHILD_SA identifier
147 */
148 uint32_t unique_id;
149
150 /**
151 * Whether FWD policieis in the outbound direction should be installed
152 */
153 bool policies_fwd_out;
154
155 /**
156 * inbound mark used for this child_sa
157 */
158 mark_t mark_in;
159
160 /**
161 * outbound mark used for this child_sa
162 */
163 mark_t mark_out;
164
165 /**
166 * absolute time when rekeying is scheduled
167 */
168 time_t rekey_time;
169
170 /**
171 * absolute time when the SA expires
172 */
173 time_t expire_time;
174
175 /**
176 * absolute time when SA has been installed
177 */
178 time_t install_time;
179
180 /**
181 * state of the CHILD_SA
182 */
183 child_sa_state_t state;
184
185 /**
186 * TRUE if this CHILD_SA is used to install trap policies
187 */
188 bool trap;
189
190 /**
191 * Specifies if UDP encapsulation is enabled (NAT traversal)
192 */
193 bool encap;
194
195 /**
196 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
197 */
198 ipcomp_transform_t ipcomp;
199
200 /**
201 * mode this SA uses, tunnel/transport
202 */
203 ipsec_mode_t mode;
204
205 /**
206 * Action to enforce if peer closes the CHILD_SA
207 */
208 action_t close_action;
209
210 /**
211 * Action to enforce if peer is considered dead
212 */
213 action_t dpd_action;
214
215 /**
216 * selected proposal
217 */
218 proposal_t *proposal;
219
220 /**
221 * config used to create this child
222 */
223 child_cfg_t *config;
224
225 /**
226 * time of last use in seconds (inbound)
227 */
228 time_t my_usetime;
229
230 /**
231 * time of last use in seconds (outbound)
232 */
233 time_t other_usetime;
234
235 /**
236 * last number of inbound bytes
237 */
238 uint64_t my_usebytes;
239
240 /**
241 * last number of outbound bytes
242 */
243 uint64_t other_usebytes;
244
245 /**
246 * last number of inbound packets
247 */
248 uint64_t my_usepackets;
249
250 /**
251 * last number of outbound bytes
252 */
253 uint64_t other_usepackets;
254 };
255
256 /**
257 * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
258 */
259 static inline uint8_t proto_ike2ip(protocol_id_t protocol)
260 {
261 switch (protocol)
262 {
263 case PROTO_ESP:
264 return IPPROTO_ESP;
265 case PROTO_AH:
266 return IPPROTO_AH;
267 default:
268 return protocol;
269 }
270 }
271
272 METHOD(child_sa_t, get_name, char*,
273 private_child_sa_t *this)
274 {
275 return this->config->get_name(this->config);
276 }
277
278 METHOD(child_sa_t, get_reqid, uint32_t,
279 private_child_sa_t *this)
280 {
281 return this->reqid;
282 }
283
284 METHOD(child_sa_t, get_unique_id, uint32_t,
285 private_child_sa_t *this)
286 {
287 return this->unique_id;
288 }
289
290 METHOD(child_sa_t, get_config, child_cfg_t*,
291 private_child_sa_t *this)
292 {
293 return this->config;
294 }
295
296 METHOD(child_sa_t, set_state, void,
297 private_child_sa_t *this, child_sa_state_t state)
298 {
299 DBG2(DBG_CHD, "CHILD_SA %s{%d} state change: %N => %N",
300 get_name(this), this->unique_id,
301 child_sa_state_names, this->state,
302 child_sa_state_names, state);
303 charon->bus->child_state_change(charon->bus, &this->public, state);
304 this->state = state;
305 }
306
307 METHOD(child_sa_t, get_state, child_sa_state_t,
308 private_child_sa_t *this)
309 {
310 return this->state;
311 }
312
313 METHOD(child_sa_t, get_outbound_state, child_sa_outbound_state_t,
314 private_child_sa_t *this)
315 {
316 return this->outbound_state;
317 }
318
319 METHOD(child_sa_t, get_spi, uint32_t,
320 private_child_sa_t *this, bool inbound)
321 {
322 return inbound ? this->my_spi : this->other_spi;
323 }
324
325 METHOD(child_sa_t, get_cpi, uint16_t,
326 private_child_sa_t *this, bool inbound)
327 {
328 return inbound ? this->my_cpi : this->other_cpi;
329 }
330
331 METHOD(child_sa_t, get_protocol, protocol_id_t,
332 private_child_sa_t *this)
333 {
334 return this->protocol;
335 }
336
337 METHOD(child_sa_t, set_protocol, void,
338 private_child_sa_t *this, protocol_id_t protocol)
339 {
340 this->protocol = protocol;
341 }
342
343 METHOD(child_sa_t, get_mode, ipsec_mode_t,
344 private_child_sa_t *this)
345 {
346 return this->mode;
347 }
348
349 METHOD(child_sa_t, set_mode, void,
350 private_child_sa_t *this, ipsec_mode_t mode)
351 {
352 this->mode = mode;
353 }
354
355 METHOD(child_sa_t, has_encap, bool,
356 private_child_sa_t *this)
357 {
358 return this->encap;
359 }
360
361 METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t,
362 private_child_sa_t *this)
363 {
364 return this->ipcomp;
365 }
366
367 METHOD(child_sa_t, set_ipcomp, void,
368 private_child_sa_t *this, ipcomp_transform_t ipcomp)
369 {
370 this->ipcomp = ipcomp;
371 }
372
373 METHOD(child_sa_t, set_close_action, void,
374 private_child_sa_t *this, action_t action)
375 {
376 this->close_action = action;
377 }
378
379 METHOD(child_sa_t, get_close_action, action_t,
380 private_child_sa_t *this)
381 {
382 return this->close_action;
383 }
384
385 METHOD(child_sa_t, set_dpd_action, void,
386 private_child_sa_t *this, action_t action)
387 {
388 this->dpd_action = action;
389 }
390
391 METHOD(child_sa_t, get_dpd_action, action_t,
392 private_child_sa_t *this)
393 {
394 return this->dpd_action;
395 }
396
397 METHOD(child_sa_t, get_proposal, proposal_t*,
398 private_child_sa_t *this)
399 {
400 return this->proposal;
401 }
402
403 METHOD(child_sa_t, set_proposal, void,
404 private_child_sa_t *this, proposal_t *proposal)
405 {
406 this->proposal = proposal->clone(proposal);
407 }
408
409 METHOD(child_sa_t, create_ts_enumerator, enumerator_t*,
410 private_child_sa_t *this, bool local)
411 {
412 if (local)
413 {
414 return array_create_enumerator(this->my_ts);
415 }
416 return array_create_enumerator(this->other_ts);
417 }
418
419 typedef struct policy_enumerator_t policy_enumerator_t;
420
421 /**
422 * Private policy enumerator
423 */
424 struct policy_enumerator_t {
425 /** implements enumerator_t */
426 enumerator_t public;
427 /** enumerator over own TS */
428 enumerator_t *mine;
429 /** enumerator over others TS */
430 enumerator_t *other;
431 /** array of others TS, to recreate enumerator */
432 array_t *array;
433 /** currently enumerating TS for "me" side */
434 traffic_selector_t *ts;
435 };
436
437 METHOD(enumerator_t, policy_enumerate, bool,
438 policy_enumerator_t *this, traffic_selector_t **my_out,
439 traffic_selector_t **other_out)
440 {
441 traffic_selector_t *other_ts;
442
443 while (this->ts || this->mine->enumerate(this->mine, &this->ts))
444 {
445 if (!this->other->enumerate(this->other, &other_ts))
446 { /* end of others list, restart with new of mine */
447 this->other->destroy(this->other);
448 this->other = array_create_enumerator(this->array);
449 this->ts = NULL;
450 continue;
451 }
452 if (this->ts->get_type(this->ts) != other_ts->get_type(other_ts))
453 { /* family mismatch */
454 continue;
455 }
456 if (this->ts->get_protocol(this->ts) &&
457 other_ts->get_protocol(other_ts) &&
458 this->ts->get_protocol(this->ts) != other_ts->get_protocol(other_ts))
459 { /* protocol mismatch */
460 continue;
461 }
462 if (my_out)
463 {
464 *my_out = this->ts;
465 }
466 if (other_out)
467 {
468 *other_out = other_ts;
469 }
470 return TRUE;
471 }
472 return FALSE;
473 }
474
475 METHOD(enumerator_t, policy_destroy, void,
476 policy_enumerator_t *this)
477 {
478 this->mine->destroy(this->mine);
479 this->other->destroy(this->other);
480 free(this);
481 }
482
483 METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
484 private_child_sa_t *this)
485 {
486 policy_enumerator_t *e;
487
488 INIT(e,
489 .public = {
490 .enumerate = (void*)_policy_enumerate,
491 .destroy = _policy_destroy,
492 },
493 .mine = array_create_enumerator(this->my_ts),
494 .other = array_create_enumerator(this->other_ts),
495 .array = this->other_ts,
496 .ts = NULL,
497 );
498
499 return &e->public;
500 }
501
502 /**
503 * update the cached usebytes
504 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
505 * are available, and NOT_SUPPORTED if the kernel interface does not support
506 * querying the usebytes.
507 */
508 static status_t update_usebytes(private_child_sa_t *this, bool inbound)
509 {
510 status_t status = FAILED;
511 uint64_t bytes, packets;
512 time_t time;
513
514 if (inbound)
515 {
516 if (this->my_spi)
517 {
518 kernel_ipsec_sa_id_t id = {
519 .src = this->other_addr,
520 .dst = this->my_addr,
521 .spi = this->my_spi,
522 .proto = proto_ike2ip(this->protocol),
523 };
524 kernel_ipsec_query_sa_t query = {};
525
526 status = charon->kernel->query_sa(charon->kernel, &id, &query,
527 &bytes, &packets, &time);
528 if (status == SUCCESS)
529 {
530 if (bytes > this->my_usebytes)
531 {
532 this->my_usebytes = bytes;
533 this->my_usepackets = packets;
534 if (time)
535 {
536 this->my_usetime = time;
537 }
538 }
539 else
540 {
541 status = FAILED;
542 }
543 }
544 }
545 }
546 else
547 {
548 if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED)
549 {
550 kernel_ipsec_sa_id_t id = {
551 .src = this->my_addr,
552 .dst = this->other_addr,
553 .spi = this->other_spi,
554 .proto = proto_ike2ip(this->protocol),
555 .mark = this->mark_out,
556 };
557 kernel_ipsec_query_sa_t query = {};
558
559 status = charon->kernel->query_sa(charon->kernel, &id, &query,
560 &bytes, &packets, &time);
561 if (status == SUCCESS)
562 {
563 if (bytes > this->other_usebytes)
564 {
565 this->other_usebytes = bytes;
566 this->other_usepackets = packets;
567 if (time)
568 {
569 this->other_usetime = time;
570 }
571 }
572 else
573 {
574 status = FAILED;
575 }
576 }
577 }
578 }
579 return status;
580 }
581
582 /**
583 * updates the cached usetime
584 */
585 static bool update_usetime(private_child_sa_t *this, bool inbound)
586 {
587 enumerator_t *enumerator;
588 traffic_selector_t *my_ts, *other_ts;
589 time_t last_use = 0;
590
591 enumerator = create_policy_enumerator(this);
592 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
593 {
594 time_t in, out, fwd;
595
596 if (inbound)
597 {
598 kernel_ipsec_policy_id_t id = {
599 .dir = POLICY_IN,
600 .src_ts = other_ts,
601 .dst_ts = my_ts,
602 .mark = this->mark_in,
603 };
604 kernel_ipsec_query_policy_t query = {};
605
606 if (charon->kernel->query_policy(charon->kernel, &id, &query,
607 &in) == SUCCESS)
608 {
609 last_use = max(last_use, in);
610 }
611 if (this->mode != MODE_TRANSPORT)
612 {
613 id.dir = POLICY_FWD;
614 if (charon->kernel->query_policy(charon->kernel, &id, &query,
615 &fwd) == SUCCESS)
616 {
617 last_use = max(last_use, fwd);
618 }
619 }
620 }
621 else
622 {
623 kernel_ipsec_policy_id_t id = {
624 .dir = POLICY_OUT,
625 .src_ts = my_ts,
626 .dst_ts = other_ts,
627 .mark = this->mark_out,
628 .interface = this->config->get_interface(this->config),
629 };
630 kernel_ipsec_query_policy_t query = {};
631
632 if (charon->kernel->query_policy(charon->kernel, &id, &query,
633 &out) == SUCCESS)
634 {
635 last_use = max(last_use, out);
636 }
637 }
638 }
639 enumerator->destroy(enumerator);
640
641 if (last_use == 0)
642 {
643 return FALSE;
644 }
645 if (inbound)
646 {
647 this->my_usetime = last_use;
648 }
649 else
650 {
651 this->other_usetime = last_use;
652 }
653 return TRUE;
654 }
655
656 METHOD(child_sa_t, get_usestats, void,
657 private_child_sa_t *this, bool inbound,
658 time_t *time, uint64_t *bytes, uint64_t *packets)
659 {
660 if ((!bytes && !packets) || update_usebytes(this, inbound) != FAILED)
661 {
662 /* there was traffic since last update or the kernel interface
663 * does not support querying the number of usebytes.
664 */
665 if (time)
666 {
667 if (!update_usetime(this, inbound) && !bytes && !packets)
668 {
669 /* if policy query did not yield a usetime, query SAs instead */
670 update_usebytes(this, inbound);
671 }
672 }
673 }
674 if (time)
675 {
676 *time = inbound ? this->my_usetime : this->other_usetime;
677 }
678 if (bytes)
679 {
680 *bytes = inbound ? this->my_usebytes : this->other_usebytes;
681 }
682 if (packets)
683 {
684 *packets = inbound ? this->my_usepackets : this->other_usepackets;
685 }
686 }
687
688 METHOD(child_sa_t, get_mark, mark_t,
689 private_child_sa_t *this, bool inbound)
690 {
691 if (inbound)
692 {
693 return this->mark_in;
694 }
695 return this->mark_out;
696 }
697
698 METHOD(child_sa_t, get_lifetime, time_t,
699 private_child_sa_t *this, bool hard)
700 {
701 return hard ? this->expire_time : this->rekey_time;
702 }
703
704 METHOD(child_sa_t, get_installtime, time_t,
705 private_child_sa_t *this)
706 {
707 return this->install_time;
708 }
709
710 METHOD(child_sa_t, alloc_spi, uint32_t,
711 private_child_sa_t *this, protocol_id_t protocol)
712 {
713 if (charon->kernel->get_spi(charon->kernel, this->other_addr, this->my_addr,
714 proto_ike2ip(protocol), &this->my_spi) == SUCCESS)
715 {
716 /* if we allocate a SPI, but then are unable to establish the SA, we
717 * need to know the protocol family to delete the partial SA */
718 this->protocol = protocol;
719 return this->my_spi;
720 }
721 return 0;
722 }
723
724 METHOD(child_sa_t, alloc_cpi, uint16_t,
725 private_child_sa_t *this)
726 {
727 if (charon->kernel->get_cpi(charon->kernel, this->other_addr, this->my_addr,
728 &this->my_cpi) == SUCCESS)
729 {
730 return this->my_cpi;
731 }
732 return 0;
733 }
734
735 /**
736 * Install the given SA in the kernel
737 */
738 static status_t install_internal(private_child_sa_t *this, chunk_t encr,
739 chunk_t integ, uint32_t spi, uint16_t cpi, bool initiator, bool inbound,
740 bool tfcv3)
741 {
742 uint16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
743 uint16_t esn = NO_EXT_SEQ_NUMBERS;
744 linked_list_t *my_ts, *other_ts, *src_ts, *dst_ts;
745 time_t now;
746 kernel_ipsec_sa_id_t id;
747 kernel_ipsec_add_sa_t sa;
748 lifetime_cfg_t *lifetime;
749 uint32_t tfc = 0;
750 host_t *src, *dst;
751 status_t status;
752 bool update = FALSE;
753
754 /* BEET requires the bound address from the traffic selectors */
755 my_ts = linked_list_create_from_enumerator(
756 array_create_enumerator(this->my_ts));
757 other_ts = linked_list_create_from_enumerator(
758 array_create_enumerator(this->other_ts));
759
760 /* now we have to decide which spi to use. Use self allocated, if "in",
761 * or the one in the proposal, if not "in" (others). Additionally,
762 * source and dest host switch depending on the role */
763 if (inbound)
764 {
765 dst = this->my_addr;
766 src = this->other_addr;
767 if (this->my_spi == spi)
768 { /* alloc_spi has been called, do an SA update */
769 update = TRUE;
770 }
771 this->my_spi = spi;
772 this->my_cpi = cpi;
773 dst_ts = my_ts;
774 src_ts = other_ts;
775 }
776 else
777 {
778 src = this->my_addr;
779 dst = this->other_addr;
780 this->other_spi = spi;
781 this->other_cpi = cpi;
782 src_ts = my_ts;
783 dst_ts = other_ts;
784
785 if (tfcv3)
786 {
787 tfc = this->config->get_tfc(this->config);
788 }
789 this->outbound_state = CHILD_OUTBOUND_INSTALLED;
790 }
791
792 DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
793 protocol_id_names, this->protocol);
794
795 /* send SA down to the kernel */
796 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
797
798 this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
799 &enc_alg, &size);
800 this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
801 &int_alg, &size);
802 this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
803 &esn, NULL);
804
805 if (int_alg == AUTH_HMAC_SHA2_256_128 &&
806 this->config->has_option(this->config, OPT_SHA256_96))
807 {
808 DBG2(DBG_CHD, " using %N with 96-bit truncation",
809 integrity_algorithm_names, int_alg);
810 int_alg = AUTH_HMAC_SHA2_256_96;
811 }
812
813 if (!this->reqid_allocated && !this->static_reqid)
814 {
815 status = charon->kernel->alloc_reqid(charon->kernel, my_ts, other_ts,
816 this->mark_in, this->mark_out, &this->reqid);
817 if (status != SUCCESS)
818 {
819 my_ts->destroy(my_ts);
820 other_ts->destroy(other_ts);
821 return status;
822 }
823 this->reqid_allocated = TRUE;
824 }
825
826 lifetime = this->config->get_lifetime(this->config, TRUE);
827
828 now = time_monotonic(NULL);
829 if (lifetime->time.rekey)
830 {
831 if (this->rekey_time)
832 {
833 this->rekey_time = min(this->rekey_time, now + lifetime->time.rekey);
834 }
835 else
836 {
837 this->rekey_time = now + lifetime->time.rekey;
838 }
839 }
840 if (lifetime->time.life)
841 {
842 this->expire_time = now + lifetime->time.life;
843 }
844
845 if (!lifetime->time.jitter && !inbound)
846 { /* avoid triggering multiple rekey events */
847 lifetime->time.rekey = 0;
848 }
849
850 id = (kernel_ipsec_sa_id_t){
851 .src = src,
852 .dst = dst,
853 .spi = spi,
854 .proto = proto_ike2ip(this->protocol),
855 .mark = inbound ? (mark_t){} : this->mark_out,
856 };
857 sa = (kernel_ipsec_add_sa_t){
858 .reqid = this->reqid,
859 .mode = this->mode,
860 .src_ts = src_ts,
861 .dst_ts = dst_ts,
862 .interface = inbound ? NULL : this->config->get_interface(this->config),
863 .lifetime = lifetime,
864 .enc_alg = enc_alg,
865 .enc_key = encr,
866 .int_alg = int_alg,
867 .int_key = integ,
868 .replay_window = this->config->get_replay_window(this->config),
869 .tfc = tfc,
870 .ipcomp = this->ipcomp,
871 .cpi = cpi,
872 .encap = this->encap,
873 .hw_offload = this->config->has_option(this->config, OPT_HW_OFFLOAD),
874 .esn = esn,
875 .initiator = initiator,
876 .inbound = inbound,
877 .update = update,
878 };
879
880 status = charon->kernel->add_sa(charon->kernel, &id, &sa);
881
882 my_ts->destroy(my_ts);
883 other_ts->destroy(other_ts);
884 free(lifetime);
885
886 return status;
887 }
888
889 METHOD(child_sa_t, install, status_t,
890 private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
891 uint16_t cpi, bool initiator, bool inbound, bool tfcv3)
892 {
893 return install_internal(this, encr, integ, spi, cpi, initiator, inbound,
894 tfcv3);
895 }
896
897 /**
898 * Check kernel interface if policy updates are required
899 */
900 static bool require_policy_update()
901 {
902 kernel_feature_t f;
903
904 f = charon->kernel->get_features(charon->kernel);
905 return !(f & KERNEL_NO_POLICY_UPDATES);
906 }
907
908 /**
909 * Prepare SA config to install/delete policies
910 */
911 static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa,
912 ipsec_sa_cfg_t *other_sa)
913 {
914 enumerator_t *enumerator;
915
916 *my_sa = (ipsec_sa_cfg_t){
917 .mode = this->mode,
918 .reqid = this->reqid,
919 .ipcomp = {
920 .transform = this->ipcomp,
921 },
922 };
923 *other_sa = *my_sa;
924
925 my_sa->ipcomp.cpi = this->my_cpi;
926 other_sa->ipcomp.cpi = this->other_cpi;
927
928 if (this->protocol == PROTO_ESP)
929 {
930 my_sa->esp.use = TRUE;
931 my_sa->esp.spi = this->my_spi;
932 other_sa->esp.use = TRUE;
933 other_sa->esp.spi = this->other_spi;
934 }
935 else
936 {
937 my_sa->ah.use = TRUE;
938 my_sa->ah.spi = this->my_spi;
939 other_sa->ah.use = TRUE;
940 other_sa->ah.spi = this->other_spi;
941 }
942
943 enumerator = create_policy_enumerator(this);
944 while (enumerator->enumerate(enumerator, NULL, NULL))
945 {
946 my_sa->policy_count++;
947 other_sa->policy_count++;
948 }
949 enumerator->destroy(enumerator);
950 }
951
952 /**
953 * Install inbound policie(s): in, fwd
954 */
955 static status_t install_policies_inbound(private_child_sa_t *this,
956 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
957 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
958 ipsec_sa_cfg_t *other_sa, policy_type_t type,
959 policy_priority_t priority, uint32_t manual_prio)
960 {
961 kernel_ipsec_policy_id_t in_id = {
962 .dir = POLICY_IN,
963 .src_ts = other_ts,
964 .dst_ts = my_ts,
965 .mark = this->mark_in,
966 };
967 kernel_ipsec_manage_policy_t in_policy = {
968 .type = type,
969 .prio = priority,
970 .manual_prio = manual_prio,
971 .src = other_addr,
972 .dst = my_addr,
973 .sa = my_sa,
974 };
975 status_t status = SUCCESS;
976
977 status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
978 if (this->mode != MODE_TRANSPORT)
979 {
980 in_id.dir = POLICY_FWD;
981 status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
982 }
983 return status;
984 }
985
986 /**
987 * Install outbound policie(s): out, [fwd]
988 */
989 static status_t install_policies_outbound(private_child_sa_t *this,
990 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
991 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
992 ipsec_sa_cfg_t *other_sa, policy_type_t type,
993 policy_priority_t priority, uint32_t manual_prio)
994 {
995 kernel_ipsec_policy_id_t out_id = {
996 .dir = POLICY_OUT,
997 .src_ts = my_ts,
998 .dst_ts = other_ts,
999 .mark = this->mark_out,
1000 .interface = this->config->get_interface(this->config),
1001 };
1002 kernel_ipsec_manage_policy_t out_policy = {
1003 .type = type,
1004 .prio = priority,
1005 .manual_prio = manual_prio,
1006 .src = my_addr,
1007 .dst = other_addr,
1008 .sa = other_sa,
1009 };
1010 status_t status = SUCCESS;
1011
1012 status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy);
1013
1014 if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
1015 {
1016 /* install an "outbound" FWD policy in case there is a drop policy
1017 * matching outbound forwarded traffic, to allow another tunnel to use
1018 * the reversed subnets and do the same we don't set a reqid (this also
1019 * allows the kernel backend to distinguish between the two types of
1020 * FWD policies). To avoid problems with symmetrically overlapping
1021 * policies of two SAs we install them with reduced priority. As they
1022 * basically act as bypass policies for drop policies we use a higher
1023 * priority than is used for them. */
1024 out_id.dir = POLICY_FWD;
1025 other_sa->reqid = 0;
1026 if (priority == POLICY_PRIORITY_DEFAULT)
1027 {
1028 out_policy.prio = POLICY_PRIORITY_ROUTED;
1029 }
1030 status |= charon->kernel->add_policy(charon->kernel, &out_id,
1031 &out_policy);
1032 /* reset the reqid for any other further policies */
1033 other_sa->reqid = this->reqid;
1034 }
1035 return status;
1036 }
1037
1038 /**
1039 * Install all policies
1040 */
1041 static status_t install_policies_internal(private_child_sa_t *this,
1042 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1043 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1044 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1045 policy_priority_t priority, uint32_t manual_prio)
1046 {
1047 status_t status = SUCCESS;
1048
1049 status |= install_policies_inbound(this, my_addr, other_addr, my_ts,
1050 other_ts, my_sa, other_sa, type,
1051 priority, manual_prio);
1052 status |= install_policies_outbound(this, my_addr, other_addr, my_ts,
1053 other_ts, my_sa, other_sa, type,
1054 priority, manual_prio);
1055 return status;
1056 }
1057
1058 /**
1059 * Delete inbound policies: in, fwd
1060 */
1061 static void del_policies_inbound(private_child_sa_t *this,
1062 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1063 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1064 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1065 policy_priority_t priority, uint32_t manual_prio)
1066 {
1067 kernel_ipsec_policy_id_t in_id = {
1068 .dir = POLICY_IN,
1069 .src_ts = other_ts,
1070 .dst_ts = my_ts,
1071 .mark = this->mark_in,
1072 };
1073 kernel_ipsec_manage_policy_t in_policy = {
1074 .type = type,
1075 .prio = priority,
1076 .manual_prio = manual_prio,
1077 .src = other_addr,
1078 .dst = my_addr,
1079 .sa = my_sa,
1080 };
1081
1082 charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
1083
1084 if (this->mode != MODE_TRANSPORT)
1085 {
1086 in_id.dir = POLICY_FWD;
1087 charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
1088 }
1089 }
1090
1091 /**
1092 * Delete outbound policies: out, [fwd]
1093 */
1094 static void del_policies_outbound(private_child_sa_t *this,
1095 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1096 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1097 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1098 policy_priority_t priority, uint32_t manual_prio)
1099 {
1100 kernel_ipsec_policy_id_t out_id = {
1101 .dir = POLICY_OUT,
1102 .src_ts = my_ts,
1103 .dst_ts = other_ts,
1104 .mark = this->mark_out,
1105 .interface = this->config->get_interface(this->config),
1106 };
1107 kernel_ipsec_manage_policy_t out_policy = {
1108 .type = type,
1109 .prio = priority,
1110 .manual_prio = manual_prio,
1111 .src = my_addr,
1112 .dst = other_addr,
1113 .sa = other_sa,
1114 };
1115
1116 charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
1117
1118 if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
1119 {
1120 out_id.dir = POLICY_FWD;
1121 other_sa->reqid = 0;
1122 if (priority == POLICY_PRIORITY_DEFAULT)
1123 {
1124 out_policy.prio = POLICY_PRIORITY_ROUTED;
1125 }
1126 charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
1127 other_sa->reqid = this->reqid;
1128 }
1129 }
1130
1131 /**
1132 * Delete in- and outbound policies
1133 */
1134 static void del_policies_internal(private_child_sa_t *this,
1135 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1136 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1137 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1138 policy_priority_t priority, uint32_t manual_prio)
1139 {
1140 del_policies_outbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
1141 other_sa, type, priority, manual_prio);
1142 del_policies_inbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
1143 other_sa, type, priority, manual_prio);
1144 }
1145
1146 METHOD(child_sa_t, set_policies, void,
1147 private_child_sa_t *this, linked_list_t *my_ts_list,
1148 linked_list_t *other_ts_list)
1149 {
1150 enumerator_t *enumerator;
1151 traffic_selector_t *my_ts, *other_ts;
1152
1153 if (array_count(this->my_ts))
1154 {
1155 array_destroy_offset(this->my_ts,
1156 offsetof(traffic_selector_t, destroy));
1157 this->my_ts = array_create(0, 0);
1158 }
1159 enumerator = my_ts_list->create_enumerator(my_ts_list);
1160 while (enumerator->enumerate(enumerator, &my_ts))
1161 {
1162 array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts));
1163 }
1164 enumerator->destroy(enumerator);
1165 array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL);
1166
1167 if (array_count(this->other_ts))
1168 {
1169 array_destroy_offset(this->other_ts,
1170 offsetof(traffic_selector_t, destroy));
1171 this->other_ts = array_create(0, 0);
1172 }
1173 enumerator = other_ts_list->create_enumerator(other_ts_list);
1174 while (enumerator->enumerate(enumerator, &other_ts))
1175 {
1176 array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts));
1177 }
1178 enumerator->destroy(enumerator);
1179 array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL);
1180 }
1181
1182 METHOD(child_sa_t, install_policies, status_t,
1183 private_child_sa_t *this)
1184 {
1185 enumerator_t *enumerator;
1186 linked_list_t *my_ts_list, *other_ts_list;
1187 traffic_selector_t *my_ts, *other_ts;
1188 status_t status = SUCCESS;
1189
1190 if (!this->reqid_allocated && !this->static_reqid)
1191 {
1192 my_ts_list = linked_list_create_from_enumerator(
1193 array_create_enumerator(this->my_ts));
1194 other_ts_list = linked_list_create_from_enumerator(
1195 array_create_enumerator(this->other_ts));
1196 status = charon->kernel->alloc_reqid(
1197 charon->kernel, my_ts_list, other_ts_list,
1198 this->mark_in, this->mark_out, &this->reqid);
1199 my_ts_list->destroy(my_ts_list);
1200 other_ts_list->destroy(other_ts_list);
1201 if (status != SUCCESS)
1202 {
1203 return status;
1204 }
1205 this->reqid_allocated = TRUE;
1206 }
1207
1208 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1209 {
1210 policy_priority_t priority;
1211 ipsec_sa_cfg_t my_sa, other_sa;
1212 uint32_t manual_prio;
1213 bool install_outbound;
1214
1215 prepare_sa_cfg(this, &my_sa, &other_sa);
1216 manual_prio = this->config->get_manual_prio(this->config);
1217
1218 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1219 * entry) we install a trap policy */
1220 this->trap = this->state == CHILD_CREATED;
1221 priority = this->trap ? POLICY_PRIORITY_ROUTED
1222 : POLICY_PRIORITY_DEFAULT;
1223 install_outbound = this->outbound_state != CHILD_OUTBOUND_REGISTERED;
1224
1225 /* enumerate pairs of traffic selectors */
1226 enumerator = create_policy_enumerator(this);
1227 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1228 {
1229 /* install outbound drop policy to avoid packets leaving unencrypted
1230 * when updating policies */
1231 if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
1232 require_policy_update() && install_outbound)
1233 {
1234 status |= install_policies_outbound(this, this->my_addr,
1235 this->other_addr, my_ts, other_ts,
1236 &my_sa, &other_sa, POLICY_DROP,
1237 POLICY_PRIORITY_FALLBACK, 0);
1238 }
1239
1240 status |= install_policies_inbound(this, this->my_addr,
1241 this->other_addr, my_ts, other_ts,
1242 &my_sa, &other_sa, POLICY_IPSEC,
1243 priority, manual_prio);
1244
1245 if (install_outbound)
1246 {
1247 status |= install_policies_outbound(this, this->my_addr,
1248 this->other_addr, my_ts, other_ts,
1249 &my_sa, &other_sa, POLICY_IPSEC,
1250 priority, manual_prio);
1251
1252 }
1253 if (status != SUCCESS)
1254 {
1255 break;
1256 }
1257 }
1258 enumerator->destroy(enumerator);
1259 }
1260
1261 if (status == SUCCESS && this->trap)
1262 {
1263 set_state(this, CHILD_ROUTED);
1264 }
1265 return status;
1266 }
1267
1268 METHOD(child_sa_t, register_outbound, void,
1269 private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
1270 uint16_t cpi, bool tfcv3)
1271 {
1272 DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names,
1273 this->protocol);
1274 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr,
1275 this->other_addr);
1276
1277 this->other_spi = spi;
1278 this->other_cpi = cpi;
1279 this->encr_r = chunk_clone(encr);
1280 this->integ_r = chunk_clone(integ);
1281 this->tfcv3 = tfcv3;
1282 this->outbound_state = CHILD_OUTBOUND_REGISTERED;
1283 }
1284
1285 METHOD(child_sa_t, install_outbound, status_t,
1286 private_child_sa_t *this)
1287 {
1288 enumerator_t *enumerator;
1289 traffic_selector_t *my_ts, *other_ts;
1290 status_t status;
1291
1292 status = install_internal(this, this->encr_r, this->integ_r,
1293 this->other_spi, this->other_cpi, FALSE, FALSE,
1294 this->tfcv3);
1295 chunk_clear(&this->encr_r);
1296 chunk_clear(&this->integ_r);
1297 if (status != SUCCESS)
1298 {
1299 return status;
1300 }
1301 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1302 {
1303 ipsec_sa_cfg_t my_sa, other_sa;
1304 uint32_t manual_prio;
1305
1306 prepare_sa_cfg(this, &my_sa, &other_sa);
1307 manual_prio = this->config->get_manual_prio(this->config);
1308
1309 enumerator = create_policy_enumerator(this);
1310 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1311 {
1312 /* install outbound drop policy to avoid packets leaving unencrypted
1313 * when updating policies */
1314 if (manual_prio == 0 && require_policy_update())
1315 {
1316 status |= install_policies_outbound(this, this->my_addr,
1317 this->other_addr, my_ts, other_ts,
1318 &my_sa, &other_sa, POLICY_DROP,
1319 POLICY_PRIORITY_FALLBACK, 0);
1320 }
1321 status |= install_policies_outbound(this, this->my_addr,
1322 this->other_addr, my_ts, other_ts,
1323 &my_sa, &other_sa, POLICY_IPSEC,
1324 POLICY_PRIORITY_DEFAULT, manual_prio);
1325 if (status != SUCCESS)
1326 {
1327 break;
1328 }
1329 }
1330 enumerator->destroy(enumerator);
1331 }
1332 return status;
1333 }
1334
1335 METHOD(child_sa_t, remove_outbound, void,
1336 private_child_sa_t *this)
1337 {
1338 enumerator_t *enumerator;
1339 traffic_selector_t *my_ts, *other_ts;
1340
1341 switch (this->outbound_state)
1342 {
1343 case CHILD_OUTBOUND_INSTALLED:
1344 break;
1345 case CHILD_OUTBOUND_REGISTERED:
1346 chunk_clear(&this->encr_r);
1347 chunk_clear(&this->integ_r);
1348 this->outbound_state = CHILD_OUTBOUND_NONE;
1349 /* fall-through */
1350 case CHILD_OUTBOUND_NONE:
1351 return;
1352 }
1353
1354 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1355 {
1356 ipsec_sa_cfg_t my_sa, other_sa;
1357 uint32_t manual_prio;
1358
1359 prepare_sa_cfg(this, &my_sa, &other_sa);
1360 manual_prio = this->config->get_manual_prio(this->config);
1361
1362 enumerator = create_policy_enumerator(this);
1363 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1364 {
1365 del_policies_outbound(this, this->my_addr, this->other_addr,
1366 my_ts, other_ts, &my_sa, &other_sa,
1367 POLICY_IPSEC, POLICY_PRIORITY_DEFAULT,
1368 manual_prio);
1369 if (manual_prio == 0 && require_policy_update())
1370 {
1371 del_policies_outbound(this, this->my_addr, this->other_addr,
1372 my_ts, other_ts, &my_sa, &other_sa,
1373 POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
1374 }
1375 }
1376 enumerator->destroy(enumerator);
1377 }
1378
1379 kernel_ipsec_sa_id_t id = {
1380 .src = this->my_addr,
1381 .dst = this->other_addr,
1382 .spi = this->other_spi,
1383 .proto = proto_ike2ip(this->protocol),
1384 .mark = this->mark_out,
1385 };
1386 kernel_ipsec_del_sa_t sa = {
1387 .cpi = this->other_cpi,
1388 };
1389 charon->kernel->del_sa(charon->kernel, &id, &sa);
1390 this->outbound_state = CHILD_OUTBOUND_NONE;
1391 }
1392
1393 METHOD(child_sa_t, set_rekey_spi, void,
1394 private_child_sa_t *this, uint32_t spi)
1395 {
1396 this->rekey_spi = spi;
1397 }
1398
1399 METHOD(child_sa_t, get_rekey_spi, uint32_t,
1400 private_child_sa_t *this)
1401 {
1402 return this->rekey_spi;
1403 }
1404
1405 /**
1406 * Callback to reinstall a virtual IP
1407 */
1408 static void reinstall_vip(host_t *vip, host_t *me)
1409 {
1410 char *iface;
1411
1412 if (charon->kernel->get_interface(charon->kernel, me, &iface))
1413 {
1414 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
1415 charon->kernel->add_ip(charon->kernel, vip, -1, iface);
1416 free(iface);
1417 }
1418 }
1419
1420 METHOD(child_sa_t, update, status_t,
1421 private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
1422 bool encap)
1423 {
1424 child_sa_state_t old;
1425 bool transport_proxy_mode;
1426
1427 /* anything changed at all? */
1428 if (me->equals(me, this->my_addr) &&
1429 other->equals(other, this->other_addr) && this->encap == encap)
1430 {
1431 return SUCCESS;
1432 }
1433
1434 old = this->state;
1435 set_state(this, CHILD_UPDATING);
1436 transport_proxy_mode = this->mode == MODE_TRANSPORT &&
1437 this->config->has_option(this->config,
1438 OPT_PROXY_MODE);
1439
1440 if (!transport_proxy_mode)
1441 {
1442 /* update our (initiator) SA */
1443 if (this->my_spi)
1444 {
1445 kernel_ipsec_sa_id_t id = {
1446 .src = this->other_addr,
1447 .dst = this->my_addr,
1448 .spi = this->my_spi,
1449 .proto = proto_ike2ip(this->protocol),
1450 };
1451 kernel_ipsec_update_sa_t sa = {
1452 .cpi = this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
1453 .new_src = other,
1454 .new_dst = me,
1455 .encap = this->encap,
1456 .new_encap = encap,
1457 };
1458 if (charon->kernel->update_sa(charon->kernel, &id,
1459 &sa) == NOT_SUPPORTED)
1460 {
1461 set_state(this, old);
1462 return NOT_SUPPORTED;
1463 }
1464 }
1465
1466 /* update his (responder) SA */
1467 if (this->other_spi)
1468 {
1469 kernel_ipsec_sa_id_t id = {
1470 .src = this->my_addr,
1471 .dst = this->other_addr,
1472 .spi = this->other_spi,
1473 .proto = proto_ike2ip(this->protocol),
1474 .mark = this->mark_out,
1475 };
1476 kernel_ipsec_update_sa_t sa = {
1477 .cpi = this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
1478 .new_src = me,
1479 .new_dst = other,
1480 .encap = this->encap,
1481 .new_encap = encap,
1482 };
1483 if (charon->kernel->update_sa(charon->kernel, &id,
1484 &sa) == NOT_SUPPORTED)
1485 {
1486 set_state(this, old);
1487 return NOT_SUPPORTED;
1488 }
1489 }
1490 }
1491
1492 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1493 require_policy_update())
1494 {
1495 if (!me->ip_equals(me, this->my_addr) ||
1496 !other->ip_equals(other, this->other_addr))
1497 {
1498 ipsec_sa_cfg_t my_sa, other_sa;
1499 enumerator_t *enumerator;
1500 traffic_selector_t *my_ts, *other_ts;
1501 uint32_t manual_prio;
1502
1503 prepare_sa_cfg(this, &my_sa, &other_sa);
1504 manual_prio = this->config->get_manual_prio(this->config);
1505
1506 /* always use high priorities, as hosts getting updated are INSTALLED */
1507 enumerator = create_policy_enumerator(this);
1508 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1509 {
1510 traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
1511
1512 /* remove old policies first */
1513 del_policies_internal(this, this->my_addr, this->other_addr,
1514 my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC,
1515 POLICY_PRIORITY_DEFAULT, manual_prio);
1516
1517 /* check if we have to update a "dynamic" traffic selector */
1518 if (!me->ip_equals(me, this->my_addr) &&
1519 my_ts->is_host(my_ts, this->my_addr))
1520 {
1521 old_my_ts = my_ts->clone(my_ts);
1522 my_ts->set_address(my_ts, me);
1523 }
1524 if (!other->ip_equals(other, this->other_addr) &&
1525 other_ts->is_host(other_ts, this->other_addr))
1526 {
1527 old_other_ts = other_ts->clone(other_ts);
1528 other_ts->set_address(other_ts, other);
1529 }
1530
1531 /* we reinstall the virtual IP to handle interface roaming
1532 * correctly */
1533 vips->invoke_function(vips, (void*)reinstall_vip, me);
1534
1535 /* reinstall updated policies */
1536 install_policies_internal(this, me, other, my_ts, other_ts,
1537 &my_sa, &other_sa, POLICY_IPSEC,
1538 POLICY_PRIORITY_DEFAULT, manual_prio);
1539
1540 /* update fallback policies after the new policy is in place */
1541 if (manual_prio == 0)
1542 {
1543 del_policies_outbound(this, this->my_addr, this->other_addr,
1544 old_my_ts ?: my_ts,
1545 old_other_ts ?: other_ts,
1546 &my_sa, &other_sa, POLICY_DROP,
1547 POLICY_PRIORITY_FALLBACK, 0);
1548 install_policies_outbound(this, me, other, my_ts, other_ts,
1549 &my_sa, &other_sa, POLICY_DROP,
1550 POLICY_PRIORITY_FALLBACK, 0);
1551 }
1552 DESTROY_IF(old_my_ts);
1553 DESTROY_IF(old_other_ts);
1554 }
1555 enumerator->destroy(enumerator);
1556 }
1557 }
1558
1559 if (!transport_proxy_mode)
1560 {
1561 /* apply hosts */
1562 if (!me->equals(me, this->my_addr))
1563 {
1564 this->my_addr->destroy(this->my_addr);
1565 this->my_addr = me->clone(me);
1566 }
1567 if (!other->equals(other, this->other_addr))
1568 {
1569 this->other_addr->destroy(this->other_addr);
1570 this->other_addr = other->clone(other);
1571 }
1572 }
1573
1574 this->encap = encap;
1575 set_state(this, old);
1576
1577 return SUCCESS;
1578 }
1579
1580 METHOD(child_sa_t, destroy, void,
1581 private_child_sa_t *this)
1582 {
1583 enumerator_t *enumerator;
1584 traffic_selector_t *my_ts, *other_ts;
1585 policy_priority_t priority;
1586
1587 priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
1588
1589 set_state(this, CHILD_DESTROYING);
1590
1591 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1592 {
1593 ipsec_sa_cfg_t my_sa, other_sa;
1594 uint32_t manual_prio;
1595 bool del_outbound;
1596
1597 prepare_sa_cfg(this, &my_sa, &other_sa);
1598 manual_prio = this->config->get_manual_prio(this->config);
1599 del_outbound = this->trap ||
1600 this->outbound_state == CHILD_OUTBOUND_INSTALLED;
1601
1602 /* delete all policies in the kernel */
1603 enumerator = create_policy_enumerator(this);
1604 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1605 {
1606 if (del_outbound)
1607 {
1608 del_policies_outbound(this, this->my_addr,
1609 this->other_addr, my_ts, other_ts,
1610 &my_sa, &other_sa, POLICY_IPSEC,
1611 priority, manual_prio);
1612 }
1613 del_policies_inbound(this, this->my_addr, this->other_addr,
1614 my_ts, other_ts, &my_sa, &other_sa,
1615 POLICY_IPSEC, priority, manual_prio);
1616 if (!this->trap && manual_prio == 0 && require_policy_update() &&
1617 del_outbound)
1618 {
1619 del_policies_outbound(this, this->my_addr, this->other_addr,
1620 my_ts, other_ts, &my_sa, &other_sa,
1621 POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
1622 }
1623 }
1624 enumerator->destroy(enumerator);
1625 }
1626
1627 /* delete SAs in the kernel, if they are set up */
1628 if (this->my_spi)
1629 {
1630 kernel_ipsec_sa_id_t id = {
1631 .src = this->other_addr,
1632 .dst = this->my_addr,
1633 .spi = this->my_spi,
1634 .proto = proto_ike2ip(this->protocol),
1635 };
1636 kernel_ipsec_del_sa_t sa = {
1637 .cpi = this->my_cpi,
1638 };
1639 charon->kernel->del_sa(charon->kernel, &id, &sa);
1640 }
1641 if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED)
1642 {
1643 kernel_ipsec_sa_id_t id = {
1644 .src = this->my_addr,
1645 .dst = this->other_addr,
1646 .spi = this->other_spi,
1647 .proto = proto_ike2ip(this->protocol),
1648 .mark = this->mark_out,
1649 };
1650 kernel_ipsec_del_sa_t sa = {
1651 .cpi = this->other_cpi,
1652 };
1653 charon->kernel->del_sa(charon->kernel, &id, &sa);
1654 }
1655
1656 if (this->reqid_allocated)
1657 {
1658 if (charon->kernel->release_reqid(charon->kernel,
1659 this->reqid, this->mark_in, this->mark_out) != SUCCESS)
1660 {
1661 DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
1662 }
1663 }
1664
1665 array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
1666 array_destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
1667 this->my_addr->destroy(this->my_addr);
1668 this->other_addr->destroy(this->other_addr);
1669 DESTROY_IF(this->proposal);
1670 this->config->destroy(this->config);
1671 chunk_clear(&this->encr_r);
1672 chunk_clear(&this->integ_r);
1673 free(this);
1674 }
1675
1676 /**
1677 * Get proxy address for one side, if any
1678 */
1679 static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local)
1680 {
1681 host_t *host = NULL;
1682 uint8_t mask;
1683 enumerator_t *enumerator;
1684 linked_list_t *ts_list, *list;
1685 traffic_selector_t *ts;
1686
1687 list = linked_list_create_with_items(ike, NULL);
1688 ts_list = config->get_traffic_selectors(config, local, NULL, list);
1689 list->destroy(list);
1690
1691 enumerator = ts_list->create_enumerator(ts_list);
1692 while (enumerator->enumerate(enumerator, &ts))
1693 {
1694 if (ts->is_host(ts, NULL) && ts->to_subnet(ts, &host, &mask))
1695 {
1696 DBG1(DBG_CHD, "%s address: %H is a transport mode proxy for %H",
1697 local ? "my" : "other", ike, host);
1698 break;
1699 }
1700 }
1701 enumerator->destroy(enumerator);
1702 ts_list->destroy_offset(ts_list, offsetof(traffic_selector_t, destroy));
1703
1704 if (!host)
1705 {
1706 host = ike->clone(ike);
1707 }
1708 return host;
1709 }
1710
1711 /**
1712 * Described in header.
1713 */
1714 child_sa_t * child_sa_create(host_t *me, host_t* other,
1715 child_cfg_t *config, uint32_t rekey, bool encap,
1716 u_int mark_in, u_int mark_out)
1717 {
1718 private_child_sa_t *this;
1719 static refcount_t unique_id = 0, unique_mark = 0;
1720 refcount_t mark;
1721
1722 INIT(this,
1723 .public = {
1724 .get_name = _get_name,
1725 .get_reqid = _get_reqid,
1726 .get_unique_id = _get_unique_id,
1727 .get_config = _get_config,
1728 .get_state = _get_state,
1729 .set_state = _set_state,
1730 .get_outbound_state = _get_outbound_state,
1731 .get_spi = _get_spi,
1732 .get_cpi = _get_cpi,
1733 .get_protocol = _get_protocol,
1734 .set_protocol = _set_protocol,
1735 .get_mode = _get_mode,
1736 .set_mode = _set_mode,
1737 .get_proposal = _get_proposal,
1738 .set_proposal = _set_proposal,
1739 .get_lifetime = _get_lifetime,
1740 .get_installtime = _get_installtime,
1741 .get_usestats = _get_usestats,
1742 .get_mark = _get_mark,
1743 .has_encap = _has_encap,
1744 .get_ipcomp = _get_ipcomp,
1745 .set_ipcomp = _set_ipcomp,
1746 .get_close_action = _get_close_action,
1747 .set_close_action = _set_close_action,
1748 .get_dpd_action = _get_dpd_action,
1749 .set_dpd_action = _set_dpd_action,
1750 .alloc_spi = _alloc_spi,
1751 .alloc_cpi = _alloc_cpi,
1752 .install = _install,
1753 .register_outbound = _register_outbound,
1754 .install_outbound = _install_outbound,
1755 .remove_outbound = _remove_outbound,
1756 .set_rekey_spi = _set_rekey_spi,
1757 .get_rekey_spi = _get_rekey_spi,
1758 .update = _update,
1759 .set_policies = _set_policies,
1760 .install_policies = _install_policies,
1761 .create_ts_enumerator = _create_ts_enumerator,
1762 .create_policy_enumerator = _create_policy_enumerator,
1763 .destroy = _destroy,
1764 },
1765 .encap = encap,
1766 .ipcomp = IPCOMP_NONE,
1767 .state = CHILD_CREATED,
1768 .my_ts = array_create(0, 0),
1769 .other_ts = array_create(0, 0),
1770 .protocol = PROTO_NONE,
1771 .mode = MODE_TUNNEL,
1772 .close_action = config->get_close_action(config),
1773 .dpd_action = config->get_dpd_action(config),
1774 .reqid = config->get_reqid(config),
1775 .unique_id = ref_get(&unique_id),
1776 .mark_in = config->get_mark(config, TRUE),
1777 .mark_out = config->get_mark(config, FALSE),
1778 .install_time = time_monotonic(NULL),
1779 .policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
1780 );
1781
1782 this->config = config;
1783 config->get_ref(config);
1784
1785 if (mark_in)
1786 {
1787 this->mark_in.value = mark_in;
1788 }
1789 if (mark_out)
1790 {
1791 this->mark_out.value = mark_out;
1792 }
1793 if (this->mark_in.value == MARK_UNIQUE ||
1794 this->mark_out.value == MARK_UNIQUE)
1795 {
1796 mark = ref_get(&unique_mark);
1797 if (this->mark_in.value == MARK_UNIQUE)
1798 {
1799 this->mark_in.value = mark;
1800 }
1801 if (this->mark_out.value == MARK_UNIQUE)
1802 {
1803 this->mark_out.value = mark;
1804 }
1805 }
1806
1807 if (!this->reqid)
1808 {
1809 /* reuse old reqid if we are rekeying an existing CHILD_SA. While the
1810 * reqid cache would find the same reqid for our selectors, this does
1811 * not work in a special case: If an SA is triggered by a trap policy,
1812 * but the negotiated SA gets narrowed, we still must reuse the same
1813 * reqid to successfully "trigger" the SA on the kernel level. Rekeying
1814 * such an SA requires an explicit reqid, as the cache currently knows
1815 * the original selectors only for that reqid. */
1816 if (rekey)
1817 {
1818 this->reqid = rekey;
1819 }
1820 else
1821 {
1822 this->reqid = charon->traps->find_reqid(charon->traps, config);
1823 }
1824 }
1825 else
1826 {
1827 this->static_reqid = TRUE;
1828 }
1829
1830 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1831 if (config->get_mode(config) == MODE_TRANSPORT &&
1832 config->has_option(config, OPT_PROXY_MODE))
1833 {
1834 this->mode = MODE_TRANSPORT;
1835
1836 this->my_addr = get_proxy_addr(config, me, TRUE);
1837 this->other_addr = get_proxy_addr(config, other, FALSE);
1838 }
1839 else
1840 {
1841 this->my_addr = me->clone(me);
1842 this->other_addr = other->clone(other);
1843 }
1844 return &this->public;
1845 }