记录wpa_supplicant四次握手的过程。

相关log:https://www.cnblogs.com/helloworldtoyou/p/9633603.html

  1. 接收到第一次握手,会设置一个认证超时时间,根据情况,设置成10s或者70s
  2. 四次握手,如果出错,将会等待这个超时时间后,才会判断认证失败。然后从新连接。
  3. wpa_supplicant/wpa_supplicant.c
  4. void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
  5. const u8 *buf, size_t len)
  6. {
  7. struct wpa_supplicant *wpa_s = ctx;
  8. // 接受到EAPOL帧
  9. wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
  10. wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
  11. #ifdef CONFIG_TESTING_OPTIONS
  12. if (wpa_s->ignore_auth_resp) {
  13. wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
  14. return;
  15. }
  16. #endif /* CONFIG_TESTING_OPTIONS */
  17. #ifdef CONFIG_PEERKEY
  18. if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
  19. wpa_s->current_ssid->peerkey &&
  20. !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
  21. wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
  22. wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
  23. return;
  24. }
  25. #endif /* CONFIG_PEERKEY */
  26. if (wpa_s->wpa_state < WPA_ASSOCIATED ||
  27. (wpa_s->last_eapol_matches_bssid &&
  28. #ifdef CONFIG_AP
  29. !wpa_s->ap_iface &&
  30. #endif /* CONFIG_AP */
  31. os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
  32. /*
  33. * There is possible race condition between receiving the
  34. * association event and the EAPOL frame since they are coming
  35. * through different paths from the driver. In order to avoid
  36. * issues in trying to process the EAPOL frame before receiving
  37. * association information, lets queue it for processing until
  38. * the association event is received. This may also be needed in
  39. * driver-based roaming case, so also use src_addr != BSSID as a
  40. * trigger if we have previously confirmed that the
  41. * Authenticator uses BSSID as the src_addr (which is not the
  42. * case with wired IEEE 802.1X).
  43. */
  44. wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
  45. "of received EAPOL frame (state=%s bssid=" MACSTR ")",
  46. wpa_supplicant_state_txt(wpa_s->wpa_state),
  47. MAC2STR(wpa_s->bssid));
  48. wpabuf_free(wpa_s->pending_eapol_rx);
  49. wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
  50. if (wpa_s->pending_eapol_rx) {
  51. os_get_reltime(&wpa_s->pending_eapol_rx_time);
  52. os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
  53. ETH_ALEN);
  54. }
  55. return;
  56. }
  57. wpa_s->last_eapol_matches_bssid =
  58. os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
  59. #ifdef CONFIG_AP
  60. if (wpa_s->ap_iface) {
  61. wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
  62. return;
  63. }
  64. #endif /* CONFIG_AP */
  65. // 没有配置密钥,退出
  66. if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
  67. wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
  68. "no key management is configured");
  69. return;
  70. }
  71. // 第一次收到EAPOL帧,设置认证超时时间,
  72. if (wpa_s->eapol_received == 0 &&
  73. (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
  74. !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
  75. wpa_s->wpa_state != WPA_COMPLETED) &&
  76. (wpa_s->current_ssid == NULL ||
  77. wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
  78. /* Timeout for completing IEEE 802.1X and WPA authentication */
  79. int timeout = 10; // 认证超时时间10s
  80. if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
  81. wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
  82. wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
  83. /* Use longer timeout for IEEE 802.1X/EAP */
  84. timeout = 70; // 802.1X/EAP认证超时时间设置成70s
  85. }
  86. // WPS相关设置
  87. #ifdef CONFIG_WPS
  88. if (wpa_s->current_ssid && wpa_s->current_bss &&
  89. (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
  90. eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
  91. /*
  92. * Use shorter timeout if going through WPS AP iteration
  93. * for PIN config method with an AP that does not
  94. * advertise Selected Registrar.
  95. */
  96. struct wpabuf *wps_ie;
  97. wps_ie = wpa_bss_get_vendor_ie_multi(
  98. wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
  99. if (wps_ie &&
  100. !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
  101. timeout = 10;
  102. else {
  103. /* We should apply a flexible timeout value,
  104. * becasue some AP which send M2D MSG
  105. * need more time to complete EAP auth,such as Marvell.
  106. * */
  107. timeout = 70;
  108. }
  109. wpabuf_free(wps_ie);
  110. }
  111. #endif /* CONFIG_WPS */
  112. wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0); // 设置认证超时,10s或者70s
  113. }
  114. wpa_s->eapol_received++; // 接受到的EAPOL计数加一
  115. if (wpa_s->countermeasures) {
  116. wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
  117. "EAPOL packet");
  118. return;
  119. }
  120. #ifdef CONFIG_IBSS_RSN
  121. if (wpa_s->current_ssid &&
  122. wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
  123. ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
  124. return;
  125. }
  126. #endif /* CONFIG_IBSS_RSN */
  127. /* Source address of the incoming EAPOL frame could be compared to the
  128. * current BSSID. However, it is possible that a centralized
  129. * Authenticator could be using another MAC address than the BSSID of
  130. * an AP, so just allow any address to be used for now. The replies are
  131. * still sent to the current BSSID (if available), though. */
  132. os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
  133. if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
  134. wpa_s->key_mgmt != WPA_KEY_MGMT_OWE &&
  135. wpa_s->key_mgmt != WPA_KEY_MGMT_DPP &&
  136. eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
  137. return;
  138. wpa_drv_poll(wpa_s);
  139. if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
  140. wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len); // 处理接受的EAPOL帧
  141. else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
  142. /*
  143. * Set portValid = TRUE here since we are going to skip 4-way
  144. * handshake processing which would normally set portValid. We
  145. * need this to allow the EAPOL state machines to be completed
  146. * without going through EAPOL-Key handshake.
  147. */
  148. eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
  149. }
  150. }
  151. src/rsn_supp/wpa.c
  152. int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
  153. const u8 *buf, size_t len)
  154. {
  155. 各种帧内容判断
  156. ...
  157. if (key_info & WPA_KEY_INFO_KEY_TYPE) {
  158. if (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) {
  159. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  160. "WPA: Ignored EAPOL-Key (Pairwise) with "
  161. "non-zero key index");
  162. goto out;
  163. }
  164. if (peerkey) {
  165. /* PeerKey 4-Way Handshake */
  166. peerkey_rx_eapol_4way(sm, peerkey, key, key_info, ver,
  167. key_data, key_data_len);
  168. } else if (key_info & (WPA_KEY_INFO_MIC |
  169. WPA_KEY_INFO_ENCR_KEY_DATA)) {
  170. /* 3/4 4-Way Handshake */ // 第三次握手
  171. wpa_supplicant_process_3_of_4(sm, key, ver, key_data,
  172. key_data_len);
  173. } else {
  174. /* 1/4 4-Way Handshake */ // 第一次握手
  175. wpa_supplicant_process_1_of_4(sm, src_addr, key,
  176. ver, key_data,
  177. key_data_len);
  178. }
  179. } else if (key_info & WPA_KEY_INFO_SMK_MESSAGE) {
  180. /* PeerKey SMK Handshake */
  181. peerkey_rx_eapol_smk(sm, src_addr, key, key_data, key_data_len,
  182. key_info, ver);
  183. } else {
  184. if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) ||
  185. (!mic_len && (key_info & WPA_KEY_INFO_ENCR_KEY_DATA))) {
  186. /* 1/2 Group Key Handshake */
  187. wpa_supplicant_process_1_of_2(sm, src_addr, key,
  188. key_data, key_data_len,
  189. ver);
  190. } else {
  191. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  192. "WPA: EAPOL-Key (Group) without Mic/Encr bit - "
  193. "dropped");
  194. }
  195. }
  196. ...
  197. }
  198. static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
  199. const unsigned char *src_addr,
  200. const struct wpa_eapol_key *key,
  201. u16 ver, const u8 *key_data,
  202. size_t key_data_len)
  203. {
  204. struct wpa_eapol_ie_parse ie;
  205. struct wpa_ptk *ptk;
  206. int res;
  207. u8 *kde, *kde_buf = NULL;
  208. size_t kde_len;
  209. if (wpa_sm_get_network_ctx(sm) == NULL) {
  210. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
  211. "found (msg 1 of 4)");
  212. return;
  213. }
  214. wpa_sm_set_state(sm, WPA_4WAY_HANDSHAKE);
  215. wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: RX message 1 of 4-Way "
  216. "Handshake from " MACSTR " (ver=%d)", MAC2STR(src_addr), ver);
  217. os_memset(&ie, 0, sizeof(ie));
  218. if (sm->proto == WPA_PROTO_RSN || sm->proto == WPA_PROTO_OSEN) {
  219. /* RSN: msg 1/4 should contain PMKID for the selected PMK */
  220. wpa_hexdump(MSG_DEBUG, "RSN: msg 1/4 key data",
  221. key_data, key_data_len);
  222. if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0)
  223. goto failed;
  224. if (ie.pmkid) {
  225. wpa_hexdump(MSG_DEBUG, "RSN: PMKID from "
  226. "Authenticator", ie.pmkid, PMKID_LEN);
  227. }
  228. }
  229. res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
  230. if (res == -2) {
  231. wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Do not reply to "
  232. "msg 1/4 - requesting full EAP authentication");
  233. return;
  234. }
  235. if (res)
  236. goto failed;
  237. if (sm->renew_snonce) {
  238. if (random_get_bytes(sm->snonce, WPA_NONCE_LEN)) {
  239. wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
  240. "WPA: Failed to get random data for SNonce");
  241. goto failed;
  242. }
  243. sm->renew_snonce = 0;
  244. wpa_hexdump(MSG_DEBUG, "WPA: Renewed SNonce",
  245. sm->snonce, WPA_NONCE_LEN);
  246. }
  247. /* Calculate PTK which will be stored as a temporary PTK until it has
  248. * been verified when processing message 3/4. */
  249. ptk = &sm->tptk;
  250. wpa_derive_ptk(sm, src_addr, key, ptk);
  251. if (sm->pairwise_cipher == WPA_CIPHER_TKIP) {
  252. u8 buf[8];
  253. /* Supplicant: swap tx/rx Mic keys */
  254. os_memcpy(buf, &ptk->tk[16], 8);
  255. os_memcpy(&ptk->tk[16], &ptk->tk[24], 8);
  256. os_memcpy(&ptk->tk[24], buf, 8);
  257. os_memset(buf, 0, sizeof(buf));
  258. }
  259. sm->tptk_set = 1;
  260. kde = sm->assoc_wpa_ie;
  261. kde_len = sm->assoc_wpa_ie_len;
  262. ...
  263. // 发送第二次握手的包
  264. if (wpa_supplicant_send_2_of_4(sm, sm->bssid, key, ver, sm->snonce,
  265. kde, kde_len, ptk) < 0)
  266. goto failed;
  267. os_free(kde_buf);
  268. os_memcpy(sm->anonce, key->key_nonce, WPA_NONCE_LEN);
  269. return;
  270. failed:
  271. os_free(kde_buf);
  272. wpa_sm_deauthenticate(sm, WLAN_REASON_UNSPECIFIED);
  273. }

Liutao

2018-11-22

Android wpa_supplicant 四次握手 流程分析的更多相关文章

  1. TCP/IP协议三次握手与四次握手流程解析

    原文链接地址:http://www.2cto.com/net/201310/251896.html TCP/IP协议三次握手与四次握手流程解析 TCP/IP协议的详细信息参看<TCP/IP协议详 ...

  2. TCP/IP协议三次握手与四次握手流程解析(转载及总结)

    原文地址:http://www.2cto.com/net/201310/251896.html,转载请注明出处: TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式  TCP/IP协议的详 ...

  3. Android 4.4 音量调节流程分析(二)

    之前在Android 4.4 音量调节流程分析(一)里已经有简单的分析音量控制的流程,今天想接着继续分析下音量大小计算的方法.对于任一播放文件而言其本身都有着固定大小的音量Volume_Max,而在A ...

  4. Android 7.1 屏幕旋转流程分析

    Android 7.1   屏幕旋转流程分析 一.概述 Android屏幕的旋转在framework主要涉及到三个类,结构如图 PhoneWindowManager:为屏幕的横竖屏转换的管理类. Wi ...

  5. TCP/IP协议三次握手与四次握手流程解析(转)

    一.TCP报文格式   下面是TCP报文格式图:       上图中有几个字段需要重点介绍下:  (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标 ...

  6. 【协议】2、TCP/IP协议三次握手与四次握手流程解析

    一.TCP报文格式  TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图:图1 TCP报文格式  上图中有几个字段需要重点介绍下:  (1)序号:Seq序 ...

  7. PPTP协议握手流程分析

    一  PPTP概述 PPTP(Point to Point Tunneling Protocol),即点对点隧道协议.该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网,可 ...

  8. Android之 MTP框架和流程分析

    概要 本文的目的是介绍Android系统中MTP的一些相关知识.主要的内容包括:第1部分 MTP简介            对Mtp协议进行简单的介绍.第2部分 MTP框架            介绍 ...

  9. PPTP协议握手流程分析--转载

    一  PPTP概述   PPTP(Point to Point Tunneling Protocol),即点对点隧道协议.该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用网 ...

随机推荐

  1. BZOJ.4766.文艺计算姬(Prufer)

    题目链接 这是完全二分图,那么在构造Prufer序列时,最后会剩下两个点,两点的边是连接两个集合的,这两个点自然分属两个集合 那么集合A被删了m-1次,每次从n个点中选:B被删了n-1次,每次都可以从 ...

  2. POJ 3243 Clever Y 扩展BSGS

    http://poj.org/problem?id=3243 这道题的输入数据输入后需要将a和b都%p https://blog.csdn.net/zzkksunboy/article/details ...

  3. CODEVS.1228 苹果树(DFS序)

    To CODEVS.1228 苹果树  To poj 3321 Description 在卡卡的房子外面,有一棵苹果树.每年的春天,树上总会结出很多的苹果.卡卡非常喜欢吃苹果,所以他一直都精心的呵护这 ...

  4. [SNOI2017]一个简单的询问

    [SNOI2017]一个简单的询问 题目大意: 给定一个长度为\(n(n\le50000)\)的序列\(A(1\le A_i\le n)\),定义\(\operatorname{get}(l,r,x) ...

  5. AngularJS中介者模式实例

    在任何应用程序中,中介者模式随处可见. → 有一个事件源,触发事件,传递参数→ 中介者记下这个事件,向外界广播,并带上参赛→ 有一个地方侦听中介者事件,一旦事件源触发事件,就从中介者手里获取事件相关参 ...

  6. SpringBoot自定义线程池处理异步任务

    @Async异步调用 就不解释什么是异步调用了,Spring Boot中进行异步调用很简单 1.通过使用@Async注解就能简单的将原来的同步函数变为异步函数 package com.winner.s ...

  7. 【.NET线程--进阶(一)】--线程方法详解

    上篇博客从线程的基本概况开始着重讨论了线程,进程,程序之间的区别,然后讨论了线程操作的几个类,并通过实例来说明了线程的创建方法.本篇博客将会带大家更深入的了解线程,介绍线程的基本方法,并通过一个Dem ...

  8. iOS开发-命令模式

    命令模式算是设计模式中比较简单的,最常见的例子是工作任务安排下来进行编程,如果工作任务不需要完成,我们可以取消我们之前完成的代码,也可以理解为回滚撤销操作.这里面涉及到命令模式中的两个对象,一个是动作 ...

  9. install pymongo,mysql

    yum install pymongo yum install MySQL-python

  10. how to check the computer is 32 bit or 64bit in linux

    just use cat /proc/cpuinfo in shell