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