📄 wps_registrar.c
字号:
}static int wps_build_credential(struct wpabuf *msg, struct wps_credential *cred){ if (wps_build_cred_network_idx(msg, cred) || wps_build_cred_ssid(msg, cred) || wps_build_cred_auth_type(msg, cred) || wps_build_cred_encr_type(msg, cred) || wps_build_cred_network_key(msg, cred) || wps_build_cred_mac_addr(msg, cred)) return -1; return 0;}static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg){ struct wpabuf *cred; if (wps->wps->registrar->skip_cred_build) goto skip_cred_build; wpa_printf(MSG_DEBUG, "WPS: * Credential"); os_memset(&wps->cred, 0, sizeof(wps->cred)); os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len); wps->cred.ssid_len = wps->wps->ssid_len; /* Select the best authentication and encryption type */ if (wps->auth_type & WPS_AUTH_WPA2PSK) wps->auth_type = WPS_AUTH_WPA2PSK; else if (wps->auth_type & WPS_AUTH_WPAPSK) wps->auth_type = WPS_AUTH_WPAPSK; else if (wps->auth_type & WPS_AUTH_OPEN) wps->auth_type = WPS_AUTH_OPEN; else if (wps->auth_type & WPS_AUTH_SHARED) wps->auth_type = WPS_AUTH_SHARED; else { wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x", wps->auth_type); return -1; } wps->cred.auth_type = wps->auth_type; if (wps->auth_type == WPS_AUTH_WPA2PSK || wps->auth_type == WPS_AUTH_WPAPSK) { if (wps->encr_type & WPS_ENCR_AES) wps->encr_type = WPS_ENCR_AES; else if (wps->encr_type & WPS_ENCR_TKIP) wps->encr_type = WPS_ENCR_TKIP; else { wpa_printf(MSG_DEBUG, "WPS: No suitable encryption " "type for WPA/WPA2"); return -1; } } else { if (wps->encr_type & WPS_ENCR_WEP) wps->encr_type = WPS_ENCR_WEP; else if (wps->encr_type & WPS_ENCR_NONE) wps->encr_type = WPS_ENCR_NONE; else { wpa_printf(MSG_DEBUG, "WPS: No suitable encryption " "type for non-WPA/WPA2 mode"); return -1; } } wps->cred.encr_type = wps->encr_type; /* 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); if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap && !wps->wps->registrar->disable_auto_conf) { u8 r[16]; /* Generate a random passphrase */ if (os_get_random(r, sizeof(r)) < 0) return -1; os_free(wps->new_psk); wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len); if (wps->new_psk == NULL) return -1; wps->new_psk_len--; /* remove newline */ while (wps->new_psk_len && wps->new_psk[wps->new_psk_len - 1] == '=') wps->new_psk_len--; wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase", wps->new_psk, wps->new_psk_len); os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len); wps->cred.key_len = wps->new_psk_len; } else if (wps->wps->network_key) { os_memcpy(wps->cred.key, wps->wps->network_key, wps->wps->network_key_len); wps->cred.key_len = wps->wps->network_key_len; } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) { char hex[65]; /* Generate a random per-device PSK */ os_free(wps->new_psk); wps->new_psk_len = 32; wps->new_psk = os_malloc(wps->new_psk_len); if (wps->new_psk == NULL) return -1; if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) { os_free(wps->new_psk); wps->new_psk = NULL; return -1; } wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK", wps->new_psk, wps->new_psk_len); wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk, wps->new_psk_len); os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2); wps->cred.key_len = wps->new_psk_len * 2; } cred = wpabuf_alloc(200); if (cred == NULL) return -1; if (wps_build_credential(cred, &wps->cred)) { wpabuf_free(cred); return -1; } wpabuf_put_be16(msg, ATTR_CRED); wpabuf_put_be16(msg, wpabuf_len(cred)); wpabuf_put_buf(msg, cred); wpabuf_free(cred);skip_cred_build: if (wps->wps->registrar->extra_cred) { wpa_printf(MSG_DEBUG, "WPS: * Credential (pre-configured)"); wpabuf_put_buf(msg, wps->wps->registrar->extra_cred); } return 0;}static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg){ wpa_printf(MSG_DEBUG, "WPS: * AP Settings"); if (wps_build_credential(msg, &wps->cred)) return -1; return 0;}static struct wpabuf * wps_build_m2(struct wps_data *wps){ struct wpabuf *msg; if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0) return NULL; wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce", wps->nonce_r, WPS_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN); wpa_printf(MSG_DEBUG, "WPS: Building Message M2"); msg = wpabuf_alloc(1000); if (msg == NULL) return NULL; if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_M2) || wps_build_enrollee_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) || wps_build_uuid_r(wps, msg) || wps_build_public_key(wps, msg) || wps_derive_keys(wps) || wps_build_auth_type_flags(wps, msg) || wps_build_encr_type_flags(wps, msg) || wps_build_conn_type_flags(wps, msg) || wps_build_config_methods_r(wps->wps->registrar, msg) || wps_build_device_attrs(&wps->wps->dev, msg) || wps_build_rf_bands(&wps->wps->dev, msg) || wps_build_assoc_state(wps, msg) || wps_build_config_error(msg, WPS_CFG_NO_ERROR) || wps_build_dev_password_id(msg, wps->dev_pw_id) || wps_build_os_version(&wps->wps->dev, msg) || wps_build_authenticator(wps, msg)) { wpabuf_free(msg); return NULL; } wps->state = RECV_M3; return msg;}static struct wpabuf * wps_build_m2d(struct wps_data *wps){ struct wpabuf *msg; u16 err = WPS_CFG_NO_ERROR; wpa_printf(MSG_DEBUG, "WPS: Building Message M2D"); msg = wpabuf_alloc(1000); if (msg == NULL) return NULL; if (wps->wps->ap && wps->wps->ap_setup_locked) err = WPS_CFG_SETUP_LOCKED; if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_M2D) || wps_build_enrollee_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) || wps_build_uuid_r(wps, msg) || wps_build_auth_type_flags(wps, msg) || wps_build_encr_type_flags(wps, msg) || wps_build_conn_type_flags(wps, msg) || wps_build_config_methods_r(wps->wps->registrar, msg) || wps_build_device_attrs(&wps->wps->dev, msg) || wps_build_rf_bands(&wps->wps->dev, msg) || wps_build_assoc_state(wps, msg) || wps_build_config_error(msg, err) || wps_build_os_version(&wps->wps->dev, msg)) { wpabuf_free(msg); return NULL; } wps->state = RECV_M2D_ACK; return msg;}static struct wpabuf * wps_build_m4(struct wps_data *wps){ struct wpabuf *msg, *plain; wpa_printf(MSG_DEBUG, "WPS: Building Message M4"); wps_derive_psk(wps, wps->dev_password, wps->dev_password_len); plain = wpabuf_alloc(200); if (plain == NULL) return NULL; msg = wpabuf_alloc(1000); if (msg == NULL) { wpabuf_free(plain); return NULL; } if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_M4) || wps_build_enrollee_nonce(wps, msg) || wps_build_r_hash(wps, msg) || wps_build_r_snonce1(wps, plain) || wps_build_key_wrap_auth(wps, plain) || wps_build_encr_settings(wps, msg, plain) || wps_build_authenticator(wps, msg)) { wpabuf_free(plain); wpabuf_free(msg); return NULL; } wpabuf_free(plain); wps->state = RECV_M5; return msg;}static struct wpabuf * wps_build_m6(struct wps_data *wps){ struct wpabuf *msg, *plain; wpa_printf(MSG_DEBUG, "WPS: Building Message M6"); plain = wpabuf_alloc(200); if (plain == NULL) return NULL; msg = wpabuf_alloc(1000); if (msg == NULL) { wpabuf_free(plain); return NULL; } if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_M6) || wps_build_enrollee_nonce(wps, msg) || wps_build_r_snonce2(wps, plain) || wps_build_key_wrap_auth(wps, plain) || wps_build_encr_settings(wps, msg, plain) || wps_build_authenticator(wps, msg)) { wpabuf_free(plain); wpabuf_free(msg); return NULL; } wpabuf_free(plain); wps->wps_pin_revealed = 1; wps->state = RECV_M7; return msg;}static struct wpabuf * wps_build_m8(struct wps_data *wps){ struct wpabuf *msg, *plain; wpa_printf(MSG_DEBUG, "WPS: Building Message M8"); plain = wpabuf_alloc(500); if (plain == NULL) return NULL; msg = wpabuf_alloc(1000); if (msg == NULL) { wpabuf_free(plain); return NULL; } if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_M8) || wps_build_enrollee_nonce(wps, msg) || (wps->wps->ap && wps_build_cred(wps, plain)) || (!wps->wps->ap && wps_build_ap_settings(wps, plain)) || wps_build_key_wrap_auth(wps, plain) || wps_build_encr_settings(wps, msg, plain) || wps_build_authenticator(wps, msg)) { wpabuf_free(plain); wpabuf_free(msg); return NULL; } wpabuf_free(plain); wps->state = RECV_DONE; return msg;}static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps){ struct wpabuf *msg; wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK"); msg = wpabuf_alloc(1000); if (msg == NULL) return NULL; if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_WSC_ACK) || wps_build_enrollee_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg)) { wpabuf_free(msg); return NULL; } return msg;}static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps){ struct wpabuf *msg; wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK"); msg = wpabuf_alloc(1000); if (msg == NULL) return NULL; if (wps_build_version(msg) || wps_build_msg_type(msg, WPS_WSC_NACK) || wps_build_enrollee_nonce(wps, msg) || wps_build_registrar_nonce(wps, msg) || wps_build_config_error(msg, wps->config_error)) { wpabuf_free(msg); return NULL; } return msg;}struct wpabuf * wps_registrar_get_msg(struct wps_data *wps, enum wsc_op_code *op_code){ struct wpabuf *msg;#ifdef CONFIG_WPS_UPNP if (wps->wps->wps_upnp) { struct upnp_pending_message *p, *prev = NULL; if (wps->ext_reg > 1) wps_registrar_free_pending_m2(wps->wps); p = wps->wps->upnp_msgs; /* TODO: check pending message MAC address */ while (p && p->next) { prev = p; p = p->next; } if (p) { wpa_printf(MSG_DEBUG, "WPS: Use pending message from " "UPnP"); if (prev) prev->next = NULL; else wps->wps->upnp_msgs = NULL; msg = p->msg; os_free(p); *op_code = WSC_MSG; if (wps->ext_reg == 0) wps->ext_reg = 1; return msg; } } if (wps->ext_reg) { wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no " "pending message available"); return NULL; }#endif /* CONFIG_WPS_UPNP */ switch (wps->state) { case SEND_M2: if (wps_get_dev_password(wps) < 0) msg = wps_build_m2d(wps); else msg = wps_build_m2(wps); *op_code = WSC_MSG; break; case SEND_M2D: msg = wps_build_m2d(wps); *op_code = WSC_MSG; break; case SEND_M4: msg = wps_build_m4(wps); *op_code = WSC_MSG; break; case SEND_M6: msg = wps_build_m6(wps); *op_code = WSC_MSG; break; case SEND_M8: msg = wps_build_m8(wps); *op_code = WSC_MSG; break; case RECV_DONE: msg = wps_build_wsc_ack(wps); *op_code = WSC_ACK; break; case SEND_WSC_NACK: msg = wps_build_wsc_nack(wps); *op_code = WSC_NACK; break; default: wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building " "a message", wps->state); msg = NULL; break; } if (*op_code == WSC_MSG && msg) { /* Save a copy of the last message for Authenticator derivation */ wpabuf_free(wps->last_msg); wps->last_msg = wpabuf_dup(msg); } return msg;}static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce){ if (e_nonce == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received"); return -1; } os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce", wps->nonce_e, WPS_NONCE_LEN); return 0;}static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce){ if (r_nonce == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received"); return -1; } if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) { wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received"); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -