Browse Source

WPS ER: Allow AP filtering based on IP address

wps_er_start command now takes an optional parameter that can be used
to configure a filter to only allow UPnP SSDP messages from the
specified IP address. In practice, this limits the WPS ER operations
to a single AP and filters out all other devices in the network.
Jouni Malinen 15 years ago
parent
commit
0848668513

+ 2 - 1
src/wps/wps.h

@@ -718,7 +718,8 @@ int wps_process_oob(struct wps_context *wps, struct oob_device_data *oob_dev,
 		    int registrar);
 int wps_attr_text(struct wpabuf *data, char *buf, char *end);
 
-struct wps_er * wps_er_init(struct wps_context *wps, const char *ifname);
+struct wps_er * wps_er_init(struct wps_context *wps, const char *ifname,
+			    const char *filter);
 void wps_er_refresh(struct wps_er *er);
 void wps_er_deinit(struct wps_er *er, void (*cb)(void *ctx), void *ctx);
 void wps_er_set_sel_reg(struct wps_er *er, int sel_reg, u16 dev_passwd_id,

+ 11 - 1
src/wps/wps_er.c

@@ -1151,7 +1151,7 @@ static void wps_er_http_req(void *ctx, struct http_request *req)
 
 
 struct wps_er *
-wps_er_init(struct wps_context *wps, const char *ifname)
+wps_er_init(struct wps_context *wps, const char *ifname, const char *filter)
 {
 	struct wps_er *er;
 	struct in_addr addr;
@@ -1173,6 +1173,16 @@ wps_er_init(struct wps_context *wps, const char *ifname)
 		return NULL;
 	}
 
+	if (filter) {
+		if (inet_aton(filter, &er->filter_addr) == 0) {
+			wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
+				   "address %s", filter);
+			wps_er_deinit(er, NULL, NULL);
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
+			   "with %s", filter);
+	}
 	if (get_netif_info(ifname, &er->ip_addr, &er->ip_addr_text,
 			   er->mac_addr)) {
 		wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "

+ 1 - 0
src/wps/wps_er.h

@@ -90,6 +90,7 @@ struct wps_er {
 	int deinitializing;
 	void (*deinit_done_cb)(void *ctx);
 	void *deinit_done_ctx;
+	struct in_addr filter_addr;
 };
 
 

+ 3 - 0
src/wps/wps_er_ssdp.c

@@ -41,6 +41,9 @@ static void wps_er_ssdp_rx(int sd, void *eloop_ctx, void *sock_ctx)
 	if (nread <= 0)
 		return;
 	buf[nread] = '\0';
+	if (er->filter_addr.s_addr &&
+	    er->filter_addr.s_addr != addr.sin_addr.s_addr)
+		return;
 
 	wpa_printf(MSG_DEBUG, "WPS ER: Received SSDP from %s",
 		   inet_ntoa(addr.sin_addr));

+ 4 - 1
wpa_supplicant/ctrl_iface.c

@@ -1793,7 +1793,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 			reply_len = -1;
 #ifdef CONFIG_WPS_ER
 	} else if (os_strcmp(buf, "WPS_ER_START") == 0) {
-		if (wpas_wps_er_start(wpa_s))
+		if (wpas_wps_er_start(wpa_s, NULL))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "WPS_ER_START ", 13) == 0) {
+		if (wpas_wps_er_start(wpa_s, buf + 13))
 			reply_len = -1;
 	} else if (os_strcmp(buf, "WPS_ER_STOP") == 0) {
 		if (wpas_wps_er_stop(wpa_s))

+ 6 - 2
wpa_supplicant/wpa_cli.c

@@ -651,8 +651,12 @@ static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
 static int wpa_cli_cmd_wps_er_start(struct wpa_ctrl *ctrl, int argc,
 				    char *argv[])
 {
+	char cmd[100];
+	if (argc > 0) {
+		os_snprintf(cmd, sizeof(cmd), "WPS_ER_START %s", argv[0]);
+		return wpa_ctrl_command(ctrl, cmd);
+	}
 	return wpa_ctrl_command(ctrl, "WPS_ER_START");
-
 }
 
 
@@ -1630,7 +1634,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
 	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
 	{ "wps_er_start", wpa_cli_cmd_wps_er_start,
 	  cli_cmd_flag_none,
-	  "= start Wi-Fi Protected Setup External Registrar" },
+	  "[IP address] = start Wi-Fi Protected Setup External Registrar" },
 	{ "wps_er_stop", wpa_cli_cmd_wps_er_stop,
 	  cli_cmd_flag_none,
 	  "= stop Wi-Fi Protected Setup External Registrar" },

+ 2 - 2
wpa_supplicant/wps_supplicant.c

@@ -1099,14 +1099,14 @@ int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
 }
 
 
-int wpas_wps_er_start(struct wpa_supplicant *wpa_s)
+int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter)
 {
 #ifdef CONFIG_WPS_ER
 	if (wpa_s->wps_er) {
 		wps_er_refresh(wpa_s->wps_er);
 		return 0;
 	}
-	wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname);
+	wpa_s->wps_er = wps_er_init(wpa_s->wps, wpa_s->ifname, filter);
 	if (wpa_s->wps_er == NULL)
 		return -1;
 	return 0;

+ 1 - 1
wpa_supplicant/wps_supplicant.h

@@ -52,7 +52,7 @@ void wpas_wps_notify_scan_results(struct wpa_supplicant *wpa_s);
 int wpas_wps_searching(struct wpa_supplicant *wpa_s);
 int wpas_wps_scan_result_text(const u8 *ies, size_t ies_len, char *pos,
 			      char *end);
-int wpas_wps_er_start(struct wpa_supplicant *wpa_s);
+int wpas_wps_er_start(struct wpa_supplicant *wpa_s, const char *filter);
 int wpas_wps_er_stop(struct wpa_supplicant *wpa_s);
 int wpas_wps_er_add_pin(struct wpa_supplicant *wpa_s, const char *uuid,
 			const char *pin);