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