WPS: Add support for setting timeout for PIN
hostapd_cli wps_pin command can now have an optional timeout parameter that sets the PIN lifetime in seconds. This can be used to reduce the likelihood of someone else using the PIN should an active PIN be left in the Registrar.
This commit is contained in:
parent
b63303b864
commit
077a781f7a
9 changed files with 84 additions and 19 deletions
|
@ -144,7 +144,7 @@ static void * eap_wsc_init(struct eap_sm *sm)
|
|||
|
||||
if (registrar && cfg.pin) {
|
||||
wps_registrar_add_pin(data->wps_ctx->registrar, NULL,
|
||||
cfg.pin, cfg.pin_len);
|
||||
cfg.pin, cfg.pin_len, 0);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
|
|
@ -552,7 +552,7 @@ wps_registrar_init(struct wps_context *wps,
|
|||
const struct wps_registrar_config *cfg);
|
||||
void wps_registrar_deinit(struct wps_registrar *reg);
|
||||
int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
|
||||
const u8 *pin, size_t pin_len);
|
||||
const u8 *pin, size_t pin_len, int timeout);
|
||||
int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid);
|
||||
int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid);
|
||||
int wps_registrar_button_pushed(struct wps_registrar *reg);
|
||||
|
|
|
@ -32,7 +32,10 @@ struct wps_uuid_pin {
|
|||
int wildcard_uuid;
|
||||
u8 *pin;
|
||||
size_t pin_len;
|
||||
int locked;
|
||||
#define PIN_LOCKED BIT(0)
|
||||
#define PIN_EXPIRES BIT(1)
|
||||
int flags;
|
||||
struct os_time expiration;
|
||||
};
|
||||
|
||||
|
||||
|
@ -413,10 +416,11 @@ void wps_registrar_deinit(struct wps_registrar *reg)
|
|||
* @uuid: UUID-E or %NULL for wildcard (any UUID)
|
||||
* @pin: PIN (Device Password)
|
||||
* @pin_len: Length of pin in octets
|
||||
* @timeout: Time (in seconds) when the PIN will be invalidated; 0 = no timeout
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
|
||||
const u8 *pin, size_t pin_len)
|
||||
const u8 *pin, size_t pin_len, int timeout)
|
||||
{
|
||||
struct wps_uuid_pin *p;
|
||||
|
||||
|
@ -435,10 +439,17 @@ int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
|
|||
os_memcpy(p->pin, pin, pin_len);
|
||||
p->pin_len = pin_len;
|
||||
|
||||
if (timeout) {
|
||||
p->flags |= PIN_EXPIRES;
|
||||
os_get_time(&p->expiration);
|
||||
p->expiration.sec += timeout;
|
||||
}
|
||||
|
||||
p->next = reg->pins;
|
||||
reg->pins = p;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "WPS: A new PIN configured");
|
||||
wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
|
||||
timeout);
|
||||
wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
|
||||
wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
|
||||
reg->selected_registrar = 1;
|
||||
|
@ -449,6 +460,34 @@ int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
|
|||
}
|
||||
|
||||
|
||||
static void wps_registrar_expire_pins(struct wps_registrar *reg)
|
||||
{
|
||||
struct wps_uuid_pin *pin, *prev, *del;
|
||||
struct os_time now;
|
||||
|
||||
os_get_time(&now);
|
||||
prev = NULL;
|
||||
pin = reg->pins;
|
||||
while (pin) {
|
||||
if ((pin->flags & PIN_EXPIRES) &&
|
||||
os_time_before(&pin->expiration, &now)) {
|
||||
if (prev == NULL)
|
||||
reg->pins = pin->next;
|
||||
else
|
||||
prev->next = pin->next;
|
||||
del = pin;
|
||||
pin = pin->next;
|
||||
wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
|
||||
del->uuid, WPS_UUID_LEN);
|
||||
wps_free_pin(del);
|
||||
continue;
|
||||
}
|
||||
prev = pin;
|
||||
pin = pin->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wps_registrar_invalidate_pin - Invalidate a PIN for a specific UUID-E
|
||||
* @reg: Registrar data from wps_registrar_init()
|
||||
|
@ -485,6 +524,8 @@ static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
|
|||
{
|
||||
struct wps_uuid_pin *pin;
|
||||
|
||||
wps_registrar_expire_pins(reg);
|
||||
|
||||
pin = reg->pins;
|
||||
while (pin) {
|
||||
if (!pin->wildcard_uuid &&
|
||||
|
@ -516,13 +557,13 @@ static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
|
|||
* Lock the PIN to avoid attacks based on concurrent re-use of the PIN
|
||||
* that could otherwise avoid PIN invalidations.
|
||||
*/
|
||||
if (pin->locked) {
|
||||
if (pin->flags & PIN_LOCKED) {
|
||||
wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
|
||||
"allow concurrent re-use");
|
||||
return NULL;
|
||||
}
|
||||
*pin_len = pin->pin_len;
|
||||
pin->locked = 1;
|
||||
pin->flags |= PIN_LOCKED;
|
||||
return pin->pin;
|
||||
}
|
||||
|
||||
|
@ -549,7 +590,7 @@ int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
|
|||
"wildcard PIN");
|
||||
return wps_registrar_invalidate_pin(reg, uuid);
|
||||
}
|
||||
pin->locked = 0;
|
||||
pin->flags &= ~PIN_LOCKED;
|
||||
return 0;
|
||||
}
|
||||
pin = pin->next;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue