4.5 wpa_supplicant连接无线网络分析

最后更新于:2022-04-02 06:03:18

本节将介绍本章第二条分析路线,即通过命令行发送命令的方式触发wpa_supplicant进行相关工作,使手机加入一个利用WPA-PSK进行认证的无线网络。 以笔者的Note 2为例,整个过程用到的命令如下所示。 **命令示例** ~~~ adb root #获取手机root用户权限。只有root被破解的手机才能成功 adb shell #登录手机shell #笔者事先已编译wpa_cli并将其放到/system/bin目录中。这个命令用于启动wpa_cli,-i参数指明unix域控制 #socket文件名,它应该和wpa_supplicant启动时设置的控制接口文件名一致 wpa_cli -iwlan0 #该命令执行后,将进入wpa_cli进程,后续操作都在此进程中开展 #发送ADD_NETWORK命令给wpa_supplicant,它将返回一个新网络配置项的编号。请参考4.3.3.1"wpas_ssid结构 #体介绍"一节 ADD_NETWORK #假设wpa_supplicant返回的新网络配置项编号为0 SET_NETWORK 0 ssid "Test" #设置0号网络的ssid为“Test” SET_NETWORK 0 key_mgmt WPA-PSK #设置0号网络的key_mgmt为“WPA-PSK” SET_NETWORK 0 psk "12345Test" #设置0号网络的psk为“12345Test” ENABLE_NETWORK 0 #使能0号网络,它将触发wpa_supplicant扫描、关联等一系列操作直到加入无线网络“Test” CTRL+C #退出wpa_cli dhcpcd wlan0 #启动dhcpd,wlan0为无线接口设备名。dhcpcd可为手机从AP那获取一个IP地址 ~~~ dhcpcd成功执行后,手机将从AP那分配到一个IP地址。至此,手机就可以使用“Test”无线网络了。 注意:上述命令执行前有几个注意事项: 1. 先要在Settings中开启无线网络。这个操作完成了wlan驱动及相应固件加载的工作。该工作实际上由netd来完成,而wpa_cli无法完成它。 2. 开启无线网络后,WifiService和wpa_supplicant都开始工作了。为了避免WifiService的干扰,可以把Settings中的那些已知的无线网络信息都清除。 3. 由于wpa_supplicant支持多个客户端,所以wpa_cli可以和WifiService共同工作。只要不操作Settings中无线网络相关的选项,WifiService就不会干扰wpa_cli。 4. 然后按上述步骤执行wpa_cli。 根据前文所述,所有来自客户端的命令都由wpa_supplicant_ctrl_iface_receive函数处理(参考4.3.4中“wpa_supplicant_ctrl_iface_init介绍”一节)。该函数代码非常简单,就是根据客户端发送的命令进行对应处理。 **ctrl_iface_unix.c::wpa_supplicant_ctrl_iface_receive** ~~~ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,void *sock_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; struct ctrl_iface_priv *priv = sock_ctx; char buf[4096]; int res; struct sockaddr_un from; socklen_t fromlen = sizeof(from); char *reply = NULL; size_t reply_len = 0; int new_attached = 0; res = recvfrom(sock, buf, sizeof(buf) - 1, 0,(struct sockaddr *) &from, &fromlen); ..... buf[res] = '\0'; //客户端第一次和WPAS连接时,需要发送"ATTACH"命令 if (os_strcmp(buf, "ATTACH") == 0) { ......//略过相关处理 } .....//"DETACH"和"LEVEL"命令处理 else { #if defined(CONFIG_P2P) && defined(ANDROID_P2P) ......//P2P处理。虽然WPAS编译时打开了CONFIG_P2P和ANDROID_P2P,但本章不讨论P2P相关的内容 #endif //大部分的命令处理都在wpa_supplicant_ctrl_iface_process函数中 reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,&reply_len); } if (reply) {//回复客户端 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,fromlen); os_free(reply); } ...... /* Client成功ATTACH后,将通知EAPOL模块。因为有些认证流程需要用户的参与(例如输入密码之类的), 所以当客户端连接上后,EAPOL模块将判断是否需要和客户端交互。读者可阅读 eapol_sm_notify_ctrl_attached函数。 */ if (new_attached) eapol_sm_notify_ctrl_attached(wpa_s->eapol); } ~~~ 如上述代码所示,绝大部分命令都由wpa_supplicant_ctrl_iface_process函数处理。下面将按顺序来分析其处理ADD_NETWORK、SET_NETWORK以及ENABLE_NETWORK的代码。
';