Annotation of embedaddon/strongswan/src/libimcv/ietf/ietf_attr_remediation_instr.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2012-2014 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 "ietf_attr_remediation_instr.h"
17:
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>
22:
23: typedef struct private_ietf_attr_remediation_instr_t private_ietf_attr_remediation_instr_t;
24:
25: /**
26: * PA-TNC Remediation Instructions type (see section 4.2.10 of RFC 5792)
27: *
28: * 1 2 3
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: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37: */
38:
39: #define REMEDIATION_INSTR_MIN_SIZE 8
40: #define REMEDIATION_INSTR_RESERVED 0x00
41:
42: /**
43: * IETF Remediation Parameters URI type (see section 4.2.10.1 of RFC 5792)
44: *
45: * 1 2 3
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: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50: */
51:
52: /**
53: * IETF Remediation Parameters String type (see section 4.2.10.2 of RFC 5792)
54: *
55: * 1 2 3
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: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64: */
65:
66: /**
67: * Private data of an ietf_attr_remediation_instr_t object.
68: */
69: struct private_ietf_attr_remediation_instr_t {
70:
71: /**
72: * Public members of ietf_attr_remediation_instr_t
73: */
74: ietf_attr_remediation_instr_t public;
75:
76: /**
77: * Vendor-specific attribute type
78: */
79: pen_type_t type;
80:
81: /**
82: * Length of attribute value
83: */
84: size_t length;
85:
86: /**
87: * Attribute value or segment
88: */
89: chunk_t value;
90:
91: /**
92: * Noskip flag
93: */
94: bool noskip_flag;
95:
96: /**
97: * Remediation Parameters Type
98: */
99: pen_type_t parameters_type;
100:
101: /**
102: * Remediation Parameters
103: */
104: chunk_t parameters;
105:
106: /**
107: * Remediation String
108: */
109: chunk_t string;
110:
111: /**
112: * Remediation Language Code
113: */
114: chunk_t lang_code;
115:
116: /**
117: * Reference count
118: */
119: refcount_t ref;
120: };
121:
122: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
123: private_ietf_attr_remediation_instr_t *this)
124: {
125: return this->type;
126: }
127:
128: METHOD(pa_tnc_attr_t, get_value, chunk_t,
129: private_ietf_attr_remediation_instr_t *this)
130: {
131: return this->value;
132: }
133:
134: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
135: private_ietf_attr_remediation_instr_t *this)
136: {
137: return this->noskip_flag;
138: }
139:
140: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
141: private_ietf_attr_remediation_instr_t *this, bool noskip)
142: {
143: this->noskip_flag = noskip;
144: }
145:
146: METHOD(pa_tnc_attr_t, build, void,
147: private_ietf_attr_remediation_instr_t *this)
148: {
149: bio_writer_t *writer;
150:
151: if (this->value.ptr)
152: {
153: return;
154: }
155:
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);
161:
162: this->value = writer->extract_buf(writer);
163: this->length = this->value.len;
164: writer->destroy(writer);
165: }
166:
167: METHOD(pa_tnc_attr_t, process, status_t,
168: private_ietf_attr_remediation_instr_t *this, uint32_t *offset)
169: {
170: bio_reader_t *reader;
171: uint8_t reserved;
172: status_t status = SUCCESS;
173: u_char *pos;
174:
175: *offset = 0;
176:
177: if (this->value.len < this->length)
178: {
179: return NEED_MORE;
180: }
181: if (this->value.len < REMEDIATION_INSTR_MIN_SIZE)
182: {
183: DBG1(DBG_TNC, "insufficient data for IETF remediation instructions");
184: return FAILED;
185: }
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);
191:
192: this->parameters = chunk_clone(this->parameters);
193: reader->destroy(reader);
194:
195: if (this->parameters_type.vendor_id == PEN_IETF &&
196: this->parameters_type.type == IETF_REMEDIATION_PARAMETERS_STRING)
197: {
198: reader = bio_reader_create(this->parameters);
199: status = FAILED;
200: *offset = 8;
201:
202: if (!reader->read_data32(reader, &this->string))
203: {
204: DBG1(DBG_TNC, "insufficient data for IETF remediation string");
205: goto end;
206: }
207: *offset += 4;
208:
209: pos = memchr(this->string.ptr, '\0', this->string.len);
210: if (pos)
211: {
212: DBG1(DBG_TNC, "nul termination in IETF remediation string");
213: *offset += (pos - this->string.ptr);
214: goto end;
215: }
216: *offset += this->string.len;
217:
218: if (!reader->read_data8(reader, &this->lang_code))
219: {
220: DBG1(DBG_TNC, "insufficient data for IETF remediation lang code");
221: goto end;
222: }
223: status = SUCCESS;
224:
225: end:
226: reader->destroy(reader);
227: }
228: return status;
229: }
230:
231: METHOD(pa_tnc_attr_t, add_segment, void,
232: private_ietf_attr_remediation_instr_t *this, chunk_t segment)
233: {
234: this->value = chunk_cat("mc", this->value, segment);
235: }
236:
237: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
238: private_ietf_attr_remediation_instr_t *this)
239: {
240: ref_get(&this->ref);
241: return &this->public.pa_tnc_attribute;
242: }
243:
244: METHOD(pa_tnc_attr_t, destroy, void,
245: private_ietf_attr_remediation_instr_t *this)
246: {
247: if (ref_put(&this->ref))
248: {
249: free(this->parameters.ptr);
250: free(this->value.ptr);
251: free(this);
252: }
253: }
254:
255: METHOD(ietf_attr_remediation_instr_t, get_parameters_type, pen_type_t,
256: private_ietf_attr_remediation_instr_t *this)
257: {
258: return this->parameters_type;
259: }
260:
261: METHOD(ietf_attr_remediation_instr_t, get_parameters, chunk_t,
262: private_ietf_attr_remediation_instr_t *this)
263: {
264: return this->parameters;
265: }
266:
267: METHOD(ietf_attr_remediation_instr_t, get_string, chunk_t,
268: private_ietf_attr_remediation_instr_t *this, chunk_t *lang_code)
269: {
270: if (lang_code)
271: {
272: *lang_code = this->lang_code;
273: }
274: return this->string;
275: }
276:
277: /**
278: * Described in header.
279: */
280: pa_tnc_attr_t *ietf_attr_remediation_instr_create(pen_type_t parameters_type,
281: chunk_t parameters)
282: {
283: private_ietf_attr_remediation_instr_t *this;
284:
285: INIT(this,
286: .public = {
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,
292: .build = _build,
293: .process = _process,
294: .add_segment = _add_segment,
295: .get_ref = _get_ref,
296: .destroy = _destroy,
297: },
298: .get_parameters_type = _get_parameters_type,
299: .get_parameters = _get_parameters,
300: .get_uri = _get_parameters,
301: .get_string = _get_string,
302: },
303: .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS },
304: .parameters_type = parameters_type,
305: .parameters = chunk_clone(parameters),
306: .ref = 1,
307: );
308:
309: return &this->public.pa_tnc_attribute;
310: }
311:
312: /**
313: * Described in header.
314: */
315: pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_uri(chunk_t uri)
316: {
317: pen_type_t type = { PEN_IETF, IETF_REMEDIATION_PARAMETERS_URI };
318:
319: return ietf_attr_remediation_instr_create(type, uri);
320: }
321:
322: /**
323: * Described in header.
324: */
325: pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_string(chunk_t string,
326: chunk_t lang_code)
327: {
328: pa_tnc_attr_t *attr;
329: bio_writer_t *writer;
330: pen_type_t type = { PEN_IETF, IETF_REMEDIATION_PARAMETERS_STRING };
331:
332: /* limit language code to 255 octets */
333: lang_code.len = min(255, lang_code.len);
334:
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);
338:
339: attr = ietf_attr_remediation_instr_create(type, writer->get_buf(writer));
340: writer->destroy(writer);
341:
342: return attr;
343: }
344:
345: /**
346: * Described in header.
347: */
348: pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(size_t length,
349: chunk_t data)
350: {
351: private_ietf_attr_remediation_instr_t *this;
352:
353: INIT(this,
354: .public = {
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,
360: .build = _build,
361: .process = _process,
362: .add_segment = _add_segment,
363: .get_ref = _get_ref,
364: .destroy = _destroy,
365: },
366: .get_parameters_type = _get_parameters_type,
367: .get_parameters = _get_parameters,
368: .get_uri = _get_parameters,
369: .get_string = _get_string,
370: },
371: .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS },
372: .length = length,
373: .value = chunk_clone(data),
374: .ref = 1,
375: );
376:
377: return &this->public.pa_tnc_attribute;
378: }
379:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>