Granting capabilities CAP_NET_ADMIN and CAP_NET_RAW allows running hostapd and wpa_supplicant without root priviledges. Add ubus acl allowing the necessary ubus interactions for the 'network' user running hostapd/wpa_supplicant. To still allow netifd to acquire the PID of wpa_supplicant and hostapd introduce a new ubus method 'getpid' for both of them and make use of that instead of querying procd (which will not work, as procd will return the PID of ujail)
Signed-off-by: Daniel Golle <dan...@makrotopia.org> --- package/network/services/hostapd/Makefile | 9 ++++++-- .../network/services/hostapd/files/hostapd.sh | 2 +- .../network/services/hostapd/files/wpad.init | 16 ++++++++++++++ .../network/services/hostapd/files/wpad.json | 22 +++++++++++++++++++ .../services/hostapd/files/wpad_acl.json | 10 +++++++++ .../services/hostapd/src/src/ap/ubus.c | 16 ++++++++++++++ .../hostapd/src/wpa_supplicant/ubus.c | 16 ++++++++++++++ 7 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 package/network/services/hostapd/files/wpad.json create mode 100644 package/network/services/hostapd/files/wpad_acl.json diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index 61b2a548ef..386c17f99d 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=18 +PKG_RELEASE:=19 PKG_SOURCE_URL:=http://w1.fi/hostap.git PKG_SOURCE_PROTO:=git @@ -149,6 +149,7 @@ define Package/hostapd/Default TITLE:=IEEE 802.1x Authenticator URL:=http://hostap.epitest.fi/ DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + USERID:=network=101:network=101 PROVIDES:=hostapd CONFLICTS:=$(HOSTAPD_PROVIDERS) HOSTAPD_PROVIDERS+=$(1) @@ -232,6 +233,7 @@ define Package/wpad/Default SUBMENU:=WirelessAPD TITLE:=IEEE 802.1x Auth/Supplicant DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + USERID:=network=101:network=101 URL:=http://hostap.epitest.fi/ PROVIDES:=hostapd wpa-supplicant CONFLICTS:=$(HOSTAPD_PROVIDERS) $(SUPPLICANT_PROVIDERS) @@ -346,6 +348,7 @@ define Package/wpa-supplicant/Default TITLE:=WPA Supplicant URL:=http://hostap.epitest.fi/wpa_supplicant/ DEPENDS:=$(DRV_DEPENDS) +hostapd-common +libubus + USERID:=network=101:network=101 PROVIDES:=wpa-supplicant CONFLICTS:=$(SUPPLICANT_PROVIDERS) SUPPLICANT_PROVIDERS+=$(1) @@ -597,10 +600,12 @@ define Install/supplicant endef define Package/hostapd-common/install - $(INSTALL_DIR) $(1)/lib/netifd $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/capabilities $(1)/etc/rc.button $(1)/etc/hotplug.d/ieee80211 $(1)/etc/init.d $(1)/lib/netifd $(1)/usr/share/acl.d $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/netifd/hostapd.sh $(INSTALL_BIN) ./files/wpad.init $(1)/etc/init.d/wpad $(INSTALL_BIN) ./files/wps-hotplug.sh $(1)/etc/rc.button/wps + $(INSTALL_DATA) ./files/wpad_acl.json $(1)/usr/share/acl.d + $(INSTALL_DATA) ./files/wpad.json $(1)/etc/capabilities endef define Package/hostapd/install diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh index 41b04e6029..781a34028a 100644 --- a/package/network/services/hostapd/files/hostapd.sh +++ b/package/network/services/hostapd/files/hostapd.sh @@ -1365,6 +1365,7 @@ wpa_supplicant_run() { _wpa_supplicant_common "$ifname" ubus wait_for wpa_supplicant + local supplicant_pid=$(ubus call wpa_supplicant getpid | jsonfilter -l 1 -e @.pid) ubus call wpa_supplicant config_add "{ \ \"driver\": \"${_w_driver:-wext}\", \"ctrl\": \"$_rpath\", \ \"iface\": \"$ifname\", \"config\": \"$_config\" \ @@ -1376,7 +1377,6 @@ wpa_supplicant_run() { [ "$ret" != 0 ] && wireless_setup_vif_failed WPA_SUPPLICANT_FAILED - local supplicant_pid=$(ubus call service list '{"name": "wpad"}' | jsonfilter -l 1 -e "@['wpad'].instances['supplicant'].pid") wireless_add_process "$supplicant_pid" "/usr/sbin/wpa_supplicant" 1 return $ret diff --git a/package/network/services/hostapd/files/wpad.init b/package/network/services/hostapd/files/wpad.init index 3198e9801f..6c60d539a2 100644 --- a/package/network/services/hostapd/files/wpad.init +++ b/package/network/services/hostapd/files/wpad.init @@ -9,17 +9,33 @@ NAME=wpad start_service() { if [ -x "/usr/sbin/hostapd" ]; then mkdir -p /var/run/hostapd + chown network:network /var/run/hostapd procd_open_instance hostapd procd_set_param command /usr/sbin/hostapd -s -g /var/run/hostapd/global procd_set_param respawn + [ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && { + procd_add_jail netifd + procd_set_param capabilities /etc/capabilities/wpad.json + procd_set_param user network + procd_set_param group network + procd_set_param no_new_privs 1 + } procd_close_instance fi if [ -x "/usr/sbin/wpa_supplicant" ]; then mkdir -p /var/run/wpa_supplicant + chown network:network /var/run/wpa_supplicant procd_open_instance supplicant procd_set_param command /usr/sbin/wpa_supplicant -n -s -g /var/run/wpa_supplicant/global procd_set_param respawn + [ -x /sbin/ujail -a -e /etc/capabilities/wpad.json ] && { + procd_add_jail netifd + procd_set_param capabilities /etc/capabilities/wpad.json + procd_set_param user network + procd_set_param group network + procd_set_param no_new_privs 1 + } procd_close_instance fi } diff --git a/package/network/services/hostapd/files/wpad.json b/package/network/services/hostapd/files/wpad.json new file mode 100644 index 0000000000..ae3edd4fea --- /dev/null +++ b/package/network/services/hostapd/files/wpad.json @@ -0,0 +1,22 @@ +{ + "bounding": [ + "CAP_NET_RAW", + "CAP_NET_ADMIN" + ], + "effective": [ + "CAP_NET_RAW", + "CAP_NET_ADMIN" + ], + "ambient": [ + "CAP_NET_RAW", + "CAP_NET_ADMIN" + ], + "permitted": [ + "CAP_NET_RAW", + "CAP_NET_ADMIN" + ], + "inheritable": [ + "CAP_NET_RAW", + "CAP_NET_ADMIN" + ] +} diff --git a/package/network/services/hostapd/files/wpad_acl.json b/package/network/services/hostapd/files/wpad_acl.json new file mode 100644 index 0000000000..c77ccd8ea0 --- /dev/null +++ b/package/network/services/hostapd/files/wpad_acl.json @@ -0,0 +1,10 @@ +{ + "user": "network", + "access": { + "service": { + "methods": [ "event" ] + } + }, + "publish": [ "hostapd", "hostapd.*", "wpa_supplicant", "wpa_supplicant.*" ], + "send": [ "bss.*", "wps_credentials" ] +} diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 8546d2ce69..e59db00bd3 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -690,6 +690,21 @@ hostapd_config_remove(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_OK; } +static int +hostapd_getpid(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + + blob_buf_init(&b, 0); + + blobmsg_add_u32(&b, "pid", getpid()); + + ubus_send_reply(ctx, req, b.head); + + return UBUS_STATUS_OK; +} + enum { CSA_FREQ, CSA_BCN_COUNT, @@ -1363,6 +1378,7 @@ void hostapd_ubus_free_bss(struct hostapd_data *hapd) static const struct ubus_method daemon_methods[] = { UBUS_METHOD("config_add", hostapd_config_add, config_add_policy), UBUS_METHOD("config_remove", hostapd_config_remove, config_remove_policy), + UBUS_METHOD_NOARG("getpid", hostapd_getpid), }; static struct ubus_object_type daemon_object_type = diff --git a/package/network/services/hostapd/src/wpa_supplicant/ubus.c b/package/network/services/hostapd/src/wpa_supplicant/ubus.c index 4bb92a7b66..f9fa1645d7 100644 --- a/package/network/services/hostapd/src/wpa_supplicant/ubus.c +++ b/package/network/services/hostapd/src/wpa_supplicant/ubus.c @@ -311,9 +311,25 @@ wpas_config_remove(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_OK; } +static int +wpas_getpid(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + + blob_buf_init(&b, 0); + + blobmsg_add_u32(&b, "pid", getpid()); + + ubus_send_reply(ctx, req, b.head); + + return UBUS_STATUS_OK; +} + static const struct ubus_method wpas_daemon_methods[] = { UBUS_METHOD("config_add", wpas_config_add, wpas_config_add_policy), UBUS_METHOD("config_remove", wpas_config_remove, wpas_config_remove_policy), + UBUS_METHOD_NOARG("getpid", wpas_getpid), }; static struct ubus_object_type wpas_daemon_object_type = -- 2.29.2 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel