WPS: Added option to disable AP auto-config on first registration
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 21 Jan 2009 11:48:10 +0000 (13:48 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 21 Jan 2009 11:48:10 +0000 (13:48 +0200)
This operation can now be moved into an external program by configuring
hostapd with wps_cred_processing=1 and skip_cred_build=1. A new
ctrl_iface message (WPS-REG-SUCCESS <Enrollee MAC addr> <UUID-E>) will
be used to notify external programs of each successful registration and
that can be used as a tricker to move from unconfigured to configured
state.

hostapd/hostapd.conf
hostapd/wps_hostapd.c
src/common/wpa_ctrl.h
src/wps/wps.h
src/wps/wps_registrar.c

index bd24f17..b423be5 100644 (file)
@@ -954,6 +954,8 @@ own_ip_addr=127.0.0.1
 #      external program(s)
 #   2 = process received credentials internally and pass them over ctrl_iface
 #      to external program(s)
+# Note: With wps_cred_processing=1, skip_cred_build should be set to 1 and
+# extra_cred be used to provide the Credential data for Enrollees.
 #wps_cred_processing=0
 
 
index 916844b..a1560c9 100644 (file)
@@ -152,6 +152,18 @@ static void hostapd_wps_pin_needed_cb(void *ctx, const u8 *uuid_e,
 }
 
 
+static void hostapd_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
+                                      const u8 *uuid_e)
+{
+       struct hostapd_data *hapd = ctx;
+       char uuid[40];
+       if (uuid_bin2str(uuid_e, uuid, sizeof(uuid)))
+               return;
+       wpa_msg(hapd, MSG_INFO, WPS_EVENT_REG_SUCCESS MACSTR " %s",
+               MAC2STR(mac_addr), uuid);
+}
+
+
 static int str_starts(const char *str, const char *start)
 {
        return os_strncmp(str, start, os_strlen(start)) == 0;
@@ -531,10 +543,13 @@ int hostapd_init_wps(struct hostapd_data *hapd,
        cfg.new_psk_cb = hostapd_wps_new_psk_cb;
        cfg.set_ie_cb = hostapd_wps_set_ie_cb;
        cfg.pin_needed_cb = hostapd_wps_pin_needed_cb;
+       cfg.reg_success_cb = hostapd_wps_reg_success_cb;
        cfg.cb_ctx = hapd;
        cfg.skip_cred_build = conf->skip_cred_build;
        cfg.extra_cred = conf->extra_cred;
        cfg.extra_cred_len = conf->extra_cred_len;
+       cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) &&
+               conf->skip_cred_build;
 
        wps->registrar = wps_registrar_init(wps, &cfg);
        if (wps->registrar == NULL) {
index 9306a33..87a4c6b 100644 (file)
@@ -70,6 +70,7 @@ extern "C" {
 /* hostapd control interface - fixed message prefixes */
 #define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
 #define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
+#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
 
 
 /* wpa_supplicant/hostapd control interface access */
index 1736d9e..4847332 100644 (file)
@@ -206,6 +206,18 @@ struct wps_registrar_config {
                              const struct wps_device_data *dev);
 
        /**
+        * reg_success_cb - Callback for reporting successful registration
+        * @ctx: Higher layer context data (cb_ctx)
+        * @mac_addr: MAC address of the Enrollee
+        * @uuid_e: UUID-E of the Enrollee
+        *
+        * This callback is called whenever an Enrollee completes registration
+        * successfully.
+        */
+       void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
+                              const u8 *uuid_e);
+
+       /**
         * cb_ctx: Higher layer context data for Registrar callbacks
         */
        void *cb_ctx;
@@ -234,6 +246,18 @@ struct wps_registrar_config {
         * extra_cred_len: Length of extra_cred in octets
         */
        size_t extra_cred_len;
+
+       /**
+        * disable_auto_conf - Disable auto-configuration on first registration
+        *
+        * By default, the AP that is started in not configured state will
+        * generate a random PSK and move to configured state when the first
+        * registration protocol run is completed successfully. This option can
+        * be used to disable this functionality and leave it up to an external
+        * program to take care of configuration. This requires the extra_cred
+        * to be set with a suitable Credential and skip_cred_build being used.
+        */
+       int disable_auto_conf;
 };
 
 
index 246c1e9..7ddd649 100644 (file)
@@ -85,6 +85,8 @@ struct wps_registrar {
                         const u8 *probe_resp_ie, size_t probe_resp_ie_len);
        void (*pin_needed_cb)(void *ctx, const u8 *uuid_e,
                              const struct wps_device_data *dev);
+       void (*reg_success_cb)(void *ctx, const u8 *mac_addr,
+                              const u8 *uuid_e);
        void *cb_ctx;
 
        struct wps_uuid_pin *pins;
@@ -92,6 +94,7 @@ struct wps_registrar {
 
        int skip_cred_build;
        struct wpabuf *extra_cred;
+       int disable_auto_conf;
 };
 
 
@@ -325,6 +328,7 @@ wps_registrar_init(struct wps_context *wps,
        reg->new_psk_cb = cfg->new_psk_cb;
        reg->set_ie_cb = cfg->set_ie_cb;
        reg->pin_needed_cb = cfg->pin_needed_cb;
+       reg->reg_success_cb = cfg->reg_success_cb;
        reg->cb_ctx = cfg->cb_ctx;
        reg->skip_cred_build = cfg->skip_cred_build;
        if (cfg->extra_cred) {
@@ -335,6 +339,7 @@ wps_registrar_init(struct wps_context *wps,
                        return NULL;
                }
        }
+       reg->disable_auto_conf = cfg->disable_auto_conf;
 
        if (wps_set_ie(reg)) {
                wps_registrar_deinit(reg);
@@ -630,6 +635,16 @@ static void wps_cb_pin_needed(struct wps_registrar *reg, const u8 *uuid_e,
 }
 
 
+static void wps_cb_reg_success(struct wps_registrar *reg, const u8 *mac_addr,
+                              const u8 *uuid_e)
+{
+       if (reg->reg_success_cb == NULL)
+               return;
+
+       reg->reg_success_cb(reg->cb_ctx, mac_addr, uuid_e);
+}
+
+
 static int wps_cb_set_ie(struct wps_registrar *reg,
                         const struct wpabuf *beacon_ie,
                         const struct wpabuf *probe_resp_ie)
@@ -983,7 +998,8 @@ static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
        /* Set MAC address in the Credential to be the AP's address (BSSID) */
        os_memcpy(wps->cred.mac_addr, wps->wps->dev.mac_addr, ETH_ALEN);
 
-       if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap) {
+       if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap &&
+           !wps->wps->registrar->disable_auto_conf) {
                u8 r[16];
                /* Generate a random passphrase */
                if (os_get_random(r, sizeof(r)) < 0)
@@ -2118,7 +2134,7 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
        wpa_printf(MSG_DEBUG, "WPS: Negotiation completed successfully");
 
        if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->new_psk &&
-           wps->wps->ap) {
+           wps->wps->ap && !wps->wps->registrar->disable_auto_conf) {
                struct wps_credential cred;
 
                wpa_printf(MSG_DEBUG, "WPS: Moving to Configured state based "
@@ -2160,6 +2176,8 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
                wps->new_psk = NULL;
        }
 
+       wps_cb_reg_success(wps->wps->registrar, wps->mac_addr_e, wps->uuid_e);
+
        if (wps->pbc) {
                wps_registrar_remove_pbc_session(wps->wps->registrar,
                                                 wps->mac_addr_e, wps->uuid_e);