]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS ER: Only activate PBC mode on single AP
authorJouni Malinen <jouni.malinen@atheros.com>
Mon, 25 Oct 2010 18:41:10 +0000 (21:41 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 25 Oct 2010 18:41:10 +0000 (21:41 +0300)
Verify that the UUID given to wps_er_pbc command is known and only
activate PBC mode on the matching AP. The UUID can be that of the
AP or the station/Enrollee.

src/wps/wps_er.c
src/wps/wps_er.h

index ed5659f61d2086eb6c08e3ec22c34f9f6ed400d2..a5b252656972103e5ab89c26aafa8c5ebe9fc533 100644 (file)
@@ -62,11 +62,15 @@ static void wps_er_sta_event(struct wps_context *wps, struct wps_er_sta *sta,
 }
 
 
-static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr)
+static struct wps_er_sta * wps_er_sta_get(struct wps_er_ap *ap, const u8 *addr,
+                                         const u8 *uuid)
 {
        struct wps_er_sta *sta;
        dl_list_for_each(sta, &ap->sta, struct wps_er_sta, list) {
-               if (os_memcmp(sta->addr, addr, ETH_ALEN) == 0)
+               if ((addr == NULL ||
+                    os_memcmp(sta->addr, addr, ETH_ALEN) == 0) &&
+                   (uuid == NULL ||
+                    os_memcmp(uuid, sta->uuid, WPS_UUID_LEN) == 0))
                        return sta;
        }
        return NULL;
@@ -649,7 +653,7 @@ static struct wps_er_sta * wps_er_add_sta_data(struct wps_er_ap *ap,
                                               struct wps_parse_attr *attr,
                                               int probe_req)
 {
-       struct wps_er_sta *sta = wps_er_sta_get(ap, addr);
+       struct wps_er_sta *sta = wps_er_sta_get(ap, addr, NULL);
        int new_sta = 0;
        int m1;
 
@@ -1418,6 +1422,10 @@ void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
        data.set_sel_reg.state = WPS_ER_SET_SEL_REG_START;
 
        dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
+               if (er->set_sel_reg_uuid_filter &&
+                   os_memcmp(ap->uuid, er->set_sel_reg_uuid_filter,
+                             WPS_UUID_LEN) != 0)
+                       continue;
                data.set_sel_reg.uuid = ap->uuid;
                er->wps->event_cb(er->wps->cb_ctx,
                                  WPS_EV_ER_SET_SELECTED_REGISTRAR, &data);
@@ -1430,6 +1438,9 @@ void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,
 
 int wps_er_pbc(struct wps_er *er, const u8 *uuid)
 {
+       int res;
+       struct wps_er_ap *ap;
+
        if (er == NULL || er->wps == NULL)
                return -1;
 
@@ -1439,13 +1450,24 @@ int wps_er_pbc(struct wps_er *er, const u8 *uuid)
                return -1;
        }
 
-       /*
-        * TODO: Should enable PBC mode only in a single AP based on which AP
-        * the Enrollee (uuid) is using. Now, we may end up enabling multiple
-        * APs in PBC mode which could result in session overlap at the
-        * Enrollee.
-        */
-       if (wps_registrar_button_pushed(er->wps->registrar))
+       ap = wps_er_ap_get(er, NULL, uuid);
+       if (ap == NULL) {
+               struct wps_er_sta *sta = NULL;
+               dl_list_for_each(ap, &er->ap, struct wps_er_ap, list) {
+                       sta = wps_er_sta_get(ap, NULL, uuid);
+                       if (sta) {
+                               uuid = ap->uuid;
+                               break;
+                       }
+               }
+               if (sta == NULL)
+                       return -1; /* Unknown UUID */
+       }
+
+       er->set_sel_reg_uuid_filter = uuid;
+       res = wps_registrar_button_pushed(er->wps->registrar);
+       er->set_sel_reg_uuid_filter = NULL;
+       if (res)
                return -1;
 
        return 0;
index d51bd702527966e989cc393e18b36e7ee6ca4f33..16dbaa67f1d5fb0f804cd94749da4dfda2a501eb 100644 (file)
@@ -92,6 +92,7 @@ struct wps_er {
        void *deinit_done_ctx;
        struct in_addr filter_addr;
        int skip_set_sel_reg;
+       const u8 *set_sel_reg_uuid_filter;
 };