ctrl_iface.c
来自「WPA在Linux下实现的原代码 WPA在Linux下实现的原代码」· C语言 代码 · 共 2,029 行 · 第 1/4 页
C
2,029 行
if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) { ret = snprintf(pos, end - pos, " WPA-EAP"); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; } if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK | WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { ret = snprintf(pos, end - pos, " WPA-PSK"); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; } if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) { ret = snprintf(pos, end - pos, " WPA-NONE"); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; } return pos - buf; } if (strcmp(field, "proto") == 0) { if (res < 0) { ret = snprintf(buf, buflen, "RSN WPA"); if (ret < 0 || (size_t) ret >= buflen) return -1; return ret; } if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 | WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) { ret = snprintf(pos, end - pos, "%sRSN", first ? "" : " "); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; first = 0; } if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) { ret = snprintf(pos, end - pos, "%sWPA", first ? "" : " "); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; first = 0; } return pos - buf; } if (strcmp(field, "auth_alg") == 0) { if (res < 0) { ret = snprintf(buf, buflen, "OPEN SHARED LEAP"); if (ret < 0 || (size_t) ret >= buflen) return -1; return ret; } if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) { ret = snprintf(pos, end - pos, "%sOPEN", first ? "" : " "); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; first = 0; } if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) { ret = snprintf(pos, end - pos, "%sSHARED", first ? "" : " "); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; first = 0; } if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) { ret = snprintf(pos, end - pos, "%sLEAP", first ? "" : " "); if (ret < 0 || ret >= end - pos) return pos - buf; pos += ret; first = 0; } return pos - buf; } wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown GET_CAPABILITY field '%s'", field); return -1;}#ifdef CONFIG_CTRL_IFACE_UDPstatic char *wpa_supplicant_ctrl_iface_get_cookie(struct wpa_supplicant *wpa_s, size_t *reply_len){ char *reply; reply = malloc(7 + 2 * COOKIE_LEN + 1); if (reply == NULL) { *reply_len = 1; return NULL; } memcpy(reply, "COOKIE=", 7); wpa_snprintf_hex(reply + 7, 2 * COOKIE_LEN + 1, wpa_s->cookie, COOKIE_LEN); *reply_len = 7 + 2 * COOKIE_LEN; return reply;}#endif /* CONFIG_CTRL_IFACE_UDP */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], *buf = _buf; 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;#ifdef CONFIG_CTRL_IFACE_UDP u8 cookie[COOKIE_LEN];#endif /* CONFIG_CTRL_IFACE_UDP */ res = recvfrom(sock, _buf, sizeof(_buf) - 1, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(ctrl_iface)"); return; }#ifdef CONFIG_CTRL_IFACE_UDP if (from.sin_addr.s_addr != htonl((127 << 24) | 1)) { /* * The OS networking stack is expected to drop this kind of * frames since the socket is bound to only localhost address. * Just in case, drop the frame if it is coming from any other * address. */ wpa_printf(MSG_DEBUG, "CTRL: Drop packet from unexpected " "source %s", inet_ntoa(from.sin_addr)); return; }#endif /* CONFIG_CTRL_IFACE_UDP */ buf[res] = '\0';#ifdef CONFIG_CTRL_IFACE_UDP if (strcmp(buf, "GET_COOKIE") == 0) { reply = wpa_supplicant_ctrl_iface_get_cookie(wpa_s, &reply_len); goto done; } /* * Require that the client includes a prefix with the 'cookie' value * fetched with GET_COOKIE command. This is used to verify that the * client has access to a bidirectional link over UDP in order to * avoid attacks using forged localhost IP address even if the OS does * not block such frames from remote destinations. */ if (strncmp(buf, "COOKIE=", 7) != 0) { wpa_printf(MSG_DEBUG, "CTLR: No cookie in the request - " "drop request"); return; } if (hexstr2bin(buf + 7, cookie, COOKIE_LEN) < 0) { wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie format in the " "request - drop request"); return; } if (memcmp(cookie, wpa_s->cookie, COOKIE_LEN) != 0) { wpa_printf(MSG_DEBUG, "CTLR: Invalid cookie in the request - " "drop request"); return; } buf += 7 + 2 * COOKIE_LEN; while (*buf == ' ') buf++;#endif /* CONFIG_CTRL_IFACE_UDP */ if (strncmp(buf, WPA_CTRL_RSP, strlen(WPA_CTRL_RSP)) == 0 || strncmp(buf, "SET_NETWORK ", 12) == 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_sm_get_mib(wpa_s->wpa, 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->wpa, 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->disconnected = 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, WPA_CTRL_RSP, strlen(WPA_CTRL_RSP)) == 0) { if (wpa_supplicant_ctrl_iface_ctrl_rsp( wpa_s, buf + strlen(WPA_CTRL_RSP))) 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 if (strncmp(buf, "BSSID ", 6) == 0) { if (wpa_supplicant_ctrl_iface_bssid(wpa_s, buf + 6)) reply_len = -1; } else if (strcmp(buf, "LIST_NETWORKS") == 0) { reply_len = wpa_supplicant_ctrl_iface_list_networks( wpa_s, reply, reply_size); } else if (strcmp(buf, "DISCONNECT") == 0) { wpa_s->reassociate = 0; wpa_s->disconnected = 1; wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING); } else if (strcmp(buf, "SCAN") == 0) { wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); } else if (strcmp(buf, "SCAN_RESULTS") == 0) { reply_len = wpa_supplicant_ctrl_iface_scan_results( wpa_s, reply, reply_size); } else if (strncmp(buf, "SELECT_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)) reply_len = -1; } else if (strncmp(buf, "ENABLE_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_enable_network(wpa_s, buf + 15)) reply_len = -1; } else if (strncmp(buf, "DISABLE_NETWORK ", 16) == 0) { if (wpa_supplicant_ctrl_iface_disable_network(wpa_s, buf + 16)) reply_len = -1; } else if (strcmp(buf, "ADD_NETWORK") == 0) { reply_len = wpa_supplicant_ctrl_iface_add_network( wpa_s, reply, reply_size); } else if (strncmp(buf, "REMOVE_NETWORK ", 15) == 0) { if (wpa_supplicant_ctrl_iface_remove_network(wpa_s, buf + 15)) reply_len = -1; } else if (strncmp(buf, "SET_NETWORK ", 12) == 0) { if (wpa_supplicant_ctrl_iface_set_network(wpa_s, buf + 12)) reply_len = -1; } else if (strncmp(buf, "GET_NETWORK ", 12) == 0) { reply_len = wpa_supplicant_ctrl_iface_get_network( wpa_s, buf + 12, reply, reply_size); } else if (strcmp(buf, "SAVE_CONFIG") == 0) { if (wpa_supplicant_ctrl_iface_save_config(wpa_s)) reply_len = -1; } else if (strncmp(buf, "GET_CAPABILITY ", 15) == 0) { reply_len = wpa_supplicant_ctrl_iface_get_capability( wpa_s, buf + 15, reply, reply_size); } else { memcpy(reply, "UNKNOWN COMMAND\n", 16); reply_len = 16; } if (reply_len < 0) { memcpy(reply, "FAIL\n", 5); reply_len = 5; }#ifdef CONFIG_CTRL_IFACE_UDPdone:#endif /* CONFIG_CTRL_IFACE_UDP */ 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);}#ifndef CONFIG_CTRL_IFACE_UDPstatic char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s){ char *buf; size_t len; if (wpa_s->conf->ctrl_interface == NULL) return NULL; len = strlen(wpa_s->conf->ctrl_interface) + strlen(wpa_s->ifname) + 2; buf = malloc(len); if (buf == NULL) return NULL; snprintf(buf, len, "%s/%s", wpa_s->conf->ctrl_interface, wpa_s->ifname);#ifdef __CYGWIN__ { /* Windows/WinPcap uses interface names that are not suitable * as a file name - convert invalid chars to underscores */ char *pos = buf; while (*pos) { if (*pos == '\\') *pos = '_'; pos++; } }#endif /* __CYGWIN__ */ return buf;}#endif /* CONFIG_CTRL_IFACE_UDP *//** * wpa_supplicant_ctrl_iface_init - Initialize control interface * @wpa_s: Pointer to wpa_supplicant data * Returns: 0 on success, -1 on failure * * Initialize the control interface and start receiving commands from external * programs. */int wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s){ CTRL_IFACE_SOCK addr; int s = -1;#ifndef CONFIG_CTRL_IFACE_UDP char *fname = NULL;#endif /* CONFIG_CTRL_IFACE_UDP */ wpa_s->ctrl_sock = -1; if (wpa_s->conf->ctrl_interface == NULL) return 0;#ifdef CONFIG_CTRL_IFACE_UDP hostapd_get_rand(wpa_s->cookie, COOKIE_LEN); s = socket(PF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket(PF_INET)"); goto fail; } memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl((127 << 24) | 1); addr.sin_port = htons(WPA_CTRL_IFACE_PORT); if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(AF_INET)"); goto fail; }#else /* CONFIG_CTRL_IFACE_UDP */ if (mkdir(wpa_s->conf->ctrl_interface, S_IRWXU | S_IRWXG) < 0) { if (errno == EEXIST) { wpa_printf(MSG_DEBUG, "Using existing control " "interface directory."); } else { perror("mkdir[ctrl_interface]"); goto fail; } } if (wpa_s->conf->ctrl_interface_gid_set && chown(wpa_s->conf->ctrl_interface, 0, wpa_s->conf->ctrl_interface_gid) < 0) { perror("chown[ctrl_interface]"); return -1; } if (strlen(wpa_s->conf->ctrl_interface) + 1 + strlen(wpa_s->ifname) >= sizeof(addr.sun_path)) goto fail; s = socket(PF_UNIX, SOCK_DGRAM, 0); if (s < 0) { perror("socket(PF_UNIX)"); goto fail; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; fname = wpa_supplicant_ctrl_iface_path(wpa_s); if (fname == NULL) goto fail; strncpy(addr.sun_path, fname, sizeof(addr.sun_path)); if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", strerror(errno)); if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" " allow connections - assuming it was left" "over from forced program termination"); if (unlink(fname) < 0) { perror("unlink[ctrl_iface]"); wpa_printf(MSG_ERROR, "Could not unlink " "existing ctrl_iface socket '%s'", fname); goto fail; } if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); goto fail; } wpa_printf(MSG_DEBUG, "Successfully replaced leftover " "ctrl_iface socket '%s'", fname); } else { wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " "be in use - cannot override it"); wpa_printf(MSG_INFO, "Delete '%s' manually if it is " "not used anymore", fname); free(fname); fname = NULL; goto fail; } } if (wpa_s->conf->ctrl_interface_gid_set && chown(fname, 0, wpa_s->conf->ctrl_interface_gid) < 0) { perror("chown[ctrl_interface/ifname]"); goto fail; } if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { perror("chmod[ctrl_interface/ifname]"); goto fail; } free(fname);#endif /* CONFIG_CTRL_IFACE_UDP */ wpa_s->ctrl_sock = s; eloop_register_read_sock(s, wpa_supplicant_ctrl_iface_receive, wpa_s, NULL); return 0;fail: if (s >= 0) close(s);#ifndef CONFIG_CTRL_IFACE_UDP if (fname) { unlink(fname); free(fname); }#endif /* CONFIG_CTRL_IFACE_UDP */ return -1;}/**
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?