store the long and excl flags in the connection state
[strongswan.git] / src / libimcv / plugins / imv_scanner / imv_scanner_state.c
1 /*
2 * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 */
14
15 #include "imv_scanner_state.h"
16
17 #include <utils/lexparser.h>
18 #include <debug.h>
19
20 typedef struct private_imv_scanner_state_t private_imv_scanner_state_t;
21
22 /**
23 * Private data of an imv_scanner_state_t object.
24 */
25 struct private_imv_scanner_state_t {
26
27 /**
28 * Public members of imv_scanner_state_t
29 */
30 imv_scanner_state_t public;
31
32 /**
33 * TNCCS connection ID
34 */
35 TNC_ConnectionID connection_id;
36
37 /**
38 * TNCCS connection state
39 */
40 TNC_ConnectionState state;
41
42 /**
43 * Does the TNCCS connection support long message types?
44 */
45 bool has_long;
46
47 /**
48 * Does the TNCCS connection support exclusive delivery?
49 */
50 bool has_excl;
51
52 /**
53 * IMV action recommendation
54 */
55 TNC_IMV_Action_Recommendation rec;
56
57 /**
58 * IMV evaluation result
59 */
60 TNC_IMV_Evaluation_Result eval;
61
62 /**
63 * String with list of ports that should be closed
64 */
65 char *violating_ports;
66
67 /**
68 * Local copy of the reason string
69 */
70 chunk_t reason_string;
71 };
72
73 typedef struct entry_t entry_t;
74
75 /**
76 * Define an internal reason string entry
77 */
78 struct entry_t {
79 char *lang;
80 char *string;
81 };
82
83 /**
84 * Table of multi-lingual reason string entries
85 */
86 static entry_t reasons[] = {
87 { "en", "The following ports are open:" },
88 { "de", "Die folgenden Ports sind offen" },
89 { "fr", "Les ports suivants sont ouverts:" },
90 { "pl", "Następujące porty sa otwarte:" }
91 };
92
93 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
94 private_imv_scanner_state_t *this)
95 {
96 return this->connection_id;
97 }
98
99 METHOD(imv_state_t, has_long, bool,
100 private_imv_scanner_state_t *this)
101 {
102 return this->has_long;
103 }
104
105 METHOD(imv_state_t, has_excl, bool,
106 private_imv_scanner_state_t *this)
107 {
108 return this->has_excl;
109 }
110
111 METHOD(imv_state_t, set_flags, void,
112 private_imv_scanner_state_t *this, bool has_long, bool has_excl)
113 {
114 this->has_long = has_long;
115 this->has_excl = has_excl;
116 }
117
118 METHOD(imv_state_t, change_state, void,
119 private_imv_scanner_state_t *this, TNC_ConnectionState new_state)
120 {
121 this->state = new_state;
122 }
123
124 METHOD(imv_state_t, get_recommendation, void,
125 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec,
126 TNC_IMV_Evaluation_Result *eval)
127 {
128 *rec = this->rec;
129 *eval = this->eval;
130 }
131
132 METHOD(imv_state_t, set_recommendation, void,
133 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
134 TNC_IMV_Evaluation_Result eval)
135 {
136 this->rec = rec;
137 this->eval = eval;
138 }
139
140 METHOD(imv_state_t, get_reason_string, bool,
141 private_imv_scanner_state_t *this, chunk_t preferred_language,
142 chunk_t *reason_string, chunk_t *reason_language)
143 {
144 chunk_t pref_lang, lang;
145 u_char *pos;
146 int i;
147
148 if (!this->violating_ports)
149 {
150 return FALSE;
151 }
152
153 while (eat_whitespace(&preferred_language))
154 {
155 if (!extract_token(&pref_lang, ',', &preferred_language))
156 {
157 /* last entry in a comma-separated list or single entry */
158 pref_lang = preferred_language;
159 }
160
161 /* eat trailing whitespace */
162 pos = pref_lang.ptr + pref_lang.len - 1;
163 while (pref_lang.len && *pos-- == ' ')
164 {
165 pref_lang.len--;
166 }
167
168 for (i = 0 ; i < countof(reasons); i++)
169 {
170 lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
171 if (chunk_equals(lang, pref_lang))
172 {
173 this->reason_string = chunk_cat("cc",
174 chunk_create(reasons[i].string,
175 strlen(reasons[i].string)),
176 chunk_create(this->violating_ports,
177 strlen(this->violating_ports)));
178 *reason_string = this->reason_string;
179 *reason_language = lang;
180 return TRUE;
181 }
182 }
183 }
184
185 /* no preferred language match found - use the default language */
186
187 this->reason_string = chunk_cat("cc",
188 chunk_create(reasons[0].string,
189 strlen(reasons[0].string)),
190 chunk_create(this->violating_ports,
191 strlen(this->violating_ports)));
192 *reason_string = this->reason_string;
193 *reason_language = chunk_create(reasons[0].lang,
194 strlen(reasons[0].lang));
195 return TRUE;
196 }
197
198 METHOD(imv_state_t, destroy, void,
199 private_imv_scanner_state_t *this)
200 {
201 free(this->violating_ports);
202 free(this->reason_string.ptr);
203 free(this);
204 }
205
206 METHOD(imv_scanner_state_t, set_violating_ports, void,
207 private_imv_scanner_state_t *this, char *ports)
208 {
209 this->violating_ports = strdup(ports);
210 }
211
212 /**
213 * Described in header.
214 */
215 imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
216 {
217 private_imv_scanner_state_t *this;
218
219 INIT(this,
220 .public = {
221 .interface = {
222 .get_connection_id = _get_connection_id,
223 .has_long = _has_long,
224 .has_excl = _has_excl,
225 .set_flags = _set_flags,
226 .change_state = _change_state,
227 .get_recommendation = _get_recommendation,
228 .set_recommendation = _set_recommendation,
229 .get_reason_string = _get_reason_string,
230 .destroy = _destroy,
231 },
232 .set_violating_ports = _set_violating_ports,
233 },
234 .state = TNC_CONNECTION_STATE_CREATE,
235 .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
236 .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
237 .connection_id = connection_id,
238 );
239
240 return &this->public.interface;
241 }
242
243