Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/delete_payload.c, revision 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>