📄 wps_hostapd.c
字号:
wps->config_methods |= WPS_CONFIG_LABEL; if (os_strstr(m, "display")) wps->config_methods |= WPS_CONFIG_DISPLAY; if (os_strstr(m, "push_button")) wps->config_methods |= WPS_CONFIG_PUSHBUTTON; if (os_strstr(m, "keypad")) wps->config_methods |= WPS_CONFIG_KEYPAD; } if (hapd->conf->device_type) { char *pos; u8 oui[4]; /* <categ>-<OUI>-<subcateg> */ wps->dev.categ = atoi(hapd->conf->device_type); pos = os_strchr(hapd->conf->device_type, '-'); if (pos == NULL) { wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); os_free(wps); return -1; } pos++; if (hexstr2bin(pos, oui, 4)) { wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI"); os_free(wps); return -1; } wps->dev.oui = WPA_GET_BE32(oui); pos = os_strchr(pos, '-'); if (pos == NULL) { wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); os_free(wps); return -1; } pos++; wps->dev.sub_categ = atoi(pos); } wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ if (conf->wpa & WPA_PROTO_RSN) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPA2PSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA2; if (conf->rsn_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->rsn_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->wpa & WPA_PROTO_WPA) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPAPSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA; if (conf->wpa_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->wpa_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->ssid.security_policy == SECURITY_PLAINTEXT) { wps->encr_types |= WPS_ENCR_NONE; wps->auth_types |= WPS_AUTH_OPEN; } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) { wps->encr_types |= WPS_ENCR_WEP; if (conf->auth_algs & WPA_AUTH_ALG_OPEN) wps->auth_types |= WPS_AUTH_OPEN; if (conf->auth_algs & WPA_AUTH_ALG_SHARED) wps->auth_types |= WPS_AUTH_SHARED; } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) { wps->auth_types |= WPS_AUTH_OPEN; if (conf->default_wep_key_len) wps->encr_types |= WPS_ENCR_WEP; else wps->encr_types |= WPS_ENCR_NONE; } if (conf->ssid.wpa_psk_file) { /* Use per-device PSKs */ } else if (conf->ssid.wpa_passphrase) { wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); } else if (conf->ssid.wpa_psk) { wps->network_key = os_malloc(2 * PMK_LEN + 1); if (wps->network_key == NULL) { os_free(wps); return -1; } wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, conf->ssid.wpa_psk->psk, PMK_LEN); wps->network_key_len = 2 * PMK_LEN; } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { wps->network_key = os_malloc(conf->ssid.wep.len[0]); if (wps->network_key == NULL) { os_free(wps); return -1; } os_memcpy(wps->network_key, conf->ssid.wep.key[0], conf->ssid.wep.len[0]); wps->network_key_len = conf->ssid.wep.len[0]; } if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) { /* Override parameters to enable security by default */ wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK; wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP; } wps->ap_settings = conf->ap_settings; wps->ap_settings_len = conf->ap_settings_len; cfg.new_psk_cb = hostapd_wps_new_psk_cb; cfg.set_ie_cb = hostapd_wps_set_ie_cb; cfg.pin_needed_cb = hostapd_wps_pin_needed_cb; cfg.reg_success_cb = hostapd_wps_reg_success_cb; cfg.cb_ctx = hapd; cfg.skip_cred_build = conf->skip_cred_build; cfg.extra_cred = conf->extra_cred; cfg.extra_cred_len = conf->extra_cred_len; cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) && conf->skip_cred_build; if (conf->ssid.security_policy == SECURITY_STATIC_WEP) cfg.static_wep_only = 1; wps->registrar = wps_registrar_init(wps, &cfg); if (wps->registrar == NULL) { printf("Failed to initialize WPS Registrar\n"); os_free(wps->network_key); os_free(wps); return -1; }#ifdef CONFIG_WPS_UPNP wps->friendly_name = hapd->conf->friendly_name; wps->manufacturer_url = hapd->conf->manufacturer_url; wps->model_description = hapd->conf->model_description; wps->model_url = hapd->conf->model_url; wps->upc = hapd->conf->upc; if (hostapd_wps_upnp_init(hapd, wps) < 0) { wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP"); wps_registrar_deinit(wps->registrar); os_free(wps->network_key); os_free(wps); return -1; }#endif /* CONFIG_WPS_UPNP */ hapd->wps = wps; return 0;}void hostapd_deinit_wps(struct hostapd_data *hapd){ if (hapd->wps == NULL) return;#ifdef CONFIG_WPS_UPNP hostapd_wps_upnp_deinit(hapd);#endif /* CONFIG_WPS_UPNP */ wps_registrar_deinit(hapd->wps->registrar); os_free(hapd->wps->network_key); wps_device_data_free(&hapd->wps->dev); wps_free_pending_msgs(hapd->wps->upnp_msgs); os_free(hapd->wps); hapd->wps = NULL; hostapd_wps_clear_ies(hapd);}int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid, const char *pin){ u8 u[UUID_LEN]; int any = 0; if (hapd->wps == NULL) return -1; if (os_strcmp(uuid, "any") == 0) any = 1; else if (uuid_str2bin(uuid, u)) return -1; return wps_registrar_add_pin(hapd->wps->registrar, any ? NULL : u, (const u8 *) pin, os_strlen(pin));}int hostapd_wps_button_pushed(struct hostapd_data *hapd){ if (hapd->wps == NULL) return -1; return wps_registrar_button_pushed(hapd->wps->registrar);}void hostapd_wps_probe_req_rx(struct hostapd_data *hapd, const u8 *addr, const u8 *ie, size_t ie_len){ struct wpabuf *wps_ie; const u8 *end, *pos, *wps; if (hapd->wps == NULL) return; pos = ie; end = ie + ie_len; wps = NULL; while (pos + 1 < end) { if (pos + 2 + pos[1] > end) return; if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && WPA_GET_BE32(&pos[2]) == WPS_DEV_OUI_WFA) { wps = pos; break; } pos += 2 + pos[1]; } if (wps == NULL) return; /* No WPS IE in Probe Request */ wps_ie = wpabuf_alloc(ie_len); if (wps_ie == NULL) return; /* There may be multiple WPS IEs in the message, so need to concatenate * their WPS Data fields */ while (pos + 1 < end) { if (pos + 2 + pos[1] > end) break; if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && WPA_GET_BE32(&pos[2]) == WPS_DEV_OUI_WFA) wpabuf_put_data(wps_ie, pos + 6, pos[1] - 4); pos += 2 + pos[1]; } if (wpabuf_len(wps_ie) > 0) { wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie);#ifdef CONFIG_WPS_UPNP /* FIX: what exactly should be included in the WLANEvent? * WPS attributes? Full ProbeReq frame? */ upnp_wps_device_send_wlan_event(hapd->wps_upnp, addr, UPNP_WPS_WLANEVENT_TYPE_PROBE, wps_ie);#endif /* CONFIG_WPS_UPNP */ } wpabuf_free(wps_ie);}#ifdef CONFIG_WPS_UPNPstatic struct wpabuf *hostapd_rx_req_get_device_info(void *priv, struct upnp_wps_peer *peer){ struct hostapd_data *hapd = priv; struct wps_config cfg; struct wps_data *wps; enum wsc_op_code op_code; struct wpabuf *m1; /* * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS * registration over UPnP with the AP acting as an Enrollee. It should * be noted that this is frequently used just to get the device data, * i.e., there may not be any intent to actually complete the * registration. */ if (peer->wps) wps_deinit(peer->wps); os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = hapd->wps; cfg.pin = (u8 *) hapd->conf->ap_pin; cfg.pin_len = os_strlen(hapd->conf->ap_pin); wps = wps_init(&cfg); if (wps == NULL) return NULL; m1 = wps_get_msg(wps, &op_code); if (m1 == NULL) { wps_deinit(wps); return NULL; } peer->wps = wps; return m1;}static struct wpabuf *hostapd_rx_req_put_message(void *priv, struct upnp_wps_peer *peer, const struct wpabuf *msg){ enum wps_process_res res; enum wsc_op_code op_code; /* PutMessage: msg = InMessage, return OutMessage */ res = wps_process_msg(peer->wps, WSC_UPnP, msg); if (res == WPS_FAILURE) return NULL; return wps_get_msg(peer->wps, &op_code);}static struct wpabuf *hostapd_rx_req_get_ap_settings(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return NULL;}static int hostapd_rx_req_set_ap_settings(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_rx_req_del_ap_settings(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static struct wpabuf *hostapd_rx_req_get_sta_settings(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return NULL;}static int hostapd_rx_req_set_sta_settings(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_rx_req_del_sta_settings(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_rx_req_put_wlan_response( void *priv, enum upnp_wps_wlanevent_type ev_type, const u8 *mac_addr, const struct wpabuf *msg, enum wps_msg_type msg_type){ struct hostapd_data *hapd = priv; struct sta_info *sta; struct upnp_pending_message *p; wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr=" MACSTR, ev_type, MAC2STR(mac_addr)); wpa_hexdump_ascii(MSG_MSGDUMP, "WPS UPnP: PutWLANResponse NewMessage", wpabuf_head(msg), wpabuf_len(msg)); if (ev_type != UPNP_WPS_WLANEVENT_TYPE_EAP) { wpa_printf(MSG_DEBUG, "WPS UPnP: Ignored unexpected " "PutWLANResponse WLANEventType %d", ev_type); return -1; } /* * EAP response to ongoing to WPS Registration. Send it to EAP-WSC * server implementation for delivery to the peer. */ sta = ap_get_sta(hapd, mac_addr); if (!sta) { /* * Workaround - Intel wsccmd uses bogus NewWLANEventMAC: * Pick STA that is in an ongoing WPS registration without * checking the MAC address. */ wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found based " "on NewWLANEventMAC; try wildcard match"); for (sta = hapd->sta_list; sta; sta = sta->next) { if (sta->eapol_sm && (sta->flags & WLAN_STA_WPS)) break; } } if (!sta) { wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found"); return 0; } p = os_zalloc(sizeof(*p)); if (p == NULL) return -1; os_memcpy(p->addr, sta->addr, ETH_ALEN); p->msg = wpabuf_dup(msg); p->type = msg_type; p->next = hapd->wps->upnp_msgs; hapd->wps->upnp_msgs = p; return eapol_auth_eap_pending_cb(sta->eapol_sm, sta->eapol_sm->eap);}static int hostapd_rx_req_set_selected_registrar(void *priv, const struct wpabuf *msg){ struct hostapd_data *hapd = priv; return wps_registrar_set_selected_registrar(hapd->wps->registrar, msg);}static int hostapd_rx_req_reboot_ap(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_rx_req_reset_ap(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_rx_req_reboot_sta(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_rx_req_reset_sta(void *priv, const struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS UPnP: TODO %s", __func__); return -1;}static int hostapd_wps_upnp_init(struct hostapd_data *hapd, struct wps_context *wps){ struct upnp_wps_device_ctx *ctx; if (!hapd->conf->upnp_iface) return 0; ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) return -1; ctx->rx_req_get_device_info = hostapd_rx_req_get_device_info; ctx->rx_req_put_message = hostapd_rx_req_put_message; ctx->rx_req_get_ap_settings = hostapd_rx_req_get_ap_settings; ctx->rx_req_set_ap_settings = hostapd_rx_req_set_ap_settings; ctx->rx_req_del_ap_settings = hostapd_rx_req_del_ap_settings; ctx->rx_req_get_sta_settings = hostapd_rx_req_get_sta_settings; ctx->rx_req_set_sta_settings = hostapd_rx_req_set_sta_settings; ctx->rx_req_del_sta_settings = hostapd_rx_req_del_sta_settings; ctx->rx_req_put_wlan_response = hostapd_rx_req_put_wlan_response; ctx->rx_req_set_selected_registrar = hostapd_rx_req_set_selected_registrar; ctx->rx_req_reboot_ap = hostapd_rx_req_reboot_ap; ctx->rx_req_reset_ap = hostapd_rx_req_reset_ap; ctx->rx_req_reboot_sta = hostapd_rx_req_reboot_sta; ctx->rx_req_reset_sta = hostapd_rx_req_reset_sta; hapd->wps_upnp = upnp_wps_device_init(ctx, wps, hapd); if (hapd->wps_upnp == NULL) { os_free(ctx); return -1; } wps->wps_upnp = hapd->wps_upnp; if (upnp_wps_device_start(hapd->wps_upnp, hapd->conf->upnp_iface)) { upnp_wps_device_deinit(hapd->wps_upnp); hapd->wps_upnp = NULL; return -1; } return 0;}static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd){ upnp_wps_device_deinit(hapd->wps_upnp);}#endif /* CONFIG_WPS_UPNP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -