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