00001
00016 #include "includes.h"
00017
00018 #include "hostapd.h"
00019 #include "driver_i.h"
00020 #include "eloop.h"
00021 #include "uuid.h"
00022 #include "wpa_ctrl.h"
00023 #include "ieee802_11_defs.h"
00024 #include "ieee802_11_common.h"
00025 #include "sta_info.h"
00026 #include "eapol_sm.h"
00027 #include "wps/wps.h"
00028 #include "wps/wps_defs.h"
00029 #include "wps/wps_dev_attr.h"
00030 #include "wps_hostapd.h"
00031 #include "dh_groups.h"
00032
00033
00034 #ifdef CONFIG_WPS_UPNP
00035 #include "wps/wps_upnp.h"
00036 static int hostapd_wps_upnp_init(struct hostapd_data *hapd,
00037 struct wps_context *wps);
00038 static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd);
00039 #endif
00040
00041 static void hostapd_wps_probe_req_rx(void *ctx, const u8 *addr,
00042 const u8 *ie, size_t ie_len);
00043
00044
00045 static int hostapd_wps_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *psk,
00046 size_t psk_len)
00047 {
00048 struct hostapd_data *hapd = ctx;
00049 struct hostapd_wpa_psk *p;
00050 struct hostapd_ssid *ssid = &hapd->conf->ssid;
00051
00052 wpa_printf(MSG_DEBUG, "Received new WPA/WPA2-PSK from WPS for STA "
00053 MACSTR, MAC2STR(mac_addr));
00054 wpa_hexdump_key(MSG_DEBUG, "Per-device PSK", psk, psk_len);
00055
00056 if (psk_len != PMK_LEN) {
00057 wpa_printf(MSG_DEBUG, "Unexpected PSK length %lu",
00058 (unsigned long) psk_len);
00059 return -1;
00060 }
00061
00062
00063 p = os_zalloc(sizeof(*p));
00064 if (p == NULL)
00065 return -1;
00066 os_memcpy(p->addr, mac_addr, ETH_ALEN);
00067 os_memcpy(p->psk, psk, PMK_LEN);
00068
00069 p->next = ssid->wpa_psk;
00070 ssid->wpa_psk = p;
00071
00072 if (ssid->wpa_psk_file) {
00073 FILE *f;
00074 char hex[PMK_LEN * 2 + 1];
00075
00076 f = fopen(ssid->wpa_psk_file, "a");
00077 if (f == NULL) {
00078 wpa_printf(MSG_DEBUG, "Failed to add the PSK to "
00079 "'%s'", ssid->wpa_psk_file);
00080 return -1;
00081 }
00082
00083 wpa_snprintf_hex(hex, sizeof(hex), psk, psk_len);
00084 fprintf(f, MACSTR " %s\n", MAC2STR(mac_addr), hex);
00085 fclose(f);
00086 }
00087
00088 return 0;
00089 }
00090
00091
00092 static int hostapd_wps_set_ie_cb(void *ctx, const u8 *beacon_ie,
00093 size_t beacon_ie_len, const u8 *probe_resp_ie,
00094 size_t probe_resp_ie_len)
00095 {
00096 struct hostapd_data *hapd = ctx;
00097
00098 os_free(hapd->wps_beacon_ie);
00099 if (beacon_ie_len == 0) {
00100 hapd->wps_beacon_ie = NULL;
00101 hapd->wps_beacon_ie_len = 0;
00102 } else {
00103 hapd->wps_beacon_ie = os_malloc(beacon_ie_len);
00104 if (hapd->wps_beacon_ie == NULL) {
00105 hapd->wps_beacon_ie_len = 0;
00106 return -1;
00107 }
00108 os_memcpy(hapd->wps_beacon_ie, beacon_ie, beacon_ie_len);
00109 hapd->wps_beacon_ie_len = beacon_ie_len;
00110 }
00111 hostapd_set_wps_beacon_ie(hapd, hapd->wps_beacon_ie,
00112 hapd->wps_beacon_ie_len);
00113
00114 os_free(hapd->wps_probe_resp_ie);
00115 if (probe_resp_ie_len == 0) {
00116 hapd->wps_probe_resp_ie = NULL;
00117 hapd->wps_probe_resp_ie_len = 0;
00118 } else {
00119 hapd->wps_probe_resp_ie = os_malloc(probe_resp_ie_len);
00120 if (hapd->wps_probe_resp_ie == NULL) {
00121 hapd->wps_probe_resp_ie_len = 0;
00122 return -1;
00123 }
00124 os_memcpy(hapd->wps_probe_resp_ie, probe_resp_ie,
00125 probe_resp_ie_len);
00126 hapd->wps_probe_resp_ie_len = probe_resp_ie_len;
00127 }
00128 hostapd_set_wps_probe_resp_ie(hapd, hapd->wps_probe_resp_ie,
00129 hapd->wps_probe_resp_ie_len);
00130
00131 return 0;
00132 }
00133
00134
00135 static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
00136 const struct wps_device_data *dev)
00137 {
00138 struct hostapd_data *hapd = ctx;
00139 char uuid[40], txt[400];
00140 int len;
00141 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
00142 return;
00143 wpa_printf(MSG_DEBUG, "WPS: PIN needed for E-UUID %s", uuid);
00144 len = os_snprintf(txt, sizeof(txt), WPS_EVENT_PIN_NEEDED
00145 "%s " MACSTR " [%s|%s|%s|%s|%s|%d-%08X-%d]",
00146 uuid, MAC2STR(dev->mac_addr), dev->device_name,
00147 dev->manufacturer, dev->model_name,
00148 dev->model_number, dev->serial_number,
00149 dev->categ, dev->oui, dev->sub_categ);
00150 if (len > 0 && len < (int) sizeof(txt))
00151 wpa_msg(hapd->msg_ctx, MSG_INFO, "%s", txt);
00152
00153 if (hapd->conf->wps_pin_requests) {
00154 FILE *f;
00155 struct os_time t;
00156 f = fopen(hapd->conf->wps_pin_requests, "a");
00157 if (f == NULL)
00158 return;
00159 os_get_time(&t);
00160 fprintf(f, "%ld\t%s\t" MACSTR "\t%s\t%s\t%s\t%s\t%s"
00161 "\t%d-%08X-%d\n",
00162 t.sec, uuid, MAC2STR(dev->mac_addr), dev->device_name,
00163 dev->manufacturer, dev->model_name, dev->model_number,
00164 dev->serial_number,
00165 dev->categ, dev->oui, dev->sub_categ);
00166 fclose(f);
00167 }
00168 }
00169
00170
00171 static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
00172 const u8 *uuid_e)
00173 {
00174 struct hostapd_data *hapd = ctx;
00175 char uuid[40];
00176 if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
00177 return;
00178 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s",
00179 MAC2STR(mac_addr), uuid);
00180 }
00181
00182
00183 static int str_starts(const char *str, const char *start)
00184 {
00185 return os_strncmp(str, start, os_strlen(start)) == 0;
00186 }
00187
00188
00189 static void wps_reload_config(void *eloop_data, void *user_ctx)
00190 {
00191 struct hostapd_iface *iface = eloop_data;
00192
00193 wpa_printf(MSG_DEBUG, "WPS: Reload configuration data");
00194 if (hostapd_reload_config(iface) < 0) {
00195 wpa_printf(MSG_WARNING, "WPS: Failed to reload the updated "
00196 "configuration");
00197 }
00198 }
00199
00200
00201 static int hostapd_wps_cred_cb(void *ctx, const struct wps_credential *cred)
00202 {
00203 struct hostapd_data *hapd = ctx;
00204 FILE *oconf, *nconf;
00205 size_t len, i;
00206 char *tmp_fname;
00207 char buf[1024];
00208 int multi_bss;
00209 int wpa;
00210
00211 wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
00212 cred->cred_attr, cred->cred_attr_len);
00213
00214 wpa_printf(MSG_DEBUG, "WPS: Received new AP Settings");
00215 wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len);
00216 wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x",
00217 cred->auth_type);
00218 wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type);
00219 wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx);
00220 wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key",
00221 cred->key, cred->key_len);
00222 wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR,
00223 MAC2STR(cred->mac_addr));
00224
00225 if ((hapd->conf->wps_cred_processing == 1 ||
00226 hapd->conf->wps_cred_processing == 2) && cred->cred_attr) {
00227 size_t blen = cred->cred_attr_len * 2 + 1;
00228 char *_buf = os_malloc(blen);
00229 if (_buf) {
00230 wpa_snprintf_hex(_buf, blen,
00231 cred->cred_attr, cred->cred_attr_len);
00232 wpa_msg(hapd->msg_ctx, MSG_INFO, "%s%s",
00233 WPS_EVENT_NEW_AP_SETTINGS, _buf);
00234 os_free(_buf);
00235 }
00236 } else
00237 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS);
00238
00239 if (hapd->conf->wps_cred_processing == 1)
00240 return 0;
00241
00242 os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len);
00243 hapd->wps->ssid_len = cred->ssid_len;
00244 hapd->wps->encr_types = cred->encr_type;
00245 hapd->wps->auth_types = cred->auth_type;
00246 if (cred->key_len == 0) {
00247 os_free(hapd->wps->network_key);
00248 hapd->wps->network_key = NULL;
00249 hapd->wps->network_key_len = 0;
00250 } else {
00251 if (hapd->wps->network_key == NULL ||
00252 hapd->wps->network_key_len < cred->key_len) {
00253 hapd->wps->network_key_len = 0;
00254 os_free(hapd->wps->network_key);
00255 hapd->wps->network_key = os_malloc(cred->key_len);
00256 if (hapd->wps->network_key == NULL)
00257 return -1;
00258 }
00259 hapd->wps->network_key_len = cred->key_len;
00260 os_memcpy(hapd->wps->network_key, cred->key, cred->key_len);
00261 }
00262 hapd->wps->wps_state = WPS_STATE_CONFIGURED;
00263
00264 len = os_strlen(hapd->iface->config_fname) + 5;
00265 tmp_fname = os_malloc(len);
00266 if (tmp_fname == NULL)
00267 return -1;
00268 os_snprintf(tmp_fname, len, "%s-new", hapd->iface->config_fname);
00269
00270 oconf = fopen(hapd->iface->config_fname, "r");
00271 if (oconf == NULL) {
00272 wpa_printf(MSG_WARNING, "WPS: Could not open current "
00273 "configuration file");
00274 os_free(tmp_fname);
00275 return -1;
00276 }
00277
00278 nconf = fopen(tmp_fname, "w");
00279 if (nconf == NULL) {
00280 wpa_printf(MSG_WARNING, "WPS: Could not write updated "
00281 "configuration file");
00282 os_free(tmp_fname);
00283 fclose(oconf);
00284 return -1;
00285 }
00286
00287 fprintf(nconf, "# WPS configuration - START\n");
00288
00289 fprintf(nconf, "wps_state=2\n");
00290
00291 fprintf(nconf, "ssid=");
00292 for (i = 0; i < cred->ssid_len; i++)
00293 fputc(cred->ssid[i], nconf);
00294 fprintf(nconf, "\n");
00295
00296 if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) &&
00297 (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)))
00298 wpa = 3;
00299 else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK))
00300 wpa = 2;
00301 else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))
00302 wpa = 1;
00303 else
00304 wpa = 0;
00305
00306 if (wpa) {
00307 char *prefix;
00308 fprintf(nconf, "wpa=%d\n", wpa);
00309
00310 fprintf(nconf, "wpa_key_mgmt=");
00311 prefix = "";
00312 if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) {
00313 fprintf(nconf, "WPA-EAP");
00314 prefix = " ";
00315 }
00316 if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK))
00317 fprintf(nconf, "%sWPA-PSK", prefix);
00318 fprintf(nconf, "\n");
00319
00320 fprintf(nconf, "wpa_pairwise=");
00321 prefix = "";
00322 if (cred->encr_type & WPS_ENCR_AES) {
00323 fprintf(nconf, "CCMP");
00324 prefix = " ";
00325 }
00326 if (cred->encr_type & WPS_ENCR_TKIP) {
00327 fprintf(nconf, "%sTKIP", prefix);
00328 }
00329 fprintf(nconf, "\n");
00330
00331 if (cred->key_len >= 8 && cred->key_len < 64) {
00332 fprintf(nconf, "wpa_passphrase=");
00333 for (i = 0; i < cred->key_len; i++)
00334 fputc(cred->key[i], nconf);
00335 fprintf(nconf, "\n");
00336 } else if (cred->key_len == 64) {
00337 fprintf(nconf, "wpa_psk=");
00338 for (i = 0; i < cred->key_len; i++)
00339 fputc(cred->key[i], nconf);
00340 fprintf(nconf, "\n");
00341 } else {
00342 wpa_printf(MSG_WARNING, "WPS: Invalid key length %lu "
00343 "for WPA/WPA2",
00344 (unsigned long) cred->key_len);
00345 }
00346
00347 fprintf(nconf, "auth_algs=1\n");
00348 } else {
00349 if ((cred->auth_type & WPS_AUTH_OPEN) &&
00350 (cred->auth_type & WPS_AUTH_SHARED))
00351 fprintf(nconf, "auth_algs=3\n");
00352 else if (cred->auth_type & WPS_AUTH_SHARED)
00353 fprintf(nconf, "auth_algs=2\n");
00354 else
00355 fprintf(nconf, "auth_algs=1\n");
00356
00357 if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) {
00358 int key_idx = cred->key_idx;
00359 if (key_idx)
00360 key_idx--;
00361 fprintf(nconf, "wep_default_key=%d\n", key_idx);
00362 fprintf(nconf, "wep_key%d=", key_idx);
00363 if (cred->key_len == 10 || cred->key_len == 26) {
00364
00365 for (i = 0; i < cred->key_len; i++)
00366 fputc(cred->key[i], nconf);
00367 } else {
00368
00369 for (i = 0; i < cred->key_len; i++)
00370 fprintf(nconf, "%02x", cred->key[i]);
00371 }
00372 fprintf(nconf, "\n");
00373 }
00374 }
00375
00376 fprintf(nconf, "# WPS configuration - END\n");
00377
00378 multi_bss = 0;
00379 while (fgets(buf, sizeof(buf), oconf)) {
00380 if (os_strncmp(buf, "bss=", 4) == 0)
00381 multi_bss = 1;
00382 if (!multi_bss &&
00383 (str_starts(buf, "ssid=") ||
00384 str_starts(buf, "auth_algs=") ||
00385 str_starts(buf, "wps_state=") ||
00386 str_starts(buf, "wpa=") ||
00387 str_starts(buf, "wpa_psk=") ||
00388 str_starts(buf, "wpa_pairwise=") ||
00389 str_starts(buf, "rsn_pairwise=") ||
00390 str_starts(buf, "wpa_key_mgmt=") ||
00391 str_starts(buf, "wpa_passphrase="))) {
00392 fprintf(nconf, "#WPS# %s", buf);
00393 } else
00394 fprintf(nconf, "%s", buf);
00395 }
00396
00397 fclose(nconf);
00398 fclose(oconf);
00399
00400 if (rename(tmp_fname, hapd->iface->config_fname) < 0) {
00401 wpa_printf(MSG_WARNING, "WPS: Failed to rename the updated "
00402 "configuration file: %s", strerror(errno));
00403 os_free(tmp_fname);
00404 return -1;
00405 }
00406
00407 os_free(tmp_fname);
00408
00409
00410
00411
00412 eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface,
00413 NULL);
00414
00415
00416
00417 wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");
00418
00419 return 0;
00420 }
00421
00422
00423 static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
00424 struct wps_event_pwd_auth_fail *data)
00425 {
00426 FILE *f;
00427
00428 if (!data->enrollee)
00429 return;
00430
00431
00432
00433
00434
00435 hapd->ap_pin_failures++;
00436 if (hapd->ap_pin_failures < 4)
00437 return;
00438
00439 wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);
00440 hapd->wps->ap_setup_locked = 1;
00441
00442 wps_registrar_update_ie(hapd->wps->registrar);
00443
00444 if (hapd->conf->wps_cred_processing == 1)
00445 return;
00446
00447 f = fopen(hapd->iface->config_fname, "a");
00448 if (f == NULL) {
00449 wpa_printf(MSG_WARNING, "WPS: Could not append to the current "
00450 "configuration file");
00451 return;
00452 }
00453
00454 fprintf(f, "# WPS AP Setup Locked based on possible attack\n");
00455 fprintf(f, "ap_setup_locked=1\n");
00456 fclose(f);
00457
00458
00459
00460 wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");
00461 }
00462
00463
00464 static void hostapd_wps_event_cb(void *ctx, enum wps_event event,
00465 union wps_event_data *data)
00466 {
00467 struct hostapd_data *hapd = ctx;
00468
00469 if (event == WPS_EV_PWD_AUTH_FAIL)
00470 hostapd_pwd_auth_fail(hapd, &data->pwd_auth_fail);
00471 }
00472
00473
00474 static void hostapd_wps_clear_ies(struct hostapd_data *hapd)
00475 {
00476 os_free(hapd->wps_beacon_ie);
00477 hapd->wps_beacon_ie = NULL;
00478 hapd->wps_beacon_ie_len = 0;
00479 hostapd_set_wps_beacon_ie(hapd, NULL, 0);
00480
00481 os_free(hapd->wps_probe_resp_ie);
00482 hapd->wps_probe_resp_ie = NULL;
00483 hapd->wps_probe_resp_ie_len = 0;
00484 hostapd_set_wps_probe_resp_ie(hapd, NULL, 0);
00485 }
00486
00487
00488 int hostapd_init_wps(struct hostapd_data *hapd,
00489 struct hostapd_bss_config *conf)
00490 {
00491 struct wps_context *wps;
00492 struct wps_registrar_config cfg;
00493
00494 if (conf->wps_state == 0) {
00495 hostapd_wps_clear_ies(hapd);
00496 return 0;
00497 }
00498
00499 wps = os_zalloc(sizeof(*wps));
00500 if (wps == NULL)
00501 return -1;
00502
00503 wps->cred_cb = hostapd_wps_cred_cb;
00504 wps->event_cb = hostapd_wps_event_cb;
00505 wps->cb_ctx = hapd;
00506
00507 os_memset(&cfg, 0, sizeof(cfg));
00508 wps->wps_state = hapd->conf->wps_state;
00509 wps->ap_setup_locked = hapd->conf->ap_setup_locked;
00510 if (is_nil_uuid(hapd->conf->uuid)) {
00511 uuid_gen_mac_addr(hapd->own_addr, wps->uuid);
00512 wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address",
00513 wps->uuid, UUID_LEN);
00514 } else
00515 os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN);
00516 wps->ssid_len = hapd->conf->ssid.ssid_len;
00517 os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len);
00518 wps->ap = 1;
00519 os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN);
00520 wps->dev.device_name = hapd->conf->device_name ?
00521 os_strdup(hapd->conf->device_name) : NULL;
00522 wps->dev.manufacturer = hapd->conf->manufacturer ?
00523 os_strdup(hapd->conf->manufacturer) : NULL;
00524 wps->dev.model_name = hapd->conf->model_name ?
00525 os_strdup(hapd->conf->model_name) : NULL;
00526 wps->dev.model_number = hapd->conf->model_number ?
00527 os_strdup(hapd->conf->model_number) : NULL;
00528 wps->dev.serial_number = hapd->conf->serial_number ?
00529 os_strdup(hapd->conf->serial_number) : NULL;
00530 if (hapd->conf->config_methods) {
00531 char *m = hapd->conf->config_methods;
00532 if (os_strstr(m, "label"))
00533 wps->config_methods |= WPS_CONFIG_LABEL;
00534 if (os_strstr(m, "display"))
00535 wps->config_methods |= WPS_CONFIG_DISPLAY;
00536 if (os_strstr(m, "push_button"))
00537 wps->config_methods |= WPS_CONFIG_PUSHBUTTON;
00538 if (os_strstr(m, "keypad"))
00539 wps->config_methods |= WPS_CONFIG_KEYPAD;
00540 }
00541 if (hapd->conf->device_type) {
00542 char *pos;
00543 u8 oui[4];
00544
00545 wps->dev.categ = atoi(hapd->conf->device_type);
00546 pos = os_strchr(hapd->conf->device_type, '-');
00547 if (pos == NULL) {
00548 wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
00549 os_free(wps);
00550 return -1;
00551 }
00552 pos++;
00553 if (hexstr2bin(pos, oui, 4)) {
00554 wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI");
00555 os_free(wps);
00556 return -1;
00557 }
00558 wps->dev.oui = WPA_GET_BE32(oui);
00559 pos = os_strchr(pos, '-');
00560 if (pos == NULL) {
00561 wpa_printf(MSG_ERROR, "WPS: Invalid device_type");
00562 os_free(wps);
00563 return -1;
00564 }
00565 pos++;
00566 wps->dev.sub_categ = atoi(pos);
00567 }
00568 wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
00569 wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ?
00570 WPS_RF_50GHZ : WPS_RF_24GHZ;
00571
00572 if (conf->wpa & WPA_PROTO_RSN) {
00573 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
00574 wps->auth_types |= WPS_AUTH_WPA2PSK;
00575 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
00576 wps->auth_types |= WPS_AUTH_WPA2;
00577
00578 if (conf->rsn_pairwise & WPA_CIPHER_CCMP)
00579 wps->encr_types |= WPS_ENCR_AES;
00580 if (conf->rsn_pairwise & WPA_CIPHER_TKIP)
00581 wps->encr_types |= WPS_ENCR_TKIP;
00582 }
00583
00584 if (conf->wpa & WPA_PROTO_WPA) {
00585 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK)
00586 wps->auth_types |= WPS_AUTH_WPAPSK;
00587 if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X)
00588 wps->auth_types |= WPS_AUTH_WPA;
00589
00590 if (conf->wpa_pairwise & WPA_CIPHER_CCMP)
00591 wps->encr_types |= WPS_ENCR_AES;
00592 if (conf->wpa_pairwise & WPA_CIPHER_TKIP)
00593 wps->encr_types |= WPS_ENCR_TKIP;
00594 }
00595
00596 if (conf->ssid.security_policy == SECURITY_PLAINTEXT) {
00597 wps->encr_types |= WPS_ENCR_NONE;
00598 wps->auth_types |= WPS_AUTH_OPEN;
00599 } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) {
00600 wps->encr_types |= WPS_ENCR_WEP;
00601 if (conf->auth_algs & WPA_AUTH_ALG_OPEN)
00602 wps->auth_types |= WPS_AUTH_OPEN;
00603 if (conf->auth_algs & WPA_AUTH_ALG_SHARED)
00604 wps->auth_types |= WPS_AUTH_SHARED;
00605 } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) {
00606 wps->auth_types |= WPS_AUTH_OPEN;
00607 if (conf->default_wep_key_len)
00608 wps->encr_types |= WPS_ENCR_WEP;
00609 else
00610 wps->encr_types |= WPS_ENCR_NONE;
00611 }
00612
00613 if (conf->ssid.wpa_psk_file) {
00614
00615 } else if (conf->ssid.wpa_passphrase) {
00616 wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase);
00617 wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
00618 } else if (conf->ssid.wpa_psk) {
00619 wps->network_key = os_malloc(2 * PMK_LEN + 1);
00620 if (wps->network_key == NULL) {
00621 os_free(wps);
00622 return -1;
00623 }
00624 wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
00625 conf->ssid.wpa_psk->psk, PMK_LEN);
00626 wps->network_key_len = 2 * PMK_LEN;
00627 } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
00628 wps->network_key = os_malloc(conf->ssid.wep.len[0]);
00629 if (wps->network_key == NULL) {
00630 os_free(wps);
00631 return -1;
00632 }
00633 os_memcpy(wps->network_key, conf->ssid.wep.key[0],
00634 conf->ssid.wep.len[0]);
00635 wps->network_key_len = conf->ssid.wep.len[0];
00636 }
00637
00638 if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) {
00639
00640 wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK;
00641 wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP;
00642 }
00643
00644 wps->ap_settings = conf->ap_settings;
00645 wps->ap_settings_len = conf->ap_settings_len;
00646
00647 cfg.new_psk_cb = hostapd_wps_new_psk_cb;
00648 cfg.set_ie_cb = hostapd_wps_set_ie_cb;
00649 cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
00650 cfg.reg_success_cb = hostapd_wps_reg_success_cb;
00651 cfg.cb_ctx = hapd;
00652 cfg.skip_cred_build = conf->skip_cred_build;
00653 cfg.extra_cred = conf->extra_cred;
00654 cfg.extra_cred_len = conf->extra_cred_len;
00655 cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
00656 conf->skip_cred_build;
00657 if (conf->ssid.security_policy == SECURITY_STATIC_WEP)
00658 cfg.static_wep_only = 1;
00659
00660 wps->registrar = wps_registrar_init(wps, &cfg);
00661 if (wps->registrar == NULL) {
00662 printf("Failed to initialize WPS Registrar\n");
00663 os_free(wps->network_key);
00664 os_free(wps);
00665 return -1;
00666 }
00667
00668 #ifdef CONFIG_WPS_UPNP
00669 wps->friendly_name = hapd->conf->friendly_name;
00670 wps->manufacturer_url = hapd->conf->manufacturer_url;
00671 wps->model_description = hapd->conf->model_description;
00672 wps->model_url = hapd->conf->model_url;
00673 wps->upc = hapd->conf->upc;
00674
00675 if (hostapd_wps_upnp_init(hapd, wps) < 0) {
00676 wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP");
00677 wps_registrar_deinit(wps->registrar);
00678 os_free(wps->network_key);
00679 os_free(wps);
00680 return -1;
00681 }
00682 #endif
00683
00684 hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd);
00685
00686 hapd->wps = wps;
00687
00688 return 0;
00689 }
00690
00691
00692 void hostapd_deinit_wps(struct hostapd_data *hapd)
00693 {
00694 if (hapd->wps == NULL)
00695 return;
00696 #ifdef CONFIG_WPS_UPNP
00697 hostapd_wps_upnp_deinit(hapd);
00698 #endif
00699 wps_registrar_deinit(hapd->wps->registrar);
00700 os_free(hapd->wps->network_key);
00701 wps_device_data_free(&hapd->wps->dev);
00702 wpabuf_free(hapd->wps->dh_pubkey);
00703 wpabuf_free(hapd->wps->dh_privkey);
00704 wpabuf_free(hapd->wps->oob_conf.pubkey_hash);
00705 wpabuf_free(hapd->wps->oob_conf.dev_password);
00706 wps_free_pending_msgs(hapd->wps->upnp_msgs);
00707 os_free(hapd->wps);
00708 hapd->wps = NULL;
00709 hostapd_wps_clear_ies(hapd);
00710 }
00711
00712
00713 int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
00714 const char *pin, int timeout)
00715 {
00716 u8 u[UUID_LEN];
00717 int any = 0;
00718
00719 if (hapd->wps == NULL)
00720 return -1;
00721 if (os_strcmp(uuid, "any") == 0)
00722 any = 1;
00723 else if (uuid_str2bin(uuid, u))
00724 return -1;
00725 return wps_registrar_add_pin(hapd->wps->registrar, any ? NULL : u,
00726 (const u8 *) pin, os_strlen(pin),
00727 timeout);
00728 }
00729
00730
00731 int hostapd_wps_button_pushed(struct hostapd_data *hapd)
00732 {
00733 if (hapd->wps == NULL)
00734 return -1;
00735 return wps_registrar_button_pushed(hapd->wps->registrar);
00736 }
00737
00738
00739 #ifdef CONFIG_WPS_OOB
00740 int hostapd_wps_start_oob(struct hostapd_data *hapd, char *device_type,
00741 char *path, char *method, char *name)
00742 {
00743 struct wps_context *wps = hapd->wps;
00744 struct oob_device_data *oob_dev;
00745
00746 oob_dev = wps_get_oob_device(device_type);
00747 if (oob_dev == NULL)
00748 return -1;
00749 oob_dev->device_path = path;
00750 oob_dev->device_name = name;
00751 wps->oob_conf.oob_method = wps_get_oob_method(method);
00752
00753 if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) {
00754
00755
00756
00757
00758 wpabuf_free(wps->dh_pubkey);
00759 wpabuf_free(wps->dh_privkey);
00760 wps->dh_privkey = NULL;
00761 wps->dh_pubkey = dh_init(dh_groups_get(WPS_DH_GROUP),
00762 &wps->dh_privkey);
00763 wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192);
00764 if (wps->dh_pubkey == NULL) {
00765 wpa_printf(MSG_ERROR, "WPS: Failed to initialize "
00766 "Diffie-Hellman handshake");
00767 return -1;
00768 }
00769 }
00770
00771 if (wps_process_oob(wps, oob_dev, 1) < 0)
00772 goto error;
00773
00774 if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E ||
00775 wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) &&
00776 hostapd_wps_add_pin(hapd, "any",
00777 wpabuf_head(wps->oob_conf.dev_password), 0) <
00778 0)
00779 goto error;
00780
00781 return 0;
00782
00783 error:
00784 wpabuf_free(wps->dh_pubkey);
00785 wps->dh_pubkey = NULL;
00786 wpabuf_free(wps->dh_privkey);
00787 wps->dh_privkey = NULL;
00788 return -1;
00789 }
00790 #endif
00791
00792
00793 static void hostapd_wps_probe_req_rx(void *ctx, const u8 *addr,
00794 const u8 *ie, size_t ie_len)
00795 {
00796 struct hostapd_data *hapd = ctx;
00797 struct wpabuf *wps_ie;
00798
00799 if (hapd->wps == NULL)
00800 return;
00801
00802 wps_ie = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
00803 if (wps_ie == NULL)
00804 return;
00805
00806 if (wpabuf_len(wps_ie) > 0) {
00807 wps_registrar_probe_req_rx(hapd->wps->registrar, addr, wps_ie);
00808 #ifdef CONFIG_WPS_UPNP
00809
00810
00811 upnp_wps_device_send_wlan_event(hapd->wps_upnp, addr,
00812 UPNP_WPS_WLANEVENT_TYPE_PROBE,
00813 wps_ie);
00814 #endif
00815 }
00816
00817 wpabuf_free(wps_ie);
00818 }
00819
00820
00821 #ifdef CONFIG_WPS_UPNP
00822
00823 static struct wpabuf *
00824 hostapd_rx_req_get_device_info(void *priv, struct upnp_wps_peer *peer)
00825 {
00826 struct hostapd_data *hapd = priv;
00827 struct wps_config cfg;
00828 struct wps_data *wps;
00829 enum wsc_op_code op_code;
00830 struct wpabuf *m1;
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 if (peer->wps)
00841 wps_deinit(peer->wps);
00842
00843 os_memset(&cfg, 0, sizeof(cfg));
00844 cfg.wps = hapd->wps;
00845 cfg.pin = (u8 *) hapd->conf->ap_pin;
00846 cfg.pin_len = os_strlen(hapd->conf->ap_pin);
00847 wps = wps_init(&cfg);
00848 if (wps == NULL)
00849 return NULL;
00850
00851 m1 = wps_get_msg(wps, &op_code);
00852 if (m1 == NULL) {
00853 wps_deinit(wps);
00854 return NULL;
00855 }
00856
00857 peer->wps = wps;
00858
00859 return m1;
00860 }
00861
00862
00863 static struct wpabuf *
00864 hostapd_rx_req_put_message(void *priv, struct upnp_wps_peer *peer,
00865 const struct wpabuf *msg)
00866 {
00867 enum wps_process_res res;
00868 enum wsc_op_code op_code;
00869
00870
00871 res = wps_process_msg(peer->wps, WSC_UPnP, msg);
00872 if (res == WPS_FAILURE)
00873 return NULL;
00874 return wps_get_msg(peer->wps, &op_code);
00875 }
00876
00877
00878 static int hostapd_rx_req_put_wlan_response(
00879 void *priv, enum upnp_wps_wlanevent_type ev_type,
00880 const u8 *mac_addr, const struct wpabuf *msg,
00881 enum wps_msg_type msg_type)
00882 {
00883 struct hostapd_data *hapd = priv;
00884 struct sta_info *sta;
00885 struct upnp_pending_message *p;
00886
00887 wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse ev_type=%d mac_addr="
00888 MACSTR, ev_type, MAC2STR(mac_addr));
00889 wpa_hexdump(MSG_MSGDUMP, "WPS UPnP: PutWLANResponse NewMessage",
00890 wpabuf_head(msg), wpabuf_len(msg));
00891 if (ev_type != UPNP_WPS_WLANEVENT_TYPE_EAP) {
00892 wpa_printf(MSG_DEBUG, "WPS UPnP: Ignored unexpected "
00893 "PutWLANResponse WLANEventType %d", ev_type);
00894 return -1;
00895 }
00896
00897
00898
00899
00900
00901
00902 sta = ap_get_sta(hapd, mac_addr);
00903 if (!sta) {
00904
00905
00906
00907
00908
00909 wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found based "
00910 "on NewWLANEventMAC; try wildcard match");
00911 for (sta = hapd->sta_list; sta; sta = sta->next) {
00912 if (sta->eapol_sm && (sta->flags & WLAN_STA_WPS))
00913 break;
00914 }
00915 }
00916
00917 if (!sta) {
00918 wpa_printf(MSG_DEBUG, "WPS UPnP: No matching STA found");
00919 return 0;
00920 }
00921
00922 p = os_zalloc(sizeof(*p));
00923 if (p == NULL)
00924 return -1;
00925 os_memcpy(p->addr, sta->addr, ETH_ALEN);
00926 p->msg = wpabuf_dup(msg);
00927 p->type = msg_type;
00928 p->next = hapd->wps->upnp_msgs;
00929 hapd->wps->upnp_msgs = p;
00930
00931 return eapol_auth_eap_pending_cb(sta->eapol_sm, sta->eapol_sm->eap);
00932 }
00933
00934
00935 static int hostapd_rx_req_set_selected_registrar(void *priv,
00936 const struct wpabuf *msg)
00937 {
00938 struct hostapd_data *hapd = priv;
00939 return wps_registrar_set_selected_registrar(hapd->wps->registrar, msg);
00940 }
00941
00942
00943 static int hostapd_wps_upnp_init(struct hostapd_data *hapd,
00944 struct wps_context *wps)
00945 {
00946 struct upnp_wps_device_ctx *ctx;
00947
00948 if (!hapd->conf->upnp_iface)
00949 return 0;
00950 ctx = os_zalloc(sizeof(*ctx));
00951 if (ctx == NULL)
00952 return -1;
00953
00954 ctx->rx_req_get_device_info = hostapd_rx_req_get_device_info;
00955 ctx->rx_req_put_message = hostapd_rx_req_put_message;
00956 ctx->rx_req_put_wlan_response = hostapd_rx_req_put_wlan_response;
00957 ctx->rx_req_set_selected_registrar =
00958 hostapd_rx_req_set_selected_registrar;
00959
00960 hapd->wps_upnp = upnp_wps_device_init(ctx, wps, hapd);
00961 if (hapd->wps_upnp == NULL) {
00962 os_free(ctx);
00963 return -1;
00964 }
00965 wps->wps_upnp = hapd->wps_upnp;
00966
00967 if (upnp_wps_device_start(hapd->wps_upnp, hapd->conf->upnp_iface)) {
00968 upnp_wps_device_deinit(hapd->wps_upnp);
00969 hapd->wps_upnp = NULL;
00970 return -1;
00971 }
00972
00973 return 0;
00974 }
00975
00976
00977 static void hostapd_wps_upnp_deinit(struct hostapd_data *hapd)
00978 {
00979 upnp_wps_device_deinit(hapd->wps_upnp);
00980 }
00981
00982 #endif
00983
00984
00985 int hostapd_wps_get_mib_sta(struct hostapd_data *hapd, const u8 *addr,
00986 char *buf, size_t buflen)
00987 {
00988 return wps_registrar_get_info(hapd->wps->registrar, addr, buf, buflen);
00989 }
00990