[PATCH v2 2/4] Add "catchall" to react to all probe requests

Stefan Tomanek stefan.tomanek at wertarbyte.de
Sun Apr 26 09:43:20 EDT 2015


This change adds the option "catchall" to the configuration; when set, hostap
reacts to any probe request received by generating a matching response and
associating the client with itself, regardless of the SSID requested by it.
This is mainly useful for honeypot use cases, but can be extended to allow
multiple SSIDs on a single BSS.

Signed-off-by: Stefan Tomanek <stefan.tomanek at wertarbyte.de>
---
 hostapd/Makefile      |  4 ++++
 hostapd/config_file.c |  4 ++++
 hostapd/defconfig     |  3 +++
 hostapd/hostapd.conf  |  3 +++
 src/ap/ap_config.h    |  4 ++++
 src/ap/beacon.c       | 54 +++++++++++++++++++++++++++++++++++++++++++++------
 src/ap/ieee802_11.c   | 21 +++++++++++++++-----
 7 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/hostapd/Makefile b/hostapd/Makefile
index 3c7bd6f..b16241f 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -897,6 +897,10 @@ LIBS += -lsqlite3
 LIBS_h += -lsqlite3
 endif
 
+ifdef CONFIG_MULTI_SSID
+CFLAGS += -DCONFIG_MULTI_SSID
+endif
+
 ALL=hostapd hostapd_cli
 
 all: verify_config $(ALL)
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 1186644..09f51c1 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1993,6 +1993,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
 		os_free(str);
 	} else if (os_strcmp(buf, "utf8_ssid") == 0) {
 		bss->ssid.utf8_ssid = atoi(pos) > 0;
+#ifdef CONFIG_MULTI_SSID
+	} else if (os_strcmp(buf, "catchall") == 0) {
+		bss->ssid.catchall = atoi(pos) > 0;
+#endif /* CONFIG_MULTI_SSID */
 	} else if (os_strcmp(buf, "macaddr_acl") == 0) {
 		bss->macaddr_acl = atoi(pos);
 		if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
diff --git a/hostapd/defconfig b/hostapd/defconfig
index 4cde2b5..2fd70bb 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -283,6 +283,9 @@ CONFIG_IPV6=y
 # Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
 #CONFIG_SQLITE=y
 
+# Enable the handling of multiple dynamically generated SSIDs for each BSS
+#CONFIG_MULTI_SSID=y
+
 # Testing options
 # This can be used to enable some testing options (see also the example
 # configuration file) that are really useful only for testing clients that
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 90d1523..10542e2 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -93,6 +93,9 @@ ssid=test
 # UTF-8 SSID: Whether the SSID is to be interpreted using UTF-8 encoding
 #utf8_ssid=1
 
+# Accept any requested SSID for association with this BSS
+#catchall=1
+
 # Country code (ISO/IEC 3166-1). Used to set regulatory domain.
 # Set as needed to indicate country in which device is operating.
 # This can limit available channels and transmit power.
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 7b4a7ea..52359d5 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -84,6 +84,10 @@ struct hostapd_ssid {
 	unsigned int wpa_passphrase_set:1;
 	unsigned int wpa_psk_set:1;
 
+#ifdef CONFIG_MULTI_SSID
+	unsigned int catchall:1;
+#endif /* CONFIG_MULTI_SSID */
+
 	char vlan[IFNAMSIZ + 1];
 	secpolicy security_policy;
 
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 00847c7..53c1a61 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -362,7 +362,8 @@ static u8 * hostapd_add_csa_elems(struct hostapd_data *hapd, u8 *pos,
 static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 				   struct sta_info *sta,
 				   const struct ieee80211_mgmt *req,
-				   int is_p2p, size_t *resp_len)
+				   int is_p2p, size_t *resp_len,
+				   const u8 *ssid, size_t ssid_len)
 {
 	struct ieee80211_mgmt *resp;
 	u8 *pos, *epos;
@@ -406,9 +407,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 
 	pos = resp->u.probe_resp.variable;
 	*pos++ = WLAN_EID_SSID;
-	*pos++ = hapd->conf->ssid.ssid_len;
-	os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len);
-	pos += hapd->conf->ssid.ssid_len;
+	*pos++ = ssid_len;
+	os_memcpy(pos, ssid, ssid_len);
+	pos += ssid_len;
 
 	/* Supported rates */
 	pos = hostapd_eid_supp_rates(hapd, pos);
@@ -503,6 +504,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 enum ssid_match_result {
 	NO_SSID_MATCH,
 	EXACT_SSID_MATCH,
+#ifdef CONFIG_MULTI_SSID
+	CATCHALL_SSID_MATCH,
+#endif /* CONFIG_MULTI_SSID */
 	WILDCARD_SSID_MATCH
 };
 
@@ -539,6 +543,19 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
 	return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
 }
 
+#ifdef CONFIG_MULTI_SSID
+static u8 ssid_is_handled(struct hostapd_iface *iface, const u8 *ssid, size_t ssid_len) {
+	size_t i;
+	struct hostapd_data *bss;
+	for (i = 0; i < iface->num_bss; i++) {
+		bss = iface->bss[i];
+		if (bss->conf->ssid.ssid_len == ssid_len &&
+		    os_memcmp(bss->conf->ssid.ssid, ssid, ssid_len) == 0)
+			return 1;
+	}
+	return 0;
+}
+#endif /* CONFIG_MULTI_SSID */
 
 void handle_probe_req(struct hostapd_data *hapd,
 		      const struct ieee80211_mgmt *mgmt, size_t len,
@@ -551,6 +568,8 @@ void handle_probe_req(struct hostapd_data *hapd,
 	struct sta_info *sta = NULL;
 	size_t i, resp_len;
 	int noack;
+	const u8 *ssid = hapd->conf->ssid.ssid;
+	size_t ssid_len = hapd->conf->ssid.ssid_len;
 	enum ssid_match_result res;
 
 	ie = mgmt->u.probe_req.variable;
@@ -649,6 +668,27 @@ void handle_probe_req(struct hostapd_data *hapd,
 
 	res = ssid_match(hapd, elems.ssid, elems.ssid_len,
 			 elems.ssid_list, elems.ssid_list_len);
+
+#ifdef CONFIG_MULTI_SSID
+	/*
+	 * Process the probe request if "catchall" is set and no other match
+	 * is found in this or any other BSS.
+	 */
+	if (res == NO_SSID_MATCH && hapd->conf->ssid.catchall && elems.ssid_len
+	    && !ssid_is_handled(hapd->iface, elems.ssid, elems.ssid_len)) {
+		wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
+			   " for foreign (but handled) SSID '%s' (DA " MACSTR ")%s",
+			   MAC2STR(mgmt->sa),
+			   wpa_ssid_txt(elems.ssid, elems.ssid_len),
+			   MAC2STR(mgmt->da),
+			   elems.ssid_list ? " (SSID list)" : "");
+
+		ssid = elems.ssid;
+		ssid_len = elems.ssid_len;
+		res = CATCHALL_SSID_MATCH;
+	}
+#endif /* CONFIG_MULTI_SSID */
+
 	if (res != NO_SSID_MATCH) {
 		if (sta)
 			sta->ssid_probe = &hapd->conf->ssid;
@@ -720,7 +760,7 @@ void handle_probe_req(struct hostapd_data *hapd,
 #endif /* CONFIG_TESTING_OPTIONS */
 
 	resp = hostapd_gen_probe_resp(hapd, sta, mgmt, elems.p2p != NULL,
-				      &resp_len);
+				      &resp_len, ssid, ssid_len);
 	if (resp == NULL)
 		return;
 
@@ -774,7 +814,9 @@ static u8 * hostapd_probe_resp_offloads(struct hostapd_data *hapd,
 			   "this");
 
 	/* Generate a Probe Response template for the non-P2P case */
-	return hostapd_gen_probe_resp(hapd, NULL, NULL, 0, resp_len);
+	return hostapd_gen_probe_resp(hapd, NULL, NULL, 0, resp_len,
+	                              hapd->conf->ssid.ssid,
+	                              hapd->conf->ssid.ssid_len);
 }
 
 #endif /* NEED_AP_MLME */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index e2d7459..a4884cc 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1186,16 +1186,27 @@ static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
 	if (ssid_ie == NULL)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
-	if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
-	    os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
+	if (ssid_ie_len == hapd->conf->ssid.ssid_len &&
+	    os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) == 0) {
+		return WLAN_STATUS_SUCCESS;
+	}
+
+#ifdef CONFIG_MULTI_SSID
+	if (hapd->conf->ssid.catchall) {
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_INFO,
-			       "Station tried to associate with unknown SSID "
+			       "Station associating with catchall network, requested SSID "
 			       "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
-		return WLAN_STATUS_UNSPECIFIED_FAILURE;
+		return WLAN_STATUS_SUCCESS;
 	}
+#endif /* CONFIG_MULTI_SSID */
 
-	return WLAN_STATUS_SUCCESS;
+	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+		HOSTAPD_LEVEL_INFO,
+		"Station tried to associate with unknown SSID "
+		"'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
+
+	return WLAN_STATUS_UNSPECIFIED_FAILURE;
 }
 
 
-- 
2.1.4


More information about the HostAP mailing list