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

1.1       misho       1: /*
                      2:  * Copyright (C) 2007 Tobias Brunner
                      3:  * Copyright (C) 2005-2006 Martin Willi
                      4:  * Copyright (C) 2005 Jan Hutter
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: /* offsetof macro */
                     19: #include <stddef.h>
                     20: 
                     21: #include "ike_header.h"
                     22: 
                     23: #include <encoding/payloads/encodings.h>
                     24: 
                     25: 
                     26: typedef struct private_ike_header_t private_ike_header_t;
                     27: 
                     28: /**
                     29:  * Private data of an ike_header_t object.
                     30:  */
                     31: struct private_ike_header_t {
                     32:        /**
                     33:         * Public interface.
                     34:         */
                     35:        ike_header_t public;
                     36: 
                     37:        /**
                     38:         * SPI of the initiator.
                     39:         */
                     40:        uint64_t initiator_spi;
                     41: 
                     42:        /**
                     43:         * SPI of the responder.
                     44:         */
                     45:        uint64_t responder_spi;
                     46: 
                     47:        /**
                     48:         * Next payload type.
                     49:         */
                     50:        uint8_t  next_payload;
                     51:        /**
                     52:         * IKE major version.
                     53:         */
                     54:        uint8_t  maj_version;
                     55: 
                     56:        /**
                     57:         * IKE minor version.
                     58:         */
                     59:        uint8_t  min_version;
                     60: 
                     61:        /**
                     62:         * Exchange type .
                     63:         */
                     64:        uint8_t  exchange_type;
                     65: 
                     66:        /**
                     67:         * Flags of the Message.
                     68:         */
                     69:        struct {
                     70:                /**
                     71:                 * Sender is initiator of the associated IKE_SA_INIT-Exchange.
                     72:                 */
                     73:                bool initiator;
                     74: 
                     75:                /**
                     76:                 * Is protocol supporting higher version?
                     77:                 */
                     78:                bool version;
                     79: 
                     80:                /**
                     81:                 * TRUE, if this is a response, FALSE if its a Request.
                     82:                 */
                     83:                bool response;
                     84: 
                     85:                /**
                     86:                 * TRUE, if the packet is encrypted (IKEv1).
                     87:                 */
                     88:                bool encryption;
                     89: 
                     90:                /**
                     91:                 * TRUE, if the commit flag is set (IKEv1).
                     92:                 */
                     93:                bool commit;
                     94: 
                     95:                /**
                     96:                 * TRUE, if the auth only flag is set (IKEv1).
                     97:                 */
                     98:                bool authonly;
                     99:        } flags;
                    100: 
                    101:        /**
                    102:         * Reserved bits of IKE header
                    103:         */
                    104:        bool reserved[2];
                    105: 
                    106:        /**
                    107:         * Associated Message-ID.
                    108:         */
                    109:        uint32_t message_id;
                    110: 
                    111:        /**
                    112:         * Length of the whole IKEv2-Message (header and all payloads).
                    113:         */
                    114:        uint32_t length;
                    115: };
                    116: 
                    117: ENUM_BEGIN(exchange_type_names, ID_PROT, TRANSACTION,
                    118:        "ID_PROT",
                    119:        "AUTH_ONLY",
                    120:        "AGGRESSIVE",
                    121:        "INFORMATIONAL_V1",
                    122:        "TRANSACTION");
                    123: ENUM_NEXT(exchange_type_names, QUICK_MODE, IKE_SESSION_RESUME, TRANSACTION,
                    124:        "QUICK_MODE",
                    125:        "NEW_GROUP_MODE",
                    126:        "IKE_SA_INIT",
                    127:        "IKE_AUTH",
                    128:        "CREATE_CHILD_SA",
                    129:        "INFORMATIONAL",
                    130:        "IKE_SESSION_RESUME");
                    131: #ifdef ME
                    132: ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, IKE_SESSION_RESUME,
                    133:        "ME_CONNECT");
                    134: ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED,
                    135:                                                           EXCHANGE_TYPE_UNDEFINED, ME_CONNECT,
                    136:        "EXCHANGE_TYPE_UNDEFINED");
                    137: #else
                    138: ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED,
                    139:                                                           EXCHANGE_TYPE_UNDEFINED, IKE_SESSION_RESUME,
                    140:        "EXCHANGE_TYPE_UNDEFINED");
                    141: #endif /* ME */
                    142: ENUM_END(exchange_type_names, EXCHANGE_TYPE_UNDEFINED);
                    143: 
                    144: /**
                    145:  * Encoding rules to parse or generate a IKE-Header.
                    146:  *
                    147:  * The defined offsets are the positions in a object of type
                    148:  * ike_header_t.
                    149:  */
                    150: static encoding_rule_t encodings[] = {
                    151:        /* 8 Byte SPI, stored in the field initiator_spi */
                    152:        { IKE_SPI,              offsetof(private_ike_header_t, initiator_spi)   },
                    153:        /* 8 Byte SPI, stored in the field responder_spi */
                    154:        { IKE_SPI,              offsetof(private_ike_header_t, responder_spi)   },
                    155:        /* 1 Byte next payload type, stored in the field next_payload */
                    156:        { U_INT_8,              offsetof(private_ike_header_t, next_payload)    },
                    157:        /* 4 Bit major version, stored in the field maj_version */
                    158:        { U_INT_4,              offsetof(private_ike_header_t, maj_version)             },
                    159:        /* 4 Bit minor version, stored in the field min_version */
                    160:        { U_INT_4,              offsetof(private_ike_header_t, min_version)             },
                    161:        /* 8 Bit for the exchange type */
                    162:        { U_INT_8,              offsetof(private_ike_header_t, exchange_type)   },
                    163:        /* 2 Bit reserved bits */
                    164:        { RESERVED_BIT, offsetof(private_ike_header_t, reserved[0])             },
                    165:        { RESERVED_BIT, offsetof(private_ike_header_t, reserved[1])             },
                    166:        /* 6 flags  */
                    167:        { FLAG,                 offsetof(private_ike_header_t, flags.response)  },
                    168:        { FLAG,                 offsetof(private_ike_header_t, flags.version)   },
                    169:        { FLAG,                 offsetof(private_ike_header_t, flags.initiator) },
                    170:        { FLAG,                 offsetof(private_ike_header_t, flags.authonly)  },
                    171:        { FLAG,                 offsetof(private_ike_header_t, flags.commit)    },
                    172:        { FLAG,                 offsetof(private_ike_header_t, flags.encryption)},
                    173:        /* 4 Byte message id, stored in the field message_id */
                    174:        { U_INT_32,             offsetof(private_ike_header_t, message_id)              },
                    175:        /* 4 Byte length field, stored in the field length */
                    176:        { HEADER_LENGTH,        offsetof(private_ike_header_t, length)                  }
                    177: };
                    178: 
                    179: /*                         1                   2                   3
                    180:        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
                    181:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    182:       !                       IKE_SA Initiator's SPI                  !
                    183:       !                                                               !
                    184:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    185:       !                       IKE_SA Responder's SPI                  !
                    186:       !                                                               !
                    187:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    188:       !  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !
                    189:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    190:       !                          Message ID                           !
                    191:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    192:       !                            Length                             !
                    193:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    194: */
                    195: 
                    196: METHOD(payload_t, verify, status_t,
                    197:        private_ike_header_t *this)
                    198: {
                    199:        switch (this->exchange_type)
                    200:        {
                    201:                case ID_PROT:
                    202:                case AGGRESSIVE:
                    203:                        if (this->message_id != 0)
                    204:                        {
                    205:                                return FAILED;
                    206:                        }
                    207:                        /* fall */
                    208:                case AUTH_ONLY:
                    209:                case INFORMATIONAL_V1:
                    210:                case TRANSACTION:
                    211:                case QUICK_MODE:
                    212:                case NEW_GROUP_MODE:
                    213:                        if (this->maj_version == IKEV2_MAJOR_VERSION)
                    214:                        {
                    215:                                /* IKEv1 exchange type in IKEv2? */
                    216:                                return FAILED;
                    217:                        }
                    218:                        break;
                    219:                case IKE_SA_INIT:
                    220:                case IKE_AUTH:
                    221:                case CREATE_CHILD_SA:
                    222:                case INFORMATIONAL:
                    223:                case IKE_SESSION_RESUME:
                    224: #ifdef ME
                    225:                case ME_CONNECT:
                    226: #endif /* ME */
                    227:                        if (this->maj_version == IKEV1_MAJOR_VERSION)
                    228:                        {
                    229:                                /* IKEv2 exchange type in IKEv1? */
                    230:                                return FAILED;
                    231:                        }
                    232:                        break;
                    233:                default:
                    234:                        if (this->maj_version == IKEV1_MAJOR_VERSION ||
                    235:                                this->maj_version == IKEV2_MAJOR_VERSION)
                    236:                        {
                    237:                                /* unsupported exchange type for known version */
                    238:                                return FAILED;
                    239:                        }
                    240:                        break;
                    241:        }
                    242:        if (this->initiator_spi == 0)
                    243:        {
                    244: #ifdef ME
                    245:                if (this->exchange_type != INFORMATIONAL)
                    246:                        /* we allow zero spi for INFORMATIONAL exchanges,
                    247:                         * to allow connectivity checks */
                    248: #endif /* ME */
                    249:                {
                    250:                        return FAILED;
                    251:                }
                    252:        }
                    253:        return SUCCESS;
                    254: }
                    255: 
                    256: METHOD(payload_t, get_encoding_rules, int,
                    257:        private_ike_header_t *this, encoding_rule_t **rules)
                    258: {
                    259:        *rules = encodings;
                    260:        return countof(encodings);
                    261: }
                    262: 
                    263: METHOD(payload_t, get_header_length, int,
                    264:        private_ike_header_t *this)
                    265: {
                    266:        return IKE_HEADER_LENGTH;
                    267: }
                    268: 
                    269: METHOD(payload_t, get_type, payload_type_t,
                    270:        private_ike_header_t *this)
                    271: {
                    272:        return PL_HEADER;
                    273: }
                    274: 
                    275: METHOD(payload_t, get_next_type, payload_type_t,
                    276:        private_ike_header_t *this)
                    277: {
                    278:        return this->next_payload;
                    279: }
                    280: 
                    281: METHOD(payload_t, set_next_type, void,
                    282:        private_ike_header_t *this, payload_type_t type)
                    283: {
                    284:        this->next_payload = type;
                    285: }
                    286: 
                    287: METHOD(payload_t, get_length, size_t,
                    288:        private_ike_header_t *this)
                    289: {
                    290:        return this->length;
                    291: }
                    292: 
                    293: METHOD(ike_header_t, get_initiator_spi, uint64_t,
                    294:        private_ike_header_t *this)
                    295: {
                    296:        return this->initiator_spi;
                    297: }
                    298: 
                    299: METHOD(ike_header_t, set_initiator_spi, void,
                    300:        private_ike_header_t *this, uint64_t initiator_spi)
                    301: {
                    302:        this->initiator_spi = initiator_spi;
                    303: }
                    304: 
                    305: METHOD(ike_header_t, get_responder_spi, uint64_t,
                    306:        private_ike_header_t *this)
                    307: {
                    308:        return this->responder_spi;
                    309: }
                    310: 
                    311: METHOD(ike_header_t, set_responder_spi, void,
                    312:        private_ike_header_t *this, uint64_t responder_spi)
                    313: {
                    314:        this->responder_spi = responder_spi;
                    315: }
                    316: 
                    317: METHOD(ike_header_t, get_maj_version, uint8_t,
                    318:        private_ike_header_t *this)
                    319: {
                    320:        return this->maj_version;
                    321: }
                    322: 
                    323: METHOD(ike_header_t, set_maj_version, void,
                    324:        private_ike_header_t *this, uint8_t major)
                    325: {
                    326:        this->maj_version = major;
                    327: }
                    328: 
                    329: METHOD(ike_header_t, get_min_version, uint8_t,
                    330:        private_ike_header_t *this)
                    331: {
                    332:        return this->min_version;
                    333: }
                    334: 
                    335: METHOD(ike_header_t, set_min_version, void,
                    336:        private_ike_header_t *this, uint8_t minor)
                    337: {
                    338:        this->min_version = minor;
                    339: }
                    340: 
                    341: METHOD(ike_header_t, get_response_flag, bool,
                    342:        private_ike_header_t *this)
                    343: {
                    344:        return this->flags.response;
                    345: }
                    346: 
                    347: METHOD(ike_header_t, set_response_flag, void,
                    348:        private_ike_header_t *this, bool response)
                    349: {
                    350:        this->flags.response = response;
                    351: }
                    352: 
                    353: METHOD(ike_header_t, get_version_flag, bool,
                    354:        private_ike_header_t *this)
                    355: {
                    356:        return this->flags.version;
                    357: }
                    358: 
                    359: METHOD(ike_header_t, set_version_flag, void,
                    360:        private_ike_header_t *this, bool version)
                    361: {
                    362:        this->flags.version = version;
                    363: }
                    364: 
                    365: METHOD(ike_header_t, get_initiator_flag, bool,
                    366:        private_ike_header_t *this)
                    367: {
                    368:        return this->flags.initiator;
                    369: }
                    370: 
                    371: METHOD(ike_header_t, set_initiator_flag, void,
                    372:        private_ike_header_t *this, bool initiator)
                    373: {
                    374:        this->flags.initiator = initiator;
                    375: }
                    376: 
                    377: METHOD(ike_header_t, get_encryption_flag, bool,
                    378:        private_ike_header_t *this)
                    379: {
                    380:        return this->flags.encryption;
                    381: }
                    382: 
                    383: METHOD(ike_header_t, set_encryption_flag, void,
                    384:        private_ike_header_t *this, bool encryption)
                    385: {
                    386:        this->flags.encryption = encryption;
                    387: }
                    388: 
                    389: 
                    390: METHOD(ike_header_t, get_commit_flag, bool,
                    391:        private_ike_header_t *this)
                    392: {
                    393:        return this->flags.commit;
                    394: }
                    395: 
                    396: METHOD(ike_header_t, set_commit_flag, void,
                    397:        private_ike_header_t *this, bool commit)
                    398: {
                    399:        this->flags.commit = commit;
                    400: }
                    401: 
                    402: METHOD(ike_header_t, get_authonly_flag, bool,
                    403:        private_ike_header_t *this)
                    404: {
                    405:        return this->flags.authonly;
                    406: }
                    407: 
                    408: METHOD(ike_header_t, set_authonly_flag, void,
                    409:        private_ike_header_t *this, bool authonly)
                    410: {
                    411:        this->flags.authonly = authonly;
                    412: }
                    413: 
                    414: METHOD(ike_header_t, get_exchange_type, uint8_t,
                    415:        private_ike_header_t *this)
                    416: {
                    417:        return this->exchange_type;
                    418: }
                    419: 
                    420: METHOD(ike_header_t, set_exchange_type, void,
                    421:        private_ike_header_t *this, uint8_t exchange_type)
                    422: {
                    423:        this->exchange_type = exchange_type;
                    424: }
                    425: 
                    426: METHOD(ike_header_t, get_message_id, uint32_t,
                    427:        private_ike_header_t *this)
                    428: {
                    429:        return this->message_id;
                    430: }
                    431: 
                    432: METHOD(ike_header_t, set_message_id, void,
                    433:        private_ike_header_t *this, uint32_t message_id)
                    434: {
                    435:        this->message_id = message_id;
                    436: }
                    437: 
                    438: METHOD2(payload_t, ike_header_t, destroy, void,
                    439:        private_ike_header_t *this)
                    440: {
                    441:        free(this);
                    442: }
                    443: 
                    444: /*
                    445:  * Described in header.
                    446:  */
                    447: ike_header_t *ike_header_create()
                    448: {
                    449:        private_ike_header_t *this;
                    450: 
                    451:        INIT(this,
                    452:                .public = {
                    453:                        .payload_interface = {
                    454:                                .verify = _verify,
                    455:                                .get_encoding_rules = _get_encoding_rules,
                    456:                                .get_header_length = _get_header_length,
                    457:                                .get_length = _get_length,
                    458:                                .get_next_type = _get_next_type,
                    459:                                .set_next_type = _set_next_type,
                    460:                                .get_type = _get_type,
                    461:                                .destroy = _destroy,
                    462:                        },
                    463:                        .get_initiator_spi = _get_initiator_spi,
                    464:                        .set_initiator_spi = _set_initiator_spi,
                    465:                        .get_responder_spi = _get_responder_spi,
                    466:                        .set_responder_spi = _set_responder_spi,
                    467:                        .get_maj_version = _get_maj_version,
                    468:                        .set_maj_version = _set_maj_version,
                    469:                        .get_min_version = _get_min_version,
                    470:                        .set_min_version = _set_min_version,
                    471:                        .get_response_flag = _get_response_flag,
                    472:                        .set_response_flag = _set_response_flag,
                    473:                        .get_version_flag = _get_version_flag,
                    474:                        .set_version_flag = _set_version_flag,
                    475:                        .get_initiator_flag = _get_initiator_flag,
                    476:                        .set_initiator_flag = _set_initiator_flag,
                    477:                        .get_encryption_flag = _get_encryption_flag,
                    478:                        .set_encryption_flag = _set_encryption_flag,
                    479:                        .get_commit_flag = _get_commit_flag,
                    480:                        .set_commit_flag = _set_commit_flag,
                    481:                        .get_authonly_flag = _get_authonly_flag,
                    482:                        .set_authonly_flag = _set_authonly_flag,
                    483:                        .get_exchange_type = _get_exchange_type,
                    484:                        .set_exchange_type = _set_exchange_type,
                    485:                        .get_message_id = _get_message_id,
                    486:                        .set_message_id = _set_message_id,
                    487:                        .destroy = _destroy,
                    488:                },
                    489:                .length = IKE_HEADER_LENGTH,
                    490:                .exchange_type = EXCHANGE_TYPE_UNDEFINED,
                    491:        );
                    492: 
                    493:        return &this->public;
                    494: }
                    495: 
                    496: /*
                    497:  * Described in header.
                    498:  */
                    499: ike_header_t *ike_header_create_version(int major, int minor)
                    500: {
                    501:        ike_header_t *this = ike_header_create();
                    502: 
                    503:        this->set_maj_version(this, major);
                    504:        this->set_min_version(this, minor);
                    505:        if (major == IKEV2_MAJOR_VERSION)
                    506:        {
                    507:                this->set_initiator_flag(this, TRUE);
                    508:        }
                    509:        return this;
                    510: }

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