imv: Return an empty enumerator instead of null, as expected by callers
[strongswan.git] / src / libimcv / imv / imv_session.c
1 /*
2 * Copyright (C) 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_session.h"
17
18 #include <utils/debug.h>
19
20 typedef struct private_imv_session_t private_imv_session_t;
21
22 /**
23 * Private data of a imv_session_t object.
24 */
25 struct private_imv_session_t {
26
27 /**
28 * Public imv_session_t interface.
29 */
30 imv_session_t public;
31
32 /**
33 * Unique Session ID
34 */
35 int session_id;
36
37 /**
38 * Unique Product ID
39 */
40 int pid;
41
42 /**
43 * Unique Device ID
44 */
45 int did;
46
47 /**
48 * TNCCS connection ID
49 */
50 TNC_ConnectionID conn_id;
51
52 /**
53 * Session creation time
54 */
55 time_t created;
56
57 /**
58 * Access Requestor ID type
59 */
60 uint32_t ar_id_type;
61
62 /**
63 * Access Requestor ID value
64 */
65 chunk_t ar_id_value;
66
67 /**
68 * OS information
69 */
70 imv_os_info_t *os_info;
71
72 /**
73 * Device ID
74 */
75 chunk_t device_id;
76
77 /**
78 * Is Device ID trusted?
79 */
80 bool trusted;
81
82 /**
83 * Have the workitems been generated?
84 */
85 bool policy_started;
86
87 /**
88 * List of worklist items
89 */
90 linked_list_t *workitems;
91
92 /**
93 * Reference count
94 */
95 refcount_t ref;
96
97 };
98
99 METHOD(imv_session_t, set_session_id, void,
100 private_imv_session_t *this, int session_id, int pid, int did)
101 {
102 this->session_id = session_id;
103 this->pid = pid;
104 this->did = did;
105 }
106
107 METHOD(imv_session_t, get_session_id, int,
108 private_imv_session_t *this, int *pid, int *did)
109 {
110 if (pid)
111 {
112 *pid = this->pid;
113 }
114 if (did)
115 {
116 *did = this->did;
117 }
118 return this->session_id;
119 }
120
121 METHOD(imv_session_t, get_connection_id, TNC_ConnectionID,
122 private_imv_session_t *this)
123 {
124 return this->conn_id;
125 }
126
127 METHOD(imv_session_t, get_creation_time, time_t,
128 private_imv_session_t *this)
129 {
130 return this->created;
131 }
132
133 METHOD(imv_session_t, get_ar_id, chunk_t,
134 private_imv_session_t *this, uint32_t *ar_id_type)
135 {
136 if (ar_id_type)
137 {
138 *ar_id_type = this->ar_id_type;
139 }
140 return this->ar_id_value;
141 }
142
143 METHOD(imv_session_t, get_os_info, imv_os_info_t*,
144 private_imv_session_t *this)
145 {
146 return this->os_info;
147 }
148
149 METHOD(imv_session_t, set_device_id, void,
150 private_imv_session_t *this, chunk_t device_id)
151 {
152 if (device_id.len == 0)
153 {
154 device_id = chunk_from_str("unknown");
155 }
156 if (this->device_id.len)
157 {
158 if (chunk_equals(device_id, this->device_id))
159 {
160 return;
161 }
162 free(this->device_id.ptr);
163 }
164 this->device_id = chunk_clone(device_id);
165 }
166
167 METHOD(imv_session_t, get_device_id, bool,
168 private_imv_session_t *this, chunk_t *device_id)
169 {
170 if (this->device_id.len == 0)
171 {
172 return FALSE;
173 }
174 if (device_id)
175 {
176 *device_id = this->device_id;
177 }
178 return TRUE;
179 }
180
181 METHOD(imv_session_t, set_device_trust, void,
182 private_imv_session_t *this, bool trusted)
183 {
184 this->trusted = trusted;
185 }
186
187 METHOD(imv_session_t, get_device_trust, bool,
188 private_imv_session_t *this)
189 {
190 return this->trusted;
191 }
192
193 METHOD(imv_session_t, set_policy_started, void,
194 private_imv_session_t *this, bool start)
195 {
196 this->policy_started = start;
197 }
198
199 METHOD(imv_session_t, get_policy_started, bool,
200 private_imv_session_t *this)
201 {
202 return this->policy_started;
203 }
204
205 METHOD(imv_session_t, insert_workitem, void,
206 private_imv_session_t *this, imv_workitem_t *workitem)
207 {
208 this->workitems->insert_last(this->workitems, workitem);
209 }
210
211 METHOD(imv_session_t, remove_workitem, void,
212 private_imv_session_t *this, enumerator_t *enumerator)
213 {
214 this->workitems->remove_at(this->workitems, enumerator);
215 }
216
217 METHOD(imv_session_t, create_workitem_enumerator, enumerator_t*,
218 private_imv_session_t *this)
219 {
220 if (!this->policy_started)
221 {
222 return enumerator_create_empty();
223 }
224 return this->workitems->create_enumerator(this->workitems);
225 }
226
227 METHOD(imv_session_t, get_workitem_count, int,
228 private_imv_session_t *this, TNC_IMVID imv_id)
229 {
230 enumerator_t *enumerator;
231 imv_workitem_t *workitem;
232 int count = 0;
233
234 enumerator = this->workitems->create_enumerator(this->workitems);
235 while (enumerator->enumerate(enumerator, &workitem))
236 {
237 if (workitem->get_imv_id(workitem) == imv_id)
238 {
239 count++;
240 }
241 }
242 enumerator->destroy(enumerator);
243
244 return count;
245 }
246
247 METHOD(imv_session_t, get_ref, imv_session_t*,
248 private_imv_session_t *this)
249 {
250 ref_get(&this->ref);
251
252 return &this->public;
253 }
254
255 METHOD(imv_session_t, destroy, void,
256 private_imv_session_t *this)
257 {
258 if (ref_put(&this->ref))
259 {
260 this->workitems->destroy_offset(this->workitems,
261 offsetof(imv_workitem_t, destroy));
262 this->os_info->destroy(this->os_info);
263 free(this->ar_id_value.ptr);
264 free(this->device_id.ptr);
265 free(this);
266 }
267 }
268
269 /**
270 * See header
271 */
272 imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
273 uint32_t ar_id_type, chunk_t ar_id_value)
274 {
275 private_imv_session_t *this;
276
277 INIT(this,
278 .public = {
279 .set_session_id = _set_session_id,
280 .get_session_id = _get_session_id,
281 .get_connection_id = _get_connection_id,
282 .get_creation_time = _get_creation_time,
283 .get_ar_id = _get_ar_id,
284 .get_os_info = _get_os_info,
285 .set_device_id = _set_device_id,
286 .get_device_id = _get_device_id,
287 .set_device_trust = _set_device_trust,
288 .get_device_trust = _get_device_trust,
289 .set_policy_started = _set_policy_started,
290 .get_policy_started = _get_policy_started,
291 .insert_workitem = _insert_workitem,
292 .remove_workitem = _remove_workitem,
293 .create_workitem_enumerator = _create_workitem_enumerator,
294 .get_workitem_count = _get_workitem_count,
295 .get_ref = _get_ref,
296 .destroy = _destroy,
297 },
298 .conn_id = conn_id,
299 .created = created,
300 .ar_id_type = ar_id_type,
301 .ar_id_value = chunk_clone(ar_id_value),
302 .os_info = imv_os_info_create(),
303 .workitems = linked_list_create(),
304 .ref = 1,
305 );
306
307 return &this->public;
308 }