83a5e584731e57757ca625573aa6977c82fd7099
[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 * Flags set for completed actions
65 */
66 u_int32_t action_flags;
67
68 /**
69 * Access Requestor ID Type
70 */
71 u_int32_t ar_id_type;
72
73 /**
74 * Access Requestor ID Value
75 */
76 chunk_t ar_id_value;
77
78 /**
79 * IMV database session associatied with TNCCS connection
80 */
81 imv_session_t *session;
82
83 /**
84 * IMV action recommendation
85 */
86 TNC_IMV_Action_Recommendation rec;
87
88 /**
89 * IMV evaluation result
90 */
91 TNC_IMV_Evaluation_Result eval;
92
93 /**
94 * IMV Scanner handshake state
95 */
96 imv_scanner_handshake_state_t handshake_state;
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_action_flags, void,
196 private_imv_scanner_state_t *this, u_int32_t flags)
197 {
198 this->action_flags |= flags;
199 }
200
201 METHOD(imv_state_t, get_action_flags, u_int32_t,
202 private_imv_scanner_state_t *this)
203 {
204 return this->action_flags;
205 }
206
207 METHOD(imv_state_t, set_ar_id, void,
208 private_imv_scanner_state_t *this, u_int32_t id_type, chunk_t id_value)
209 {
210 this->ar_id_type = id_type;
211 this->ar_id_value = chunk_clone(id_value);
212 }
213
214 METHOD(imv_state_t, get_ar_id, chunk_t,
215 private_imv_scanner_state_t *this, u_int32_t *id_type)
216 {
217 if (id_type)
218 {
219 *id_type = this->ar_id_type;
220 }
221 return this->ar_id_value;
222 }
223
224 METHOD(imv_state_t, set_session, void,
225 private_imv_scanner_state_t *this, imv_session_t *session)
226 {
227 this->session = session;
228 }
229
230 METHOD(imv_state_t, get_session, imv_session_t*,
231 private_imv_scanner_state_t *this)
232 {
233 return this->session;
234 }
235
236 METHOD(imv_state_t, change_state, void,
237 private_imv_scanner_state_t *this, TNC_ConnectionState new_state)
238 {
239 this->state = new_state;
240 }
241
242 METHOD(imv_state_t, get_recommendation, void,
243 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec,
244 TNC_IMV_Evaluation_Result *eval)
245 {
246 *rec = this->rec;
247 *eval = this->eval;
248 }
249
250 METHOD(imv_state_t, set_recommendation, void,
251 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
252 TNC_IMV_Evaluation_Result eval)
253 {
254 this->rec = rec;
255 this->eval = eval;
256 }
257
258 METHOD(imv_state_t, update_recommendation, void,
259 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
260 TNC_IMV_Evaluation_Result eval)
261 {
262 this->rec = tncif_policy_update_recommendation(this->rec, rec);
263 this->eval = tncif_policy_update_evaluation(this->eval, eval);
264 }
265
266 METHOD(imv_state_t, get_reason_string, bool,
267 private_imv_scanner_state_t *this, enumerator_t *language_enumerator,
268 chunk_t *reason_string, char **reason_language)
269 {
270 if (!this->violating_ports)
271 {
272 return FALSE;
273 }
274 *reason_language = imv_lang_string_select_lang(language_enumerator,
275 languages, countof(languages));
276
277 /* Instantiate a TNC Reason String object */
278 DESTROY_IF(this->reason_string);
279 this->reason_string = imv_reason_string_create(*reason_language);
280 this->reason_string->add_reason(this->reason_string, reasons);
281 *reason_string = this->reason_string->get_encoding(this->reason_string);
282
283 return TRUE;
284 }
285
286 METHOD(imv_state_t, get_remediation_instructions, bool,
287 private_imv_scanner_state_t *this, enumerator_t *language_enumerator,
288 chunk_t *string, char **lang_code, char **uri)
289 {
290 if (!this->violating_ports)
291 {
292 return FALSE;
293 }
294 *lang_code = imv_lang_string_select_lang(language_enumerator,
295 languages, countof(languages));
296
297 /* Instantiate an IETF Remediation Instructions String object */
298 DESTROY_IF(this->remediation_string);
299 this->remediation_string = imv_remediation_string_create(
300 TRUE, *lang_code); /* TODO get os_type */
301
302 this->remediation_string->add_instruction(this->remediation_string,
303 instr_ports_title,
304 instr_ports_descr,
305 instr_ports_header,
306 this->violating_ports);
307 *string = this->remediation_string->get_encoding(this->remediation_string);
308 *uri = lib->settings->get_str(lib->settings,
309 "libimcv.plugins.imv-scanner.remediation_uri", NULL);
310
311 return TRUE;
312 }
313
314 METHOD(imv_state_t, destroy, void,
315 private_imv_scanner_state_t *this)
316 {
317 DESTROY_IF(this->session);
318 DESTROY_IF(this->reason_string);
319 DESTROY_IF(this->remediation_string);
320 this->violating_ports->destroy_function(this->violating_ports, free);
321 free(this->ar_id_value.ptr);
322 free(this);
323 }
324
325 METHOD(imv_scanner_state_t, set_handshake_state, void,
326 private_imv_scanner_state_t *this, imv_scanner_handshake_state_t new_state)
327 {
328 this->handshake_state = new_state;
329 }
330
331 METHOD(imv_scanner_state_t, get_handshake_state, imv_scanner_handshake_state_t,
332 private_imv_scanner_state_t *this)
333 {
334 return this->handshake_state;
335 }
336
337 METHOD(imv_scanner_state_t, add_violating_port, void,
338 private_imv_scanner_state_t *this, char *port)
339 {
340 this->violating_ports->insert_last(this->violating_ports, port);
341 }
342
343 /**
344 * Described in header.
345 */
346 imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
347 {
348 private_imv_scanner_state_t *this;
349
350 INIT(this,
351 .public = {
352 .interface = {
353 .get_connection_id = _get_connection_id,
354 .has_long = _has_long,
355 .has_excl = _has_excl,
356 .set_flags = _set_flags,
357 .set_max_msg_len = _set_max_msg_len,
358 .get_max_msg_len = _get_max_msg_len,
359 .set_action_flags = _set_action_flags,
360 .get_action_flags = _get_action_flags,
361 .set_ar_id = _set_ar_id,
362 .get_ar_id = _get_ar_id,
363 .set_session = _set_session,
364 .get_session= _get_session,
365 .change_state = _change_state,
366 .get_recommendation = _get_recommendation,
367 .set_recommendation = _set_recommendation,
368 .update_recommendation = _update_recommendation,
369 .get_reason_string = _get_reason_string,
370 .get_remediation_instructions = _get_remediation_instructions,
371 .destroy = _destroy,
372 },
373 .set_handshake_state = _set_handshake_state,
374 .get_handshake_state = _get_handshake_state,
375 .add_violating_port = _add_violating_port,
376 },
377 .state = TNC_CONNECTION_STATE_CREATE,
378 .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
379 .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
380 .connection_id = connection_id,
381 .violating_ports = linked_list_create(),
382 );
383
384 return &this->public.interface;
385 }
386
387