2 * Test program for combined WPA authenticator/supplicant
3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "ieee802_11_defs.h"
23 #include "../hostapd/wpa.h"
26 extern int wpa_debug_level
;
27 extern int wpa_debug_show_keys
;
31 u8 auth_addr
[ETH_ALEN
];
32 u8 supp_addr
[ETH_ALEN
];
35 /* from authenticator */
36 u8 auth_eapol_dst
[ETH_ALEN
];
38 size_t auth_eapol_len
;
42 size_t supp_eapol_len
;
45 struct wpa_authenticator
*auth_group
;
46 struct wpa_state_machine
*auth
;
54 static struct wpa_ssid
* supp_get_ssid(void *ctx
)
56 struct wpa
*wpa
= ctx
;
57 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
62 static int supp_get_bssid(void *ctx
, u8
*bssid
)
64 struct wpa
*wpa
= ctx
;
65 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
66 os_memcpy(bssid
, wpa
->auth_addr
, ETH_ALEN
);
71 static void supp_set_state(void *ctx
, wpa_states state
)
73 wpa_printf(MSG_DEBUG
, "SUPP: %s(state=%d)", __func__
, state
);
77 static void auth_eapol_rx(void *eloop_data
, void *user_ctx
)
79 struct wpa
*wpa
= eloop_data
;
81 wpa_printf(MSG_DEBUG
, "AUTH: RX EAPOL frame");
82 wpa_receive(wpa
->auth_group
, wpa
->auth
, wpa
->supp_eapol
,
87 static int supp_ether_send(void *ctx
, const u8
*dest
, u16 proto
, const u8
*buf
,
90 struct wpa
*wpa
= ctx
;
92 wpa_printf(MSG_DEBUG
, "SUPP: %s(dest=" MACSTR
" proto=0x%04x "
94 __func__
, MAC2STR(dest
), proto
, (unsigned long) len
);
96 os_free(wpa
->supp_eapol
);
97 wpa
->supp_eapol
= os_malloc(len
);
98 if (wpa
->supp_eapol
== NULL
)
100 os_memcpy(wpa
->supp_eapol
, buf
, len
);
101 wpa
->supp_eapol_len
= len
;
102 eloop_register_timeout(0, 0, auth_eapol_rx
, wpa
, NULL
);
108 static u8
* supp_alloc_eapol(void *ctx
, u8 type
, const void *data
,
109 u16 data_len
, size_t *msg_len
, void **data_pos
)
111 struct ieee802_1x_hdr
*hdr
;
113 wpa_printf(MSG_DEBUG
, "SUPP: %s(type=%d data_len=%d)",
114 __func__
, type
, data_len
);
116 *msg_len
= sizeof(*hdr
) + data_len
;
117 hdr
= os_malloc(*msg_len
);
123 hdr
->length
= host_to_be16(data_len
);
126 os_memcpy(hdr
+ 1, data
, data_len
);
128 os_memset(hdr
+ 1, 0, data_len
);
137 static int supp_get_beacon_ie(void *ctx
)
139 struct wpa
*wpa
= ctx
;
143 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
145 ie
= wpa_auth_get_wpa_ie(wpa
->auth_group
, &ielen
);
146 if (ie
== NULL
|| ielen
< 1)
148 if (ie
[0] == WLAN_EID_RSN
)
149 return wpa_sm_set_ap_rsn_ie(wpa
->supp
, ie
, 2 + ie
[1]);
150 return wpa_sm_set_ap_wpa_ie(wpa
->supp
, ie
, 2 + ie
[1]);
154 static int supp_set_key(void *ctx
, wpa_alg alg
,
155 const u8
*addr
, int key_idx
, int set_tx
,
156 const u8
*seq
, size_t seq_len
,
157 const u8
*key
, size_t key_len
)
159 wpa_printf(MSG_DEBUG
, "SUPP: %s(alg=%d addr=" MACSTR
" key_idx=%d "
161 __func__
, alg
, MAC2STR(addr
), key_idx
, set_tx
);
162 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - seq", seq
, seq_len
);
163 wpa_hexdump(MSG_DEBUG
, "SUPP: set_key - key", key
, key_len
);
168 static int supp_mlme_setprotection(void *ctx
, const u8
*addr
,
169 int protection_type
, int key_type
)
171 wpa_printf(MSG_DEBUG
, "SUPP: %s(addr=" MACSTR
" protection_type=%d "
173 __func__
, MAC2STR(addr
), protection_type
, key_type
);
178 static void supp_cancel_scan(void *ctx
)
180 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
184 static void supp_cancel_auth_timeout(void *ctx
)
186 wpa_printf(MSG_DEBUG
, "SUPP: %s", __func__
);
190 static int supp_init(struct wpa
*wpa
)
192 struct wpa_sm_ctx
*ctx
= os_zalloc(sizeof(*ctx
));
197 ctx
->set_state
= supp_set_state
;
198 ctx
->get_ssid
= supp_get_ssid
;
199 ctx
->get_bssid
= supp_get_bssid
;
200 ctx
->ether_send
= supp_ether_send
;
201 ctx
->get_beacon_ie
= supp_get_beacon_ie
;
202 ctx
->alloc_eapol
= supp_alloc_eapol
;
203 ctx
->set_key
= supp_set_key
;
204 ctx
->mlme_setprotection
= supp_mlme_setprotection
;
205 ctx
->cancel_scan
= supp_cancel_scan
;
206 ctx
->cancel_auth_timeout
= supp_cancel_auth_timeout
;
207 wpa
->supp
= wpa_sm_init(ctx
);
208 if (wpa
->supp
== NULL
) {
209 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_init() failed");
213 wpa_sm_set_own_addr(wpa
->supp
, wpa
->supp_addr
);
214 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_RSN_ENABLED
, 1);
215 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_PROTO
, WPA_PROTO_RSN
);
216 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_PAIRWISE
, WPA_CIPHER_CCMP
);
217 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_GROUP
, WPA_CIPHER_CCMP
);
218 wpa_sm_set_param(wpa
->supp
, WPA_PARAM_KEY_MGMT
, WPA_KEY_MGMT_PSK
);
219 wpa_sm_set_pmk(wpa
->supp
, wpa
->psk
, PMK_LEN
);
221 wpa
->supp_ie_len
= sizeof(wpa
->supp_ie
);
222 if (wpa_sm_set_assoc_wpa_ie_default(wpa
->supp
, wpa
->supp_ie
,
223 &wpa
->supp_ie_len
) < 0) {
224 wpa_printf(MSG_DEBUG
, "SUPP: wpa_sm_set_assoc_wpa_ie_default()"
229 wpa_sm_notify_assoc(wpa
->supp
, wpa
->auth_addr
);
235 static void auth_logger(void *ctx
, const u8
*addr
, logger_level level
,
239 wpa_printf(MSG_DEBUG
, "AUTH: " MACSTR
" - %s",
242 wpa_printf(MSG_DEBUG
, "AUTH: %s", txt
);
246 static void supp_eapol_rx(void *eloop_data
, void *user_ctx
)
248 struct wpa
*wpa
= eloop_data
;
250 wpa_printf(MSG_DEBUG
, "SUPP: RX EAPOL frame");
251 wpa_sm_rx_eapol(wpa
->supp
, wpa
->auth_addr
, wpa
->auth_eapol
,
252 wpa
->auth_eapol_len
);
256 static int auth_send_eapol(void *ctx
, const u8
*addr
, const u8
*data
,
257 size_t data_len
, int encrypt
)
259 struct wpa
*wpa
= ctx
;
261 wpa_printf(MSG_DEBUG
, "AUTH: %s(addr=" MACSTR
" data_len=%lu "
263 __func__
, MAC2STR(addr
), (unsigned long) data_len
, encrypt
);
265 os_free(wpa
->auth_eapol
);
266 wpa
->auth_eapol
= os_malloc(data_len
);
267 if (wpa
->auth_eapol
== NULL
)
269 os_memcpy(wpa
->auth_eapol_dst
, addr
, ETH_ALEN
);
270 os_memcpy(wpa
->auth_eapol
, data
, data_len
);
271 wpa
->auth_eapol_len
= data_len
;
272 eloop_register_timeout(0, 0, supp_eapol_rx
, wpa
, NULL
);
278 static const u8
* auth_get_psk(void *ctx
, const u8
*addr
, const u8
*prev_psk
)
280 struct wpa
*wpa
= ctx
;
281 wpa_printf(MSG_DEBUG
, "AUTH: %s (addr=" MACSTR
" prev_psk=%p)",
282 __func__
, MAC2STR(addr
), prev_psk
);
289 static int auth_init_group(struct wpa
*wpa
)
291 struct wpa_auth_config conf
;
292 struct wpa_auth_callbacks cb
;
294 wpa_printf(MSG_DEBUG
, "AUTH: Initializing group state machine");
296 os_memset(&conf
, 0, sizeof(conf
));
298 conf
.wpa_key_mgmt
= WPA_KEY_MGMT_PSK
;
299 conf
.wpa_pairwise
= WPA_CIPHER_CCMP
;
300 conf
.rsn_pairwise
= WPA_CIPHER_CCMP
;
301 conf
.wpa_group
= WPA_CIPHER_CCMP
;
302 conf
.eapol_version
= 2;
304 os_memset(&cb
, 0, sizeof(cb
));
306 cb
.logger
= auth_logger
;
307 cb
.send_eapol
= auth_send_eapol
;
308 cb
.get_psk
= auth_get_psk
;
310 wpa
->auth_group
= wpa_init(wpa
->auth_addr
, &conf
, &cb
);
311 if (wpa
->auth_group
== NULL
) {
312 wpa_printf(MSG_DEBUG
, "AUTH: wpa_init() failed");
320 static int auth_init(struct wpa
*wpa
)
322 wpa
->auth
= wpa_auth_sta_init(wpa
->auth_group
, wpa
->supp_addr
);
323 if (wpa
->auth
== NULL
) {
324 wpa_printf(MSG_DEBUG
, "AUTH: wpa_auth_sta_init() failed");
328 if (wpa_validate_wpa_ie(wpa
->auth_group
, wpa
->auth
, wpa
->supp_ie
,
329 wpa
->supp_ie_len
, NULL
, 0) != WPA_IE_OK
) {
330 wpa_printf(MSG_DEBUG
, "AUTH: wpa_validate_wpa_ie() failed");
334 wpa_auth_sm_event(wpa
->auth
, WPA_ASSOC
);
336 wpa_auth_sta_associated(wpa
->auth_group
, wpa
->auth
);
342 static void deinit(struct wpa
*wpa
)
344 wpa_auth_sta_deinit(wpa
->auth
);
345 wpa_sm_deinit(wpa
->supp
);
346 wpa_deinit(wpa
->auth_group
);
347 os_free(wpa
->auth_eapol
);
348 wpa
->auth_eapol
= NULL
;
349 os_free(wpa
->supp_eapol
);
350 wpa
->supp_eapol
= NULL
;
354 int main(int argc
, char *argv
[])
358 if (os_program_init())
361 os_memset(&wpa
, 0, sizeof(wpa
));
362 os_memset(wpa
.auth_addr
, 0x12, ETH_ALEN
);
363 os_memset(wpa
.supp_addr
, 0x32, ETH_ALEN
);
364 os_memset(wpa
.psk
, 0x44, PMK_LEN
);
367 wpa_debug_show_keys
= 1;
369 if (eloop_init(&wpa
)) {
370 wpa_printf(MSG_ERROR
, "Failed to initialize event loop");
374 if (auth_init_group(&wpa
) < 0)
377 if (supp_init(&wpa
) < 0)
380 if (auth_init(&wpa
) < 0)
383 wpa_printf(MSG_DEBUG
, "Starting eloop");
385 wpa_printf(MSG_DEBUG
, "eloop done");