wps_registrar.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "sha256.h"
00020 #include "base64.h"
00021 #include "ieee802_11_defs.h"
00022 #include "eloop.h"
00023 #include "wps_i.h"
00024 #include "wps_dev_attr.h"
00025 #include "wps_upnp.h"
00026 #include "crypto.h"
00027 #include "uuid.h"
00028 
00029 #define WPS_WORKAROUNDS
00030 
00031 struct wps_uuid_pin {
00032         struct wps_uuid_pin *next;
00033         u8 uuid[WPS_UUID_LEN];
00034         int wildcard_uuid;
00035         u8 *pin;
00036         size_t pin_len;
00037 #define PIN_LOCKED BIT(0)
00038 #define PIN_EXPIRES BIT(1)
00039         int flags;
00040         struct os_time expiration;
00041 };
00042 
00043 
00044 static void wps_free_pin(struct wps_uuid_pin *pin)
00045 {
00046         os_free(pin->pin);
00047         os_free(pin);
00048 }
00049 
00050 
00051 static void wps_free_pins(struct wps_uuid_pin *pins)
00052 {
00053         struct wps_uuid_pin *pin, *prev;
00054 
00055         pin = pins;
00056         while (pin) {
00057                 prev = pin;
00058                 pin = pin->next;
00059                 wps_free_pin(prev);
00060         }
00061 }
00062 
00063 
00064 struct wps_pbc_session {
00065         struct wps_pbc_session *next;
00066         u8 addr[ETH_ALEN];
00067         u8 uuid_e[WPS_UUID_LEN];
00068         struct os_time timestamp;
00069 };
00070 
00071 
00072 static void wps_free_pbc_sessions(struct wps_pbc_session *pbc)
00073 {
00074         struct wps_pbc_session *prev;
00075 
00076         while (pbc) {
00077                 prev = pbc;
00078                 pbc = pbc->next;
00079                 os_free(prev);
00080         }
00081 }
00082 
00083 
00084 struct wps_registrar_device {
00085         struct wps_registrar_device *next;
00086         struct wps_device_data dev;
00087         u8 uuid[WPS_UUID_LEN];
00088 };
00089 
00090 
00091 struct wps_registrar {
00092         struct wps_context *wps;
00093 
00094         int pbc;
00095         int selected_registrar;
00096 
00097         int (*new_psk_cb)(void *ctx, const u8 *mac_addr, const u8 *psk,
00098                           size_t psk_len);
00099         int (*set_ie_cb)(void *ctx, const u8 *beacon_ie, size_t beacon_ie_len,
00100                          const u8 *probe_resp_ie, size_t probe_resp_ie_len);
00101         void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
00102                               const struct wps_device_data *dev);
00103         void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
00104                                const u8 *uuid_e);
00105         void (*set_sel_reg_cb)(void *ctx, int sel_reg, u16 dev_passwd_id,
00106                                u16 sel_reg_config_methods);
00107         void *cb_ctx;
00108 
00109         struct wps_uuid_pin *pins;
00110         struct wps_pbc_session *pbc_sessions;
00111 
00112         int skip_cred_build;
00113         struct wpabuf *extra_cred;
00114         int disable_auto_conf;
00115         int sel_reg_dev_password_id_override;
00116         int sel_reg_config_methods_override;
00117         int static_wep_only;
00118 
00119         struct wps_registrar_device *devices;
00120 
00121         int force_pbc_overlap;
00122 };
00123 
00124 
00125 static int wps_set_ie(struct wps_registrar *reg);
00126 static void wps_cb_set_sel_reg(struct wps_registrar *reg);
00127 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx);
00128 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
00129                                                void *timeout_ctx);
00130 
00131 
00132 static void wps_free_devices(struct wps_registrar_device *dev)
00133 {
00134         struct wps_registrar_device *prev;
00135 
00136         while (dev) {
00137                 prev = dev;
00138                 dev = dev->next;
00139                 wps_device_data_free(&prev->dev);
00140                 os_free(prev);
00141         }
00142 }
00143 
00144 
00145 static struct wps_registrar_device * wps_device_get(struct wps_registrar *reg,
00146                                                     const u8 *addr)
00147 {
00148         struct wps_registrar_device *dev;
00149 
00150         for (dev = reg->devices; dev; dev = dev->next) {
00151                 if (os_memcmp(dev->dev.mac_addr, addr, ETH_ALEN) == 0)
00152                         return dev;
00153         }
00154         return NULL;
00155 }
00156 
00157 
00158 static void wps_device_clone_data(struct wps_device_data *dst,
00159                                   struct wps_device_data *src)
00160 {
00161         os_memcpy(dst->mac_addr, src->mac_addr, ETH_ALEN);
00162         dst->categ = src->categ;
00163         dst->oui = src->oui;
00164         dst->sub_categ = src->sub_categ;
00165 
00166 #define WPS_STRDUP(n) \
00167         os_free(dst->n); \
00168         dst->n = src->n ? os_strdup(src->n) : NULL
00169 
00170         WPS_STRDUP(device_name);
00171         WPS_STRDUP(manufacturer);
00172         WPS_STRDUP(model_name);
00173         WPS_STRDUP(model_number);
00174         WPS_STRDUP(serial_number);
00175 #undef WPS_STRDUP
00176 }
00177 
00178 
00179 int wps_device_store(struct wps_registrar *reg,
00180                      struct wps_device_data *dev, const u8 *uuid)
00181 {
00182         struct wps_registrar_device *d;
00183 
00184         d = wps_device_get(reg, dev->mac_addr);
00185         if (d == NULL) {
00186                 d = os_zalloc(sizeof(*d));
00187                 if (d == NULL)
00188                         return -1;
00189                 d->next = reg->devices;
00190                 reg->devices = d;
00191         }
00192 
00193         wps_device_clone_data(&d->dev, dev);
00194         os_memcpy(d->uuid, uuid, WPS_UUID_LEN);
00195 
00196         return 0;
00197 }
00198 
00199 
00200 static void wps_registrar_add_pbc_session(struct wps_registrar *reg,
00201                                           const u8 *addr, const u8 *uuid_e)
00202 {
00203         struct wps_pbc_session *pbc, *prev = NULL;
00204         struct os_time now;
00205 
00206         os_get_time(&now);
00207 
00208         pbc = reg->pbc_sessions;
00209         while (pbc) {
00210                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
00211                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
00212                         if (prev)
00213                                 prev->next = pbc->next;
00214                         else
00215                                 reg->pbc_sessions = pbc->next;
00216                         break;
00217                 }
00218                 prev = pbc;
00219                 pbc = pbc->next;
00220         }
00221 
00222         if (!pbc) {
00223                 pbc = os_zalloc(sizeof(*pbc));
00224                 if (pbc == NULL)
00225                         return;
00226                 os_memcpy(pbc->addr, addr, ETH_ALEN);
00227                 if (uuid_e)
00228                         os_memcpy(pbc->uuid_e, uuid_e, WPS_UUID_LEN);
00229         }
00230 
00231         pbc->next = reg->pbc_sessions;
00232         reg->pbc_sessions = pbc;
00233         pbc->timestamp = now;
00234 
00235         /* remove entries that have timed out */
00236         prev = pbc;
00237         pbc = pbc->next;
00238 
00239         while (pbc) {
00240                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME) {
00241                         prev->next = NULL;
00242                         wps_free_pbc_sessions(pbc);
00243                         break;
00244                 }
00245                 prev = pbc;
00246                 pbc = pbc->next;
00247         }
00248 }
00249 
00250 
00251 static void wps_registrar_remove_pbc_session(struct wps_registrar *reg,
00252                                              const u8 *addr, const u8 *uuid_e)
00253 {
00254         struct wps_pbc_session *pbc, *prev = NULL;
00255 
00256         pbc = reg->pbc_sessions;
00257         while (pbc) {
00258                 if (os_memcmp(pbc->addr, addr, ETH_ALEN) == 0 &&
00259                     os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) {
00260                         if (prev)
00261                                 prev->next = pbc->next;
00262                         else
00263                                 reg->pbc_sessions = pbc->next;
00264                         os_free(pbc);
00265                         break;
00266                 }
00267                 prev = pbc;
00268                 pbc = pbc->next;
00269         }
00270 }
00271 
00272 
00273 static int wps_registrar_pbc_overlap(struct wps_registrar *reg,
00274                                      const u8 *addr, const u8 *uuid_e)
00275 {
00276         int count = 0;
00277         struct wps_pbc_session *pbc;
00278         struct os_time now;
00279 
00280         os_get_time(&now);
00281 
00282         for (pbc = reg->pbc_sessions; pbc; pbc = pbc->next) {
00283                 if (now.sec > pbc->timestamp.sec + WPS_PBC_WALK_TIME)
00284                         break;
00285                 if (addr == NULL || os_memcmp(addr, pbc->addr, ETH_ALEN) ||
00286                     uuid_e == NULL ||
00287                     os_memcmp(uuid_e, pbc->uuid_e, WPS_UUID_LEN))
00288                         count++;
00289         }
00290 
00291         if (addr || uuid_e)
00292                 count++;
00293 
00294         return count > 1 ? 1 : 0;
00295 }
00296 
00297 
00298 static int wps_build_wps_state(struct wps_context *wps, struct wpabuf *msg)
00299 {
00300         wpa_printf(MSG_DEBUG, "WPS:  * Wi-Fi Protected Setup State (%d)",
00301                    wps->wps_state);
00302         wpabuf_put_be16(msg, ATTR_WPS_STATE);
00303         wpabuf_put_be16(msg, 1);
00304         wpabuf_put_u8(msg, wps->wps_state);
00305         return 0;
00306 }
00307 
00308 
00309 #ifdef CONFIG_WPS_UPNP
00310 static void wps_registrar_free_pending_m2(struct wps_context *wps)
00311 {
00312         struct upnp_pending_message *p, *p2, *prev = NULL;
00313         p = wps->upnp_msgs;
00314         while (p) {
00315                 if (p->type == WPS_M2 || p->type == WPS_M2D) {
00316                         if (prev == NULL)
00317                                 wps->upnp_msgs = p->next;
00318                         else
00319                                 prev->next = p->next;
00320                         wpa_printf(MSG_DEBUG, "WPS UPnP: Drop pending M2/M2D");
00321                         p2 = p;
00322                         p = p->next;
00323                         wpabuf_free(p2->msg);
00324                         os_free(p2);
00325                         continue;
00326                 }
00327                 prev = p;
00328                 p = p->next;
00329         }
00330 }
00331 #endif /* CONFIG_WPS_UPNP */
00332 
00333 
00334 static int wps_build_ap_setup_locked(struct wps_context *wps,
00335                                      struct wpabuf *msg)
00336 {
00337         if (wps->ap_setup_locked) {
00338                 wpa_printf(MSG_DEBUG, "WPS:  * AP Setup Locked");
00339                 wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED);
00340                 wpabuf_put_be16(msg, 1);
00341                 wpabuf_put_u8(msg, 1);
00342         }
00343         return 0;
00344 }
00345 
00346 
00347 static int wps_build_selected_registrar(struct wps_registrar *reg,
00348                                         struct wpabuf *msg)
00349 {
00350         if (!reg->selected_registrar)
00351                 return 0;
00352         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar");
00353         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR);
00354         wpabuf_put_be16(msg, 1);
00355         wpabuf_put_u8(msg, 1);
00356         return 0;
00357 }
00358 
00359 
00360 static int wps_build_sel_reg_dev_password_id(struct wps_registrar *reg,
00361                                              struct wpabuf *msg)
00362 {
00363         u16 id = reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT;
00364         if (!reg->selected_registrar)
00365                 return 0;
00366         if (reg->sel_reg_dev_password_id_override >= 0)
00367                 id = reg->sel_reg_dev_password_id_override;
00368         wpa_printf(MSG_DEBUG, "WPS:  * Device Password ID (%d)", id);
00369         wpabuf_put_be16(msg, ATTR_DEV_PASSWORD_ID);
00370         wpabuf_put_be16(msg, 2);
00371         wpabuf_put_be16(msg, id);
00372         return 0;
00373 }
00374 
00375 
00376 static int wps_build_sel_reg_config_methods(struct wps_registrar *reg,
00377                                             struct wpabuf *msg)
00378 {
00379         u16 methods;
00380         if (!reg->selected_registrar)
00381                 return 0;
00382         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00383         if (reg->pbc)
00384                 methods |= WPS_CONFIG_PUSHBUTTON;
00385         if (reg->sel_reg_config_methods_override >= 0)
00386                 methods = reg->sel_reg_config_methods_override;
00387         wpa_printf(MSG_DEBUG, "WPS:  * Selected Registrar Config Methods (%x)",
00388                    methods);
00389         wpabuf_put_be16(msg, ATTR_SELECTED_REGISTRAR_CONFIG_METHODS);
00390         wpabuf_put_be16(msg, 2);
00391         wpabuf_put_be16(msg, methods);
00392         return 0;
00393 }
00394 
00395 
00396 static int wps_build_probe_config_methods(struct wps_registrar *reg,
00397                                           struct wpabuf *msg)
00398 {
00399         u16 methods;
00400         methods = 0;
00401         wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);
00402         wpabuf_put_be16(msg, ATTR_CONFIG_METHODS);
00403         wpabuf_put_be16(msg, 2);
00404         wpabuf_put_be16(msg, methods);
00405         return 0;
00406 }
00407 
00408 
00409 static int wps_build_config_methods_r(struct wps_registrar *reg,
00410                                       struct wpabuf *msg)
00411 {
00412         u16 methods;
00413         methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00414         if (reg->pbc)
00415                 methods |= WPS_CONFIG_PUSHBUTTON;
00416         return wps_build_config_methods(msg, methods);
00417 }
00418 
00419 
00420 static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
00421 {
00422         u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
00423         wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", resp);
00424         wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
00425         wpabuf_put_be16(msg, 1);
00426         wpabuf_put_u8(msg, resp);
00427         return 0;
00428 }
00429 
00430 
00444 struct wps_registrar *
00445 wps_registrar_init(struct wps_context *wps,
00446                    const struct wps_registrar_config *cfg)
00447 {
00448         struct wps_registrar *reg = os_zalloc(sizeof(*reg));
00449         if (reg == NULL)
00450                 return NULL;
00451 
00452         reg->wps = wps;
00453         reg->new_psk_cb = cfg->new_psk_cb;
00454         reg->set_ie_cb = cfg->set_ie_cb;
00455         reg->pin_needed_cb = cfg->pin_needed_cb;
00456         reg->reg_success_cb = cfg->reg_success_cb;
00457         reg->set_sel_reg_cb = cfg->set_sel_reg_cb;
00458         reg->cb_ctx = cfg->cb_ctx;
00459         reg->skip_cred_build = cfg->skip_cred_build;
00460         if (cfg->extra_cred) {
00461                 reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
00462                                                     cfg->extra_cred_len);
00463                 if (reg->extra_cred == NULL) {
00464                         os_free(reg);
00465                         return NULL;
00466                 }
00467         }
00468         reg->disable_auto_conf = cfg->disable_auto_conf;
00469         reg->sel_reg_dev_password_id_override = -1;
00470         reg->sel_reg_config_methods_override = -1;
00471         reg->static_wep_only = cfg->static_wep_only;
00472 
00473         if (wps_set_ie(reg)) {
00474                 wps_registrar_deinit(reg);
00475                 return NULL;
00476         }
00477 
00478         return reg;
00479 }
00480 
00481 
00487 void wps_registrar_deinit(struct wps_registrar *reg)
00488 {
00489         if (reg == NULL)
00490                 return;
00491         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00492         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00493         wps_free_pins(reg->pins);
00494         wps_free_pbc_sessions(reg->pbc_sessions);
00495         wpabuf_free(reg->extra_cred);
00496         wps_free_devices(reg->devices);
00497         os_free(reg);
00498 }
00499 
00500 
00511 int wps_registrar_add_pin(struct wps_registrar *reg, const u8 *uuid,
00512                           const u8 *pin, size_t pin_len, int timeout)
00513 {
00514         struct wps_uuid_pin *p;
00515 
00516         p = os_zalloc(sizeof(*p));
00517         if (p == NULL)
00518                 return -1;
00519         if (uuid == NULL)
00520                 p->wildcard_uuid = 1;
00521         else
00522                 os_memcpy(p->uuid, uuid, WPS_UUID_LEN);
00523         p->pin = os_malloc(pin_len);
00524         if (p->pin == NULL) {
00525                 os_free(p);
00526                 return -1;
00527         }
00528         os_memcpy(p->pin, pin, pin_len);
00529         p->pin_len = pin_len;
00530 
00531         if (timeout) {
00532                 p->flags |= PIN_EXPIRES;
00533                 os_get_time(&p->expiration);
00534                 p->expiration.sec += timeout;
00535         }
00536 
00537         p->next = reg->pins;
00538         reg->pins = p;
00539 
00540         wpa_printf(MSG_DEBUG, "WPS: A new PIN configured (timeout=%d)",
00541                    timeout);
00542         wpa_hexdump(MSG_DEBUG, "WPS: UUID", uuid, WPS_UUID_LEN);
00543         wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: PIN", pin, pin_len);
00544         reg->selected_registrar = 1;
00545         reg->pbc = 0;
00546         wps_set_ie(reg);
00547         wps_cb_set_sel_reg(reg);
00548         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00549         eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
00550                                wps_registrar_set_selected_timeout,
00551                                reg, NULL);
00552 
00553         return 0;
00554 }
00555 
00556 
00557 static void wps_registrar_expire_pins(struct wps_registrar *reg)
00558 {
00559         struct wps_uuid_pin *pin, *prev, *del;
00560         struct os_time now;
00561 
00562         os_get_time(&now);
00563         prev = NULL;
00564         pin = reg->pins;
00565         while (pin) {
00566                 if ((pin->flags & PIN_EXPIRES) &&
00567                     os_time_before(&pin->expiration, &now)) {
00568                         if (prev == NULL)
00569                                 reg->pins = pin->next;
00570                         else
00571                                 prev->next = pin->next;
00572                         del = pin;
00573                         pin = pin->next;
00574                         wpa_hexdump(MSG_DEBUG, "WPS: Expired PIN for UUID",
00575                                     del->uuid, WPS_UUID_LEN);
00576                         wps_free_pin(del);
00577                         continue;
00578                 }
00579                 prev = pin;
00580                 pin = pin->next;
00581         }
00582 }
00583 
00584 
00592 int wps_registrar_invalidate_pin(struct wps_registrar *reg, const u8 *uuid)
00593 {
00594         struct wps_uuid_pin *pin, *prev;
00595 
00596         prev = NULL;
00597         pin = reg->pins;
00598         while (pin) {
00599                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00600                         if (prev == NULL)
00601                                 reg->pins = pin->next;
00602                         else
00603                                 prev->next = pin->next;
00604                         wpa_hexdump(MSG_DEBUG, "WPS: Invalidated PIN for UUID",
00605                                     pin->uuid, WPS_UUID_LEN);
00606                         wps_free_pin(pin);
00607                         return 0;
00608                 }
00609                 prev = pin;
00610                 pin = pin->next;
00611         }
00612 
00613         return -1;
00614 }
00615 
00616 
00617 static const u8 * wps_registrar_get_pin(struct wps_registrar *reg,
00618                                         const u8 *uuid, size_t *pin_len)
00619 {
00620         struct wps_uuid_pin *pin;
00621 
00622         wps_registrar_expire_pins(reg);
00623 
00624         pin = reg->pins;
00625         while (pin) {
00626                 if (!pin->wildcard_uuid &&
00627                     os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0)
00628                         break;
00629                 pin = pin->next;
00630         }
00631 
00632         if (!pin) {
00633                 /* Check for wildcard UUIDs since none of the UUID-specific
00634                  * PINs matched */
00635                 pin = reg->pins;
00636                 while (pin) {
00637                         if (pin->wildcard_uuid == 1) {
00638                                 wpa_printf(MSG_DEBUG, "WPS: Found a wildcard "
00639                                            "PIN. Assigned it for this UUID-E");
00640                                 pin->wildcard_uuid = 2;
00641                                 os_memcpy(pin->uuid, uuid, WPS_UUID_LEN);
00642                                 break;
00643                         }
00644                         pin = pin->next;
00645                 }
00646         }
00647 
00648         if (!pin)
00649                 return NULL;
00650 
00651         /*
00652          * Lock the PIN to avoid attacks based on concurrent re-use of the PIN
00653          * that could otherwise avoid PIN invalidations.
00654          */
00655         if (pin->flags & PIN_LOCKED) {
00656                 wpa_printf(MSG_DEBUG, "WPS: Selected PIN locked - do not "
00657                            "allow concurrent re-use");
00658                 return NULL;
00659         }
00660         *pin_len = pin->pin_len;
00661         pin->flags |= PIN_LOCKED;
00662         return pin->pin;
00663 }
00664 
00665 
00677 int wps_registrar_unlock_pin(struct wps_registrar *reg, const u8 *uuid)
00678 {
00679         struct wps_uuid_pin *pin;
00680 
00681         pin = reg->pins;
00682         while (pin) {
00683                 if (os_memcmp(pin->uuid, uuid, WPS_UUID_LEN) == 0) {
00684                         if (pin->wildcard_uuid == 2) {
00685                                 wpa_printf(MSG_DEBUG, "WPS: Invalidating used "
00686                                            "wildcard PIN");
00687                                 return wps_registrar_invalidate_pin(reg, uuid);
00688                         }
00689                         pin->flags &= ~PIN_LOCKED;
00690                         return 0;
00691                 }
00692                 pin = pin->next;
00693         }
00694 
00695         return -1;
00696 }
00697 
00698 
00699 static void wps_registrar_stop_pbc(struct wps_registrar *reg)
00700 {
00701         reg->selected_registrar = 0;
00702         reg->pbc = 0;
00703         wps_set_ie(reg);
00704         wps_cb_set_sel_reg(reg);
00705 }
00706 
00707 
00708 static void wps_registrar_pbc_timeout(void *eloop_ctx, void *timeout_ctx)
00709 {
00710         struct wps_registrar *reg = eloop_ctx;
00711 
00712         wpa_printf(MSG_DEBUG, "WPS: PBC timed out - disable PBC mode");
00713         wps_pbc_timeout_event(reg->wps);
00714         wps_registrar_stop_pbc(reg);
00715 }
00716 
00717 
00728 int wps_registrar_button_pushed(struct wps_registrar *reg)
00729 {
00730         if (wps_registrar_pbc_overlap(reg, NULL, NULL)) {
00731                 wpa_printf(MSG_DEBUG, "WPS: PBC overlap - do not start PBC "
00732                            "mode");
00733                 wps_pbc_overlap_event(reg->wps);
00734                 return -1;
00735         }
00736         wpa_printf(MSG_DEBUG, "WPS: Button pushed - PBC mode started");
00737         reg->force_pbc_overlap = 0;
00738         reg->selected_registrar = 1;
00739         reg->pbc = 1;
00740         wps_set_ie(reg);
00741         wps_cb_set_sel_reg(reg);
00742 
00743         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00744         eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wps_registrar_pbc_timeout,
00745                                reg, NULL);
00746         return 0;
00747 }
00748 
00749 
00750 static void wps_registrar_pbc_completed(struct wps_registrar *reg)
00751 {
00752         wpa_printf(MSG_DEBUG, "WPS: PBC completed - stopping PBC mode");
00753         eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
00754         wps_registrar_stop_pbc(reg);
00755 }
00756 
00757 static void wps_registrar_pin_completed(struct wps_registrar *reg)
00758 {
00759         wpa_printf(MSG_DEBUG, "WPS: PIN completed using internal Registrar");
00760         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
00761         reg->selected_registrar = 0;
00762         wps_set_ie(reg);
00763         wps_cb_set_sel_reg(reg);
00764 }
00765 
00766 
00778 void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
00779                                 const struct wpabuf *wps_data)
00780 {
00781         struct wps_parse_attr attr;
00782         u16 methods;
00783 
00784         wpa_hexdump_buf(MSG_MSGDUMP,
00785                         "WPS: Probe Request with WPS data received",
00786                         wps_data);
00787 
00788         if (wps_parse_msg(wps_data, &attr) < 0)
00789                 return;
00790         if (!wps_version_supported(attr.version)) {
00791                 wpa_printf(MSG_DEBUG, "WPS: Unsupported ProbeReq WPS IE "
00792                            "version 0x%x", attr.version ? *attr.version : 0);
00793                 return;
00794         }
00795 
00796         if (attr.config_methods == NULL) {
00797                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods attribute in "
00798                            "Probe Request");
00799                 return;
00800         }
00801 
00802         methods = WPA_GET_BE16(attr.config_methods);
00803         if (!(methods & WPS_CONFIG_PUSHBUTTON))
00804                 return; /* Not PBC */
00805 
00806         wpa_printf(MSG_DEBUG, "WPS: Probe Request for PBC received from "
00807                    MACSTR, MAC2STR(addr));
00808 
00809         wps_registrar_add_pbc_session(reg, addr, attr.uuid_e);
00810         if (wps_registrar_pbc_overlap(reg, addr, attr.uuid_e)) {
00811                 wpa_printf(MSG_DEBUG, "WPS: PBC session overlap detected");
00812                 reg->force_pbc_overlap = 1;
00813                 wps_pbc_overlap_event(reg->wps);
00814         }
00815 }
00816 
00817 
00818 static int wps_cb_new_psk(struct wps_registrar *reg, const u8 *mac_addr,
00819                           const u8 *psk, size_t psk_len)
00820 {
00821         if (reg->new_psk_cb == NULL)
00822                 return 0;
00823 
00824         return reg->new_psk_cb(reg->cb_ctx, mac_addr, psk, psk_len);
00825 }
00826 
00827 
00828 static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
00829                               const struct wps_device_data *dev)
00830 {
00831         if (reg->pin_needed_cb == NULL)
00832                 return;
00833 
00834         reg->pin_needed_cb(reg->cb_ctx, uuid_e, dev);
00835 }
00836 
00837 
00838 static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
00839                                const u8 *uuid_e)
00840 {
00841         if (reg->reg_success_cb == NULL)
00842                 return;
00843 
00844         reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
00845 }
00846 
00847 
00848 static int wps_cb_set_ie(struct wps_registrar *reg,
00849                          const struct wpabuf *beacon_ie,
00850                          const struct wpabuf *probe_resp_ie)
00851 {
00852         if (reg->set_ie_cb == NULL)
00853                 return 0;
00854 
00855         return reg->set_ie_cb(reg->cb_ctx, wpabuf_head(beacon_ie),
00856                               wpabuf_len(beacon_ie),
00857                               wpabuf_head(probe_resp_ie),
00858                               wpabuf_len(probe_resp_ie));
00859 }
00860 
00861 
00862 static void wps_cb_set_sel_reg(struct wps_registrar *reg)
00863 {
00864         u16 methods = 0;
00865         if (reg->set_sel_reg_cb == NULL)
00866                 return;
00867 
00868         if (reg->selected_registrar) {
00869                 methods = reg->wps->config_methods & ~WPS_CONFIG_PUSHBUTTON;
00870                 if (reg->pbc)
00871                         methods |= WPS_CONFIG_PUSHBUTTON;
00872         }
00873 
00874         reg->set_sel_reg_cb(reg->cb_ctx, reg->selected_registrar,
00875                             reg->pbc ? DEV_PW_PUSHBUTTON : DEV_PW_DEFAULT,
00876                             methods);
00877 }
00878 
00879 
00880 /* Encapsulate WPS IE data with one (or more, if needed) IE headers */
00881 static struct wpabuf * wps_ie_encapsulate(struct wpabuf *data)
00882 {
00883         struct wpabuf *ie;
00884         const u8 *pos, *end;
00885 
00886         ie = wpabuf_alloc(wpabuf_len(data) + 100);
00887         if (ie == NULL) {
00888                 wpabuf_free(data);
00889                 return NULL;
00890         }
00891 
00892         pos = wpabuf_head(data);
00893         end = pos + wpabuf_len(data);
00894 
00895         while (end > pos) {
00896                 size_t frag_len = end - pos;
00897                 if (frag_len > 251)
00898                         frag_len = 251;
00899                 wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
00900                 wpabuf_put_u8(ie, 4 + frag_len);
00901                 wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
00902                 wpabuf_put_data(ie, pos, frag_len);
00903                 pos += frag_len;
00904         }
00905 
00906         wpabuf_free(data);
00907 
00908         return ie;
00909 }
00910 
00911 
00912 static int wps_set_ie(struct wps_registrar *reg)
00913 {
00914         struct wpabuf *beacon;
00915         struct wpabuf *probe;
00916         int ret;
00917 
00918         wpa_printf(MSG_DEBUG, "WPS: Build Beacon and Probe Response IEs");
00919 
00920         beacon = wpabuf_alloc(300);
00921         if (beacon == NULL)
00922                 return -1;
00923         probe = wpabuf_alloc(400);
00924         if (probe == NULL) {
00925                 wpabuf_free(beacon);
00926                 return -1;
00927         }
00928 
00929         if (wps_build_version(beacon) ||
00930             wps_build_wps_state(reg->wps, beacon) ||
00931             wps_build_ap_setup_locked(reg->wps, beacon) ||
00932             wps_build_selected_registrar(reg, beacon) ||
00933             wps_build_sel_reg_dev_password_id(reg, beacon) ||
00934             wps_build_sel_reg_config_methods(reg, beacon) ||
00935             wps_build_version(probe) ||
00936             wps_build_wps_state(reg->wps, probe) ||
00937             wps_build_ap_setup_locked(reg->wps, probe) ||
00938             wps_build_selected_registrar(reg, probe) ||
00939             wps_build_sel_reg_dev_password_id(reg, probe) ||
00940             wps_build_sel_reg_config_methods(reg, probe) ||
00941             wps_build_resp_type(reg, probe) ||
00942             wps_build_uuid_e(probe, reg->wps->uuid) ||
00943             wps_build_device_attrs(&reg->wps->dev, probe) ||
00944             wps_build_probe_config_methods(reg, probe) ||
00945             wps_build_rf_bands(&reg->wps->dev, probe)) {
00946                 wpabuf_free(beacon);
00947                 wpabuf_free(probe);
00948                 return -1;
00949         }
00950 
00951         beacon = wps_ie_encapsulate(beacon);
00952         probe = wps_ie_encapsulate(probe);
00953 
00954         if (!beacon || !probe) {
00955                 wpabuf_free(beacon);
00956                 wpabuf_free(probe);
00957                 return -1;
00958         }
00959 
00960         if (reg->static_wep_only) {
00961                 /*
00962                  * Windows XP and Vista clients can get confused about
00963                  * EAP-Identity/Request when they probe the network with
00964                  * EAPOL-Start. In such a case, they may assume the network is
00965                  * using IEEE 802.1X and prompt user for a certificate while
00966                  * the correct (non-WPS) behavior would be to ask for the
00967                  * static WEP key. As a workaround, use Microsoft Provisioning
00968                  * IE to advertise that legacy 802.1X is not supported.
00969                  */
00970                 const u8 ms_wps[7] = {
00971                         WLAN_EID_VENDOR_SPECIFIC, 5,
00972                         /* Microsoft Provisioning IE (00:50:f2:5) */
00973                         0x00, 0x50, 0xf2, 5,
00974                         0x00 /* no legacy 802.1X or MS WPS */
00975                 };
00976                 wpa_printf(MSG_DEBUG, "WPS: Add Microsoft Provisioning IE "
00977                            "into Beacon/Probe Response frames");
00978                 wpabuf_put_data(beacon, ms_wps, sizeof(ms_wps));
00979                 wpabuf_put_data(probe, ms_wps, sizeof(ms_wps));
00980         }
00981 
00982         ret = wps_cb_set_ie(reg, beacon, probe);
00983         wpabuf_free(beacon);
00984         wpabuf_free(probe);
00985 
00986         return ret;
00987 }
00988 
00989 
00990 static int wps_get_dev_password(struct wps_data *wps)
00991 {
00992         const u8 *pin;
00993         size_t pin_len = 0;
00994 
00995         os_free(wps->dev_password);
00996         wps->dev_password = NULL;
00997 
00998         if (wps->pbc) {
00999                 wpa_printf(MSG_DEBUG, "WPS: Use default PIN for PBC");
01000                 pin = (const u8 *) "00000000";
01001                 pin_len = 8;
01002         } else {
01003                 pin = wps_registrar_get_pin(wps->wps->registrar, wps->uuid_e,
01004                                             &pin_len);
01005         }
01006         if (pin == NULL) {
01007                 wpa_printf(MSG_DEBUG, "WPS: No Device Password available for "
01008                            "the Enrollee");
01009                 wps_cb_pin_needed(wps->wps->registrar, wps->uuid_e,
01010                                   &wps->peer_dev);
01011                 return -1;
01012         }
01013 
01014         wps->dev_password = os_malloc(pin_len);
01015         if (wps->dev_password == NULL)
01016                 return -1;
01017         os_memcpy(wps->dev_password, pin, pin_len);
01018         wps->dev_password_len = pin_len;
01019 
01020         return 0;
01021 }
01022 
01023 
01024 static int wps_build_uuid_r(struct wps_data *wps, struct wpabuf *msg)
01025 {
01026         wpa_printf(MSG_DEBUG, "WPS:  * UUID-R");
01027         wpabuf_put_be16(msg, ATTR_UUID_R);
01028         wpabuf_put_be16(msg, WPS_UUID_LEN);
01029         wpabuf_put_data(msg, wps->uuid_r, WPS_UUID_LEN);
01030         return 0;
01031 }
01032 
01033 
01034 static int wps_build_r_hash(struct wps_data *wps, struct wpabuf *msg)
01035 {
01036         u8 *hash;
01037         const u8 *addr[4];
01038         size_t len[4];
01039 
01040         if (os_get_random(wps->snonce, 2 * WPS_SECRET_NONCE_LEN) < 0)
01041                 return -1;
01042         wpa_hexdump(MSG_DEBUG, "WPS: R-S1", wps->snonce, WPS_SECRET_NONCE_LEN);
01043         wpa_hexdump(MSG_DEBUG, "WPS: R-S2",
01044                     wps->snonce + WPS_SECRET_NONCE_LEN, WPS_SECRET_NONCE_LEN);
01045 
01046         if (wps->dh_pubkey_e == NULL || wps->dh_pubkey_r == NULL) {
01047                 wpa_printf(MSG_DEBUG, "WPS: DH public keys not available for "
01048                            "R-Hash derivation");
01049                 return -1;
01050         }
01051 
01052         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash1");
01053         wpabuf_put_be16(msg, ATTR_R_HASH1);
01054         wpabuf_put_be16(msg, SHA256_MAC_LEN);
01055         hash = wpabuf_put(msg, SHA256_MAC_LEN);
01056         /* R-Hash1 = HMAC_AuthKey(R-S1 || PSK1 || PK_E || PK_R) */
01057         addr[0] = wps->snonce;
01058         len[0] = WPS_SECRET_NONCE_LEN;
01059         addr[1] = wps->psk1;
01060         len[1] = WPS_PSK_LEN;
01061         addr[2] = wpabuf_head(wps->dh_pubkey_e);
01062         len[2] = wpabuf_len(wps->dh_pubkey_e);
01063         addr[3] = wpabuf_head(wps->dh_pubkey_r);
01064         len[3] = wpabuf_len(wps->dh_pubkey_r);
01065         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01066         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash1", hash, SHA256_MAC_LEN);
01067 
01068         wpa_printf(MSG_DEBUG, "WPS:  * R-Hash2");
01069         wpabuf_put_be16(msg, ATTR_R_HASH2);
01070         wpabuf_put_be16(msg, SHA256_MAC_LEN);
01071         hash = wpabuf_put(msg, SHA256_MAC_LEN);
01072         /* R-Hash2 = HMAC_AuthKey(R-S2 || PSK2 || PK_E || PK_R) */
01073         addr[0] = wps->snonce + WPS_SECRET_NONCE_LEN;
01074         addr[1] = wps->psk2;
01075         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01076         wpa_hexdump(MSG_DEBUG, "WPS: R-Hash2", hash, SHA256_MAC_LEN);
01077 
01078         return 0;
01079 }
01080 
01081 
01082 static int wps_build_r_snonce1(struct wps_data *wps, struct wpabuf *msg)
01083 {
01084         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce1");
01085         wpabuf_put_be16(msg, ATTR_R_SNONCE1);
01086         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
01087         wpabuf_put_data(msg, wps->snonce, WPS_SECRET_NONCE_LEN);
01088         return 0;
01089 }
01090 
01091 
01092 static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
01093 {
01094         wpa_printf(MSG_DEBUG, "WPS:  * R-SNonce2");
01095         wpabuf_put_be16(msg, ATTR_R_SNONCE2);
01096         wpabuf_put_be16(msg, WPS_SECRET_NONCE_LEN);
01097         wpabuf_put_data(msg, wps->snonce + WPS_SECRET_NONCE_LEN,
01098                         WPS_SECRET_NONCE_LEN);
01099         return 0;
01100 }
01101 
01102 
01103 static int wps_build_cred_network_idx(struct wpabuf *msg,
01104                                       const struct wps_credential *cred)
01105 {
01106         wpa_printf(MSG_DEBUG, "WPS:  * Network Index");
01107         wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
01108         wpabuf_put_be16(msg, 1);
01109         wpabuf_put_u8(msg, 1);
01110         return 0;
01111 }
01112 
01113 
01114 static int wps_build_cred_ssid(struct wpabuf *msg,
01115                                const struct wps_credential *cred)
01116 {
01117         wpa_printf(MSG_DEBUG, "WPS:  * SSID");
01118         wpabuf_put_be16(msg, ATTR_SSID);
01119         wpabuf_put_be16(msg, cred->ssid_len);
01120         wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
01121         return 0;
01122 }
01123 
01124 
01125 static int wps_build_cred_auth_type(struct wpabuf *msg,
01126                                     const struct wps_credential *cred)
01127 {
01128         wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
01129                    cred->auth_type);
01130         wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
01131         wpabuf_put_be16(msg, 2);
01132         wpabuf_put_be16(msg, cred->auth_type);
01133         return 0;
01134 }
01135 
01136 
01137 static int wps_build_cred_encr_type(struct wpabuf *msg,
01138                                     const struct wps_credential *cred)
01139 {
01140         wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
01141                    cred->encr_type);
01142         wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
01143         wpabuf_put_be16(msg, 2);
01144         wpabuf_put_be16(msg, cred->encr_type);
01145         return 0;
01146 }
01147 
01148 
01149 static int wps_build_cred_network_key(struct wpabuf *msg,
01150                                       const const struct wps_credential *cred)
01151 {
01152         wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
01153         wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
01154         wpabuf_put_be16(msg, cred->key_len);
01155         wpabuf_put_data(msg, cred->key, cred->key_len);
01156         return 0;
01157 }
01158 
01159 
01160 static int wps_build_cred_mac_addr(struct wpabuf *msg,
01161                                    const struct wps_credential *cred)
01162 {
01163         wpa_printf(MSG_DEBUG, "WPS:  * MAC Address (" MACSTR ")",
01164                    MAC2STR(cred->mac_addr));
01165         wpabuf_put_be16(msg, ATTR_MAC_ADDR);
01166         wpabuf_put_be16(msg, ETH_ALEN);
01167         wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
01168         return 0;
01169 }
01170 
01171 
01172 static int wps_build_credential(struct wpabuf *msg,
01173                                 const struct wps_credential *cred)
01174 {
01175         if (wps_build_cred_network_idx(msg, cred) ||
01176             wps_build_cred_ssid(msg, cred) ||
01177             wps_build_cred_auth_type(msg, cred) ||
01178             wps_build_cred_encr_type(msg, cred) ||
01179             wps_build_cred_network_key(msg, cred) ||
01180             wps_build_cred_mac_addr(msg, cred))
01181                 return -1;
01182         return 0;
01183 }
01184 
01185 
01186 int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
01187 {
01188         struct wpabuf *cred;
01189 
01190         if (wps->wps->registrar->skip_cred_build)
01191                 goto skip_cred_build;
01192 
01193         wpa_printf(MSG_DEBUG, "WPS:  * Credential");
01194         if (wps->use_cred) {
01195                 os_memcpy(&wps->cred, wps->use_cred, sizeof(wps->cred));
01196                 goto use_provided;
01197         }
01198         os_memset(&wps->cred, 0, sizeof(wps->cred));
01199 
01200         os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
01201         wps->cred.ssid_len = wps->wps->ssid_len;
01202 
01203         /* Select the best authentication and encryption type */
01204         if (wps->auth_type & WPS_AUTH_WPA2PSK)
01205                 wps->auth_type = WPS_AUTH_WPA2PSK;
01206         else if (wps->auth_type & WPS_AUTH_WPAPSK)
01207                 wps->auth_type = WPS_AUTH_WPAPSK;
01208         else if (wps->auth_type & WPS_AUTH_OPEN)
01209                 wps->auth_type = WPS_AUTH_OPEN;
01210         else if (wps->auth_type & WPS_AUTH_SHARED)
01211                 wps->auth_type = WPS_AUTH_SHARED;
01212         else {
01213                 wpa_printf(MSG_DEBUG, "WPS: Unsupported auth_type 0x%x",
01214                            wps->auth_type);
01215                 return -1;
01216         }
01217         wps->cred.auth_type = wps->auth_type;
01218 
01219         if (wps->auth_type == WPS_AUTH_WPA2PSK ||
01220             wps->auth_type == WPS_AUTH_WPAPSK) {
01221                 if (wps->encr_type & WPS_ENCR_AES)
01222                         wps->encr_type = WPS_ENCR_AES;
01223                 else if (wps->encr_type & WPS_ENCR_TKIP)
01224                         wps->encr_type = WPS_ENCR_TKIP;
01225                 else {
01226                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
01227                                    "type for WPA/WPA2");
01228                         return -1;
01229                 }
01230         } else {
01231                 if (wps->encr_type & WPS_ENCR_WEP)
01232                         wps->encr_type = WPS_ENCR_WEP;
01233                 else if (wps->encr_type & WPS_ENCR_NONE)
01234                         wps->encr_type = WPS_ENCR_NONE;
01235                 else {
01236                         wpa_printf(MSG_DEBUG, "WPS: No suitable encryption "
01237                                    "type for non-WPA/WPA2 mode");
01238                         return -1;
01239                 }
01240         }
01241         wps->cred.encr_type = wps->encr_type;
01242         /*
01243          * Set MAC address in the Credential to be the Enrollee's MAC address
01244          */
01245         os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
01246 
01247         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
01248             !wps->wps->registrar->disable_auto_conf) {
01249                 u8 r[16];
01250                 /* Generate a random passphrase */
01251                 if (os_get_random(r, sizeof(r)) < 0)
01252                         return -1;
01253                 os_free(wps->new_psk);
01254                 wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
01255                 if (wps->new_psk == NULL)
01256                         return -1;
01257                 wps->new_psk_len--; /* remove newline */
01258                 while (wps->new_psk_len &&
01259                        wps->new_psk[wps->new_psk_len - 1] == '=')
01260                         wps->new_psk_len--;
01261                 wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
01262                                       wps->new_psk, wps->new_psk_len);
01263                 os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
01264                 wps->cred.key_len = wps->new_psk_len;
01265         } else if (wps->wps->network_key) {
01266                 os_memcpy(wps->cred.key, wps->wps->network_key,
01267                           wps->wps->network_key_len);
01268                 wps->cred.key_len = wps->wps->network_key_len;
01269         } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
01270                 char hex[65];
01271                 /* Generate a random per-device PSK */
01272                 os_free(wps->new_psk);
01273                 wps->new_psk_len = 32;
01274                 wps->new_psk = os_malloc(wps->new_psk_len);
01275                 if (wps->new_psk == NULL)
01276                         return -1;
01277                 if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
01278                         os_free(wps->new_psk);
01279                         wps->new_psk = NULL;
01280                         return -1;
01281                 }
01282                 wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
01283                                 wps->new_psk, wps->new_psk_len);
01284                 wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
01285                                  wps->new_psk_len);
01286                 os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
01287                 wps->cred.key_len = wps->new_psk_len * 2;
01288         }
01289 
01290 use_provided:
01291         cred = wpabuf_alloc(200);
01292         if (cred == NULL)
01293                 return -1;
01294 
01295         if (wps_build_credential(cred, &wps->cred)) {
01296                 wpabuf_free(cred);
01297                 return -1;
01298         }
01299 
01300         wpabuf_put_be16(msg, ATTR_CRED);
01301         wpabuf_put_be16(msg, wpabuf_len(cred));
01302         wpabuf_put_buf(msg, cred);
01303         wpabuf_free(cred);
01304 
01305 skip_cred_build:
01306         if (wps->wps->registrar->extra_cred) {
01307                 wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
01308                 wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
01309         }
01310 
01311         return 0;
01312 }
01313 
01314 
01315 static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
01316 {
01317         wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
01318 
01319         if (wps_build_credential(msg, &wps->cred))
01320                 return -1;
01321 
01322         return 0;
01323 }
01324 
01325 
01326 static struct wpabuf * wps_build_m2(struct wps_data *wps)
01327 {
01328         struct wpabuf *msg;
01329 
01330         if (os_get_random(wps->nonce_r, WPS_NONCE_LEN) < 0)
01331                 return NULL;
01332         wpa_hexdump(MSG_DEBUG, "WPS: Registrar Nonce",
01333                     wps->nonce_r, WPS_NONCE_LEN);
01334         wpa_hexdump(MSG_DEBUG, "WPS: UUID-R", wps->uuid_r, WPS_UUID_LEN);
01335 
01336         wpa_printf(MSG_DEBUG, "WPS: Building Message M2");
01337         msg = wpabuf_alloc(1000);
01338         if (msg == NULL)
01339                 return NULL;
01340 
01341         if (wps_build_version(msg) ||
01342             wps_build_msg_type(msg, WPS_M2) ||
01343             wps_build_enrollee_nonce(wps, msg) ||
01344             wps_build_registrar_nonce(wps, msg) ||
01345             wps_build_uuid_r(wps, msg) ||
01346             wps_build_public_key(wps, msg) ||
01347             wps_derive_keys(wps) ||
01348             wps_build_auth_type_flags(wps, msg) ||
01349             wps_build_encr_type_flags(wps, msg) ||
01350             wps_build_conn_type_flags(wps, msg) ||
01351             wps_build_config_methods_r(wps->wps->registrar, msg) ||
01352             wps_build_device_attrs(&wps->wps->dev, msg) ||
01353             wps_build_rf_bands(&wps->wps->dev, msg) ||
01354             wps_build_assoc_state(wps, msg) ||
01355             wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
01356             wps_build_dev_password_id(msg, wps->dev_pw_id) ||
01357             wps_build_os_version(&wps->wps->dev, msg) ||
01358             wps_build_authenticator(wps, msg)) {
01359                 wpabuf_free(msg);
01360                 return NULL;
01361         }
01362 
01363         wps->state = RECV_M3;
01364         return msg;
01365 }
01366 
01367 
01368 static struct wpabuf * wps_build_m2d(struct wps_data *wps)
01369 {
01370         struct wpabuf *msg;
01371         u16 err = wps->config_error;
01372 
01373         wpa_printf(MSG_DEBUG, "WPS: Building Message M2D");
01374         msg = wpabuf_alloc(1000);
01375         if (msg == NULL)
01376                 return NULL;
01377 
01378         if (wps->wps->ap && wps->wps->ap_setup_locked &&
01379             err == WPS_CFG_NO_ERROR)
01380                 err = WPS_CFG_SETUP_LOCKED;
01381 
01382         if (wps_build_version(msg) ||
01383             wps_build_msg_type(msg, WPS_M2D) ||
01384             wps_build_enrollee_nonce(wps, msg) ||
01385             wps_build_registrar_nonce(wps, msg) ||
01386             wps_build_uuid_r(wps, msg) ||
01387             wps_build_auth_type_flags(wps, msg) ||
01388             wps_build_encr_type_flags(wps, msg) ||
01389             wps_build_conn_type_flags(wps, msg) ||
01390             wps_build_config_methods_r(wps->wps->registrar, msg) ||
01391             wps_build_device_attrs(&wps->wps->dev, msg) ||
01392             wps_build_rf_bands(&wps->wps->dev, msg) ||
01393             wps_build_assoc_state(wps, msg) ||
01394             wps_build_config_error(msg, err) ||
01395             wps_build_os_version(&wps->wps->dev, msg)) {
01396                 wpabuf_free(msg);
01397                 return NULL;
01398         }
01399 
01400         wps->state = RECV_M2D_ACK;
01401         return msg;
01402 }
01403 
01404 
01405 static struct wpabuf * wps_build_m4(struct wps_data *wps)
01406 {
01407         struct wpabuf *msg, *plain;
01408 
01409         wpa_printf(MSG_DEBUG, "WPS: Building Message M4");
01410 
01411         wps_derive_psk(wps, wps->dev_password, wps->dev_password_len);
01412 
01413         plain = wpabuf_alloc(200);
01414         if (plain == NULL)
01415                 return NULL;
01416 
01417         msg = wpabuf_alloc(1000);
01418         if (msg == NULL) {
01419                 wpabuf_free(plain);
01420                 return NULL;
01421         }
01422 
01423         if (wps_build_version(msg) ||
01424             wps_build_msg_type(msg, WPS_M4) ||
01425             wps_build_enrollee_nonce(wps, msg) ||
01426             wps_build_r_hash(wps, msg) ||
01427             wps_build_r_snonce1(wps, plain) ||
01428             wps_build_key_wrap_auth(wps, plain) ||
01429             wps_build_encr_settings(wps, msg, plain) ||
01430             wps_build_authenticator(wps, msg)) {
01431                 wpabuf_free(plain);
01432                 wpabuf_free(msg);
01433                 return NULL;
01434         }
01435         wpabuf_free(plain);
01436 
01437         wps->state = RECV_M5;
01438         return msg;
01439 }
01440 
01441 
01442 static struct wpabuf * wps_build_m6(struct wps_data *wps)
01443 {
01444         struct wpabuf *msg, *plain;
01445 
01446         wpa_printf(MSG_DEBUG, "WPS: Building Message M6");
01447 
01448         plain = wpabuf_alloc(200);
01449         if (plain == NULL)
01450                 return NULL;
01451 
01452         msg = wpabuf_alloc(1000);
01453         if (msg == NULL) {
01454                 wpabuf_free(plain);
01455                 return NULL;
01456         }
01457 
01458         if (wps_build_version(msg) ||
01459             wps_build_msg_type(msg, WPS_M6) ||
01460             wps_build_enrollee_nonce(wps, msg) ||
01461             wps_build_r_snonce2(wps, plain) ||
01462             wps_build_key_wrap_auth(wps, plain) ||
01463             wps_build_encr_settings(wps, msg, plain) ||
01464             wps_build_authenticator(wps, msg)) {
01465                 wpabuf_free(plain);
01466                 wpabuf_free(msg);
01467                 return NULL;
01468         }
01469         wpabuf_free(plain);
01470 
01471         wps->wps_pin_revealed = 1;
01472         wps->state = RECV_M7;
01473         return msg;
01474 }
01475 
01476 
01477 static struct wpabuf * wps_build_m8(struct wps_data *wps)
01478 {
01479         struct wpabuf *msg, *plain;
01480 
01481         wpa_printf(MSG_DEBUG, "WPS: Building Message M8");
01482 
01483         plain = wpabuf_alloc(500);
01484         if (plain == NULL)
01485                 return NULL;
01486 
01487         msg = wpabuf_alloc(1000);
01488         if (msg == NULL) {
01489                 wpabuf_free(plain);
01490                 return NULL;
01491         }
01492 
01493         if (wps_build_version(msg) ||
01494             wps_build_msg_type(msg, WPS_M8) ||
01495             wps_build_enrollee_nonce(wps, msg) ||
01496             ((wps->wps->ap || wps->er) && wps_build_cred(wps, plain)) ||
01497             (!wps->wps->ap && !wps->er && wps_build_ap_settings(wps, plain)) ||
01498             wps_build_key_wrap_auth(wps, plain) ||
01499             wps_build_encr_settings(wps, msg, plain) ||
01500             wps_build_authenticator(wps, msg)) {
01501                 wpabuf_free(plain);
01502                 wpabuf_free(msg);
01503                 return NULL;
01504         }
01505         wpabuf_free(plain);
01506 
01507         wps->state = RECV_DONE;
01508         return msg;
01509 }
01510 
01511 
01512 static struct wpabuf * wps_build_wsc_ack(struct wps_data *wps)
01513 {
01514         struct wpabuf *msg;
01515 
01516         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_ACK");
01517 
01518         msg = wpabuf_alloc(1000);
01519         if (msg == NULL)
01520                 return NULL;
01521 
01522         if (wps_build_version(msg) ||
01523             wps_build_msg_type(msg, WPS_WSC_ACK) ||
01524             wps_build_enrollee_nonce(wps, msg) ||
01525             wps_build_registrar_nonce(wps, msg)) {
01526                 wpabuf_free(msg);
01527                 return NULL;
01528         }
01529 
01530         return msg;
01531 }
01532 
01533 
01534 static struct wpabuf * wps_build_wsc_nack(struct wps_data *wps)
01535 {
01536         struct wpabuf *msg;
01537 
01538         wpa_printf(MSG_DEBUG, "WPS: Building Message WSC_NACK");
01539 
01540         msg = wpabuf_alloc(1000);
01541         if (msg == NULL)
01542                 return NULL;
01543 
01544         if (wps_build_version(msg) ||
01545             wps_build_msg_type(msg, WPS_WSC_NACK) ||
01546             wps_build_enrollee_nonce(wps, msg) ||
01547             wps_build_registrar_nonce(wps, msg) ||
01548             wps_build_config_error(msg, wps->config_error)) {
01549                 wpabuf_free(msg);
01550                 return NULL;
01551         }
01552 
01553         return msg;
01554 }
01555 
01556 
01557 struct wpabuf * wps_registrar_get_msg(struct wps_data *wps,
01558                                       enum wsc_op_code *op_code)
01559 {
01560         struct wpabuf *msg;
01561 
01562 #ifdef CONFIG_WPS_UPNP
01563         if (wps->wps->wps_upnp) {
01564                 struct upnp_pending_message *p, *prev = NULL;
01565                 if (wps->ext_reg > 1)
01566                         wps_registrar_free_pending_m2(wps->wps);
01567                 p = wps->wps->upnp_msgs;
01568                 /* TODO: check pending message MAC address */
01569                 while (p && p->next) {
01570                         prev = p;
01571                         p = p->next;
01572                 }
01573                 if (p) {
01574                         wpa_printf(MSG_DEBUG, "WPS: Use pending message from "
01575                                    "UPnP");
01576                         if (prev)
01577                                 prev->next = NULL;
01578                         else
01579                                 wps->wps->upnp_msgs = NULL;
01580                         msg = p->msg;
01581                         switch (p->type) {
01582                         case WPS_WSC_ACK:
01583                                 *op_code = WSC_ACK;
01584                                 break;
01585                         case WPS_WSC_NACK:
01586                                 *op_code = WSC_NACK;
01587                                 break;
01588                         default:
01589                                 *op_code = WSC_MSG;
01590                                 break;
01591                         }
01592                         os_free(p);
01593                         if (wps->ext_reg == 0)
01594                                 wps->ext_reg = 1;
01595                         return msg;
01596                 }
01597         }
01598         if (wps->ext_reg) {
01599                 wpa_printf(MSG_DEBUG, "WPS: Using external Registrar, but no "
01600                            "pending message available");
01601                 return NULL;
01602         }
01603 #endif /* CONFIG_WPS_UPNP */
01604 
01605         switch (wps->state) {
01606         case SEND_M2:
01607                 if (wps_get_dev_password(wps) < 0)
01608                         msg = wps_build_m2d(wps);
01609                 else
01610                         msg = wps_build_m2(wps);
01611                 *op_code = WSC_MSG;
01612                 break;
01613         case SEND_M2D:
01614                 msg = wps_build_m2d(wps);
01615                 *op_code = WSC_MSG;
01616                 break;
01617         case SEND_M4:
01618                 msg = wps_build_m4(wps);
01619                 *op_code = WSC_MSG;
01620                 break;
01621         case SEND_M6:
01622                 msg = wps_build_m6(wps);
01623                 *op_code = WSC_MSG;
01624                 break;
01625         case SEND_M8:
01626                 msg = wps_build_m8(wps);
01627                 *op_code = WSC_MSG;
01628                 break;
01629         case RECV_DONE:
01630                 msg = wps_build_wsc_ack(wps);
01631                 *op_code = WSC_ACK;
01632                 break;
01633         case SEND_WSC_NACK:
01634                 msg = wps_build_wsc_nack(wps);
01635                 *op_code = WSC_NACK;
01636                 break;
01637         default:
01638                 wpa_printf(MSG_DEBUG, "WPS: Unsupported state %d for building "
01639                            "a message", wps->state);
01640                 msg = NULL;
01641                 break;
01642         }
01643 
01644         if (*op_code == WSC_MSG && msg) {
01645                 /* Save a copy of the last message for Authenticator derivation
01646                  */
01647                 wpabuf_free(wps->last_msg);
01648                 wps->last_msg = wpabuf_dup(msg);
01649         }
01650 
01651         return msg;
01652 }
01653 
01654 
01655 static int wps_process_enrollee_nonce(struct wps_data *wps, const u8 *e_nonce)
01656 {
01657         if (e_nonce == NULL) {
01658                 wpa_printf(MSG_DEBUG, "WPS: No Enrollee Nonce received");
01659                 return -1;
01660         }
01661 
01662         os_memcpy(wps->nonce_e, e_nonce, WPS_NONCE_LEN);
01663         wpa_hexdump(MSG_DEBUG, "WPS: Enrollee Nonce",
01664                     wps->nonce_e, WPS_NONCE_LEN);
01665 
01666         return 0;
01667 }
01668 
01669 
01670 static int wps_process_registrar_nonce(struct wps_data *wps, const u8 *r_nonce)
01671 {
01672         if (r_nonce == NULL) {
01673                 wpa_printf(MSG_DEBUG, "WPS: No Registrar Nonce received");
01674                 return -1;
01675         }
01676 
01677         if (os_memcmp(wps->nonce_r, r_nonce, WPS_NONCE_LEN) != 0) {
01678                 wpa_printf(MSG_DEBUG, "WPS: Invalid Registrar Nonce received");
01679                 return -1;
01680         }
01681 
01682         return 0;
01683 }
01684 
01685 
01686 static int wps_process_uuid_e(struct wps_data *wps, const u8 *uuid_e)
01687 {
01688         if (uuid_e == NULL) {
01689                 wpa_printf(MSG_DEBUG, "WPS: No UUID-E received");
01690                 return -1;
01691         }
01692 
01693         os_memcpy(wps->uuid_e, uuid_e, WPS_UUID_LEN);
01694         wpa_hexdump(MSG_DEBUG, "WPS: UUID-E", wps->uuid_e, WPS_UUID_LEN);
01695 
01696         return 0;
01697 }
01698 
01699 
01700 static int wps_process_dev_password_id(struct wps_data *wps, const u8 *pw_id)
01701 {
01702         if (pw_id == NULL) {
01703                 wpa_printf(MSG_DEBUG, "WPS: No Device Password ID received");
01704                 return -1;
01705         }
01706 
01707         wps->dev_pw_id = WPA_GET_BE16(pw_id);
01708         wpa_printf(MSG_DEBUG, "WPS: Device Password ID %d", wps->dev_pw_id);
01709 
01710         return 0;
01711 }
01712 
01713 
01714 static int wps_process_e_hash1(struct wps_data *wps, const u8 *e_hash1)
01715 {
01716         if (e_hash1 == NULL) {
01717                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash1 received");
01718                 return -1;
01719         }
01720 
01721         os_memcpy(wps->peer_hash1, e_hash1, WPS_HASH_LEN);
01722         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash1", wps->peer_hash1, WPS_HASH_LEN);
01723 
01724         return 0;
01725 }
01726 
01727 
01728 static int wps_process_e_hash2(struct wps_data *wps, const u8 *e_hash2)
01729 {
01730         if (e_hash2 == NULL) {
01731                 wpa_printf(MSG_DEBUG, "WPS: No E-Hash2 received");
01732                 return -1;
01733         }
01734 
01735         os_memcpy(wps->peer_hash2, e_hash2, WPS_HASH_LEN);
01736         wpa_hexdump(MSG_DEBUG, "WPS: E-Hash2", wps->peer_hash2, WPS_HASH_LEN);
01737 
01738         return 0;
01739 }
01740 
01741 
01742 static int wps_process_e_snonce1(struct wps_data *wps, const u8 *e_snonce1)
01743 {
01744         u8 hash[SHA256_MAC_LEN];
01745         const u8 *addr[4];
01746         size_t len[4];
01747 
01748         if (e_snonce1 == NULL) {
01749                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce1 received");
01750                 return -1;
01751         }
01752 
01753         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce1", e_snonce1,
01754                         WPS_SECRET_NONCE_LEN);
01755 
01756         /* E-Hash1 = HMAC_AuthKey(E-S1 || PSK1 || PK_E || PK_R) */
01757         addr[0] = e_snonce1;
01758         len[0] = WPS_SECRET_NONCE_LEN;
01759         addr[1] = wps->psk1;
01760         len[1] = WPS_PSK_LEN;
01761         addr[2] = wpabuf_head(wps->dh_pubkey_e);
01762         len[2] = wpabuf_len(wps->dh_pubkey_e);
01763         addr[3] = wpabuf_head(wps->dh_pubkey_r);
01764         len[3] = wpabuf_len(wps->dh_pubkey_r);
01765         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01766 
01767         if (os_memcmp(wps->peer_hash1, hash, WPS_HASH_LEN) != 0) {
01768                 wpa_printf(MSG_DEBUG, "WPS: E-Hash1 derived from E-S1 does "
01769                            "not match with the pre-committed value");
01770                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
01771                 wps_pwd_auth_fail_event(wps->wps, 0, 1);
01772                 return -1;
01773         }
01774 
01775         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the first "
01776                    "half of the device password");
01777 
01778         return 0;
01779 }
01780 
01781 
01782 static int wps_process_e_snonce2(struct wps_data *wps, const u8 *e_snonce2)
01783 {
01784         u8 hash[SHA256_MAC_LEN];
01785         const u8 *addr[4];
01786         size_t len[4];
01787 
01788         if (e_snonce2 == NULL) {
01789                 wpa_printf(MSG_DEBUG, "WPS: No E-SNonce2 received");
01790                 return -1;
01791         }
01792 
01793         wpa_hexdump_key(MSG_DEBUG, "WPS: E-SNonce2", e_snonce2,
01794                         WPS_SECRET_NONCE_LEN);
01795 
01796         /* E-Hash2 = HMAC_AuthKey(E-S2 || PSK2 || PK_E || PK_R) */
01797         addr[0] = e_snonce2;
01798         len[0] = WPS_SECRET_NONCE_LEN;
01799         addr[1] = wps->psk2;
01800         len[1] = WPS_PSK_LEN;
01801         addr[2] = wpabuf_head(wps->dh_pubkey_e);
01802         len[2] = wpabuf_len(wps->dh_pubkey_e);
01803         addr[3] = wpabuf_head(wps->dh_pubkey_r);
01804         len[3] = wpabuf_len(wps->dh_pubkey_r);
01805         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 4, addr, len, hash);
01806 
01807         if (os_memcmp(wps->peer_hash2, hash, WPS_HASH_LEN) != 0) {
01808                 wpa_printf(MSG_DEBUG, "WPS: E-Hash2 derived from E-S2 does "
01809                            "not match with the pre-committed value");
01810                 wps_registrar_invalidate_pin(wps->wps->registrar, wps->uuid_e);
01811                 wps->config_error = WPS_CFG_DEV_PASSWORD_AUTH_FAILURE;
01812                 wps_pwd_auth_fail_event(wps->wps, 0, 2);
01813                 return -1;
01814         }
01815 
01816         wpa_printf(MSG_DEBUG, "WPS: Enrollee proved knowledge of the second "
01817                    "half of the device password");
01818         wps->wps_pin_revealed = 0;
01819         wps_registrar_unlock_pin(wps->wps->registrar, wps->uuid_e);
01820 
01821         return 0;
01822 }
01823 
01824 
01825 static int wps_process_mac_addr(struct wps_data *wps, const u8 *mac_addr)
01826 {
01827         if (mac_addr == NULL) {
01828                 wpa_printf(MSG_DEBUG, "WPS: No MAC Address received");
01829                 return -1;
01830         }
01831 
01832         wpa_printf(MSG_DEBUG, "WPS: Enrollee MAC Address " MACSTR,
01833                    MAC2STR(mac_addr));
01834         os_memcpy(wps->mac_addr_e, mac_addr, ETH_ALEN);
01835         os_memcpy(wps->peer_dev.mac_addr, mac_addr, ETH_ALEN);
01836 
01837         return 0;
01838 }
01839 
01840 
01841 static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
01842                               size_t pk_len)
01843 {
01844         if (pk == NULL || pk_len == 0) {
01845                 wpa_printf(MSG_DEBUG, "WPS: No Public Key received");
01846                 return -1;
01847         }
01848 
01849 #ifdef CONFIG_WPS_OOB
01850         if (wps->wps->oob_conf.pubkey_hash != NULL) {
01851                 const u8 *addr[1];
01852                 u8 hash[WPS_HASH_LEN];
01853 
01854                 addr[0] = pk;
01855                 sha256_vector(1, addr, &pk_len, hash);
01856                 if (os_memcmp(hash,
01857                               wpabuf_head(wps->wps->oob_conf.pubkey_hash),
01858                               WPS_OOB_PUBKEY_HASH_LEN) != 0) {
01859                         wpa_printf(MSG_ERROR, "WPS: Public Key hash error");
01860                         return -1;
01861                 }
01862         }
01863 #endif /* CONFIG_WPS_OOB */
01864 
01865         wpabuf_free(wps->dh_pubkey_e);
01866         wps->dh_pubkey_e = wpabuf_alloc_copy(pk, pk_len);
01867         if (wps->dh_pubkey_e == NULL)
01868                 return -1;
01869 
01870         return 0;
01871 }
01872 
01873 
01874 static int wps_process_auth_type_flags(struct wps_data *wps, const u8 *auth)
01875 {
01876         u16 auth_types;
01877 
01878         if (auth == NULL) {
01879                 wpa_printf(MSG_DEBUG, "WPS: No Authentication Type flags "
01880                            "received");
01881                 return -1;
01882         }
01883 
01884         auth_types = WPA_GET_BE16(auth);
01885 
01886         wpa_printf(MSG_DEBUG, "WPS: Enrollee Authentication Type flags 0x%x",
01887                    auth_types);
01888         wps->auth_type = wps->wps->auth_types & auth_types;
01889         if (wps->auth_type == 0) {
01890                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
01891                            "authentication types (own 0x%x Enrollee 0x%x)",
01892                            wps->wps->auth_types, auth_types);
01893 #ifdef WPS_WORKAROUNDS
01894                 /*
01895                  * Some deployed implementations seem to advertise incorrect
01896                  * information in this attribute. For example, Linksys WRT350N
01897                  * seems to have a byteorder bug that breaks this negotiation.
01898                  * In order to interoperate with existing implementations,
01899                  * assume that the Enrollee supports everything we do.
01900                  */
01901                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
01902                            "does not advertise supported authentication types "
01903                            "correctly");
01904                 wps->auth_type = wps->wps->auth_types;
01905 #else /* WPS_WORKAROUNDS */
01906                 return -1;
01907 #endif /* WPS_WORKAROUNDS */
01908         }
01909 
01910         return 0;
01911 }
01912 
01913 
01914 static int wps_process_encr_type_flags(struct wps_data *wps, const u8 *encr)
01915 {
01916         u16 encr_types;
01917 
01918         if (encr == NULL) {
01919                 wpa_printf(MSG_DEBUG, "WPS: No Encryption Type flags "
01920                            "received");
01921                 return -1;
01922         }
01923 
01924         encr_types = WPA_GET_BE16(encr);
01925 
01926         wpa_printf(MSG_DEBUG, "WPS: Enrollee Encryption Type flags 0x%x",
01927                    encr_types);
01928         wps->encr_type = wps->wps->encr_types & encr_types;
01929         if (wps->encr_type == 0) {
01930                 wpa_printf(MSG_DEBUG, "WPS: No match in supported "
01931                            "encryption types (own 0x%x Enrollee 0x%x)",
01932                            wps->wps->encr_types, encr_types);
01933 #ifdef WPS_WORKAROUNDS
01934                 /*
01935                  * Some deployed implementations seem to advertise incorrect
01936                  * information in this attribute. For example, Linksys WRT350N
01937                  * seems to have a byteorder bug that breaks this negotiation.
01938                  * In order to interoperate with existing implementations,
01939                  * assume that the Enrollee supports everything we do.
01940                  */
01941                 wpa_printf(MSG_DEBUG, "WPS: Workaround - assume Enrollee "
01942                            "does not advertise supported encryption types "
01943                            "correctly");
01944                 wps->encr_type = wps->wps->encr_types;
01945 #else /* WPS_WORKAROUNDS */
01946                 return -1;
01947 #endif /* WPS_WORKAROUNDS */
01948         }
01949 
01950         return 0;
01951 }
01952 
01953 
01954 static int wps_process_conn_type_flags(struct wps_data *wps, const u8 *conn)
01955 {
01956         if (conn == NULL) {
01957                 wpa_printf(MSG_DEBUG, "WPS: No Connection Type flags "
01958                            "received");
01959                 return -1;
01960         }
01961 
01962         wpa_printf(MSG_DEBUG, "WPS: Enrollee Connection Type flags 0x%x",
01963                    *conn);
01964 
01965         return 0;
01966 }
01967 
01968 
01969 static int wps_process_config_methods(struct wps_data *wps, const u8 *methods)
01970 {
01971         u16 m;
01972 
01973         if (methods == NULL) {
01974                 wpa_printf(MSG_DEBUG, "WPS: No Config Methods received");
01975                 return -1;
01976         }
01977 
01978         m = WPA_GET_BE16(methods);
01979 
01980         wpa_printf(MSG_DEBUG, "WPS: Enrollee Config Methods 0x%x", m);
01981 
01982         return 0;
01983 }
01984 
01985 
01986 static int wps_process_wps_state(struct wps_data *wps, const u8 *state)
01987 {
01988         if (state == NULL) {
01989                 wpa_printf(MSG_DEBUG, "WPS: No Wi-Fi Protected Setup State "
01990                            "received");
01991                 return -1;
01992         }
01993 
01994         wpa_printf(MSG_DEBUG, "WPS: Enrollee Wi-Fi Protected Setup State %d",
01995                    *state);
01996 
01997         return 0;
01998 }
01999 
02000 
02001 static int wps_process_assoc_state(struct wps_data *wps, const u8 *assoc)
02002 {
02003         u16 a;
02004 
02005         if (assoc == NULL) {
02006                 wpa_printf(MSG_DEBUG, "WPS: No Association State received");
02007                 return -1;
02008         }
02009 
02010         a = WPA_GET_BE16(assoc);
02011         wpa_printf(MSG_DEBUG, "WPS: Enrollee Association State %d", a);
02012 
02013         return 0;
02014 }
02015 
02016 
02017 static int wps_process_config_error(struct wps_data *wps, const u8 *err)
02018 {
02019         u16 e;
02020 
02021         if (err == NULL) {
02022                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error received");
02023                 return -1;
02024         }
02025 
02026         e = WPA_GET_BE16(err);
02027         wpa_printf(MSG_DEBUG, "WPS: Enrollee Configuration Error %d", e);
02028 
02029         return 0;
02030 }
02031 
02032 
02033 static enum wps_process_res wps_process_m1(struct wps_data *wps,
02034                                            struct wps_parse_attr *attr)
02035 {
02036         wpa_printf(MSG_DEBUG, "WPS: Received M1");
02037 
02038         if (wps->state != RECV_M1) {
02039                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02040                            "receiving M1", wps->state);
02041                 return WPS_FAILURE;
02042         }
02043 
02044         if (wps_process_uuid_e(wps, attr->uuid_e) ||
02045             wps_process_mac_addr(wps, attr->mac_addr) ||
02046             wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
02047             wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
02048             wps_process_auth_type_flags(wps, attr->auth_type_flags) ||
02049             wps_process_encr_type_flags(wps, attr->encr_type_flags) ||
02050             wps_process_conn_type_flags(wps, attr->conn_type_flags) ||
02051             wps_process_config_methods(wps, attr->config_methods) ||
02052             wps_process_wps_state(wps, attr->wps_state) ||
02053             wps_process_device_attrs(&wps->peer_dev, attr) ||
02054             wps_process_rf_bands(&wps->peer_dev, attr->rf_bands) ||
02055             wps_process_assoc_state(wps, attr->assoc_state) ||
02056             wps_process_dev_password_id(wps, attr->dev_password_id) ||
02057             wps_process_config_error(wps, attr->config_error) ||
02058             wps_process_os_version(&wps->peer_dev, attr->os_version))
02059                 return WPS_FAILURE;
02060 
02061         if (wps->dev_pw_id < 0x10 &&
02062             wps->dev_pw_id != DEV_PW_DEFAULT &&
02063             wps->dev_pw_id != DEV_PW_USER_SPECIFIED &&
02064             wps->dev_pw_id != DEV_PW_MACHINE_SPECIFIED &&
02065             wps->dev_pw_id != DEV_PW_REGISTRAR_SPECIFIED &&
02066             (wps->dev_pw_id != DEV_PW_PUSHBUTTON ||
02067              !wps->wps->registrar->pbc)) {
02068                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Device Password ID %d",
02069                            wps->dev_pw_id);
02070                 wps->state = SEND_M2D;
02071                 return WPS_CONTINUE;
02072         }
02073 
02074 #ifdef CONFIG_WPS_OOB
02075         if (wps->dev_pw_id >= 0x10 &&
02076             wps->dev_pw_id != wps->wps->oob_dev_pw_id) {
02077                 wpa_printf(MSG_DEBUG, "WPS: OOB Device Password ID "
02078                            "%d mismatch", wps->dev_pw_id);
02079                 wps->state = SEND_M2D;
02080                 return WPS_CONTINUE;
02081         }
02082 #endif /* CONFIG_WPS_OOB */
02083 
02084         if (wps->dev_pw_id == DEV_PW_PUSHBUTTON) {
02085                 if (wps->wps->registrar->force_pbc_overlap ||
02086                     wps_registrar_pbc_overlap(wps->wps->registrar,
02087                                               wps->mac_addr_e, wps->uuid_e)) {
02088                         wpa_printf(MSG_DEBUG, "WPS: PBC overlap - deny PBC "
02089                                    "negotiation");
02090                         wps->state = SEND_M2D;
02091                         wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02092                         wps_pbc_overlap_event(wps->wps);
02093                         wps->wps->registrar->force_pbc_overlap = 1;
02094                         return WPS_CONTINUE;
02095                 }
02096                 wps_registrar_add_pbc_session(wps->wps->registrar,
02097                                               wps->mac_addr_e, wps->uuid_e);
02098                 wps->pbc = 1;
02099         }
02100 
02101         wps->state = SEND_M2;
02102         return WPS_CONTINUE;
02103 }
02104 
02105 
02106 static enum wps_process_res wps_process_m3(struct wps_data *wps,
02107                                            const struct wpabuf *msg,
02108                                            struct wps_parse_attr *attr)
02109 {
02110         wpa_printf(MSG_DEBUG, "WPS: Received M3");
02111 
02112         if (wps->state != RECV_M3) {
02113                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02114                            "receiving M3", wps->state);
02115                 wps->state = SEND_WSC_NACK;
02116                 return WPS_CONTINUE;
02117         }
02118 
02119         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02120                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02121                            "session overlap");
02122                 wps->state = SEND_WSC_NACK;
02123                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02124                 return WPS_CONTINUE;
02125         }
02126 
02127         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02128             wps_process_authenticator(wps, attr->authenticator, msg) ||
02129             wps_process_e_hash1(wps, attr->e_hash1) ||
02130             wps_process_e_hash2(wps, attr->e_hash2)) {
02131                 wps->state = SEND_WSC_NACK;
02132                 return WPS_CONTINUE;
02133         }
02134 
02135         wps->state = SEND_M4;
02136         return WPS_CONTINUE;
02137 }
02138 
02139 
02140 static enum wps_process_res wps_process_m5(struct wps_data *wps,
02141                                            const struct wpabuf *msg,
02142                                            struct wps_parse_attr *attr)
02143 {
02144         struct wpabuf *decrypted;
02145         struct wps_parse_attr eattr;
02146 
02147         wpa_printf(MSG_DEBUG, "WPS: Received M5");
02148 
02149         if (wps->state != RECV_M5) {
02150                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02151                            "receiving M5", wps->state);
02152                 wps->state = SEND_WSC_NACK;
02153                 return WPS_CONTINUE;
02154         }
02155 
02156         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02157                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02158                            "session overlap");
02159                 wps->state = SEND_WSC_NACK;
02160                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02161                 return WPS_CONTINUE;
02162         }
02163 
02164         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02165             wps_process_authenticator(wps, attr->authenticator, msg)) {
02166                 wps->state = SEND_WSC_NACK;
02167                 return WPS_CONTINUE;
02168         }
02169 
02170         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
02171                                               attr->encr_settings_len);
02172         if (decrypted == NULL) {
02173                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypted Encrypted "
02174                            "Settings attribute");
02175                 wps->state = SEND_WSC_NACK;
02176                 return WPS_CONTINUE;
02177         }
02178 
02179         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
02180                    "attribute");
02181         if (wps_parse_msg(decrypted, &eattr) < 0 ||
02182             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
02183             wps_process_e_snonce1(wps, eattr.e_snonce1)) {
02184                 wpabuf_free(decrypted);
02185                 wps->state = SEND_WSC_NACK;
02186                 return WPS_CONTINUE;
02187         }
02188         wpabuf_free(decrypted);
02189 
02190         wps->state = SEND_M6;
02191         return WPS_CONTINUE;
02192 }
02193 
02194 
02195 static void wps_sta_cred_cb(struct wps_data *wps)
02196 {
02197         /*
02198          * Update credential to only include a single authentication and
02199          * encryption type in case the AP configuration includes more than one
02200          * option.
02201          */
02202         if (wps->cred.auth_type & WPS_AUTH_WPA2PSK)
02203                 wps->cred.auth_type = WPS_AUTH_WPA2PSK;
02204         else if (wps->cred.auth_type & WPS_AUTH_WPAPSK)
02205                 wps->cred.auth_type = WPS_AUTH_WPAPSK;
02206         if (wps->cred.encr_type & WPS_ENCR_AES)
02207                 wps->cred.encr_type = WPS_ENCR_AES;
02208         else if (wps->cred.encr_type & WPS_ENCR_TKIP)
02209                 wps->cred.encr_type = WPS_ENCR_TKIP;
02210         wpa_printf(MSG_DEBUG, "WPS: Update local configuration based on the "
02211                    "AP configuration");
02212         if (wps->wps->cred_cb)
02213                 wps->wps->cred_cb(wps->wps->cb_ctx, &wps->cred);
02214 }
02215 
02216 
02217 static void wps_cred_update(struct wps_credential *dst,
02218                             struct wps_credential *src)
02219 {
02220         os_memcpy(dst->ssid, src->ssid, sizeof(dst->ssid));
02221         dst->ssid_len = src->ssid_len;
02222         dst->auth_type = src->auth_type;
02223         dst->encr_type = src->encr_type;
02224         dst->key_idx = src->key_idx;
02225         os_memcpy(dst->key, src->key, sizeof(dst->key));
02226         dst->key_len = src->key_len;
02227 }
02228 
02229 
02230 static int wps_process_ap_settings_r(struct wps_data *wps,
02231                                      struct wps_parse_attr *attr)
02232 {
02233         if (wps->wps->ap || wps->er)
02234                 return 0;
02235 
02236         /* AP Settings Attributes in M7 when Enrollee is an AP */
02237         if (wps_process_ap_settings(attr, &wps->cred) < 0)
02238                 return -1;
02239 
02240         wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
02241 
02242         if (wps->new_ap_settings) {
02243                 wpa_printf(MSG_INFO, "WPS: Update AP configuration based on "
02244                            "new settings");
02245                 wps_cred_update(&wps->cred, wps->new_ap_settings);
02246                 return 0;
02247         } else {
02248                 /*
02249                  * Use the AP PIN only to receive the current AP settings, not
02250                  * to reconfigure the AP.
02251                  */
02252                 if (wps->ap_settings_cb) {
02253                         wps->ap_settings_cb(wps->ap_settings_cb_ctx,
02254                                             &wps->cred);
02255                         return 1;
02256                 }
02257                 wps_sta_cred_cb(wps);
02258                 return 1;
02259         }
02260 }
02261 
02262 
02263 static enum wps_process_res wps_process_m7(struct wps_data *wps,
02264                                            const struct wpabuf *msg,
02265                                            struct wps_parse_attr *attr)
02266 {
02267         struct wpabuf *decrypted;
02268         struct wps_parse_attr eattr;
02269 
02270         wpa_printf(MSG_DEBUG, "WPS: Received M7");
02271 
02272         if (wps->state != RECV_M7) {
02273                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02274                            "receiving M7", wps->state);
02275                 wps->state = SEND_WSC_NACK;
02276                 return WPS_CONTINUE;
02277         }
02278 
02279         if (wps->pbc && wps->wps->registrar->force_pbc_overlap) {
02280                 wpa_printf(MSG_DEBUG, "WPS: Reject negotiation due to PBC "
02281                            "session overlap");
02282                 wps->state = SEND_WSC_NACK;
02283                 wps->config_error = WPS_CFG_MULTIPLE_PBC_DETECTED;
02284                 return WPS_CONTINUE;
02285         }
02286 
02287         if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
02288             wps_process_authenticator(wps, attr->authenticator, msg)) {
02289                 wps->state = SEND_WSC_NACK;
02290                 return WPS_CONTINUE;
02291         }
02292 
02293         decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings,
02294                                               attr->encr_settings_len);
02295         if (decrypted == NULL) {
02296                 wpa_printf(MSG_DEBUG, "WPS: Failed to decrypt Encrypted "
02297                            "Settings attribute");
02298                 wps->state = SEND_WSC_NACK;
02299                 return WPS_CONTINUE;
02300         }
02301 
02302         wpa_printf(MSG_DEBUG, "WPS: Processing decrypted Encrypted Settings "
02303                    "attribute");
02304         if (wps_parse_msg(decrypted, &eattr) < 0 ||
02305             wps_process_key_wrap_auth(wps, decrypted, eattr.key_wrap_auth) ||
02306             wps_process_e_snonce2(wps, eattr.e_snonce2) ||
02307             wps_process_ap_settings_r(wps, &eattr)) {
02308                 wpabuf_free(decrypted);
02309                 wps->state = SEND_WSC_NACK;
02310                 return WPS_CONTINUE;
02311         }
02312 
02313         wpabuf_free(decrypted);
02314 
02315         wps->state = SEND_M8;
02316         return WPS_CONTINUE;
02317 }
02318 
02319 
02320 static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
02321                                                 const struct wpabuf *msg)
02322 {
02323         struct wps_parse_attr attr;
02324         enum wps_process_res ret = WPS_CONTINUE;
02325 
02326         wpa_printf(MSG_DEBUG, "WPS: Received WSC_MSG");
02327 
02328         if (wps_parse_msg(msg, &attr) < 0)
02329                 return WPS_FAILURE;
02330 
02331         if (!wps_version_supported(attr.version)) {
02332                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02333                            attr.version ? *attr.version : 0);
02334                 return WPS_FAILURE;
02335         }
02336 
02337         if (attr.msg_type == NULL) {
02338                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02339                 return WPS_FAILURE;
02340         }
02341 
02342         if (*attr.msg_type != WPS_M1 &&
02343             (attr.registrar_nonce == NULL ||
02344              os_memcmp(wps->nonce_r, attr.registrar_nonce,
02345                        WPS_NONCE_LEN != 0))) {
02346                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02347                 return WPS_FAILURE;
02348         }
02349 
02350         switch (*attr.msg_type) {
02351         case WPS_M1:
02352 #ifdef CONFIG_WPS_UPNP
02353                 if (wps->wps->wps_upnp && attr.mac_addr) {
02354                         /* Remove old pending messages when starting new run */
02355                         wps_free_pending_msgs(wps->wps->upnp_msgs);
02356                         wps->wps->upnp_msgs = NULL;
02357 
02358                         upnp_wps_device_send_wlan_event(
02359                                 wps->wps->wps_upnp, attr.mac_addr,
02360                                 UPNP_WPS_WLANEVENT_TYPE_EAP, msg);
02361                 }
02362 #endif /* CONFIG_WPS_UPNP */
02363                 ret = wps_process_m1(wps, &attr);
02364                 break;
02365         case WPS_M3:
02366                 ret = wps_process_m3(wps, msg, &attr);
02367                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02368                         wps_fail_event(wps->wps, WPS_M3);
02369                 break;
02370         case WPS_M5:
02371                 ret = wps_process_m5(wps, msg, &attr);
02372                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02373                         wps_fail_event(wps->wps, WPS_M5);
02374                 break;
02375         case WPS_M7:
02376                 ret = wps_process_m7(wps, msg, &attr);
02377                 if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
02378                         wps_fail_event(wps->wps, WPS_M7);
02379                 break;
02380         default:
02381                 wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
02382                            *attr.msg_type);
02383                 return WPS_FAILURE;
02384         }
02385 
02386         if (ret == WPS_CONTINUE) {
02387                 /* Save a copy of the last message for Authenticator derivation
02388                  */
02389                 wpabuf_free(wps->last_msg);
02390                 wps->last_msg = wpabuf_dup(msg);
02391         }
02392 
02393         return ret;
02394 }
02395 
02396 
02397 static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
02398                                                 const struct wpabuf *msg)
02399 {
02400         struct wps_parse_attr attr;
02401 
02402         wpa_printf(MSG_DEBUG, "WPS: Received WSC_ACK");
02403 
02404         if (wps_parse_msg(msg, &attr) < 0)
02405                 return WPS_FAILURE;
02406 
02407         if (!wps_version_supported(attr.version)) {
02408                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02409                            attr.version ? *attr.version : 0);
02410                 return WPS_FAILURE;
02411         }
02412 
02413         if (attr.msg_type == NULL) {
02414                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02415                 return WPS_FAILURE;
02416         }
02417 
02418         if (*attr.msg_type != WPS_WSC_ACK) {
02419                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02420                            *attr.msg_type);
02421                 return WPS_FAILURE;
02422         }
02423 
02424 #ifdef CONFIG_WPS_UPNP
02425         if (wps->wps->wps_upnp && wps->ext_reg && wps->state == RECV_M2D_ACK &&
02426             upnp_wps_subscribers(wps->wps->wps_upnp)) {
02427                 if (wps->wps->upnp_msgs)
02428                         return WPS_CONTINUE;
02429                 wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
02430                            "external Registrar");
02431                 return WPS_PENDING;
02432         }
02433 #endif /* CONFIG_WPS_UPNP */
02434 
02435         if (attr.registrar_nonce == NULL ||
02436             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02437         {
02438                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02439                 return WPS_FAILURE;
02440         }
02441 
02442         if (attr.enrollee_nonce == NULL ||
02443             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02444                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02445                 return WPS_FAILURE;
02446         }
02447 
02448         if (wps->state == RECV_M2D_ACK) {
02449 #ifdef CONFIG_WPS_UPNP
02450                 if (wps->wps->wps_upnp &&
02451                     upnp_wps_subscribers(wps->wps->wps_upnp)) {
02452                         if (wps->wps->upnp_msgs)
02453                                 return WPS_CONTINUE;
02454                         if (wps->ext_reg == 0)
02455                                 wps->ext_reg = 1;
02456                         wpa_printf(MSG_DEBUG, "WPS: Wait for response from an "
02457                                    "external Registrar");
02458                         return WPS_PENDING;
02459                 }
02460 #endif /* CONFIG_WPS_UPNP */
02461 
02462                 wpa_printf(MSG_DEBUG, "WPS: No more registrars available - "
02463                            "terminate negotiation");
02464         }
02465 
02466         return WPS_FAILURE;
02467 }
02468 
02469 
02470 static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
02471                                                  const struct wpabuf *msg)
02472 {
02473         struct wps_parse_attr attr;
02474         int old_state;
02475 
02476         wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
02477 
02478         old_state = wps->state;
02479         wps->state = SEND_WSC_NACK;
02480 
02481         if (wps_parse_msg(msg, &attr) < 0)
02482                 return WPS_FAILURE;
02483 
02484         if (!wps_version_supported(attr.version)) {
02485                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02486                            attr.version ? *attr.version : 0);
02487                 return WPS_FAILURE;
02488         }
02489 
02490         if (attr.msg_type == NULL) {
02491                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02492                 return WPS_FAILURE;
02493         }
02494 
02495         if (*attr.msg_type != WPS_WSC_NACK) {
02496                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02497                            *attr.msg_type);
02498                 return WPS_FAILURE;
02499         }
02500 
02501 #ifdef CONFIG_WPS_UPNP
02502         if (wps->wps->wps_upnp && wps->ext_reg) {
02503                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
02504                            "Registrar terminated by the Enrollee");
02505                 return WPS_FAILURE;
02506         }
02507 #endif /* CONFIG_WPS_UPNP */
02508 
02509         if (attr.registrar_nonce == NULL ||
02510             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02511         {
02512                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02513                 return WPS_FAILURE;
02514         }
02515 
02516         if (attr.enrollee_nonce == NULL ||
02517             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02518                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02519                 return WPS_FAILURE;
02520         }
02521 
02522         if (attr.config_error == NULL) {
02523                 wpa_printf(MSG_DEBUG, "WPS: No Configuration Error attribute "
02524                            "in WSC_NACK");
02525                 return WPS_FAILURE;
02526         }
02527 
02528         wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
02529                    "Configuration Error %d", WPA_GET_BE16(attr.config_error));
02530 
02531         switch (old_state) {
02532         case RECV_M3:
02533                 wps_fail_event(wps->wps, WPS_M2);
02534                 break;
02535         case RECV_M5:
02536                 wps_fail_event(wps->wps, WPS_M4);
02537                 break;
02538         case RECV_M7:
02539                 wps_fail_event(wps->wps, WPS_M6);
02540                 break;
02541         case RECV_DONE:
02542                 wps_fail_event(wps->wps, WPS_M8);
02543                 break;
02544         default:
02545                 break;
02546         }
02547 
02548         return WPS_FAILURE;
02549 }
02550 
02551 
02552 static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
02553                                                  const struct wpabuf *msg)
02554 {
02555         struct wps_parse_attr attr;
02556 
02557         wpa_printf(MSG_DEBUG, "WPS: Received WSC_Done");
02558 
02559         if (wps->state != RECV_DONE &&
02560             (!wps->wps->wps_upnp || !wps->ext_reg)) {
02561                 wpa_printf(MSG_DEBUG, "WPS: Unexpected state (%d) for "
02562                            "receiving WSC_Done", wps->state);
02563                 return WPS_FAILURE;
02564         }
02565 
02566         if (wps_parse_msg(msg, &attr) < 0)
02567                 return WPS_FAILURE;
02568 
02569         if (!wps_version_supported(attr.version)) {
02570                 wpa_printf(MSG_DEBUG, "WPS: Unsupported message version 0x%x",
02571                            attr.version ? *attr.version : 0);
02572                 return WPS_FAILURE;
02573         }
02574 
02575         if (attr.msg_type == NULL) {
02576                 wpa_printf(MSG_DEBUG, "WPS: No Message Type attribute");
02577                 return WPS_FAILURE;
02578         }
02579 
02580         if (*attr.msg_type != WPS_WSC_DONE) {
02581                 wpa_printf(MSG_DEBUG, "WPS: Invalid Message Type %d",
02582                            *attr.msg_type);
02583                 return WPS_FAILURE;
02584         }
02585 
02586 #ifdef CONFIG_WPS_UPNP
02587         if (wps->wps->wps_upnp && wps->ext_reg) {
02588                 wpa_printf(MSG_DEBUG, "WPS: Negotiation using external "
02589                            "Registrar completed successfully");
02590                 wps_device_store(wps->wps->registrar, &wps->peer_dev,
02591                                  wps->uuid_e);
02592                 return WPS_DONE;
02593         }
02594 #endif /* CONFIG_WPS_UPNP */
02595 
02596         if (attr.registrar_nonce == NULL ||
02597             os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
02598         {
02599                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
02600                 return WPS_FAILURE;
02601         }
02602 
02603         if (attr.enrollee_nonce == NULL ||
02604             os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
02605                 wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
02606                 return WPS_FAILURE;
02607         }
02608 
02609         wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
02610         wps_device_store(wps->wps->registrar, &wps->peer_dev,
02611                          wps->uuid_e);
02612 
02613         if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
02614             wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
02615                 struct wps_credential cred;
02616 
02617                 wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
02618                            "on first Enrollee connection");
02619 
02620                 os_memset(&cred, 0, sizeof(cred));
02621                 os_memcpy(cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
02622                 cred.ssid_len = wps->wps->ssid_len;
02623                 cred.auth_type = WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK;
02624                 cred.encr_type = WPS_ENCR_TKIP | WPS_ENCR_AES;
02625                 os_memcpy(cred.key, wps->new_psk, wps->new_psk_len);
02626                 cred.key_len = wps->new_psk_len;
02627 
02628                 wps->wps->wps_state = WPS_STATE_CONFIGURED;
02629                 wpa_hexdump_ascii_key(MSG_DEBUG,
02630                                       "WPS: Generated random passphrase",
02631                                       wps->new_psk, wps->new_psk_len);
02632                 if (wps->wps->cred_cb)
02633                         wps->wps->cred_cb(wps->wps->cb_ctx, &cred);
02634 
02635                 os_free(wps->new_psk);
02636                 wps->new_psk = NULL;
02637         }
02638 
02639         if (!wps->wps->ap && !wps->er)
02640                 wps_sta_cred_cb(wps);
02641 
02642         if (wps->new_psk) {
02643                 if (wps_cb_new_psk(wps->wps->registrar, wps->mac_addr_e,
02644                                    wps->new_psk, wps->new_psk_len)) {
02645                         wpa_printf(MSG_DEBUG, "WPS: Failed to configure the "
02646                                    "new PSK");
02647                 }
02648                 os_free(wps->new_psk);
02649                 wps->new_psk = NULL;
02650         }
02651 
02652         wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
02653 
02654         if (wps->pbc) {
02655                 wps_registrar_remove_pbc_session(wps->wps->registrar,
02656                                                  wps->mac_addr_e, wps->uuid_e);
02657                 wps_registrar_pbc_completed(wps->wps->registrar);
02658         } else {
02659                 wps_registrar_pin_completed(wps->wps->registrar);
02660         }
02661 
02662         wps_success_event(wps->wps);
02663 
02664         return WPS_DONE;
02665 }
02666 
02667 
02668 enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
02669                                                enum wsc_op_code op_code,
02670                                                const struct wpabuf *msg)
02671 {
02672         enum wps_process_res ret;
02673 
02674         wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
02675                    "op_code=%d)",
02676                    (unsigned long) wpabuf_len(msg), op_code);
02677 
02678 #ifdef CONFIG_WPS_UPNP
02679         if (wps->wps->wps_upnp && op_code == WSC_MSG && wps->ext_reg == 1) {
02680                 struct wps_parse_attr attr;
02681                 if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type &&
02682                     *attr.msg_type == WPS_M3)
02683                         wps->ext_reg = 2; /* past M2/M2D phase */
02684         }
02685         if (wps->ext_reg > 1)
02686                 wps_registrar_free_pending_m2(wps->wps);
02687         if (wps->wps->wps_upnp && wps->ext_reg &&
02688             wps->wps->upnp_msgs == NULL &&
02689             (op_code == WSC_MSG || op_code == WSC_Done || op_code == WSC_NACK))
02690         {
02691                 struct wps_parse_attr attr;
02692                 int type;
02693                 if (wps_parse_msg(msg, &attr) < 0 || attr.msg_type == NULL)
02694                         type = -1;
02695                 else
02696                         type = *attr.msg_type;
02697                 wpa_printf(MSG_DEBUG, "WPS: Sending received message (type %d)"
02698                            " to external Registrar for processing", type);
02699                 upnp_wps_device_send_wlan_event(wps->wps->wps_upnp,
02700                                                 wps->mac_addr_e,
02701                                                 UPNP_WPS_WLANEVENT_TYPE_EAP,
02702                                                 msg);
02703                 if (op_code == WSC_MSG)
02704                         return WPS_PENDING;
02705         } else if (wps->wps->wps_upnp && wps->ext_reg && op_code == WSC_MSG) {
02706                 wpa_printf(MSG_DEBUG, "WPS: Skip internal processing - using "
02707                            "external Registrar");
02708                 return WPS_CONTINUE;
02709         }
02710 #endif /* CONFIG_WPS_UPNP */
02711 
02712         switch (op_code) {
02713         case WSC_MSG:
02714                 return wps_process_wsc_msg(wps, msg);
02715         case WSC_ACK:
02716                 return wps_process_wsc_ack(wps, msg);
02717         case WSC_NACK:
02718                 return wps_process_wsc_nack(wps, msg);
02719         case WSC_Done:
02720                 ret = wps_process_wsc_done(wps, msg);
02721                 if (ret == WPS_FAILURE) {
02722                         wps->state = SEND_WSC_NACK;
02723                         wps_fail_event(wps->wps, WPS_WSC_DONE);
02724                 }
02725                 return ret;
02726         default:
02727                 wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
02728                 return WPS_FAILURE;
02729         }
02730 }
02731 
02732 
02733 int wps_registrar_update_ie(struct wps_registrar *reg)
02734 {
02735         return wps_set_ie(reg);
02736 }
02737 
02738 
02739 static void wps_registrar_set_selected_timeout(void *eloop_ctx,
02740                                                void *timeout_ctx)
02741 {
02742         struct wps_registrar *reg = eloop_ctx;
02743 
02744         wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar timed out - "
02745                    "unselect Registrar");
02746         reg->selected_registrar = 0;
02747         reg->pbc = 0;
02748         reg->sel_reg_dev_password_id_override = -1;
02749         reg->sel_reg_config_methods_override = -1;
02750         wps_set_ie(reg);
02751         wps_cb_set_sel_reg(reg);
02752 }
02753 
02754 
02765 int wps_registrar_set_selected_registrar(struct wps_registrar *reg,
02766                                          const struct wpabuf *msg)
02767 {
02768         struct wps_parse_attr attr;
02769 
02770         wpa_hexdump_buf(MSG_MSGDUMP, "WPS: SetSelectedRegistrar attributes",
02771                         msg);
02772 
02773         if (wps_parse_msg(msg, &attr) < 0)
02774                 return -1;
02775         if (!wps_version_supported(attr.version)) {
02776                 wpa_printf(MSG_DEBUG, "WPS: Unsupported SetSelectedRegistrar "
02777                            "version 0x%x", attr.version ? *attr.version : 0);
02778                 return -1;
02779         }
02780 
02781         if (attr.selected_registrar == NULL ||
02782             *attr.selected_registrar == 0) {
02783                 wpa_printf(MSG_DEBUG, "WPS: SetSelectedRegistrar: Disable "
02784                            "Selected Registrar");
02785                 eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg,
02786                                      NULL);
02787                 wps_registrar_set_selected_timeout(reg, NULL);
02788                 return 0;
02789         }
02790 
02791         reg->selected_registrar = 1;
02792         reg->sel_reg_dev_password_id_override = attr.dev_password_id ?
02793                 WPA_GET_BE16(attr.dev_password_id) : DEV_PW_DEFAULT;
02794         reg->sel_reg_config_methods_override = attr.sel_reg_config_methods ?
02795                 WPA_GET_BE16(attr.sel_reg_config_methods) : -1;
02796         wps_set_ie(reg);
02797 
02798         eloop_cancel_timeout(wps_registrar_set_selected_timeout, reg, NULL);
02799         eloop_register_timeout(WPS_PBC_WALK_TIME, 0,
02800                                wps_registrar_set_selected_timeout,
02801                                reg, NULL);
02802         return 0;
02803 }
02804 
02805 
02806 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
02807                            char *buf, size_t buflen)
02808 {
02809         struct wps_registrar_device *d;
02810         int len = 0, ret;
02811         char uuid[40];
02812 
02813         d = wps_device_get(reg, addr);
02814         if (d == NULL)
02815                 return 0;
02816         if (uuid_bin2str(d->uuid, uuid, sizeof(uuid)))
02817                 return 0;
02818 
02819         ret = os_snprintf(buf + len, buflen - len,
02820                           "wpsUuid=%s\n"
02821                           "wpsPrimaryDeviceType=%u-%08X-%u\n"
02822                           "wpsDeviceName=%s\n"
02823                           "wpsManufacturer=%s\n"
02824                           "wpsModelName=%s\n"
02825                           "wpsModelNumber=%s\n"
02826                           "wpsSerialNumber=%s\n",
02827                           uuid,
02828                           d->dev.categ, d->dev.oui, d->dev.sub_categ,
02829                           d->dev.device_name ? d->dev.device_name : "",
02830                           d->dev.manufacturer ? d->dev.manufacturer : "",
02831                           d->dev.model_name ? d->dev.model_name : "",
02832                           d->dev.model_number ? d->dev.model_number : "",
02833                           d->dev.serial_number ? d->dev.serial_number : "");
02834         if (ret < 0 || (size_t) ret >= buflen - len)
02835                 return len;
02836         len += ret;
02837 
02838         return len;
02839 }
02840 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:55 2009 for hostapd by  doxygen 1.6.1