wpa_supplicant AP: Add preliminary support for WPS Internal Registrar
When in AP mode, wpa_supplicant is now enabling WPS (only Internal Registrar). wpa_cli wps_pbc and wps_pin commands can be used to initiate WPS negotiation similarly to how this is done in station mode (though, the BSSID parameter is ignored).
This commit is contained in:
parent
a8d6ffa48f
commit
3ec97afe57
5 changed files with 78 additions and 8 deletions
|
@ -12,8 +12,8 @@
|
||||||
* See README and COPYING for more details.
|
* See README and COPYING for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EAP_METHODS_H
|
#ifndef EAP_SERVER_METHODS_H
|
||||||
#define EAP_METHODS_H
|
#define EAP_SERVER_METHODS_H
|
||||||
|
|
||||||
const struct eap_method * eap_server_get_eap_method(int vendor,
|
const struct eap_method * eap_server_get_eap_method(int vendor,
|
||||||
EapType method);
|
EapType method);
|
||||||
|
@ -26,4 +26,4 @@ EapType eap_server_get_type(const char *name, int *vendor);
|
||||||
int eap_server_register_methods(void);
|
int eap_server_register_methods(void);
|
||||||
void eap_server_unregister_methods(void);
|
void eap_server_unregister_methods(void);
|
||||||
|
|
||||||
#endif /* EAP_METHODS_H */
|
#endif /* EAP_SERVER_METHODS_H */
|
||||||
|
|
|
@ -21,9 +21,11 @@
|
||||||
#ifdef NEED_MLME
|
#ifdef NEED_MLME
|
||||||
#include "../hostapd/ieee802_11.h"
|
#include "../hostapd/ieee802_11.h"
|
||||||
#endif /* NEED_MLME */
|
#endif /* NEED_MLME */
|
||||||
|
#include "../hostapd/wps_hostapd.h"
|
||||||
#include "eap_common/eap_defs.h"
|
#include "eap_common/eap_defs.h"
|
||||||
#include "eap_server/eap_methods.h"
|
#include "eap_server/eap_methods.h"
|
||||||
#include "eap_common/eap_wsc_common.h"
|
#include "eap_common/eap_wsc_common.h"
|
||||||
|
#include "wps/wps.h"
|
||||||
#include "config_ssid.h"
|
#include "config_ssid.h"
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
|
@ -382,6 +384,17 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
|
||||||
else
|
else
|
||||||
bss->ssid.security_policy = SECURITY_PLAINTEXT;
|
bss->ssid.security_policy = SECURITY_PLAINTEXT;
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
/*
|
||||||
|
* Enable WPS by default, but require user interaction to actually use
|
||||||
|
* it. Only the internal Registrar is supported.
|
||||||
|
*/
|
||||||
|
bss->eap_server = 1;
|
||||||
|
bss->wps_state = 2;
|
||||||
|
bss->ap_setup_locked = 1;
|
||||||
|
bss->config_methods = os_strdup("display push_button");
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,3 +520,31 @@ void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
hostapd_eapol_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
|
hostapd_eapol_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_WPS
|
||||||
|
|
||||||
|
int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
||||||
|
{
|
||||||
|
return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
const char *pin, char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int ret, ret_len = 0;
|
||||||
|
|
||||||
|
if (pin == NULL) {
|
||||||
|
unsigned int rpin = wps_generate_pin();
|
||||||
|
ret_len = os_snprintf(buf, buflen, "%d", rpin);
|
||||||
|
pin = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], "any", pin);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
return ret_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_WPS */
|
||||||
|
|
|
@ -21,5 +21,8 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
|
||||||
void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s);
|
void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s);
|
||||||
void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
|
void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
|
||||||
const u8 *src_addr, const u8 *buf, size_t len);
|
const u8 *src_addr, const u8 *buf, size_t len);
|
||||||
|
int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid);
|
||||||
|
int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
|
const char *pin, char *buf, size_t buflen);
|
||||||
|
|
||||||
#endif /* AP_H */
|
#endif /* AP_H */
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "wps_supplicant.h"
|
#include "wps_supplicant.h"
|
||||||
#include "wps/wps.h"
|
#include "wps/wps.h"
|
||||||
#include "ibss_rsn.h"
|
#include "ibss_rsn.h"
|
||||||
|
#include "ap.h"
|
||||||
|
|
||||||
extern struct wpa_driver_ops *wpa_drivers[];
|
extern struct wpa_driver_ops *wpa_drivers[];
|
||||||
|
|
||||||
|
@ -150,18 +151,22 @@ static int wpa_supplicant_ctrl_iface_ft_ds(
|
||||||
static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
|
static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
|
||||||
char *cmd)
|
char *cmd)
|
||||||
{
|
{
|
||||||
u8 bssid[ETH_ALEN];
|
u8 bssid[ETH_ALEN], *_bssid = bssid;
|
||||||
|
|
||||||
if (cmd == NULL || os_strcmp(cmd, "any") == 0)
|
if (cmd == NULL || os_strcmp(cmd, "any") == 0)
|
||||||
return wpas_wps_start_pbc(wpa_s, NULL);
|
_bssid = NULL;
|
||||||
|
else if (hwaddr_aton(cmd, bssid)) {
|
||||||
if (hwaddr_aton(cmd, bssid)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
|
||||||
cmd);
|
cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wpas_wps_start_pbc(wpa_s, bssid);
|
#ifdef CONFIG_AP
|
||||||
|
if (wpa_s->ap_iface)
|
||||||
|
return wpa_supplicant_ap_wps_pbc(wpa_s, _bssid);
|
||||||
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
|
return wpas_wps_start_pbc(wpa_s, _bssid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -185,6 +190,12 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_AP
|
||||||
|
if (wpa_s->ap_iface)
|
||||||
|
return wpa_supplicant_ap_wps_pin(wpa_s, _bssid, pin,
|
||||||
|
buf, buflen);
|
||||||
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
if (pin) {
|
if (pin) {
|
||||||
ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
|
ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "eapol_supp/eapol_supp_sm.h"
|
#include "eapol_supp/eapol_supp_sm.h"
|
||||||
#include "eap_peer/eap.h"
|
#include "eap_peer/eap.h"
|
||||||
|
#include "eap_server/eap_methods.h"
|
||||||
#include "wpa.h"
|
#include "wpa.h"
|
||||||
#include "eloop.h"
|
#include "eloop.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -2118,6 +2119,17 @@ struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_AP
|
||||||
|
ret = eap_server_register_methods();
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_ERROR, "Failed to register EAP server methods");
|
||||||
|
if (ret == -2)
|
||||||
|
wpa_printf(MSG_ERROR, "Two or more EAP methods used "
|
||||||
|
"the same EAP type.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
global = os_zalloc(sizeof(*global));
|
global = os_zalloc(sizeof(*global));
|
||||||
if (global == NULL)
|
if (global == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2241,6 +2253,9 @@ void wpa_supplicant_deinit(struct wpa_global *global)
|
||||||
wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface);
|
wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface);
|
||||||
|
|
||||||
eap_peer_unregister_methods();
|
eap_peer_unregister_methods();
|
||||||
|
#ifdef CONFIG_AP
|
||||||
|
eap_server_unregister_methods();
|
||||||
|
#endif /* CONFIG_AP */
|
||||||
|
|
||||||
for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
|
for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
|
||||||
if (!global->drv_priv[i])
|
if (!global->drv_priv[i])
|
||||||
|
|
Loading…
Reference in a new issue