Wpa supplicant introduction

24
Wpa_supplicant Introduction [email protected] 2016/03/20

Transcript of Wpa supplicant introduction

Page 2: Wpa supplicant introduction

Outline● Wha is Wpa_supplicant● Usage● Initialization Flow● cfg80211 and libnl● Layer 2 Packet Sniffing● Event Loop

Page 3: Wpa supplicant introduction

What is Wpa_supplicant● From Wiki page: wpa_supplicant

● wpa_supplicant is widely used in Linux distributions and Android!● These slides are based on 2.6-devel

wpa_supplicant is a free software implementation of an IEEE 802.11i supplicant for Linux, FreeBSD, NetBSD, QNX, AROS, Microsoft Windows, Solaris, OS/2 (including eComStation) and Haiku. In addition to being a fully featured WPA2 supplicant, it also implements WPA and older wireless LAN security protocols. Features include:

● WPA and full IEEE 802.11i/RSN/WPA2● WPA-PSK and WPA2-PSK ("WPA-Personal", pre-shared key)● WPA with EAP ("WPA-Enterprise", for example with RADIUS authentication server)● key management for CCMP, TKIP, WEP (both 104/128- and 40/64-bit)● RSN: PMKSA caching, pre-authentication● IEEE 802.11r● IEEE 802.11w● Wi-Fi Protected Setup (WPS)

Page 4: Wpa supplicant introduction

Usage● wpa_supplicant

○ -D: driver type, cfg80211 or wext○ -B: run as a daemon○ -b: the bridge interface○ -c: configure file path○ -C: control interface○ -d: decrease debug level (show more log)○ -e: entropy file○ -f: debug log file○ -g: global control interface (ctrl_interface)○ -G: the ctrl_interface will set to be owned by the specified group○ -h: show usage○ -i: interface○ -I: another configuration file○ -K: show key in debug log

Page 5: Wpa supplicant introduction

Usage● wpa_supplicant

○ -L: show license○ -m: p2p device configuration file○ -o: override driver option○ -O: override control interface option○ -p: driver parameter○ -P: PID file○ -q: increase debug level (show less log)○ -s: use syslog○ -T: use Linux Tracing○ -t: add timestamp in debug log○ -u: dbus control interface○ -v: show wpa_supplicant version○ -W: defer the main event loop until first external program attaches wpa_supplicant○ -N: combine multiple interface parameters

Page 6: Wpa supplicant introduction

cfg80211

wpa_supplicant, hostapd, iw, ...

nl80211

libnl, libnl-genl

mac80211

User Space

Kernel Space

wireless driver

wireless device Physical HW

Architechture

Page 7: Wpa supplicant introduction

Initialization Flow1. wpa_supplicant_init()2. Add each interface via wpa_supplicant_add_iface()3. Run event loop via wpa_supplicant_run()

Page 8: Wpa supplicant introduction

Init Step 1: wpa_supplicant_init()1. Init debug log setting

a. If specified to dump log to file via -f parameter, then initialize the output file via

wpa_debug_open_file(). Otherwise, initialize the standard output for debug log via wpa_debug_setup_stdout()

b. If specified to dump log to syslog via -s parameter, then initialize syslog setting via wpa_debug_open_syslog()

c. If specified to dump log by Linux Tracing via -T parameter, then initialize the setting via wpa_debug_open_linux_tracing()

2. Initialize EAP methods via eap_register_methods()3. Initialize global ctrl_interface via wpa_supplicant_global_ctrl_iface_init()

a. Open socket for the ctrl_interfaceb. Set the group permission if the group is specified by -G parametersc. Register ctrl_interface reader socket via eloop_register_read_sock()

Page 9: Wpa supplicant introduction

Init Step 1: wpa_supplicant_init()4. Initialize dbus via wpas_notify_supplicant_initialized()5. Check global driver list wpa_drivers6. Register a period timeout (10s) function wpas_periodic to:

a. P2P: check whether P2P peers expired via p2p_expire_peers()b. STA: flush expired bss via wpa_bss_flush_by_age()c. AP: check whether the acl is expired via ap_periodic()

Page 10: Wpa supplicant introduction

Init Step 2: wpa_supplicant_add_iface()1. Allocate wpa_supplicant structure fo each interface2. If the override driver option is set by -o parameter, override the driver

specified by -D parameter3. If the override ctrl_interface option is set by -O parameter, override the

ctrl_interface specified by -C parameter4. wpa_supplicant_init_iface()

a. Read configuration file via wpa_config_read if the file is specified by -c parameter; if not specified, make default configrations

b. Read another configuration file vi wpa_config_read if the file is specified by -I parameter

c. If ctrl_interface and driver_param are specified by configuration file and comman line parameter, use the one specified by command line

Page 11: Wpa supplicant introduction

Init Step 2: wpa_supplicant_add_iface()5. wpas_init_driver()

a. Set the driver (e.g. cfg80211 driver)b. Initialize driver via wpa_drv_init()c. Setup driver parameter via wpa_drv_set_param() if specified by -p parameterd. Add the interface into the wpa_s->radio_list via radio_add_interface()

6. Initialize wpa context via wpa_supplicant_init_wpa()7. Initialize hw feature to wpa_s->hw.modes via

wpa_drv_get_hw_feature_data()8. Get and setup driver capability via wpa_drv_get_capa()9. etup bridge or trigger scan via wpa_supplicant_driver_init()

10. If the interface is not P2P device, initialize TDLS via wpa_tdls_init()11. Set country via wpa_drv_set_country()

Page 12: Wpa supplicant introduction

Init Step 2: wpa_supplicant_add_iface()12. Initialize WPS via wpas_wps_init()13. Initialize EAPOL via wpa_supplicant_init_eapol()14. Initialize the ctrl_iface of the interface via wpa_supplicant_ctrl_iface_init()15. Initialize GAS query via gas_query_init()16. Initialize P2P via wpas_p2p_init(), if the interface support P2P devic

operations17. Set WOW settings via wpas_set_wowlan_triggers()18. If support P2P device, try to add P2P device interface via

wpas_p2p_add_p2pdev_interface()

Page 13: Wpa supplicant introduction

Init Step 3: wpa_supplicant_run()1. If -B parameter is assigned, run wpa_supplicant as daemon via

wpa_supplicant_daemon2. If -W parameter is assigned, start the event loop after external program

starting to attach wpa_supplicant via wpa_supplicant_ctrl_iface_wait()3. Register terminal signal SIGINT and SIGTERM handler via

eloop_register_signal_terminate4. Register SIGHUP as reconfig signal via eloop_register_signal_reconfig()5. Start event loop via eloop_run()

Page 14: Wpa supplicant introduction

cfg80211 and libnl

Page 15: Wpa supplicant introduction

What is cfg80211 and libnl● cfg80211 is a configuration system in Linux kernel for manipulating

802.11 devices● libnl is the bridge for user space and kernel space to interact with each

other during manipulating 802.11 devices● nl80211 in kernel registers the generic netlink(nl) family “nl80211”● wpa_supplicant in userspace calls libnl APIs to communicate with kernel

generic nl family “nl80211”

Page 16: Wpa supplicant introduction

Wpa_supplicant to kernel cf80211 via linbl1. Initialize netlink connection via netlink_init()2. Initialize the connection to kernel nl80211 via

wpa_driver_nl80211_init_nl_global()a. Allocate nl handler via global->nl = nl_create_handle(global->nl_cb, "nl");b. Resolve nl80211 via global->nl80211_id = genl_ctrl_resolve(global->nl, "nl80211");c. Allocate event handler via global->nl_event = nl_create_handle(global->nl_cb, "event");d. Add global->nl_event to “mlme”, “scan”, “regulatory”, “vendor” groups via:

i. ret = nl_get_multicast_id(global, "nl80211", "mlme");ii. ret = nl_socket_add_membership(global->nl_event, ret);

e. Assign the global event handler via:

i. nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM, process_global_event, global);

f. Assign “mlme”, “scan”, “regulatory”, “vendor” event handler via:

i. nl80211_register_eloop_read(&global->nl_event, wpa_driver_nl80211_event_receive, global->nl_cb)

Page 17: Wpa supplicant introduction

Layer 2 Packet Sniffing

Page 18: Wpa supplicant introduction

Why Need to Access Layer 2 Packets● To maintain the state machine of specified functions (e.g. TDLS),

wpa_supplicant needs to access layer 2(l2) packets○ e.g. TDLS, many action frames are encapulated in layer 2 packets

Page 19: Wpa supplicant introduction

Take TDLS as Example1. wpa_supplicant calls l2_packet_init() to initialize the connection to l2 and

monitor the specified l2 packetsa. Assign the rx_callback (wpa_supplicant_rx_tdls())function for specified protocolb. Assign the rx handle function l2_packet_receive() which will invoke the rx_callback

int wpa_tdls_init(struct wpa_sm *sm){ if (sm == NULL) return -1;

sm->l2_tdls = l2_packet_init(sm->bridge_ifname ? sm->bridge_ifname : sm->ifname, sm->own_addr, ETH_P_80211_ENCAP, wpa_supplicant_rx_tdls, sm, 0); if (sm->l2_tdls == NULL) { wpa_printf(MSG_ERROR, "TDLS: Failed to open l2_packet " "connection"); return -1; }...

Page 20: Wpa supplicant introduction

Event Loop

Page 21: Wpa supplicant introduction

eloop_init()● Initialize eloop.timeout list● Initialize eloop.reader, eloop.writer, eloop.exception

Page 22: Wpa supplicant introduction

eloop_run()● eloop keeps running is eloop.terminate is not set or any count of eloop.

reader, eloop.writer, eloop.exception is not zero● During the while loop

○ Get first timout event in eloop.timeout list and calculate the remianing time to reach the timeout

○ Call select() to wait for coming reader, writer, exception events○ Call eloop_process_pending_signals() to process pending signal by calling their handlers

○ Get first timout event in eloop.timeout list, if the timeout fired, call the handler to process the timeout event

○ If reader, writer, exception socekts are changed, skip previous select() results○ Call eloop_sock_table_dispatch() to handle all the set reader, writer, exceptions events

Page 23: Wpa supplicant introduction

Reader, Writer, Exceptions Event Sources● Reader event source

○ ctrl_iface connection○ netlink connection between wpa_supplicant and nl80211○ EAPOL Tx status in wpa_driver_nl80211_drv_init()○ EAPOL socket in i802_init()○ Socket for Monitor mode○ …

● Writer event source○ Dbus watch○ http client

● Exception event source○ Dbus watch