]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libtnccs / plugins / tnccs_dynamic / tnccs_dynamic.c
1 /*
2 * Copyright (C) 2011-2015 Andreas Steffen
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "tnccs_dynamic.h"
18
19 #include <tnc/tnc.h>
20
21 #include <utils/debug.h>
22
23 typedef struct private_tnccs_dynamic_t private_tnccs_dynamic_t;
24
25 /**
26 * Private data of a tnccs_dynamic_t object.
27 */
28 struct private_tnccs_dynamic_t {
29
30 /**
31 * Public tnccs_t interface.
32 */
33 tnccs_t public;
34
35 /**
36 * Server identity
37 */
38 identification_t *server_id;
39
40 /**
41 * Client identity
42 */
43 identification_t *peer_id;
44
45 /**
46 * Server IP address
47 */
48 host_t *server_ip;
49
50 /**
51 * Client IP address
52 */
53 host_t *peer_ip;
54
55 /**
56 * Detected TNC IF-TNCCS stack
57 */
58 tls_t *tls;
59
60 /**
61 * Underlying TNC IF-T transport protocol
62 */
63 tnc_ift_type_t transport;
64
65 /**
66 * Type of TNC client authentication
67 */
68 uint32_t auth_type;
69
70 /**
71 * Callback function to communicate recommendation (TNC Server only)
72 */
73 tnccs_cb_t callback;
74
75 /**
76 * reference count
77 */
78 refcount_t ref;
79
80 };
81
82 /**
83 * Determine the version of the IF-TNCCS protocol used by analyzing the first
84 * byte of the TNCCS batch received from a TNC Client according to the rules
85 * defined by section 3.5 "Interoperability with older IF-TNCCS versions" of
86 * the TCG TNC IF-TNCCS TLV Bindings Version 2.0 standard.
87 */
88 tnccs_type_t determine_tnccs_protocol(char version)
89 {
90 switch (version)
91 {
92 case '\t':
93 case '\n':
94 case '\r':
95 case ' ':
96 case '<':
97 return TNCCS_1_1;
98 case 0x00:
99 return TNCCS_SOH;
100 case 0x02:
101 return TNCCS_2_0;
102 default:
103 return TNCCS_UNKNOWN;
104 }
105 }
106
107 METHOD(tls_t, process, status_t,
108 private_tnccs_dynamic_t *this, void *buf, size_t buflen)
109 {
110 tnccs_type_t type;
111 tnccs_t *tnccs;
112
113 if (!this->tls)
114 {
115 if (buflen == 0)
116 {
117 return FAILED;
118 }
119 type = determine_tnccs_protocol(*(char*)buf);
120 DBG1(DBG_TNC, "%N protocol detected dynamically",
121 tnccs_type_names, type);
122 tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, TRUE,
123 this->server_id, this->peer_id, this->server_ip,
124 this->peer_ip, this->transport, this->callback);
125 if (!tnccs)
126 {
127 DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type);
128 return FAILED;
129 }
130 tnccs->set_auth_type(tnccs, this->auth_type);
131 this->tls = &tnccs->tls;
132 }
133 return this->tls->process(this->tls, buf, buflen);
134 }
135
136 METHOD(tls_t, build, status_t,
137 private_tnccs_dynamic_t *this, void *buf, size_t *buflen, size_t *msglen)
138 {
139 return this->tls->build(this->tls, buf, buflen, msglen);
140 }
141
142 METHOD(tls_t, is_server, bool,
143 private_tnccs_dynamic_t *this)
144 {
145 return TRUE;
146 }
147
148 METHOD(tls_t, get_server_id, identification_t*,
149 private_tnccs_dynamic_t *this)
150 {
151 return this->server_id;
152 }
153
154 METHOD(tls_t, set_peer_id, void,
155 private_tnccs_dynamic_t *this, identification_t *id)
156 {
157 DESTROY_IF(this->peer_id);
158 this->peer_id = id->clone(id);
159 if (this->tls)
160 {
161 this->tls->set_peer_id(this->tls, id);
162 }
163 }
164
165 METHOD(tls_t, get_peer_id, identification_t*,
166 private_tnccs_dynamic_t *this)
167 {
168 return this->peer_id;
169 }
170
171 METHOD(tls_t, get_purpose, tls_purpose_t,
172 private_tnccs_dynamic_t *this)
173 {
174 return TLS_PURPOSE_EAP_TNC;
175 }
176
177 METHOD(tls_t, is_complete, bool,
178 private_tnccs_dynamic_t *this)
179 {
180 return this->tls ? this->tls->is_complete(this->tls) : FALSE;
181 }
182
183 METHOD(tls_t, get_eap_msk, chunk_t,
184 private_tnccs_dynamic_t *this)
185 {
186 return chunk_empty;
187 }
188
189 METHOD(tls_t, destroy, void,
190 private_tnccs_dynamic_t *this)
191 {
192 if (ref_put(&this->ref))
193 {
194 DESTROY_IF(this->tls);
195 this->server_id->destroy(this->server_id);
196 this->peer_id->destroy(this->peer_id);
197 this->server_ip->destroy(this->server_ip);
198 this->peer_ip->destroy(this->peer_ip);
199 free(this);
200 }
201 }
202
203 METHOD(tnccs_t, get_server_ip, host_t*,
204 private_tnccs_dynamic_t *this)
205 {
206 return this->server_ip;
207 }
208
209 METHOD(tnccs_t, get_peer_ip, host_t*,
210 private_tnccs_dynamic_t *this)
211 {
212 return this->peer_ip;
213 }
214
215 METHOD(tnccs_t, get_transport, tnc_ift_type_t,
216 private_tnccs_dynamic_t *this)
217 {
218 return this->transport;
219 }
220
221 METHOD(tnccs_t, set_transport, void,
222 private_tnccs_dynamic_t *this, tnc_ift_type_t transport)
223 {
224 this->transport = transport;
225 }
226
227 METHOD(tnccs_t, get_auth_type, uint32_t,
228 private_tnccs_dynamic_t *this)
229 {
230 return this->auth_type;
231 }
232
233 METHOD(tnccs_t, set_auth_type, void,
234 private_tnccs_dynamic_t *this, uint32_t auth_type)
235 {
236 this->auth_type = auth_type;
237 }
238
239 METHOD(tnccs_t, get_pdp_server, chunk_t,
240 private_tnccs_dynamic_t *this, uint16_t *port)
241 {
242 tnccs_t *tnccs = (tnccs_t*)this->tls;
243
244 return tnccs->get_pdp_server(tnccs, port);
245 }
246
247 METHOD(tnccs_t, get_ref, tnccs_t*,
248 private_tnccs_dynamic_t *this)
249 {
250 ref_get(&this->ref);
251 return &this->public;
252 }
253
254 /**
255 * See header
256 */
257 tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id,
258 identification_t *peer_id, host_t *server_ip,
259 host_t *peer_ip, tnc_ift_type_t transport,
260 tnccs_cb_t cb)
261 {
262 private_tnccs_dynamic_t *this;
263
264 INIT(this,
265 .public = {
266 .tls = {
267 .process = _process,
268 .build = _build,
269 .is_server = _is_server,
270 .get_server_id = _get_server_id,
271 .set_peer_id = _set_peer_id,
272 .get_peer_id = _get_peer_id,
273 .get_purpose = _get_purpose,
274 .is_complete = _is_complete,
275 .get_eap_msk = _get_eap_msk,
276 .destroy = _destroy,
277 },
278 .get_server_ip = _get_server_ip,
279 .get_peer_ip = _get_peer_ip,
280 .get_transport = _get_transport,
281 .set_transport = _set_transport,
282 .get_auth_type = _get_auth_type,
283 .set_auth_type = _set_auth_type,
284 .get_pdp_server = _get_pdp_server,
285 .get_ref = _get_ref,
286 },
287 .server_id = server_id->clone(server_id),
288 .peer_id = peer_id->clone(peer_id),
289 .server_ip = server_ip->clone(server_ip),
290 .peer_ip = peer_ip->clone(peer_ip),
291 .transport = transport,
292 .callback = cb,
293 .ref = 1,
294 );
295
296 return &this->public;
297 }