fixed UTF-8 representation of polish reason string
[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 * IMV action recommendation
44 */
45 TNC_IMV_Action_Recommendation rec;
46
47 /**
48 * IMV evaluation result
49 */
50 TNC_IMV_Evaluation_Result eval;
51
52 /**
53 * String with list of ports that should be closed
54 */
55 char *violating_ports;
56
57 /**
58 * Local copy of the reason string
59 */
60 chunk_t reason_string;
61 };
62
63 typedef struct entry_t entry_t;
64
65 /**
66 * Define an internal reason string entry
67 */
68 struct entry_t {
69 char *lang;
70 char *string;
71 };
72
73 /**
74 * Table of multi-lingual reason string entries
75 */
76 static entry_t reasons[] = {
77 { "en", "The following ports are open:" },
78 { "de", "Die folgenden Ports sind offen" },
79 { "fr", "Les ports suivants sont ouverts:" },
80 { "pl", "Następujące porty sa otwarte:" }
81 };
82
83 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
84 private_imv_scanner_state_t *this)
85 {
86 return this->connection_id;
87 }
88
89 METHOD(imv_state_t, change_state, void,
90 private_imv_scanner_state_t *this, TNC_ConnectionState new_state)
91 {
92 this->state = new_state;
93 }
94
95 METHOD(imv_state_t, get_recommendation, void,
96 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation *rec,
97 TNC_IMV_Evaluation_Result *eval)
98 {
99 *rec = this->rec;
100 *eval = this->eval;
101 }
102
103 METHOD(imv_state_t, set_recommendation, void,
104 private_imv_scanner_state_t *this, TNC_IMV_Action_Recommendation rec,
105 TNC_IMV_Evaluation_Result eval)
106 {
107 this->rec = rec;
108 this->eval = eval;
109 }
110
111 METHOD(imv_state_t, get_reason_string, bool,
112 private_imv_scanner_state_t *this, chunk_t preferred_language,
113 chunk_t *reason_string, chunk_t *reason_language)
114 {
115 chunk_t pref_lang, lang;
116 u_char *pos;
117 int i;
118
119 while (eat_whitespace(&preferred_language))
120 {
121 if (!extract_token(&pref_lang, ',', &preferred_language))
122 {
123 /* last entry in a comma-separated list or single entry */
124 pref_lang = preferred_language;
125 }
126
127 /* eat trailing whitespace */
128 pos = pref_lang.ptr + pref_lang.len - 1;
129 while (pref_lang.len && *pos-- == ' ')
130 {
131 pref_lang.len--;
132 }
133
134 for (i = 0 ; i < countof(reasons); i++)
135 {
136 lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
137 if (chunk_equals(lang, pref_lang))
138 {
139 this->reason_string = chunk_cat("cc",
140 chunk_create(reasons[i].string,
141 strlen(reasons[i].string)),
142 chunk_create(this->violating_ports,
143 strlen(this->violating_ports)));
144 *reason_string = this->reason_string;
145 *reason_language = lang;
146 return TRUE;
147 }
148 }
149 }
150
151 /* no preferred language match found - use the default language */
152
153 this->reason_string = chunk_cat("cc",
154 chunk_create(reasons[0].string,
155 strlen(reasons[0].string)),
156 chunk_create(this->violating_ports,
157 strlen(this->violating_ports)));
158 *reason_string = this->reason_string;
159 *reason_language = chunk_create(reasons[0].lang,
160 strlen(reasons[0].lang));
161 return TRUE;
162 }
163
164 METHOD(imv_state_t, destroy, void,
165 private_imv_scanner_state_t *this)
166 {
167 free(this->violating_ports);
168 free(this->reason_string.ptr);
169 free(this);
170 }
171
172 METHOD(imv_scanner_state_t, set_violating_ports, void,
173 private_imv_scanner_state_t *this, char *ports)
174 {
175 this->violating_ports = strdup(ports);
176 }
177
178 /**
179 * Described in header.
180 */
181 imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
182 {
183 private_imv_scanner_state_t *this;
184
185 INIT(this,
186 .public = {
187 .interface = {
188 .get_connection_id = _get_connection_id,
189 .change_state = _change_state,
190 .get_recommendation = _get_recommendation,
191 .set_recommendation = _set_recommendation,
192 .get_reason_string = _get_reason_string,
193 .destroy = _destroy,
194 },
195 .set_violating_ports = _set_violating_ports,
196 },
197 .state = TNC_CONNECTION_STATE_CREATE,
198 .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
199 .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
200 .connection_id = connection_id,
201 );
202
203 return &this->public.interface;
204 }
205
206