Annotation of embedaddon/strongswan/src/libimcv/ietf/ietf_attr_string_version.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_string_version.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_string_version_t private_ietf_attr_string_version_t;
24:
25: /**
26: * PA-TNC String Version type (see section 4.2.4 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: * | Version Len | Product Version Number (Variable Length) |
32: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33: * | Build Num Len | Internal Build Number (Variable Length) |
34: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35: * | Config. Len | Configuration Version Number (Variable Length)|
36: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37: */
38:
39: #define STRING_VERSION_MIN_SIZE 3
40:
41: /**
42: * Private data of an ietf_attr_string_version_t object.
43: */
44: struct private_ietf_attr_string_version_t {
45:
46: /**
47: * Public members of ietf_attr_string_version_t
48: */
49: ietf_attr_string_version_t public;
50:
51: /**
52: * Vendor-specific attribute type
53: */
54: pen_type_t type;
55:
56: /**
57: * Length of attribute value
58: */
59: size_t length;
60:
61: /**
62: * Attribute value or segment
63: */
64: chunk_t value;
65:
66: /**
67: * Noskip flag
68: */
69: bool noskip_flag;
70:
71: /**
72: * Product Version Number
73: */
74: chunk_t version;
75:
76: /**
77: * Internal Build Number
78: */
79: chunk_t build;
80:
81: /**
82: * Configuration Version Number
83: */
84: chunk_t config;
85:
86: /**
87: * Reference count
88: */
89: refcount_t ref;
90: };
91:
92: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
93: private_ietf_attr_string_version_t *this)
94: {
95: return this->type;
96: }
97:
98: METHOD(pa_tnc_attr_t, get_value, chunk_t,
99: private_ietf_attr_string_version_t *this)
100: {
101: return this->value;
102: }
103:
104: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
105: private_ietf_attr_string_version_t *this)
106: {
107: return this->noskip_flag;
108: }
109:
110: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
111: private_ietf_attr_string_version_t *this, bool noskip)
112: {
113: this->noskip_flag = noskip;
114: }
115:
116: METHOD(pa_tnc_attr_t, build, void,
117: private_ietf_attr_string_version_t *this)
118: {
119: bio_writer_t *writer;
120:
121: if (this->value.ptr)
122: {
123: return;
124: }
125:
126: writer = bio_writer_create(STRING_VERSION_MIN_SIZE);
127: writer->write_data8(writer, this->version);
128: writer->write_data8(writer, this->build);
129: writer->write_data8(writer, this->config);
130:
131: this->value = writer->extract_buf(writer);
132: this->length = this->value.len;
133: writer->destroy(writer);
134: }
135:
136: METHOD(pa_tnc_attr_t, process, status_t,
137: private_ietf_attr_string_version_t *this, uint32_t *offset)
138: {
139: bio_reader_t *reader;
140: status_t status = FAILED;
141: chunk_t version, build, config;
142: u_char *pos;
143:
144: *offset = 0;
145:
146: if (this->value.len < this->length)
147: {
148: return NEED_MORE;
149: }
150: if (this->value.len < STRING_VERSION_MIN_SIZE)
151: {
152: DBG1(DBG_TNC, "insufficient data for IETF string version");
153: return FAILED;
154: }
155: reader = bio_reader_create(this->value);
156:
157: if (!reader->read_data8(reader, &version))
158: {
159: DBG1(DBG_TNC, "insufficient data for IETF product version number");
160: goto end;
161:
162: }
163: pos = memchr(version.ptr, '\0', version.len);
164: if (pos)
165: {
166: DBG1(DBG_TNC, "nul termination in IETF product version number");
167: *offset += 1 + (pos - version.ptr);
168: goto end;
169: }
170: *offset += 1 + version.len;
171:
172: if (!reader->read_data8(reader, &build))
173: {
174: DBG1(DBG_TNC, "insufficient data for IETF internal build number");
175: goto end;
176:
177: }
178: pos = memchr(build.ptr, '\0', build.len);
179: if (pos)
180: {
181: DBG1(DBG_TNC, "nul termination in IETF internal build number");
182: *offset += 1 + (pos - build.ptr);
183: goto end;
184: }
185: *offset += 1 + build.len;
186:
187: if (!reader->read_data8(reader, &config))
188: {
189: DBG1(DBG_TNC, "insufficient data for IETF configuration version number");
190: goto end;
191:
192: }
193: pos = memchr(config.ptr, '\0', config.len);
194: if (pos)
195: {
196: DBG1(DBG_TNC, "nul termination in IETF configuration version number");
197: *offset += 1 + (pos - config.ptr);
198: goto end;
199: }
200:
201: this->version = chunk_clone(version);
202: this->build = chunk_clone(build);
203: this->config = chunk_clone(config);
204: status = SUCCESS;
205:
206: end:
207: reader->destroy(reader);
208: return status;
209: }
210:
211: METHOD(pa_tnc_attr_t, add_segment, void,
212: private_ietf_attr_string_version_t *this, chunk_t segment)
213: {
214: this->value = chunk_cat("mc", this->value, segment);
215: }
216:
217: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
218: private_ietf_attr_string_version_t *this)
219: {
220: ref_get(&this->ref);
221: return &this->public.pa_tnc_attribute;
222: }
223:
224: METHOD(pa_tnc_attr_t, destroy, void,
225: private_ietf_attr_string_version_t *this)
226: {
227: if (ref_put(&this->ref))
228: {
229: free(this->version.ptr);
230: free(this->build.ptr);
231: free(this->config.ptr);
232: free(this->value.ptr);
233: free(this);
234: }
235: }
236:
237: METHOD(ietf_attr_string_version_t, get_version, chunk_t,
238: private_ietf_attr_string_version_t *this, chunk_t *build, chunk_t *config)
239: {
240: if (build)
241: {
242: *build = this->build;
243: }
244: if (config)
245: {
246: *config = this->config;
247: }
248: return this->version;
249: }
250:
251: /**
252: * Described in header.
253: */
254: pa_tnc_attr_t *ietf_attr_string_version_create(chunk_t version, chunk_t build,
255: chunk_t config)
256: {
257: private_ietf_attr_string_version_t *this;
258:
259: /* limit version numbers to 255 octets */
260: version.len = min(255, version.len);
261: build.len = min(255, build.len);
262: config.len = min(255, config.len);
263:
264: INIT(this,
265: .public = {
266: .pa_tnc_attribute = {
267: .get_type = _get_type,
268: .get_value = _get_value,
269: .get_noskip_flag = _get_noskip_flag,
270: .set_noskip_flag = _set_noskip_flag,
271: .build = _build,
272: .process = _process,
273: .add_segment = _add_segment,
274: .get_ref = _get_ref,
275: .destroy = _destroy,
276: },
277: .get_version = _get_version,
278: },
279: .type = { PEN_IETF, IETF_ATTR_STRING_VERSION },
280: .version = chunk_clone(version),
281: .build = chunk_clone(build),
282: .config = chunk_clone(config),
283: .ref = 1,
284: );
285:
286: return &this->public.pa_tnc_attribute;
287: }
288:
289: /**
290: * Described in header.
291: */
292: pa_tnc_attr_t *ietf_attr_string_version_create_from_data(size_t length,
293: chunk_t data)
294: {
295: private_ietf_attr_string_version_t *this;
296:
297: INIT(this,
298: .public = {
299: .pa_tnc_attribute = {
300: .get_type = _get_type,
301: .get_value = _get_value,
302: .get_noskip_flag = _get_noskip_flag,
303: .set_noskip_flag = _set_noskip_flag,
304: .build = _build,
305: .process = _process,
306: .add_segment = _add_segment,
307: .get_ref = _get_ref,
308: .destroy = _destroy,
309: },
310: .get_version = _get_version,
311: },
312: .type = { PEN_IETF, IETF_ATTR_STRING_VERSION },
313: .length = length,
314: .value = chunk_clone(data),
315: .ref = 1,
316: );
317:
318: return &this->public.pa_tnc_attribute;
319: }
320:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>