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

Stefan Tomanek stefan.tomanek at wertarbyte.de
Sat Apr 25 11:37:32 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/config_file.c |  2 ++
 src/ap/ap_config.h    |  2 ++
 src/ap/beacon.c       | 48 ++++++++++++++++++++++++++++++++++++++++++------
 src/ap/ieee802_11.c   | 19 ++++++++++++++-----
 4 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 1186644..e83d125 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1993,6 +1993,8 @@ 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;
+	} else if (os_strcmp(buf, "catchall") == 0) {
+		bss->ssid.catchall = atoi(pos) > 0;
 	} else if (os_strcmp(buf, "macaddr_acl") == 0) {
 		bss->macaddr_acl = atoi(pos);
 		if (bss->macaddr_acl != ACCEPT_UNLESS_DENIED &&
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 7b4a7ea..c2d7043 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -84,6 +84,8 @@ struct hostapd_ssid {
 	unsigned int wpa_passphrase_set:1;
 	unsigned int wpa_psk_set:1;
 
+	unsigned int catchall:1;
+
 	char vlan[IFNAMSIZ + 1];
 	secpolicy security_policy;
 
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 00847c7..66b76e9 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,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
 enum ssid_match_result {
 	NO_SSID_MATCH,
 	EXACT_SSID_MATCH,
+	CATCHALL_SSID_MATCH,
 	WILDCARD_SSID_MATCH
 };
 
@@ -539,6 +541,17 @@ static enum ssid_match_result ssid_match(struct hostapd_data *hapd,
 	return wildcard ? WILDCARD_SSID_MATCH : NO_SSID_MATCH;
 }
 
+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;
+}
 
 void handle_probe_req(struct hostapd_data *hapd,
 		      const struct ieee80211_mgmt *mgmt, size_t len,
@@ -551,6 +564,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 +664,25 @@ void handle_probe_req(struct hostapd_data *hapd,
 
 	res = ssid_match(hapd, elems.ssid, elems.ssid_len,
 			 elems.ssid_list, elems.ssid_list_len);
+
+	/*
+	 * 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;
+	}
+
 	if (res != NO_SSID_MATCH) {
 		if (sta)
 			sta->ssid_probe = &hapd->conf->ssid;
@@ -720,7 +754,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 +808,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 b44a74b..7321c1d 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -1186,16 +1186,25 @@ 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;
+	}
+
+	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;
 	}
 
-	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