00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/dh_group5.h"
00019 #include "common/ieee802_11_defs.h"
00020 #include "wps_i.h"
00021 #include "wps_dev_attr.h"
00022
00023
00034 struct wps_data * wps_init(const struct wps_config *cfg)
00035 {
00036 struct wps_data *data = os_zalloc(sizeof(*data));
00037 if (data == NULL)
00038 return NULL;
00039 data->wps = cfg->wps;
00040 data->registrar = cfg->registrar;
00041 if (cfg->registrar) {
00042 os_memcpy(data->uuid_r, cfg->wps->uuid, WPS_UUID_LEN);
00043 } else {
00044 os_memcpy(data->mac_addr_e, cfg->wps->dev.mac_addr, ETH_ALEN);
00045 os_memcpy(data->uuid_e, cfg->wps->uuid, WPS_UUID_LEN);
00046 }
00047 if (cfg->pin) {
00048 data->dev_pw_id = data->wps->oob_dev_pw_id == 0 ?
00049 DEV_PW_DEFAULT : data->wps->oob_dev_pw_id;
00050 data->dev_password = os_malloc(cfg->pin_len);
00051 if (data->dev_password == NULL) {
00052 os_free(data);
00053 return NULL;
00054 }
00055 os_memcpy(data->dev_password, cfg->pin, cfg->pin_len);
00056 data->dev_password_len = cfg->pin_len;
00057 }
00058
00059 data->pbc = cfg->pbc;
00060 if (cfg->pbc) {
00061
00062 data->dev_pw_id = DEV_PW_PUSHBUTTON;
00063 os_free(data->dev_password);
00064 data->dev_password = os_malloc(8);
00065 if (data->dev_password == NULL) {
00066 os_free(data);
00067 return NULL;
00068 }
00069 os_memset(data->dev_password, '0', 8);
00070 data->dev_password_len = 8;
00071 }
00072
00073 data->state = data->registrar ? RECV_M1 : SEND_M1;
00074
00075 if (cfg->assoc_wps_ie) {
00076 struct wps_parse_attr attr;
00077 wpa_hexdump_buf(MSG_DEBUG, "WPS: WPS IE from (Re)AssocReq",
00078 cfg->assoc_wps_ie);
00079 if (wps_parse_msg(cfg->assoc_wps_ie, &attr) < 0) {
00080 wpa_printf(MSG_DEBUG, "WPS: Failed to parse WPS IE "
00081 "from (Re)AssocReq");
00082 } else if (attr.request_type == NULL) {
00083 wpa_printf(MSG_DEBUG, "WPS: No Request Type attribute "
00084 "in (Re)AssocReq WPS IE");
00085 } else {
00086 wpa_printf(MSG_DEBUG, "WPS: Request Type (from WPS IE "
00087 "in (Re)AssocReq WPS IE): %d",
00088 *attr.request_type);
00089 data->request_type = *attr.request_type;
00090 }
00091 }
00092
00093 if (cfg->new_ap_settings) {
00094 data->new_ap_settings =
00095 os_malloc(sizeof(*data->new_ap_settings));
00096 if (data->new_ap_settings == NULL) {
00097 os_free(data);
00098 return NULL;
00099 }
00100 os_memcpy(data->new_ap_settings, cfg->new_ap_settings,
00101 sizeof(*data->new_ap_settings));
00102 }
00103
00104 if (cfg->peer_addr)
00105 os_memcpy(data->peer_dev.mac_addr, cfg->peer_addr, ETH_ALEN);
00106
00107 data->use_psk_key = cfg->use_psk_key;
00108
00109 return data;
00110 }
00111
00112
00117 void wps_deinit(struct wps_data *data)
00118 {
00119 if (data->wps_pin_revealed) {
00120 wpa_printf(MSG_DEBUG, "WPS: Full PIN information revealed and "
00121 "negotiation failed");
00122 if (data->registrar)
00123 wps_registrar_invalidate_pin(data->wps->registrar,
00124 data->uuid_e);
00125 } else if (data->registrar)
00126 wps_registrar_unlock_pin(data->wps->registrar, data->uuid_e);
00127
00128 wpabuf_free(data->dh_privkey);
00129 wpabuf_free(data->dh_pubkey_e);
00130 wpabuf_free(data->dh_pubkey_r);
00131 wpabuf_free(data->last_msg);
00132 os_free(data->dev_password);
00133 os_free(data->new_psk);
00134 wps_device_data_free(&data->peer_dev);
00135 os_free(data->new_ap_settings);
00136 dh5_free(data->dh_ctx);
00137 os_free(data);
00138 }
00139
00140
00153 enum wps_process_res wps_process_msg(struct wps_data *wps,
00154 enum wsc_op_code op_code,
00155 const struct wpabuf *msg)
00156 {
00157 if (wps->registrar)
00158 return wps_registrar_process_msg(wps, op_code, msg);
00159 else
00160 return wps_enrollee_process_msg(wps, op_code, msg);
00161 }
00162
00163
00173 struct wpabuf * wps_get_msg(struct wps_data *wps, enum wsc_op_code *op_code)
00174 {
00175 if (wps->registrar)
00176 return wps_registrar_get_msg(wps, op_code);
00177 else
00178 return wps_enrollee_get_msg(wps, op_code);
00179 }
00180
00181
00187 int wps_is_selected_pbc_registrar(const struct wpabuf *msg)
00188 {
00189 struct wps_parse_attr attr;
00190
00191
00192
00193
00194
00195
00196
00197
00198 if (wps_parse_msg(msg, &attr) < 0 ||
00199 !attr.selected_registrar || *attr.selected_registrar == 0 ||
00200 !attr.dev_password_id ||
00201 WPA_GET_BE16(attr.dev_password_id) != DEV_PW_PUSHBUTTON)
00202 return 0;
00203
00204 return 1;
00205 }
00206
00207
00213 int wps_is_selected_pin_registrar(const struct wpabuf *msg)
00214 {
00215 struct wps_parse_attr attr;
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 if (wps_parse_msg(msg, &attr) < 0)
00226 return 0;
00227
00228 if (!attr.selected_registrar || *attr.selected_registrar == 0)
00229 return 0;
00230
00231 if (attr.dev_password_id != NULL &&
00232 WPA_GET_BE16(attr.dev_password_id) == DEV_PW_PUSHBUTTON)
00233 return 0;
00234
00235 return 1;
00236 }
00237
00238
00247 const u8 * wps_get_uuid_e(const struct wpabuf *msg)
00248 {
00249 struct wps_parse_attr attr;
00250
00251 if (wps_parse_msg(msg, &attr) < 0)
00252 return NULL;
00253 return attr.uuid_e;
00254 }
00255
00256
00264 struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type)
00265 {
00266 struct wpabuf *ie;
00267 u8 *len;
00268
00269 wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
00270 "Request");
00271 ie = wpabuf_alloc(100);
00272 if (ie == NULL)
00273 return NULL;
00274
00275 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
00276 len = wpabuf_put(ie, 1);
00277 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
00278
00279 if (wps_build_version(ie) ||
00280 wps_build_req_type(ie, req_type)) {
00281 wpabuf_free(ie);
00282 return NULL;
00283 }
00284
00285 *len = wpabuf_len(ie) - 2;
00286
00287 return ie;
00288 }
00289
00290
00301 struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
00302 const u8 *uuid,
00303 enum wps_request_type req_type)
00304 {
00305 struct wpabuf *ie;
00306 u8 *len;
00307 u16 methods;
00308
00309 wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for Probe Request");
00310
00311 ie = wpabuf_alloc(200);
00312 if (ie == NULL)
00313 return NULL;
00314
00315 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
00316 len = wpabuf_put(ie, 1);
00317 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
00318
00319 if (pbc)
00320 methods = WPS_CONFIG_PUSHBUTTON;
00321 else {
00322 methods = WPS_CONFIG_LABEL | WPS_CONFIG_DISPLAY |
00323 WPS_CONFIG_KEYPAD;
00324 #ifdef CONFIG_WPS_UFD
00325 methods |= WPS_CONFIG_USBA;
00326 #endif
00327 #ifdef CONFIG_WPS_NFC
00328 methods |= WPS_CONFIG_NFC_INTERFACE;
00329 #endif
00330 }
00331
00332 if (wps_build_version(ie) ||
00333 wps_build_req_type(ie, req_type) ||
00334 wps_build_config_methods(ie, methods) ||
00335 wps_build_uuid_e(ie, uuid) ||
00336 wps_build_primary_dev_type(dev, ie) ||
00337 wps_build_rf_bands(dev, ie) ||
00338 wps_build_assoc_state(NULL, ie) ||
00339 wps_build_config_error(ie, WPS_CFG_NO_ERROR) ||
00340 wps_build_dev_password_id(ie, pbc ? DEV_PW_PUSHBUTTON :
00341 DEV_PW_DEFAULT)) {
00342 wpabuf_free(ie);
00343 return NULL;
00344 }
00345
00346 *len = wpabuf_len(ie) - 2;
00347
00348 return ie;
00349 }
00350
00351
00352 void wps_free_pending_msgs(struct upnp_pending_message *msgs)
00353 {
00354 struct upnp_pending_message *p, *prev;
00355 p = msgs;
00356 while (p) {
00357 prev = p;
00358 p = p->next;
00359 wpabuf_free(prev->msg);
00360 os_free(prev);
00361 }
00362 }
00363
00364
00365 int wps_attr_text(struct wpabuf *data, char *buf, char *end)
00366 {
00367 struct wps_parse_attr attr;
00368 char *pos = buf;
00369 int ret;
00370
00371 if (wps_parse_msg(data, &attr) < 0)
00372 return -1;
00373
00374 if (attr.wps_state) {
00375 if (*attr.wps_state == WPS_STATE_NOT_CONFIGURED)
00376 ret = os_snprintf(pos, end - pos,
00377 "wps_state=unconfigured\n");
00378 else if (*attr.wps_state == WPS_STATE_CONFIGURED)
00379 ret = os_snprintf(pos, end - pos,
00380 "wps_state=configured\n");
00381 else
00382 ret = 0;
00383 if (ret < 0 || ret >= end - pos)
00384 return pos - buf;
00385 pos += ret;
00386 }
00387
00388 if (attr.ap_setup_locked && *attr.ap_setup_locked) {
00389 ret = os_snprintf(pos, end - pos,
00390 "wps_ap_setup_locked=1\n");
00391 if (ret < 0 || ret >= end - pos)
00392 return pos - buf;
00393 pos += ret;
00394 }
00395
00396 if (attr.selected_registrar && *attr.selected_registrar) {
00397 ret = os_snprintf(pos, end - pos,
00398 "wps_selected_registrar=1\n");
00399 if (ret < 0 || ret >= end - pos)
00400 return pos - buf;
00401 pos += ret;
00402 }
00403
00404 if (attr.dev_password_id) {
00405 ret = os_snprintf(pos, end - pos,
00406 "wps_device_password_id=%u\n",
00407 WPA_GET_BE16(attr.dev_password_id));
00408 if (ret < 0 || ret >= end - pos)
00409 return pos - buf;
00410 pos += ret;
00411 }
00412
00413 if (attr.sel_reg_config_methods) {
00414 ret = os_snprintf(pos, end - pos,
00415 "wps_selected_registrar_config_methods="
00416 "0x%04x\n",
00417 WPA_GET_BE16(attr.sel_reg_config_methods));
00418 if (ret < 0 || ret >= end - pos)
00419 return pos - buf;
00420 pos += ret;
00421 }
00422
00423 if (attr.primary_dev_type) {
00424 char devtype[WPS_DEV_TYPE_BUFSIZE];
00425 ret = os_snprintf(pos, end - pos,
00426 "wps_primary_device_type=%s\n",
00427 wps_dev_type_bin2str(attr.primary_dev_type,
00428 devtype,
00429 sizeof(devtype)));
00430 if (ret < 0 || ret >= end - pos)
00431 return pos - buf;
00432 pos += ret;
00433 }
00434
00435 if (attr.dev_name) {
00436 char *str = os_malloc(attr.dev_name_len + 1);
00437 size_t i;
00438 if (str == NULL)
00439 return pos - buf;
00440 for (i = 0; i < attr.dev_name_len; i++) {
00441 if (attr.dev_name[i] < 32)
00442 str[i] = '_';
00443 else
00444 str[i] = attr.dev_name[i];
00445 }
00446 str[i] = '\0';
00447 ret = os_snprintf(pos, end - pos, "wps_device_name=%s\n", str);
00448 os_free(str);
00449 if (ret < 0 || ret >= end - pos)
00450 return pos - buf;
00451 pos += ret;
00452 }
00453
00454 if (attr.config_methods) {
00455 ret = os_snprintf(pos, end - pos,
00456 "wps_config_methods=0x%04x\n",
00457 WPA_GET_BE16(attr.config_methods));
00458 if (ret < 0 || ret >= end - pos)
00459 return pos - buf;
00460 pos += ret;
00461 }
00462
00463 return pos - buf;
00464 }