📄 driver_privsep.c
字号:
return; os_memset(&data, 0, sizeof(data)); os_memcpy(data.stkstart.peer, buf, ETH_ALEN); wpa_supplicant_event(ctx, EVENT_STKSTART, &data);}static void wpa_driver_privsep_event_ft_response(void *ctx, u8 *buf, size_t len){ union wpa_event_data data; if (len < sizeof(int) + ETH_ALEN) return; os_memset(&data, 0, sizeof(data)); os_memcpy(&data.ft_ies.ft_action, buf, sizeof(int)); os_memcpy(data.ft_ies.target_ap, buf + sizeof(int), ETH_ALEN); data.ft_ies.ies = buf + sizeof(int) + ETH_ALEN; data.ft_ies.ies_len = len - sizeof(int) - ETH_ALEN; wpa_supplicant_event(ctx, EVENT_FT_RESPONSE, &data);}static void wpa_driver_privsep_event_rx_eapol(void *ctx, u8 *buf, size_t len){ if (len < ETH_ALEN) return; wpa_supplicant_rx_eapol(ctx, buf, buf + ETH_ALEN, len - ETH_ALEN);}static void wpa_driver_privsep_event_sta_rx(void *ctx, u8 *buf, size_t len){#ifdef CONFIG_CLIENT_MLME struct ieee80211_rx_status *rx_status; if (len < sizeof(*rx_status)) return; rx_status = (struct ieee80211_rx_status *) buf; buf += sizeof(*rx_status); len -= sizeof(*rx_status); wpa_supplicant_sta_rx(ctx, buf, len, rx_status);#endif /* CONFIG_CLIENT_MLME */}static void wpa_driver_privsep_receive(int sock, void *eloop_ctx, void *sock_ctx){ struct wpa_driver_privsep_data *drv = eloop_ctx; u8 *buf, *event_buf; size_t event_len; int res, event; enum privsep_event e; struct sockaddr_un from; socklen_t fromlen = sizeof(from); const size_t buflen = 2000; buf = os_malloc(buflen); if (buf == NULL) return; res = recvfrom(sock, buf, buflen, 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom(priv_socket)"); os_free(buf); return; } wpa_printf(MSG_DEBUG, "privsep_driver: received %u bytes", res); if (res < (int) sizeof(int)) { wpa_printf(MSG_DEBUG, "Too short event message (len=%d)", res); return; } os_memcpy(&event, buf, sizeof(int)); event_buf = &buf[sizeof(int)]; event_len = res - sizeof(int); wpa_printf(MSG_DEBUG, "privsep: Event %d received (len=%lu)", event, (unsigned long) event_len); e = event; switch (e) { case PRIVSEP_EVENT_SCAN_RESULTS: wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL); break; case PRIVSEP_EVENT_ASSOC: wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOC, event_buf, event_len); break; case PRIVSEP_EVENT_DISASSOC: wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL); break; case PRIVSEP_EVENT_ASSOCINFO: wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOCINFO, event_buf, event_len); break; case PRIVSEP_EVENT_MICHAEL_MIC_FAILURE: wpa_driver_privsep_event_michael_mic_failure( drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_INTERFACE_STATUS: wpa_driver_privsep_event_interface_status(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_PMKID_CANDIDATE: wpa_driver_privsep_event_pmkid_candidate(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_STKSTART: wpa_driver_privsep_event_stkstart(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_FT_RESPONSE: wpa_driver_privsep_event_ft_response(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_RX_EAPOL: wpa_driver_privsep_event_rx_eapol(drv->ctx, event_buf, event_len); break; case PRIVSEP_EVENT_STA_RX: wpa_driver_privsep_event_sta_rx(drv->ctx, event_buf, event_len); break; } os_free(buf);}static void * wpa_driver_privsep_init(void *ctx, const char *ifname){ struct wpa_driver_privsep_data *drv; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) return NULL; drv->ctx = ctx; drv->priv_socket = -1; drv->cmd_socket = -1; os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); return drv;}static void wpa_driver_privsep_deinit(void *priv){ struct wpa_driver_privsep_data *drv = priv; if (drv->priv_socket >= 0) { wpa_priv_reg_cmd(drv, PRIVSEP_CMD_UNREGISTER); eloop_unregister_read_sock(drv->priv_socket); close(drv->priv_socket); } if (drv->own_socket_path) { unlink(drv->own_socket_path); os_free(drv->own_socket_path); } if (drv->cmd_socket >= 0) { eloop_unregister_read_sock(drv->cmd_socket); close(drv->cmd_socket); } if (drv->own_cmd_path) { unlink(drv->own_cmd_path); os_free(drv->own_cmd_path); } os_free(drv);}static int wpa_driver_privsep_set_param(void *priv, const char *param){ struct wpa_driver_privsep_data *drv = priv; const char *pos; char *own_dir, *priv_dir; static unsigned int counter = 0; size_t len; struct sockaddr_un addr; wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); if (param == NULL) pos = NULL; else pos = os_strstr(param, "own_dir="); if (pos) { char *end; own_dir = os_strdup(pos + 8); if (own_dir == NULL) return -1; end = os_strchr(own_dir, ' '); if (end) *end = '\0'; } else { own_dir = os_strdup("/tmp"); if (own_dir == NULL) return -1; } if (param == NULL) pos = NULL; else pos = os_strstr(param, "priv_dir="); if (pos) { char *end; priv_dir = os_strdup(pos + 9); if (priv_dir == NULL) { os_free(own_dir); return -1; } end = os_strchr(priv_dir, ' '); if (end) *end = '\0'; } else { priv_dir = os_strdup("/var/run/wpa_priv"); if (priv_dir == NULL) { os_free(own_dir); return -1; } } len = os_strlen(own_dir) + 50; drv->own_socket_path = os_malloc(len); if (drv->own_socket_path == NULL) { os_free(priv_dir); os_free(own_dir); return -1; } os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d", own_dir, getpid(), counter++); len = os_strlen(own_dir) + 50; drv->own_cmd_path = os_malloc(len); if (drv->own_cmd_path == NULL) { os_free(drv->own_socket_path); drv->own_socket_path = NULL; os_free(priv_dir); os_free(own_dir); return -1; } os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d", own_dir, getpid(), counter++); os_free(own_dir); drv->priv_addr.sun_family = AF_UNIX; os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path), "%s/%s", priv_dir, drv->ifname); os_free(priv_dir); drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->priv_socket < 0) { perror("socket(PF_UNIX)"); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); close(drv->priv_socket); drv->priv_socket = -1; unlink(drv->own_socket_path); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive, drv, NULL); drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->cmd_socket < 0) { perror("socket(PF_UNIX)"); os_free(drv->own_cmd_path); drv->own_cmd_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path)); if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); close(drv->cmd_socket); drv->cmd_socket = -1; unlink(drv->own_cmd_path); os_free(drv->own_cmd_path); drv->own_cmd_path = NULL; return -1; } if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) { wpa_printf(MSG_ERROR, "Failed to register with wpa_priv"); return -1; } return 0;}static int wpa_driver_privsep_get_capa(void *priv, struct wpa_driver_capa *capa){ struct wpa_driver_privsep_data *drv = priv; int res; size_t len = sizeof(*capa); res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_CAPA, NULL, 0, capa, &len); if (res < 0 || len != sizeof(*capa)) return -1; return 0;}static const u8 * wpa_driver_privsep_get_mac_addr(void *priv){ struct wpa_driver_privsep_data *drv = priv; wpa_printf(MSG_DEBUG, "%s", __func__); return drv->own_addr;}static int wpa_driver_privsep_set_mode(void *priv, int mode){ struct wpa_driver_privsep_data *drv = priv; wpa_printf(MSG_DEBUG, "%s mode=%d", __func__, mode); return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_MODE, &mode, sizeof(mode), NULL, NULL);}static int wpa_driver_privsep_set_country(void *priv, const char *alpha2){ struct wpa_driver_privsep_data *drv = priv; wpa_printf(MSG_DEBUG, "%s country='%s'", __func__, alpha2); return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_COUNTRY, alpha2, os_strlen(alpha2), NULL, NULL);}struct wpa_driver_ops wpa_driver_privsep_ops = { "privsep", "wpa_supplicant privilege separated driver", wpa_driver_privsep_get_bssid, wpa_driver_privsep_get_ssid, wpa_driver_privsep_set_wpa, wpa_driver_privsep_set_key, wpa_driver_privsep_init, wpa_driver_privsep_deinit, wpa_driver_privsep_set_param, NULL /* set_countermeasures */, NULL /* set_drop_unencrypted */, wpa_driver_privsep_scan, NULL /* get_scan_results */, wpa_driver_privsep_deauthenticate, wpa_driver_privsep_disassociate, wpa_driver_privsep_associate, NULL /* set_auth_alg */, NULL /* add_pmkid */, NULL /* remove_pmkid */, NULL /* flush_pmkid */, wpa_driver_privsep_get_capa, NULL /* poll */, NULL /* get_ifname */, wpa_driver_privsep_get_mac_addr, NULL /* send_eapol */, NULL /* set_operstate */, NULL /* mlme_setprotection */, NULL /* get_hw_feature_data */, NULL /* set_channel */, NULL /* set_ssid */, NULL /* set_bssid */, NULL /* send_mlme */, NULL /* mlme_add_sta */, NULL /* mlme_remove_sta */, NULL /* update_ft_ies */, NULL /* send_ft_action */, wpa_driver_privsep_get_scan_results2, NULL /* set_probe_req_ie */, wpa_driver_privsep_set_mode, wpa_driver_privsep_set_country, NULL /* global_init */, NULL /* global_deinit */, NULL /* init2 */, NULL /* get_interfaces */};struct wpa_driver_ops *wpa_supplicant_drivers[] ={ &wpa_driver_privsep_ops, NULL};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -