]>
Commit | Line | Data |
---|---|---|
6fc6879b JM |
1 | /* |
2 | * EAPOL supplicant state machines | |
0ebb23e3 | 3 | * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi> |
6fc6879b | 4 | * |
0f3d578e JM |
5 | * This software may be distributed under the terms of the BSD license. |
6 | * See README for more details. | |
6fc6879b JM |
7 | */ |
8 | ||
9 | #ifndef EAPOL_SUPP_SM_H | |
10 | #define EAPOL_SUPP_SM_H | |
11 | ||
90973fb2 | 12 | #include "common/defs.h" |
6fc6879b JM |
13 | |
14 | typedef enum { Unauthorized, Authorized } PortStatus; | |
15 | typedef enum { Auto, ForceUnauthorized, ForceAuthorized } PortControl; | |
16 | ||
17 | /** | |
18 | * struct eapol_config - Per network configuration for EAPOL state machines | |
19 | */ | |
20 | struct eapol_config { | |
21 | /** | |
22 | * accept_802_1x_keys - Accept IEEE 802.1X (non-WPA) EAPOL-Key frames | |
23 | * | |
24 | * This variable should be set to 1 when using EAPOL state machines | |
25 | * with non-WPA security policy to generate dynamic WEP keys. When | |
26 | * using WPA, this should be set to 0 so that WPA state machine can | |
27 | * process the EAPOL-Key frames. | |
28 | */ | |
29 | int accept_802_1x_keys; | |
30 | ||
31 | #define EAPOL_REQUIRE_KEY_UNICAST BIT(0) | |
32 | #define EAPOL_REQUIRE_KEY_BROADCAST BIT(1) | |
33 | /** | |
34 | * required_keys - Which EAPOL-Key packets are required | |
35 | * | |
36 | * This variable determines which EAPOL-Key packets are required before | |
37 | * marking connection authenticated. This is a bit field of | |
38 | * EAPOL_REQUIRE_KEY_UNICAST and EAPOL_REQUIRE_KEY_BROADCAST flags. | |
39 | */ | |
40 | int required_keys; | |
41 | ||
42 | /** | |
43 | * fast_reauth - Whether fast EAP reauthentication is enabled | |
44 | */ | |
45 | int fast_reauth; | |
46 | ||
47 | /** | |
48 | * workaround - Whether EAP workarounds are enabled | |
49 | */ | |
50 | unsigned int workaround; | |
51 | ||
52 | /** | |
53 | * eap_disabled - Whether EAP is disabled | |
54 | */ | |
55 | int eap_disabled; | |
a5d44ac0 JM |
56 | |
57 | /** | |
58 | * external_sim - Use external processing for SIM/USIM operations | |
59 | */ | |
60 | int external_sim; | |
6fc6879b JM |
61 | }; |
62 | ||
63 | struct eapol_sm; | |
64 | struct wpa_config_blob; | |
65 | ||
c60ba9f7 JM |
66 | enum eapol_supp_result { |
67 | EAPOL_SUPP_RESULT_FAILURE, | |
68 | EAPOL_SUPP_RESULT_SUCCESS, | |
69 | EAPOL_SUPP_RESULT_EXPECTED_FAILURE | |
70 | }; | |
71 | ||
6fc6879b JM |
72 | /** |
73 | * struct eapol_ctx - Global (for all networks) EAPOL state machine context | |
74 | */ | |
75 | struct eapol_ctx { | |
76 | /** | |
77 | * ctx - Pointer to arbitrary upper level context | |
78 | */ | |
79 | void *ctx; | |
80 | ||
81 | /** | |
82 | * preauth - IEEE 802.11i/RSN pre-authentication | |
83 | * | |
84 | * This EAPOL state machine is used for IEEE 802.11i/RSN | |
85 | * pre-authentication | |
86 | */ | |
87 | int preauth; | |
88 | ||
89 | /** | |
90 | * cb - Function to be called when EAPOL negotiation has been completed | |
91 | * @eapol: Pointer to EAPOL state machine data | |
c60ba9f7 | 92 | * @result: Whether the authentication was completed successfully |
6fc6879b JM |
93 | * @ctx: Pointer to context data (cb_ctx) |
94 | * | |
95 | * This optional callback function will be called when the EAPOL | |
96 | * authentication has been completed. This allows the owner of the | |
97 | * EAPOL state machine to process the key and terminate the EAPOL state | |
98 | * machine. Currently, this is used only in RSN pre-authentication. | |
99 | */ | |
c60ba9f7 JM |
100 | void (*cb)(struct eapol_sm *eapol, enum eapol_supp_result result, |
101 | void *ctx); | |
6fc6879b JM |
102 | |
103 | /** | |
104 | * cb_ctx - Callback context for cb() | |
105 | */ | |
106 | void *cb_ctx; | |
107 | ||
108 | /** | |
109 | * msg_ctx - Callback context for wpa_msg() calls | |
110 | */ | |
111 | void *msg_ctx; | |
112 | ||
113 | /** | |
114 | * scard_ctx - Callback context for PC/SC scard_*() function calls | |
115 | * | |
116 | * This context can be updated with eapol_sm_register_scard_ctx(). | |
117 | */ | |
118 | void *scard_ctx; | |
119 | ||
120 | /** | |
121 | * eapol_send_ctx - Callback context for eapol_send() calls | |
122 | */ | |
123 | void *eapol_send_ctx; | |
124 | ||
125 | /** | |
126 | * eapol_done_cb - Function to be called at successful completion | |
127 | * @ctx: Callback context (ctx) | |
128 | * | |
129 | * This function is called at the successful completion of EAPOL | |
130 | * authentication. If dynamic WEP keys are used, this is called only | |
131 | * after all the expected keys have been received. | |
132 | */ | |
133 | void (*eapol_done_cb)(void *ctx); | |
134 | ||
135 | /** | |
136 | * eapol_send - Send EAPOL packets | |
137 | * @ctx: Callback context (eapol_send_ctx) | |
138 | * @type: EAPOL type (IEEE802_1X_TYPE_*) | |
139 | * @buf: Pointer to EAPOL payload | |
140 | * @len: Length of the EAPOL payload | |
141 | * Returns: 0 on success, -1 on failure | |
142 | */ | |
143 | int (*eapol_send)(void *ctx, int type, const u8 *buf, size_t len); | |
144 | ||
145 | /** | |
146 | * set_wep_key - Configure WEP keys | |
147 | * @ctx: Callback context (ctx) | |
148 | * @unicast: Non-zero = unicast, 0 = multicast/broadcast key | |
149 | * @keyidx: Key index (0..3) | |
150 | * @key: WEP key | |
151 | * @keylen: Length of the WEP key | |
152 | * Returns: 0 on success, -1 on failure | |
153 | */ | |
154 | int (*set_wep_key)(void *ctx, int unicast, int keyidx, | |
155 | const u8 *key, size_t keylen); | |
156 | ||
157 | /** | |
158 | * set_config_blob - Set or add a named configuration blob | |
159 | * @ctx: Callback context (ctx) | |
160 | * @blob: New value for the blob | |
161 | * | |
162 | * Adds a new configuration blob or replaces the current value of an | |
163 | * existing blob. | |
164 | */ | |
165 | void (*set_config_blob)(void *ctx, struct wpa_config_blob *blob); | |
166 | ||
167 | /** | |
168 | * get_config_blob - Get a named configuration blob | |
169 | * @ctx: Callback context (ctx) | |
170 | * @name: Name of the blob | |
171 | * Returns: Pointer to blob data or %NULL if not found | |
172 | */ | |
173 | const struct wpa_config_blob * (*get_config_blob)(void *ctx, | |
174 | const char *name); | |
175 | ||
176 | /** | |
177 | * aborted_cached - Notify that cached PMK attempt was aborted | |
178 | * @ctx: Callback context (ctx) | |
179 | */ | |
180 | void (*aborted_cached)(void *ctx); | |
181 | ||
6fc6879b JM |
182 | /** |
183 | * opensc_engine_path - Path to the OpenSSL engine for opensc | |
184 | * | |
185 | * This is an OpenSSL specific configuration option for loading OpenSC | |
186 | * engine (engine_opensc.so); if %NULL, this engine is not loaded. | |
187 | */ | |
188 | const char *opensc_engine_path; | |
189 | ||
190 | /** | |
191 | * pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11 | |
192 | * | |
193 | * This is an OpenSSL specific configuration option for loading PKCS#11 | |
194 | * engine (engine_pkcs11.so); if %NULL, this engine is not loaded. | |
195 | */ | |
196 | const char *pkcs11_engine_path; | |
197 | ||
198 | /** | |
199 | * pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module | |
200 | * | |
201 | * This is an OpenSSL specific configuration option for configuring | |
202 | * path to OpenSC/PKCS#11 engine (opensc-pkcs11.so); if %NULL, this | |
203 | * module is not loaded. | |
204 | */ | |
205 | const char *pkcs11_module_path; | |
f855f923 | 206 | |
ad08c363 | 207 | /** |
116654ce | 208 | * wps - WPS context data |
ad08c363 | 209 | * |
116654ce | 210 | * This is only used by EAP-WSC and can be left %NULL if not available. |
ad08c363 | 211 | */ |
116654ce | 212 | struct wps_context *wps; |
6fc6879b JM |
213 | |
214 | /** | |
215 | * eap_param_needed - Notify that EAP parameter is needed | |
216 | * @ctx: Callback context (ctx) | |
9ef1aaae | 217 | * @field: Field indicator (e.g., WPA_CTRL_REQ_EAP_IDENTITY) |
6fc6879b JM |
218 | * @txt: User readable text describing the required parameter |
219 | */ | |
9ef1aaae | 220 | void (*eap_param_needed)(void *ctx, enum wpa_ctrl_req_type field, |
6fc6879b | 221 | const char *txt); |
4bc181ec JM |
222 | |
223 | /** | |
224 | * port_cb - Set port authorized/unauthorized callback (optional) | |
225 | * @ctx: Callback context (ctx) | |
226 | * @authorized: Whether the supplicant port is now in authorized state | |
227 | */ | |
228 | void (*port_cb)(void *ctx, int authorized); | |
ade74830 MC |
229 | |
230 | /** | |
231 | * cert_cb - Notification of a peer certificate | |
232 | * @ctx: Callback context (ctx) | |
233 | * @depth: Depth in certificate chain (0 = server) | |
234 | * @subject: Subject of the peer certificate | |
235 | * @cert_hash: SHA-256 hash of the certificate | |
236 | * @cert: Peer certificate | |
237 | */ | |
238 | void (*cert_cb)(void *ctx, int depth, const char *subject, | |
239 | const char *cert_hash, const struct wpabuf *cert); | |
1b414f59 JM |
240 | |
241 | /** | |
242 | * cert_in_cb - Include server certificates in callback | |
243 | */ | |
244 | int cert_in_cb; | |
dd7fec1f PS |
245 | |
246 | /** | |
247 | * status_cb - Notification of a change in EAP status | |
248 | * @ctx: Callback context (ctx) | |
249 | * @status: Step in the process of EAP authentication | |
250 | * @parameter: Step-specific parameter, e.g., EAP method name | |
251 | */ | |
252 | void (*status_cb)(void *ctx, const char *status, | |
253 | const char *parameter); | |
e026159a JM |
254 | |
255 | /** | |
256 | * set_anon_id - Set or add anonymous identity | |
257 | * @ctx: eapol_ctx from eap_peer_sm_init() call | |
258 | * @id: Anonymous identity (e.g., EAP-SIM pseudonym) | |
259 | * @len: Length of anonymous identity in octets | |
260 | */ | |
261 | void (*set_anon_id)(void *ctx, const u8 *id, size_t len); | |
6fc6879b JM |
262 | }; |
263 | ||
264 | ||
265 | struct eap_peer_config; | |
0ebb23e3 | 266 | struct ext_password_data; |
6fc6879b JM |
267 | |
268 | #ifdef IEEE8021X_EAPOL | |
269 | struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx); | |
270 | void eapol_sm_deinit(struct eapol_sm *sm); | |
271 | void eapol_sm_step(struct eapol_sm *sm); | |
272 | int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen, | |
273 | int verbose); | |
274 | int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen); | |
275 | void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod, | |
276 | int startPeriod, int maxStart); | |
277 | int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf, | |
278 | size_t len); | |
279 | void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm); | |
280 | void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled); | |
281 | void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid); | |
282 | void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success); | |
283 | void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail); | |
284 | void eapol_sm_notify_config(struct eapol_sm *sm, | |
285 | struct eap_peer_config *config, | |
286 | const struct eapol_config *conf); | |
287 | int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len); | |
288 | void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff); | |
289 | void eapol_sm_notify_cached(struct eapol_sm *sm); | |
290 | void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm, int attempt); | |
291 | void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx); | |
292 | void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl); | |
293 | void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm); | |
294 | void eapol_sm_notify_ctrl_response(struct eapol_sm *sm); | |
295 | void eapol_sm_request_reauth(struct eapol_sm *sm); | |
296 | void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, int in_eapol_sm); | |
297 | void eapol_sm_invalidate_cached_session(struct eapol_sm *sm); | |
c83e2e1c | 298 | const char * eapol_sm_get_method_name(struct eapol_sm *sm); |
0ebb23e3 JM |
299 | void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, |
300 | struct ext_password_data *ext); | |
00e5e3d5 | 301 | int eapol_sm_failed(struct eapol_sm *sm); |
07041c6f | 302 | int eapol_sm_get_eap_proxy_imsi(struct eapol_sm *sm, char *imsi, size_t *len); |
6fc6879b JM |
303 | #else /* IEEE8021X_EAPOL */ |
304 | static inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx) | |
305 | { | |
306 | free(ctx); | |
307 | return (struct eapol_sm *) 1; | |
308 | } | |
309 | static inline void eapol_sm_deinit(struct eapol_sm *sm) | |
310 | { | |
311 | } | |
312 | static inline void eapol_sm_step(struct eapol_sm *sm) | |
313 | { | |
314 | } | |
315 | static inline int eapol_sm_get_status(struct eapol_sm *sm, char *buf, | |
316 | size_t buflen, int verbose) | |
317 | { | |
318 | return 0; | |
319 | } | |
320 | static inline int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, | |
321 | size_t buflen) | |
322 | { | |
323 | return 0; | |
324 | } | |
325 | static inline void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, | |
326 | int authPeriod, int startPeriod, | |
327 | int maxStart) | |
328 | { | |
329 | } | |
330 | static inline int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, | |
331 | const u8 *buf, size_t len) | |
332 | { | |
333 | return 0; | |
334 | } | |
335 | static inline void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm) | |
336 | { | |
337 | } | |
338 | static inline void eapol_sm_notify_portEnabled(struct eapol_sm *sm, | |
339 | Boolean enabled) | |
340 | { | |
341 | } | |
342 | static inline void eapol_sm_notify_portValid(struct eapol_sm *sm, | |
343 | Boolean valid) | |
344 | { | |
345 | } | |
346 | static inline void eapol_sm_notify_eap_success(struct eapol_sm *sm, | |
347 | Boolean success) | |
348 | { | |
349 | } | |
350 | static inline void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail) | |
351 | { | |
352 | } | |
353 | static inline void eapol_sm_notify_config(struct eapol_sm *sm, | |
354 | struct eap_peer_config *config, | |
355 | struct eapol_config *conf) | |
356 | { | |
357 | } | |
358 | static inline int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len) | |
359 | { | |
360 | return -1; | |
361 | } | |
362 | static inline void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff) | |
363 | { | |
364 | } | |
365 | static inline void eapol_sm_notify_cached(struct eapol_sm *sm) | |
366 | { | |
367 | } | |
368 | #define eapol_sm_notify_pmkid_attempt(sm, attempt) do { } while (0) | |
369 | #define eapol_sm_register_scard_ctx(sm, ctx) do { } while (0) | |
370 | static inline void eapol_sm_notify_portControl(struct eapol_sm *sm, | |
371 | PortControl portControl) | |
372 | { | |
373 | } | |
374 | static inline void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm) | |
375 | { | |
376 | } | |
377 | static inline void eapol_sm_notify_ctrl_response(struct eapol_sm *sm) | |
378 | { | |
379 | } | |
380 | static inline void eapol_sm_request_reauth(struct eapol_sm *sm) | |
381 | { | |
382 | } | |
383 | static inline void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm, | |
384 | int in_eapol_sm) | |
385 | { | |
386 | } | |
387 | static inline void eapol_sm_invalidate_cached_session(struct eapol_sm *sm) | |
388 | { | |
389 | } | |
cf83fb0b PS |
390 | static inline const char * eapol_sm_get_method_name(struct eapol_sm *sm) |
391 | { | |
392 | return NULL; | |
393 | } | |
0ebb23e3 JM |
394 | static inline void eapol_sm_set_ext_pw_ctx(struct eapol_sm *sm, |
395 | struct ext_password_data *ext) | |
396 | { | |
397 | } | |
00e5e3d5 JM |
398 | static inline int eapol_sm_failed(struct eapol_sm *sm) |
399 | { | |
400 | return 0; | |
401 | } | |
6fc6879b JM |
402 | #endif /* IEEE8021X_EAPOL */ |
403 | ||
404 | #endif /* EAPOL_SUPP_SM_H */ |