Merge commit 'child-sa-rekey-tkm'
[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_FLAGS(child_sa_outbound_state_names, CHILD_OUTBOUND_REGISTERED, CHILD_OUTBOUND_POLICIES,
44 "REGISTERED",
45 "SA",
46 "POLICIES",
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, va_list args)
439 {
440 traffic_selector_t *other_ts, **my_out, **other_out;
441
442 VA_ARGS_VGET(args, my_out, other_out);
443
444 while (this->ts || this->mine->enumerate(this->mine, &this->ts))
445 {
446 if (!this->other->enumerate(this->other, &other_ts))
447 { /* end of others list, restart with new of mine */
448 this->other->destroy(this->other);
449 this->other = array_create_enumerator(this->array);
450 this->ts = NULL;
451 continue;
452 }
453 if (this->ts->get_type(this->ts) != other_ts->get_type(other_ts))
454 { /* family mismatch */
455 continue;
456 }
457 if (this->ts->get_protocol(this->ts) &&
458 other_ts->get_protocol(other_ts) &&
459 this->ts->get_protocol(this->ts) != other_ts->get_protocol(other_ts))
460 { /* protocol mismatch */
461 continue;
462 }
463 if (my_out)
464 {
465 *my_out = this->ts;
466 }
467 if (other_out)
468 {
469 *other_out = other_ts;
470 }
471 return TRUE;
472 }
473 return FALSE;
474 }
475
476 METHOD(enumerator_t, policy_destroy, void,
477 policy_enumerator_t *this)
478 {
479 this->mine->destroy(this->mine);
480 this->other->destroy(this->other);
481 free(this);
482 }
483
484 METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
485 private_child_sa_t *this)
486 {
487 policy_enumerator_t *e;
488
489 INIT(e,
490 .public = {
491 .enumerate = enumerator_enumerate_default,
492 .venumerate = _policy_enumerate,
493 .destroy = _policy_destroy,
494 },
495 .mine = array_create_enumerator(this->my_ts),
496 .other = array_create_enumerator(this->other_ts),
497 .array = this->other_ts,
498 .ts = NULL,
499 );
500
501 return &e->public;
502 }
503
504 /**
505 * update the cached usebytes
506 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
507 * are available, and NOT_SUPPORTED if the kernel interface does not support
508 * querying the usebytes.
509 */
510 static status_t update_usebytes(private_child_sa_t *this, bool inbound)
511 {
512 status_t status = FAILED;
513 uint64_t bytes, packets;
514 time_t time;
515
516 if (inbound)
517 {
518 if (this->my_spi)
519 {
520 kernel_ipsec_sa_id_t id = {
521 .src = this->other_addr,
522 .dst = this->my_addr,
523 .spi = this->my_spi,
524 .proto = proto_ike2ip(this->protocol),
525 };
526 kernel_ipsec_query_sa_t query = {};
527
528 status = charon->kernel->query_sa(charon->kernel, &id, &query,
529 &bytes, &packets, &time);
530 if (status == SUCCESS)
531 {
532 if (bytes > this->my_usebytes)
533 {
534 this->my_usebytes = bytes;
535 this->my_usepackets = packets;
536 if (time)
537 {
538 this->my_usetime = time;
539 }
540 }
541 else
542 {
543 status = FAILED;
544 }
545 }
546 }
547 }
548 else
549 {
550 if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
551 {
552 kernel_ipsec_sa_id_t id = {
553 .src = this->my_addr,
554 .dst = this->other_addr,
555 .spi = this->other_spi,
556 .proto = proto_ike2ip(this->protocol),
557 .mark = this->mark_out,
558 };
559 kernel_ipsec_query_sa_t query = {};
560
561 status = charon->kernel->query_sa(charon->kernel, &id, &query,
562 &bytes, &packets, &time);
563 if (status == SUCCESS)
564 {
565 if (bytes > this->other_usebytes)
566 {
567 this->other_usebytes = bytes;
568 this->other_usepackets = packets;
569 if (time)
570 {
571 this->other_usetime = time;
572 }
573 }
574 else
575 {
576 status = FAILED;
577 }
578 }
579 }
580 }
581 return status;
582 }
583
584 /**
585 * updates the cached usetime
586 */
587 static bool update_usetime(private_child_sa_t *this, bool inbound)
588 {
589 enumerator_t *enumerator;
590 traffic_selector_t *my_ts, *other_ts;
591 time_t last_use = 0;
592
593 enumerator = create_policy_enumerator(this);
594 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
595 {
596 time_t in, out, fwd;
597
598 if (inbound)
599 {
600 kernel_ipsec_policy_id_t id = {
601 .dir = POLICY_IN,
602 .src_ts = other_ts,
603 .dst_ts = my_ts,
604 .mark = this->mark_in,
605 };
606 kernel_ipsec_query_policy_t query = {};
607
608 if (charon->kernel->query_policy(charon->kernel, &id, &query,
609 &in) == SUCCESS)
610 {
611 last_use = max(last_use, in);
612 }
613 if (this->mode != MODE_TRANSPORT)
614 {
615 id.dir = POLICY_FWD;
616 if (charon->kernel->query_policy(charon->kernel, &id, &query,
617 &fwd) == SUCCESS)
618 {
619 last_use = max(last_use, fwd);
620 }
621 }
622 }
623 else
624 {
625 kernel_ipsec_policy_id_t id = {
626 .dir = POLICY_OUT,
627 .src_ts = my_ts,
628 .dst_ts = other_ts,
629 .mark = this->mark_out,
630 .interface = this->config->get_interface(this->config),
631 };
632 kernel_ipsec_query_policy_t query = {};
633
634 if (charon->kernel->query_policy(charon->kernel, &id, &query,
635 &out) == SUCCESS)
636 {
637 last_use = max(last_use, out);
638 }
639 }
640 }
641 enumerator->destroy(enumerator);
642
643 if (last_use == 0)
644 {
645 return FALSE;
646 }
647 if (inbound)
648 {
649 this->my_usetime = last_use;
650 }
651 else
652 {
653 this->other_usetime = last_use;
654 }
655 return TRUE;
656 }
657
658 METHOD(child_sa_t, get_usestats, void,
659 private_child_sa_t *this, bool inbound,
660 time_t *time, uint64_t *bytes, uint64_t *packets)
661 {
662 if ((!bytes && !packets) || update_usebytes(this, inbound) != FAILED)
663 {
664 /* there was traffic since last update or the kernel interface
665 * does not support querying the number of usebytes.
666 */
667 if (time)
668 {
669 if (!update_usetime(this, inbound) && !bytes && !packets)
670 {
671 /* if policy query did not yield a usetime, query SAs instead */
672 update_usebytes(this, inbound);
673 }
674 }
675 }
676 if (time)
677 {
678 *time = inbound ? this->my_usetime : this->other_usetime;
679 }
680 if (bytes)
681 {
682 *bytes = inbound ? this->my_usebytes : this->other_usebytes;
683 }
684 if (packets)
685 {
686 *packets = inbound ? this->my_usepackets : this->other_usepackets;
687 }
688 }
689
690 METHOD(child_sa_t, get_mark, mark_t,
691 private_child_sa_t *this, bool inbound)
692 {
693 if (inbound)
694 {
695 return this->mark_in;
696 }
697 return this->mark_out;
698 }
699
700 METHOD(child_sa_t, get_lifetime, time_t,
701 private_child_sa_t *this, bool hard)
702 {
703 return hard ? this->expire_time : this->rekey_time;
704 }
705
706 METHOD(child_sa_t, get_installtime, time_t,
707 private_child_sa_t *this)
708 {
709 return this->install_time;
710 }
711
712 METHOD(child_sa_t, alloc_spi, uint32_t,
713 private_child_sa_t *this, protocol_id_t protocol)
714 {
715 if (charon->kernel->get_spi(charon->kernel, this->other_addr, this->my_addr,
716 proto_ike2ip(protocol), &this->my_spi) == SUCCESS)
717 {
718 /* if we allocate a SPI, but then are unable to establish the SA, we
719 * need to know the protocol family to delete the partial SA */
720 this->protocol = protocol;
721 return this->my_spi;
722 }
723 return 0;
724 }
725
726 METHOD(child_sa_t, alloc_cpi, uint16_t,
727 private_child_sa_t *this)
728 {
729 if (charon->kernel->get_cpi(charon->kernel, this->other_addr, this->my_addr,
730 &this->my_cpi) == SUCCESS)
731 {
732 return this->my_cpi;
733 }
734 return 0;
735 }
736
737 /**
738 * Install the given SA in the kernel
739 */
740 static status_t install_internal(private_child_sa_t *this, chunk_t encr,
741 chunk_t integ, uint32_t spi, uint16_t cpi, bool initiator, bool inbound,
742 bool tfcv3)
743 {
744 uint16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
745 uint16_t esn = NO_EXT_SEQ_NUMBERS;
746 linked_list_t *my_ts, *other_ts, *src_ts, *dst_ts;
747 time_t now;
748 kernel_ipsec_sa_id_t id;
749 kernel_ipsec_add_sa_t sa;
750 lifetime_cfg_t *lifetime;
751 uint32_t tfc = 0;
752 host_t *src, *dst;
753 status_t status;
754 bool update = FALSE;
755
756 /* BEET requires the bound address from the traffic selectors */
757 my_ts = linked_list_create_from_enumerator(
758 array_create_enumerator(this->my_ts));
759 other_ts = linked_list_create_from_enumerator(
760 array_create_enumerator(this->other_ts));
761
762 /* now we have to decide which spi to use. Use self allocated, if "in",
763 * or the one in the proposal, if not "in" (others). Additionally,
764 * source and dest host switch depending on the role */
765 if (inbound)
766 {
767 dst = this->my_addr;
768 src = this->other_addr;
769 if (this->my_spi == spi)
770 { /* alloc_spi has been called, do an SA update */
771 update = TRUE;
772 }
773 this->my_spi = spi;
774 this->my_cpi = cpi;
775 dst_ts = my_ts;
776 src_ts = other_ts;
777 }
778 else
779 {
780 src = this->my_addr;
781 dst = this->other_addr;
782 this->other_spi = spi;
783 this->other_cpi = cpi;
784 src_ts = my_ts;
785 dst_ts = other_ts;
786
787 if (tfcv3)
788 {
789 tfc = this->config->get_tfc(this->config);
790 }
791 this->outbound_state |= CHILD_OUTBOUND_SA;
792 }
793
794 DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
795 protocol_id_names, this->protocol);
796
797 /* send SA down to the kernel */
798 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
799
800 this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
801 &enc_alg, &size);
802 this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
803 &int_alg, &size);
804 this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
805 &esn, NULL);
806
807 if (int_alg == AUTH_HMAC_SHA2_256_128 &&
808 this->config->has_option(this->config, OPT_SHA256_96))
809 {
810 DBG2(DBG_CHD, " using %N with 96-bit truncation",
811 integrity_algorithm_names, int_alg);
812 int_alg = AUTH_HMAC_SHA2_256_96;
813 }
814
815 if (!this->reqid_allocated && !this->static_reqid)
816 {
817 status = charon->kernel->alloc_reqid(charon->kernel, my_ts, other_ts,
818 this->mark_in, this->mark_out, &this->reqid);
819 if (status != SUCCESS)
820 {
821 my_ts->destroy(my_ts);
822 other_ts->destroy(other_ts);
823 return status;
824 }
825 this->reqid_allocated = TRUE;
826 }
827
828 lifetime = this->config->get_lifetime(this->config, TRUE);
829
830 now = time_monotonic(NULL);
831 if (lifetime->time.rekey)
832 {
833 if (this->rekey_time)
834 {
835 this->rekey_time = min(this->rekey_time, now + lifetime->time.rekey);
836 }
837 else
838 {
839 this->rekey_time = now + lifetime->time.rekey;
840 }
841 }
842 if (lifetime->time.life)
843 {
844 this->expire_time = now + lifetime->time.life;
845 }
846
847 if (!lifetime->time.jitter && !inbound)
848 { /* avoid triggering multiple rekey events */
849 lifetime->time.rekey = 0;
850 }
851
852 id = (kernel_ipsec_sa_id_t){
853 .src = src,
854 .dst = dst,
855 .spi = spi,
856 .proto = proto_ike2ip(this->protocol),
857 .mark = inbound ? (mark_t){} : this->mark_out,
858 };
859 sa = (kernel_ipsec_add_sa_t){
860 .reqid = this->reqid,
861 .mode = this->mode,
862 .src_ts = src_ts,
863 .dst_ts = dst_ts,
864 .interface = inbound ? NULL : this->config->get_interface(this->config),
865 .lifetime = lifetime,
866 .enc_alg = enc_alg,
867 .enc_key = encr,
868 .int_alg = int_alg,
869 .int_key = integ,
870 .replay_window = this->config->get_replay_window(this->config),
871 .tfc = tfc,
872 .ipcomp = this->ipcomp,
873 .cpi = cpi,
874 .encap = this->encap,
875 .hw_offload = this->config->has_option(this->config, OPT_HW_OFFLOAD),
876 .esn = esn,
877 .initiator = initiator,
878 .inbound = inbound,
879 .update = update,
880 };
881
882 status = charon->kernel->add_sa(charon->kernel, &id, &sa);
883
884 my_ts->destroy(my_ts);
885 other_ts->destroy(other_ts);
886 free(lifetime);
887
888 return status;
889 }
890
891 METHOD(child_sa_t, install, status_t,
892 private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
893 uint16_t cpi, bool initiator, bool inbound, bool tfcv3)
894 {
895 return install_internal(this, encr, integ, spi, cpi, initiator, inbound,
896 tfcv3);
897 }
898
899 /**
900 * Check kernel interface if policy updates are required
901 */
902 static bool require_policy_update()
903 {
904 kernel_feature_t f;
905
906 f = charon->kernel->get_features(charon->kernel);
907 return !(f & KERNEL_NO_POLICY_UPDATES);
908 }
909
910 /**
911 * Prepare SA config to install/delete policies
912 */
913 static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa,
914 ipsec_sa_cfg_t *other_sa)
915 {
916 enumerator_t *enumerator;
917
918 *my_sa = (ipsec_sa_cfg_t){
919 .mode = this->mode,
920 .reqid = this->reqid,
921 .ipcomp = {
922 .transform = this->ipcomp,
923 },
924 };
925 *other_sa = *my_sa;
926
927 my_sa->ipcomp.cpi = this->my_cpi;
928 other_sa->ipcomp.cpi = this->other_cpi;
929
930 if (this->protocol == PROTO_ESP)
931 {
932 my_sa->esp.use = TRUE;
933 my_sa->esp.spi = this->my_spi;
934 other_sa->esp.use = TRUE;
935 other_sa->esp.spi = this->other_spi;
936 }
937 else
938 {
939 my_sa->ah.use = TRUE;
940 my_sa->ah.spi = this->my_spi;
941 other_sa->ah.use = TRUE;
942 other_sa->ah.spi = this->other_spi;
943 }
944
945 enumerator = create_policy_enumerator(this);
946 while (enumerator->enumerate(enumerator, NULL, NULL))
947 {
948 my_sa->policy_count++;
949 other_sa->policy_count++;
950 }
951 enumerator->destroy(enumerator);
952 }
953
954 /**
955 * Install inbound policie(s): in, fwd
956 */
957 static status_t install_policies_inbound(private_child_sa_t *this,
958 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
959 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
960 ipsec_sa_cfg_t *other_sa, policy_type_t type,
961 policy_priority_t priority, uint32_t manual_prio)
962 {
963 kernel_ipsec_policy_id_t in_id = {
964 .dir = POLICY_IN,
965 .src_ts = other_ts,
966 .dst_ts = my_ts,
967 .mark = this->mark_in,
968 };
969 kernel_ipsec_manage_policy_t in_policy = {
970 .type = type,
971 .prio = priority,
972 .manual_prio = manual_prio,
973 .src = other_addr,
974 .dst = my_addr,
975 .sa = my_sa,
976 };
977 status_t status = SUCCESS;
978
979 status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
980 if (this->mode != MODE_TRANSPORT)
981 {
982 in_id.dir = POLICY_FWD;
983 status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
984 }
985 return status;
986 }
987
988 /**
989 * Install outbound policie(s): out, [fwd]
990 */
991 static status_t install_policies_outbound(private_child_sa_t *this,
992 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
993 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
994 ipsec_sa_cfg_t *other_sa, policy_type_t type,
995 policy_priority_t priority, uint32_t manual_prio)
996 {
997 kernel_ipsec_policy_id_t out_id = {
998 .dir = POLICY_OUT,
999 .src_ts = my_ts,
1000 .dst_ts = other_ts,
1001 .mark = this->mark_out,
1002 .interface = this->config->get_interface(this->config),
1003 };
1004 kernel_ipsec_manage_policy_t out_policy = {
1005 .type = type,
1006 .prio = priority,
1007 .manual_prio = manual_prio,
1008 .src = my_addr,
1009 .dst = other_addr,
1010 .sa = other_sa,
1011 };
1012 status_t status = SUCCESS;
1013
1014 status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy);
1015
1016 if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
1017 {
1018 /* install an "outbound" FWD policy in case there is a drop policy
1019 * matching outbound forwarded traffic, to allow another tunnel to use
1020 * the reversed subnets and do the same we don't set a reqid (this also
1021 * allows the kernel backend to distinguish between the two types of
1022 * FWD policies). To avoid problems with symmetrically overlapping
1023 * policies of two SAs we install them with reduced priority. As they
1024 * basically act as bypass policies for drop policies we use a higher
1025 * priority than is used for them. */
1026 out_id.dir = POLICY_FWD;
1027 other_sa->reqid = 0;
1028 if (priority == POLICY_PRIORITY_DEFAULT)
1029 {
1030 out_policy.prio = POLICY_PRIORITY_ROUTED;
1031 }
1032 status |= charon->kernel->add_policy(charon->kernel, &out_id,
1033 &out_policy);
1034 /* reset the reqid for any other further policies */
1035 other_sa->reqid = this->reqid;
1036 }
1037 return status;
1038 }
1039
1040 /**
1041 * Install all policies
1042 */
1043 static status_t install_policies_internal(private_child_sa_t *this,
1044 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1045 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1046 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1047 policy_priority_t priority, uint32_t manual_prio)
1048 {
1049 status_t status = SUCCESS;
1050
1051 status |= install_policies_inbound(this, my_addr, other_addr, my_ts,
1052 other_ts, my_sa, other_sa, type,
1053 priority, manual_prio);
1054 status |= install_policies_outbound(this, my_addr, other_addr, my_ts,
1055 other_ts, my_sa, other_sa, type,
1056 priority, manual_prio);
1057 return status;
1058 }
1059
1060 /**
1061 * Delete inbound policies: in, fwd
1062 */
1063 static void del_policies_inbound(private_child_sa_t *this,
1064 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1065 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1066 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1067 policy_priority_t priority, uint32_t manual_prio)
1068 {
1069 kernel_ipsec_policy_id_t in_id = {
1070 .dir = POLICY_IN,
1071 .src_ts = other_ts,
1072 .dst_ts = my_ts,
1073 .mark = this->mark_in,
1074 };
1075 kernel_ipsec_manage_policy_t in_policy = {
1076 .type = type,
1077 .prio = priority,
1078 .manual_prio = manual_prio,
1079 .src = other_addr,
1080 .dst = my_addr,
1081 .sa = my_sa,
1082 };
1083
1084 charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
1085
1086 if (this->mode != MODE_TRANSPORT)
1087 {
1088 in_id.dir = POLICY_FWD;
1089 charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
1090 }
1091 }
1092
1093 /**
1094 * Delete outbound policies: out, [fwd]
1095 */
1096 static void del_policies_outbound(private_child_sa_t *this,
1097 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1098 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1099 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1100 policy_priority_t priority, uint32_t manual_prio)
1101 {
1102 kernel_ipsec_policy_id_t out_id = {
1103 .dir = POLICY_OUT,
1104 .src_ts = my_ts,
1105 .dst_ts = other_ts,
1106 .mark = this->mark_out,
1107 .interface = this->config->get_interface(this->config),
1108 };
1109 kernel_ipsec_manage_policy_t out_policy = {
1110 .type = type,
1111 .prio = priority,
1112 .manual_prio = manual_prio,
1113 .src = my_addr,
1114 .dst = other_addr,
1115 .sa = other_sa,
1116 };
1117
1118 charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
1119
1120 if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
1121 {
1122 out_id.dir = POLICY_FWD;
1123 other_sa->reqid = 0;
1124 if (priority == POLICY_PRIORITY_DEFAULT)
1125 {
1126 out_policy.prio = POLICY_PRIORITY_ROUTED;
1127 }
1128 charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
1129 other_sa->reqid = this->reqid;
1130 }
1131 }
1132
1133 /**
1134 * Delete in- and outbound policies
1135 */
1136 static void del_policies_internal(private_child_sa_t *this,
1137 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1138 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1139 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1140 policy_priority_t priority, uint32_t manual_prio)
1141 {
1142 del_policies_outbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
1143 other_sa, type, priority, manual_prio);
1144 del_policies_inbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
1145 other_sa, type, priority, manual_prio);
1146 }
1147
1148 METHOD(child_sa_t, set_policies, void,
1149 private_child_sa_t *this, linked_list_t *my_ts_list,
1150 linked_list_t *other_ts_list)
1151 {
1152 enumerator_t *enumerator;
1153 traffic_selector_t *my_ts, *other_ts;
1154
1155 if (array_count(this->my_ts))
1156 {
1157 array_destroy_offset(this->my_ts,
1158 offsetof(traffic_selector_t, destroy));
1159 this->my_ts = array_create(0, 0);
1160 }
1161 enumerator = my_ts_list->create_enumerator(my_ts_list);
1162 while (enumerator->enumerate(enumerator, &my_ts))
1163 {
1164 array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts));
1165 }
1166 enumerator->destroy(enumerator);
1167 array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL);
1168
1169 if (array_count(this->other_ts))
1170 {
1171 array_destroy_offset(this->other_ts,
1172 offsetof(traffic_selector_t, destroy));
1173 this->other_ts = array_create(0, 0);
1174 }
1175 enumerator = other_ts_list->create_enumerator(other_ts_list);
1176 while (enumerator->enumerate(enumerator, &other_ts))
1177 {
1178 array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts));
1179 }
1180 enumerator->destroy(enumerator);
1181 array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL);
1182 }
1183
1184 METHOD(child_sa_t, install_policies, status_t,
1185 private_child_sa_t *this)
1186 {
1187 enumerator_t *enumerator;
1188 linked_list_t *my_ts_list, *other_ts_list;
1189 traffic_selector_t *my_ts, *other_ts;
1190 status_t status = SUCCESS;
1191 bool install_outbound = FALSE;
1192
1193 if (!this->reqid_allocated && !this->static_reqid)
1194 {
1195 my_ts_list = linked_list_create_from_enumerator(
1196 array_create_enumerator(this->my_ts));
1197 other_ts_list = linked_list_create_from_enumerator(
1198 array_create_enumerator(this->other_ts));
1199 status = charon->kernel->alloc_reqid(
1200 charon->kernel, my_ts_list, other_ts_list,
1201 this->mark_in, this->mark_out, &this->reqid);
1202 my_ts_list->destroy(my_ts_list);
1203 other_ts_list->destroy(other_ts_list);
1204 if (status != SUCCESS)
1205 {
1206 return status;
1207 }
1208 this->reqid_allocated = TRUE;
1209 }
1210
1211 if (!(this->outbound_state & CHILD_OUTBOUND_REGISTERED))
1212 {
1213 install_outbound = TRUE;
1214 this->outbound_state |= CHILD_OUTBOUND_POLICIES;
1215 }
1216
1217 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1218 {
1219 policy_priority_t priority;
1220 ipsec_sa_cfg_t my_sa, other_sa;
1221 uint32_t manual_prio;
1222
1223 prepare_sa_cfg(this, &my_sa, &other_sa);
1224 manual_prio = this->config->get_manual_prio(this->config);
1225
1226 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1227 * entry) we install a trap policy */
1228 this->trap = this->state == CHILD_CREATED;
1229 priority = this->trap ? POLICY_PRIORITY_ROUTED
1230 : POLICY_PRIORITY_DEFAULT;
1231
1232 /* enumerate pairs of traffic selectors */
1233 enumerator = create_policy_enumerator(this);
1234 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1235 {
1236 /* install outbound drop policy to avoid packets leaving unencrypted
1237 * when updating policies */
1238 if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
1239 require_policy_update() && install_outbound)
1240 {
1241 status |= install_policies_outbound(this, this->my_addr,
1242 this->other_addr, my_ts, other_ts,
1243 &my_sa, &other_sa, POLICY_DROP,
1244 POLICY_PRIORITY_FALLBACK, 0);
1245 }
1246
1247 status |= install_policies_inbound(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 if (install_outbound)
1253 {
1254 status |= install_policies_outbound(this, this->my_addr,
1255 this->other_addr, my_ts, other_ts,
1256 &my_sa, &other_sa, POLICY_IPSEC,
1257 priority, manual_prio);
1258 }
1259 if (status != SUCCESS)
1260 {
1261 break;
1262 }
1263 }
1264 enumerator->destroy(enumerator);
1265 }
1266
1267 if (status == SUCCESS && this->trap)
1268 {
1269 set_state(this, CHILD_ROUTED);
1270 }
1271 return status;
1272 }
1273
1274 METHOD(child_sa_t, register_outbound, status_t,
1275 private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
1276 uint16_t cpi, bool tfcv3)
1277 {
1278 status_t status;
1279
1280 /* if the kernel supports installing SPIs with policies we install the
1281 * SA immediately as it will only be used once we update the policies */
1282 if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI)
1283 {
1284 status = install_internal(this, encr, integ, spi, cpi, FALSE, FALSE,
1285 tfcv3);
1286 }
1287 else
1288 {
1289 DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names,
1290 this->protocol);
1291 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr,
1292 this->other_addr);
1293
1294 this->other_spi = spi;
1295 this->other_cpi = cpi;
1296 this->encr_r = chunk_clone(encr);
1297 this->integ_r = chunk_clone(integ);
1298 this->tfcv3 = tfcv3;
1299 status = SUCCESS;
1300 }
1301 this->outbound_state |= CHILD_OUTBOUND_REGISTERED;
1302 return status;
1303 }
1304
1305 METHOD(child_sa_t, install_outbound, status_t,
1306 private_child_sa_t *this)
1307 {
1308 enumerator_t *enumerator;
1309 traffic_selector_t *my_ts, *other_ts;
1310 status_t status = SUCCESS;
1311
1312 if (!(this->outbound_state & CHILD_OUTBOUND_SA))
1313 {
1314 status = install_internal(this, this->encr_r, this->integ_r,
1315 this->other_spi, this->other_cpi, FALSE,
1316 FALSE, this->tfcv3);
1317 chunk_clear(&this->encr_r);
1318 chunk_clear(&this->integ_r);
1319 }
1320 this->outbound_state &= ~CHILD_OUTBOUND_REGISTERED;
1321 if (status != SUCCESS)
1322 {
1323 return status;
1324 }
1325 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1326 !(this->outbound_state & CHILD_OUTBOUND_POLICIES))
1327 {
1328 ipsec_sa_cfg_t my_sa, other_sa;
1329 uint32_t manual_prio;
1330
1331 prepare_sa_cfg(this, &my_sa, &other_sa);
1332 manual_prio = this->config->get_manual_prio(this->config);
1333
1334 enumerator = create_policy_enumerator(this);
1335 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1336 {
1337 /* install outbound drop policy to avoid packets leaving unencrypted
1338 * when updating policies */
1339 if (manual_prio == 0 && require_policy_update())
1340 {
1341 status |= install_policies_outbound(this, this->my_addr,
1342 this->other_addr, my_ts, other_ts,
1343 &my_sa, &other_sa, POLICY_DROP,
1344 POLICY_PRIORITY_FALLBACK, 0);
1345 }
1346 status |= install_policies_outbound(this, this->my_addr,
1347 this->other_addr, my_ts, other_ts,
1348 &my_sa, &other_sa, POLICY_IPSEC,
1349 POLICY_PRIORITY_DEFAULT, manual_prio);
1350 if (status != SUCCESS)
1351 {
1352 break;
1353 }
1354 }
1355 enumerator->destroy(enumerator);
1356 }
1357 this->outbound_state |= CHILD_OUTBOUND_POLICIES;
1358 return status;
1359 }
1360
1361 METHOD(child_sa_t, remove_outbound, void,
1362 private_child_sa_t *this)
1363 {
1364 enumerator_t *enumerator;
1365 traffic_selector_t *my_ts, *other_ts;
1366
1367 if (!(this->outbound_state & CHILD_OUTBOUND_SA))
1368 {
1369 if (this->outbound_state & CHILD_OUTBOUND_REGISTERED)
1370 {
1371 chunk_clear(&this->encr_r);
1372 chunk_clear(&this->integ_r);
1373 this->outbound_state = CHILD_OUTBOUND_NONE;
1374 }
1375 return;
1376 }
1377
1378 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1379 (this->outbound_state & CHILD_OUTBOUND_POLICIES))
1380 {
1381 ipsec_sa_cfg_t my_sa, other_sa;
1382 uint32_t manual_prio;
1383
1384 prepare_sa_cfg(this, &my_sa, &other_sa);
1385 manual_prio = this->config->get_manual_prio(this->config);
1386
1387 enumerator = create_policy_enumerator(this);
1388 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1389 {
1390 del_policies_outbound(this, this->my_addr, this->other_addr,
1391 my_ts, other_ts, &my_sa, &other_sa,
1392 POLICY_IPSEC, POLICY_PRIORITY_DEFAULT,
1393 manual_prio);
1394 if (manual_prio == 0 && require_policy_update())
1395 {
1396 del_policies_outbound(this, this->my_addr, this->other_addr,
1397 my_ts, other_ts, &my_sa, &other_sa,
1398 POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
1399 }
1400 }
1401 enumerator->destroy(enumerator);
1402 }
1403
1404 kernel_ipsec_sa_id_t id = {
1405 .src = this->my_addr,
1406 .dst = this->other_addr,
1407 .spi = this->other_spi,
1408 .proto = proto_ike2ip(this->protocol),
1409 .mark = this->mark_out,
1410 };
1411 kernel_ipsec_del_sa_t sa = {
1412 .cpi = this->other_cpi,
1413 };
1414 charon->kernel->del_sa(charon->kernel, &id, &sa);
1415 this->outbound_state = CHILD_OUTBOUND_NONE;
1416 }
1417
1418 METHOD(child_sa_t, set_rekey_spi, void,
1419 private_child_sa_t *this, uint32_t spi)
1420 {
1421 this->rekey_spi = spi;
1422 }
1423
1424 METHOD(child_sa_t, get_rekey_spi, uint32_t,
1425 private_child_sa_t *this)
1426 {
1427 return this->rekey_spi;
1428 }
1429
1430 CALLBACK(reinstall_vip, void,
1431 host_t *vip, va_list args)
1432 {
1433 host_t *me;
1434 char *iface;
1435
1436 VA_ARGS_VGET(args, me);
1437 if (charon->kernel->get_interface(charon->kernel, me, &iface))
1438 {
1439 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
1440 charon->kernel->add_ip(charon->kernel, vip, -1, iface);
1441 free(iface);
1442 }
1443 }
1444
1445 METHOD(child_sa_t, update, status_t,
1446 private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
1447 bool encap)
1448 {
1449 child_sa_state_t old;
1450 bool transport_proxy_mode;
1451
1452 /* anything changed at all? */
1453 if (me->equals(me, this->my_addr) &&
1454 other->equals(other, this->other_addr) && this->encap == encap)
1455 {
1456 return SUCCESS;
1457 }
1458
1459 old = this->state;
1460 set_state(this, CHILD_UPDATING);
1461 transport_proxy_mode = this->mode == MODE_TRANSPORT &&
1462 this->config->has_option(this->config,
1463 OPT_PROXY_MODE);
1464
1465 if (!transport_proxy_mode)
1466 {
1467 /* update our (initiator) SA */
1468 if (this->my_spi)
1469 {
1470 kernel_ipsec_sa_id_t id = {
1471 .src = this->other_addr,
1472 .dst = this->my_addr,
1473 .spi = this->my_spi,
1474 .proto = proto_ike2ip(this->protocol),
1475 };
1476 kernel_ipsec_update_sa_t sa = {
1477 .cpi = this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
1478 .new_src = other,
1479 .new_dst = me,
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 /* update his (responder) SA */
1492 if (this->other_spi)
1493 {
1494 kernel_ipsec_sa_id_t id = {
1495 .src = this->my_addr,
1496 .dst = this->other_addr,
1497 .spi = this->other_spi,
1498 .proto = proto_ike2ip(this->protocol),
1499 .mark = this->mark_out,
1500 };
1501 kernel_ipsec_update_sa_t sa = {
1502 .cpi = this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
1503 .new_src = me,
1504 .new_dst = other,
1505 .encap = this->encap,
1506 .new_encap = encap,
1507 };
1508 if (charon->kernel->update_sa(charon->kernel, &id,
1509 &sa) == NOT_SUPPORTED)
1510 {
1511 set_state(this, old);
1512 return NOT_SUPPORTED;
1513 }
1514 }
1515 }
1516
1517 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1518 require_policy_update())
1519 {
1520 if (!me->ip_equals(me, this->my_addr) ||
1521 !other->ip_equals(other, this->other_addr))
1522 {
1523 ipsec_sa_cfg_t my_sa, other_sa;
1524 enumerator_t *enumerator;
1525 traffic_selector_t *my_ts, *other_ts;
1526 uint32_t manual_prio;
1527
1528 prepare_sa_cfg(this, &my_sa, &other_sa);
1529 manual_prio = this->config->get_manual_prio(this->config);
1530
1531 /* always use high priorities, as hosts getting updated are INSTALLED */
1532 enumerator = create_policy_enumerator(this);
1533 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1534 {
1535 traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
1536
1537 /* remove old policies first */
1538 del_policies_internal(this, this->my_addr, this->other_addr,
1539 my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC,
1540 POLICY_PRIORITY_DEFAULT, manual_prio);
1541
1542 /* check if we have to update a "dynamic" traffic selector */
1543 if (!me->ip_equals(me, this->my_addr) &&
1544 my_ts->is_host(my_ts, this->my_addr))
1545 {
1546 old_my_ts = my_ts->clone(my_ts);
1547 my_ts->set_address(my_ts, me);
1548 }
1549 if (!other->ip_equals(other, this->other_addr) &&
1550 other_ts->is_host(other_ts, this->other_addr))
1551 {
1552 old_other_ts = other_ts->clone(other_ts);
1553 other_ts->set_address(other_ts, other);
1554 }
1555
1556 /* we reinstall the virtual IP to handle interface roaming
1557 * correctly */
1558 vips->invoke_function(vips, reinstall_vip, me);
1559
1560 /* reinstall updated policies */
1561 install_policies_internal(this, me, other, my_ts, other_ts,
1562 &my_sa, &other_sa, POLICY_IPSEC,
1563 POLICY_PRIORITY_DEFAULT, manual_prio);
1564
1565 /* update fallback policies after the new policy is in place */
1566 if (manual_prio == 0)
1567 {
1568 del_policies_outbound(this, this->my_addr, this->other_addr,
1569 old_my_ts ?: my_ts,
1570 old_other_ts ?: other_ts,
1571 &my_sa, &other_sa, POLICY_DROP,
1572 POLICY_PRIORITY_FALLBACK, 0);
1573 install_policies_outbound(this, me, other, my_ts, other_ts,
1574 &my_sa, &other_sa, POLICY_DROP,
1575 POLICY_PRIORITY_FALLBACK, 0);
1576 }
1577 DESTROY_IF(old_my_ts);
1578 DESTROY_IF(old_other_ts);
1579 }
1580 enumerator->destroy(enumerator);
1581 }
1582 }
1583
1584 if (!transport_proxy_mode)
1585 {
1586 /* apply hosts */
1587 if (!me->equals(me, this->my_addr))
1588 {
1589 this->my_addr->destroy(this->my_addr);
1590 this->my_addr = me->clone(me);
1591 }
1592 if (!other->equals(other, this->other_addr))
1593 {
1594 this->other_addr->destroy(this->other_addr);
1595 this->other_addr = other->clone(other);
1596 }
1597 }
1598
1599 this->encap = encap;
1600 set_state(this, old);
1601
1602 return SUCCESS;
1603 }
1604
1605 METHOD(child_sa_t, destroy, void,
1606 private_child_sa_t *this)
1607 {
1608 enumerator_t *enumerator;
1609 traffic_selector_t *my_ts, *other_ts;
1610 policy_priority_t priority;
1611
1612 priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
1613
1614 set_state(this, CHILD_DESTROYING);
1615
1616 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1617 {
1618 ipsec_sa_cfg_t my_sa, other_sa;
1619 uint32_t manual_prio;
1620 bool del_outbound;
1621
1622 prepare_sa_cfg(this, &my_sa, &other_sa);
1623 manual_prio = this->config->get_manual_prio(this->config);
1624 del_outbound = (this->outbound_state & CHILD_OUTBOUND_POLICIES) ||
1625 this->trap;
1626
1627 /* delete all policies in the kernel */
1628 enumerator = create_policy_enumerator(this);
1629 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1630 {
1631 if (del_outbound)
1632 {
1633 del_policies_outbound(this, this->my_addr,
1634 this->other_addr, my_ts, other_ts,
1635 &my_sa, &other_sa, POLICY_IPSEC,
1636 priority, manual_prio);
1637 }
1638 del_policies_inbound(this, this->my_addr, this->other_addr,
1639 my_ts, other_ts, &my_sa, &other_sa,
1640 POLICY_IPSEC, priority, manual_prio);
1641 if (!this->trap && manual_prio == 0 && require_policy_update() &&
1642 del_outbound)
1643 {
1644 del_policies_outbound(this, this->my_addr, this->other_addr,
1645 my_ts, other_ts, &my_sa, &other_sa,
1646 POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
1647 }
1648 }
1649 enumerator->destroy(enumerator);
1650 }
1651
1652 /* delete SAs in the kernel, if they are set up */
1653 if (this->my_spi)
1654 {
1655 kernel_ipsec_sa_id_t id = {
1656 .src = this->other_addr,
1657 .dst = this->my_addr,
1658 .spi = this->my_spi,
1659 .proto = proto_ike2ip(this->protocol),
1660 };
1661 kernel_ipsec_del_sa_t sa = {
1662 .cpi = this->my_cpi,
1663 };
1664 charon->kernel->del_sa(charon->kernel, &id, &sa);
1665 }
1666 if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
1667 {
1668 kernel_ipsec_sa_id_t id = {
1669 .src = this->my_addr,
1670 .dst = this->other_addr,
1671 .spi = this->other_spi,
1672 .proto = proto_ike2ip(this->protocol),
1673 .mark = this->mark_out,
1674 };
1675 kernel_ipsec_del_sa_t sa = {
1676 .cpi = this->other_cpi,
1677 };
1678 charon->kernel->del_sa(charon->kernel, &id, &sa);
1679 }
1680
1681 if (this->reqid_allocated)
1682 {
1683 if (charon->kernel->release_reqid(charon->kernel,
1684 this->reqid, this->mark_in, this->mark_out) != SUCCESS)
1685 {
1686 DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
1687 }
1688 }
1689
1690 array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
1691 array_destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
1692 this->my_addr->destroy(this->my_addr);
1693 this->other_addr->destroy(this->other_addr);
1694 DESTROY_IF(this->proposal);
1695 this->config->destroy(this->config);
1696 chunk_clear(&this->encr_r);
1697 chunk_clear(&this->integ_r);
1698 free(this);
1699 }
1700
1701 /**
1702 * Get proxy address for one side, if any
1703 */
1704 static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local)
1705 {
1706 host_t *host = NULL;
1707 uint8_t mask;
1708 enumerator_t *enumerator;
1709 linked_list_t *ts_list, *list;
1710 traffic_selector_t *ts;
1711
1712 list = linked_list_create_with_items(ike, NULL);
1713 ts_list = config->get_traffic_selectors(config, local, NULL, list);
1714 list->destroy(list);
1715
1716 enumerator = ts_list->create_enumerator(ts_list);
1717 while (enumerator->enumerate(enumerator, &ts))
1718 {
1719 if (ts->is_host(ts, NULL) && ts->to_subnet(ts, &host, &mask))
1720 {
1721 DBG1(DBG_CHD, "%s address: %H is a transport mode proxy for %H",
1722 local ? "my" : "other", ike, host);
1723 break;
1724 }
1725 }
1726 enumerator->destroy(enumerator);
1727 ts_list->destroy_offset(ts_list, offsetof(traffic_selector_t, destroy));
1728
1729 if (!host)
1730 {
1731 host = ike->clone(ike);
1732 }
1733 return host;
1734 }
1735
1736 /**
1737 * Described in header.
1738 */
1739 child_sa_t * child_sa_create(host_t *me, host_t* other,
1740 child_cfg_t *config, uint32_t rekey, bool encap,
1741 u_int mark_in, u_int mark_out)
1742 {
1743 private_child_sa_t *this;
1744 static refcount_t unique_id = 0, unique_mark = 0;
1745 refcount_t mark;
1746
1747 INIT(this,
1748 .public = {
1749 .get_name = _get_name,
1750 .get_reqid = _get_reqid,
1751 .get_unique_id = _get_unique_id,
1752 .get_config = _get_config,
1753 .get_state = _get_state,
1754 .set_state = _set_state,
1755 .get_outbound_state = _get_outbound_state,
1756 .get_spi = _get_spi,
1757 .get_cpi = _get_cpi,
1758 .get_protocol = _get_protocol,
1759 .set_protocol = _set_protocol,
1760 .get_mode = _get_mode,
1761 .set_mode = _set_mode,
1762 .get_proposal = _get_proposal,
1763 .set_proposal = _set_proposal,
1764 .get_lifetime = _get_lifetime,
1765 .get_installtime = _get_installtime,
1766 .get_usestats = _get_usestats,
1767 .get_mark = _get_mark,
1768 .has_encap = _has_encap,
1769 .get_ipcomp = _get_ipcomp,
1770 .set_ipcomp = _set_ipcomp,
1771 .get_close_action = _get_close_action,
1772 .set_close_action = _set_close_action,
1773 .get_dpd_action = _get_dpd_action,
1774 .set_dpd_action = _set_dpd_action,
1775 .alloc_spi = _alloc_spi,
1776 .alloc_cpi = _alloc_cpi,
1777 .install = _install,
1778 .register_outbound = _register_outbound,
1779 .install_outbound = _install_outbound,
1780 .remove_outbound = _remove_outbound,
1781 .set_rekey_spi = _set_rekey_spi,
1782 .get_rekey_spi = _get_rekey_spi,
1783 .update = _update,
1784 .set_policies = _set_policies,
1785 .install_policies = _install_policies,
1786 .create_ts_enumerator = _create_ts_enumerator,
1787 .create_policy_enumerator = _create_policy_enumerator,
1788 .destroy = _destroy,
1789 },
1790 .encap = encap,
1791 .ipcomp = IPCOMP_NONE,
1792 .state = CHILD_CREATED,
1793 .my_ts = array_create(0, 0),
1794 .other_ts = array_create(0, 0),
1795 .protocol = PROTO_NONE,
1796 .mode = MODE_TUNNEL,
1797 .close_action = config->get_close_action(config),
1798 .dpd_action = config->get_dpd_action(config),
1799 .reqid = config->get_reqid(config),
1800 .unique_id = ref_get(&unique_id),
1801 .mark_in = config->get_mark(config, TRUE),
1802 .mark_out = config->get_mark(config, FALSE),
1803 .install_time = time_monotonic(NULL),
1804 .policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
1805 );
1806
1807 this->config = config;
1808 config->get_ref(config);
1809
1810 if (mark_in)
1811 {
1812 this->mark_in.value = mark_in;
1813 }
1814 if (mark_out)
1815 {
1816 this->mark_out.value = mark_out;
1817 }
1818 if (this->mark_in.value == MARK_UNIQUE ||
1819 this->mark_out.value == MARK_UNIQUE)
1820 {
1821 mark = ref_get(&unique_mark);
1822 if (this->mark_in.value == MARK_UNIQUE)
1823 {
1824 this->mark_in.value = mark;
1825 }
1826 if (this->mark_out.value == MARK_UNIQUE)
1827 {
1828 this->mark_out.value = mark;
1829 }
1830 }
1831
1832 if (!this->reqid)
1833 {
1834 /* reuse old reqid if we are rekeying an existing CHILD_SA. While the
1835 * reqid cache would find the same reqid for our selectors, this does
1836 * not work in a special case: If an SA is triggered by a trap policy,
1837 * but the negotiated SA gets narrowed, we still must reuse the same
1838 * reqid to successfully "trigger" the SA on the kernel level. Rekeying
1839 * such an SA requires an explicit reqid, as the cache currently knows
1840 * the original selectors only for that reqid. */
1841 if (rekey)
1842 {
1843 this->reqid = rekey;
1844 }
1845 else
1846 {
1847 this->reqid = charon->traps->find_reqid(charon->traps, config);
1848 }
1849 }
1850 else
1851 {
1852 this->static_reqid = TRUE;
1853 }
1854
1855 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1856 if (config->get_mode(config) == MODE_TRANSPORT &&
1857 config->has_option(config, OPT_PROXY_MODE))
1858 {
1859 this->mode = MODE_TRANSPORT;
1860
1861 this->my_addr = get_proxy_addr(config, me, TRUE);
1862 this->other_addr = get_proxy_addr(config, other, FALSE);
1863 }
1864 else
1865 {
1866 this->my_addr = me->clone(me);
1867 this->other_addr = other->clone(other);
1868 }
1869 return &this->public;
1870 }