Add Cisco Unity client support for Split-Include and Local-LAN
[strongswan.git] / src / libcharon / plugins / unity / unity_narrow.c
1 /*
2 * Copyright (C) 2012 Martin Willi
3 * Copyright (C) 2012 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "unity_narrow.h"
17
18 #include <daemon.h>
19
20 typedef struct private_unity_narrow_t private_unity_narrow_t;
21
22 /**
23 * Private data of an unity_narrow_t object.
24 */
25 struct private_unity_narrow_t {
26
27 /**
28 * Public unity_narrow_t interface.
29 */
30 unity_narrow_t public;
31
32 /**
33 * Unity attribute handler
34 */
35 unity_handler_t *handler;
36 };
37
38 METHOD(listener_t, narrow, bool,
39 private_unity_narrow_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
40 narrow_hook_t type, linked_list_t *local, linked_list_t *remote)
41 {
42 traffic_selector_t *current, *orig = NULL;
43 enumerator_t *enumerator;
44
45 if (type == NARROW_INITIATOR_POST_AUTH &&
46 remote->get_count(remote) == 1)
47 {
48 enumerator = this->handler->create_include_enumerator(this->handler,
49 ike_sa->get_unique_id(ike_sa));
50 while (enumerator->enumerate(enumerator, &current))
51 {
52 if (orig == NULL)
53 { /* got one, replace original TS */
54 remote->remove_first(remote, (void**)&orig);
55 }
56 remote->insert_last(remote, orig->get_subset(orig, current));
57 }
58 enumerator->destroy(enumerator);
59 if (orig)
60 {
61 DBG1(DBG_CFG, "narrowed CHILD_SA to %N %#R",
62 configuration_attribute_type_names,
63 UNITY_SPLIT_INCLUDE, remote);
64 orig->destroy(orig);
65 }
66 }
67 return TRUE;
68 }
69
70 METHOD(unity_narrow_t, destroy, void,
71 private_unity_narrow_t *this)
72 {
73 free(this);
74 }
75
76 /**
77 * See header
78 */
79 unity_narrow_t *unity_narrow_create(unity_handler_t *handler)
80 {
81 private_unity_narrow_t *this;
82
83 INIT(this,
84 .public = {
85 .listener = {
86 .narrow = _narrow,
87 },
88 .destroy = _destroy,
89 },
90 .handler = handler,
91 );
92
93 return &this->public;
94 }