WPS 2.0: Convert new attributes into WFA vendor extension

The WSC 2.0 specification moved to use another design for the new
attributes to avoid backwards compatibility issues with some
deployed implementations.
This commit is contained in:
Jouni Malinen 2010-07-29 10:23:20 -07:00 committed by Jouni Malinen
parent ac4dcaf7bf
commit fdc9eeb175
9 changed files with 185 additions and 108 deletions

View file

@ -367,7 +367,7 @@ struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type)
if (wps_build_version(ie) || if (wps_build_version(ie) ||
wps_build_req_type(ie, req_type) || wps_build_req_type(ie, req_type) ||
wps_build_version2(ie)) { wps_build_wfa_ext(ie, 0, NULL, 0)) {
wpabuf_free(ie); wpabuf_free(ie);
return NULL; return NULL;
} }
@ -401,7 +401,7 @@ struct wpabuf * wps_build_assoc_resp_ie(void)
if (wps_build_version(ie) || if (wps_build_version(ie) ||
wps_build_resp_type(ie, WPS_RESP_AP) || wps_build_resp_type(ie, WPS_RESP_AP) ||
wps_build_version2(ie)) { wps_build_wfa_ext(ie, 0, NULL, 0)) {
wpabuf_free(ie); wpabuf_free(ie);
return NULL; return NULL;
} }
@ -475,13 +475,11 @@ struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON : wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
DEV_PW_DEFAULT) || DEV_PW_DEFAULT) ||
#ifdef CONFIG_WPS2 #ifdef CONFIG_WPS2
wps_build_version2(ie) ||
wps_build_manufacturer(dev, ie) || wps_build_manufacturer(dev, ie) ||
wps_build_model_name(dev, ie) || wps_build_model_name(dev, ie) ||
wps_build_model_number(dev, ie) || wps_build_model_number(dev, ie) ||
wps_build_dev_name(dev, ie) || wps_build_dev_name(dev, ie) ||
(req_type == WPS_REQ_ENROLLEE && wps_build_wfa_ext(ie, req_type == WPS_REQ_ENROLLEE, NULL, 0)
wps_build_req_to_enroll(ie))
#else /* CONFIG_WPS2 */ #else /* CONFIG_WPS2 */
0 0
#endif /* CONFIG_WPS2 */ #endif /* CONFIG_WPS2 */

View file

@ -172,13 +172,43 @@ int wps_build_version(struct wpabuf *msg)
} }
int wps_build_version2(struct wpabuf *msg) int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
const u8 *auth_macs, size_t auth_macs_count)
{ {
#ifdef CONFIG_WPS2 #ifdef CONFIG_WPS2
u8 *len;
wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
len = wpabuf_put(msg, 2); /* to be filled */
wpabuf_put_be24(msg, WPS_VENDOR_ID_WFA);
wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION); wpa_printf(MSG_DEBUG, "WPS: * Version2 (0x%x)", WPS_VERSION);
wpabuf_put_be16(msg, ATTR_VERSION2); wpabuf_put_u8(msg, WFA_ELEM_VERSION2);
wpabuf_put_be16(msg, 1); wpabuf_put_u8(msg, 1);
wpabuf_put_u8(msg, WPS_VERSION); wpabuf_put_u8(msg, WPS_VERSION);
if (req_to_enroll) {
wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)");
wpabuf_put_u8(msg, WFA_ELEM_REQUEST_TO_ENROLL);
wpabuf_put_u8(msg, 1);
wpabuf_put_u8(msg, 1);
}
if (auth_macs && auth_macs_count) {
size_t i;
wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)",
(int) auth_macs_count);
wpabuf_put_u8(msg, WFA_ELEM_AUTHORIZEDMACS);
wpabuf_put_u8(msg, auth_macs_count * ETH_ALEN);
wpabuf_put_data(msg, auth_macs, auth_macs_count * ETH_ALEN);
for (i = 0; i < auth_macs_count; i++)
wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR,
MAC2STR(&auth_macs[i * ETH_ALEN]));
}
WPA_PUT_BE16(len, (u8 *) wpabuf_put(msg, 0) - len - 2);
#endif /* CONFIG_WPS2 */
#ifdef CONFIG_WPS_EXTENSIBILITY_TESTING #ifdef CONFIG_WPS_EXTENSIBILITY_TESTING
wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra " wpa_printf(MSG_DEBUG, "WPS: * Extensibility Testing - extra "
"attribute"; "attribute";
@ -186,7 +216,6 @@ int wps_build_version2(struct wpabuf *msg)
wpabuf_put_be16(msg, 1); wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, 42); wpabuf_put_u8(msg, 42);
#endif /* CONFIG_WPS_EXTENSIBILITY_TESTING */ #endif /* CONFIG_WPS_EXTENSIBILITY_TESTING */
#endif /* CONFIG_WPS2 */
return 0; return 0;
} }
@ -349,18 +378,6 @@ int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps)
#endif /* CONFIG_WPS_OOB */ #endif /* CONFIG_WPS_OOB */
int wps_build_req_to_enroll(struct wpabuf *msg)
{
#ifdef CONFIG_WPS2
wpa_printf(MSG_DEBUG, "WPS: * Request to Enroll (1)");
wpabuf_put_be16(msg, ATTR_REQUEST_TO_ENROLL);
wpabuf_put_be16(msg, 1);
wpabuf_put_u8(msg, 1);
#endif /* CONFIG_WPS2 */
return 0;
}
/* Encapsulate WPS IE data with one (or more, if needed) IE headers */ /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
struct wpabuf * wps_ie_encapsulate(struct wpabuf *data) struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
{ {

View file

@ -22,6 +22,102 @@
#endif /* CONFIG_WPS_STRICT */ #endif /* CONFIG_WPS_STRICT */
static int wps_set_vendor_ext_wfa_subelem(struct wps_parse_attr *attr,
u8 id, u8 len, const u8 *pos)
{
wpa_printf(MSG_MSGDUMP, "WPS: WFA subelement id=%u len=%u",
id, len);
switch (id) {
case WFA_ELEM_VERSION2:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Version2 length "
"%u", len);
return -1;
}
attr->version2 = pos;
break;
case WFA_ELEM_AUTHORIZEDMACS:
attr->authorized_macs = pos;
attr->authorized_macs_len = len;
break;
case WFA_ELEM_NETWORK_KEY_SHAREABLE:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key "
"Shareable length %u", len);
return -1;
}
attr->network_key_shareable = pos;
break;
case WFA_ELEM_REQUEST_TO_ENROLL:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Request to Enroll "
"length %u", len);
return -1;
}
attr->request_to_enroll = pos;
break;
case WFA_ELEM_SETTINGS_DELAY_TIME:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Settings Delay "
"Time length %u", len);
return -1;
}
attr->settings_delay_time = pos;
break;
default:
wpa_printf(MSG_MSGDUMP, "WPS: Skipped unknown WFA Vendor "
"Extension subelement %u", id);
break;
}
return 0;
}
static int wps_parse_vendor_ext_wfa(struct wps_parse_attr *attr, const u8 *pos,
u16 len)
{
const u8 *end = pos + len;
u8 id, elen;
while (pos + 2 < end) {
id = *pos++;
elen = *pos++;
if (pos + elen > end)
break;
if (wps_set_vendor_ext_wfa_subelem(attr, id, elen, pos) < 0)
return -1;
pos += elen;
}
return 0;
}
static int wps_parse_vendor_ext(struct wps_parse_attr *attr, const u8 *pos,
u16 len)
{
u32 vendor_id;
if (len < 3) {
wpa_printf(MSG_DEBUG, "WPS: Skip invalid Vendor Extension");
return 0;
}
vendor_id = WPA_GET_BE24(pos);
switch (vendor_id) {
case WPS_VENDOR_ID_WFA:
return wps_parse_vendor_ext_wfa(attr, pos + 3, len - 3);
default:
wpa_printf(MSG_MSGDUMP, "WPS: Skip unknown Vendor Extension "
"(Vendor ID %u)", vendor_id);
break;
}
return 0;
}
static int wps_set_attr(struct wps_parse_attr *attr, u16 type, static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
const u8 *pos, u16 len) const u8 *pos, u16 len)
{ {
@ -34,16 +130,6 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
} }
attr->version = pos; attr->version = pos;
break; break;
#ifdef CONFIG_WPS2
case ATTR_VERSION2:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Version2 length "
"%u", len);
return -1;
}
attr->version2 = pos;
break;
#endif /* CONFIG_WPS2 */
case ATTR_MSG_TYPE: case ATTR_MSG_TYPE:
if (len != 1) { if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type " wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type "
@ -412,34 +498,6 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->ap_setup_locked = pos; attr->ap_setup_locked = pos;
break; break;
#ifdef CONFIG_WPS2 #ifdef CONFIG_WPS2
case ATTR_SETTINGS_DELAY_TIME:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Settings Delay "
"Time length %u", len);
return -1;
}
attr->settings_delay_time = pos;
break;
case ATTR_NETWORK_KEY_SHAREABLE:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Network Key "
"Shareable length %u", len);
return -1;
}
attr->network_key_shareable = pos;
break;
case ATTR_REQUEST_TO_ENROLL:
if (len != 1) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Request to Enroll "
"length %u", len);
return -1;
}
attr->request_to_enroll = pos;
break;
case ATTR_AUTHORIZED_MACS:
attr->authorized_macs = pos;
attr->authorized_macs_len = len;
break;
case ATTR_REQUESTED_DEV_TYPE: case ATTR_REQUESTED_DEV_TYPE:
if (len != WPS_DEV_TYPE_LEN) { if (len != WPS_DEV_TYPE_LEN) {
wpa_printf(MSG_DEBUG, "WPS: Invalid Requested Device " wpa_printf(MSG_DEBUG, "WPS: Invalid Requested Device "
@ -456,6 +514,10 @@ static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
attr->num_req_dev_type++; attr->num_req_dev_type++;
break; break;
#endif /* CONFIG_WPS2 */ #endif /* CONFIG_WPS2 */
case ATTR_VENDOR_EXT:
if (wps_parse_vendor_ext(attr, pos, len) < 0)
return -1;
break;
default: default:
wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x " wpa_printf(MSG_DEBUG, "WPS: Unsupported attribute type 0x%x "
"len=%u", type, len); "len=%u", type, len);
@ -491,6 +553,7 @@ int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr)
type, len); type, len);
if (len > end - pos) { if (len > end - pos) {
wpa_printf(MSG_DEBUG, "WPS: Attribute overflow"); wpa_printf(MSG_DEBUG, "WPS: Attribute overflow");
wpa_hexdump_buf(MSG_MSGDUMP, "WPS: Message data", msg);
return -1; return -1;
} }

View file

@ -133,17 +133,21 @@ enum wps_attribute {
ATTR_802_1X_ENABLED = 0x1062, ATTR_802_1X_ENABLED = 0x1062,
ATTR_APPSESSIONKEY = 0x1063, ATTR_APPSESSIONKEY = 0x1063,
ATTR_WEPTRANSMITKEY = 0x1064, ATTR_WEPTRANSMITKEY = 0x1064,
#ifdef CONFIG_WPS2
ATTR_SETTINGS_DELAY_TIME = 0x1065,
ATTR_NETWORK_KEY_SHAREABLE = 0x1066,
ATTR_VERSION2 = 0x1067,
ATTR_REQUEST_TO_ENROLL = 0x1068,
ATTR_AUTHORIZED_MACS = 0x1069,
ATTR_REQUESTED_DEV_TYPE = 0x106a, ATTR_REQUESTED_DEV_TYPE = 0x106a,
#endif /* CONFIG_WPS2 */
ATTR_EXTENSIBILITY_TEST = 0x10fa /* _NOT_ defined in the spec */ ATTR_EXTENSIBILITY_TEST = 0x10fa /* _NOT_ defined in the spec */
}; };
#define WPS_VENDOR_ID_WFA 14122
/* WFA Vendor Extension subelements */
enum {
WFA_ELEM_VERSION2 = 0x00,
WFA_ELEM_AUTHORIZEDMACS = 0x01,
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04
};
/* Device Password ID */ /* Device Password ID */
enum wps_dev_password_id { enum wps_dev_password_id {
DEV_PW_DEFAULT = 0x0000, DEV_PW_DEFAULT = 0x0000,

View file

@ -147,7 +147,7 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
wps_build_dev_password_id(msg, wps->dev_pw_id) || wps_build_dev_password_id(msg, wps->dev_pw_id) ||
wps_build_config_error(msg, WPS_CFG_NO_ERROR) || wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
wps_build_os_version(&wps->wps->dev, msg) || wps_build_os_version(&wps->wps->dev, msg) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }
@ -177,7 +177,7 @@ static struct wpabuf * wps_build_m3(struct wps_data *wps)
wps_build_msg_type(msg, WPS_M3) || wps_build_msg_type(msg, WPS_M3) ||
wps_build_registrar_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) ||
wps_build_e_hash(wps, msg) || wps_build_e_hash(wps, msg) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
@ -210,7 +210,7 @@ static struct wpabuf * wps_build_m5(struct wps_data *wps)
wps_build_e_snonce1(wps, plain) || wps_build_e_snonce1(wps, plain) ||
wps_build_key_wrap_auth(wps, plain) || wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) || wps_build_encr_settings(wps, msg, plain) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(plain); wpabuf_free(plain);
wpabuf_free(msg); wpabuf_free(msg);
@ -313,7 +313,7 @@ static struct wpabuf * wps_build_m7(struct wps_data *wps)
(wps->wps->ap && wps_build_ap_settings(wps, plain)) || (wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
wps_build_key_wrap_auth(wps, plain) || wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) || wps_build_encr_settings(wps, msg, plain) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(plain); wpabuf_free(plain);
wpabuf_free(msg); wpabuf_free(msg);
@ -350,7 +350,7 @@ static struct wpabuf * wps_build_wsc_done(struct wps_data *wps)
wps_build_msg_type(msg, WPS_WSC_DONE) || wps_build_msg_type(msg, WPS_WSC_DONE) ||
wps_build_enrollee_nonce(wps, msg) || wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }
@ -379,7 +379,7 @@ static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
wps_build_msg_type(msg, WPS_WSC_ACK) || wps_build_msg_type(msg, WPS_WSC_ACK) ||
wps_build_enrollee_nonce(wps, msg) || wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }
@ -403,7 +403,7 @@ static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
wps_build_enrollee_nonce(wps, msg) || wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) ||
wps_build_config_error(msg, wps->config_error) || wps_build_config_error(msg, wps->config_error) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }

View file

@ -1366,6 +1366,9 @@ void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
{ {
struct wpabuf *msg; struct wpabuf *msg;
struct wps_er_ap *ap; struct wps_er_ap *ap;
struct wps_registrar *reg = er->wps->registrar;
const u8 *auth_macs;
size_t count;
if (er->skip_set_sel_reg) { if (er->skip_set_sel_reg) {
wpa_printf(MSG_DEBUG, "WPS ER: Skip SetSelectedRegistrar"); wpa_printf(MSG_DEBUG, "WPS ER: Skip SetSelectedRegistrar");
@ -1376,12 +1379,13 @@ void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
if (msg == NULL) if (msg == NULL)
return; return;
auth_macs = wps_authorized_macs(reg, &count);
if (wps_build_version(msg) || if (wps_build_version(msg) ||
wps_er_build_selected_registrar(msg, sel_reg) || wps_er_build_selected_registrar(msg, sel_reg) ||
wps_er_build_dev_password_id(msg, dev_passwd_id) || wps_er_build_dev_password_id(msg, dev_passwd_id) ||
wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) || wps_er_build_sel_reg_config_methods(msg, sel_reg_config_methods) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, auth_macs, count) ||
wps_build_authorized_macs(er->wps->registrar, msg) ||
wps_er_build_uuid_r(msg, er->wps->uuid)) { wps_er_build_uuid_r(msg, er->wps->uuid)) {
wpabuf_free(msg); wpabuf_free(msg);
return; return;

View file

@ -238,7 +238,8 @@ int wps_build_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg);
int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg, int wps_build_encr_settings(struct wps_data *wps, struct wpabuf *msg,
struct wpabuf *plain); struct wpabuf *plain);
int wps_build_version(struct wpabuf *msg); int wps_build_version(struct wpabuf *msg);
int wps_build_version2(struct wpabuf *msg); int wps_build_wfa_ext(struct wpabuf *msg, int req_to_enroll,
const u8 *auth_macs, size_t auth_macs_count);
int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type); int wps_build_msg_type(struct wpabuf *msg, enum wps_msg_type msg_type);
int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg); int wps_build_enrollee_nonce(struct wps_data *wps, struct wpabuf *msg);
int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg); int wps_build_registrar_nonce(struct wps_data *wps, struct wpabuf *msg);
@ -247,7 +248,6 @@ int wps_build_encr_type_flags(struct wps_data *wps, struct wpabuf *msg);
int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg); int wps_build_conn_type_flags(struct wps_data *wps, struct wpabuf *msg);
int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg); int wps_build_assoc_state(struct wps_data *wps, struct wpabuf *msg);
int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps); int wps_build_oob_dev_password(struct wpabuf *msg, struct wps_context *wps);
int wps_build_req_to_enroll(struct wpabuf *msg);
struct wpabuf * wps_ie_encapsulate(struct wpabuf *data); struct wpabuf * wps_ie_encapsulate(struct wpabuf *data);
/* wps_attr_process.c */ /* wps_attr_process.c */
@ -277,7 +277,7 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg);
int wps_device_store(struct wps_registrar *reg, int wps_device_store(struct wps_registrar *reg,
struct wps_device_data *dev, const u8 *uuid); struct wps_device_data *dev, const u8 *uuid);
void wps_registrar_selected_registrar_changed(struct wps_registrar *reg); void wps_registrar_selected_registrar_changed(struct wps_registrar *reg);
int wps_build_authorized_macs(struct wps_registrar *reg, struct wpabuf *msg); const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count);
int wps_registrar_pbc_overlap(struct wps_registrar *reg, int wps_registrar_pbc_overlap(struct wps_registrar *reg,
const u8 *addr, const u8 *uuid_e); const u8 *addr, const u8 *uuid_e);

View file

@ -514,30 +514,19 @@ static int wps_build_config_methods_r(struct wps_registrar *reg,
} }
int wps_build_authorized_macs(struct wps_registrar *reg, struct wpabuf *msg) const u8 * wps_authorized_macs(struct wps_registrar *reg, size_t *count)
{ {
*count = 0;
#ifdef CONFIG_WPS2 #ifdef CONFIG_WPS2
int count = 0, i; while (*count < WPS_MAX_AUTHORIZED_MACS) {
if (is_zero_ether_addr(reg->authorized_macs_union[*count]))
while (count < WPS_MAX_AUTHORIZED_MACS) {
if (is_zero_ether_addr(reg->authorized_macs_union[count]))
break; break;
count++; (*count)++;
} }
if (count == 0)
return 0;
wpa_printf(MSG_DEBUG, "WPS: * AuthorizedMACs (count=%d)", count);
wpabuf_put_be16(msg, ATTR_AUTHORIZED_MACS);
wpabuf_put_be16(msg, count * ETH_ALEN);
wpabuf_put_data(msg, reg->authorized_macs_union, count * ETH_ALEN);
for (i = 0; i < count; i++)
wpa_printf(MSG_DEBUG, "WPS: AuthorizedMAC: " MACSTR,
MAC2STR(reg->authorized_macs_union[i]));
#endif /* CONFIG_WPS2 */ #endif /* CONFIG_WPS2 */
return 0; return (const u8 *) reg->authorized_macs_union;
} }
@ -1016,6 +1005,8 @@ static int wps_set_ie(struct wps_registrar *reg)
{ {
struct wpabuf *beacon; struct wpabuf *beacon;
struct wpabuf *probe; struct wpabuf *probe;
const u8 *auth_macs;
size_t count;
if (reg->set_ie_cb == NULL) if (reg->set_ie_cb == NULL)
return 0; return 0;
@ -1029,6 +1020,8 @@ static int wps_set_ie(struct wps_registrar *reg)
return -1; return -1;
} }
auth_macs = wps_authorized_macs(reg, &count);
wpa_printf(MSG_DEBUG, "WPS: Build Beacon IEs"); wpa_printf(MSG_DEBUG, "WPS: Build Beacon IEs");
if (wps_build_version(beacon) || if (wps_build_version(beacon) ||
@ -1037,8 +1030,7 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_selected_registrar(reg, beacon) || wps_build_selected_registrar(reg, beacon) ||
wps_build_sel_reg_dev_password_id(reg, beacon) || wps_build_sel_reg_dev_password_id(reg, beacon) ||
wps_build_sel_reg_config_methods(reg, beacon) || wps_build_sel_reg_config_methods(reg, beacon) ||
wps_build_version2(beacon) || wps_build_wfa_ext(beacon, 0, auth_macs, count)) {
wps_build_authorized_macs(reg, beacon)) {
wpabuf_free(beacon); wpabuf_free(beacon);
wpabuf_free(probe); wpabuf_free(probe);
return -1; return -1;
@ -1058,8 +1050,7 @@ static int wps_set_ie(struct wps_registrar *reg)
wps_build_device_attrs(&reg->wps->dev, probe) || wps_build_device_attrs(&reg->wps->dev, probe) ||
wps_build_probe_config_methods(reg, probe) || wps_build_probe_config_methods(reg, probe) ||
wps_build_rf_bands(&reg->wps->dev, probe) || wps_build_rf_bands(&reg->wps->dev, probe) ||
wps_build_version2(probe) || wps_build_wfa_ext(probe, 0, auth_macs, count)) {
wps_build_authorized_macs(reg, probe)) {
wpabuf_free(beacon); wpabuf_free(beacon);
wpabuf_free(probe); wpabuf_free(probe);
return -1; return -1;
@ -1499,7 +1490,7 @@ static struct wpabuf * wps_build_m2(struct wps_data *wps)
wps_build_config_error(msg, WPS_CFG_NO_ERROR) || wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
wps_build_dev_password_id(msg, wps->dev_pw_id) || wps_build_dev_password_id(msg, wps->dev_pw_id) ||
wps_build_os_version(&wps->wps->dev, msg) || wps_build_os_version(&wps->wps->dev, msg) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
@ -1539,7 +1530,7 @@ static struct wpabuf * wps_build_m2d(struct wps_data *wps)
wps_build_assoc_state(wps, msg) || wps_build_assoc_state(wps, msg) ||
wps_build_config_error(msg, err) || wps_build_config_error(msg, err) ||
wps_build_os_version(&wps->wps->dev, msg) || wps_build_os_version(&wps->wps->dev, msg) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }
@ -1574,7 +1565,7 @@ static struct wpabuf * wps_build_m4(struct wps_data *wps)
wps_build_r_snonce1(wps, plain) || wps_build_r_snonce1(wps, plain) ||
wps_build_key_wrap_auth(wps, plain) || wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) || wps_build_encr_settings(wps, msg, plain) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(plain); wpabuf_free(plain);
wpabuf_free(msg); wpabuf_free(msg);
@ -1609,7 +1600,7 @@ static struct wpabuf * wps_build_m6(struct wps_data *wps)
wps_build_r_snonce2(wps, plain) || wps_build_r_snonce2(wps, plain) ||
wps_build_key_wrap_auth(wps, plain) || wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) || wps_build_encr_settings(wps, msg, plain) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(plain); wpabuf_free(plain);
wpabuf_free(msg); wpabuf_free(msg);
@ -1646,7 +1637,7 @@ static struct wpabuf * wps_build_m8(struct wps_data *wps)
(!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) || (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
wps_build_key_wrap_auth(wps, plain) || wps_build_key_wrap_auth(wps, plain) ||
wps_build_encr_settings(wps, msg, plain) || wps_build_encr_settings(wps, msg, plain) ||
wps_build_version2(msg) || wps_build_wfa_ext(msg, 0, NULL, 0) ||
wps_build_authenticator(wps, msg)) { wps_build_authenticator(wps, msg)) {
wpabuf_free(plain); wpabuf_free(plain);
wpabuf_free(msg); wpabuf_free(msg);
@ -1673,7 +1664,7 @@ static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
wps_build_msg_type(msg, WPS_WSC_ACK) || wps_build_msg_type(msg, WPS_WSC_ACK) ||
wps_build_enrollee_nonce(wps, msg) || wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }
@ -1697,7 +1688,7 @@ static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
wps_build_enrollee_nonce(wps, msg) || wps_build_enrollee_nonce(wps, msg) ||
wps_build_registrar_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) ||
wps_build_config_error(msg, wps->config_error) || wps_build_config_error(msg, wps->config_error) ||
wps_build_version2(msg)) { wps_build_wfa_ext(msg, 0, NULL, 0)) {
wpabuf_free(msg); wpabuf_free(msg);
return NULL; return NULL;
} }

View file

@ -578,7 +578,7 @@ static struct wpabuf * build_fake_wsc_ack(void)
wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE); wpabuf_put_be16(msg, ATTR_REGISTRAR_NONCE);
wpabuf_put_be16(msg, WPS_NONCE_LEN); wpabuf_put_be16(msg, WPS_NONCE_LEN);
wpabuf_put(msg, WPS_NONCE_LEN); wpabuf_put(msg, WPS_NONCE_LEN);
wps_build_version2(msg); wps_build_wfa_ext(msg, 0, NULL, 0);
return msg; return msg;
} }