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