register received scanner attributes
[strongswan.git] / src / libimcv / plugins / imv_scanner / imv_scanner_state.c
1 /*
2 * Copyright (C) 2011-2013 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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 "imv_scanner_state.h"
17 #include "imv/imv_lang_string.h"
18 #include "imv/imv_reason_string.h"
19 #include "imv/imv_remediation_string.h"
20
21 #include <tncif_policy.h>
22
23 #include <utils/lexparser.h>
24 #include <utils/debug.h>
25
26 typedef struct private_imv_scanner_state_t private_imv_scanner_state_t;
27
28 /**
29 * Private data of an imv_scanner_state_t object.
30 */
31 struct private_imv_scanner_state_t {
32
33 /**
34 * Public members of imv_scanner_state_t
35 */
36 imv_scanner_state_t public;
37
38 /**
39 * TNCCS connection ID
40 */
41 TNC_ConnectionID connection_id;
42
43 /**
44 * TNCCS connection state
45 */
46 TNC_ConnectionState state;
47
48 /**
49 * Does the TNCCS connection support long message types?
50 */
51 bool has_long;
52
53 /**
54 * Does the TNCCS connection support exclusive delivery?
55 */
56 bool has_excl;
57
58 /**
59 * Maximum PA-TNC message size for this TNCCS connection
60 */
61 u_int32_t max_msg_len;
62
63 /**
64 * Access Requestor ID Type
65 */
66 u_int32_t ar_id_type;
67
68 /**
69 * Access Requestor ID Value
70 */
71 chunk_t ar_id_value;
72
73 /**
74 * IMV database session associatied with TNCCS connection
75 */
76 imv_session_t *session;
77
78 /**
79 * IMV action recommendation
80 */
81 TNC_IMV_Action_Recommendation rec;
82
83 /**
84 * IMV evaluation result
85 */
86 TNC_IMV_Evaluation_Result eval;
87
88 /**
89 * IMV Scanner handshake state
90 */
91 imv_scanner_handshake_state_t handshake_state;
92
93 /**
94 * Flags set for received attributes
95 */
96 u_int received_flags;
97
98 /**
99 * List with ports that should be closed
100 */
101 linked_list_t *violating_ports;
102
103 /**
104 * TNC Reason String
105 */
106 imv_reason_string_t *reason_string;
107
108 /**
109 * IETF Remediation Instructions String
110 */
111 imv_remediation_string_t *remediation_string;
112
113 };
114
115 /**
116 * Supported languages
117 */
118 static char* languages[] = { "en", "de", "fr", "pl" };
119
120 /**
121 * Reason strings for "Port Filter"
122 */
123 static imv_lang_string_t reasons[] = {
124 { "en", "Open server ports were detected" },
125 { "de", "Offene Serverports wurden festgestellt" },
126 { "fr", "Il y a des ports du serveur ouverts" },
127 { "pl", "Są otwarte porty serwera" },
128 { NULL, NULL }
129 };
130
131 /**
132 * Instruction strings for "Port Filters"
133 */
134 static imv_lang_string_t instr_ports_title[] = {
135 { "en", "Open Server Ports" },
136 { "de", "Offene Server Ports" },
137 { "fr", "Ports ouverts du serveur" },
138 { "pl", "Otwarte Porty Serwera" },
139 { NULL, NULL }
140 };
141
142 static imv_lang_string_t instr_ports_descr[] = {
143 { "en", "Open Internet ports have been detected" },
144 { "de", "Offenen Internet-Ports wurden festgestellt" },
145 { "fr", "Il y'a des ports Internet ouverts" },
146 { "pl", "Porty internetowe są otwarte" },
147 { NULL, NULL }
148 };
149
150 static imv_lang_string_t instr_ports_header[] = {
151 { "en", "Please close the following server ports:" },
152 { "de", "Bitte schliessen Sie die folgenden Serverports:" },
153 { "fr", "Fermez les ports du serveur suivants s'il vous plait:" },
154 { "pl", "Proszę zamknąć następujące porty serwera:" },
155 { NULL, NULL }
156 };
157
158 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
159 private_imv_scanner_state_t *this)
160 {
161 return this->connection_id;
162 }
163
164 METHOD(imv_state_t, has_long, bool,
165 private_imv_scanner_state_t *this)
166 {
167 return this->has_long;
168 }
169
170 METHOD(imv_state_t, has_excl, bool,
171 private_imv_scanner_state_t *this)
172 {
173 return this->has_excl;
174 }
175
176 METHOD(imv_state_t, set_flags, void,
177 private_imv_scanner_state_t *this, bool has_long, bool has_excl)
178 {
179 this->has_long = has_long;
180 this->has_excl = has_excl;
181 }
182
183 METHOD(imv_state_t, set_max_msg_len, void,
184 private_imv_scanner_state_t *this, u_int32_t max_msg_len)
185 {
186 this->max_msg_len = max_msg_len;
187 }
188
189 METHOD(imv_state_t, get_max_msg_len, u_int32_t,
190 private_imv_scanner_state_t *this)
191 {
192 return this->max_msg_len;
193 }
194
195 METHOD(imv_state_t, set_ar_id, void,
196 private_imv_scanner_state_t *this, u_int32_t id_type, chunk_t id_value)
197 {
198 this->ar_id_type = id_type;
199 this->ar_id_value = chunk_clone(id_value);
200 }
201
202 METHOD(imv_state_t, get_ar_id, chunk_t,
203 private_imv_scanner_state_t *this, u_int32_t *id_type)
204 {
205 if (id_type)
206 {
207 *id_type = this->ar_id_type;
208 }
209 return this->ar_id_value;
210 }
211
212 METHOD(imv_state_t, set_session, void,
213 private_imv_scanner_state_t *this, imv_session_t *session)
214 {
215 this->session = session;
216 }
217
218 METHOD(imv_state_t, get_session, imv_session_t*,
219 private_imv_scanner_state_t *this)
220 {
221 return this->session;
222 }
223
224 METHOD(imv_state_t, change_state, void,
225 private_imv_scanner_state_t *this, TNC_ConnectionState new_state)
226 {
227 this->state = new_state;
228 }
229
230 METHOD(imv_state_t, get_recommendation, void,
231 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec,
232 TNC_IMV_Evaluation_Result *eval)
233 {
234 *rec = this->rec;
235 *eval = this->eval;
236 }
237
238 METHOD(imv_state_t, set_recommendation, void,
239 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
240 TNC_IMV_Evaluation_Result eval)
241 {
242 this->rec = rec;
243 this->eval = eval;
244 }
245
246 METHOD(imv_state_t, update_recommendation, void,
247 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
248 TNC_IMV_Evaluation_Result eval)
249 {
250 this->rec = tncif_policy_update_recommendation(this->rec, rec);
251 this->eval = tncif_policy_update_evaluation(this->eval, eval);
252 }
253
254 METHOD(imv_state_t, get_reason_string, bool,
255 private_imv_scanner_state_t *this, enumerator_t *language_enumerator,
256 chunk_t *reason_string, char **reason_language)
257 {
258 if (!this->violating_ports)
259 {
260 return FALSE;
261 }
262 *reason_language = imv_lang_string_select_lang(language_enumerator,
263 languages, countof(languages));
264
265 /* Instantiate a TNC Reason String object */
266 DESTROY_IF(this->reason_string);
267 this->reason_string = imv_reason_string_create(*reason_language);
268 this->reason_string->add_reason(this->reason_string, reasons);
269 *reason_string = this->reason_string->get_encoding(this->reason_string);
270
271 return TRUE;
272 }
273
274 METHOD(imv_state_t, get_remediation_instructions, bool,
275 private_imv_scanner_state_t *this, enumerator_t *language_enumerator,
276 chunk_t *string, char **lang_code, char **uri)
277 {
278 if (!this->violating_ports)
279 {
280 return FALSE;
281 }
282 *lang_code = imv_lang_string_select_lang(language_enumerator,
283 languages, countof(languages));
284
285 /* Instantiate an IETF Remediation Instructions String object */
286 DESTROY_IF(this->remediation_string);
287 this->remediation_string = imv_remediation_string_create(
288 TRUE, *lang_code); /* TODO get os_type */
289
290 this->remediation_string->add_instruction(this->remediation_string,
291 instr_ports_title,
292 instr_ports_descr,
293 instr_ports_header,
294 this->violating_ports);
295 *string = this->remediation_string->get_encoding(this->remediation_string);
296 *uri = lib->settings->get_str(lib->settings,
297 "libimcv.plugins.imv-scanner.remediation_uri", NULL);
298
299 return TRUE;
300 }
301
302 METHOD(imv_state_t, destroy, void,
303 private_imv_scanner_state_t *this)
304 {
305 DESTROY_IF(this->session);
306 DESTROY_IF(this->reason_string);
307 DESTROY_IF(this->remediation_string);
308 this->violating_ports->destroy_function(this->violating_ports, free);
309 free(this->ar_id_value.ptr);
310 free(this);
311 }
312
313 METHOD(imv_scanner_state_t, set_handshake_state, void,
314 private_imv_scanner_state_t *this, imv_scanner_handshake_state_t new_state)
315 {
316 this->handshake_state = new_state;
317 }
318
319 METHOD(imv_scanner_state_t, get_handshake_state, imv_scanner_handshake_state_t,
320 private_imv_scanner_state_t *this)
321 {
322 return this->handshake_state;
323 }
324
325 METHOD(imv_scanner_state_t, set_received, void,
326 private_imv_scanner_state_t *this, u_int flags)
327 {
328 this->received_flags |= flags;
329 }
330
331 METHOD(imv_scanner_state_t, get_received, u_int,
332 private_imv_scanner_state_t *this)
333 {
334 return this->received_flags;
335 }
336
337
338 METHOD(imv_scanner_state_t, add_violating_port, void,
339 private_imv_scanner_state_t *this, char *port)
340 {
341 this->violating_ports->insert_last(this->violating_ports, port);
342 }
343
344 /**
345 * Described in header.
346 */
347 imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
348 {
349 private_imv_scanner_state_t *this;
350
351 INIT(this,
352 .public = {
353 .interface = {
354 .get_connection_id = _get_connection_id,
355 .has_long = _has_long,
356 .has_excl = _has_excl,
357 .set_flags = _set_flags,
358 .set_max_msg_len = _set_max_msg_len,
359 .get_max_msg_len = _get_max_msg_len,
360 .set_ar_id = _set_ar_id,
361 .get_ar_id = _get_ar_id,
362 .set_session = _set_session,
363 .get_session= _get_session,
364 .change_state = _change_state,
365 .get_recommendation = _get_recommendation,
366 .set_recommendation = _set_recommendation,
367 .update_recommendation = _update_recommendation,
368 .get_reason_string = _get_reason_string,
369 .get_remediation_instructions = _get_remediation_instructions,
370 .destroy = _destroy,
371 },
372 .set_handshake_state = _set_handshake_state,
373 .get_handshake_state = _get_handshake_state,
374 .set_received = _set_received,
375 .get_received = _get_received,
376 .add_violating_port = _add_violating_port,
377 },
378 .state = TNC_CONNECTION_STATE_CREATE,
379 .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
380 .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
381 .connection_id = connection_id,
382 .violating_ports = linked_list_create(),
383 );
384
385 return &this->public.interface;
386 }
387
388