Added Check_Measurement function to pts_database instead of returning enumerator...
[strongswan.git] / src / libimcv / plugins / imv_attestation / imv_attestation_state.c
1 /*
2 * Copyright (C) 2011 Sansar Choinyambuu
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_attestation_state.h"
17
18 #include <utils/lexparser.h>
19 #include <debug.h>
20
21 typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
22
23 /**
24 * Private data of an imv_attestation_state_t object.
25 */
26 struct private_imv_attestation_state_t {
27
28 /**
29 * Public members of imv_attestation_state_t
30 */
31 imv_attestation_state_t public;
32
33 /**
34 * TNCCS connection ID
35 */
36 TNC_ConnectionID connection_id;
37
38 /**
39 * TNCCS connection state
40 */
41 TNC_ConnectionState state;
42
43 /**
44 * IMV Attestation handshake state
45 */
46 imv_attestation_handshake_state_t handshake_state;
47
48 /**
49 * IMV action recommendation
50 */
51 TNC_IMV_Action_Recommendation rec;
52
53 /**
54 * IMV evaluation result
55 */
56 TNC_IMV_Evaluation_Result eval;
57
58 /**
59 * PTS object
60 */
61 pts_t *pts;
62
63 /**
64 * Requested files and directories
65 */
66 linked_list_t *requested_files;
67
68 };
69
70 typedef struct entry_t entry_t;
71
72 /**
73 * Define an internal reason string entry
74 */
75 struct entry_t {
76 char *lang;
77 char *string;
78 };
79
80 /**
81 * Table of multi-lingual reason string entries
82 */
83 static entry_t reasons[] = {
84 { "en", "IMC Attestation Measurement/s of requested file didn't match" },
85 { "mn", "IMC Attestation Шалгахаар тохируулсан файлуудын хэмжилтүүд таарсангүй" },
86 { "de", "IMC Attestation Messung/en von angefordeten Datein stimmt nicht überein" },
87 };
88
89 METHOD(imv_state_t, get_connection_id, TNC_ConnectionID,
90 private_imv_attestation_state_t *this)
91 {
92 return this->connection_id;
93 }
94
95 METHOD(imv_state_t, change_state, void,
96 private_imv_attestation_state_t *this, TNC_ConnectionState new_state)
97 {
98 this->state = new_state;
99 }
100
101 METHOD(imv_state_t, get_recommendation, void,
102 private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation *rec,
103 TNC_IMV_Evaluation_Result *eval)
104 {
105 *rec = this->rec;
106 *eval = this->eval;
107 }
108
109 METHOD(imv_state_t, set_recommendation, void,
110 private_imv_attestation_state_t *this, TNC_IMV_Action_Recommendation rec,
111 TNC_IMV_Evaluation_Result eval)
112 {
113 this->rec = rec;
114 this->eval = eval;
115 }
116
117 METHOD(imv_state_t, get_reason_string, bool,
118 private_imv_attestation_state_t *this, chunk_t preferred_language,
119 chunk_t *reason_string, chunk_t *reason_language)
120 {
121 chunk_t pref_lang, lang;
122 u_char *pos;
123 int i;
124
125 while (eat_whitespace(&preferred_language))
126 {
127 if (!extract_token(&pref_lang, ',', &preferred_language))
128 {
129 /* last entry in a comma-separated list or single entry */
130 pref_lang = preferred_language;
131 }
132
133 /* eat trailing whitespace */
134 pos = pref_lang.ptr + pref_lang.len - 1;
135 while (pref_lang.len && *pos-- == ' ')
136 {
137 pref_lang.len--;
138 }
139
140 for (i = 0 ; i < countof(reasons); i++)
141 {
142 lang = chunk_create(reasons[i].lang, strlen(reasons[i].lang));
143 if (chunk_equals(lang, pref_lang))
144 {
145 *reason_language = lang;
146 *reason_string = chunk_create(reasons[i].string,
147 strlen(reasons[i].string));
148 return TRUE;
149 }
150 }
151 }
152
153 /* no preferred language match found - use the default language */
154 *reason_string = chunk_create(reasons[0].string,
155 strlen(reasons[0].string));
156 *reason_language = chunk_create(reasons[0].lang,
157 strlen(reasons[0].lang));
158 return TRUE;
159 }
160
161 METHOD(imv_state_t, destroy, void,
162 private_imv_attestation_state_t *this)
163 {
164 this->pts->destroy(this->pts);
165 this->requested_files->destroy_function(this->requested_files, free);
166 free(this);
167 }
168
169 METHOD(imv_attestation_state_t, get_handshake_state, imv_attestation_handshake_state_t,
170 private_imv_attestation_state_t *this)
171 {
172 return this->handshake_state;
173 }
174
175 METHOD(imv_attestation_state_t, set_handshake_state, void,
176 private_imv_attestation_state_t *this, imv_attestation_handshake_state_t new_state)
177 {
178 this->handshake_state = new_state;
179 }
180
181 METHOD(imv_attestation_state_t, get_pts, pts_t*,
182 private_imv_attestation_state_t *this)
183 {
184 return this->pts;
185 }
186
187 METHOD(imv_attestation_state_t, create_requests_enumerator, enumerator_t*,
188 private_imv_attestation_state_t *this)
189 {
190 enumerator_t *e;
191 e = this->requested_files->create_enumerator(this->requested_files);
192 return e;
193 }
194
195 METHOD(imv_attestation_state_t, get_requests_count, int,
196 private_imv_attestation_state_t *this)
197 {
198 return this->requested_files->get_count(this->requested_files);
199 }
200
201
202 METHOD(imv_attestation_state_t, add_requested_file, void,
203 private_imv_attestation_state_t *this, int request_id, int is_dir)
204 {
205 file_request_t *entry;
206
207 entry = malloc_thing(file_request_t);
208 entry->request_id = request_id;
209 entry->is_dir = is_dir;
210 this->requested_files->insert_last(this->requested_files, entry);
211 }
212
213 /**
214 * Comparison function to match an file request entry with its request_id
215 */
216 static bool request_match(file_request_t *current_list_item, int request_id)
217 {
218 return (current_list_item->request_id == request_id);
219 }
220
221 METHOD(imv_attestation_state_t, remove_requested_file, bool,
222 private_imv_attestation_state_t *this, int request_id)
223 {
224 file_request_t *entry;
225
226 if (this->requested_files->find_first(this->requested_files,
227 (linked_list_match_t)request_match, (void**)&entry, request_id) != SUCCESS)
228 {
229 DBG1(DBG_IMV, "request entry with id: %d not found", request_id);
230 return FALSE;
231 }
232
233 this->requested_files->remove(this->requested_files, entry, NULL);
234 return TRUE;
235 }
236
237 METHOD(imv_attestation_state_t, is_request_dir, bool,
238 private_imv_attestation_state_t *this, int request_id, bool *is_dir)
239 {
240 file_request_t *entry;
241
242 if (this->requested_files->find_first(this->requested_files,
243 (linked_list_match_t)request_match, (void**)&entry, request_id) != SUCCESS)
244 {
245 DBG1(DBG_IMV, "request entry with id: %d not found", request_id);
246 return FALSE;
247 }
248
249 *is_dir = (entry->is_dir);
250 return TRUE;
251 }
252
253
254 /**
255 * Described in header.
256 */
257 imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
258 {
259 private_imv_attestation_state_t *this;
260 char *platform_info;
261
262 INIT(this,
263 .public = {
264 .interface = {
265 .get_connection_id = _get_connection_id,
266 .change_state = _change_state,
267 .get_recommendation = _get_recommendation,
268 .set_recommendation = _set_recommendation,
269 .get_reason_string = _get_reason_string,
270 .destroy = _destroy,
271 },
272 .get_handshake_state = _get_handshake_state,
273 .set_handshake_state = _set_handshake_state,
274 .get_pts = _get_pts,
275 .create_requests_enumerator = _create_requests_enumerator,
276 .get_requests_count = _get_requests_count,
277 .add_requested_file = _add_requested_file,
278 .remove_requested_file = _remove_requested_file,
279 .is_request_dir = _is_request_dir,
280 },
281 .connection_id = connection_id,
282 .state = TNC_CONNECTION_STATE_CREATE,
283 .handshake_state = IMV_ATTESTATION_STATE_INIT,
284 .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
285 .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
286 .pts = pts_create(FALSE),
287 .requested_files = linked_list_create(),
288 );
289
290 platform_info = lib->settings->get_str(lib->settings,
291 "libimcv.plugins.imv-attestation.platform_info", NULL);
292 if (platform_info)
293 {
294 this->pts->set_platform_info(this->pts, platform_info);
295 }
296
297 return &this->public.interface;
298 }