Parcourir la source

Added an option to add (or override) Credential attribute(s) in M8

Jouni Malinen il y a 16 ans
Parent
commit
6fa68a0ee5
6 fichiers modifiés avec 88 ajouts et 0 suppressions
  1. 21 0
      hostapd/config.c
  2. 3 0
      hostapd/config.h
  3. 14 0
      hostapd/hostapd.conf
  4. 3 0
      hostapd/wps_hostapd.c
  5. 25 0
      src/wps/wps.h
  6. 22 0
      src/wps/wps_registrar.c

+ 21 - 0
hostapd/config.c

@@ -2158,6 +2158,7 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 				errors++;
 			}
 		} else if (os_strcmp(buf, "wps_pin_requests") == 0) {
+			os_free(bss->wps_pin_requests);
 			bss->wps_pin_requests = os_strdup(pos);
 		} else if (os_strcmp(buf, "device_name") == 0) {
 			if (os_strlen(pos) > 32) {
@@ -2165,6 +2166,7 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 					   "device_name", line);
 				errors++;
 			}
+			os_free(bss->device_name);
 			bss->device_name = os_strdup(pos);
 		} else if (os_strcmp(buf, "manufacturer") == 0) {
 			if (os_strlen(pos) > 64) {
@@ -2172,6 +2174,7 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 					   "manufacturer", line);
 				errors++;
 			}
+			os_free(bss->manufacturer);
 			bss->manufacturer = os_strdup(pos);
 		} else if (os_strcmp(buf, "model_name") == 0) {
 			if (os_strlen(pos) > 32) {
@@ -2179,6 +2182,7 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 					   "model_name", line);
 				errors++;
 			}
+			os_free(bss->model_name);
 			bss->model_name = os_strdup(pos);
 		} else if (os_strcmp(buf, "model_number") == 0) {
 			if (os_strlen(pos) > 32) {
@@ -2186,6 +2190,7 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 					   "model_number", line);
 				errors++;
 			}
+			os_free(bss->model_number);
 			bss->model_number = os_strdup(pos);
 		} else if (os_strcmp(buf, "serial_number") == 0) {
 			if (os_strlen(pos) > 32) {
@@ -2193,10 +2198,13 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 					   "serial_number", line);
 				errors++;
 			}
+			os_free(bss->serial_number);
 			bss->serial_number = os_strdup(pos);
 		} else if (os_strcmp(buf, "device_type") == 0) {
+			os_free(bss->device_type);
 			bss->device_type = os_strdup(pos);
 		} else if (os_strcmp(buf, "config_methods") == 0) {
+			os_free(bss->config_methods);
 			bss->config_methods = os_strdup(pos);
 		} else if (os_strcmp(buf, "os_version") == 0) {
 			if (hexstr2bin(pos, bss->os_version, 4)) {
@@ -2205,7 +2213,20 @@ struct hostapd_config * hostapd_config_read(const char *fname)
 				errors++;
 			}
 		} else if (os_strcmp(buf, "ap_pin") == 0) {
+			os_free(bss->ap_pin);
 			bss->ap_pin = os_strdup(pos);
+		} else if (os_strcmp(buf, "skip_cred_build") == 0) {
+			bss->skip_cred_build = atoi(pos);
+		} else if (os_strcmp(buf, "extra_cred") == 0) {
+			os_free(bss->extra_cred);
+			bss->extra_cred =
+				(u8 *) os_readfile(pos, &bss->extra_cred_len);
+			if (bss->extra_cred == NULL) {
+				wpa_printf(MSG_ERROR, "Line %d: could not "
+					   "read Credentials from '%s'",
+					   line, pos);
+				errors++;
+			}
 #endif /* CONFIG_WPS */
 		} else {
 			wpa_printf(MSG_ERROR, "Line %d: unknown configuration "

+ 3 - 0
hostapd/config.h

@@ -300,6 +300,9 @@ struct hostapd_bss_config {
 	char *config_methods;
 	u8 os_version[4];
 	char *ap_pin;
+	int skip_cred_build;
+	u8 *extra_cred;
+	size_t extra_cred_len;
 #endif /* CONFIG_WPS */
 };
 

+ 14 - 0
hostapd/hostapd.conf

@@ -934,6 +934,20 @@ own_ip_addr=127.0.0.1
 # access point.
 #ap_pin=12345670
 
+# Skip building of automatic WPS credential
+# This can be used to allow the automatically generated Credential attribute to
+# be replaced with pre-configured Credential(s).
+#skip_cred_build=1
+
+# Additional Credential attribute(s)
+# This option can be used to add pre-configured Credential attributes into M8
+# message when acting as a Registrar. If skip_cred_build=1, this data will also
+# be able to override the Credential attribute that would have otherwise been
+# automatically generated based on network configuration. This configuration
+# option points to an external file that much contain the WPS Credential
+# attribute(s) as binary data.
+#extra_cred=hostapd.cred
+
 
 ##### Multiple BSSID support ##################################################
 #

+ 3 - 0
hostapd/wps_hostapd.c

@@ -516,6 +516,9 @@ int hostapd_init_wps(struct hostapd_data *hapd,
 	cfg.set_ie_cb = hostapd_wps_set_ie_cb;
 	cfg.pin_needed_cb = hostapd_wps_pin_needed_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;
 
 	wps->registrar = wps_registrar_init(wps, &cfg);
 	if (wps->registrar == NULL) {

+ 25 - 0
src/wps/wps.h

@@ -204,6 +204,31 @@ struct wps_registrar_config {
 	 * cb_ctx: Higher layer context data for Registrar callbacks
 	 */
 	void *cb_ctx;
+
+	/**
+	 * skip_cred_build: Do not build credential
+	 *
+	 * This option can be used to disable internal code that builds
+	 * Credential attribute into M8 based on the current network
+	 * configuration and Enrollee capabilities. The extra_cred data will
+	 * then be used as the Credential(s).
+	 */
+	int skip_cred_build;
+
+	/**
+	 * extra_cred: Additional Credential attribute(s)
+	 *
+	 * This optional data (set to %NULL to disable) can be used to add
+	 * Credential attribute(s) for other networks into M8. If
+	 * skip_cred_build is set, this will also override the automatically
+	 * generated Credential attribute.
+	 */
+	const u8 *extra_cred;
+
+	/**
+	 * extra_cred_len: Length of extra_cred in octets
+	 */
+	size_t extra_cred_len;
 };
 
 

+ 22 - 0
src/wps/wps_registrar.c

@@ -89,6 +89,9 @@ struct wps_registrar {
 
 	struct wps_uuid_pin *pins;
 	struct wps_pbc_session *pbc_sessions;
+
+	int skip_cred_build;
+	struct wpabuf *extra_cred;
 };
 
 
@@ -323,6 +326,15 @@ wps_registrar_init(struct wps_context *wps,
 	reg->set_ie_cb = cfg->set_ie_cb;
 	reg->pin_needed_cb = cfg->pin_needed_cb;
 	reg->cb_ctx = cfg->cb_ctx;
+	reg->skip_cred_build = cfg->skip_cred_build;
+	if (cfg->extra_cred) {
+		reg->extra_cred = wpabuf_alloc_copy(cfg->extra_cred,
+						    cfg->extra_cred_len);
+		if (reg->extra_cred == NULL) {
+			os_free(reg);
+			return NULL;
+		}
+	}
 
 	if (wps_set_ie(reg)) {
 		wps_registrar_deinit(reg);
@@ -344,6 +356,7 @@ void wps_registrar_deinit(struct wps_registrar *reg)
 	eloop_cancel_timeout(wps_registrar_pbc_timeout, reg, NULL);
 	wps_free_pins(reg->pins);
 	wps_free_pbc_sessions(reg->pbc_sessions);
+	wpabuf_free(reg->extra_cred);
 	os_free(reg);
 }
 
@@ -918,6 +931,9 @@ static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
 {
 	struct wpabuf *cred;
 
+	if (wps->wps->registrar->skip_cred_build)
+		goto skip_cred_build;
+
 	wpa_printf(MSG_DEBUG, "WPS:  * Credential");
 	os_memset(&wps->cred, 0, sizeof(wps->cred));
 
@@ -1021,6 +1037,12 @@ static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
 	wpabuf_put_buf(msg, cred);
 	wpabuf_free(cred);
 
+skip_cred_build:
+	if (wps->wps->registrar->extra_cred) {
+		wpa_printf(MSG_DEBUG, "WPS:  * Credential (pre-configured)");
+		wpabuf_put_buf(msg, wps->wps->registrar->extra_cred);
+	}
+
 	return 0;
 }