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

1.1       misho       1: /*
                      2:  * Copyright (C) 2005-2010 Martin Willi
                      3:  * Copyright (C) 2010 revosec AG
                      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: #include <stddef.h>
                     19: 
                     20: #include "configuration_attribute.h"
                     21: 
                     22: #include <encoding/payloads/encodings.h>
                     23: #include <library.h>
                     24: #include <daemon.h>
                     25: 
                     26: typedef struct private_configuration_attribute_t private_configuration_attribute_t;
                     27: 
                     28: /**
                     29:  * Private data of an configuration_attribute_t object.
                     30:  */
                     31: struct private_configuration_attribute_t {
                     32: 
                     33:        /**
                     34:         * Public configuration_attribute_t interface.
                     35:         */
                     36:        configuration_attribute_t public;
                     37: 
                     38:        /**
                     39:         * Value encoded in length field?
                     40:         */
                     41:        bool af_flag;
                     42: 
                     43:        /**
                     44:         * Reserved bit (af_flag in IKEv2)
                     45:         */
                     46:        bool reserved;
                     47: 
                     48:        /**
                     49:         * Type of the attribute.
                     50:         */
                     51:        uint16_t attr_type;
                     52: 
                     53:        /**
                     54:         * Length of the attribute, value if af_flag set.
                     55:         */
                     56:        uint16_t length_or_value;
                     57: 
                     58:        /**
                     59:         * Attribute value as chunk.
                     60:         */
                     61:        chunk_t value;
                     62: 
                     63:        /**
                     64:         * Payload type, PLV2_CONFIGURATION_ATTRIBUTE or DATA_ATTRIBUTE_V1
                     65:         */
                     66:        payload_type_t type;
                     67: };
                     68: 
                     69: /**
                     70:  * Encoding rules for a IKEv2 configuration attribute / IKEv1 data attribute
                     71:  */
                     72: static encoding_rule_t encodings_v2[] = {
                     73:        /* 1 reserved bit */
                     74:        { RESERVED_BIT,                                 offsetof(private_configuration_attribute_t, reserved)           },
                     75:        /* type of the attribute as 15 bit unsigned integer */
                     76:        { ATTRIBUTE_TYPE,                               offsetof(private_configuration_attribute_t, attr_type)          },
                     77:        /* Length of attribute value */
                     78:        { ATTRIBUTE_LENGTH,                             offsetof(private_configuration_attribute_t, length_or_value)},
                     79:        /* Value of attribute if attribute format flag is zero */
                     80:        { ATTRIBUTE_VALUE,                              offsetof(private_configuration_attribute_t, value)                      },
                     81: };
                     82: 
                     83: /*
                     84:                            1                   2                   3
                     85:        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
                     86:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     87:       !R|         Attribute Type      !            Length             |
                     88:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     89:       |                                                               |
                     90:       ~                             Value                             ~
                     91:       |                                                               |
                     92:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     93: */
                     94: 
                     95: /**
                     96:  * Encoding rules for a IKEv1 data attribute
                     97:  */
                     98: static encoding_rule_t encodings_v1[] = {
                     99:        /* AF Flag */
                    100:        { ATTRIBUTE_FORMAT,                             offsetof(private_configuration_attribute_t, af_flag)            },
                    101:        /* type of the attribute as 15 bit unsigned integer */
                    102:        { ATTRIBUTE_TYPE,                               offsetof(private_configuration_attribute_t, attr_type)          },
                    103:        /* Length of attribute value */
                    104:        { ATTRIBUTE_LENGTH_OR_VALUE,    offsetof(private_configuration_attribute_t, length_or_value)},
                    105:        /* Value of attribute if attribute format flag is zero */
                    106:        { ATTRIBUTE_VALUE,                              offsetof(private_configuration_attribute_t, value)                      },
                    107: };
                    108: 
                    109: /*
                    110:                            1                   2                   3
                    111:        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
                    112:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    113:       !F|         Attribute Type      !            Length             |
                    114:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    115:       |                                                               |
                    116:       ~                             Value                             ~
                    117:       |                                                               |
                    118:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    119: */
                    120: 
                    121: 
                    122: METHOD(payload_t, verify, status_t,
                    123:        private_configuration_attribute_t *this)
                    124: {
                    125:        bool failed = FALSE;
                    126: 
                    127:        switch (this->attr_type)
                    128:        {
                    129:                case INTERNAL_IP4_ADDRESS:
                    130:                case INTERNAL_IP4_NETMASK:
                    131:                case INTERNAL_IP4_DNS:
                    132:                case INTERNAL_IP4_NBNS:
                    133:                case INTERNAL_ADDRESS_EXPIRY:
                    134:                case INTERNAL_IP4_DHCP:
                    135:                case P_CSCF_IP4_ADDRESS:
                    136:                        if (this->length_or_value != 0 && this->length_or_value != 4)
                    137:                        {
                    138:                                failed = TRUE;
                    139:                        }
                    140:                        break;
                    141:                case INTERNAL_IP4_SUBNET:
                    142:                        if (this->length_or_value != 0 && this->length_or_value != 8)
                    143:                        {
                    144:                                failed = TRUE;
                    145:                        }
                    146:                        break;
                    147:                case INTERNAL_IP6_ADDRESS:
                    148:                        if (this->type == PLV1_CONFIGURATION_ATTRIBUTE &&
                    149:                                this->length_or_value == 16)
                    150:                        {       /* 16 bytes are correct for IKEv1, but older releases sent a
                    151:                                 * prefix byte so we still accept 0 or 17 as in IKEv2 */
                    152:                                break;
                    153:                        }
                    154:                        /* fall-through */
                    155:                case INTERNAL_IP6_SUBNET:
                    156:                        if (this->length_or_value != 0 && this->length_or_value != 17)
                    157:                        {
                    158:                                failed = TRUE;
                    159:                        }
                    160:                        break;
                    161:                case INTERNAL_IP6_DNS:
                    162:                case INTERNAL_IP6_NBNS:
                    163:                case INTERNAL_IP6_DHCP:
                    164:                case P_CSCF_IP6_ADDRESS:
                    165:                        if (this->length_or_value != 0 && this->length_or_value != 16)
                    166:                        {
                    167:                                failed = TRUE;
                    168:                        }
                    169:                        break;
                    170:                case SUPPORTED_ATTRIBUTES:
                    171:                        if (this->length_or_value % 2)
                    172:                        {
                    173:                                failed = TRUE;
                    174:                        }
                    175:                        break;
                    176:                case APPLICATION_VERSION:
                    177:                case INTERNAL_IP4_SERVER:
                    178:                case INTERNAL_IP6_SERVER:
                    179:                case XAUTH_TYPE:
                    180:                case XAUTH_USER_NAME:
                    181:                case XAUTH_USER_PASSWORD:
                    182:                case XAUTH_PASSCODE:
                    183:                case XAUTH_MESSAGE:
                    184:                case XAUTH_CHALLENGE:
                    185:                case XAUTH_DOMAIN:
                    186:                case XAUTH_STATUS:
                    187:                case XAUTH_NEXT_PIN:
                    188:                case XAUTH_ANSWER:
                    189:                case UNITY_BANNER:
                    190:                case UNITY_SAVE_PASSWD:
                    191:                case UNITY_DEF_DOMAIN:
                    192:                case UNITY_SPLITDNS_NAME:
                    193:                case UNITY_SPLIT_INCLUDE:
                    194:                case UNITY_NATT_PORT:
                    195:                case UNITY_LOCAL_LAN:
                    196:                case UNITY_PFS:
                    197:                case UNITY_FW_TYPE:
                    198:                case UNITY_BACKUP_SERVERS:
                    199:                case UNITY_DDNS_HOSTNAME:
                    200:                        /* any length acceptable */
                    201:                        break;
                    202:                default:
                    203:                        DBG1(DBG_ENC, "unknown attribute type %N",
                    204:                                 configuration_attribute_type_names, this->attr_type);
                    205:                        break;
                    206:        }
                    207: 
                    208:        if (failed)
                    209:        {
                    210:                DBG1(DBG_ENC, "invalid attribute length %d for %N",
                    211:                         this->length_or_value, configuration_attribute_type_names,
                    212:                         this->attr_type);
                    213:                return FAILED;
                    214:        }
                    215:        return SUCCESS;
                    216: }
                    217: 
                    218: METHOD(payload_t, get_encoding_rules, int,
                    219:        private_configuration_attribute_t *this, encoding_rule_t **rules)
                    220: {
                    221:        if (this->type == PLV2_CONFIGURATION_ATTRIBUTE)
                    222:        {
                    223:                *rules = encodings_v2;
                    224:                return countof(encodings_v2);
                    225:        }
                    226:        *rules = encodings_v1;
                    227:        return countof(encodings_v1);
                    228: }
                    229: 
                    230: METHOD(payload_t, get_header_length, int,
                    231:        private_configuration_attribute_t *this)
                    232: {
                    233:        return 4;
                    234: }
                    235: 
                    236: METHOD(payload_t, get_type, payload_type_t,
                    237:        private_configuration_attribute_t *this)
                    238: {
                    239:        return this->type;
                    240: }
                    241: 
                    242: METHOD(payload_t, get_next_type, payload_type_t,
                    243:        private_configuration_attribute_t *this)
                    244: {
                    245:        return PL_NONE;
                    246: }
                    247: 
                    248: METHOD(payload_t, set_next_type, void,
                    249:        private_configuration_attribute_t *this, payload_type_t type)
                    250: {
                    251: }
                    252: 
                    253: METHOD(payload_t, get_length, size_t,
                    254:        private_configuration_attribute_t *this)
                    255: {
                    256:        return get_header_length(this) + this->value.len;
                    257: }
                    258: 
                    259: METHOD(configuration_attribute_t, get_cattr_type, configuration_attribute_type_t,
                    260:        private_configuration_attribute_t *this)
                    261: {
                    262:        return this->attr_type;
                    263: }
                    264: 
                    265: METHOD(configuration_attribute_t, get_chunk, chunk_t,
                    266:        private_configuration_attribute_t *this)
                    267: {
                    268:        if (this->af_flag)
                    269:        {
                    270:                return chunk_from_thing(this->length_or_value);
                    271:        }
                    272:        return this->value;
                    273: }
                    274: 
                    275: METHOD(configuration_attribute_t, get_value, uint16_t,
                    276:        private_configuration_attribute_t *this)
                    277: {
                    278:        if (this->af_flag)
                    279:        {
                    280:                return this->length_or_value;
                    281:        }
                    282:        return 0;
                    283: }
                    284: 
                    285: METHOD2(payload_t, configuration_attribute_t, destroy, void,
                    286:        private_configuration_attribute_t *this)
                    287: {
                    288:        free(this->value.ptr);
                    289:        free(this);
                    290: }
                    291: 
                    292: /*
                    293:  * Described in header.
                    294:  */
                    295: configuration_attribute_t *configuration_attribute_create(payload_type_t type)
                    296: {
                    297:        private_configuration_attribute_t *this;
                    298: 
                    299:        INIT(this,
                    300:                .public = {
                    301:                        .payload_interface = {
                    302:                                .verify = _verify,
                    303:                                .get_encoding_rules = _get_encoding_rules,
                    304:                                .get_header_length = _get_header_length,
                    305:                                .get_length = _get_length,
                    306:                                .get_next_type = _get_next_type,
                    307:                                .set_next_type = _set_next_type,
                    308:                                .get_type = _get_type,
                    309:                                .destroy = _destroy,
                    310:                        },
                    311:                        .get_chunk = _get_chunk,
                    312:                        .get_value = _get_value,
                    313:                        .get_type = _get_cattr_type,
                    314:                        .destroy = _destroy,
                    315:                },
                    316:                .type = type
                    317:        );
                    318:        return &this->public;
                    319: }
                    320: 
                    321: /*
                    322:  * Described in header.
                    323:  */
                    324: configuration_attribute_t *configuration_attribute_create_chunk(
                    325:        payload_type_t type, configuration_attribute_type_t attr_type, chunk_t chunk)
                    326: {
                    327:        private_configuration_attribute_t *this;
                    328: 
                    329:        this = (private_configuration_attribute_t*)
                    330:                                                        configuration_attribute_create(type);
                    331:        this->attr_type = ((uint16_t)attr_type) & 0x7FFF;
                    332:        this->value = chunk_clone(chunk);
                    333:        this->length_or_value = chunk.len;
                    334: 
                    335:        return &this->public;
                    336: }
                    337: 
                    338: /*
                    339:  * Described in header.
                    340:  */
                    341: configuration_attribute_t *configuration_attribute_create_value(
                    342:                                        configuration_attribute_type_t attr_type, uint16_t value)
                    343: {
                    344:        private_configuration_attribute_t *this;
                    345: 
                    346:        this = (private_configuration_attribute_t*)
                    347:                                        configuration_attribute_create(PLV1_CONFIGURATION_ATTRIBUTE);
                    348:        this->attr_type = ((uint16_t)attr_type) & 0x7FFF;
                    349:        this->length_or_value = value;
                    350:        this->af_flag = TRUE;
                    351: 
                    352:        return &this->public;
                    353: }
                    354: 

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