WPS: Added option to disable AP auto-config on first registration
This operation can now be moved into an external program by configuring hostapd with wps_cred_processing=1 and skip_cred_build=1. A new ctrl_iface message (WPS-REG-SUCCESS <Enrollee MAC addr> <UUID-E>) will be used to notify external programs of each successful registration and that can be used as a tricker to move from unconfigured to configured state.
This commit is contained in:
parent
d745c7cc1a
commit
aabe26a136
5 changed files with 62 additions and 2 deletions
|
@ -954,6 +954,8 @@ own_ip_addr=127.0.0.1
|
||||||
# external program(s)
|
# external program(s)
|
||||||
# 2 = process received credentials internally and pass them over ctrl_iface
|
# 2 = process received credentials internally and pass them over ctrl_iface
|
||||||
# to external program(s)
|
# to external program(s)
|
||||||
|
# Note: With wps_cred_processing=1, skip_cred_build should be set to 1 and
|
||||||
|
# extra_cred be used to provide the Credential data for Enrollees.
|
||||||
#wps_cred_processing=0
|
#wps_cred_processing=0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -152,6 +152,18 @@ static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
|
||||||
|
const u8 *uuid_e)
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = ctx;
|
||||||
|
char uuid[40];
|
||||||
|
if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
|
||||||
|
return;
|
||||||
|
wpa_msg(hapd, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s",
|
||||||
|
MAC2STR(mac_addr), uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int str_starts(const char *str, const char *start)
|
static int str_starts(const char *str, const char *start)
|
||||||
{
|
{
|
||||||
return os_strncmp(str, start, os_strlen(start)) == 0;
|
return os_strncmp(str, start, os_strlen(start)) == 0;
|
||||||
|
@ -531,10 +543,13 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
||||||
cfg.new_psk_cb = hostapd_wps_new_psk_cb;
|
cfg.new_psk_cb = hostapd_wps_new_psk_cb;
|
||||||
cfg.set_ie_cb = hostapd_wps_set_ie_cb;
|
cfg.set_ie_cb = hostapd_wps_set_ie_cb;
|
||||||
cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
|
cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
|
||||||
|
cfg.reg_success_cb = hostapd_wps_reg_success_cb;
|
||||||
cfg.cb_ctx = hapd;
|
cfg.cb_ctx = hapd;
|
||||||
cfg.skip_cred_build = conf->skip_cred_build;
|
cfg.skip_cred_build = conf->skip_cred_build;
|
||||||
cfg.extra_cred = conf->extra_cred;
|
cfg.extra_cred = conf->extra_cred;
|
||||||
cfg.extra_cred_len = conf->extra_cred_len;
|
cfg.extra_cred_len = conf->extra_cred_len;
|
||||||
|
cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
|
||||||
|
conf->skip_cred_build;
|
||||||
|
|
||||||
wps->registrar = wps_registrar_init(wps, &cfg);
|
wps->registrar = wps_registrar_init(wps, &cfg);
|
||||||
if (wps->registrar == NULL) {
|
if (wps->registrar == NULL) {
|
||||||
|
|
|
@ -70,6 +70,7 @@ extern "C" {
|
||||||
/* hostapd control interface - fixed message prefixes */
|
/* hostapd control interface - fixed message prefixes */
|
||||||
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
|
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
|
||||||
#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
|
#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
|
||||||
|
#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
|
||||||
|
|
||||||
|
|
||||||
/* wpa_supplicant/hostapd control interface access */
|
/* wpa_supplicant/hostapd control interface access */
|
||||||
|
|
|
@ -205,6 +205,18 @@ struct wps_registrar_config {
|
||||||
void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
|
void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
|
||||||
const struct wps_device_data *dev);
|
const struct wps_device_data *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reg_success_cb - Callback for reporting successful registration
|
||||||
|
* @ctx: Higher layer context data (cb_ctx)
|
||||||
|
* @mac_addr: MAC address of the Enrollee
|
||||||
|
* @uuid_e: UUID-E of the Enrollee
|
||||||
|
*
|
||||||
|
* This callback is called whenever an Enrollee completes registration
|
||||||
|
* successfully.
|
||||||
|
*/
|
||||||
|
void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
|
||||||
|
const u8 *uuid_e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cb_ctx: Higher layer context data for Registrar callbacks
|
* cb_ctx: Higher layer context data for Registrar callbacks
|
||||||
*/
|
*/
|
||||||
|
@ -234,6 +246,18 @@ struct wps_registrar_config {
|
||||||
* extra_cred_len: Length of extra_cred in octets
|
* extra_cred_len: Length of extra_cred in octets
|
||||||
*/
|
*/
|
||||||
size_t extra_cred_len;
|
size_t extra_cred_len;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disable_auto_conf - Disable auto-configuration on first registration
|
||||||
|
*
|
||||||
|
* By default, the AP that is started in not configured state will
|
||||||
|
* generate a random PSK and move to configured state when the first
|
||||||
|
* registration protocol run is completed successfully. This option can
|
||||||
|
* be used to disable this functionality and leave it up to an external
|
||||||
|
* program to take care of configuration. This requires the extra_cred
|
||||||
|
* to be set with a suitable Credential and skip_cred_build being used.
|
||||||
|
*/
|
||||||
|
int disable_auto_conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,8 @@ struct wps_registrar {
|
||||||
const u8 *probe_resp_ie, size_t probe_resp_ie_len);
|
const u8 *probe_resp_ie, size_t probe_resp_ie_len);
|
||||||
void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
|
void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
|
||||||
const struct wps_device_data *dev);
|
const struct wps_device_data *dev);
|
||||||
|
void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
|
||||||
|
const u8 *uuid_e);
|
||||||
void *cb_ctx;
|
void *cb_ctx;
|
||||||
|
|
||||||
struct wps_uuid_pin *pins;
|
struct wps_uuid_pin *pins;
|
||||||
|
@ -92,6 +94,7 @@ struct wps_registrar {
|
||||||
|
|
||||||
int skip_cred_build;
|
int skip_cred_build;
|
||||||
struct wpabuf *extra_cred;
|
struct wpabuf *extra_cred;
|
||||||
|
int disable_auto_conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,6 +328,7 @@ wps_registrar_init(struct wps_context *wps,
|
||||||
reg->new_psk_cb = cfg->new_psk_cb;
|
reg->new_psk_cb = cfg->new_psk_cb;
|
||||||
reg->set_ie_cb = cfg->set_ie_cb;
|
reg->set_ie_cb = cfg->set_ie_cb;
|
||||||
reg->pin_needed_cb = cfg->pin_needed_cb;
|
reg->pin_needed_cb = cfg->pin_needed_cb;
|
||||||
|
reg->reg_success_cb = cfg->reg_success_cb;
|
||||||
reg->cb_ctx = cfg->cb_ctx;
|
reg->cb_ctx = cfg->cb_ctx;
|
||||||
reg->skip_cred_build = cfg->skip_cred_build;
|
reg->skip_cred_build = cfg->skip_cred_build;
|
||||||
if (cfg->extra_cred) {
|
if (cfg->extra_cred) {
|
||||||
|
@ -335,6 +339,7 @@ wps_registrar_init(struct wps_context *wps,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
reg->disable_auto_conf = cfg->disable_auto_conf;
|
||||||
|
|
||||||
if (wps_set_ie(reg)) {
|
if (wps_set_ie(reg)) {
|
||||||
wps_registrar_deinit(reg);
|
wps_registrar_deinit(reg);
|
||||||
|
@ -630,6 +635,16 @@ static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
|
||||||
|
const u8 *uuid_e)
|
||||||
|
{
|
||||||
|
if (reg->reg_success_cb == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wps_cb_set_ie(struct wps_registrar *reg,
|
static int wps_cb_set_ie(struct wps_registrar *reg,
|
||||||
const struct wpabuf *beacon_ie,
|
const struct wpabuf *beacon_ie,
|
||||||
const struct wpabuf *probe_resp_ie)
|
const struct wpabuf *probe_resp_ie)
|
||||||
|
@ -983,7 +998,8 @@ static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
|
||||||
/* Set MAC address in the Credential to be the AP's address (BSSID) */
|
/* Set MAC address in the Credential to be the AP's address (BSSID) */
|
||||||
os_memcpy(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN);
|
os_memcpy(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN);
|
||||||
|
|
||||||
if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap) {
|
if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
|
||||||
|
!wps->wps->registrar->disable_auto_conf) {
|
||||||
u8 r[16];
|
u8 r[16];
|
||||||
/* Generate a random passphrase */
|
/* Generate a random passphrase */
|
||||||
if (os_get_random(r, sizeof(r)) < 0)
|
if (os_get_random(r, sizeof(r)) < 0)
|
||||||
|
@ -2118,7 +2134,7 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
|
wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
|
||||||
|
|
||||||
if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
|
if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
|
||||||
wps->wps->ap) {
|
wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
|
||||||
struct wps_credential cred;
|
struct wps_credential cred;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
|
wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
|
||||||
|
@ -2160,6 +2176,8 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
|
||||||
wps->new_psk = NULL;
|
wps->new_psk = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
|
||||||
|
|
||||||
if (wps->pbc) {
|
if (wps->pbc) {
|
||||||
wps_registrar_remove_pbc_session(wps->wps->registrar,
|
wps_registrar_remove_pbc_session(wps->wps->registrar,
|
||||||
wps->mac_addr_e, wps->uuid_e);
|
wps->mac_addr_e, wps->uuid_e);
|
||||||
|
|
Loading…
Reference in a new issue