2 * Copyright (C) 2012-2014 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
82 * Length of attribute value
87 * Attribute value or segment
97 * Remediation Parameters Type
99 pen_type_t parameters_type
;
102 * Remediation Parameters
112 * Remediation Language Code
122 METHOD(pa_tnc_attr_t
, get_type
, pen_type_t
,
123 private_ietf_attr_remediation_instr_t
*this)
128 METHOD(pa_tnc_attr_t
, get_value
, chunk_t
,
129 private_ietf_attr_remediation_instr_t
*this)
134 METHOD(pa_tnc_attr_t
, get_noskip_flag
, bool,
135 private_ietf_attr_remediation_instr_t
*this)
137 return this->noskip_flag
;
140 METHOD(pa_tnc_attr_t
, set_noskip_flag
,void,
141 private_ietf_attr_remediation_instr_t
*this, bool noskip
)
143 this->noskip_flag
= noskip
;
146 METHOD(pa_tnc_attr_t
, build
, void,
147 private_ietf_attr_remediation_instr_t
*this)
149 bio_writer_t
*writer
;
156 writer
= bio_writer_create(REMEDIATION_INSTR_MIN_SIZE
);
157 writer
->write_uint8 (writer
, REMEDIATION_INSTR_RESERVED
);
158 writer
->write_uint24(writer
, this->parameters_type
.vendor_id
);
159 writer
->write_uint32(writer
, this->parameters_type
.type
);
160 writer
->write_data (writer
, this->parameters
);
162 this->value
= writer
->extract_buf(writer
);
163 this->length
= this->value
.len
;
164 writer
->destroy(writer
);
167 METHOD(pa_tnc_attr_t
, process
, status_t
,
168 private_ietf_attr_remediation_instr_t
*this, u_int32_t
*offset
)
170 bio_reader_t
*reader
;
172 status_t status
= SUCCESS
;
177 if (this->value
.len
< this->length
)
181 if (this->value
.len
< REMEDIATION_INSTR_MIN_SIZE
)
183 DBG1(DBG_TNC
, "insufficient data for IETF remediation instructions");
186 reader
= bio_reader_create(this->value
);
187 reader
->read_uint8 (reader
, &reserved
);
188 reader
->read_uint24(reader
, &this->parameters_type
.vendor_id
);
189 reader
->read_uint32(reader
, &this->parameters_type
.type
);
190 reader
->read_data (reader
, reader
->remaining(reader
), &this->parameters
);
192 this->parameters
= chunk_clone(this->parameters
);
193 reader
->destroy(reader
);
195 if (this->parameters_type
.vendor_id
== PEN_IETF
&&
196 this->parameters_type
.type
== IETF_REMEDIATION_PARAMETERS_STRING
)
198 reader
= bio_reader_create(this->parameters
);
202 if (!reader
->read_data32(reader
, &this->string
))
204 DBG1(DBG_TNC
, "insufficient data for IETF remediation string");
209 pos
= memchr(this->string
.ptr
, '\0', this->string
.len
);
212 DBG1(DBG_TNC
, "nul termination in IETF remediation string");
213 *offset
+= (pos
- this->string
.ptr
);
216 *offset
+= this->string
.len
;
218 if (!reader
->read_data8(reader
, &this->lang_code
))
220 DBG1(DBG_TNC
, "insufficient data for IETF remediation lang code");
226 reader
->destroy(reader
);
231 METHOD(pa_tnc_attr_t
, add_segment
, void,
232 private_ietf_attr_remediation_instr_t
*this, chunk_t segment
)
234 this->value
= chunk_cat("mc", this->value
, segment
);
237 METHOD(pa_tnc_attr_t
, get_ref
, pa_tnc_attr_t
*,
238 private_ietf_attr_remediation_instr_t
*this)
241 return &this->public.pa_tnc_attribute
;
244 METHOD(pa_tnc_attr_t
, destroy
, void,
245 private_ietf_attr_remediation_instr_t
*this)
247 if (ref_put(&this->ref
))
249 free(this->parameters
.ptr
);
250 free(this->value
.ptr
);
255 METHOD(ietf_attr_remediation_instr_t
, get_parameters_type
, pen_type_t
,
256 private_ietf_attr_remediation_instr_t
*this)
258 return this->parameters_type
;
261 METHOD(ietf_attr_remediation_instr_t
, get_parameters
, chunk_t
,
262 private_ietf_attr_remediation_instr_t
*this)
264 return this->parameters
;
267 METHOD(ietf_attr_remediation_instr_t
, get_string
, chunk_t
,
268 private_ietf_attr_remediation_instr_t
*this, chunk_t
*lang_code
)
272 *lang_code
= this->lang_code
;
278 * Described in header.
280 pa_tnc_attr_t
*ietf_attr_remediation_instr_create(pen_type_t parameters_type
,
283 private_ietf_attr_remediation_instr_t
*this;
287 .pa_tnc_attribute
= {
288 .get_type
= _get_type
,
289 .get_value
= _get_value
,
290 .get_noskip_flag
= _get_noskip_flag
,
291 .set_noskip_flag
= _set_noskip_flag
,
294 .add_segment
= _add_segment
,
298 .get_parameters_type
= _get_parameters_type
,
299 .get_parameters
= _get_parameters
,
300 .get_uri
= _get_parameters
,
301 .get_string
= _get_string
,
303 .type
= { PEN_IETF
, IETF_ATTR_REMEDIATION_INSTRUCTIONS
},
304 .parameters_type
= parameters_type
,
305 .parameters
= chunk_clone(parameters
),
309 return &this->public.pa_tnc_attribute
;
313 * Described in header.
315 pa_tnc_attr_t
*ietf_attr_remediation_instr_create_from_uri(chunk_t uri
)
317 pen_type_t type
= { PEN_IETF
, IETF_REMEDIATION_PARAMETERS_URI
};
319 return ietf_attr_remediation_instr_create(type
, uri
);
323 * Described in header.
325 pa_tnc_attr_t
*ietf_attr_remediation_instr_create_from_string(chunk_t string
,
329 bio_writer_t
*writer
;
330 pen_type_t type
= { PEN_IETF
, IETF_REMEDIATION_PARAMETERS_STRING
};
332 /* limit language code to 255 octets */
333 lang_code
.len
= min(255, lang_code
.len
);
335 writer
= bio_writer_create(4 + string
.len
+ 1 + lang_code
.len
);
336 writer
->write_data32(writer
, string
);
337 writer
->write_data8 (writer
, lang_code
);
339 attr
= ietf_attr_remediation_instr_create(type
, writer
->get_buf(writer
));
340 writer
->destroy(writer
);
346 * Described in header.
348 pa_tnc_attr_t
*ietf_attr_remediation_instr_create_from_data(size_t length
,
351 private_ietf_attr_remediation_instr_t
*this;
355 .pa_tnc_attribute
= {
356 .get_type
= _get_type
,
357 .get_value
= _get_value
,
358 .get_noskip_flag
= _get_noskip_flag
,
359 .set_noskip_flag
= _set_noskip_flag
,
362 .add_segment
= _add_segment
,
366 .get_parameters_type
= _get_parameters_type
,
367 .get_parameters
= _get_parameters
,
368 .get_uri
= _get_parameters
,
369 .get_string
= _get_string
,
371 .type
= { PEN_IETF
, IETF_ATTR_REMEDIATION_INSTRUCTIONS
},
373 .value
= chunk_clone(data
),
377 return &this->public.pa_tnc_attribute
;