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