2 * Copyright (C) 2012 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "ietf_attr_remediation_instr.h"
18 #include <pa_tnc/pa_tnc_msg.h>
19 #include <bio/bio_writer.h>
20 #include <bio/bio_reader.h>
21 #include <utils/debug.h>
23 typedef struct private_ietf_attr_remediation_instr_t private_ietf_attr_remediation_instr_t
;
26 * PA-TNC Remediation Instructions type (see section 4.2.10 of RFC 5792)
29 * 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
30 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 * | Reserved | Remediation Parameters Vendor ID |
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 * | Remediation Parameters Type |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 * | Remediation Parameters (Variable Length) |
36 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 #define REMEDIATION_INSTR_MIN_SIZE 8
40 #define REMEDIATION_INSTR_RESERVED 0x00
43 * IETF Remediation Parameters URI type (see section 4.2.10.1 of RFC 5792)
46 * 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
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * | Remediation URI (Variable Length) |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 * IETF Remediation Parameters String type (see section 4.2.10.2 of RFC 5792)
56 * 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
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * | Remediation String Length |
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 * | Remediation String (Variable Length) |
61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 * | Lang Code Len | Remediation String Lang Code (Variable Len) |
63 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 * Private data of an ietf_attr_remediation_instr_t object.
69 struct private_ietf_attr_remediation_instr_t
{
72 * Public members of ietf_attr_remediation_instr_t
74 ietf_attr_remediation_instr_t
public;
77 * Vendor-specific attribute type
92 * Remediation Parameters Type
94 pen_type_t parameters_type
;
97 * Remediation Parameters
107 * Remediation Language Code
117 METHOD(pa_tnc_attr_t
, get_type
, pen_type_t
,
118 private_ietf_attr_remediation_instr_t
*this)
123 METHOD(pa_tnc_attr_t
, get_value
, chunk_t
,
124 private_ietf_attr_remediation_instr_t
*this)
129 METHOD(pa_tnc_attr_t
, get_noskip_flag
, bool,
130 private_ietf_attr_remediation_instr_t
*this)
132 return this->noskip_flag
;
135 METHOD(pa_tnc_attr_t
, set_noskip_flag
,void,
136 private_ietf_attr_remediation_instr_t
*this, bool noskip
)
138 this->noskip_flag
= noskip
;
141 METHOD(pa_tnc_attr_t
, build
, void,
142 private_ietf_attr_remediation_instr_t
*this)
144 bio_writer_t
*writer
;
151 writer
= bio_writer_create(REMEDIATION_INSTR_MIN_SIZE
);
152 writer
->write_uint8 (writer
, REMEDIATION_INSTR_RESERVED
);
153 writer
->write_uint24(writer
, this->parameters_type
.vendor_id
);
154 writer
->write_uint32(writer
, this->parameters_type
.type
);
155 writer
->write_data (writer
, this->parameters
);
157 this->value
= chunk_clone(writer
->get_buf(writer
));
158 writer
->destroy(writer
);
161 METHOD(pa_tnc_attr_t
, process
, status_t
,
162 private_ietf_attr_remediation_instr_t
*this, u_int32_t
*offset
)
164 bio_reader_t
*reader
;
166 status_t status
= SUCCESS
;
171 if (this->value
.len
< REMEDIATION_INSTR_MIN_SIZE
)
173 DBG1(DBG_TNC
, "insufficient data for IETF remediation instructions");
176 reader
= bio_reader_create(this->value
);
177 reader
->read_uint8 (reader
, &reserved
);
178 reader
->read_uint24(reader
, &this->parameters_type
.vendor_id
);
179 reader
->read_uint32(reader
, &this->parameters_type
.type
);
180 reader
->read_data (reader
, reader
->remaining(reader
), &this->parameters
);
182 this->parameters
= chunk_clone(this->parameters
);
183 reader
->destroy(reader
);
185 if (this->parameters_type
.vendor_id
== PEN_IETF
&&
186 this->parameters_type
.type
== IETF_REMEDIATION_PARAMETERS_STRING
)
188 reader
= bio_reader_create(this->parameters
);
192 if (!reader
->read_data32(reader
, &this->string
))
194 DBG1(DBG_TNC
, "insufficient data for IETF remediation string");
197 pos
= memchr(this->string
.ptr
, '\0', this->string
.len
);
200 DBG1(DBG_TNC
, "nul termination in IETF remediation string");
201 *offset
+= 1 + (pos
- this->string
.ptr
);
204 *offset
+= 4 + this->string
.len
;
206 if (!reader
->read_data8(reader
, &this->lang_code
))
208 DBG1(DBG_TNC
, "insufficient data for IETF remediation lang code");
214 reader
->destroy(reader
);
219 METHOD(pa_tnc_attr_t
, get_ref
, pa_tnc_attr_t
*,
220 private_ietf_attr_remediation_instr_t
*this)
223 return &this->public.pa_tnc_attribute
;
226 METHOD(pa_tnc_attr_t
, destroy
, void,
227 private_ietf_attr_remediation_instr_t
*this)
229 if (ref_put(&this->ref
))
231 free(this->parameters
.ptr
);
232 free(this->value
.ptr
);
237 METHOD(ietf_attr_remediation_instr_t
, get_parameters_type
, pen_type_t
,
238 private_ietf_attr_remediation_instr_t
*this)
240 return this->parameters_type
;
243 METHOD(ietf_attr_remediation_instr_t
, get_parameters
, chunk_t
,
244 private_ietf_attr_remediation_instr_t
*this)
246 return this->parameters
;
249 METHOD(ietf_attr_remediation_instr_t
, get_uri
, chunk_t
,
250 private_ietf_attr_remediation_instr_t
*this)
252 return this->parameters
;
255 METHOD(ietf_attr_remediation_instr_t
, get_string
, chunk_t
,
256 private_ietf_attr_remediation_instr_t
*this, chunk_t
*lang_code
)
260 *lang_code
= this->lang_code
;
266 * Described in header.
268 pa_tnc_attr_t
*ietf_attr_remediation_instr_create(pen_type_t parameters_type
,
271 private_ietf_attr_remediation_instr_t
*this;
275 .pa_tnc_attribute
= {
276 .get_type
= _get_type
,
277 .get_value
= _get_value
,
278 .get_noskip_flag
= _get_noskip_flag
,
279 .set_noskip_flag
= _set_noskip_flag
,
285 .get_parameters_type
= _get_parameters_type
,
286 .get_parameters
= _get_parameters
,
288 .get_string
= _get_string
,
290 .type
= { PEN_IETF
, IETF_ATTR_REMEDIATION_INSTRUCTIONS
},
291 .parameters_type
= parameters_type
,
292 .parameters
= chunk_clone(parameters
),
296 return &this->public.pa_tnc_attribute
;
300 * Described in header.
302 pa_tnc_attr_t
*ietf_attr_remediation_instr_create_from_uri(chunk_t uri
)
304 pen_type_t type
= { PEN_IETF
, IETF_REMEDIATION_PARAMETERS_URI
};
306 return ietf_attr_remediation_instr_create(type
, uri
);
310 * Described in header.
312 pa_tnc_attr_t
*ietf_attr_remediation_instr_create_from_string(chunk_t string
,
316 bio_writer_t
*writer
;
317 pen_type_t type
= { PEN_IETF
, IETF_REMEDIATION_PARAMETERS_STRING
};
319 /* limit language code to 255 octets */
320 lang_code
.len
= min(255, lang_code
.len
);
322 writer
= bio_writer_create(4 + string
.len
+ 1 + lang_code
.len
);
323 writer
->write_data32(writer
, string
);
324 writer
->write_data8 (writer
, lang_code
);
326 attr
= ietf_attr_remediation_instr_create(type
, writer
->get_buf(writer
));
327 writer
->destroy(writer
);
333 * Described in header.
335 pa_tnc_attr_t
*ietf_attr_remediation_instr_create_from_data(chunk_t data
)
337 private_ietf_attr_remediation_instr_t
*this;
341 .pa_tnc_attribute
= {
342 .get_type
= _get_type
,
343 .get_value
= _get_value
,
344 .get_noskip_flag
= _get_noskip_flag
,
345 .set_noskip_flag
= _set_noskip_flag
,
351 .get_parameters_type
= _get_parameters_type
,
352 .get_parameters
= _get_parameters
,
354 .get_string
= _get_string
,
356 .type
= { PEN_IETF
, IETF_ATTR_REMEDIATION_INSTRUCTIONS
},
357 .value
= chunk_clone(data
),
361 return &this->public.pa_tnc_attribute
;