]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/plugins/eap_identity/eap_identity.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libcharon / plugins / eap_identity / eap_identity.c
1 /*
2 * Copyright (C) 2007-2008 Martin Willi
3 *
4 * Copyright (C) secunet Security Networks AG
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "eap_identity.h"
18
19 #include <daemon.h>
20 #include <library.h>
21
22 typedef struct private_eap_identity_t private_eap_identity_t;
23
24 /**
25 * Private data of an eap_identity_t object.
26 */
27 struct private_eap_identity_t {
28
29 /**
30 * Public authenticator_t interface.
31 */
32 eap_identity_t public;
33
34 /**
35 * ID of the peer
36 */
37 identification_t *peer;
38
39 /**
40 * received identity chunk
41 */
42 chunk_t identity;
43
44 /**
45 * EAP identifier
46 */
47 uint8_t identifier;
48 };
49
50 typedef struct eap_identity_header_t eap_identity_header_t;
51
52 /**
53 * packed EAP Identity header struct
54 */
55 struct eap_identity_header_t {
56 /** EAP code (REQUEST/RESPONSE) */
57 uint8_t code;
58 /** unique message identifier */
59 uint8_t identifier;
60 /** length of whole message */
61 uint16_t length;
62 /** EAP type */
63 uint8_t type;
64 /** identity data */
65 uint8_t data[];
66 } __attribute__((__packed__));
67
68 METHOD(eap_method_t, process_peer, status_t,
69 private_eap_identity_t *this, eap_payload_t *in, eap_payload_t **out)
70 {
71 chunk_t id;
72 eap_identity_header_t *hdr;
73 size_t len;
74
75 id = this->peer->get_encoding(this->peer);
76 len = sizeof(eap_identity_header_t) + id.len;
77 if (in)
78 {
79 this->identifier = in->get_identifier(in);
80 }
81 hdr = alloca(len);
82 hdr->code = EAP_RESPONSE;
83 hdr->identifier = this->identifier;
84 hdr->length = htons(len);
85 hdr->type = EAP_IDENTITY;
86 memcpy(hdr->data, id.ptr, id.len);
87
88 *out = eap_payload_create_data(chunk_create((u_char*)hdr, len));
89 return SUCCESS;
90 }
91
92 METHOD(eap_method_t, initiate_peer, status_t,
93 private_eap_identity_t *this, eap_payload_t **out)
94 {
95 /* peer never initiates */
96 return FAILED;
97 }
98
99 METHOD(eap_method_t, process_server, status_t,
100 private_eap_identity_t *this, eap_payload_t *in, eap_payload_t **out)
101 {
102 chunk_t data;
103
104 data = chunk_skip(in->get_data(in), 5);
105 if (data.len)
106 {
107 this->identity = chunk_clone(data);
108 }
109 return SUCCESS;
110 }
111
112 METHOD(eap_method_t, initiate_server, status_t,
113 private_eap_identity_t *this, eap_payload_t **out)
114 {
115 eap_identity_header_t hdr;
116
117 hdr.code = EAP_REQUEST;
118 hdr.identifier = this->identifier;
119 hdr.length = htons(sizeof(eap_identity_header_t));
120 hdr.type = EAP_IDENTITY;
121
122 *out = eap_payload_create_data(chunk_create((u_char*)&hdr,
123 sizeof(eap_identity_header_t)));
124 return NEED_MORE;
125 }
126
127 METHOD(eap_method_t, get_type, eap_type_t,
128 private_eap_identity_t *this, uint32_t *vendor)
129 {
130 *vendor = 0;
131 return EAP_IDENTITY;
132 }
133
134 METHOD(eap_method_t, get_msk, status_t,
135 private_eap_identity_t *this, chunk_t *msk)
136 {
137 if (this->identity.ptr)
138 {
139 *msk = this->identity;
140 return SUCCESS;
141 }
142 return FAILED;
143 }
144
145 METHOD(eap_method_t, get_identifier, uint8_t,
146 private_eap_identity_t *this)
147 {
148 return this->identifier;
149 }
150
151 METHOD(eap_method_t, set_identifier, void,
152 private_eap_identity_t *this, uint8_t identifier)
153 {
154 this->identifier = identifier;
155 }
156
157 METHOD(eap_method_t, is_mutual, bool,
158 private_eap_identity_t *this)
159 {
160 return FALSE;
161 }
162
163 METHOD(eap_method_t, destroy, void,
164 private_eap_identity_t *this)
165 {
166 this->peer->destroy(this->peer);
167 free(this->identity.ptr);
168 free(this);
169 }
170
171 /*
172 * Described in header.
173 */
174 eap_identity_t *eap_identity_create_peer(identification_t *server,
175 identification_t *peer)
176 {
177 private_eap_identity_t *this;
178
179 INIT(this,
180 .public = {
181 .eap_method = {
182 .initiate = _initiate_peer,
183 .process = _process_peer,
184 .get_type = _get_type,
185 .is_mutual = _is_mutual,
186 .get_msk = _get_msk,
187 .get_identifier = _get_identifier,
188 .set_identifier = _set_identifier,
189 .destroy = _destroy,
190 },
191 },
192 .peer = peer->clone(peer),
193 .identity = chunk_empty,
194 );
195
196 return &this->public;
197 }
198
199 /*
200 * Described in header.
201 */
202 eap_identity_t *eap_identity_create_server(identification_t *server,
203 identification_t *peer)
204 {
205 private_eap_identity_t *this;
206
207 INIT(this,
208 .public = {
209 .eap_method = {
210 .initiate = _initiate_server,
211 .process = _process_server,
212 .get_type = _get_type,
213 .is_mutual = _is_mutual,
214 .get_msk = _get_msk,
215 .get_identifier = _get_identifier,
216 .set_identifier = _set_identifier,
217 .destroy = _destroy,
218 },
219 },
220 .peer = peer->clone(peer),
221 .identity = chunk_empty,
222 );
223
224 return &this->public;
225 }
226