Annotation of embedaddon/strongswan/src/libimcv/ita/ita_attr_symlinks.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2020 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 "ita_attr_symlinks.h"
17:
18: #include <pa_tnc/pa_tnc_msg.h>
19: #include <bio/bio_writer.h>
20: #include <bio/bio_reader.h>
21: #include <collections/linked_list.h>
22: #include <utils/debug.h>
23:
24: typedef struct private_ita_attr_symlinks_t private_ita_attr_symlinks_t;
25:
26: /**
27: * List of Symbolic Links pointing to Directories
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: * | Number of Symlinks |
33: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34: * | Symlink #1 Length | Symlink #1 Path (Var Len) ~
35: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36: * | Symlink #1 Path (Variable Length) |
37: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38: * | Directory #1 Length | Directory #1 Path (Var Len) ~
39: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40: * | Directory #1 Path (Variable Length) |
41: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42: * | Symlink #2 Length | Symlink #2 Path (Var Len) ~
43: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44: * | Symlink #2 Path (Variable Length) |
45: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46: * | Directory #2 Length | Directory #2 Path (Var Len) ~
47: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48: * | Directory #2 Path (Variable Length) |
49: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50: * ...........................
51: */
52:
53: #define ITA_ATTR_SYMLINKS_SIZE 4
54:
55: /**
56: * Private data of an ita_attr_symlinks_t object.
57: */
58: struct private_ita_attr_symlinks_t {
59:
60: /**
61: * Public members of ita_attr_symlinks_t
62: */
63: ita_attr_symlinks_t public;
64:
65: /**
66: * Vendor-specific attribute type
67: */
68: pen_type_t type;
69:
70: /**
71: * Length of attribute value
72: */
73: size_t length;
74:
75: /**
76: * Offset up to which attribute value has been processed
77: */
78: size_t offset;
79:
80: /**
81: * Current position of attribute value pointer
82: */
83: chunk_t value;
84:
85: /**
86: * Contains complete attribute or current segment
87: */
88: chunk_t segment;
89:
90: /**
91: * Noskip flag
92: */
93: bool noskip_flag;
94:
95: /**
96: * Number of symbolic link entries
97: */
98: uint32_t count;
99:
100: /**
101: * List of symbolic links
102: */
103: pts_symlinks_t *symlinks;
104:
105: /**
106: * Reference count
107: */
108: refcount_t ref;
109: };
110:
111: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
112: private_ita_attr_symlinks_t *this)
113: {
114: return this->type;
115: }
116:
117: METHOD(pa_tnc_attr_t, get_value, chunk_t,
118: private_ita_attr_symlinks_t *this)
119: {
120: return this->value;
121: }
122:
123: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
124: private_ita_attr_symlinks_t *this)
125: {
126: return this->noskip_flag;
127: }
128:
129: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
130: private_ita_attr_symlinks_t *this, bool noskip)
131: {
132: this->noskip_flag = noskip;
133: }
134:
135: METHOD(pa_tnc_attr_t, build, void,
136: private_ita_attr_symlinks_t *this)
137: {
138: bio_writer_t *writer;
139: enumerator_t *enumerator;
140: chunk_t symlink, dir;
141:
142: if (this->value.ptr)
143: {
144: return;
145: }
146: this->count = this->symlinks->get_count(this->symlinks);
147:
148: writer = bio_writer_create(ITA_ATTR_SYMLINKS_SIZE);
149: writer->write_uint32(writer, this->count);
150:
151: enumerator = this->symlinks->create_enumerator(this->symlinks);
152: while (enumerator->enumerate(enumerator, &symlink, &dir))
153: {
154: writer->write_data16(writer, symlink);
155: writer->write_data16(writer, dir);
156: }
157: enumerator->destroy(enumerator);
158:
159: this->value = writer->extract_buf(writer);
160: this->segment = this->value;
161: this->length = this->value.len;
162: writer->destroy(writer);
163: }
164:
165: METHOD(pa_tnc_attr_t, process, status_t,
166: private_ita_attr_symlinks_t *this, uint32_t *offset)
167: {
168: bio_reader_t *reader;
169: chunk_t symlink, dir;
170: status_t status = NEED_MORE;
171:
172: if (this->offset == 0)
173: {
174: if (this->length < ITA_ATTR_SYMLINKS_SIZE)
175: {
176: DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_ITA,
177: ita_attr_names, this->type.type);
178: *offset = this->offset;
179: return FAILED;
180: }
181: if (this->value.len < ITA_ATTR_SYMLINKS_SIZE)
182: {
183: return NEED_MORE;
184: }
185: reader = bio_reader_create(this->value);
186: reader->read_uint32(reader, &this->count);
187: this->offset = ITA_ATTR_SYMLINKS_SIZE;
188: this->value = reader->peek(reader);
189: reader->destroy(reader);
190: }
191:
192: this->symlinks = pts_symlinks_create();
193: reader = bio_reader_create(this->value);
194:
195: while (this->count)
196: {
197: if (!reader->read_data16(reader, &symlink) ||
198: !reader->read_data16(reader, &dir))
199: {
200: goto end;
201: }
202: this->offset += this->value.len - reader->remaining(reader);
203: this->value = reader->peek(reader);
204: this->symlinks->add(this->symlinks, symlink, dir);
205: this->count--;
206: }
207:
208: status = SUCCESS;
209:
210: if (this->length != this->offset)
211: {
212: DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_ITA,
213: ita_attr_names, this->type.type);
214: *offset = this->offset;
215: status = FAILED;
216: }
217:
218: end:
219: reader->destroy(reader);
220: return status;
221: }
222:
223: METHOD(pa_tnc_attr_t, add_segment, void,
224: private_ita_attr_symlinks_t *this, chunk_t segment)
225: {
226: this->value = chunk_cat("cc", this->value, segment);
227: chunk_free(&this->segment);
228: this->segment = this->value;
229: }
230:
231: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
232: private_ita_attr_symlinks_t *this)
233: {
234: ref_get(&this->ref);
235: return &this->public.pa_tnc_attribute;
236: }
237:
238: METHOD(pa_tnc_attr_t, destroy, void,
239: private_ita_attr_symlinks_t *this)
240: {
241: if (ref_put(&this->ref))
242: {
243: DESTROY_IF(this->symlinks);
244: free(this->segment.ptr);
245: free(this);
246: }
247: }
248:
249: METHOD(ita_attr_symlinks_t, get_symlinks, pts_symlinks_t*,
250: private_ita_attr_symlinks_t *this)
251: {
252: return this->symlinks;
253: }
254:
255: /**
256: * Described in header.
257: */
258: pa_tnc_attr_t *ita_attr_symlinks_create(pts_symlinks_t *symlinks)
259: {
260: private_ita_attr_symlinks_t *this;
261:
262: INIT(this,
263: .public = {
264: .pa_tnc_attribute = {
265: .get_type = _get_type,
266: .get_value = _get_value,
267: .get_noskip_flag = _get_noskip_flag,
268: .set_noskip_flag = _set_noskip_flag,
269: .build = _build,
270: .process = _process,
271: .add_segment = _add_segment,
272: .get_ref = _get_ref,
273: .destroy = _destroy,
274: },
275: .get_symlinks = _get_symlinks,
276: },
277: .type = { PEN_ITA, ITA_ATTR_SYMLINKS },
278: .symlinks = symlinks->get_ref(symlinks),
279: .ref = 1,
280: );
281:
282: return &this->public.pa_tnc_attribute;
283: }
284:
285:
286: /**
287: * Described in header.
288: */
289: pa_tnc_attr_t *ita_attr_symlinks_create_from_data(size_t length, chunk_t data)
290: {
291: private_ita_attr_symlinks_t *this;
292:
293: INIT(this,
294: .public = {
295: .pa_tnc_attribute = {
296: .get_type = _get_type,
297: .get_value = _get_value,
298: .get_noskip_flag = _get_noskip_flag,
299: .set_noskip_flag = _set_noskip_flag,
300: .build = _build,
301: .process = _process,
302: .add_segment = _add_segment,
303: .get_ref = _get_ref,
304: .destroy = _destroy,
305: },
306: .get_symlinks = _get_symlinks,
307: },
308: .type = { PEN_ITA, ITA_ATTR_SYMLINKS },
309: .length = length,
310: .segment = chunk_clone(data),
311: .ref = 1,
312: );
313:
314: /* received either complete attribute value or first segment */
315: this->value = this->segment;
316:
317: return &this->public.pa_tnc_attribute;
318: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>