Annotation of embedaddon/strongswan/src/libcharon/plugins/eap_ttls/eap_ttls_avp.c, revision 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>