Guest User

Untitled

a guest
May 22nd, 2018
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.50 KB | None | 0 0
  1. /*
  2. * WPA Supplicant / Control interface (shared code for all backends)
  3. * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
  4. *
  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.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14.  
  15. #include "includes.h"
  16.  
  17. #include "common.h"
  18. #include "eloop.h"
  19. #include "wpa.h"
  20. #include "wpa_supplicant.h"
  21. #include "config.h"
  22. #include "eapol_sm.h"
  23. #include "wpa_supplicant_i.h"
  24. #include "ctrl_iface.h"
  25. #include "l2_packet.h"
  26. #include "preauth.h"
  27. #include "pmksa_cache.h"
  28. #include "wpa_ctrl.h"
  29. #include "eap.h"
  30.  
  31.  
  32. static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
  33. char *buf, int len);
  34.  
  35.  
  36. static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
  37. char *cmd)
  38. {
  39. char *value;
  40. int ret = 0;
  41.  
  42. value = os_strchr(cmd, ' ');
  43. if (value == NULL)
  44. return -1;
  45. *value++ = '\0';
  46.  
  47. wpa_printf(MSG_DEBUG, "CTRL_IFACE SET '%s'='%s'", cmd, value);
  48. if (os_strcasecmp(cmd, "EAPOL::heldPeriod") == 0) {
  49. eapol_sm_configure(wpa_s->eapol,
  50. atoi(value), -1, -1, -1);
  51. } else if (os_strcasecmp(cmd, "EAPOL::authPeriod") == 0) {
  52. eapol_sm_configure(wpa_s->eapol,
  53. -1, atoi(value), -1, -1);
  54. } else if (os_strcasecmp(cmd, "EAPOL::startPeriod") == 0) {
  55. eapol_sm_configure(wpa_s->eapol,
  56. -1, -1, atoi(value), -1);
  57. } else if (os_strcasecmp(cmd, "EAPOL::maxStart") == 0) {
  58. eapol_sm_configure(wpa_s->eapol,
  59. -1, -1, -1, atoi(value));
  60. } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKLifetime") == 0) {
  61. if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
  62. atoi(value)))
  63. ret = -1;
  64. } else if (os_strcasecmp(cmd, "dot11RSNAConfigPMKReauthThreshold") ==
  65. 0) {
  66. if (wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
  67. atoi(value)))
  68. ret = -1;
  69. } else if (os_strcasecmp(cmd, "dot11RSNAConfigSATimeout") == 0) {
  70. if (wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT, atoi(value)))
  71. ret = -1;
  72. } else
  73. ret = -1;
  74.  
  75. return ret;
  76. }
  77.  
  78.  
  79. #ifdef IEEE8021X_EAPOL
  80. static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
  81. char *addr)
  82. {
  83. u8 bssid[ETH_ALEN];
  84.  
  85. if (hwaddr_aton(addr, bssid)) {
  86. wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH: invalid address "
  87. "'%s'", addr);
  88. return -1;
  89. }
  90.  
  91. wpa_printf(MSG_DEBUG, "CTRL_IFACE PREAUTH " MACSTR, MAC2STR(bssid));
  92. rsn_preauth_deinit(wpa_s->wpa);
  93. if (rsn_preauth_init(wpa_s->wpa, bssid, wpa_s->current_ssid))
  94. return -1;
  95.  
  96. return 0;
  97. }
  98. #endif /* IEEE8021X_EAPOL */
  99.  
  100.  
  101. #ifdef CONFIG_PEERKEY
  102. /* MLME-STKSTART.request(peer) */
  103. static int wpa_supplicant_ctrl_iface_stkstart(
  104. struct wpa_supplicant *wpa_s, char *addr)
  105. {
  106. u8 peer[ETH_ALEN];
  107.  
  108. if (hwaddr_aton(addr, peer)) {
  109. wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART: invalid "
  110. "address '%s'", peer);
  111. return -1;
  112. }
  113.  
  114. wpa_printf(MSG_DEBUG, "CTRL_IFACE STKSTART " MACSTR,
  115. MAC2STR(peer));
  116.  
  117. return wpa_sm_stkstart(wpa_s->wpa, peer);
  118. }
  119. #endif /* CONFIG_PEERKEY */
  120.  
  121.  
  122. static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
  123. char *rsp)
  124. {
  125. #ifdef IEEE8021X_EAPOL
  126. char *pos, *id_pos;
  127. int id;
  128. struct wpa_ssid *ssid;
  129.  
  130. pos = os_strchr(rsp, '-');
  131. if (pos == NULL)
  132. return -1;
  133. *pos++ = '\0';
  134. id_pos = pos;
  135. pos = os_strchr(pos, ':');
  136. if (pos == NULL)
  137. return -1;
  138. *pos++ = '\0';
  139. id = atoi(id_pos);
  140. wpa_printf(MSG_DEBUG, "CTRL_IFACE: field=%s id=%d", rsp, id);
  141. wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
  142. (u8 *) pos, os_strlen(pos));
  143.  
  144. ssid = wpa_config_get_network(wpa_s->conf, id);
  145. if (ssid == NULL) {
  146. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
  147. "to update", id);
  148. return -1;
  149. }
  150.  
  151. if (os_strcmp(rsp, "IDENTITY") == 0) {
  152. os_free(ssid->identity);
  153. ssid->identity = (u8 *) os_strdup(pos);
  154. ssid->identity_len = os_strlen(pos);
  155. ssid->pending_req_identity = 0;
  156. if (ssid == wpa_s->current_ssid)
  157. wpa_s->reassociate = 1;
  158. } else if (os_strcmp(rsp, "PASSWORD") == 0) {
  159. os_free(ssid->password);
  160. ssid->password = (u8 *) os_strdup(pos);
  161. ssid->password_len = os_strlen(pos);
  162. ssid->pending_req_password = 0;
  163. if (ssid == wpa_s->current_ssid)
  164. wpa_s->reassociate = 1;
  165. } else if (os_strcmp(rsp, "NEW_PASSWORD") == 0) {
  166. os_free(ssid->new_password);
  167. ssid->new_password = (u8 *) os_strdup(pos);
  168. ssid->new_password_len = os_strlen(pos);
  169. ssid->pending_req_new_password = 0;
  170. if (ssid == wpa_s->current_ssid)
  171. wpa_s->reassociate = 1;
  172. } else if (os_strcmp(rsp, "PIN") == 0) {
  173. os_free(ssid->pin);
  174. ssid->pin = os_strdup(pos);
  175. ssid->pending_req_pin = 0;
  176. if (ssid == wpa_s->current_ssid)
  177. wpa_s->reassociate = 1;
  178. } else if (os_strcmp(rsp, "OTP") == 0) {
  179. os_free(ssid->otp);
  180. ssid->otp = (u8 *) os_strdup(pos);
  181. ssid->otp_len = os_strlen(pos);
  182. os_free(ssid->pending_req_otp);
  183. ssid->pending_req_otp = NULL;
  184. ssid->pending_req_otp_len = 0;
  185. } else if (os_strcmp(rsp, "PASSPHRASE") == 0) {
  186. os_free(ssid->private_key_passwd);
  187. ssid->private_key_passwd = (u8 *) os_strdup(pos);
  188. ssid->pending_req_passphrase = 0;
  189. if (ssid == wpa_s->current_ssid)
  190. wpa_s->reassociate = 1;
  191. } else {
  192. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", rsp);
  193. return -1;
  194. }
  195.  
  196. return 0;
  197. #else /* IEEE8021X_EAPOL */
  198. wpa_printf(MSG_DEBUG, "CTRL_IFACE: 802.1X not included");
  199. return -1;
  200. #endif /* IEEE8021X_EAPOL */
  201. }
  202.  
  203.  
  204. static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
  205. const char *params,
  206. char *buf, size_t buflen)
  207. {
  208. char *pos, *end, tmp[30];
  209. int res, verbose, ret;
  210.  
  211. verbose = os_strcmp(params, "-VERBOSE") == 0;
  212. pos = buf;
  213. end = buf + buflen;
  214. if (wpa_s->wpa_state >= WPA_ASSOCIATED) {
  215. struct wpa_ssid *ssid = wpa_s->current_ssid;
  216. ret = os_snprintf(pos, end - pos, "bssid=" MACSTR "\n",
  217. MAC2STR(wpa_s->bssid));
  218. if (ret < 0 || ret >= end - pos)
  219. return pos - buf;
  220. pos += ret;
  221. if (ssid) {
  222. u8 *_ssid = ssid->ssid;
  223. size_t ssid_len = ssid->ssid_len;
  224. u8 ssid_buf[MAX_SSID_LEN];
  225. if (ssid_len == 0) {
  226. int _res = wpa_drv_get_ssid(wpa_s, ssid_buf);
  227. if (_res < 0)
  228. ssid_len = 0;
  229. else
  230. ssid_len = _res;
  231. _ssid = ssid_buf;
  232. }
  233. ret = os_snprintf(pos, end - pos, "ssid=%s\nid=%d\n",
  234. wpa_ssid_txt(_ssid, ssid_len),
  235. ssid->id);
  236. if (ret < 0 || ret >= end - pos)
  237. return pos - buf;
  238. pos += ret;
  239.  
  240. if (ssid->id_str) {
  241. ret = os_snprintf(pos, end - pos,
  242. "id_str=%s\n",
  243. ssid->id_str);
  244. if (ret < 0 || ret >= end - pos)
  245. return pos - buf;
  246. pos += ret;
  247. }
  248. }
  249.  
  250. pos += wpa_sm_get_status(wpa_s->wpa, pos, end - pos, verbose);
  251. }
  252. ret = os_snprintf(pos, end - pos, "wpa_state=%s\n",
  253. wpa_supplicant_state_txt(wpa_s->wpa_state));
  254. if (ret < 0 || ret >= end - pos)
  255. return pos - buf;
  256. pos += ret;
  257.  
  258. if (wpa_s->l2 &&
  259. l2_packet_get_ip_addr(wpa_s->l2, tmp, sizeof(tmp)) >= 0) {
  260. ret = os_snprintf(pos, end - pos, "ip_address=%s\n", tmp);
  261. if (ret < 0 || ret >= end - pos)
  262. return pos - buf;
  263. pos += ret;
  264. }
  265.  
  266. if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
  267. wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
  268. res = eapol_sm_get_status(wpa_s->eapol, pos, end - pos,
  269. verbose);
  270. if (res >= 0)
  271. pos += res;
  272. }
  273.  
  274. res = rsn_preauth_get_status(wpa_s->wpa, pos, end - pos, verbose);
  275. if (res >= 0)
  276. pos += res;
  277.  
  278. return pos - buf;
  279. }
  280.  
  281.  
  282. static int wpa_supplicant_ctrl_iface_bssid(struct wpa_supplicant *wpa_s,
  283. char *cmd)
  284. {
  285. char *pos;
  286. int id;
  287. struct wpa_ssid *ssid;
  288. u8 bssid[ETH_ALEN];
  289.  
  290. /* cmd: "<network id> <BSSID>" */
  291. pos = os_strchr(cmd, ' ');
  292. if (pos == NULL)
  293. return -1;
  294. *pos++ = '\0';
  295. id = atoi(cmd);
  296. wpa_printf(MSG_DEBUG, "CTRL_IFACE: id=%d bssid='%s'", id, pos);
  297. if (hwaddr_aton(pos, bssid)) {
  298. wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", pos);
  299. return -1;
  300. }
  301.  
  302. ssid = wpa_config_get_network(wpa_s->conf, id);
  303. if (ssid == NULL) {
  304. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find SSID id=%d "
  305. "to update", id);
  306. return -1;
  307. }
  308.  
  309. os_memcpy(ssid->bssid, bssid, ETH_ALEN);
  310. ssid->bssid_set =
  311. os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0;
  312.  
  313.  
  314. return 0;
  315. }
  316.  
  317. #ifdef ANDROID
  318. static int wpa_supplicant_ctrl_iface_blacklist(
  319. struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
  320. {
  321. struct wpa_ssid *ssid;
  322. u8 bssid[ETH_ALEN];
  323. struct wpa_blacklist *e;
  324. char *pos, *end;
  325. int ret;
  326.  
  327. /* cmd: "BLACKLIST [<BSSID>]" */
  328. if (*cmd == '\0') {
  329. pos = buf;
  330. end = buf + buflen;
  331.  
  332. e = wpa_s->blacklist;
  333. while (e) {
  334. ret = os_snprintf(pos, end-pos,
  335. "%02x:%02x:%02x:%02x:%02x:%02x\n",
  336. e->bssid[0],
  337. e->bssid[1],
  338. e->bssid[2],
  339. e->bssid[3],
  340. e->bssid[4],
  341. e->bssid[5]);
  342. if (ret < 0 || ret >= end - pos)
  343. return pos - buf;
  344. pos += ret;
  345. e = e->next;
  346. }
  347. return pos - buf;
  348. }
  349. wpa_printf(MSG_DEBUG, "CTRL_IFACE: bssid='%s'", cmd);
  350.  
  351. ++cmd;
  352. if (os_strncmp(cmd, "clear", 5) == 0) {
  353. wpa_blacklist_clear(wpa_s);
  354. return 0;
  355. }
  356.  
  357. if (hwaddr_aton(cmd, bssid)) {
  358. wpa_printf(MSG_DEBUG ,"CTRL_IFACE: invalid BSSID '%s'", cmd);
  359. return -1;
  360. }
  361.  
  362. /*
  363. * Add the BSSID twice, so its count will be 2, causing it to be
  364. * skipped when processing scan results.
  365. */
  366. ret = wpa_blacklist_add(wpa_s, bssid);
  367. if (ret != 0)
  368. return ret;
  369. return wpa_blacklist_add(wpa_s, bssid);
  370. }
  371. #endif
  372.  
  373. static int wpa_supplicant_ctrl_iface_list_networks(
  374. struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
  375. {
  376. char *pos, *end;
  377. struct wpa_ssid *ssid;
  378. int ret;
  379.  
  380. pos = buf;
  381. end = buf + buflen;
  382. ret = os_snprintf(pos, end - pos,
  383. "network id / ssid / bssid / flags\n");
  384. if (ret < 0 || ret >= end - pos)
  385. return pos - buf;
  386. pos += ret;
  387.  
  388. ssid = wpa_s->conf->ssid;
  389. while (ssid) {
  390. ret = os_snprintf(pos, end - pos, "%d\t%s",
  391. ssid->id,
  392. wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
  393. if (ret < 0 || ret >= end - pos)
  394. return pos - buf;
  395. pos += ret;
  396. if (ssid->bssid_set) {
  397. ret = os_snprintf(pos, end - pos, "\t" MACSTR,
  398. MAC2STR(ssid->bssid));
  399. } else {
  400. ret = os_snprintf(pos, end - pos, "\tany");
  401. }
  402. if (ret < 0 || ret >= end - pos)
  403. return pos - buf;
  404. pos += ret;
  405. ret = os_snprintf(pos, end - pos, "\t%s%s",
  406. ssid == wpa_s->current_ssid ?
  407. "[CURRENT]" : "",
  408. ssid->disabled ? "[DISABLED]" : "");
  409. if (ret < 0 || ret >= end - pos)
  410. return pos - buf;
  411. pos += ret;
  412. ret = os_snprintf(pos, end - pos, "\n");
  413. if (ret < 0 || ret >= end - pos)
  414. return pos - buf;
  415. pos += ret;
  416.  
  417. ssid = ssid->next;
  418. }
  419.  
  420. return pos - buf;
  421. }
  422.  
  423.  
  424. static char * wpa_supplicant_cipher_txt(char *pos, char *end, int cipher)
  425. {
  426. int first = 1, ret;
  427. ret = os_snprintf(pos, end - pos, "-");
  428. if (ret < 0 || ret >= end - pos)
  429. return pos;
  430. pos += ret;
  431. if (cipher & WPA_CIPHER_NONE) {
  432. ret = os_snprintf(pos, end - pos, "%sNONE", first ? "" : "+");
  433. if (ret < 0 || ret >= end - pos)
  434. return pos;
  435. pos += ret;
  436. first = 0;
  437. }
  438. if (cipher & WPA_CIPHER_WEP40) {
  439. ret = os_snprintf(pos, end - pos, "%sWEP40", first ? "" : "+");
  440. if (ret < 0 || ret >= end - pos)
  441. return pos;
  442. pos += ret;
  443. first = 0;
  444. }
  445. if (cipher & WPA_CIPHER_WEP104) {
  446. ret = os_snprintf(pos, end - pos, "%sWEP104",
  447. first ? "" : "+");
  448. if (ret < 0 || ret >= end - pos)
  449. return pos;
  450. pos += ret;
  451. first = 0;
  452. }
  453. if (cipher & WPA_CIPHER_TKIP) {
  454. ret = os_snprintf(pos, end - pos, "%sTKIP", first ? "" : "+");
  455. if (ret < 0 || ret >= end - pos)
  456. return pos;
  457. pos += ret;
  458. first = 0;
  459. }
  460. if (cipher & WPA_CIPHER_CCMP) {
  461. ret = os_snprintf(pos, end - pos, "%sCCMP", first ? "" : "+");
  462. if (ret < 0 || ret >= end - pos)
  463. return pos;
  464. pos += ret;
  465. first = 0;
  466. }
  467. return pos;
  468. }
  469.  
  470.  
  471. static char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
  472. const u8 *ie, size_t ie_len)
  473. {
  474. struct wpa_ie_data data;
  475. int first, ret;
  476.  
  477. ret = os_snprintf(pos, end - pos, "[%s-", proto);
  478. if (ret < 0 || ret >= end - pos)
  479. return pos;
  480. pos += ret;
  481.  
  482. if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
  483. ret = os_snprintf(pos, end - pos, "?]");
  484. if (ret < 0 || ret >= end - pos)
  485. return pos;
  486. pos += ret;
  487. return pos;
  488. }
  489.  
  490. first = 1;
  491. if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
  492. ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
  493. if (ret < 0 || ret >= end - pos)
  494. return pos;
  495. pos += ret;
  496. first = 0;
  497. }
  498. if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
  499. ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
  500. if (ret < 0 || ret >= end - pos)
  501. return pos;
  502. pos += ret;
  503. first = 0;
  504. }
  505. if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
  506. ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
  507. if (ret < 0 || ret >= end - pos)
  508. return pos;
  509. pos += ret;
  510. first = 0;
  511. }
  512.  
  513. pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
  514.  
  515. if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
  516. ret = os_snprintf(pos, end - pos, "-preauth");
  517. if (ret < 0 || ret >= end - pos)
  518. return pos;
  519. pos += ret;
  520. }
  521.  
  522. ret = os_snprintf(pos, end - pos, "]");
  523. if (ret < 0 || ret >= end - pos)
  524. return pos;
  525. pos += ret;
  526.  
  527. return pos;
  528. }
  529.  
  530.  
  531. static int wpa_supplicant_ctrl_iface_scan_results(
  532. struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
  533. {
  534. char *pos, *end, *retpos;
  535. struct wpa_scan_result *res;
  536. int i, ret;
  537.  
  538. if (wpa_s->scan_results == NULL &&
  539. wpa_supplicant_get_scan_results(wpa_s) < 0)
  540. return 0;
  541. if (wpa_s->scan_results == NULL)
  542. return 0;
  543.  
  544. pos = buf;
  545. end = buf + buflen;
  546. ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
  547. "flags / ssid\n");
  548. if (ret < 0 || ret >= end - pos)
  549. return pos - buf;
  550. pos += ret;
  551.  
  552. for (i = 0; i < wpa_s->num_scan_results; i++) {
  553. retpos = pos;
  554. res = &wpa_s->scan_results[i];
  555. ret = os_snprintf(pos, end - pos, MACSTR "\t%d\t%d\t",
  556. MAC2STR(res->bssid), res->freq, res->level);
  557. if (ret < 0 || ret >= end - pos)
  558. return retpos - buf;
  559. pos += ret;
  560. if (res->wpa_ie_len) {
  561. pos = wpa_supplicant_ie_txt(pos, end, "WPA",
  562. res->wpa_ie,
  563. res->wpa_ie_len);
  564. }
  565. if (res->rsn_ie_len) {
  566. pos = wpa_supplicant_ie_txt(pos, end, "WPA2",
  567. res->rsn_ie,
  568. res->rsn_ie_len);
  569. }
  570. if (!res->wpa_ie_len && !res->rsn_ie_len &&
  571. res->caps & IEEE80211_CAP_PRIVACY) {
  572. ret = os_snprintf(pos, end - pos, "[WEP]");
  573. if (ret < 0 || ret >= end - pos)
  574. return retpos - buf;
  575. pos += ret;
  576. }
  577. if (res->caps & IEEE80211_CAP_IBSS) {
  578. ret = os_snprintf(pos, end - pos, "[IBSS]");
  579. if (ret < 0 || ret >= end - pos)
  580. return retpos - buf;
  581. pos += ret;
  582. }
  583. if (!res->wpa_ie_len && !res->rsn_ie_len) {
  584. ret = os_snprintf(pos, end - pos, "\t");
  585. if (ret < 0 || ret >= end - pos)
  586. return retpos - buf;
  587. pos += ret;
  588. }
  589.  
  590. ret = os_snprintf(pos, end - pos, "\t%s",
  591. wpa_ssid_txt(res->ssid, res->ssid_len));
  592. if (ret < 0 || ret >= end - pos)
  593. return retpos - buf;
  594. pos += ret;
  595.  
  596. ret = os_snprintf(pos, end - pos, "\n");
  597. if (ret < 0 || ret >= end - pos)
  598. return retpos - buf;
  599. pos += ret;
  600. }
  601.  
  602. return pos - buf;
  603. }
  604.  
  605.  
  606. static int wpa_supplicant_ctrl_iface_select_network(
  607. struct wpa_supplicant *wpa_s, char *cmd)
  608. {
  609. int id;
  610. struct wpa_ssid *ssid;
  611.  
  612. /* cmd: "<network id>" or "any" */
  613. if (os_strcmp(cmd, "any") == 0) {
  614. wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK any");
  615. ssid = wpa_s->conf->ssid;
  616. while (ssid) {
  617. ssid->disabled = 0;
  618. ssid = ssid->next;
  619. }
  620. wpa_s->reassociate = 1;
  621. wpa_supplicant_req_scan(wpa_s, 0, 0);
  622. return 0;
  623. }
  624.  
  625. id = atoi(cmd);
  626. wpa_printf(MSG_DEBUG, "CTRL_IFACE: SELECT_NETWORK id=%d", id);
  627.  
  628. ssid = wpa_config_get_network(wpa_s->conf, id);
  629. if (ssid == NULL) {
  630. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
  631. "id=%d", id);
  632. return -1;
  633. }
  634.  
  635. if (ssid != wpa_s->current_ssid && wpa_s->current_ssid)
  636. wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
  637.  
  638. /* Mark all other networks disabled and trigger reassociation */
  639. ssid = wpa_s->conf->ssid;
  640. while (ssid) {
  641. ssid->disabled = id != ssid->id;
  642. ssid = ssid->next;
  643. }
  644. wpa_s->reassociate = 1;
  645. wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
  646. wpa_supplicant_req_scan(wpa_s, 0, 0);
  647.  
  648. return 0;
  649. }
  650.  
  651.  
  652. static int wpa_supplicant_ctrl_iface_enable_network(
  653. struct wpa_supplicant *wpa_s, char *cmd)
  654. {
  655. int id;
  656. struct wpa_ssid *ssid;
  657.  
  658. /* cmd: "<network id>" */
  659. id = atoi(cmd);
  660. wpa_printf(MSG_DEBUG, "CTRL_IFACE: ENABLE_NETWORK id=%d", id);
  661.  
  662. ssid = wpa_config_get_network(wpa_s->conf, id);
  663. if (ssid == NULL) {
  664. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
  665. "id=%d", id);
  666. return -1;
  667. }
  668.  
  669. if (wpa_s->current_ssid == NULL && ssid->disabled) {
  670. /*
  671. * Try to reassociate since there is no current configuration
  672. * and a new network was made available. */
  673. wpa_s->reassociate = 1;
  674. #ifdef ANDROID
  675. wpa_supplicant_req_scan(wpa_s, 2, 0);
  676. #else
  677. wpa_supplicant_req_scan(wpa_s, 0, 0);
  678. #endif
  679. }
  680. ssid->disabled = 0;
  681.  
  682. return 0;
  683. }
  684.  
  685.  
  686. static int wpa_supplicant_ctrl_iface_disable_network(
  687. struct wpa_supplicant *wpa_s, char *cmd)
  688. {
  689. int id;
  690. struct wpa_ssid *ssid;
  691.  
  692. /* cmd: "<network id>" */
  693. id = atoi(cmd);
  694. wpa_printf(MSG_DEBUG, "CTRL_IFACE: DISABLE_NETWORK id=%d", id);
  695.  
  696. ssid = wpa_config_get_network(wpa_s->conf, id);
  697. if (ssid == NULL) {
  698. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
  699. "id=%d", id);
  700. return -1;
  701. }
  702.  
  703. if (ssid == wpa_s->current_ssid)
  704. wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
  705. ssid->disabled = 1;
  706.  
  707. return 0;
  708. }
  709.  
  710.  
  711. static int wpa_supplicant_ctrl_iface_add_network(
  712. struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
  713. {
  714. struct wpa_ssid *ssid;
  715. int ret;
  716.  
  717. wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_NETWORK");
  718.  
  719. ssid = wpa_config_add_network(wpa_s->conf);
  720. if (ssid == NULL)
  721. return -1;
  722. ssid->disabled = 1;
  723. wpa_config_set_network_defaults(ssid);
  724.  
  725. ret = os_snprintf(buf, buflen, "%d\n", ssid->id);
  726. if (ret < 0 || (size_t) ret >= buflen)
  727. return -1;
  728. return ret;
  729. }
  730.  
  731.  
  732. static int wpa_supplicant_ctrl_iface_remove_network(
  733. struct wpa_supplicant *wpa_s, char *cmd)
  734. {
  735. int id;
  736. struct wpa_ssid *ssid;
  737.  
  738. /* cmd: "<network id>" */
  739. id = atoi(cmd);
  740. wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);
  741.  
  742. ssid = wpa_config_get_network(wpa_s->conf, id);
  743. if (ssid == NULL ||
  744. wpa_config_remove_network(wpa_s->conf, id) < 0) {
  745. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
  746. "id=%d", id);
  747. return -1;
  748. }
  749.  
  750. if (ssid == wpa_s->current_ssid) {
  751. /*
  752. * Invalidate the EAP session cache if the current network is
  753. * removed.
  754. */
  755. eapol_sm_invalidate_cached_session(wpa_s->eapol);
  756.  
  757. wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
  758. }
  759.  
  760. return 0;
  761. }
  762.  
  763.  
  764. static int wpa_supplicant_ctrl_iface_set_network(
  765. struct wpa_supplicant *wpa_s, char *cmd)
  766. {
  767. int id;
  768. struct wpa_ssid *ssid;
  769. char *name, *value;
  770.  
  771. /* cmd: "<network id> <variable name> <value>" */
  772. name = os_strchr(cmd, ' ');
  773. if (name == NULL)
  774. return -1;
  775. *name++ = '\0';
  776.  
  777. value = os_strchr(name, ' ');
  778. if (value == NULL)
  779. return -1;
  780. *value++ = '\0';
  781.  
  782. id = atoi(cmd);
  783. wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_NETWORK id=%d name='%s'",
  784. id, name);
  785. wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
  786. (u8 *) value, os_strlen(value));
  787.  
  788. ssid = wpa_config_get_network(wpa_s->conf, id);
  789. if (ssid == NULL) {
  790. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
  791. "id=%d", id);
  792. return -1;
  793. }
  794.  
  795. if (wpa_config_set(ssid, name, value, 0) < 0) {
  796. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set network "
  797. "variable '%s'", name);
  798. return -1;
  799. } else {
  800. if (os_strcmp(name, "priority") == 0) {
  801. wpa_config_update_prio_list(wpa_s->conf);
  802. }
  803. }
  804.  
  805. if (wpa_s->current_ssid == ssid) {
  806. /*
  807. * Invalidate the EAP session cache if anything in the current
  808. * configuration changes.
  809. */
  810. eapol_sm_invalidate_cached_session(wpa_s->eapol);
  811. }
  812.  
  813. if ((os_strcmp(name, "psk") == 0 &&
  814. value[0] == '"' && ssid->ssid_len) ||
  815. (os_strcmp(name, "ssid") == 0 && ssid->passphrase))
  816. wpa_config_update_psk(ssid);
  817.  
  818. return 0;
  819. }
  820.  
  821.  
  822. static int wpa_supplicant_ctrl_iface_get_network(
  823. struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
  824. {
  825. int id;
  826. struct wpa_ssid *ssid;
  827. char *name, *value;
  828.  
  829. /* cmd: "<network id> <variable name>" */
  830. name = os_strchr(cmd, ' ');
  831. if (name == NULL || buflen == 0)
  832. return -1;
  833. *name++ = '\0';
  834.  
  835. id = atoi(cmd);
  836. wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_NETWORK id=%d name='%s'",
  837. id, name);
  838.  
  839. ssid = wpa_config_get_network(wpa_s->conf, id);
  840. if (ssid == NULL) {
  841. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
  842. "id=%d", id);
  843. return -1;
  844. }
  845.  
  846. value = wpa_config_get_no_key(ssid, name);
  847. if (value == NULL) {
  848. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to get network "
  849. "variable '%s'", name);
  850. return -1;
  851. }
  852.  
  853. os_snprintf(buf, buflen, "%s", value);
  854. buf[buflen - 1] = '\0';
  855.  
  856. os_free(value);
  857.  
  858. return os_strlen(buf);
  859. }
  860.  
  861.  
  862. static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
  863. {
  864. int ret;
  865.  
  866. if (!wpa_s->conf->update_config) {
  867. wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Not allowed "
  868. "to update configuration (update_config=0)");
  869. return -1;
  870. }
  871.  
  872. ret = wpa_config_write(wpa_s->confname, wpa_s->conf);
  873. if (ret) {
  874. wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Failed to "
  875. "update configuration");
  876. } else {
  877. wpa_printf(MSG_DEBUG, "CTRL_IFACE: SAVE_CONFIG - Configuration"
  878. " updated");
  879. }
  880.  
  881. return ret;
  882. }
  883.  
  884.  
  885. static int wpa_supplicant_ctrl_iface_get_capability(
  886. struct wpa_supplicant *wpa_s, const char *_field, char *buf,
  887. size_t buflen)
  888. {
  889. struct wpa_driver_capa capa;
  890. int res, first = 1, ret;
  891. char *pos, *end, *strict;
  892. char field[30];
  893.  
  894. /* Determine whether or not strict checking was requested */
  895. os_snprintf(field, sizeof(field), "%s", _field);
  896. field[sizeof(field) - 1] = '\0';
  897. strict = os_strchr(field, ' ');
  898. if (strict != NULL) {
  899. *strict++ = '\0';
  900. if (os_strcmp(strict, "strict") != 0)
  901. return -1;
  902. }
  903.  
  904. wpa_printf(MSG_DEBUG, "CTRL_IFACE: GET_CAPABILITY '%s' %s",
  905. field, strict ? strict : "");
  906.  
  907. if (os_strcmp(field, "eap") == 0) {
  908. return eap_get_names(buf, buflen);
  909. }
  910.  
  911. res = wpa_drv_get_capa(wpa_s, &capa);
  912.  
  913. pos = buf;
  914. end = pos + buflen;
  915.  
  916. if (os_strcmp(field, "pairwise") == 0) {
  917. if (res < 0) {
  918. if (strict)
  919. return 0;
  920. ret = os_snprintf(buf, buflen, "CCMP TKIP NONE");
  921. if (ret < 0 || (size_t) ret >= buflen)
  922. return -1;
  923. return ret;
  924. }
  925.  
  926. if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
  927. ret = os_snprintf(pos, end - pos, "%sCCMP",
  928. first ? "" : " ");
  929. if (ret < 0 || ret >= end - pos)
  930. return pos - buf;
  931. pos += ret;
  932. first = 0;
  933. }
  934.  
  935. if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
  936. ret = os_snprintf(pos, end - pos, "%sTKIP",
  937. first ? "" : " ");
  938. if (ret < 0 || ret >= end - pos)
  939. return pos - buf;
  940. pos += ret;
  941. first = 0;
  942. }
  943.  
  944. if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
  945. ret = os_snprintf(pos, end - pos, "%sNONE",
  946. first ? "" : " ");
  947. if (ret < 0 || ret >= end - pos)
  948. return pos - buf;
  949. pos += ret;
  950. first = 0;
  951. }
  952.  
  953. return pos - buf;
  954. }
  955.  
  956. if (os_strcmp(field, "group") == 0) {
  957. if (res < 0) {
  958. if (strict)
  959. return 0;
  960. ret = os_snprintf(buf, buflen,
  961. "CCMP TKIP WEP104 WEP40");
  962. if (ret < 0 || (size_t) ret >= buflen)
  963. return -1;
  964. return ret;
  965. }
  966.  
  967. if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
  968. ret = os_snprintf(pos, end - pos, "%sCCMP",
  969. first ? "" : " ");
  970. if (ret < 0 || ret >= end - pos)
  971. return pos - buf;
  972. pos += ret;
  973. first = 0;
  974. }
  975.  
  976. if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
  977. ret = os_snprintf(pos, end - pos, "%sTKIP",
  978. first ? "" : " ");
  979. if (ret < 0 || ret >= end - pos)
  980. return pos - buf;
  981. pos += ret;
  982. first = 0;
  983. }
  984.  
  985. if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
  986. ret = os_snprintf(pos, end - pos, "%sWEP104",
  987. first ? "" : " ");
  988. if (ret < 0 || ret >= end - pos)
  989. return pos - buf;
  990. pos += ret;
  991. first = 0;
  992. }
  993.  
  994. if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
  995. ret = os_snprintf(pos, end - pos, "%sWEP40",
  996. first ? "" : " ");
  997. if (ret < 0 || ret >= end - pos)
  998. return pos - buf;
  999. pos += ret;
  1000. first = 0;
  1001. }
  1002.  
  1003. return pos - buf;
  1004. }
  1005.  
  1006. if (os_strcmp(field, "key_mgmt") == 0) {
  1007. if (res < 0) {
  1008. if (strict)
  1009. return 0;
  1010. ret = os_snprintf(buf, buflen, "WPA-PSK WPA-EAP "
  1011. "IEEE8021X WPA-NONE NONE");
  1012. if (ret < 0 || (size_t) ret >= buflen)
  1013. return -1;
  1014. return ret;
  1015. }
  1016.  
  1017. ret = os_snprintf(pos, end - pos, "NONE IEEE8021X");
  1018. if (ret < 0 || ret >= end - pos)
  1019. return pos - buf;
  1020. pos += ret;
  1021.  
  1022. if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
  1023. WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
  1024. ret = os_snprintf(pos, end - pos, " WPA-EAP");
  1025. if (ret < 0 || ret >= end - pos)
  1026. return pos - buf;
  1027. pos += ret;
  1028. }
  1029.  
  1030. if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
  1031. WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
  1032. ret = os_snprintf(pos, end - pos, " WPA-PSK");
  1033. if (ret < 0 || ret >= end - pos)
  1034. return pos - buf;
  1035. pos += ret;
  1036. }
  1037.  
  1038. if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
  1039. ret = os_snprintf(pos, end - pos, " WPA-NONE");
  1040. if (ret < 0 || ret >= end - pos)
  1041. return pos - buf;
  1042. pos += ret;
  1043. }
  1044.  
  1045. return pos - buf;
  1046. }
  1047.  
  1048. if (os_strcmp(field, "proto") == 0) {
  1049. if (res < 0) {
  1050. if (strict)
  1051. return 0;
  1052. ret = os_snprintf(buf, buflen, "RSN WPA");
  1053. if (ret < 0 || (size_t) ret >= buflen)
  1054. return -1;
  1055. return ret;
  1056. }
  1057.  
  1058. if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
  1059. WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
  1060. ret = os_snprintf(pos, end - pos, "%sRSN",
  1061. first ? "" : " ");
  1062. if (ret < 0 || ret >= end - pos)
  1063. return pos - buf;
  1064. pos += ret;
  1065. first = 0;
  1066. }
  1067.  
  1068. if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
  1069. WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
  1070. ret = os_snprintf(pos, end - pos, "%sWPA",
  1071. first ? "" : " ");
  1072. if (ret < 0 || ret >= end - pos)
  1073. return pos - buf;
  1074. pos += ret;
  1075. first = 0;
  1076. }
  1077.  
  1078. return pos - buf;
  1079. }
  1080.  
  1081. if (os_strcmp(field, "auth_alg") == 0) {
  1082. if (res < 0) {
  1083. if (strict)
  1084. return 0;
  1085. ret = os_snprintf(buf, buflen, "OPEN SHARED LEAP");
  1086. if (ret < 0 || (size_t) ret >= buflen)
  1087. return -1;
  1088. return ret;
  1089. }
  1090.  
  1091. if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
  1092. ret = os_snprintf(pos, end - pos, "%sOPEN",
  1093. first ? "" : " ");
  1094. if (ret < 0 || ret >= end - pos)
  1095. return pos - buf;
  1096. pos += ret;
  1097. first = 0;
  1098. }
  1099.  
  1100. if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
  1101. ret = os_snprintf(pos, end - pos, "%sSHARED",
  1102. first ? "" : " ");
  1103. if (ret < 0 || ret >= end - pos)
  1104. return pos - buf;
  1105. pos += ret;
  1106. first = 0;
  1107. }
  1108.  
  1109. if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
  1110. ret = os_snprintf(pos, end - pos, "%sLEAP",
  1111. first ? "" : " ");
  1112. if (ret < 0 || ret >= end - pos)
  1113. return pos - buf;
  1114. pos += ret;
  1115. first = 0;
  1116. }
  1117.  
  1118. return pos - buf;
  1119. }
  1120.  
  1121. wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'",
  1122. field);
  1123.  
  1124. return -1;
  1125. }
  1126.  
  1127.  
  1128. static int wpa_supplicant_ctrl_iface_ap_scan(
  1129. struct wpa_supplicant *wpa_s, char *cmd)
  1130. {
  1131. int ap_scan = atoi(cmd);
  1132.  
  1133. if (ap_scan < 0 || ap_scan > 2)
  1134. return -1;
  1135. #ifdef ANDROID
  1136. if ((ap_scan == 2) && (wpa_s->wpa_state != WPA_COMPLETED)) {
  1137. return 0;
  1138. }
  1139. #endif
  1140. wpa_s->conf->ap_scan = ap_scan;
  1141. return 0;
  1142. }
  1143.  
  1144. static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s,
  1145. char *cmd, char *buf, size_t buflen)
  1146. {
  1147. int ret;
  1148.  
  1149. ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen);
  1150. if( ret == 0 ) {
  1151. ret = sprintf(buf, "%s\n", "OK");
  1152. }
  1153. return( ret );
  1154. }
  1155.  
  1156. static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
  1157. size_t buflen)
  1158. {
  1159. int ret;
  1160. int lssize=20;
  1161. int rssisize=16;
  1162. char linkspeed[lssize];
  1163. char rssi[rssisize];
  1164.  
  1165. wpa_supplicant_driver_cmd(wpa_s, "linkspeed", linkspeed, lssize);
  1166. wpa_supplicant_driver_cmd(wpa_s, "rssi", rssi, rssisize);
  1167.  
  1168. ret = os_snprintf(buf, buflen, "RSSI=%s\nLINKSPEED=%s\n"
  1169. "NOISE=0\nFREQUENCY=0\n",
  1170. strcasestr(rssi,"rssi")+5,linkspeed+10);
  1171. if (ret < 0 || (unsigned int) ret > buflen)
  1172. return -1;
  1173. return ret;
  1174. }
  1175.  
  1176. char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
  1177. char *buf, size_t *resp_len)
  1178. {
  1179. char *reply;
  1180. const int reply_size = 4096;
  1181. int ctrl_rsp = 0;
  1182. int reply_len;
  1183.  
  1184. if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 ||
  1185. os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
  1186. wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
  1187. (const u8 *) buf, os_strlen(buf));
  1188. } else {
  1189. if (os_strcmp(buf, "PING") != 0)
  1190. wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface",
  1191. (const u8 *) buf, os_strlen(buf));
  1192. }
  1193.  
  1194. reply = os_malloc(reply_size);
  1195. if (reply == NULL) {
  1196. *resp_len = 1;
  1197. return NULL;
  1198. }
  1199.  
  1200. os_memcpy(reply, "OK\n", 3);
  1201. reply_len = 3;
  1202.  
  1203. if (os_strcmp(buf, "PING") == 0) {
  1204. os_memcpy(reply, "PONG\n", 5);
  1205. reply_len = 5;
  1206. } else if (os_strcmp(buf, "MIB") == 0) {
  1207. reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size);
  1208. if (reply_len >= 0) {
  1209. int res;
  1210. res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len,
  1211. reply_size - reply_len);
  1212. if (res < 0)
  1213. reply_len = -1;
  1214. else
  1215. reply_len += res;
  1216. }
  1217. } else if (os_strncmp(buf, "STATUS", 6) == 0) {
  1218. reply_len = wpa_supplicant_ctrl_iface_status(
  1219. wpa_s, buf + 6, reply, reply_size);
  1220. } else if (os_strcmp(buf, "PMKSA") == 0) {
  1221. reply_len = pmksa_cache_list(wpa_s->wpa, reply, reply_size);
  1222. } else if (os_strncmp(buf, "SET ", 4) == 0) {
  1223. if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4))
  1224. reply_len = -1;
  1225. } else if (os_strcmp(buf, "LOGON") == 0) {
  1226. eapol_sm_notify_logoff(wpa_s->eapol, FALSE);
  1227. } else if (os_strcmp(buf, "LOGOFF") == 0) {
  1228. eapol_sm_notify_logoff(wpa_s->eapol, TRUE);
  1229. } else if (os_strcmp(buf, "REASSOCIATE") == 0) {
  1230. wpa_s->disconnected = 0;
  1231. wpa_s->reassociate = 1;
  1232. wpa_supplicant_req_scan(wpa_s, 0, 0);
  1233. } else if (os_strcmp(buf, "RECONNECT") == 0) {
  1234. if (wpa_s->disconnected) {
  1235. wpa_s->disconnected = 0;
  1236. wpa_s->reassociate = 1;
  1237. wpa_supplicant_req_scan(wpa_s, 0, 0);
  1238. }
  1239. #ifdef IEEE8021X_EAPOL
  1240. } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
  1241. if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
  1242. reply_len = -1;
  1243. #endif /* IEEE8021X_EAPOL */
  1244. #ifdef CONFIG_PEERKEY
  1245. } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
  1246. if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
  1247. reply_len = -1;
  1248. #endif /* CONFIG_PEERKEY */
  1249. } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
  1250. {
  1251. if (wpa_supplicant_ctrl_iface_ctrl_rsp(
  1252. wpa_s, buf + os_strlen(WPA_CTRL_RSP)))
  1253. reply_len = -1;
  1254. else
  1255. ctrl_rsp = 1;
  1256. } else if (os_strcmp(buf, "RECONFIGURE") == 0) {
  1257. if (wpa_supplicant_reload_configuration(wpa_s))
  1258. reply_len = -1;
  1259. } else if (os_strcmp(buf, "TERMINATE") == 0) {
  1260. eloop_terminate();
  1261. } else if (os_strncmp(buf, "BSSID ", 6) == 0) {
  1262. if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6))
  1263. reply_len = -1;
  1264. #ifdef ANDROID
  1265. } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) {
  1266. reply_len = wpa_supplicant_ctrl_iface_blacklist(
  1267. wpa_s, buf + 9, reply, reply_size);
  1268. if (os_strlen(buf) > 10 && reply_len == 0) {
  1269. struct wpa_blacklist *bl = wpa_s->blacklist;
  1270. if (os_strncmp(buf+10, "clear", 5) == 0 ||
  1271. (bl != NULL && os_memcmp(bl->bssid, wpa_s->bssid, ETH_ALEN) == 0)) {
  1272. wpa_s->disconnected = 0;
  1273. wpa_s->reassociate = 1;
  1274. wpa_supplicant_req_scan(wpa_s, 0, 0);
  1275. }
  1276. }
  1277. #endif
  1278. } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) {
  1279. reply_len = wpa_supplicant_ctrl_iface_list_networks(
  1280. wpa_s, reply, reply_size);
  1281. } else if (os_strcmp(buf, "DISCONNECT") == 0) {
  1282. wpa_s->reassociate = 0;
  1283. wpa_s->disconnected = 1;
  1284. wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
  1285. } else if (os_strcmp(buf, "SCAN") == 0) {
  1286. #ifdef ANDROID
  1287. if (!wpa_s->scan_ongoing && ((wpa_s->wpa_state <= WPA_SCANNING) ||
  1288. (wpa_s->wpa_state >= WPA_COMPLETED))) {
  1289. #endif
  1290. wpa_s->scan_req = 2;
  1291. wpa_supplicant_req_scan(wpa_s, 0, 0);
  1292. #ifdef ANDROID
  1293. } else {
  1294. wpa_printf(MSG_DEBUG, "Ongoing Scan action...");
  1295. }
  1296. #endif
  1297. } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
  1298. reply_len = wpa_supplicant_ctrl_iface_scan_results(
  1299. wpa_s, reply, reply_size);
  1300. } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
  1301. if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15))
  1302. reply_len = -1;
  1303. } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) {
  1304. if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15))
  1305. reply_len = -1;
  1306. } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) {
  1307. if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16))
  1308. reply_len = -1;
  1309. } else if (os_strcmp(buf, "ADD_NETWORK") == 0) {
  1310. reply_len = wpa_supplicant_ctrl_iface_add_network(
  1311. wpa_s, reply, reply_size);
  1312. } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) {
  1313. if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15))
  1314. reply_len = -1;
  1315. } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) {
  1316. if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12))
  1317. reply_len = -1;
  1318. } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
  1319. reply_len = wpa_supplicant_ctrl_iface_get_network(
  1320. wpa_s, buf + 12, reply, reply_size);
  1321. } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
  1322. if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
  1323. reply_len = -1;
  1324. } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
  1325. reply_len = wpa_supplicant_ctrl_iface_get_capability(
  1326. wpa_s, buf + 15, reply, reply_size);
  1327. } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
  1328. if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
  1329. reply_len = -1;
  1330. } else if (os_strcmp(buf, "INTERFACES") == 0) {
  1331. reply_len = wpa_supplicant_global_iface_interfaces(
  1332. wpa_s->global, reply, reply_size);
  1333. } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) {
  1334. reply_len = wpa_supplicant_signal_poll(wpa_s, reply,
  1335. reply_size);
  1336. } else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
  1337. reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, reply_size);
  1338. } else {
  1339. os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  1340. reply_len = 16;
  1341. }
  1342.  
  1343. if (reply_len < 0) {
  1344. os_memcpy(reply, "FAIL\n", 5);
  1345. reply_len = 5;
  1346. }
  1347.  
  1348. if (ctrl_rsp)
  1349. eapol_sm_notify_ctrl_response(wpa_s->eapol);
  1350.  
  1351. *resp_len = reply_len;
  1352. return reply;
  1353. }
  1354.  
  1355.  
  1356. static int wpa_supplicant_global_iface_add(struct wpa_global *global,
  1357. char *cmd)
  1358. {
  1359. struct wpa_interface iface;
  1360. char *pos;
  1361.  
  1362. /*
  1363. * <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB<driver_param>
  1364. * TAB<bridge_ifname>
  1365. */
  1366. wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_ADD '%s'", cmd);
  1367.  
  1368. os_memset(&iface, 0, sizeof(iface));
  1369.  
  1370. do {
  1371. iface.ifname = pos = cmd;
  1372. pos = os_strchr(pos, '\t');
  1373. if (pos)
  1374. *pos++ = '\0';
  1375. if (iface.ifname[0] == '\0')
  1376. return -1;
  1377. if (pos == NULL)
  1378. break;
  1379.  
  1380. iface.confname = pos;
  1381. pos = os_strchr(pos, '\t');
  1382. if (pos)
  1383. *pos++ = '\0';
  1384. if (iface.confname[0] == '\0')
  1385. iface.confname = NULL;
  1386. if (pos == NULL)
  1387. break;
  1388.  
  1389. iface.driver = pos;
  1390. pos = os_strchr(pos, '\t');
  1391. if (pos)
  1392. *pos++ = '\0';
  1393. if (iface.driver[0] == '\0')
  1394. iface.driver = NULL;
  1395. if (pos == NULL)
  1396. break;
  1397.  
  1398. iface.ctrl_interface = pos;
  1399. pos = os_strchr(pos, '\t');
  1400. if (pos)
  1401. *pos++ = '\0';
  1402. if (iface.ctrl_interface[0] == '\0')
  1403. iface.ctrl_interface = NULL;
  1404. if (pos == NULL)
  1405. break;
  1406.  
  1407. iface.driver_param = pos;
  1408. pos = os_strchr(pos, '\t');
  1409. if (pos)
  1410. *pos++ = '\0';
  1411. if (iface.driver_param[0] == '\0')
  1412. iface.driver_param = NULL;
  1413. if (pos == NULL)
  1414. break;
  1415.  
  1416. iface.bridge_ifname = pos;
  1417. pos = os_strchr(pos, '\t');
  1418. if (pos)
  1419. *pos++ = '\0';
  1420. if (iface.bridge_ifname[0] == '\0')
  1421. iface.bridge_ifname = NULL;
  1422. if (pos == NULL)
  1423. break;
  1424. } while (0);
  1425.  
  1426. if (wpa_supplicant_get_iface(global, iface.ifname))
  1427. return -1;
  1428.  
  1429. return wpa_supplicant_add_iface(global, &iface) ? 0 : -1;
  1430. }
  1431.  
  1432.  
  1433. static int wpa_supplicant_global_iface_remove(struct wpa_global *global,
  1434. char *cmd)
  1435. {
  1436. struct wpa_supplicant *wpa_s;
  1437.  
  1438. wpa_printf(MSG_DEBUG, "CTRL_IFACE GLOBAL INTERFACE_REMOVE '%s'", cmd);
  1439.  
  1440. wpa_s = wpa_supplicant_get_iface(global, cmd);
  1441. if (wpa_s == NULL)
  1442. return -1;
  1443. return wpa_supplicant_remove_iface(global, wpa_s);
  1444. }
  1445.  
  1446.  
  1447. static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
  1448. char *buf, int len)
  1449. {
  1450. int res;
  1451. char *pos, *end;
  1452. struct wpa_supplicant *wpa_s;
  1453.  
  1454. wpa_s = global->ifaces;
  1455. pos = buf;
  1456. end = buf + len;
  1457.  
  1458. while (wpa_s) {
  1459. res = os_snprintf(pos, end - pos, "%s\n", wpa_s->ifname);
  1460. if (res < 0 || res >= end - pos) {
  1461. *pos = '\0';
  1462. break;
  1463. }
  1464. pos += res;
  1465. wpa_s = wpa_s->next;
  1466. }
  1467. return pos - buf;
  1468. }
  1469.  
  1470.  
  1471. char * wpa_supplicant_global_ctrl_iface_process(struct wpa_global *global,
  1472. char *buf, size_t *resp_len)
  1473. {
  1474. char *reply;
  1475. const int reply_size = 4096;
  1476. int reply_len;
  1477.  
  1478. if (os_strcmp(buf, "PING") != 0)
  1479. wpa_hexdump_ascii(MSG_DEBUG, "RX global ctrl_iface",
  1480. (const u8 *) buf, os_strlen(buf));
  1481.  
  1482. reply = os_malloc(reply_size);
  1483. if (reply == NULL) {
  1484. *resp_len = 1;
  1485. return NULL;
  1486. }
  1487.  
  1488. os_memcpy(reply, "OK\n", 3);
  1489. reply_len = 3;
  1490.  
  1491. if (os_strcmp(buf, "PING") == 0) {
  1492. os_memcpy(reply, "PONG\n", 5);
  1493. reply_len = 5;
  1494. } else if (os_strncmp(buf, "INTERFACE_ADD ", 14) == 0) {
  1495. if (wpa_supplicant_global_iface_add(global, buf + 14))
  1496. reply_len = -1;
  1497. } else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
  1498. if (wpa_supplicant_global_iface_remove(global, buf + 17))
  1499. reply_len = -1;
  1500. } else if (os_strcmp(buf, "INTERFACES") == 0) {
  1501. reply_len = wpa_supplicant_global_iface_interfaces(
  1502. global, reply, reply_size);
  1503. } else if (os_strcmp(buf, "TERMINATE") == 0) {
  1504. eloop_terminate();
  1505. } else {
  1506. os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
  1507. reply_len = 16;
  1508. }
  1509.  
  1510. if (reply_len < 0) {
  1511. os_memcpy(reply, "FAIL\n", 5);
  1512. reply_len = 5;
  1513. }
  1514.  
  1515. *resp_len = reply_len;
  1516. return reply;
  1517. }
Add Comment
Please, Sign In to add comment