hostapd: add support for WPS pushbutton station
similar to hostapd, also add a ubus interface for wpa_supplicant
which will allow handling WPS push-button just as it works for hostapd.
In order to have wpa_supplicant running without any network
configuration (so you can use it to retrieve credentials via WPS),
configure wifi-iface in /etc/config/wireless:
  config wifi-iface 'default_radio0'
      option device 'radio0'
      option network 'wwan'
      option mode 'sta'
      option encryption 'wps'
This section will automatically be edited if credentials have
successfully been acquired via WPS.
Size difference (mips_24kc): roughly +4kb for the 'full' variants of
wpa_supplicant and wpad which do support WPS.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
			
			
This commit is contained in:
		| @@ -7,7 +7,7 @@ | |||||||
| include $(TOPDIR)/rules.mk | include $(TOPDIR)/rules.mk | ||||||
|  |  | ||||||
| PKG_NAME:=hostapd | PKG_NAME:=hostapd | ||||||
| PKG_RELEASE:=6 | PKG_RELEASE:=7 | ||||||
|  |  | ||||||
| PKG_SOURCE_URL:=http://w1.fi/hostap.git | PKG_SOURCE_URL:=http://w1.fi/hostap.git | ||||||
| PKG_SOURCE_PROTO:=git | PKG_SOURCE_PROTO:=git | ||||||
| @@ -296,7 +296,7 @@ define Package/wpa-supplicant/Default | |||||||
|   CATEGORY:=Network |   CATEGORY:=Network | ||||||
|   TITLE:=WPA Supplicant |   TITLE:=WPA Supplicant | ||||||
|   URL:=http://hostap.epitest.fi/wpa_supplicant/ |   URL:=http://hostap.epitest.fi/wpa_supplicant/ | ||||||
|   DEPENDS:=$(DRV_DEPENDS) |   DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus | ||||||
|   PROVIDES:=wpa-supplicant |   PROVIDES:=wpa-supplicant | ||||||
|   CONFLICTS:=$(SUPPLICANT_PROVIDERS) |   CONFLICTS:=$(SUPPLICANT_PROVIDERS) | ||||||
|   SUPPLICANT_PROVIDERS+=$(1) |   SUPPLICANT_PROVIDERS+=$(1) | ||||||
| @@ -444,10 +444,7 @@ TARGET_CPPFLAGS := \ | |||||||
| 	$(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) | 	$(if $(CONFIG_WPA_MSG_MIN_PRIORITY),-DCONFIG_MSG_MIN_PRIORITY=$(CONFIG_WPA_MSG_MIN_PRIORITY)) | ||||||
|  |  | ||||||
| TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto | TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto | ||||||
| TARGET_LDFLAGS += -Wl,--gc-sections -flto=jobserver -fuse-linker-plugin | TARGET_LDFLAGS += -Wl,--gc-sections -flto=jobserver -fuse-linker-plugin -lubox -lubus | ||||||
| ifeq ($(findstring supplicant,$(BUILD_VARIANT)),) |  | ||||||
|   TARGET_LDFLAGS += -lubox -lubus |  | ||||||
| endif |  | ||||||
|  |  | ||||||
| ifdef CONFIG_PACKAGE_kmod-cfg80211 | ifdef CONFIG_PACKAGE_kmod-cfg80211 | ||||||
|   TARGET_LDFLAGS += -lm -lnl-tiny |   TARGET_LDFLAGS += -lm -lnl-tiny | ||||||
| @@ -534,8 +531,9 @@ define Install/supplicant | |||||||
| endef | endef | ||||||
|  |  | ||||||
| define Package/hostapd-common/install | define Package/hostapd-common/install | ||||||
| 	$(INSTALL_DIR) $(1)/lib/netifd | 	$(INSTALL_DIR) $(1)/lib/netifd $(1)/etc/rc.button | ||||||
| 	$(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh | 	$(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh | ||||||
|  | 	$(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define Package/hostapd/install | define Package/hostapd/install | ||||||
| @@ -549,9 +547,8 @@ Package/hostapd-wolfssl/install = $(Package/hostapd/install) | |||||||
|  |  | ||||||
| ifneq ($(LOCAL_TYPE),supplicant) | ifneq ($(LOCAL_TYPE),supplicant) | ||||||
|   define Package/hostapd-utils/install |   define Package/hostapd-utils/install | ||||||
| 	$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/rc.button | 	$(INSTALL_DIR) $(1)/usr/sbin | ||||||
| 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli $(1)/usr/sbin/ | 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd_cli $(1)/usr/sbin/ | ||||||
| 	$(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps |  | ||||||
|   endef |   endef | ||||||
| endif | endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -762,6 +762,9 @@ wpa_supplicant_add_network() { | |||||||
| 			hostapd_append_wep_key network_data | 			hostapd_append_wep_key network_data | ||||||
| 			append network_data "wep_tx_keyidx=$wep_keyidx" "$N$T" | 			append network_data "wep_tx_keyidx=$wep_keyidx" "$N$T" | ||||||
| 		;; | 		;; | ||||||
|  | 		wps) | ||||||
|  | 			key_mgmt='WPS' | ||||||
|  | 		;; | ||||||
| 		psk|sae|psk-sae) | 		psk|sae|psk-sae) | ||||||
| 			local passphrase | 			local passphrase | ||||||
|  |  | ||||||
| @@ -869,7 +872,10 @@ wpa_supplicant_add_network() { | |||||||
| 		append network_data "mcast_rate=$mc_rate" "$N$T" | 		append network_data "mcast_rate=$mc_rate" "$N$T" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cat >> "$_config" <<EOF | 	if [ "$key_mgnt" = "WPS" ]; then | ||||||
|  | 		echo "wps_cred_processing=1" >> "$_config" | ||||||
|  | 	else | ||||||
|  | 		cat >> "$_config" <<EOF | ||||||
| network={ | network={ | ||||||
| 	$scan_ssid | 	$scan_ssid | ||||||
| 	ssid="$ssid" | 	ssid="$ssid" | ||||||
| @@ -877,6 +883,7 @@ network={ | |||||||
| 	$network_data | 	$network_data | ||||||
| } | } | ||||||
| EOF | EOF | ||||||
|  | 	fi | ||||||
| 	return 0 | 	return 0 | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -591,3 +591,8 @@ CONFIG_NO_RANDOM_POOL=y | |||||||
| # Opportunistic Wireless Encryption (OWE) | # Opportunistic Wireless Encryption (OWE) | ||||||
| # Experimental implementation of draft-harkins-owe-07.txt | # Experimental implementation of draft-harkins-owe-07.txt | ||||||
| #CONFIG_OWE=y | #CONFIG_OWE=y | ||||||
|  |  | ||||||
|  | # uBus IPC/RPC System | ||||||
|  | # Services can connect to the bus and provide methods | ||||||
|  | # that can be called by other services or clients. | ||||||
|  | CONFIG_UBUS=y | ||||||
|   | |||||||
| @@ -593,3 +593,8 @@ CONFIG_IBSS_RSN=y | |||||||
| # Opportunistic Wireless Encryption (OWE) | # Opportunistic Wireless Encryption (OWE) | ||||||
| # Experimental implementation of draft-harkins-owe-07.txt | # Experimental implementation of draft-harkins-owe-07.txt | ||||||
| #CONFIG_OWE=y | #CONFIG_OWE=y | ||||||
|  |  | ||||||
|  | # uBus IPC/RPC System | ||||||
|  | # Services can connect to the bus and provide methods | ||||||
|  | # that can be called by other services or clients. | ||||||
|  | CONFIG_UBUS=y | ||||||
|   | |||||||
| @@ -593,3 +593,8 @@ CONFIG_NO_RANDOM_POOL=y | |||||||
| # Opportunistic Wireless Encryption (OWE) | # Opportunistic Wireless Encryption (OWE) | ||||||
| # Experimental implementation of draft-harkins-owe-07.txt | # Experimental implementation of draft-harkins-owe-07.txt | ||||||
| #CONFIG_OWE=y | #CONFIG_OWE=y | ||||||
|  |  | ||||||
|  | # uBus IPC/RPC System | ||||||
|  | # Services can connect to the bus and provide methods | ||||||
|  | # that can be called by other services or clients. | ||||||
|  | CONFIG_UBUS=y | ||||||
|   | |||||||
| @@ -593,3 +593,8 @@ CONFIG_IBSS_RSN=y | |||||||
| # Opportunistic Wireless Encryption (OWE) | # Opportunistic Wireless Encryption (OWE) | ||||||
| # Experimental implementation of draft-harkins-owe-07.txt | # Experimental implementation of draft-harkins-owe-07.txt | ||||||
| #CONFIG_OWE=y | #CONFIG_OWE=y | ||||||
|  |  | ||||||
|  | # uBus IPC/RPC System | ||||||
|  | # Services can connect to the bus and provide methods | ||||||
|  | # that can be called by other services or clients. | ||||||
|  | CONFIG_UBUS=y | ||||||
|   | |||||||
| @@ -1,11 +1,56 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
|  |  | ||||||
| if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then | wps_catch_credentials() { | ||||||
| 	cd /var/run/hostapd | 	local iface ifaces ifc ifname ssid encryption key radio radios | ||||||
| 	for socket in *; do | 	local found=0 | ||||||
| 		[ -S "$socket" ] || continue |  | ||||||
| 		hostapd_cli -i "$socket" wps_pbc | 	. /usr/share/libubox/jshn.sh | ||||||
|  | 	ubus -S -t 30 listen wps_credentials | while read creds; do | ||||||
|  | 		json_init | ||||||
|  | 		json_load "$creds" | ||||||
|  | 		json_select wps_credentials || continue | ||||||
|  | 		json_get_vars ifname ssid key encryption | ||||||
|  | 		local ifcname="$ifname" | ||||||
|  | 		json_init | ||||||
|  | 		json_load "$(ubus -S call network.wireless status)" | ||||||
|  | 		json_get_keys radios | ||||||
|  | 		for radio in $radios; do | ||||||
|  | 			json_select $radio | ||||||
|  | 			json_select interfaces | ||||||
|  | 			json_get_keys ifaces | ||||||
|  | 			for ifc in $ifaces; do | ||||||
|  | 				json_select $ifc | ||||||
|  | 				json_get_vars ifname | ||||||
|  | 				[ "$ifname" = "$ifcname" ] && { | ||||||
|  | 					ubus -S call uci set "{\"config\":\"wireless\", \"type\":\"wifi-iface\",		\ | ||||||
|  | 								\"match\": { \"device\": \"$radio\", \"encryption\": \"wps\" },	\ | ||||||
|  | 								\"values\": { \"encryption\": \"$encryption\", 			\ | ||||||
|  | 										\"ssid\": \"$ssid\", 				\ | ||||||
|  | 										\"key\": \"$key\" } }" | ||||||
|  | 					ubus -S call uci commit '{"config": "wireless"}' | ||||||
|  | 					ubus -S call uci apply | ||||||
|  | 				} | ||||||
|  | 				json_select .. | ||||||
|  | 			done | ||||||
|  | 			json_select .. | ||||||
|  | 			json_select .. | ||||||
|  | 		done | ||||||
| 	done | 	done | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if [ "$ACTION" = "pressed" -a "$BUTTON" = "wps" ]; then | ||||||
|  | 	wps_done=0 | ||||||
|  | 	ubusobjs="$( ubus -S list hostapd.* )" | ||||||
|  | 	for ubusobj in $ubusobjs; do | ||||||
|  | 		ubus -S call $ubusobj wps_start && wps_done=1 | ||||||
|  | 	done | ||||||
|  | 	[ $wps_done = 0 ] || return 0 | ||||||
|  | 	wps_done=0 | ||||||
|  | 	ubusobjs="$( ubus -S list wpa_supplicant.* )" | ||||||
|  | 	for ubusobj in $ubusobjs; do | ||||||
|  | 		ubus -S call $ubusobj wps_start && wps_done=1 | ||||||
|  | 	done | ||||||
|  | 	[ $wps_done = 0 ] || wps_catch_credentials & | ||||||
| fi | fi | ||||||
|  |  | ||||||
| return 0 | return 0 | ||||||
|   | |||||||
| @@ -341,3 +341,85 @@ | |||||||
|  } |  } | ||||||
|   |   | ||||||
|   |   | ||||||
|  | --- a/wpa_supplicant/Makefile | ||||||
|  | +++ b/wpa_supplicant/Makefile | ||||||
|  | @@ -189,6 +189,12 @@ ifdef CONFIG_EAPOL_TEST | ||||||
|  |  CFLAGS += -Werror -DEAPOL_TEST | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  | +ifdef CONFIG_UBUS | ||||||
|  | +CFLAGS += -DUBUS_SUPPORT | ||||||
|  | +OBJS += ubus.o | ||||||
|  | +LIBS += -lubox -lubus | ||||||
|  | +endif | ||||||
|  | + | ||||||
|  |  ifdef CONFIG_CODE_COVERAGE | ||||||
|  |  CFLAGS += -O0 -fprofile-arcs -ftest-coverage | ||||||
|  |  LIBS += -lgcov | ||||||
|  | @@ -915,6 +921,9 @@ endif | ||||||
|  |  ifdef CONFIG_IEEE80211AX | ||||||
|  |  OBJS += ../src/ap/ieee802_11_he.o | ||||||
|  |  endif | ||||||
|  | +ifdef CONFIG_UBUS | ||||||
|  | +OBJS += ../src/ap/ubus.o | ||||||
|  | +endif | ||||||
|  |  endif | ||||||
|  |  ifdef CONFIG_WNM_AP | ||||||
|  |  CFLAGS += -DCONFIG_WNM_AP | ||||||
|  | --- a/wpa_supplicant/wpa_supplicant.c | ||||||
|  | +++ b/wpa_supplicant/wpa_supplicant.c | ||||||
|  | @@ -5998,6 +5998,8 @@ struct wpa_supplicant * wpa_supplicant_a | ||||||
|  |  	} | ||||||
|  |  #endif /* CONFIG_P2P */ | ||||||
|  |   | ||||||
|  | +	wpas_ubus_add_bss(wpa_s); | ||||||
|  | + | ||||||
|  |  	return wpa_s; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -6024,6 +6026,8 @@ int wpa_supplicant_remove_iface(struct w | ||||||
|  |  	struct wpa_supplicant *parent = wpa_s->parent; | ||||||
|  |  #endif /* CONFIG_MESH */ | ||||||
|  |   | ||||||
|  | +	wpas_ubus_free_bss(wpa_s); | ||||||
|  | + | ||||||
|  |  	/* Remove interface from the global list of interfaces */ | ||||||
|  |  	prev = global->ifaces; | ||||||
|  |  	if (prev == wpa_s) { | ||||||
|  | --- a/wpa_supplicant/wpa_supplicant_i.h | ||||||
|  | +++ b/wpa_supplicant/wpa_supplicant_i.h | ||||||
|  | @@ -17,6 +17,7 @@ | ||||||
|  |  #include "wps/wps_defs.h" | ||||||
|  |  #include "config_ssid.h" | ||||||
|  |  #include "wmm_ac.h" | ||||||
|  | +#include "ubus.h" | ||||||
|  |   | ||||||
|  |  extern const char *const wpa_supplicant_version; | ||||||
|  |  extern const char *const wpa_supplicant_license; | ||||||
|  | @@ -500,6 +501,7 @@ struct wpa_supplicant { | ||||||
|  |  	unsigned char own_addr[ETH_ALEN]; | ||||||
|  |  	unsigned char perm_addr[ETH_ALEN]; | ||||||
|  |  	char ifname[100]; | ||||||
|  | +	struct wpas_ubus_bss ubus; | ||||||
|  |  #ifdef CONFIG_MATCH_IFACE | ||||||
|  |  	int matched; | ||||||
|  |  #endif /* CONFIG_MATCH_IFACE */ | ||||||
|  | --- a/wpa_supplicant/wps_supplicant.c | ||||||
|  | +++ b/wpa_supplicant/wps_supplicant.c | ||||||
|  | @@ -33,6 +33,7 @@ | ||||||
|  |  #include "p2p/p2p.h" | ||||||
|  |  #include "p2p_supplicant.h" | ||||||
|  |  #include "wps_supplicant.h" | ||||||
|  | +#include "ubus.h" | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG | ||||||
|  | @@ -388,6 +389,8 @@ static int wpa_supplicant_wps_cred(void | ||||||
|  |  	wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", | ||||||
|  |  			cred->cred_attr, cred->cred_attr_len); | ||||||
|  |   | ||||||
|  | +	wpas_ubus_notify(wpa_s, cred); | ||||||
|  | + | ||||||
|  |  	if (wpa_s->conf->wps_cred_processing == 1) | ||||||
|  |  		return 0; | ||||||
|  |   | ||||||
|   | |||||||
							
								
								
									
										249
									
								
								package/network/services/hostapd/src/wpa_supplicant/ubus.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								package/network/services/hostapd/src/wpa_supplicant/ubus.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | |||||||
|  | /* | ||||||
|  |  * wpa_supplicant / ubus support | ||||||
|  |  * Copyright (c) 2018, Daniel Golle <daniel@makrotopia.org> | ||||||
|  |  * Copyright (c) 2013, Felix Fietkau <nbd@nbd.name> | ||||||
|  |  * | ||||||
|  |  * This software may be distributed under the terms of the BSD license. | ||||||
|  |  * See README for more details. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "utils/includes.h" | ||||||
|  | #include "utils/common.h" | ||||||
|  | #include "utils/eloop.h" | ||||||
|  | #include "utils/wpabuf.h" | ||||||
|  | #include "common/ieee802_11_defs.h" | ||||||
|  | #include "wpa_supplicant_i.h" | ||||||
|  | #include "wps_supplicant.h" | ||||||
|  | #include "ubus.h" | ||||||
|  |  | ||||||
|  | static struct ubus_context *ctx; | ||||||
|  | static struct blob_buf b; | ||||||
|  | static int ctx_ref; | ||||||
|  |  | ||||||
|  | static inline struct wpa_supplicant *get_wpas_from_object(struct ubus_object *obj) | ||||||
|  | { | ||||||
|  | 	return container_of(obj, struct wpa_supplicant, ubus.obj); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ubus_receive(int sock, void *eloop_ctx, void *sock_ctx) | ||||||
|  | { | ||||||
|  | 	struct ubus_context *ctx = eloop_ctx; | ||||||
|  | 	ubus_handle_event(ctx); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void ubus_reconnect_timeout(void *eloop_data, void *user_ctx) | ||||||
|  | { | ||||||
|  | 	if (ubus_reconnect(ctx, NULL)) { | ||||||
|  | 		eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void wpas_ubus_connection_lost(struct ubus_context *ctx) | ||||||
|  | { | ||||||
|  | 	eloop_unregister_read_sock(ctx->sock.fd); | ||||||
|  | 	eloop_register_timeout(1, 0, ubus_reconnect_timeout, ctx, NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static bool wpas_ubus_init(void) | ||||||
|  | { | ||||||
|  | 	if (ctx) | ||||||
|  | 		return true; | ||||||
|  |  | ||||||
|  | 	ctx = ubus_connect(NULL); | ||||||
|  | 	if (!ctx) | ||||||
|  | 		return false; | ||||||
|  |  | ||||||
|  | 	ctx->connection_lost = wpas_ubus_connection_lost; | ||||||
|  | 	eloop_register_read_sock(ctx->sock.fd, ubus_receive, ctx, NULL); | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void wpas_ubus_ref_inc(void) | ||||||
|  | { | ||||||
|  | 	ctx_ref++; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void wpas_ubus_ref_dec(void) | ||||||
|  | { | ||||||
|  | 	ctx_ref--; | ||||||
|  | 	if (!ctx) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if (ctx_ref) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	eloop_unregister_read_sock(ctx->sock.fd); | ||||||
|  | 	ubus_free(ctx); | ||||||
|  | 	ctx = NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | wpas_bss_get_features(struct ubus_context *ctx, struct ubus_object *obj, | ||||||
|  | 			struct ubus_request_data *req, const char *method, | ||||||
|  | 			struct blob_attr *msg) | ||||||
|  | { | ||||||
|  | 	struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); | ||||||
|  |  | ||||||
|  | 	blob_buf_init(&b, 0); | ||||||
|  | 	blobmsg_add_u8(&b, "ht_supported", ht_supported(wpa_s->hw.modes)); | ||||||
|  | 	blobmsg_add_u8(&b, "vht_supported", vht_supported(wpa_s->hw.modes)); | ||||||
|  | 	ubus_send_reply(ctx, req, b.head); | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_WPS | ||||||
|  | static int | ||||||
|  | wpas_bss_wps_start(struct ubus_context *ctx, struct ubus_object *obj, | ||||||
|  | 			struct ubus_request_data *req, const char *method, | ||||||
|  | 			struct blob_attr *msg) | ||||||
|  | { | ||||||
|  | 	int rc; | ||||||
|  | 	struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); | ||||||
|  |  | ||||||
|  | 	rc = wpas_wps_start_pbc(wpa_s, NULL, 0); | ||||||
|  |  | ||||||
|  | 	if (rc != 0) | ||||||
|  | 		return UBUS_STATUS_NOT_SUPPORTED; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | wpas_bss_wps_cancel(struct ubus_context *ctx, struct ubus_object *obj, | ||||||
|  | 			struct ubus_request_data *req, const char *method, | ||||||
|  | 			struct blob_attr *msg) | ||||||
|  | { | ||||||
|  | 	int rc; | ||||||
|  | 	struct wpa_supplicant *wpa_s = get_wpas_from_object(obj); | ||||||
|  |  | ||||||
|  | 	rc = wpas_wps_cancel(wpa_s); | ||||||
|  |  | ||||||
|  | 	if (rc != 0) | ||||||
|  | 		return UBUS_STATUS_NOT_SUPPORTED; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | static const struct ubus_method bss_methods[] = { | ||||||
|  | #ifdef CONFIG_WPS | ||||||
|  | 	UBUS_METHOD_NOARG("wps_start", wpas_bss_wps_start), | ||||||
|  | 	UBUS_METHOD_NOARG("wps_cancel", wpas_bss_wps_cancel), | ||||||
|  | #endif | ||||||
|  | 	UBUS_METHOD_NOARG("get_features", wpas_bss_get_features), | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static struct ubus_object_type bss_object_type = | ||||||
|  | 	UBUS_OBJECT_TYPE("wpas_bss", bss_methods); | ||||||
|  |  | ||||||
|  | void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | 	struct ubus_object *obj = &wpa_s->ubus.obj; | ||||||
|  | 	char *name; | ||||||
|  | 	int ret; | ||||||
|  |  | ||||||
|  | 	if (!wpas_ubus_init()) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if (asprintf(&name, "wpa_supplicant.%s", wpa_s->ifname) < 0) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	obj->name = name; | ||||||
|  | 	obj->type = &bss_object_type; | ||||||
|  | 	obj->methods = bss_object_type.methods; | ||||||
|  | 	obj->n_methods = bss_object_type.n_methods; | ||||||
|  | 	ret = ubus_add_object(ctx, obj); | ||||||
|  | 	wpas_ubus_ref_inc(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | 	struct ubus_object *obj = &wpa_s->ubus.obj; | ||||||
|  | 	char *name = (char *) obj->name; | ||||||
|  |  | ||||||
|  | 	if (!ctx) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if (obj->id) { | ||||||
|  | 		ubus_remove_object(ctx, obj); | ||||||
|  | 		wpas_ubus_ref_dec(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	free(name); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_WPS | ||||||
|  | void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred) | ||||||
|  | { | ||||||
|  | 	u16 auth_type; | ||||||
|  | 	char *ifname, *encryption, *ssid, *key; | ||||||
|  | 	size_t ifname_len; | ||||||
|  |  | ||||||
|  | 	if (!cred) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	auth_type = cred->auth_type; | ||||||
|  |  | ||||||
|  | 	if (auth_type == (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) | ||||||
|  | 		auth_type = WPS_AUTH_WPA2PSK; | ||||||
|  |  | ||||||
|  | 	if (auth_type != WPS_AUTH_OPEN && | ||||||
|  | 	    auth_type != WPS_AUTH_WPAPSK && | ||||||
|  | 	    auth_type != WPS_AUTH_WPA2PSK) { | ||||||
|  | 		wpa_printf(MSG_DEBUG, "WPS: Ignored credentials for " | ||||||
|  | 			   "unsupported authentication type 0x%x", | ||||||
|  | 			   auth_type); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (auth_type == WPS_AUTH_WPAPSK || auth_type == WPS_AUTH_WPA2PSK) { | ||||||
|  | 		if (cred->key_len < 8 || cred->key_len > 2 * PMK_LEN) { | ||||||
|  | 			wpa_printf(MSG_ERROR, "WPS: Reject PSK credential with " | ||||||
|  | 				   "invalid Network Key length %lu", | ||||||
|  | 				   (unsigned long) cred->key_len); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	blob_buf_init(&b, 0); | ||||||
|  |  | ||||||
|  | 	ifname_len = strlen(wpa_s->ifname); | ||||||
|  | 	ifname = blobmsg_alloc_string_buffer(&b, "ifname", ifname_len + 1); | ||||||
|  | 	memcpy(ifname, wpa_s->ifname, ifname_len + 1); | ||||||
|  | 	ifname[ifname_len] = '\0'; | ||||||
|  | 	blobmsg_add_string_buffer(&b); | ||||||
|  |  | ||||||
|  | 	switch (auth_type) { | ||||||
|  | 		case WPS_AUTH_WPA2PSK: | ||||||
|  | 			encryption = "psk2"; | ||||||
|  | 			break; | ||||||
|  | 		case WPS_AUTH_WPAPSK: | ||||||
|  | 			encryption = "psk"; | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			encryption = "none"; | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	blobmsg_add_string(&b, "encryption", encryption); | ||||||
|  |  | ||||||
|  | 	ssid = blobmsg_alloc_string_buffer(&b, "ssid", cred->ssid_len + 1); | ||||||
|  | 	memcpy(ssid, cred->ssid, cred->ssid_len); | ||||||
|  | 	ssid[cred->ssid_len] = '\0'; | ||||||
|  | 	blobmsg_add_string_buffer(&b); | ||||||
|  |  | ||||||
|  | 	if (cred->key_len > 0) { | ||||||
|  | 		key = blobmsg_alloc_string_buffer(&b, "key", cred->key_len + 1); | ||||||
|  | 		memcpy(key, cred->key, cred->key_len); | ||||||
|  | 		key[cred->key_len] = '\0'; | ||||||
|  | 		blobmsg_add_string_buffer(&b); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | //	ubus_notify(ctx, &wpa_s->ubus.obj, "wps_credentials", b.head, -1); | ||||||
|  | 	ubus_send_event(ctx, "wps_credentials", b.head); | ||||||
|  | } | ||||||
|  | #endif /* CONFIG_WPS */ | ||||||
							
								
								
									
										53
									
								
								package/network/services/hostapd/src/wpa_supplicant/ubus.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								package/network/services/hostapd/src/wpa_supplicant/ubus.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | /* | ||||||
|  |  * wpa_supplicant / ubus support | ||||||
|  |  * Copyright (c) 2018, Daniel Golle <daniel@makrotopia.org> | ||||||
|  |  * Copyright (c) 2013, Felix Fietkau <nbd@nbd.name> | ||||||
|  |  * | ||||||
|  |  * This software may be distributed under the terms of the BSD license. | ||||||
|  |  * See README for more details. | ||||||
|  |  */ | ||||||
|  | #ifndef __WPAS_UBUS_H | ||||||
|  | #define __WPAS_UBUS_H | ||||||
|  |  | ||||||
|  | struct wpa_supplicant; | ||||||
|  | #include "wps_supplicant.h" | ||||||
|  |  | ||||||
|  | #ifdef UBUS_SUPPORT | ||||||
|  | #include <libubus.h> | ||||||
|  |  | ||||||
|  | struct wpas_ubus_bss { | ||||||
|  | 	struct ubus_object obj; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s); | ||||||
|  | void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s); | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_WPS | ||||||
|  | void wpas_ubus_notify(struct wpa_supplicant *wpa_s, const struct wps_credential *cred); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #else | ||||||
|  | struct wpas_ubus_bss {}; | ||||||
|  |  | ||||||
|  | static inline void wpas_ubus_add_iface(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ubus_free_iface(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ubus_add_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ubus_free_bss(struct wpa_supplicant *wpa_s) | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline void wpas_ubus_notify(struct wpa_supplicant *wpa_s, struct wps_credential *cred) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user
	 Daniel Golle
					Daniel Golle