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>