X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fwps%2Fwps_registrar.c;h=7da374a450fc8f37498534342ad2828522328c69;hb=81611b95ff786db2a7fb86cea2f34e7dc5bee07a;hp=6c479672c449327ed0eee8b98f226b29030eb84b;hpb=62281bc6908ec2d57a8a792f0199cd9203df37fb;p=libeap.git diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 6c47967..7da374a 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -126,6 +126,7 @@ struct wps_registrar { int sel_reg_dev_password_id_override; int sel_reg_config_methods_override; int static_wep_only; + int dualband; struct wps_registrar_device *devices; @@ -430,6 +431,20 @@ static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg, } +static int wps_build_sel_pbc_reg_uuid_e(struct wps_registrar *reg, + struct wpabuf *msg) +{ + u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT; + if (!reg->sel_reg_union) + return 0; + if (reg->sel_reg_dev_password_id_override >= 0) + id = reg->sel_reg_dev_password_id_override; + if (id != DEV_PW_PUSHBUTTON || !reg->dualband) + return 0; + return wps_build_uuid_e(msg, reg->wps->uuid); +} + + static void wps_set_pushbutton(u16 *methods, u16 conf_methods) { *methods |= WPS_CONFIG_PUSHBUTTON; @@ -572,6 +587,7 @@ wps_registrar_init(struct wps_context *wps, reg->sel_reg_dev_password_id_override = -1; reg->sel_reg_config_methods_override = -1; reg->static_wep_only = cfg->static_wep_only; + reg->dualband = cfg->dualband; if (wps_set_ie(reg)) { wps_registrar_deinit(reg); @@ -662,6 +678,22 @@ int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *addr, } +static void wps_registrar_remove_pin(struct wps_registrar *reg, + struct wps_uuid_pin *pin) +{ + u8 *addr; + u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + if (is_zero_ether_addr(pin->enrollee_addr)) + addr = bcast; + else + addr = pin->enrollee_addr; + wps_registrar_remove_authorized_mac(reg, addr); + wps_remove_pin(pin); + wps_registrar_selected_registrar_changed(reg); +} + + static void wps_registrar_expire_pins(struct wps_registrar *reg) { struct wps_uuid_pin *pin, *prev; @@ -672,20 +704,34 @@ static void wps_registrar_expire_pins(struct wps_registrar *reg) { if ((pin->flags & PIN_EXPIRES) && os_time_before(&pin->expiration, &now)) { - u8 *addr; - u8 bcast[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID", pin->uuid, WPS_UUID_LEN); - if (is_zero_ether_addr(pin->enrollee_addr)) - addr = bcast; - else - addr = pin->enrollee_addr; - wps_registrar_remove_authorized_mac(reg, addr); - wps_remove_pin(pin); - wps_registrar_selected_registrar_changed(reg); + wps_registrar_remove_pin(reg, pin); + } + } +} + + +/** + * wps_registrar_invalidate_wildcard_pin - Invalidate a wildcard PIN + * @reg: Registrar data from wps_registrar_init() + * Returns: 0 on success, -1 if not wildcard PIN is enabled + */ +static int wps_registrar_invalidate_wildcard_pin(struct wps_registrar *reg) +{ + struct wps_uuid_pin *pin, *prev; + + dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list) + { + if (pin->wildcard_uuid) { + wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID", + pin->uuid, WPS_UUID_LEN); + wps_registrar_remove_pin(reg, pin); + return 0; } } + + return -1; } @@ -702,18 +748,9 @@ int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid) dl_list_for_each_safe(pin, prev, ®->pins, struct wps_uuid_pin, list) { if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) { - u8 *addr; - u8 bcast[ETH_ALEN] = - { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID", pin->uuid, WPS_UUID_LEN); - if (is_zero_ether_addr(pin->enrollee_addr)) - addr = bcast; - else - addr = pin->enrollee_addr; - wps_registrar_remove_authorized_mac(reg, addr); - wps_remove_pin(pin); - wps_registrar_selected_registrar_changed(reg); + wps_registrar_remove_pin(reg, pin); return 0; } } @@ -841,6 +878,7 @@ int wps_registrar_button_pushed(struct wps_registrar *reg) reg->pbc = 1; wps_registrar_selected_registrar_changed(reg); + eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL); eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL); eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout, reg, NULL); @@ -865,6 +903,23 @@ static void wps_registrar_pin_completed(struct wps_registrar *reg) } +int wps_registrar_wps_cancel(struct wps_registrar *reg) +{ + if (reg->pbc) { + wpa_printf(MSG_DEBUG, "WPS: PBC is set - cancelling it"); + wps_registrar_pbc_timeout(reg, NULL); + return 1; + } else if (reg->selected_registrar) { + /* PIN Method */ + wpa_printf(MSG_DEBUG, "WPS: PIN is set - cancelling it"); + wps_registrar_pin_completed(reg); + wps_registrar_invalidate_wildcard_pin(reg); + return 1; + } + return 0; +} + + /** * wps_registrar_probe_req_rx - Notify Registrar of Probe Request * @reg: Registrar data from wps_registrar_init() @@ -1031,6 +1086,8 @@ static int wps_set_ie(struct wps_registrar *reg) wps_build_selected_registrar(reg, beacon) || wps_build_sel_reg_dev_password_id(reg, beacon) || wps_build_sel_reg_config_methods(reg, beacon) || + wps_build_sel_pbc_reg_uuid_e(reg, beacon) || + (reg->dualband && wps_build_rf_bands(®->wps->dev, beacon)) || wps_build_wfa_ext(beacon, 0, auth_macs, count)) { wpabuf_free(beacon); wpabuf_free(probe); @@ -1217,7 +1274,7 @@ static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg) static int wps_build_cred_network_idx(struct wpabuf *msg, const struct wps_credential *cred) { - wpa_printf(MSG_DEBUG, "WPS: * Network Index"); + wpa_printf(MSG_DEBUG, "WPS: * Network Index (1)"); wpabuf_put_be16(msg, ATTR_NETWORK_INDEX); wpabuf_put_be16(msg, 1); wpabuf_put_u8(msg, 1); @@ -1229,6 +1286,8 @@ static int wps_build_cred_ssid(struct wpabuf *msg, const struct wps_credential *cred) { wpa_printf(MSG_DEBUG, "WPS: * SSID"); + wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID for Credential", + cred->ssid, cred->ssid_len); wpabuf_put_be16(msg, ATTR_SSID); wpabuf_put_be16(msg, cred->ssid_len); wpabuf_put_data(msg, cred->ssid, cred->ssid_len); @@ -1265,6 +1324,8 @@ static int wps_build_cred_network_key(struct wpabuf *msg, { wpa_printf(MSG_DEBUG, "WPS: * Network Key (len=%d)", (int) cred->key_len); + wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", + cred->key, cred->key_len); wpabuf_put_be16(msg, ATTR_NETWORK_KEY); wpabuf_put_be16(msg, cred->key_len); wpabuf_put_data(msg, cred->key, cred->key_len); @@ -1409,8 +1470,11 @@ int wps_build_cred(struct wps_data *wps, struct wpabuf *msg) } use_provided: -#ifdef CONFIG_WPS_TESTING_EXTRA_CRED - cred = wpabuf_alloc(200); +#ifdef CONFIG_WPS_TESTING + if (wps_testing_dummy_cred) + cred = wpabuf_alloc(200); + else + cred = NULL; if (cred) { struct wps_credential dummy; wpa_printf(MSG_DEBUG, "WPS: Add dummy credential"); @@ -1431,7 +1495,7 @@ use_provided: wpabuf_free(cred); } -#endif /* CONFIG_WPS_TESTING_EXTRA_CRED */ +#endif /* CONFIG_WPS_TESTING */ cred = wpabuf_alloc(200); if (cred == NULL) @@ -2367,7 +2431,7 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m5_encr(decrypted) < 0) { + if (wps_validate_m5_encr(decrypted, attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -2446,6 +2510,13 @@ static int wps_process_ap_settings_r(struct wps_data *wps, * Use the AP PIN only to receive the current AP settings, not * to reconfigure the AP. */ + + /* + * Clear selected registrar here since we do not get to + * WSC_Done in this protocol run. + */ + wps_registrar_pin_completed(wps->wps->registrar); + if (wps->ap_settings_cb) { wps->ap_settings_cb(wps->ap_settings_cb_ctx, &wps->cred); @@ -2496,7 +2567,8 @@ static enum wps_process_res wps_process_m7(struct wps_data *wps, return WPS_CONTINUE; } - if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er) < 0) { + if (wps_validate_m7_encr(decrypted, wps->wps->ap || wps->er, + attr->version2 != NULL) < 0) { wpabuf_free(decrypted); wps->state = SEND_WSC_NACK; return WPS_CONTINUE; @@ -2566,21 +2638,21 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps, return WPS_FAILURE; ret = wps_process_m3(wps, msg, &attr); if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) - wps_fail_event(wps->wps, WPS_M3); + wps_fail_event(wps->wps, WPS_M3, wps->config_error); break; case WPS_M5: if (wps_validate_m5(msg) < 0) return WPS_FAILURE; ret = wps_process_m5(wps, msg, &attr); if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) - wps_fail_event(wps->wps, WPS_M5); + wps_fail_event(wps->wps, WPS_M5, wps->config_error); break; case WPS_M7: if (wps_validate_m7(msg) < 0) return WPS_FAILURE; ret = wps_process_m7(wps, msg, &attr); if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK) - wps_fail_event(wps->wps, WPS_M7); + wps_fail_event(wps->wps, WPS_M7, wps->config_error); break; default: wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d", @@ -2671,6 +2743,7 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps, { struct wps_parse_attr attr; int old_state; + u16 config_error; wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK"); @@ -2718,21 +2791,22 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps, return WPS_FAILURE; } + config_error = WPA_GET_BE16(attr.config_error); wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with " - "Configuration Error %d", WPA_GET_BE16(attr.config_error)); + "Configuration Error %d", config_error); switch (old_state) { case RECV_M3: - wps_fail_event(wps->wps, WPS_M2); + wps_fail_event(wps->wps, WPS_M2, config_error); break; case RECV_M5: - wps_fail_event(wps->wps, WPS_M4); + wps_fail_event(wps->wps, WPS_M4, config_error); break; case RECV_M7: - wps_fail_event(wps->wps, WPS_M6); + wps_fail_event(wps->wps, WPS_M6, config_error); break; case RECV_DONE: - wps_fail_event(wps->wps, WPS_M8); + wps_fail_event(wps->wps, WPS_M8, config_error); break; default: break; @@ -2915,7 +2989,8 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps, ret = wps_process_wsc_done(wps, msg); if (ret == WPS_FAILURE) { wps->state = SEND_WSC_NACK; - wps_fail_event(wps->wps, WPS_WSC_DONE); + wps_fail_event(wps->wps, WPS_WSC_DONE, + wps->config_error); } return ret; default: