Return to eap_ttls_avp.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / eap_ttls |
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: }