hostapd_cli wps_pin 53b63a98-d29e-4457-a2ed-094d7e6a669c 12345670
+If the UUID-E is not available (e.g., Enrollee waits for the Registrar
+to be selected before connecting), wildcard UUID may be used to allow the PIN to be used once with any UUID:
+
+hostapd_cli wps_pin any 12345670
+
+
After this, the Enrollee can connect to the AP again and complete WPS
negotiation. At that point, a new, random WPA PSK is generated for the
client device and the client can then use that key to connect to the
const char *pin)
{
u8 u[UUID_LEN];
- if (hapd->wps == NULL || uuid_str2bin(uuid, u))
+ 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, u,
+ return wps_registrar_add_pin(hapd->wps->registrar, any ? NULL : u,
(const u8 *) pin, os_strlen(pin));
}
struct wps_uuid_pin {
struct wps_uuid_pin *next;
u8 uuid[WPS_UUID_LEN];
+ int wildcard_uuid;
u8 *pin;
size_t pin_len;
int locked;
p = os_zalloc(sizeof(*p));
if (p == NULL)
return -1;
- os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
+ if (uuid == NULL)
+ p->wildcard_uuid = 1;
+ else
+ os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
p->pin = os_malloc(pin_len);
if (p->pin == NULL) {
os_free(p);
pin = reg->pins;
while (pin) {
- if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
- /*
- * Lock the PIN to avoid attacks based on concurrent
- * re-use of the PIN that could otherwise avoid PIN
- * invalidations.
- */
- if (pin->locked) {
- wpa_printf(MSG_DEBUG, "WPS: Selected PIN "
- "locked - do not allow concurrent "
- "re-use");
- return NULL;
+ if (!pin->wildcard_uuid &&
+ os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
+ break;
+ pin = pin->next;
+ }
+
+ if (!pin) {
+ /* Check for wildcard UUIDs since none of the UUID-specific
+ * PINs matched */
+ pin = reg->pins;
+ while (pin) {
+ if (pin->wildcard_uuid == 1) {
+ wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
+ "PIN. Assigned it for this UUID-E");
+ pin->wildcard_uuid = 2;
+ os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
+ break;
}
- *pin_len = pin->pin_len;
- pin->locked = 1;
- return pin->pin;
+ pin = pin->next;
}
- pin = pin->next;
}
- return NULL;
+ if (!pin)
+ return NULL;
+
+ /*
+ * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
+ * that could otherwise avoid PIN invalidations.
+ */
+ if (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;
+ return pin->pin;
}
pin = reg->pins;
while (pin) {
if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
+ if (pin->wildcard_uuid == 2) {
+ wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
+ "wildcard PIN");
+ return wps_registrar_invalidate_pin(reg, uuid);
+ }
pin->locked = 0;
return 0;
}