Defined generic boolean PA-TNC attribute
[strongswan.git] / src / libimcv / generic / generic_attr_bool.c
1 /*
2 * Copyright (C) 2015 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 "generic_attr_bool.h"
17
18 #include <imcv.h>
19 #include <pa_tnc/pa_tnc_msg.h>
20 #include <bio/bio_writer.h>
21 #include <bio/bio_reader.h>
22 #include <utils/debug.h>
23
24 typedef struct private_generic_attr_bool_t private_generic_attr_bool_t;
25
26 /**
27 * Generic PA-TNC attribute containing boolean status value in 32 bit encoding
28 *
29 * 1 2 3
30 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Boolean Value |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 */
35
36 #define ATTR_BOOL_SIZE 4
37
38 /**
39 * Private data of an generic_attr_bool_t object.
40 */
41 struct private_generic_attr_bool_t {
42
43 /**
44 * Public members of generic_attr_bool_t
45 */
46 generic_attr_bool_t public;
47
48 /**
49 * Vendor-specific attribute type
50 */
51 pen_type_t type;
52
53 /**
54 * Length of attribute value
55 */
56 size_t length;
57
58 /**
59 * Attribute value or segment
60 */
61 chunk_t value;
62
63 /**
64 * Noskip flag
65 */
66 bool noskip_flag;
67
68 /**
69 * Boolean status value
70 */
71 bool status;
72
73 /**
74 * Reference count
75 */
76 refcount_t ref;
77 };
78
79 METHOD(pa_tnc_attr_t, get_type, pen_type_t,
80 private_generic_attr_bool_t *this)
81 {
82 return this->type;
83 }
84
85 METHOD(pa_tnc_attr_t, get_value, chunk_t,
86 private_generic_attr_bool_t *this)
87 {
88 return this->value;
89 }
90
91 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
92 private_generic_attr_bool_t *this)
93 {
94 return this->noskip_flag;
95 }
96
97 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
98 private_generic_attr_bool_t *this, bool noskip)
99 {
100 this->noskip_flag = noskip;
101 }
102
103 METHOD(pa_tnc_attr_t, build, void,
104 private_generic_attr_bool_t *this)
105 {
106 bio_writer_t *writer;
107
108 if (this->value.ptr)
109 {
110 return;
111 }
112 writer = bio_writer_create(ATTR_BOOL_SIZE);
113 writer->write_uint32(writer, this->status);
114
115 this->value = writer->extract_buf(writer);
116 this->length = this->value.len;
117 writer->destroy(writer);
118 }
119
120 METHOD(pa_tnc_attr_t, process, status_t,
121 private_generic_attr_bool_t *this, u_int32_t *offset)
122 {
123 enum_name_t *pa_attr_names;
124 bio_reader_t *reader;
125 u_int32_t status;
126
127 pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
128 this->type.vendor_id);
129 *offset = 0;
130
131 if (this->value.len < this->length)
132 {
133 return NEED_MORE;
134 }
135 if (this->value.len != ATTR_BOOL_SIZE)
136 {
137 DBG1(DBG_TNC, "incorrect attribute size for %N/%N",
138 pen_names, this->type.vendor_id, pa_attr_names, this->type.type);
139 return FAILED;
140 }
141 reader = bio_reader_create(this->value);
142 reader->read_uint32(reader, &status);
143 reader->destroy(reader);
144
145 if (status > 1)
146 {
147 DBG1(DBG_TNC, "%N/%N attribute contains invalid non-boolean value %u",
148 pen_names, this->type.vendor_id, pa_attr_names, this->type.type,
149 status);
150 return FAILED;
151 }
152 this->status = status;
153
154 return SUCCESS;
155 }
156
157 METHOD(pa_tnc_attr_t, add_segment, void,
158 private_generic_attr_bool_t *this, chunk_t segment)
159 {
160 this->value = chunk_cat("mc", this->value, segment);
161 }
162
163 METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
164 private_generic_attr_bool_t *this)
165 {
166 ref_get(&this->ref);
167 return &this->public.pa_tnc_attribute;
168 }
169
170 METHOD(pa_tnc_attr_t, destroy, void,
171 private_generic_attr_bool_t *this)
172 {
173 if (ref_put(&this->ref))
174 {
175 free(this->value.ptr);
176 free(this);
177 }
178 }
179
180 METHOD(generic_attr_bool_t, get_status, bool,
181 private_generic_attr_bool_t *this)
182 {
183 return this->status;
184 }
185
186 /**
187 * Described in header.
188 */
189 pa_tnc_attr_t *generic_attr_bool_create(bool status, pen_type_t type)
190 {
191 private_generic_attr_bool_t *this;
192
193 INIT(this,
194 .public = {
195 .pa_tnc_attribute = {
196 .get_type = _get_type,
197 .get_value = _get_value,
198 .get_noskip_flag = _get_noskip_flag,
199 .set_noskip_flag = _set_noskip_flag,
200 .build = _build,
201 .process = _process,
202 .add_segment = _add_segment,
203 .get_ref = _get_ref,
204 .destroy = _destroy,
205 },
206 .get_status = _get_status,
207 },
208 .type = type,
209 .status = status,
210 .ref = 1,
211 );
212
213 return &this->public.pa_tnc_attribute;
214 }
215
216 /**
217 * Described in header.
218 */
219 pa_tnc_attr_t *generic_attr_bool_create_from_data(size_t length, chunk_t data,
220 pen_type_t type)
221 {
222 private_generic_attr_bool_t *this;
223
224 INIT(this,
225 .public = {
226 .pa_tnc_attribute = {
227 .get_type = _get_type,
228 .get_value = _get_value,
229 .get_noskip_flag = _get_noskip_flag,
230 .set_noskip_flag = _set_noskip_flag,
231 .build = _build,
232 .process = _process,
233 .add_segment = _add_segment,
234 .get_ref = _get_ref,
235 .destroy = _destroy,
236 },
237 .get_status = _get_status,
238 },
239 .type = type,
240 .length = length,
241 .value = chunk_clone(data),
242 .ref = 1,
243 );
244
245 return &this->public.pa_tnc_attribute;
246 }
247