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>