Annotation of embedaddon/strongswan/src/libcharon/plugins/unity/unity_provider.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2013 Tobias Brunner
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * Copyright (C) 2012 Martin Willi
6: * Copyright (C) 2012 revosec AG
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: #include "unity_provider.h"
20:
21: #include <daemon.h>
22: #include <bio/bio_writer.h>
23:
24: typedef struct private_unity_provider_t private_unity_provider_t;
25:
26: /**
27: * Private data of an unity_provider_t object.
28: */
29: struct private_unity_provider_t {
30:
31: /**
32: * Public unity_provider_t interface.
33: */
34: unity_provider_t public;
35: };
36:
37: /**
38: * Attribute enumerator for UNITY_SPLIT_INCLUDE attribute
39: */
40: typedef struct {
41: /** Implements enumerator_t */
42: enumerator_t public;
43: /** list of traffic selectors to enumerate */
44: linked_list_t *list;
45: /** attribute value */
46: chunk_t attr;
47: } attribute_enumerator_t;
48:
49: /**
50: * Append data from the given traffic selector to the attribute data
51: */
52: static void append_ts(bio_writer_t *writer, traffic_selector_t *ts)
53: {
54: host_t *net, *mask;
55: chunk_t padding;
56: uint8_t bits;
57:
58: if (!ts->to_subnet(ts, &net, &bits))
59: {
60: return;
61: }
62: mask = host_create_netmask(AF_INET, bits);
63: if (!mask)
64: {
65: net->destroy(net);
66: return;
67: }
68: writer->write_data(writer, net->get_address(net));
69: writer->write_data(writer, mask->get_address(mask));
70: /* the Cisco client parses the "padding" as protocol, src and dst port, the
71: * first two in network order the last in host order - no other clients seem
72: * to support these fields so we don't use them either */
73: padding = writer->skip(writer, 6);
74: memset(padding.ptr, 0, padding.len);
75: mask->destroy(mask);
76: net->destroy(net);
77: }
78:
79: METHOD(enumerator_t, attribute_enumerate, bool,
80: attribute_enumerator_t *this, va_list args)
81: {
82: configuration_attribute_type_t *type;
83: chunk_t *attr;
84: traffic_selector_t *ts;
85: bio_writer_t *writer;
86:
87: VA_ARGS_VGET(args, type, attr);
88:
89: if (this->list->get_count(this->list) == 0)
90: {
91: return FALSE;
92: }
93:
94: writer = bio_writer_create(14);
95: while (this->list->remove_first(this->list, (void**)&ts) == SUCCESS)
96: {
97: append_ts(writer, ts);
98: ts->destroy(ts);
99: }
100:
101: *type = UNITY_SPLIT_INCLUDE;
102: *attr = this->attr = writer->extract_buf(writer);
103:
104: writer->destroy(writer);
105: return TRUE;
106: }
107:
108: METHOD(enumerator_t, attribute_destroy, void,
109: attribute_enumerator_t *this)
110: {
111: this->list->destroy_offset(this->list, offsetof(traffic_selector_t, destroy));
112: chunk_free(&this->attr);
113: free(this);
114: }
115:
116: /**
117: * Check if we should send a configured TS as Split-Include attribute
118: */
119: static bool use_ts(traffic_selector_t *ts)
120: {
121: uint8_t mask;
122: host_t *net;
123:
124: if (ts->get_type(ts) != TS_IPV4_ADDR_RANGE)
125: {
126: return FALSE;
127: }
128: if (ts->is_dynamic(ts))
129: {
130: return FALSE;
131: }
132: if (!ts->to_subnet(ts, &net, &mask))
133: {
134: return FALSE;
135: }
136: net->destroy(net);
137: return mask > 0;
138: }
139:
140: METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
141: private_unity_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
142: linked_list_t *vips)
143: {
144: attribute_enumerator_t *attr_enum;
145: enumerator_t *enumerator;
146: linked_list_t *list, *current;
147: traffic_selector_t *ts;
148: peer_cfg_t *peer_cfg;
149: child_cfg_t *child_cfg;
150:
151: if (ike_sa->get_version(ike_sa) != IKEV1 ||
152: !ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY) ||
153: !vips->get_count(vips))
154: {
155: return NULL;
156: }
157:
158: list = linked_list_create();
159: peer_cfg = ike_sa->get_peer_cfg(ike_sa);
160: enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
161: while (enumerator->enumerate(enumerator, &child_cfg))
162: {
163: current = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL,
164: FALSE);
165: while (current->remove_first(current, (void**)&ts) == SUCCESS)
166: {
167: if (use_ts(ts))
168: {
169: list->insert_last(list, ts);
170: }
171: else
172: {
173: ts->destroy(ts);
174: }
175: }
176: current->destroy(current);
177: }
178: enumerator->destroy(enumerator);
179:
180: if (list->get_count(list) == 0)
181: {
182: list->destroy(list);
183: return NULL;
184: }
185: DBG1(DBG_CFG, "sending %N: %#R",
186: configuration_attribute_type_names, UNITY_SPLIT_INCLUDE, list);
187:
188: INIT(attr_enum,
189: .public = {
190: .enumerate = enumerator_enumerate_default,
191: .venumerate = _attribute_enumerate,
192: .destroy = _attribute_destroy,
193: },
194: .list = list,
195: );
196:
197: return &attr_enum->public;
198: }
199:
200: METHOD(unity_provider_t, destroy, void,
201: private_unity_provider_t *this)
202: {
203: free(this);
204: }
205:
206: /**
207: * See header
208: */
209: unity_provider_t *unity_provider_create()
210: {
211: private_unity_provider_t *this;
212:
213: INIT(this,
214: .public = {
215: .provider = {
216: .acquire_address = (void*)return_null,
217: .release_address = (void*)return_false,
218: .create_attribute_enumerator = _create_attribute_enumerator,
219: },
220: .destroy = _destroy,
221: },
222: );
223:
224: return &this->public;
225: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>