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