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