Annotation of embedaddon/strongswan/src/libimcv/ita/ita_attr_symlinks.c, revision 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>