Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/delete_payload.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2015 Tobias Brunner
                      3:  * Copyright (C) 2005-2010 Martin Willi
                      4:  * Copyright (C) 2010 revosec AG
                      5:  * Copyright (C) 2005 Jan Hutter
                      6:  * HSR Hochschule fuer Technik Rapperswil
                      7:  *
                      8:  * This program is free software; you can redistribute it and/or modify it
                      9:  * under the terms of the GNU General Public License as published by the
                     10:  * Free Software Foundation; either version 2 of the License, or (at your
                     11:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     12:  *
                     13:  * This program is distributed in the hope that it will be useful, but
                     14:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     16:  * for more details.
                     17:  */
                     18: 
                     19: #include <stddef.h>
                     20: 
                     21: #include "delete_payload.h"
                     22: 
                     23: 
                     24: typedef struct private_delete_payload_t private_delete_payload_t;
                     25: 
                     26: /**
                     27:  * Private data of an delete_payload_t object.
                     28:  */
                     29: struct private_delete_payload_t {
                     30: 
                     31:        /**
                     32:         * Public delete_payload_t interface.
                     33:         */
                     34:        delete_payload_t public;
                     35: 
                     36:        /**
                     37:         * Next payload type.
                     38:         */
                     39:        uint8_t  next_payload;
                     40: 
                     41:        /**
                     42:         * Critical flag.
                     43:         */
                     44:        bool critical;
                     45: 
                     46:        /**
                     47:         * reserved bits
                     48:         */
                     49:        bool reserved[8];
                     50: 
                     51:        /**
                     52:         * Length of this payload.
                     53:         */
                     54:        uint16_t payload_length;
                     55: 
                     56:        /**
                     57:         * IKEv1 Domain of Interpretation
                     58:         */
                     59:        uint32_t doi;
                     60: 
                     61:        /**
                     62:         * Protocol ID.
                     63:         */
                     64:        uint8_t protocol_id;
                     65: 
                     66:        /**
                     67:         * SPI Size.
                     68:         */
                     69:        uint8_t spi_size;
                     70: 
                     71:        /**
                     72:         * Number of SPI's.
                     73:         */
                     74:        uint16_t spi_count;
                     75: 
                     76:        /**
                     77:         * The contained SPI's.
                     78:         */
                     79:        chunk_t spis;
                     80: 
                     81:        /**
                     82:         * Payload type, PLV2_DELETE or PLV1_DELETE
                     83:         */
                     84:        payload_type_t type;
                     85: };
                     86: 
                     87: /**
                     88:  * Encoding rules for an IKEv2 delete payload.
                     89:  */
                     90: static encoding_rule_t encodings_v2[] = {
                     91:        /* 1 Byte next payload type, stored in the field next_payload */
                     92:        { U_INT_8,                      offsetof(private_delete_payload_t, next_payload)        },
                     93:        /* the critical bit */
                     94:        { FLAG,                         offsetof(private_delete_payload_t, critical)            },
                     95:        /* 7 Bit reserved bits */
                     96:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[0])         },
                     97:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[1])         },
                     98:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[2])         },
                     99:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[3])         },
                    100:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[4])         },
                    101:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[5])         },
                    102:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[6])         },
                    103:        /* Length of the whole payload*/
                    104:        { PAYLOAD_LENGTH,       offsetof(private_delete_payload_t, payload_length)      },
                    105:        { U_INT_8,                      offsetof(private_delete_payload_t, protocol_id)         },
                    106:        { U_INT_8,                      offsetof(private_delete_payload_t, spi_size)            },
                    107:        { U_INT_16,                     offsetof(private_delete_payload_t, spi_count)           },
                    108:        /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
                    109:        { CHUNK_DATA,           offsetof(private_delete_payload_t, spis)                        },
                    110: };
                    111: 
                    112: /*
                    113:                            1                   2                   3
                    114:        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
                    115:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    116:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
                    117:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    118:       ! Protocol ID   !   SPI Size    !           # of SPIs           !
                    119:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    120:       !                                                               !
                    121:       ~               Security Parameter Index(es) (SPI)              ~
                    122:       !                                                               !
                    123:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    124: */
                    125: 
                    126: /**
                    127:  * Encoding rules for an IKEv1 delete payload.
                    128:  */
                    129: static encoding_rule_t encodings_v1[] = {
                    130:        /* 1 Byte next payload type, stored in the field next_payload */
                    131:        { U_INT_8,                      offsetof(private_delete_payload_t, next_payload)        },
                    132:        /* 8 Bit reserved bits */
                    133:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[0])         },
                    134:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[1])         },
                    135:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[2])         },
                    136:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[3])         },
                    137:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[4])         },
                    138:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[5])         },
                    139:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[6])         },
                    140:        { RESERVED_BIT,         offsetof(private_delete_payload_t, reserved[7])         },
                    141:        /* Length of the whole payload*/
                    142:        { PAYLOAD_LENGTH,       offsetof(private_delete_payload_t, payload_length)      },
                    143:        /* Domain of interpretation */
                    144:        { U_INT_32,                     offsetof(private_delete_payload_t, doi)                         },
                    145:        { U_INT_8,                      offsetof(private_delete_payload_t, protocol_id)         },
                    146:        { U_INT_8,                      offsetof(private_delete_payload_t, spi_size)            },
                    147:        { U_INT_16,                     offsetof(private_delete_payload_t, spi_count)           },
                    148:        /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
                    149:        { CHUNK_DATA,           offsetof(private_delete_payload_t, spis)                        },
                    150: };
                    151: 
                    152: /*
                    153:                            1                   2                   3
                    154:        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
                    155:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    156:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
                    157:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    158:       !                          DOI                                  !
                    159:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    160:       ! Protocol ID   !   SPI Size    !           # of SPIs           !
                    161:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    162:       !                                                               !
                    163:       ~               Security Parameter Index(es) (SPI)              ~
                    164:       !                                                               !
                    165:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    166: */
                    167: 
                    168: METHOD(payload_t, verify, status_t,
                    169:        private_delete_payload_t *this)
                    170: {
                    171:        switch (this->protocol_id)
                    172:        {
                    173:                case PROTO_AH:
                    174:                case PROTO_ESP:
                    175:                        if (this->spi_size != 4)
                    176:                        {
                    177:                                return FAILED;
                    178:                        }
                    179:                        break;
                    180:                case PROTO_IKE:
                    181:                case 0:
                    182:                        if (this->type == PLV2_DELETE)
                    183:                        {       /* IKEv2 deletion has no spi assigned! */
                    184:                                if (this->spi_size != 0)
                    185:                                {
                    186:                                        return FAILED;
                    187:                                }
                    188:                        }
                    189:                        else
                    190:                        {       /* IKEv1 uses the two concatenated ISAKMP cookies as SPI */
                    191:                                if (this->spi_size != 16)
                    192:                                {
                    193:                                        return FAILED;
                    194:                                }
                    195:                        }
                    196:                        break;
                    197:                default:
                    198:                        return FAILED;
                    199:        }
                    200:        if (this->spis.len != (this->spi_count * this->spi_size))
                    201:        {
                    202:                return FAILED;
                    203:        }
                    204:        return SUCCESS;
                    205: }
                    206: 
                    207: METHOD(payload_t, get_encoding_rules, int,
                    208:        private_delete_payload_t *this, encoding_rule_t **rules)
                    209: {
                    210:        if (this->type == PLV2_DELETE)
                    211:        {
                    212:                *rules = encodings_v2;
                    213:                return countof(encodings_v2);
                    214:        }
                    215:        *rules = encodings_v1;
                    216:        return countof(encodings_v1);
                    217: }
                    218: 
                    219: METHOD(payload_t, get_header_length, int,
                    220:        private_delete_payload_t *this)
                    221: {
                    222:        if (this->type == PLV2_DELETE)
                    223:        {
                    224:                return 8;
                    225:        }
                    226:        return 12;
                    227: }
                    228: 
                    229: METHOD(payload_t, get_payload_type, payload_type_t,
                    230:        private_delete_payload_t *this)
                    231: {
                    232:        return this->type;
                    233: }
                    234: 
                    235: METHOD(payload_t, get_next_type, payload_type_t,
                    236:        private_delete_payload_t *this)
                    237: {
                    238:        return this->next_payload;
                    239: }
                    240: 
                    241: METHOD(payload_t, set_next_type, void,
                    242:        private_delete_payload_t *this,payload_type_t type)
                    243: {
                    244:        this->next_payload = type;
                    245: }
                    246: 
                    247: METHOD(payload_t, get_length, size_t,
                    248:        private_delete_payload_t *this)
                    249: {
                    250:        return this->payload_length;
                    251: }
                    252: 
                    253: METHOD(delete_payload_t, get_protocol_id, protocol_id_t,
                    254:        private_delete_payload_t *this)
                    255: {
                    256:        return this->protocol_id;
                    257: }
                    258: 
                    259: METHOD(delete_payload_t, add_spi, void,
                    260:        private_delete_payload_t *this, uint32_t spi)
                    261: {
                    262:        switch (this->protocol_id)
                    263:        {
                    264:                case PROTO_AH:
                    265:                case PROTO_ESP:
                    266:                        this->spi_count++;
                    267:                        this->payload_length += sizeof(spi);
                    268:                        this->spis = chunk_cat("mc", this->spis, chunk_from_thing(spi));
                    269:                        break;
                    270:                default:
                    271:                        break;
                    272:        }
                    273: }
                    274: 
                    275: METHOD(delete_payload_t, set_ike_spi, void,
                    276:        private_delete_payload_t *this, uint64_t spi_i, uint64_t spi_r)
                    277: {
                    278:        free(this->spis.ptr);
                    279:        this->spis = chunk_cat("cc", chunk_from_thing(spi_i),
                    280:                                                                 chunk_from_thing(spi_r));
                    281:        this->spi_count = 1;
                    282:        this->payload_length = get_header_length(this) + this->spi_size;
                    283: }
                    284: 
                    285: METHOD(delete_payload_t, get_ike_spi, bool,
                    286:        private_delete_payload_t *this, uint64_t *spi_i, uint64_t *spi_r)
                    287: {
                    288:        if (this->protocol_id != PROTO_IKE ||
                    289:                this->spis.len < 2 * sizeof(uint64_t))
                    290:        {
                    291:                return FALSE;
                    292:        }
                    293:        memcpy(spi_i, this->spis.ptr, sizeof(uint64_t));
                    294:        memcpy(spi_r, this->spis.ptr + sizeof(uint64_t), sizeof(uint64_t));
                    295:        return TRUE;
                    296: }
                    297: 
                    298: /**
                    299:  * SPI enumerator implementation
                    300:  */
                    301: typedef struct {
                    302:        /** implements enumerator_t */
                    303:        enumerator_t public;
                    304:        /** remaining SPIs */
                    305:        chunk_t spis;
                    306: } spi_enumerator_t;
                    307: 
                    308: METHOD(enumerator_t, spis_enumerate, bool,
                    309:        spi_enumerator_t *this, va_list args)
                    310: {
                    311:        uint32_t *spi;
                    312: 
                    313:        VA_ARGS_VGET(args, spi);
                    314: 
                    315:        if (this->spis.len >= sizeof(*spi))
                    316:        {
                    317:                memcpy(spi, this->spis.ptr, sizeof(*spi));
                    318:                this->spis = chunk_skip(this->spis, sizeof(*spi));
                    319:                return TRUE;
                    320:        }
                    321:        return FALSE;
                    322: }
                    323: 
                    324: METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*,
                    325:        private_delete_payload_t *this)
                    326: {
                    327:        spi_enumerator_t *e;
                    328: 
                    329:        if (this->spi_size != sizeof(uint32_t))
                    330:        {
                    331:                return enumerator_create_empty();
                    332:        }
                    333:        INIT(e,
                    334:                .public = {
                    335:                        .enumerate = enumerator_enumerate_default,
                    336:                        .venumerate = _spis_enumerate,
                    337:                        .destroy = (void*)free,
                    338:                },
                    339:                .spis = this->spis,
                    340:        );
                    341:        return &e->public;
                    342: }
                    343: 
                    344: METHOD2(payload_t, delete_payload_t, destroy, void,
                    345:        private_delete_payload_t *this)
                    346: {
                    347:        free(this->spis.ptr);
                    348:        free(this);
                    349: }
                    350: 
                    351: /*
                    352:  * Described in header
                    353:  */
                    354: delete_payload_t *delete_payload_create(payload_type_t type,
                    355:                                                                                protocol_id_t protocol_id)
                    356: {
                    357:        private_delete_payload_t *this;
                    358: 
                    359:        INIT(this,
                    360:                .public = {
                    361:                        .payload_interface = {
                    362:                                .verify = _verify,
                    363:                                .get_encoding_rules = _get_encoding_rules,
                    364:                                .get_header_length = _get_header_length,
                    365:                                .get_length = _get_length,
                    366:                                .get_next_type = _get_next_type,
                    367:                                .set_next_type = _set_next_type,
                    368:                                .get_type = _get_payload_type,
                    369:                                .destroy = _destroy,
                    370:                        },
                    371:                        .get_protocol_id = _get_protocol_id,
                    372:                        .add_spi = _add_spi,
                    373:                        .set_ike_spi = _set_ike_spi,
                    374:                        .get_ike_spi = _get_ike_spi,
                    375:                        .create_spi_enumerator = _create_spi_enumerator,
                    376:                        .destroy = _destroy,
                    377:                },
                    378:                .next_payload = PL_NONE,
                    379:                .protocol_id = protocol_id,
                    380:                .doi = IKEV1_DOI_IPSEC,
                    381:                .type = type,
                    382:        );
                    383:        this->payload_length = get_header_length(this);
                    384: 
                    385:        if (protocol_id == PROTO_IKE)
                    386:        {
                    387:                if (type == PLV1_DELETE)
                    388:                {
                    389:                        this->spi_size = 16;
                    390:                }
                    391:        }
                    392:        else
                    393:        {
                    394:                this->spi_size = 4;
                    395:        }
                    396:        return &this->public;
                    397: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>