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

1.1       misho       1: /*
                      2:  * Copyright (C) 2006-2018 Tobias Brunner
                      3:  * Copyright (C) 2005-2010 Martin Willi
                      4:  * Copyright (C) 2010 revosec AG
                      5:  * Copyright (C) 2006 Daniel Roethlisberger
                      6:  * Copyright (C) 2005 Jan Hutter
                      7:  * HSR Hochschule fuer Technik Rapperswil
                      8:  *
                      9:  * This program is free software; you can redistribute it and/or modify it
                     10:  * under the terms of the GNU General Public License as published by the
                     11:  * Free Software Foundation; either version 2 of the License, or (at your
                     12:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     13:  *
                     14:  * This program is distributed in the hope that it will be useful, but
                     15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     16:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     17:  * for more details.
                     18:  */
                     19: 
                     20: #include <stddef.h>
                     21: 
                     22: #include "notify_payload.h"
                     23: 
                     24: #include <daemon.h>
                     25: #include <encoding/payloads/encodings.h>
                     26: #include <crypto/hashers/hasher.h>
                     27: 
                     28: ENUM_BEGIN(notify_type_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
                     29:        "UNSUPPORTED_CRITICAL_PAYLOAD");
                     30: ENUM_NEXT(notify_type_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
                     31:        "INVALID_IKE_SPI",
                     32:        "INVALID_MAJOR_VERSION");
                     33: ENUM_NEXT(notify_type_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
                     34:        "INVALID_SYNTAX");
                     35: ENUM_NEXT(notify_type_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
                     36:        "INVALID_MESSAGE_ID");
                     37: ENUM_NEXT(notify_type_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
                     38:        "INVALID_SPI");
                     39: ENUM_NEXT(notify_type_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
                     40:        "ATTRIBUTES_NOT_SUPPORTED",
                     41:        "NO_PROPOSAL_CHOSEN");
                     42: ENUM_NEXT(notify_type_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
                     43:        "PAYLOAD_MALFORMED",
                     44:        "INVALID_KE_PAYLOAD",
                     45:        "INVALID_ID_INFORMATION",
                     46:        "INVALID_CERT_ENCODING",
                     47:        "INVALID_CERTIFICATE",
                     48:        "CERT_TYPE_UNSUPPORTED",
                     49:        "INVALID_CERT_AUTHORITY",
                     50:        "INVALID_HASH_INFORMATION",
                     51:        "AUTHENTICATION_FAILED");
                     52: ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
                     53:        "SINGLE_PAIR_REQUIRED",
                     54:        "NO_ADDITIONAL_SAS",
                     55:        "INTERNAL_ADDRESS_FAILURE",
                     56:        "FAILED_CP_REQUIRED",
                     57:        "TS_UNACCEPTABLE",
                     58:        "INVALID_SELECTORS",
                     59:        "UNACCEPTABLE_ADDRESSES",
                     60:        "UNEXPECTED_NAT_DETECTED",
                     61:        "USE_ASSIGNED_HoA",
                     62:        "TEMPORARY_FAILURE",
                     63:        "CHILD_SA_NOT_FOUND");
                     64: ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
                     65:        "ME_CONNECT_FAILED");
                     66: ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
                     67:        "MS_NOTIFY_STATUS");
                     68: ENUM_NEXT(notify_type_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
                     69:        "INITIAL_CONTACT",
                     70:        "SET_WINDOW_SIZE",
                     71:        "ADDITIONAL_TS_POSSIBLE",
                     72:        "IPCOMP_SUPPORTED",
                     73:        "NAT_DETECTION_SOURCE_IP",
                     74:        "NAT_DETECTION_DESTINATION_IP",
                     75:        "COOKIE",
                     76:        "USE_TRANSPORT_MODE",
                     77:        "HTTP_CERT_LOOKUP_SUPPORTED",
                     78:        "REKEY_SA",
                     79:        "ESP_TFC_PADDING_NOT_SUPPORTED",
                     80:        "NON_FIRST_FRAGMENTS_ALSO",
                     81:        "MOBIKE_SUPPORTED",
                     82:        "ADDITIONAL_IP4_ADDRESS",
                     83:        "ADDITIONAL_IP6_ADDRESS",
                     84:        "NO_ADDITIONAL_ADDRESSES",
                     85:        "UPDATE_SA_ADDRESSES",
                     86:        "COOKIE2",
                     87:        "NO_NATS_ALLOWED",
                     88:        "AUTH_LIFETIME",
                     89:        "MULTIPLE_AUTH_SUPPORTED",
                     90:        "ANOTHER_AUTH_FOLLOWS",
                     91:        "REDIRECT_SUPPORTED",
                     92:        "REDIRECT",
                     93:        "REDIRECTED_FROM",
                     94:        "TICKET_LT_OPAQUE",
                     95:        "TICKET_REQUEST",
                     96:        "TICKET_ACK",
                     97:        "TICKET_NACK",
                     98:        "TICKET_OPAQUE",
                     99:        "LINK_ID",
                    100:        "USE_WESP_MODE",
                    101:        "ROHC_SUPPORTED",
                    102:        "EAP_ONLY_AUTHENTICATION",
                    103:        "CHILDLESS_IKEV2_SUPPORTED",
                    104:        "QUICK_CRASH_DETECTION",
                    105:        "IKEV2_MESSAGE_ID_SYNC_SUPPORTED",
                    106:        "IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED",
                    107:        "IKEV2_MESSAGE_ID_SYNC",
                    108:        "IPSEC_REPLAY_COUNTER_SYNC",
                    109:        "SECURE PASSWORD_METHOD",
                    110:        "PSK_PERSIST",
                    111:        "PSK_CONFIRM",
                    112:        "ERX_SUPPORTED",
                    113:        "IFOM_CAPABILITY",
                    114:        "SENDER_REQUEST_ID",
                    115:        "FRAGMENTATION_SUPPORTED",
                    116:        "SIGNATURE_HASH_ALGORITHMS");
                    117: ENUM_NEXT(notify_type_names, USE_PPK, NO_PPK_AUTH, SIGNATURE_HASH_ALGORITHMS,
                    118:        "USE_PPK",
                    119:        "PPK_IDENTITY",
                    120:        "NO_PPK_AUTH");
                    121: ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, NO_PPK_AUTH,
                    122:        "INITIAL_CONTACT");
                    123: ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
                    124:        "DPD_R_U_THERE",
                    125:        "DPD_R_U_THERE_ACK");
                    126: ENUM_NEXT(notify_type_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
                    127:        "UNITY_LOAD_BALANCE");
                    128: ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
                    129:        "USE_BEET_MODE");
                    130: ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
                    131:        "ME_MEDIATION",
                    132:        "ME_ENDPOINT",
                    133:        "ME_CALLBACK",
                    134:        "ME_CONNECTID",
                    135:        "ME_CONNECTKEY",
                    136:        "ME_CONNECTAUTH",
                    137:        "ME_RESPONSE",
                    138:        "RADIUS_ATTRIBUTE");
                    139: ENUM_END(notify_type_names, RADIUS_ATTRIBUTE);
                    140: 
                    141: 
                    142: ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
                    143:        "CRIT");
                    144: ENUM_NEXT(notify_type_short_names, INVALID_IKE_SPI, INVALID_MAJOR_VERSION, UNSUPPORTED_CRITICAL_PAYLOAD,
                    145:        "INVAL_IKE_SPI",
                    146:        "INVAL_MAJOR");
                    147: ENUM_NEXT(notify_type_short_names, INVALID_SYNTAX, INVALID_SYNTAX, INVALID_MAJOR_VERSION,
                    148:        "INVAL_SYN");
                    149: ENUM_NEXT(notify_type_short_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYNTAX,
                    150:        "INVAL_MID");
                    151: ENUM_NEXT(notify_type_short_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
                    152:        "INVAL_SPI");
                    153: ENUM_NEXT(notify_type_short_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
                    154:        "ATTR_UNSUP",
                    155:        "NO_PROP");
                    156: ENUM_NEXT(notify_type_short_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
                    157:        "PLD_MAL",
                    158:        "INVAL_KE",
                    159:        "INVAL_ID",
                    160:        "INVAL_CERTEN",
                    161:        "INVAL_CERT",
                    162:        "CERT_UNSUP",
                    163:        "INVAL_CA",
                    164:        "INVAL_HASH",
                    165:        "AUTH_FAILED");
                    166: ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
                    167:        "SINGLE_PAIR",
                    168:        "NO_ADD_SAS",
                    169:        "INT_ADDR_FAIL",
                    170:        "FAIL_CP_REQ",
                    171:        "TS_UNACCEPT",
                    172:        "INVAL_SEL",
                    173:        "UNACCEPT_ADDR",
                    174:        "UNEXPECT_NAT",
                    175:        "ASSIGNED_HoA",
                    176:        "TEMP_FAIL",
                    177:        "NO_CHILD_SA");
                    178: ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_FOUND,
                    179:        "ME_CONN_FAIL");
                    180: ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED,
                    181:        "MS_STATUS");
                    182: ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS,
                    183:        "INIT_CONTACT",
                    184:        "SET_WINSIZE",
                    185:        "ADD_TS_POSS",
                    186:        "IPCOMP_SUP",
                    187:        "NATD_S_IP",
                    188:        "NATD_D_IP",
                    189:        "COOKIE",
                    190:        "USE_TRANSP",
                    191:        "HTTP_CERT_LOOK",
                    192:        "REKEY_SA",
                    193:        "ESP_TFC_PAD_N",
                    194:        "NON_FIRST_FRAG",
                    195:        "MOBIKE_SUP",
                    196:        "ADD_4_ADDR",
                    197:        "ADD_6_ADDR",
                    198:        "NO_ADD_ADDR",
                    199:        "UPD_SA_ADDR",
                    200:        "COOKIE2",
                    201:        "NO_NATS",
                    202:        "AUTH_LFT",
                    203:        "MULT_AUTH",
                    204:        "AUTH_FOLLOWS",
                    205:        "REDIR_SUP",
                    206:        "REDIR",
                    207:        "REDIR_FROM",
                    208:        "TKT_LT_OPAK",
                    209:        "TKT_REQ",
                    210:        "TKT_ACK",
                    211:        "TKT_NACK",
                    212:        "TKT_OPAK",
                    213:        "LINK_ID",
                    214:        "WESP_MODE",
                    215:        "ROHC_SUP",
                    216:        "EAP_ONLY",
                    217:        "CHDLESS_SUP",
                    218:        "CRASH_DET",
                    219:        "MSG_ID_SYN_SUP",
                    220:        "RPL_CTR_SYN_SUP",
                    221:        "MSG_ID_SYN",
                    222:        "RPL_CTR_SYN",
                    223:        "SEC_PASSWD",
                    224:        "PSK_PST",
                    225:        "PSK_CFM",
                    226:        "ERX_SUP",
                    227:        "IFOM_CAP",
                    228:        "SENDER_REQ_ID",
                    229:        "FRAG_SUP",
                    230:        "HASH_ALG");
                    231: ENUM_NEXT(notify_type_short_names, USE_PPK, NO_PPK_AUTH, SIGNATURE_HASH_ALGORITHMS,
                    232:        "USE_PPK",
                    233:        "PPK_ID",
                    234:        "NO_PPK");
                    235: ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, NO_PPK_AUTH,
                    236:        "INITIAL_CONTACT");
                    237: ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
                    238:        "DPD",
                    239:        "DPD_ACK");
                    240: ENUM_NEXT(notify_type_short_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
                    241:        "UNITY_LB");
                    242: ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
                    243:        "BEET_MODE");
                    244: ENUM_NEXT(notify_type_short_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
                    245:        "ME_MED",
                    246:        "ME_EP",
                    247:        "ME_CB",
                    248:        "ME_CID",
                    249:        "ME_CKEY",
                    250:        "ME_CAUTH",
                    251:        "ME_R",
                    252:        "RADIUS");
                    253: ENUM_END(notify_type_short_names, RADIUS_ATTRIBUTE);
                    254: 
                    255: 
                    256: typedef struct private_notify_payload_t private_notify_payload_t;
                    257: 
                    258: /**
                    259:  * Private data of an notify_payload_t object.
                    260:  */
                    261: struct private_notify_payload_t {
                    262: 
                    263:        /**
                    264:         * Public notify_payload_t interface.
                    265:         */
                    266:        notify_payload_t public;
                    267: 
                    268:        /**
                    269:         * Next payload type.
                    270:         */
                    271:        uint8_t  next_payload;
                    272: 
                    273:        /**
                    274:         * Critical flag.
                    275:         */
                    276:        bool critical;
                    277: 
                    278:        /**
                    279:         * reserved bits
                    280:         */
                    281:        bool reserved[8];
                    282: 
                    283:        /**
                    284:         * Length of this payload.
                    285:         */
                    286:        uint16_t payload_length;
                    287: 
                    288:        /**
                    289:         * Domain of interpretation, IKEv1 only.
                    290:         */
                    291:        uint32_t doi;
                    292: 
                    293:        /**
                    294:         * Protocol id.
                    295:         */
                    296:        uint8_t protocol_id;
                    297: 
                    298:        /**
                    299:         * Spi size.
                    300:         */
                    301:        uint8_t spi_size;
                    302: 
                    303:        /**
                    304:         * Notify message type.
                    305:         */
                    306:        uint16_t notify_type;
                    307: 
                    308:        /**
                    309:         * Security parameter index (spi).
                    310:         */
                    311:        chunk_t spi;
                    312: 
                    313:        /**
                    314:         * Notification data.
                    315:         */
                    316:        chunk_t notify_data;
                    317: 
                    318:        /**
                    319:         * Type of payload, PLV2_NOTIFY or PLV1_NOTIFY
                    320:         */
                    321:        payload_type_t type;
                    322: };
                    323: 
                    324: /**
                    325:  * Encoding rules for an IKEv2 notification payload
                    326:  */
                    327: static encoding_rule_t encodings_v2[] = {
                    328:        /* 1 Byte next payload type, stored in the field next_payload */
                    329:        { U_INT_8,                      offsetof(private_notify_payload_t, next_payload)        },
                    330:        /* the critical bit */
                    331:        { FLAG,                         offsetof(private_notify_payload_t, critical)            },
                    332:        /* 7 Bit reserved bits, nowhere stored */
                    333:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[0])         },
                    334:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[1])         },
                    335:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[2])         },
                    336:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[3])         },
                    337:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[4])         },
                    338:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[5])         },
                    339:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[6])         },
                    340:        /* Length of the whole payload*/
                    341:        { PAYLOAD_LENGTH,       offsetof(private_notify_payload_t, payload_length)      },
                    342:        /* Protocol ID as 8 bit field*/
                    343:        { U_INT_8,                      offsetof(private_notify_payload_t, protocol_id)         },
                    344:        /* SPI Size as 8 bit field*/
                    345:        { SPI_SIZE,                     offsetof(private_notify_payload_t, spi_size)            },
                    346:        /* Notify message type as 16 bit field*/
                    347:        { U_INT_16,                     offsetof(private_notify_payload_t, notify_type)         },
                    348:        /* SPI as variable length field*/
                    349:        { SPI,                          offsetof(private_notify_payload_t, spi)                         },
                    350:        /* Key Exchange Data is from variable size */
                    351:        { CHUNK_DATA,           offsetof(private_notify_payload_t, notify_data)         },
                    352: };
                    353: 
                    354: /*
                    355:                            1                   2                   3
                    356:        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
                    357:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    358:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
                    359:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    360:       !  Protocol ID  !   SPI Size    !      Notify Message Type      !
                    361:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    362:       !                                                               !
                    363:       ~                Security Parameter Index (SPI)                 ~
                    364:       !                                                               !
                    365:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    366:       !                                                               !
                    367:       ~                       Notification Data                       ~
                    368:       !                                                               !
                    369:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    370: */
                    371: /**
                    372:  * Encoding rules for an IKEv1 notification payload
                    373:  */
                    374: static encoding_rule_t encodings_v1[] = {
                    375:        /* 1 Byte next payload type, stored in the field next_payload */
                    376:        { U_INT_8,                      offsetof(private_notify_payload_t, next_payload)        },
                    377:        /* 8 reserved bits */
                    378:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[0])         },
                    379:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[1])         },
                    380:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[2])         },
                    381:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[3])         },
                    382:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[4])         },
                    383:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[5])         },
                    384:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[6])         },
                    385:        { RESERVED_BIT,         offsetof(private_notify_payload_t, reserved[7])         },
                    386:        /* Length of the whole payload*/
                    387:        { PAYLOAD_LENGTH,       offsetof(private_notify_payload_t, payload_length)      },
                    388:        /* DOI as  32 bit field*/
                    389:        { U_INT_32,                     offsetof(private_notify_payload_t, doi)                         },
                    390:        /* Protocol ID as 8 bit field*/
                    391:        { U_INT_8,                      offsetof(private_notify_payload_t, protocol_id)         },
                    392:        /* SPI Size as 8 bit field*/
                    393:        { SPI_SIZE,                     offsetof(private_notify_payload_t, spi_size)            },
                    394:        /* Notify message type as 16 bit field*/
                    395:        { U_INT_16,                     offsetof(private_notify_payload_t, notify_type)         },
                    396:        /* SPI as variable length field*/
                    397:        { SPI,                          offsetof(private_notify_payload_t, spi)                         },
                    398:        /* Key Exchange Data is from variable size */
                    399:        { CHUNK_DATA,           offsetof(private_notify_payload_t, notify_data)         },
                    400: };
                    401: 
                    402: /*
                    403:                            1                   2                   3
                    404:        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
                    405:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    406:       ! Next Payload  !    RESERVED   !         Payload Length        !
                    407:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    408:       !                             DOI                               !
                    409:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    410:       !  Protocol ID  !   SPI Size    !      Notify Message Type      !
                    411:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    412:       !                                                               !
                    413:       ~                Security Parameter Index (SPI)                 ~
                    414:       !                                                               !
                    415:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    416:       !                                                               !
                    417:       ~                       Notification Data                       ~
                    418:       !                                                               !
                    419:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    420: */
                    421: 
                    422: 
                    423: METHOD(payload_t, verify, status_t,
                    424:        private_notify_payload_t *this)
                    425: {
                    426:        bool bad_length = FALSE;
                    427: 
                    428:        switch (this->protocol_id)
                    429:        {
                    430:                case PROTO_NONE:
                    431:                case PROTO_IKE:
                    432:                case PROTO_AH:
                    433:                case PROTO_ESP:
                    434:                        break;
                    435:                default:
                    436:                        DBG1(DBG_ENC, "Unknown protocol (%d)", this->protocol_id);
                    437:                        return FAILED;
                    438:        }
                    439: 
                    440:        switch (this->notify_type)
                    441:        {
                    442:                case INVALID_KE_PAYLOAD:
                    443:                {
                    444:                        if (this->type == PLV2_NOTIFY && this->notify_data.len != 2)
                    445:                        {
                    446:                                bad_length = TRUE;
                    447:                        }
                    448:                        break;
                    449:                }
                    450:                case NAT_DETECTION_SOURCE_IP:
                    451:                case NAT_DETECTION_DESTINATION_IP:
                    452:                case ME_CONNECTAUTH:
                    453:                {
                    454:                        if (this->notify_data.len != HASH_SIZE_SHA1)
                    455:                        {
                    456:                                bad_length = TRUE;
                    457:                        }
                    458:                        break;
                    459:                }
                    460:                case INVALID_SYNTAX:
                    461:                case INVALID_MAJOR_VERSION:
                    462:                case NO_PROPOSAL_CHOSEN:
                    463:                {
                    464:                        if (this->type == PLV2_NOTIFY && this->notify_data.len != 0)
                    465:                        {
                    466:                                bad_length = TRUE;
                    467:                        }
                    468:                        break;
                    469:                }
                    470:                case COOKIE:
                    471:                {
                    472:                        if (this->notify_data.len < 1 || this->notify_data.len > 64)
                    473:                        {
                    474:                                bad_length = TRUE;
                    475:                        }
                    476:                        break;
                    477:                }
                    478:                case ADDITIONAL_IP4_ADDRESS:
                    479:                {
                    480:                        if (this->notify_data.len != 4)
                    481:                        {
                    482:                                bad_length = TRUE;
                    483:                        }
                    484:                        break;
                    485:                }
                    486:                case ADDITIONAL_IP6_ADDRESS:
                    487:                {
                    488:                        if (this->notify_data.len != 16)
                    489:                        {
                    490:                                bad_length = TRUE;
                    491:                        }
                    492:                        break;
                    493:                }
                    494:                case SIGNATURE_HASH_ALGORITHMS:
                    495:                {
                    496:                        if (this->notify_data.len % 2)
                    497:                        {
                    498:                                bad_length = TRUE;
                    499:                        }
                    500:                        break;
                    501:                }
                    502:                case AUTH_LIFETIME:
                    503:                {
                    504:                        if (this->notify_data.len != 4)
                    505:                        {
                    506:                                bad_length = TRUE;
                    507:                        }
                    508:                        break;
                    509:                }
                    510:                case IPCOMP_SUPPORTED:
                    511:                {
                    512:                        if (this->notify_data.len != 3)
                    513:                        {
                    514:                                bad_length = TRUE;
                    515:                        }
                    516:                        break;
                    517:                }
                    518:                case ME_ENDPOINT:
                    519:                        if (this->notify_data.len != 8 &&
                    520:                                this->notify_data.len != 12 &&
                    521:                                this->notify_data.len != 24)
                    522:                        {
                    523:                                bad_length = TRUE;
                    524:                        }
                    525:                        break;
                    526:                case ME_CONNECTID:
                    527:                        if (this->notify_data.len < 4 ||
                    528:                                this->notify_data.len > 16)
                    529:                        {
                    530:                                bad_length = TRUE;
                    531:                        }
                    532:                        break;
                    533:                case ME_CONNECTKEY:
                    534:                        if (this->notify_data.len < 16 ||
                    535:                                this->notify_data.len > 32)
                    536:                        {
                    537:                                bad_length = TRUE;
                    538:                        }
                    539:                        break;
                    540:                case DPD_R_U_THERE:
                    541:                case DPD_R_U_THERE_ACK:
                    542:                        if (this->notify_data.len != 4)
                    543:                        {
                    544:                                bad_length = TRUE;
                    545:                        }
                    546:                        break;
                    547:                default:
                    548:                        /* TODO: verify */
                    549:                        break;
                    550:        }
                    551:        if (bad_length)
                    552:        {
                    553:                DBG1(DBG_ENC, "invalid notify data length for %N (%d)",
                    554:                         notify_type_names, this->notify_type,
                    555:                         this->notify_data.len);
                    556:                return FAILED;
                    557:        }
                    558:        return SUCCESS;
                    559: }
                    560: 
                    561: METHOD(payload_t, get_encoding_rules, int,
                    562:        private_notify_payload_t *this, encoding_rule_t **rules)
                    563: {
                    564:        if (this->type == PLV2_NOTIFY)
                    565:        {
                    566:                *rules = encodings_v2;
                    567:                return countof(encodings_v2);
                    568:        }
                    569:        *rules = encodings_v1;
                    570:        return countof(encodings_v1);
                    571: }
                    572: 
                    573: METHOD(payload_t, get_header_length, int,
                    574:        private_notify_payload_t *this)
                    575: {
                    576:        if (this->type == PLV2_NOTIFY)
                    577:        {
                    578:                return 8 + this->spi_size;
                    579:        }
                    580:        return 12 + this->spi_size;
                    581: }
                    582: 
                    583: METHOD(payload_t, get_type, payload_type_t,
                    584:        private_notify_payload_t *this)
                    585: {
                    586:        return this->type;
                    587: }
                    588: 
                    589: METHOD(payload_t, get_next_type, payload_type_t,
                    590:        private_notify_payload_t *this)
                    591: {
                    592:        return this->next_payload;
                    593: }
                    594: 
                    595: METHOD(payload_t, set_next_type, void,
                    596:        private_notify_payload_t *this, payload_type_t type)
                    597: {
                    598:        this->next_payload = type;
                    599: }
                    600: 
                    601: /**
                    602:  * recompute the payloads length.
                    603:  */
                    604: static void compute_length(private_notify_payload_t *this)
                    605: {
                    606:        this->payload_length = get_header_length(this) + this->notify_data.len;
                    607: }
                    608: 
                    609: METHOD(payload_t, get_length, size_t,
                    610:        private_notify_payload_t *this)
                    611: {
                    612:        return this->payload_length;
                    613: }
                    614: 
                    615: METHOD(notify_payload_t, get_protocol_id, uint8_t,
                    616:        private_notify_payload_t *this)
                    617: {
                    618:        return this->protocol_id;
                    619: }
                    620: 
                    621: METHOD(notify_payload_t, set_protocol_id, void,
                    622:        private_notify_payload_t *this, uint8_t protocol_id)
                    623: {
                    624:        this->protocol_id = protocol_id;
                    625: }
                    626: 
                    627: METHOD(notify_payload_t, get_notify_type, notify_type_t,
                    628:        private_notify_payload_t *this)
                    629: {
                    630:        return this->notify_type;
                    631: }
                    632: 
                    633: METHOD(notify_payload_t, set_notify_type, void,
                    634:        private_notify_payload_t *this, notify_type_t notify_type)
                    635: {
                    636:        this->notify_type = notify_type;
                    637: }
                    638: 
                    639: METHOD(notify_payload_t, get_spi, uint32_t,
                    640:        private_notify_payload_t *this)
                    641: {
                    642:        switch (this->protocol_id)
                    643:        {
                    644:                case PROTO_AH:
                    645:                case PROTO_ESP:
                    646:                        if (this->spi.len == 4)
                    647:                        {
                    648:                                return *((uint32_t*)this->spi.ptr);
                    649:                        }
                    650:                default:
                    651:                        break;
                    652:        }
                    653:        return 0;
                    654: }
                    655: 
                    656: METHOD(notify_payload_t, set_spi, void,
                    657:        private_notify_payload_t *this, uint32_t spi)
                    658: {
                    659:        chunk_free(&this->spi);
                    660:        switch (this->protocol_id)
                    661:        {
                    662:                case PROTO_AH:
                    663:                case PROTO_ESP:
                    664:                        this->spi = chunk_alloc(4);
                    665:                        *((uint32_t*)this->spi.ptr) = spi;
                    666:                        break;
                    667:                default:
                    668:                        break;
                    669:        }
                    670:        this->spi_size = this->spi.len;
                    671:        compute_length(this);
                    672: }
                    673: 
                    674: METHOD(notify_payload_t, get_spi_data, chunk_t,
                    675:        private_notify_payload_t *this)
                    676: {
                    677:        switch (this->protocol_id)
                    678:        {
                    679:                case PROTO_IKE:
                    680:                        if (this->spi.len == 16)
                    681:                        {
                    682:                                return this->spi;
                    683:                        }
                    684:                default:
                    685:                        break;
                    686:        }
                    687:        return chunk_empty;
                    688: }
                    689: 
                    690: METHOD(notify_payload_t, set_spi_data, void,
                    691:        private_notify_payload_t *this, chunk_t spi)
                    692: {
                    693:        chunk_free(&this->spi);
                    694:        switch (this->protocol_id)
                    695:        {
                    696:                case PROTO_IKE:
                    697:                        this->spi = chunk_clone(spi);
                    698:                default:
                    699:                        break;
                    700:        }
                    701:        this->spi_size = this->spi.len;
                    702:        compute_length(this);
                    703: }
                    704: 
                    705: METHOD(notify_payload_t, get_notification_data, chunk_t,
                    706:        private_notify_payload_t *this)
                    707: {
                    708:        return this->notify_data;
                    709: }
                    710: 
                    711: METHOD(notify_payload_t, set_notification_data, void,
                    712:        private_notify_payload_t *this, chunk_t data)
                    713: {
                    714:        free(this->notify_data.ptr);
                    715:        this->notify_data = chunk_clone(data);
                    716:        compute_length(this);
                    717: }
                    718: 
                    719: METHOD2(payload_t, notify_payload_t, destroy, void,
                    720:        private_notify_payload_t *this)
                    721: {
                    722:        free(this->notify_data.ptr);
                    723:        free(this->spi.ptr);
                    724:        free(this);
                    725: }
                    726: 
                    727: /*
                    728:  * Described in header
                    729:  */
                    730: notify_payload_t *notify_payload_create(payload_type_t type)
                    731: {
                    732:        private_notify_payload_t *this;
                    733: 
                    734:        INIT(this,
                    735:                .public = {
                    736:                        .payload_interface = {
                    737:                                .verify = _verify,
                    738:                                .get_encoding_rules = _get_encoding_rules,
                    739:                                .get_header_length = _get_header_length,
                    740:                                .get_length = _get_length,
                    741:                                .get_next_type = _get_next_type,
                    742:                                .set_next_type = _set_next_type,
                    743:                                .get_type = _get_type,
                    744:                                .destroy = _destroy,
                    745:                        },
                    746:                        .get_protocol_id = _get_protocol_id,
                    747:                        .set_protocol_id  = _set_protocol_id,
                    748:                        .get_notify_type = _get_notify_type,
                    749:                        .set_notify_type = _set_notify_type,
                    750:                        .get_spi = _get_spi,
                    751:                        .set_spi = _set_spi,
                    752:                        .get_spi_data = _get_spi_data,
                    753:                        .set_spi_data = _set_spi_data,
                    754:                        .get_notification_data = _get_notification_data,
                    755:                        .set_notification_data = _set_notification_data,
                    756:                        .destroy = _destroy,
                    757:                },
                    758:                .doi = IKEV1_DOI_IPSEC,
                    759:                .next_payload = PL_NONE,
                    760:                .type = type,
                    761:        );
                    762:        compute_length(this);
                    763:        return &this->public;
                    764: }
                    765: 
                    766: /*
                    767:  * Described in header.
                    768:  */
                    769: notify_payload_t *notify_payload_create_from_protocol_and_type(
                    770:                        payload_type_t type, protocol_id_t protocol, notify_type_t notify)
                    771: {
                    772:        notify_payload_t *this = notify_payload_create(type);
                    773: 
                    774:        this->set_notify_type(this, notify);
                    775:        this->set_protocol_id(this, protocol);
                    776: 
                    777:        return this;
                    778: }

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