char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, char *buf, size_t *resp_len) { char *reply; const int reply_size = 4096; int ctrl_rsp = 0; int reply_len; if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0 || os_strncmp(buf, "SET_NETWORK ", 12) == 0) { wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", (const u8 *) buf, os_strlen(buf)); } else { if (os_strcmp(buf, "PING") != 0) wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface", (const u8 *) buf, os_strlen(buf)); } reply = os_malloc(reply_size); if (reply == NULL) { *resp_len = 1; return NULL; } os_memcpy(reply, "OK\n", 3); reply_len = 3; if (os_strcmp(buf, "PING") == 0) { os_memcpy(reply, "PONG\n", 5); reply_len = 5; } else if (os_strcmp(buf, "MIB") == 0) { reply_len = wpa_sm_get_mib(wpa_s->wpa, reply, reply_size); if (reply_len >= 0) { int res; res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, reply_size - reply_len); if (res < 0) reply_len = -1; else reply_len += res; } } else if (os_strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); } else if (os_strcmp(buf, "PMKSA") == 0) { reply_len = pmksa_cache_list(wpa_s->wpa, reply, reply_size); } else if (os_strncmp(buf, "SET ", 4) == 0) { if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) reply_len = -1; } else if (os_strcmp(buf, "LOGON") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, FALSE); } else if (os_strcmp(buf, "LOGOFF") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, TRUE); } else if (os_strcmp(buf, "REASSOCIATE") == 0) { wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } else if (os_strcmp(buf, "RECONNECT") == 0) { if (wpa_s->disconnected) { wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } #ifdef IEEE8021X_EAPOL } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) { if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) reply_len = -1; #endif /* IEEE8021X_EAPOL */ #ifdef CONFIG_PEERKEY } else if (os_strncmp(buf, "STKSTART ", 9) == 0) { if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9)) reply_len = -1; #endif /* CONFIG_PEERKEY */ } else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0) { if (wpa_supplicant_ctrl_iface_ctrl_rsp( wpa_s, buf + os_strlen(WPA_CTRL_RSP))) reply_len = -1; else ctrl_rsp = 1; } else if (os_strcmp(buf, "RECONFIGURE") == 0) { if (wpa_supplicant_reload_configuration(wpa_s)) reply_len = -1; } else if (os_strcmp(buf, "TERMINATE") == 0) { eloop_terminate(); } else if (os_strncmp(buf, "BSSID ", 6) == 0) { if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) reply_len = -1; #ifdef ANDROID } else if (os_strncmp(buf, "BLACKLIST", 9) == 0) { reply_len = wpa_supplicant_ctrl_iface_blacklist( wpa_s, buf + 9, reply, reply_size); if (os_strlen(buf) > 10 && reply_len == 0) { struct wpa_blacklist *bl = wpa_s->blacklist; if (os_strncmp(buf+10, "clear", 5) == 0 || (bl != NULL && os_memcmp(bl->bssid, wpa_s->bssid, ETH_ALEN) == 0)) { wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } } #endif } else if (os_strcmp(buf, "LIST_NETWORKS") == 0) { reply_len = wpa_supplicant_ctrl_iface_list_networks( wpa_s, reply, reply_size); } else if (os_strcmp(buf, "DISCONNECT") == 0) { wpa_s->reassociate = 0; wpa_s->disconnected = 1; wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING); } else if (os_strcmp(buf, "SCAN") == 0) { #ifdef ANDROID if (!wpa_s->scan_ongoing && ((wpa_s->wpa_state <= WPA_SCANNING) || (wpa_s->wpa_state >= WPA_COMPLETED))) { #endif wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); #ifdef ANDROID } else { wpa_printf(MSG_DEBUG, "Ongoing Scan action..."); } #endif } else if (os_strcmp(buf, "SCAN_RESULTS") == 0) { reply_len = wpa_supplicant_ctrl_iface_scan_results( wpa_s, reply, reply_size); } else if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) reply_len = -1; } else if (os_strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) reply_len = -1; } else if (os_strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) reply_len = -1; } else if (os_strcmp(buf, "ADD_NETWORK") == 0) { reply_len = wpa_supplicant_ctrl_iface_add_network( wpa_s, reply, reply_size); } else if (os_strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) reply_len = -1; } else if (os_strncmp(buf, "SET_NETWORK ", 12) == 0) { if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) reply_len = -1; } else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) { reply_len = wpa_supplicant_ctrl_iface_get_network( wpa_s, buf + 12, reply, reply_size); } else if (os_strcmp(buf, "SAVE_CONFIG") == 0) { if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) reply_len = -1; } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) { reply_len = wpa_supplicant_ctrl_iface_get_capability( wpa_s, buf + 15, reply, reply_size); } else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) { if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8)) reply_len = -1; } else if (os_strcmp(buf, "INTERFACES") == 0) { reply_len = wpa_supplicant_global_iface_interfaces( wpa_s->global, reply, reply_size); } else if (os_strncmp(buf, "DRIVER ", 7) == 0) { reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply, reply_size); } else { os_memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; } if (reply_len < 0) { os_memcpy(reply, "FAIL\n", 5); reply_len = 5; } if (ctrl_rsp) eapol_sm_notify_ctrl_response(wpa_s->eapol); *resp_len = reply_len; return reply; }
static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, void *sock_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; char buf[256]; int res; CTRL_IFACE_SOCK from; socklen_t fromlen = sizeof(from); char *reply; const int reply_size = 2048; int reply_len; int new_attached = 0, ctrl_rsp = 0; res = recvfrom(sock, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(ctrl_iface)"); return; } buf[res] = '\0'; if (strncmp(buf, "CTRL-RSP-", 9) == 0) { wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface", (u8 *) buf, res); } else { wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface", (u8 *) buf, res); } reply = malloc(reply_size); if (reply == NULL) { sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, fromlen); return; } memcpy(reply, "OK\n", 3); reply_len = 3; if (strcmp(buf, "PING") == 0) { memcpy(reply, "PONG\n", 5); reply_len = 5; } else if (strcmp(buf, "MIB") == 0) { reply_len = wpa_get_mib(wpa_s, reply, reply_size); if (reply_len >= 0) { res = eapol_sm_get_mib(wpa_s->eapol, reply + reply_len, reply_size - reply_len); if (res < 0) reply_len = -1; else reply_len += res; } } else if (strncmp(buf, "STATUS", 6) == 0) { reply_len = wpa_supplicant_ctrl_iface_status( wpa_s, buf + 6, reply, reply_size); } else if (strcmp(buf, "PMKSA") == 0) { reply_len = pmksa_cache_list(wpa_s, reply, reply_size); } else if (strncmp(buf, "SET ", 4) == 0) { if (wpa_supplicant_ctrl_iface_set(wpa_s, buf + 4)) reply_len = -1; } else if (strcmp(buf, "LOGON") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, FALSE); } else if (strcmp(buf, "LOGOFF") == 0) { eapol_sm_notify_logoff(wpa_s->eapol, TRUE); } else if (strcmp(buf, "REASSOCIATE") == 0) { wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); } else if (strncmp(buf, "PREAUTH ", 8) == 0) { if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8)) reply_len = -1; } else if (strcmp(buf, "ATTACH") == 0) { if (wpa_supplicant_ctrl_iface_attach(wpa_s, &from, fromlen)) reply_len = -1; else new_attached = 1; } else if (strcmp(buf, "DETACH") == 0) { if (wpa_supplicant_ctrl_iface_detach(wpa_s, &from, fromlen)) reply_len = -1; } else if (strncmp(buf, "LEVEL ", 6) == 0) { if (wpa_supplicant_ctrl_iface_level(wpa_s, &from, fromlen, buf + 6)) reply_len = -1; } else if (strncmp(buf, "CTRL-RSP-", 9) == 0) { if (wpa_supplicant_ctrl_iface_ctrl_rsp(wpa_s, buf + 9)) reply_len = -1; else ctrl_rsp = 1; } else if (strcmp(buf, "RECONFIGURE") == 0) { if (wpa_supplicant_reload_configuration(wpa_s)) reply_len = -1; } else if (strcmp(buf, "TERMINATE") == 0) { eloop_terminate(); } else { memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; } if (reply_len < 0) { memcpy(reply, "FAIL\n", 5); reply_len = 5; } sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, fromlen); free(reply); if (new_attached) eapol_sm_notify_ctrl_attached(wpa_s->eapol); if (ctrl_rsp) eapol_sm_notify_ctrl_response(wpa_s->eapol); }