Annotation of embedaddon/strongswan/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2010 Andreas Steffen
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "eap_ttls_avp.h"
                     17: 
                     18: #include <utils/debug.h>
                     19: 
                     20: #define AVP_EAP_MESSAGE                79
                     21: #define AVP_HEADER_LEN          8
                     22: 
                     23: typedef struct private_eap_ttls_avp_t private_eap_ttls_avp_t;
                     24: 
                     25: /**
                     26:  * Private data of an eap_ttls_avp_t object.
                     27:  */
                     28: struct private_eap_ttls_avp_t {
                     29: 
                     30:        /**
                     31:         * Public eap_ttls_avp_t interface.
                     32:         */
                     33:        eap_ttls_avp_t public;
                     34: 
                     35:        /**
                     36:         * AVP input buffer
                     37:         */
                     38:        chunk_t input;
                     39: 
                     40:        /**
                     41:         * Position in input buffer
                     42:         */
                     43:        size_t inpos;
                     44: 
                     45:        /**
                     46:         * process header (TRUE) or body (FALSE)
                     47:         */
                     48:        bool process_header;
                     49: 
                     50:        /**
                     51:         * Size of AVP data
                     52:         */
                     53:        size_t data_len;
                     54: };
                     55: 
                     56: METHOD(eap_ttls_avp_t, build, void,
                     57:        private_eap_ttls_avp_t *this, bio_writer_t *writer, chunk_t data)
                     58: {
                     59:        char zero_padding[] = { 0x00, 0x00, 0x00 };
                     60:        chunk_t   avp_padding;
                     61:        uint8_t  avp_flags;
                     62:        uint32_t avp_len;
                     63: 
                     64:        avp_flags = 0x40;
                     65:        avp_len = 8 + data.len;
                     66:        avp_padding = chunk_create(zero_padding, (4 - data.len) % 4);
                     67: 
                     68:        writer->write_uint32(writer, AVP_EAP_MESSAGE);
                     69:        writer->write_uint8(writer, avp_flags);
                     70:        writer->write_uint24(writer, avp_len);
                     71:        writer->write_data(writer, data);
                     72:        writer->write_data(writer, avp_padding);
                     73: }
                     74: 
                     75: METHOD(eap_ttls_avp_t, process, status_t,
                     76:        private_eap_ttls_avp_t* this, bio_reader_t *reader, chunk_t *data)
                     77: {
                     78:        size_t len;
                     79:        chunk_t buf;
                     80: 
                     81:        if (this->process_header)
                     82:        {
                     83:                bio_reader_t *header;
                     84:                uint32_t avp_code;
                     85:                uint8_t  avp_flags;
                     86:                uint32_t avp_len;
                     87:                bool success;
                     88: 
                     89:                len = min(reader->remaining(reader), AVP_HEADER_LEN - this->inpos);
                     90:                if (!reader->read_data(reader, len, &buf))
                     91:                {
                     92:                        return FAILED;
                     93:                }
                     94:                if (this->input.len == 0)
                     95:                {
                     96:                        /* start of a new AVP header */
                     97:                        this->input = chunk_alloc(AVP_HEADER_LEN);
                     98:                        memcpy(this->input.ptr, buf.ptr, len);
                     99:                        this->inpos = len;
                    100:                }
                    101:                else
                    102:                {
                    103:                        memcpy(this->input.ptr + this->inpos, buf.ptr, len);
                    104:                        this->inpos += len;
                    105:                }
                    106: 
                    107:                if (this->inpos < AVP_HEADER_LEN)
                    108:                {
                    109:                        return NEED_MORE;
                    110:                }
                    111: 
                    112:                /* parse AVP header */
                    113:                header = bio_reader_create(this->input);
                    114:                success = header->read_uint32(header, &avp_code) &&
                    115:                                  header->read_uint8(header, &avp_flags) &&
                    116:                                  header->read_uint24(header, &avp_len);
                    117:                header->destroy(header);
                    118:                chunk_free(&this->input);
                    119:                this->inpos = 0;
                    120: 
                    121:                if (!success)
                    122:                {
                    123:                        DBG1(DBG_IKE, "received invalid AVP header");
                    124:                        return FAILED;
                    125:                }
                    126:                if (avp_code != AVP_EAP_MESSAGE)
                    127:                {
                    128:                        DBG1(DBG_IKE, "expected AVP_EAP_MESSAGE but received %u", avp_code);
                    129:                        return FAILED;
                    130:                }
                    131:                this->process_header = FALSE;
                    132:                this->data_len = avp_len - 8;
                    133:                this->input = chunk_alloc(this->data_len + (4 - avp_len) % 4);
                    134:        }
                    135: 
                    136:        /* process AVP data */
                    137:        len = min(reader->remaining(reader), this->input.len - this->inpos);
                    138:        if (!reader->read_data(reader, len, &buf))
                    139:        {
                    140:                return FAILED;
                    141:        }
                    142:        memcpy(this->input.ptr + this->inpos, buf.ptr, len);
                    143:        this->inpos += len;
                    144:        if (this->inpos < this->input.len)
                    145:        {
                    146:                return NEED_MORE;
                    147:        }
                    148: 
                    149:        *data = this->input;
                    150:        data->len = this->data_len;
                    151: 
                    152:        /* preparing for next AVP */
                    153:        this->input = chunk_empty;
                    154:        this->inpos = 0;
                    155:        this->process_header = TRUE;
                    156: 
                    157:        return SUCCESS;
                    158: }
                    159: 
                    160: METHOD(eap_ttls_avp_t, destroy, void,
                    161:        private_eap_ttls_avp_t *this)
                    162: {
                    163:        chunk_free(&this->input);
                    164:        free(this);
                    165: }
                    166: 
                    167: /**
                    168:  * See header
                    169:  */
                    170: eap_ttls_avp_t *eap_ttls_avp_create(void)
                    171: {
                    172:        private_eap_ttls_avp_t *this;
                    173: 
                    174:        INIT(this,
                    175:                .public= {
                    176:                        .process = _process,
                    177:                        .build = _build,
                    178:                        .destroy = _destroy,
                    179:                },
                    180:                .input = chunk_empty,
                    181:                .inpos = 0,
                    182:                .process_header = TRUE,
                    183:                .data_len = 0,
                    184:        );
                    185: 
                    186:        return &this->public;
                    187: }

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