]>
Commit | Line | Data |
---|---|---|
1be296df | 1 | /* |
1b671669 | 2 | * Copyright (C) 2010 Martin Willi |
1b671669 | 3 | * Copyright (C) 2010 Andreas Steffen |
19ef2aec TB |
4 | * |
5 | * Copyright (C) secunet Security Networks AG | |
1be296df AS |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | |
8 | * under the terms of the GNU General Public License as published by the | |
9 | * Free Software Foundation; either version 2 of the License, or (at your | |
10 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | * for more details. | |
16 | */ | |
17 | ||
18 | #include "eap_peap.h" | |
19 | #include "eap_peap_peer.h" | |
20 | #include "eap_peap_server.h" | |
21 | ||
22 | #include <tls_eap.h> | |
23 | ||
24 | #include <daemon.h> | |
25 | #include <library.h> | |
26 | ||
27 | typedef struct private_eap_peap_t private_eap_peap_t; | |
28 | ||
29 | /** | |
30 | * Private data of an eap_peap_t object. | |
31 | */ | |
32 | struct private_eap_peap_t { | |
33 | ||
34 | /** | |
35 | * Public interface. | |
36 | */ | |
37 | eap_peap_t public; | |
38 | ||
39 | /** | |
40 | * TLS stack, wrapped by EAP helper | |
41 | */ | |
42 | tls_eap_t *tls_eap; | |
43 | }; | |
44 | ||
45 | /** Maximum number of EAP-PEAP messages/fragments allowed */ | |
46 | #define MAX_MESSAGE_COUNT 32 | |
47 | /** Default size of a EAP-PEAP fragment */ | |
48 | #define MAX_FRAGMENT_LEN 1024 | |
49 | ||
50 | METHOD(eap_method_t, initiate, status_t, | |
51 | private_eap_peap_t *this, eap_payload_t **out) | |
52 | { | |
53 | chunk_t data; | |
54 | ||
55 | if (this->tls_eap->initiate(this->tls_eap, &data) == NEED_MORE) | |
56 | { | |
57 | *out = eap_payload_create_data(data); | |
58 | free(data.ptr); | |
59 | return NEED_MORE; | |
60 | } | |
61 | return FAILED; | |
62 | } | |
63 | ||
64 | METHOD(eap_method_t, process, status_t, | |
65 | private_eap_peap_t *this, eap_payload_t *in, eap_payload_t **out) | |
66 | { | |
67 | status_t status; | |
68 | chunk_t data; | |
69 | ||
70 | data = in->get_data(in); | |
71 | status = this->tls_eap->process(this->tls_eap, data, &data); | |
72 | if (status == NEED_MORE) | |
73 | { | |
74 | *out = eap_payload_create_data(data); | |
75 | free(data.ptr); | |
76 | } | |
77 | return status; | |
78 | } | |
79 | ||
80 | METHOD(eap_method_t, get_type, eap_type_t, | |
b12c53ce | 81 | private_eap_peap_t *this, uint32_t *vendor) |
1be296df AS |
82 | { |
83 | *vendor = 0; | |
84 | return EAP_PEAP; | |
85 | } | |
86 | ||
87 | METHOD(eap_method_t, get_msk, status_t, | |
88 | private_eap_peap_t *this, chunk_t *msk) | |
89 | { | |
90 | *msk = this->tls_eap->get_msk(this->tls_eap); | |
91 | if (msk->len) | |
92 | { | |
93 | return SUCCESS; | |
94 | } | |
95 | return FAILED; | |
96 | } | |
97 | ||
b12c53ce | 98 | METHOD(eap_method_t, get_identifier, uint8_t, |
1be296df AS |
99 | private_eap_peap_t *this) |
100 | { | |
101 | return this->tls_eap->get_identifier(this->tls_eap); | |
102 | } | |
103 | ||
104 | METHOD(eap_method_t, set_identifier, void, | |
b12c53ce | 105 | private_eap_peap_t *this, uint8_t identifier) |
1be296df AS |
106 | { |
107 | this->tls_eap->set_identifier(this->tls_eap, identifier); | |
108 | } | |
109 | ||
110 | METHOD(eap_method_t, is_mutual, bool, | |
111 | private_eap_peap_t *this) | |
112 | { | |
113 | return TRUE; | |
114 | } | |
115 | ||
116 | METHOD(eap_method_t, destroy, void, | |
117 | private_eap_peap_t *this) | |
118 | { | |
119 | this->tls_eap->destroy(this->tls_eap); | |
120 | free(this); | |
121 | } | |
122 | ||
123 | /** | |
124 | * Create an empty private eap_peap_t object | |
125 | */ | |
126 | static private_eap_peap_t *eap_peap_create_empty(void) | |
127 | { | |
128 | private_eap_peap_t *this; | |
129 | ||
130 | INIT(this, | |
131 | .public = { | |
132 | .eap_method = { | |
133 | .initiate = _initiate, | |
134 | .process = _process, | |
135 | .get_type = _get_type, | |
136 | .is_mutual = _is_mutual, | |
137 | .get_msk = _get_msk, | |
138 | .get_identifier = _get_identifier, | |
139 | .set_identifier = _set_identifier, | |
140 | .destroy = _destroy, | |
141 | }, | |
142 | }, | |
143 | ); | |
144 | return this; | |
145 | } | |
146 | ||
147 | /** | |
148 | * Generic private constructor | |
149 | */ | |
150 | static eap_peap_t *eap_peap_create(private_eap_peap_t * this, | |
151 | identification_t *server, | |
152 | identification_t *peer, bool is_server, | |
153 | tls_application_t *application) | |
154 | { | |
155 | size_t frag_size; | |
156 | int max_msg_count; | |
2778b664 | 157 | bool include_length; |
1be296df AS |
158 | tls_t *tls; |
159 | ||
160 | if (is_server && !lib->settings->get_bool(lib->settings, | |
42500c27 | 161 | "%s.plugins.eap-peap.request_peer_auth", FALSE, |
d223fe80 | 162 | lib->ns)) |
1be296df AS |
163 | { |
164 | peer = NULL; | |
165 | } | |
166 | frag_size = lib->settings->get_int(lib->settings, | |
42500c27 | 167 | "%s.plugins.eap-peap.fragment_size", MAX_FRAGMENT_LEN, |
d223fe80 | 168 | lib->ns); |
1be296df | 169 | max_msg_count = lib->settings->get_int(lib->settings, |
42500c27 | 170 | "%s.plugins.eap-peap.max_message_count", MAX_MESSAGE_COUNT, |
d223fe80 | 171 | lib->ns); |
2778b664 | 172 | include_length = lib->settings->get_bool(lib->settings, |
d223fe80 | 173 | "%s.plugins.eap-peap.include_length", FALSE, lib->ns); |
6a5c86b7 | 174 | tls = tls_create(is_server, server, peer, TLS_PURPOSE_EAP_PEAP, |
11a46879 | 175 | application, NULL, 0); |
2778b664 AS |
176 | this->tls_eap = tls_eap_create(EAP_PEAP, tls, frag_size, max_msg_count, |
177 | include_length); | |
1be296df AS |
178 | if (!this->tls_eap) |
179 | { | |
180 | application->destroy(application); | |
181 | free(this); | |
182 | return NULL; | |
183 | } | |
184 | return &this->public; | |
185 | } | |
186 | ||
187 | eap_peap_t *eap_peap_create_server(identification_t *server, | |
42500c27 | 188 | identification_t *peer) |
1be296df AS |
189 | { |
190 | private_eap_peap_t *eap_peap; | |
191 | eap_method_t *eap_method; | |
192 | eap_peap_server_t *eap_peap_server; | |
193 | tls_application_t *application; | |
194 | ||
195 | /* the tunneled application needs a reference to the outer EAP-PEAP method */ | |
196 | eap_peap = eap_peap_create_empty(); | |
197 | eap_method = &eap_peap->public.eap_method; | |
198 | eap_peap_server = eap_peap_server_create(server, peer, eap_method); | |
199 | application = &eap_peap_server->application; | |
200 | ||
201 | return eap_peap_create(eap_peap, server, peer, TRUE, application); | |
202 | } | |
203 | ||
204 | eap_peap_t *eap_peap_create_peer(identification_t *server, | |
205 | identification_t *peer) | |
206 | { | |
207 | private_eap_peap_t *eap_peap; | |
208 | eap_method_t *eap_method; | |
209 | eap_peap_peer_t *eap_peap_peer; | |
210 | tls_application_t *application; | |
211 | ||
212 | /* the tunneled application needs a reference to the outer EAP-PEAP method */ | |
213 | eap_peap = eap_peap_create_empty(); | |
214 | eap_method = &eap_peap->public.eap_method; | |
215 | eap_peap_peer = eap_peap_peer_create(server, peer, eap_method); | |
216 | application = &eap_peap_peer->application; | |
217 | ||
218 | return eap_peap_create(eap_peap, server, peer, FALSE, application); | |
219 | } |