]>
git.ipfire.org Git - thirdparty/hostap.git/blob - src/wps/wps.c
2 * Wi-Fi Protected Setup
3 * Copyright (c) 2007-2008, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
19 #include "wps_dev_attr.h"
20 #include "ieee802_11_defs.h"
23 struct wps_data
* wps_init(const struct wps_config
*cfg
)
25 struct wps_data
*data
= os_zalloc(sizeof(*data
));
28 data
->authenticator
= cfg
->authenticator
;
30 data
->registrar
= cfg
->registrar
;
31 if (cfg
->enrollee_mac_addr
)
32 os_memcpy(data
->mac_addr_e
, cfg
->enrollee_mac_addr
, ETH_ALEN
);
34 os_memcpy(cfg
->registrar
? data
->uuid_r
: data
->uuid_e
,
35 cfg
->uuid
, WPS_UUID_LEN
);
38 data
->dev_pw_id
= DEV_PW_DEFAULT
;
39 data
->dev_password
= os_malloc(cfg
->pin_len
);
40 if (data
->dev_password
== NULL
) {
44 os_memcpy(data
->dev_password
, cfg
->pin
, cfg
->pin_len
);
45 data
->dev_password_len
= cfg
->pin_len
;
50 /* Use special PIN '00000000' for PBC */
51 data
->dev_pw_id
= DEV_PW_PUSHBUTTON
;
52 os_free(data
->dev_password
);
53 data
->dev_password
= os_malloc(8);
54 if (data
->dev_password
== NULL
) {
58 os_memset(data
->dev_password
, '0', 8);
59 data
->dev_password_len
= 8;
62 data
->state
= data
->registrar
? RECV_M1
: SEND_M1
;
64 if (cfg
->assoc_wps_ie
) {
65 struct wps_parse_attr attr
;
66 wpa_hexdump_buf(MSG_DEBUG
, "WPS: WPS IE from (Re)AssocReq",
68 if (wps_parse_msg(cfg
->assoc_wps_ie
, &attr
) < 0) {
69 wpa_printf(MSG_DEBUG
, "WPS: Failed to parse WPS IE "
71 } else if (attr
.request_type
== NULL
) {
72 wpa_printf(MSG_DEBUG
, "WPS: No Request Type attribute "
73 "in (Re)AssocReq WPS IE");
75 wpa_printf(MSG_DEBUG
, "WPS: Request Type (from WPS IE "
76 "in (Re)AssocReq WPS IE): %d",
78 data
->request_type
= *attr
.request_type
;
86 void wps_deinit(struct wps_data
*data
)
88 if (data
->wps_pin_revealed
) {
89 wpa_printf(MSG_DEBUG
, "WPS: Full PIN information revealed and "
90 "negotiation failed");
92 wps_registrar_invalidate_pin(data
->registrar
,
94 } else if (data
->registrar
)
95 wps_registrar_unlock_pin(data
->registrar
, data
->uuid_e
);
97 wpabuf_free(data
->dh_privkey
);
98 wpabuf_free(data
->dh_pubkey_e
);
99 wpabuf_free(data
->dh_pubkey_r
);
100 wpabuf_free(data
->last_msg
);
101 os_free(data
->dev_password
);
102 os_free(data
->new_psk
);
103 wps_device_data_free(&data
->peer_dev
);
108 enum wps_process_res
wps_process_msg(struct wps_data
*wps
, u8 op_code
,
109 const struct wpabuf
*msg
)
112 return wps_registrar_process_msg(wps
, op_code
, msg
);
114 return wps_enrollee_process_msg(wps
, op_code
, msg
);
118 struct wpabuf
* wps_get_msg(struct wps_data
*wps
, u8
*op_code
)
121 return wps_registrar_get_msg(wps
, op_code
);
123 return wps_enrollee_get_msg(wps
, op_code
);
127 int wps_is_selected_pbc_registrar(const struct wpabuf
*msg
)
129 struct wps_parse_attr attr
;
131 if (wps_parse_msg(msg
, &attr
) < 0 ||
132 !attr
.selected_registrar
|| *attr
.selected_registrar
== 0 ||
133 !attr
.sel_reg_config_methods
||
134 !(WPA_GET_BE16(attr
.sel_reg_config_methods
) &
135 WPS_CONFIG_PUSHBUTTON
) ||
136 !attr
.dev_password_id
||
137 WPA_GET_BE16(attr
.dev_password_id
) != DEV_PW_PUSHBUTTON
)
144 int wps_is_selected_pin_registrar(const struct wpabuf
*msg
)
146 struct wps_parse_attr attr
;
148 if (wps_parse_msg(msg
, &attr
) < 0 ||
149 !attr
.selected_registrar
|| *attr
.selected_registrar
== 0 ||
150 !attr
.sel_reg_config_methods
||
151 !(WPA_GET_BE16(attr
.sel_reg_config_methods
) &
152 (WPS_CONFIG_LABEL
| WPS_CONFIG_DISPLAY
| WPS_CONFIG_KEYPAD
)) ||
153 !attr
.dev_password_id
||
154 WPA_GET_BE16(attr
.dev_password_id
) == DEV_PW_PUSHBUTTON
)
161 const u8
* wps_get_uuid_e(const struct wpabuf
*msg
)
163 struct wps_parse_attr attr
;
165 if (wps_parse_msg(msg
, &attr
) < 0)
171 struct wpabuf
* wps_build_assoc_req_ie(u8 req_type
)
176 wpa_printf(MSG_DEBUG
, "WPS: Building WPS IE for (Re)Association "
178 ie
= wpabuf_alloc(100);
182 wpabuf_put_u8(ie
, WLAN_EID_VENDOR_SPECIFIC
);
183 len
= wpabuf_put(ie
, 1);
184 wpabuf_put_be32(ie
, WPS_DEV_OUI_WFA
);
186 if (wps_build_version(ie
) ||
187 wps_build_req_type(ie
, req_type
)) {
192 *len
= wpabuf_len(ie
) - 2;
198 struct wpabuf
* wps_build_probe_req_ie(int pbc
, struct wps_device_data
*dev
,
199 const u8
*uuid
, u8 req_type
)
205 wpa_printf(MSG_DEBUG
, "WPS: Building WPS IE for Probe Request");
207 ie
= wpabuf_alloc(200);
211 wpabuf_put_u8(ie
, WLAN_EID_VENDOR_SPECIFIC
);
212 len
= wpabuf_put(ie
, 1);
213 wpabuf_put_be32(ie
, WPS_DEV_OUI_WFA
);
216 methods
= WPS_CONFIG_PUSHBUTTON
;
218 methods
= WPS_CONFIG_LABEL
| WPS_CONFIG_DISPLAY
|
221 if (wps_build_version(ie
) ||
222 wps_build_req_type(ie
, req_type
) ||
223 wps_build_config_methods(ie
, methods
) ||
224 wps_build_uuid_e(ie
, uuid
) ||
225 wps_build_primary_dev_type(dev
, ie
) ||
226 wps_build_rf_bands(dev
, ie
) ||
227 wps_build_assoc_state(NULL
, ie
) ||
228 wps_build_config_error(ie
, WPS_CFG_NO_ERROR
) ||
229 wps_build_dev_password_id(ie
, pbc
? DEV_PW_PUSHBUTTON
:
235 *len
= wpabuf_len(ie
) - 2;