Compare commits

..

2 Commits

Author SHA1 Message Date
Sukru Senli
bb7b1cf0b8 rename mosquitto-auth-shadow->mosquitto-auth-plugin 2025-10-28 09:26:41 +01:00
Sukru Senli
ff24c2e1fa mosquitto-auth-shadow: Add per-user subnet-based access control to mosquitto auth plugin
- Implement whitelist/blacklist subnet filtering for MQTT users
- Add support for CIDR notation (e.g., 192.168.1.0/24)
- Parse subnet ACL files via auth_opt_subnet_acl_file option
- Support multiple subnets per user (up to 32 allow + 32 deny rules)
- Deny rules take precedence over allow rules
- Localhost (127.0.0.1/::1) always allowed
- IPv6 addresses gracefully deferred to other ACL handlers
- Backward compatible: users without subnet rules are not affected
- Configuration format: 'subnet allow|deny <username> <cidr>'
- Integrates with existing shadow/PAM authentication and topic ACLs
2025-10-28 00:38:03 +01:00
40 changed files with 1607 additions and 1121 deletions

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bbfdm
PKG_VERSION:=1.18.12
PKG_VERSION:=1.18.10
USE_LOCAL:=0
ifneq ($(USE_LOCAL),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bbfdm.git
PKG_SOURCE_VERSION:=adfdb54d625b952c533670f093dae008782ff56a
PKG_SOURCE_VERSION:=1a86b8a4432a2c3a9d41a9b18ccfc830bd0083cb
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -149,10 +149,10 @@ define Package/bbfdmd/install
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
$(INSTALL_BIN) ./files/etc/hotplug.d/iface/85-bbfdm-sysctl $(1)/etc/hotplug.d/iface/85-bbfdm-sysctl
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/bbf $(1)/lib/upgrade/keep.d/bbf
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-fix-bbfdmd-enabled-option $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/ruleng.bbfdm $(1)/etc/uci-defaults

View File

@@ -5,7 +5,6 @@ STOP=05
USE_PROCD=1
PROG=/usr/sbin/dm-service
DM_AGENT_PROG=/usr/sbin/dm-agent
BBFDM_MICROSERVICE_DIR="/etc/bbfdm/services"
@@ -25,8 +24,7 @@ validate_bbfdm_micro_service_section()
_add_microservice()
{
local name path loglevel
local enable enable_core unified_daemon dm_framework
local daemon_prog
local enable enable_core unified_daemon
# Check enable from micro-service
path="${1}"
@@ -49,25 +47,14 @@ _add_microservice()
return 0
fi
json_get_var dm_framework dm-framework 0
if [ "${dm_framework}" -eq "1" ] || [ "${dm_framework}" = "true" ]; then
daemon_prog="${DM_AGENT_PROG}"
else
daemon_prog="${PROG}"
fi
json_select config
json_get_var loglevel loglevel 4
procd_open_instance "${name}"
procd_set_param command ${daemon_prog}
# Only add parameters for dm-service, not for dm-agent
if [ "${daemon_prog}" = "${PROG}" ]; then
procd_append_param command -m "${name}"
procd_append_param command -l "${loglevel}"
fi
procd_set_param command ${PROG}
procd_append_param command -m "${name}"
procd_append_param command -l "${loglevel}"
if [ "${enable_core}" -eq "1" ]; then
procd_set_param limits core="unlimited"

17
bridgemngr/Config.in Normal file
View File

@@ -0,0 +1,17 @@
if PACKAGE_bridgemngr
config BRIDGEMNGR_BRIDGE_VLAN
bool "Use bridge-vlan backend"
help
Set this option to use bridge-vlan as backend for VLAN objects.
config BRIDGEMNGR_BRIDGE_VENDOR_EXT
bool "Use bridge BBF vendor extensions"
default y
help
Set this option to use bridge BBF vendor extensions.
config BRIDGEMNGR_BRIDGE_VENDOR_PREFIX
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""
endif

75
bridgemngr/Makefile Normal file
View File

@@ -0,0 +1,75 @@
#
# Copyright (C) 2020-2024 iopsys
#
include $(TOPDIR)/rules.mk
PKG_NAME:=bridgemngr
PKG_VERSION:=1.1.4
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/bridgemngr.git
PKG_SOURCE_VERSION:=e5e0d9adfc919c25d88a867d42a9c500cb09f834
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
PKG_LICENSE:=GPL-2.0-only
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include ../bbfdm/bbfdm.mk
define Package/bridgemngr
CATEGORY:=Utilities
TITLE:=Bridge Manager
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
endef
define Package/bridgemngr/description
Package to add Device.Bridging. data model support.
endef
define Package/$(PKG_NAME)/config
source "$(SOURCE)/Config.in"
endef
MAKE_PATH:=src
ifeq ($(CONFIG_BRIDGEMNGR_BRIDGE_VENDOR_PREFIX),"")
VENDOR_PREFIX = $(CONFIG_BBF_VENDOR_PREFIX)
else
VENDOR_PREFIX = $(CONFIG_BRIDGEMNGR_BRIDGE_VENDOR_PREFIX)
endif
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(VENDOR_PREFIX)\\\"
ifeq ($(CONFIG_BRIDGEMNGR_BRIDGE_VLAN),y)
TARGET_CFLAGS += -DBRIDGE_VLAN_BACKEND
endif
define Package/bridgemngr/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
$(BBFDM_INSTALL_MS_DM) $(PKG_BUILD_DIR)/src/libbridgemngr.so $(1) $(PKG_NAME)
ifeq ($(CONFIG_BRIDGEMNGR_BRIDGE_VENDOR_EXT), y)
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/src/libbridgeext.so $(1) $(PKG_NAME) 10
$(BBFDM_INSTALL_MS_PLUGIN) -v ${VENDOR_PREFIX} ./files/VLAN_Filtering_Extension.json $(1) $(PKG_NAME) 11
endif
$(INSTALL_BIN) ./files/etc/init.d/bridging $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/config/bridging $(1)/etc/config/
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) ~/git/bridgemngr/* $(PKG_BUILD_DIR)/
endef
endif
$(eval $(call BuildPackage,bridgemngr))

View File

@@ -2,7 +2,6 @@
"daemon": {
"enable": "1",
"service_name": "bridgemngr",
"dm-framework": true,
"unified_daemon": false,
"services": [
{

View File

@@ -0,0 +1,31 @@
{
"json_plugin_version": 2,
"Device.Bridging.Bridge.{i}.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": true,
"array": true,
"{BBF_VENDOR_PREFIX}VLANFiltering": {
"type": "boolean",
"read": true,
"write": true,
"protocols": [
"cwmp",
"usp"
],
"datatype": "boolean",
"description": "Enable or disable VLAN Filtering on this bridge.",
"mapping": [
{
"data": "@Parent",
"type": "uci_sec",
"key": "vlan_filtering"
}
]
}
}
}

View File

@@ -77,7 +77,6 @@ handle_ebtables_rule() {
}
start_service() {
ubus -t 30 wait_for network.device uci
config_load bridging
config_foreach handle_ebtables_chain chain
config_foreach handle_ebtables_rule rule

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=decollector
PKG_VERSION:=6.2.2.7
PKG_VERSION:=6.2.2.4
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=9d1399c09f55da14a8de55828ba57c0e296ce62f
PKG_SOURCE_VERSION:=b632ef13fed94c683d65dedcbc91afdee9ee980f
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/decollector.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip

View File

@@ -1,207 +0,0 @@
#
# Copyright (c) 2023 Genexis B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dm-framework
PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/lcm/dm-framework.git
PKG_SOURCE_VERSION:=37dade4a2df6eaf6a4291a06ac776641ed81a79e
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
# Build directories for each component
DATAMODELS_BUILD_DIR:=$(PKG_BUILD_DIR)/datamodels-build
DMAPI_BUILD_DIR:=$(PKG_BUILD_DIR)/dm-api-build
DMAGENT_BUILD_DIR:=$(PKG_BUILD_DIR)/dm-agent-build
include $(INCLUDE_DIR)/package.mk
-include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
#
# Datamodels Package Definition
#
define Package/datamodels
SECTION:=utils
CATEGORY:=Genexis
TITLE:=dm-framework Datamodel
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/datamodels/description
This package contains dm-framework datamodel.
endef
#
# DM-API Package Definition
#
define Package/dm-api
CATEGORY:=Genexis
TITLE:=dm-api
PKG_BUILD_DEPENDS:=datamodels
DEPENDS:=+libsqlite3 \
+libjson-c +libstdcpp +quickjs \
+libubus +libubox +libuci
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/dm-api/description
This package contains api for the dm-framework
endef
#
# DM-Agent Package Definition
#
define Package/dm-agent
DEPENDS:=+dm-api +datamodels +libubox +libubus +ubus
CATEGORY:=Genexis
TITLE:=dm-framework agent
URL:=http://www.genexis.eu
PKG_LICENSE:=GENEXIS
PKG_LICENSE_URL:=
endef
define Package/dm-agent/description
This package contains dm-framework agent.
endef
#
# Build Preparation
#
define Build/Prepare
$(call Build/Prepare/Default)
# Prepare datamodels
mkdir -p $(DATAMODELS_BUILD_DIR)
$(CP) -rf $(PKG_BUILD_DIR)/datamodels/* $(DATAMODELS_BUILD_DIR)/
# Copy scripts from top-level scripts directory
mkdir -p $(DATAMODELS_BUILD_DIR)/scripts
$(CP) -rf $(PKG_BUILD_DIR)/scripts/* $(DATAMODELS_BUILD_DIR)/scripts/
cd $(DATAMODELS_BUILD_DIR); \
npm install better-sqlite3 quickjs && \
node ./scripts/json2code.js && \
node ./scripts/qjs-handlers-validate.js
# Prepare dm-api
mkdir -p $(DMAPI_BUILD_DIR)
$(CP) -rf $(PKG_BUILD_DIR)/dm-api/* $(DMAPI_BUILD_DIR)/
# Prepare dm-agent
mkdir -p $(DMAGENT_BUILD_DIR)
$(CP) -rf $(PKG_BUILD_DIR)/dm-agent/* $(DMAGENT_BUILD_DIR)/
endef
TARGET_CFLAGS += $(FPIC)
#
# Build Compilation
#
define Build/Compile
# Build datamodels first (dependency for others)
$(MAKE) -C $(DATAMODELS_BUILD_DIR)\
PROJECT_ROOT="$(DATAMODELS_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS) -I$(DATAMODELS_BUILD_DIR)" \
all
# Build dm-api (depends on datamodels)
$(MAKE) -C $(DMAPI_BUILD_DIR)\
PROJECT_ROOT="$(DMAPI_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS) -I$(DMAPI_BUILD_DIR)" \
all
# Build dm-agent (depends on both)
$(MAKE) -C $(DMAGENT_BUILD_DIR)\
PROJECT_ROOT="$(DMAGENT_BUILD_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
EXTRA_CFLAGS="$(TARGET_CFLAGS) -I$(DMAGENT_BUILD_DIR)" \
all
endef
#
# Development Installation (headers and libraries)
#
define Build/InstallDev
# Datamodels development files
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(DATAMODELS_BUILD_DIR)/dm.h $(1)/usr/include/
$(CP) $(DATAMODELS_BUILD_DIR)/libdm.so $(1)/usr/lib/
# DM-API development files - headers are now in dm-api/include/
$(CP) $(DMAPI_BUILD_DIR)/include/dm_types.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/include/dm_node.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/core/dm_api.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/core/dm_linker.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/core/dbmgr.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/include/dm_log.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/utils/dm_list.h $(1)/usr/include/
$(CP) $(DMAPI_BUILD_DIR)/libdmapi.so $(1)/usr/lib/
endef
#
# Package Installation - Datamodels
#
define Package/datamodels/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/bbfdm
$(INSTALL_DIR) $(1)/usr/lib/dmf_handlers
$(INSTALL_BIN) $(DATAMODELS_BUILD_DIR)/default.db $(1)/etc/bbfdm/default_dm.db
$(INSTALL_BIN) $(DATAMODELS_BUILD_DIR)/libdm.so $(1)/usr/lib/
# Copy handler files from datamodels directory (new structure)
# Copy .js files from root datamodels directory
( cd $(DATAMODELS_BUILD_DIR); \
find . -maxdepth 1 -type f -name '*.js' -not -path './.*' -exec $(INSTALL_BIN) {} $(1)/usr/lib/dmf_handlers/{} \; )
# Copy .js files from subdirectories, preserving folder structure (skip hidden files/folders)
( cd $(DATAMODELS_BUILD_DIR); \
find . -type d -mindepth 1 -not -path './.*' -not -path './scripts*' -exec $(INSTALL_DIR) $(1)/usr/lib/dmf_handlers/{} \; ; \
find . -type f -name '*.js' -mindepth 2 -not -path './.*' -not -path './scripts*' -exec $(INSTALL_BIN) {} $(1)/usr/lib/dmf_handlers/{} \; )
endef
#
# Package Installation - DM-API
#
define Package/dm-api/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/sbin/
$(INSTALL_BIN) $(DMAPI_BUILD_DIR)/libdmapi.so $(1)/usr/lib/
endef
#
# Package Installation - DM-Agent
#
define Package/dm-agent/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./files/etc/init.d/bridging $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/config/bridging $(1)/etc/config/
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) dm-agent
$(INSTALL_BIN) $(DMAGENT_BUILD_DIR)/dm-agent $(1)/usr/sbin
endef
# Register all three packages
$(eval $(call BuildPackage,datamodels))
$(eval $(call BuildPackage,dm-api))
$(eval $(call BuildPackage,dm-agent))

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ieee1905
PKG_VERSION:=8.7.39
PKG_VERSION:=8.7.38
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=85fa0fe16d6a5a3452422b72186f6bbb16a13c62
PKG_SOURCE_VERSION:=c685111f87aaca4dc17cc03b0d34e20b47c83a03
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/ieee1905.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip

View File

@@ -34,9 +34,6 @@ define Package/$(PKG_NAME)
+@PACKAGE_syslog-ng:SYSLOGNG_LOGROTATE \
+PACKAGE_fluent-bit:logrotate \
+@DMCLI_REMOTE_CONNECTION
# tools used in development/testing
DEPENDS+= \
+iperf3
endef

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libwifi
PKG_VERSION:=7.22.6
PKG_VERSION:=7.22.4
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=ddeb681a9f99202b1ded6c965591bb8c1f5cb05d
PKG_SOURCE_VERSION:=fadbe86a2ea05037ee9df6040b74bec683a6ca66
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/libwifi.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip

View File

@@ -6,9 +6,9 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-agent
PKG_VERSION:=6.4.3.6
PKG_VERSION:=6.4.3.5
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=e37b8f1a4b988b907416161e3c8fe83cd39597c3
PKG_SOURCE_VERSION:=eeea7b39112717639046ac347e30ed0991ca490f
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@iopsys.eu>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -6,9 +6,9 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-controller
PKG_VERSION:=6.4.4.8
PKG_VERSION:=6.4.4.4
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=a863fc3a9d248b0be7385524e0680155ff614467
PKG_SOURCE_VERSION:=3d10c21efbb0b0da7206435a1ecfeed107d55e83
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@genexis.eu>
LOCAL_DEV=0

View File

@@ -13,7 +13,7 @@ config controller 'controller'
config sta_steering 'sta_steering'
option enable_sta_steer '1'
option enable_bsta_steer '1'
option enable_bsta_steer '0'
option rcpi_threshold_2g '70'
option rcpi_threshold_5g '86'
option rcpi_threshold_6g '86'

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-plugins
PKG_VERSION:=1.2.5
PKG_VERSION:=1.2.2
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=05c0aa02b60b27aa57bf80b8fb068b1ee8bfc8ac
PKG_SOURCE_VERSION:=03524191711a50a07b9c26f3be2c16b845140e49
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/map-plugins.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip

View File

@@ -32,7 +32,7 @@ define Package/mcastmngr
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json
DEPENDS+=+!TARGET_brcmbca:mcproxy +!TARGET_brcmbca:sipcalc
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service +!TARGET_brcmbca:kmod-ebt-igmpsnooping +!TARGET_brcmbca:kmod-ebt-mldsnooping
DEPENDS+=+!TARGET_brcmbca:ebtables-legacy +dm-agent
DEPENDS+=+!TARGET_brcmbca:ebtables-legacy +bridgemngr
endef
define Package/mcastmngr/description

View File

@@ -47,7 +47,7 @@ endif
define Package/mosquitto-auth-plugin/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_plugin.so $(1)/usr/lib/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_shadow.so $(1)/usr/lib/
$(CP) ./files/* $(1)/
endef

View File

@@ -30,169 +30,101 @@
#define MAX_SUBNETS_PER_USER 32
typedef struct {
union {
uint32_t ipv4_network;
uint8_t ipv6_network[16];
};
union {
uint32_t ipv4_netmask;
uint8_t ipv6_netmask[16];
};
int is_ipv6;
uint32_t network;
uint32_t netmask;
} subnet_t;
typedef struct {
char username[64];
subnet_t allow_subnets[MAX_SUBNETS_PER_USER];
int allow_count;
subnet_t deny_subnets[MAX_SUBNETS_PER_USER];
int deny_count;
char username[64];
subnet_t allow_subnets[MAX_SUBNETS_PER_USER];
int allow_count;
subnet_t deny_subnets[MAX_SUBNETS_PER_USER];
int deny_count;
} user_acl_t;
typedef struct {
user_acl_t users[MAX_USERS];
int user_count;
mosquitto_plugin_id_t *identifier;
user_acl_t users[MAX_USERS];
int user_count;
mosquitto_plugin_id_t *identifier;
} plugin_data_t;
/* Parse CIDR notation for IPv4 or IPv6 (e.g., "192.168.1.0/24" or "2001:db8::/32") */
/* Parse CIDR notation (e.g., "192.168.1.0/24") */
static int parse_subnet(const char *cidr, subnet_t *subnet)
{
char ip_str[128];
char *slash;
int prefix_len;
struct in_addr addr4;
struct in6_addr addr6;
char ip_str[64];
char *slash;
int prefix_len;
struct in_addr addr;
strncpy(ip_str, cidr, sizeof(ip_str) - 1);
ip_str[sizeof(ip_str) - 1] = '\0';
strncpy(ip_str, cidr, sizeof(ip_str) - 1);
ip_str[sizeof(ip_str) - 1] = '\0';
slash = strchr(ip_str, '/');
if (slash != NULL) {
*slash = '\0';
prefix_len = atoi(slash + 1);
}
slash = strchr(ip_str, '/');
if (slash == NULL) {
/* No prefix length, assume /32 */
prefix_len = 32;
} else {
*slash = '\0';
prefix_len = atoi(slash + 1);
if (prefix_len < 0 || prefix_len > 32)
return -1;
}
/* Try IPv4 first */
if (inet_pton(AF_INET, ip_str, &addr4) == 1) {
subnet->is_ipv6 = 0;
if (slash == NULL)
prefix_len = 32;
if (prefix_len < 0 || prefix_len > 32)
return -1;
if (inet_pton(AF_INET, ip_str, &addr) != 1)
return -1;
subnet->ipv4_network = ntohl(addr4.s_addr);
subnet->ipv4_netmask = prefix_len == 0 ? 0 : (~0U << (32 - prefix_len));
subnet->ipv4_network &= subnet->ipv4_netmask;
return 0;
}
subnet->network = ntohl(addr.s_addr);
subnet->netmask = prefix_len == 0 ? 0 : (~0U << (32 - prefix_len));
subnet->network &= subnet->netmask;
/* Try IPv6 */
if (inet_pton(AF_INET6, ip_str, &addr6) == 1) {
subnet->is_ipv6 = 1;
if (slash == NULL)
prefix_len = 128;
if (prefix_len < 0 || prefix_len > 128)
return -1;
/* Copy network address */
memcpy(subnet->ipv6_network, addr6.s6_addr, 16);
/* Generate netmask */
memset(subnet->ipv6_netmask, 0, 16);
for (int i = 0; i < prefix_len / 8; i++)
subnet->ipv6_netmask[i] = 0xff;
if (prefix_len % 8)
subnet->ipv6_netmask[prefix_len / 8] = ~((1 << (8 - (prefix_len % 8))) - 1);
/* Apply netmask to network address */
for (int i = 0; i < 16; i++)
subnet->ipv6_network[i] &= subnet->ipv6_netmask[i];
return 0;
}
return -1;
return 0;
}
/* Check if IPv4 address is in subnet */
static int ipv4_in_subnet(uint32_t ip, const subnet_t *subnet)
/* Check if IP is in subnet */
static int ip_in_subnet(uint32_t ip, const subnet_t *subnet)
{
if (subnet->is_ipv6)
return 0;
return (ip & subnet->ipv4_netmask) == subnet->ipv4_network;
}
/* Check if IPv6 address is in subnet */
static int ipv6_in_subnet(const uint8_t *ip, const subnet_t *subnet)
{
if (!subnet->is_ipv6)
return 0;
for (int i = 0; i < 16; i++) {
if ((ip[i] & subnet->ipv6_netmask[i]) != subnet->ipv6_network[i])
return 0;
}
return 1;
return (ip & subnet->netmask) == subnet->network;
}
/* Check if IP is in any subnet in the list */
static int ip_in_subnet_list(const char *client_address, const subnet_t *subnets, int count)
static int ip_in_subnet_list(uint32_t ip, const subnet_t *subnets, int count)
{
struct in_addr addr4;
struct in6_addr addr6;
uint32_t ipv4;
/* Try IPv4 */
if (inet_pton(AF_INET, client_address, &addr4) == 1) {
ipv4 = ntohl(addr4.s_addr);
for (int i = 0; i < count; i++) {
if (ipv4_in_subnet(ipv4, &subnets[i]))
return 1;
}
return 0;
}
/* Try IPv6 */
if (inet_pton(AF_INET6, client_address, &addr6) == 1) {
for (int i = 0; i < count; i++) {
if (ipv6_in_subnet(addr6.s6_addr, &subnets[i]))
return 1;
}
return 0;
}
return 0;
for (int i = 0; i < count; i++) {
if (ip_in_subnet(ip, &subnets[i]))
return 1;
}
return 0;
}
/* Find or create user ACL entry */
static user_acl_t* find_or_create_user_acl(plugin_data_t *pdata, const char *username)
{
user_acl_t *user;
user_acl_t *user;
/* Find existing user */
for (int i = 0; i < pdata->user_count; i++) {
if (strcmp(pdata->users[i].username, username) == 0)
return &pdata->users[i];
}
/* Find existing user */
for (int i = 0; i < pdata->user_count; i++) {
if (strcmp(pdata->users[i].username, username) == 0)
return &pdata->users[i];
}
/* Create new user if not found */
if (pdata->user_count >= MAX_USERS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max users exceeded");
return NULL;
}
/* Create new user if not found */
if (pdata->user_count >= MAX_USERS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max users exceeded");
return NULL;
}
user = &pdata->users[pdata->user_count];
strncpy(user->username, username, sizeof(user->username) - 1);
user->username[sizeof(user->username) - 1] = '\0';
user->allow_count = 0;
user->deny_count = 0;
pdata->user_count++;
user = &pdata->users[pdata->user_count];
strncpy(user->username, username, sizeof(user->username) - 1);
user->username[sizeof(user->username) - 1] = '\0';
user->allow_count = 0;
user->deny_count = 0;
pdata->user_count++;
return user;
return user;
}
/* Parse subnet ACL file with simplified format
/* Parse subnet ACL file
* Format:
* # Comment lines
* subnet allow <username> <cidr>
@@ -200,417 +132,399 @@ static user_acl_t* find_or_create_user_acl(plugin_data_t *pdata, const char *use
*/
static int load_subnet_acl_config(plugin_data_t *pdata, const char *config_file)
{
FILE *fp;
char line[512];
int line_num = 0;
FILE *fp;
char line[512];
int line_num = 0;
/* Initialize user count */
pdata->user_count = 0;
if (config_file == NULL) {
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: No subnet ACL file specified, subnet filtering disabled");
return 0;
}
/* Config file is optional - if not provided, no subnet filtering */
if (config_file == NULL) {
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: No subnet ACL file specified, subnet filtering disabled");
return 0;
}
fp = fopen(config_file, "r");
if (fp == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Could not open subnet ACL file %s, subnet filtering disabled",
config_file);
return 0; /* Non-fatal */
}
/* If config file is specified but cannot be opened, this is a fatal error */
fp = fopen(config_file, "r");
if (fp == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to open subnet ACL file '%s'", config_file);
return -1;
}
pdata->user_count = 0;
while (fgets(line, sizeof(line), fp) != NULL) {
char *token, *saveptr;
char *action, *username, *cidr;
user_acl_t *user;
subnet_t subnet;
while (fgets(line, sizeof(line), fp) != NULL) {
char *token, *saveptr;
char *action, *username, *cidr;
user_acl_t *user;
subnet_t subnet;
line_num++;
line_num++;
/* Remove newline and comments */
line[strcspn(line, "\r\n")] = '\0';
char *comment = strchr(line, '#');
if (comment)
*comment = '\0';
/* Remove newline and comments */
line[strcspn(line, "\r\n")] = '\0';
char *comment = strchr(line, '#');
if (comment)
*comment = '\0';
/* Trim leading whitespace */
char *line_start = line;
while (*line_start == ' ' || *line_start == '\t')
line_start++;
/* Trim leading whitespace */
char *line_start = line;
while (*line_start == ' ' || *line_start == '\t')
line_start++;
/* Skip empty lines */
if (*line_start == '\0')
continue;
/* Skip empty lines */
if (*line_start == '\0')
continue;
/* Parse: subnet allow|deny <username> <cidr> */
token = strtok_r(line_start, " \t", &saveptr);
if (token == NULL)
continue;
/* Parse: subnet allow|deny <username> <cidr> */
token = strtok_r(line_start, " \t", &saveptr);
if (token == NULL)
continue;
/* Must start with "subnet" */
if (strcmp(token, "subnet") != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Invalid directive '%s' at line %d (expected 'subnet')",
token, line_num);
fclose(fp);
return -1;
}
/* Must start with "subnet" */
if (strcmp(token, "subnet") != 0) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Unknown directive '%s' at line %d (expected 'subnet')",
token, line_num);
continue;
}
/* Get allow/deny */
action = strtok_r(NULL, " \t", &saveptr);
if (action == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Missing allow/deny at line %d", line_num);
fclose(fp);
return -1;
}
/* Get allow/deny */
action = strtok_r(NULL, " \t", &saveptr);
if (action == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Missing allow/deny at line %d", line_num);
continue;
}
if (strcmp(action, "allow") != 0 && strcmp(action, "deny") != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Invalid action '%s' at line %d (use 'allow' or 'deny')",
action, line_num);
fclose(fp);
return -1;
}
if (strcmp(action, "allow") != 0 && strcmp(action, "deny") != 0) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Unknown action '%s' at line %d (use 'allow' or 'deny')",
action, line_num);
continue;
}
/* Get username */
username = strtok_r(NULL, " \t", &saveptr);
if (username == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Missing username at line %d", line_num);
fclose(fp);
return -1;
}
/* Get username */
username = strtok_r(NULL, " \t", &saveptr);
if (username == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Missing username at line %d", line_num);
continue;
}
/* Get CIDR */
cidr = strtok_r(NULL, " \t", &saveptr);
if (cidr == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Missing CIDR at line %d", line_num);
fclose(fp);
return -1;
}
/* Get CIDR */
cidr = strtok_r(NULL, " \t", &saveptr);
if (cidr == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Missing CIDR at line %d", line_num);
continue;
}
/* Parse subnet */
if (parse_subnet(cidr, &subnet) != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Invalid CIDR '%s' at line %d", cidr, line_num);
fclose(fp);
return -1;
}
/* Parse subnet */
if (parse_subnet(cidr, &subnet) != 0) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Invalid CIDR '%s' at line %d", cidr, line_num);
continue;
}
/* Find or create user */
user = find_or_create_user_acl(pdata, username);
if (user == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max users (%d) exceeded at line %d", MAX_USERS, line_num);
fclose(fp);
return -1;
}
/* Find or create user */
user = find_or_create_user_acl(pdata, username);
if (user == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to create user at line %d", line_num);
continue;
}
/* Add to appropriate list */
if (strcmp(action, "allow") == 0) {
if (user->allow_count >= MAX_SUBNETS_PER_USER) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max allow subnets (%d) exceeded for user '%s' at line %d",
MAX_SUBNETS_PER_USER, user->username, line_num);
fclose(fp);
return -1;
}
user->allow_subnets[user->allow_count] = subnet;
user->allow_count++;
/* Add to appropriate list */
if (strcmp(action, "allow") == 0) {
if (user->allow_count >= MAX_SUBNETS_PER_USER) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Max allow subnets exceeded for user '%s' at line %d",
user->username, line_num);
continue;
}
user->allow_subnets[user->allow_count] = subnet;
user->allow_count++;
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' allow subnet %s",
user->username, cidr);
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' allow subnet %s",
user->username, cidr);
} else { /* deny */
if (user->deny_count >= MAX_SUBNETS_PER_USER) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max deny subnets (%d) exceeded for user '%s' at line %d",
MAX_SUBNETS_PER_USER, user->username, line_num);
fclose(fp);
return -1;
}
user->deny_subnets[user->deny_count] = subnet;
user->deny_count++;
} else { /* deny */
if (user->deny_count >= MAX_SUBNETS_PER_USER) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Max deny subnets exceeded for user '%s' at line %d",
user->username, line_num);
continue;
}
user->deny_subnets[user->deny_count] = subnet;
user->deny_count++;
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' deny subnet %s",
user->username, cidr);
}
}
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' deny subnet %s",
user->username, cidr);
}
}
fclose(fp);
fclose(fp);
/* Log summary */
for (int i = 0; i < pdata->user_count; i++) {
user_acl_t *user = &pdata->users[i];
if (user->allow_count > 0 || user->deny_count > 0) {
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: User '%s' has %d allow and %d deny subnet rules",
user->username, user->allow_count, user->deny_count);
}
}
/* Log summary */
for (int i = 0; i < pdata->user_count; i++) {
user_acl_t *user = &pdata->users[i];
if (user->allow_count > 0 || user->deny_count > 0) {
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: User '%s' has %d allow and %d deny subnet rules",
user->username, user->allow_count, user->deny_count);
}
}
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Loaded subnet restrictions for %d user(s)", pdata->user_count);
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Loaded subnet restrictions for %d user(s)", pdata->user_count);
return 0;
return 0;
}
/* Find user ACL entry */
static const user_acl_t* find_user_acl(const plugin_data_t *pdata, const char *username)
{
for (int i = 0; i < pdata->user_count; i++) {
if (strcmp(pdata->users[i].username, username) == 0)
return &pdata->users[i];
}
return NULL;
for (int i = 0; i < pdata->user_count; i++) {
if (strcmp(pdata->users[i].username, username) == 0)
return &pdata->users[i];
}
return NULL;
}
/* Check subnet access on authentication (connection time)
* Returns: MOSQ_ERR_SUCCESS if allowed, MOSQ_ERR_AUTH if denied
*/
static int check_subnet_on_auth(plugin_data_t *pdata, struct mosquitto_evt_basic_auth *ed)
/* ACL check for subnet validation */
static int acl_check_callback(int event, void *event_data, void *userdata)
{
const user_acl_t *user_acl;
const char *client_address;
struct mosquitto_evt_acl_check *ed = event_data;
plugin_data_t *pdata = userdata;
const user_acl_t *user_acl;
const char *client_address;
const char *username;
struct in_addr addr;
uint32_t client_ip;
/* Skip if no subnet config loaded */
if (pdata == NULL || pdata->user_count == 0)
return MOSQ_ERR_SUCCESS;
/* Skip if no subnet config loaded */
if (pdata == NULL || pdata->user_count == 0) {
return MOSQ_ERR_PLUGIN_DEFER;
}
/* Skip anonymous users */
if (ed->username == NULL)
return MOSQ_ERR_SUCCESS;
/* Get username from client */
username = mosquitto_client_username(ed->client);
/* Find user's subnet ACL */
user_acl = find_user_acl(pdata, ed->username);
/* Skip anonymous users */
if (username == NULL) {
return MOSQ_ERR_PLUGIN_DEFER;
}
/* If user not in config or has no subnet rules, allow */
if (user_acl == NULL || (user_acl->allow_count == 0 && user_acl->deny_count == 0))
return MOSQ_ERR_SUCCESS;
/* Find user's subnet ACL */
user_acl = find_user_acl(pdata, username);
/* Get client IP address */
client_address = mosquitto_client_address(ed->client);
if (client_address == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Could not get client address for user '%s', denying connection",
ed->username);
return MOSQ_ERR_AUTH;
}
/* If user not in config or has no subnet rules, allow */
if (user_acl == NULL || (user_acl->allow_count == 0 && user_acl->deny_count == 0)) {
return MOSQ_ERR_PLUGIN_DEFER;
}
/* Check deny list first - deny takes precedence */
if (user_acl->deny_count > 0) {
if (ip_in_subnet_list(client_address, user_acl->deny_subnets, user_acl->deny_count)) {
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: User '%s' from %s DENIED by deny rule",
ed->username, client_address);
return MOSQ_ERR_AUTH;
}
}
/* Get client IP address */
client_address = mosquitto_client_address(ed->client);
if (client_address == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Could not get client address for user '%s'", username);
return MOSQ_ERR_PLUGIN_DEFER;
}
/* If there are allow rules, IP must match one of them */
if (user_acl->allow_count > 0) {
if (ip_in_subnet_list(client_address, user_acl->allow_subnets, user_acl->allow_count)) {
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' from %s allowed by allow rule",
ed->username, client_address);
return MOSQ_ERR_SUCCESS;
} else {
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: User '%s' from %s DENIED (not in allowed subnets)",
ed->username, client_address);
return MOSQ_ERR_AUTH;
}
}
/* Skip localhost checks - always allow */
if (strcmp(client_address, "127.0.0.1") == 0 || strcmp(client_address, "::1") == 0) {
return MOSQ_ERR_PLUGIN_DEFER;
}
/* No subnet rules for this user - allow */
return MOSQ_ERR_SUCCESS;
/* Parse client IP */
if (inet_pton(AF_INET, client_address, &addr) != 1) {
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: Non-IPv4 address '%s' for user '%s', allowing",
client_address, username);
/* For IPv6 or parse errors, defer to other plugins */
return MOSQ_ERR_PLUGIN_DEFER;
}
client_ip = ntohl(addr.s_addr);
/* Check deny list first - deny takes precedence */
if (user_acl->deny_count > 0) {
if (ip_in_subnet_list(client_ip, user_acl->deny_subnets, user_acl->deny_count)) {
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: User '%s' from %s DENIED (matches deny rule)",
username, client_address);
return MOSQ_ERR_ACL_DENIED;
}
}
/* If there are allow rules, IP must match one of them */
if (user_acl->allow_count > 0) {
if (ip_in_subnet_list(client_ip, user_acl->allow_subnets, user_acl->allow_count)) {
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' from %s allowed (matches allow rule)",
username, client_address);
return MOSQ_ERR_PLUGIN_DEFER;
} else {
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: User '%s' from %s DENIED (no matching allow rule)",
username, client_address);
return MOSQ_ERR_ACL_DENIED;
}
}
/* No subnet rules for this user - allow */
return MOSQ_ERR_PLUGIN_DEFER;
}
#ifdef ENABLE_PAM_SUPPORT
static int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
static int pam_conversation(int num_msg, const struct pam_message **msg,
struct pam_response **resp, void *appdata_ptr)
{
int i;
const char *pass = (const char *)appdata_ptr;
*resp = calloc(num_msg, sizeof(struct pam_response));
if (*resp == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed to allocate buffer for validation");
return PAM_BUF_ERR;
}
if (pass == NULL)
return PAM_SUCCESS;
for (i = 0; i < num_msg; ++i) {
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
(*resp)[i].resp = strdup(pass);
if ((*resp)[i].resp == NULL) {
for (int j = 0; j < i ; j++)
free((*resp)[j].resp);
free(*resp);
*resp = NULL;
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed in strdup");
return PAM_BUF_ERR;
}
}
}
return PAM_SUCCESS;
int i;
const char *pass = (const char *)appdata_ptr;
*resp = calloc(num_msg, sizeof(struct pam_response));
if (*resp == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed to allocate buffer for validation");
return PAM_BUF_ERR;
}
if (pass == NULL)
return PAM_SUCCESS;
for (i = 0; i < num_msg; ++i) {
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
(*resp)[i].resp = strdup(pass);
if ((*resp)[i].resp == NULL) {
for (int j = 0; j < i ; j++)
free((*resp)[j].resp);
free(*resp);
*resp = NULL;
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed in strdup");
return PAM_BUF_ERR;
}
}
}
return PAM_SUCCESS;
}
static int process_pam_auth_callback(struct mosquitto_evt_basic_auth *ed)
{
struct pam_conv conv;
int retval;
pam_handle_t *pamh = NULL;
conv.conv = pam_conversation;
conv.appdata_ptr = (void *)ed->password;
retval = pam_start("mosquitto", ed->username, &conv, &pamh);
if (retval != PAM_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR, "pam start failed: %s", pam_strerror(pamh, retval));
return MOSQ_ERR_AUTH;
}
retval = pam_authenticate(pamh, 0);
pam_end(pamh, retval);
if (retval == PAM_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] logged in", ed->username);
return MOSQ_ERR_SUCCESS;
}
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] failed authentication, err [%s]", ed->username, pam_strerror(pamh, retval));
return MOSQ_ERR_AUTH;
struct pam_conv conv;
int retval;
pam_handle_t *pamh = NULL;
conv.conv = pam_conversation;
conv.appdata_ptr = (void *)ed->password;
retval = pam_start("mosquitto", ed->username, &conv, &pamh);
if (retval != PAM_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR, "pam start failed: %s", pam_strerror(pamh, retval));
return MOSQ_ERR_AUTH;
}
retval = pam_authenticate(pamh, 0);
pam_end(pamh, retval);
if (retval == PAM_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] logged in", ed->username);
return MOSQ_ERR_SUCCESS;
}
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] failed authentication, err [%s]",
ed->username, pam_strerror(pamh, retval));
return MOSQ_ERR_AUTH;
}
#else
static int process_shadow_auth_callback(struct mosquitto_evt_basic_auth *ed)
{
struct spwd spbuf, *sp = NULL;
char buf[256];
struct crypt_data data;
char *hash;
getspnam_r(ed->username, &spbuf, buf, sizeof(buf), &sp);
if (sp == NULL || sp->sp_pwdp == NULL)
return MOSQ_ERR_AUTH;
/* Empty string as hash means password is not required */
if (sp->sp_pwdp[0] == 0)
return MOSQ_ERR_SUCCESS;
if (ed->password == NULL)
return MOSQ_ERR_AUTH;
memset(&data, 0, sizeof(data));
hash = crypt_r(ed->password, sp->sp_pwdp, &data);
if (hash == NULL)
return MOSQ_ERR_AUTH;
if (strcmp(hash, sp->sp_pwdp) == 0)
return MOSQ_ERR_SUCCESS;
return MOSQ_ERR_AUTH;
struct spwd spbuf, *sp = NULL;
char buf[256];
struct crypt_data data;
char *hash;
getspnam_r(ed->username, &spbuf, buf, sizeof(buf), &sp);
if (sp == NULL || sp->sp_pwdp == NULL)
return MOSQ_ERR_AUTH;
/* Empty string as hash means password is not required */
if (sp->sp_pwdp[0] == 0)
return MOSQ_ERR_SUCCESS;
if (ed->password == NULL)
return MOSQ_ERR_AUTH;
memset(&data, 0, sizeof(data));
hash = crypt_r(ed->password, sp->sp_pwdp, &data);
if (hash == NULL)
return MOSQ_ERR_AUTH;
if (strcmp(hash, sp->sp_pwdp) == 0)
return MOSQ_ERR_SUCCESS;
return MOSQ_ERR_AUTH;
}
#endif
static int basic_auth_callback(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_basic_auth *ed = event_data;
plugin_data_t *pdata = userdata;
int auth_result;
/* Let other plugins or broker decide about anonymous login */
if (ed->username == NULL)
return MOSQ_ERR_PLUGIN_DEFER;
/* First check username/password authentication */
struct mosquitto_evt_basic_auth *ed = event_data;
/* Let other plugins or broker decide about anonymous login */
if (ed->username == NULL)
return MOSQ_ERR_PLUGIN_DEFER;
#ifdef ENABLE_PAM_SUPPORT
auth_result = process_pam_auth_callback(ed);
return process_pam_auth_callback(ed);
#else
auth_result = process_shadow_auth_callback(ed);
return process_shadow_auth_callback(ed);
#endif
/* If authentication failed, reject immediately */
if (auth_result != MOSQ_ERR_SUCCESS)
return auth_result;
/* Authentication succeeded, now check subnet restrictions */
return check_subnet_on_auth(pdata, ed);
}
int mosquitto_plugin_version(int supported_version_count,
const int *supported_versions)
const int *supported_versions)
{
return 5;
return 5;
}
int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier,
void **user_data,
struct mosquitto_opt *opts, int opt_count)
void **user_data,
struct mosquitto_opt *opts, int opt_count)
{
plugin_data_t *pdata;
const char *config_file = NULL;
int rc;
plugin_data_t *pdata;
const char *config_file = NULL;
/* Find subnet config file option */
for (int i = 0; i < opt_count; i++) {
if (strcmp(opts[i].key, "subnet_acl_file") == 0) {
config_file = opts[i].value;
break;
}
}
/* Find subnet config file option */
for (int i = 0; i < opt_count; i++) {
if (strcmp(opts[i].key, "subnet_acl_file") == 0) {
config_file = opts[i].value;
break;
}
}
pdata = calloc(1, sizeof(plugin_data_t));
if (pdata == NULL)
return MOSQ_ERR_NOMEM;
pdata = calloc(1, sizeof(plugin_data_t));
if (pdata == NULL)
return MOSQ_ERR_NOMEM;
pdata->identifier = identifier;
pdata->identifier = identifier;
*user_data = pdata;
/* Load subnet ACL configuration */
if (load_subnet_acl_config(pdata, config_file) != 0) {
free(pdata);
return MOSQ_ERR_UNKNOWN;
}
/* Load subnet ACL configuration */
if (load_subnet_acl_config(pdata, config_file) != 0) {
free(pdata);
return MOSQ_ERR_UNKNOWN;
}
/* Register authentication callback only - subnet check is done during auth */
rc = mosquitto_callback_register(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL, pdata);
if (rc != MOSQ_ERR_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to register authentication callback");
free(pdata);
return rc;
}
/* Register both authentication and ACL callbacks */
mosquitto_callback_register(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL, pdata);
mosquitto_callback_register(identifier, MOSQ_EVT_ACL_CHECK,
acl_check_callback, NULL, pdata);
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: Plugin initialized with %d user(s)", pdata->user_count);
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: Plugin initialized with %d user(s)", pdata->user_count);
/* Only assign user_data after all possible error paths */
*user_data = pdata;
return MOSQ_ERR_SUCCESS;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_plugin_cleanup(void *user_data,
struct mosquitto_opt *opts, int opt_count)
struct mosquitto_opt *opts, int opt_count)
{
plugin_data_t *pdata = user_data;
plugin_data_t *pdata = user_data;
if (pdata) {
mosquitto_callback_unregister(pdata->identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
free(pdata);
}
if (pdata) {
mosquitto_callback_unregister(pdata->identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
mosquitto_callback_unregister(pdata->identifier, MOSQ_EVT_ACL_CHECK,
acl_check_callback, NULL);
free(pdata);
}
return MOSQ_ERR_SUCCESS;
return MOSQ_ERR_SUCCESS;
}

View File

@@ -11,7 +11,7 @@ LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/netmngr.git
PKG_SOURCE_VERSION:=000da9cbb2cfe965908adf60eda0823682c8bd69
PKG_SOURCE_VERSION:=ff08a8cc5c860056a022e5376a973dee5a323595
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=netmode
PKG_VERSION:=1.1.8
PKG_VERSION:=1.1.7
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=GPL-2.0-only

View File

@@ -4,19 +4,13 @@ enabled="$(uci -q get netmode.global.enabled)"
[ "$enabled" == "1" ] || exit 0
mode="$(uci -q get netmode.global.mode)"
wanproto=$(uci -q get network.wan.proto)
if [ -n "$mode" ]; then
# check if wanproto and mode aligned
if [ "${mode}" = "routed-${wanproto}" ]; then
exit 0
fi
fi
[ -n "$mode" ] && exit 0
[ -f /etc/netmodes/supported_modes.json ] || exit 0
# NetMode is enabled without a Mode being set
# Figure out the current mode from network config
wanproto=$(uci -q get network.wan.proto)
curmode=""
case "$wanproto" in
dhcp) curmode="routed-dhcp" ;;

View File

@@ -1 +0,0 @@
/etc/netmodes/.last_mode

View File

@@ -32,7 +32,7 @@ define Package/qosmngr
TITLE:=QoS Manager
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libqos +!(TARGET_brcmbca||TARGET_airoha):tc-full
DEPENDS+=+kmod-ebt-vlantranslation +kmod-ebt-dscp2pbit +!(TARGET_brcmbca):ebtables-legacy
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service +dm-agent
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service +bridgemngr
endef
define Package/qosmngr/description

2
quickjs/Makefile Executable file → Normal file
View File

@@ -15,8 +15,6 @@ PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
TARGET_CFLAGS += -fPIC
define Package/quickjs
SECTION:=lang
CATEGORY:=Languages

View File

@@ -5,11 +5,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sulu-base
PKG_VERSION:=5.2.2
PKG_VERSION:=5.1.1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/websdk/sulu.git
PKG_SOURCE_VERSION:=b2bf5c9615e0e81afb2e6bcbf6c75b347e24c705
PKG_SOURCE_VERSION:=08195779cbc2d1d7410cb324b9e35692b0579a7e
PKG_MIRROR_HASH:=skip
SULU_MOD:=core

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sulu-builder
PKG_VERSION:=5.2.2
PKG_VERSION:=5.1.1
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/websdk/sulu-builder.git
PKG_SOURCE_VERSION:=d270fcaec14aaf53b1a8983e71b2c61dec1ab1ed
PKG_SOURCE_VERSION:=7f646ecf643967f4b4b2c545a31bbef0514b34bc
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
PKG_BUILD_DIR:=$(BUILD_DIR)/sulu-$(PKG_VERSION)/sulu-builder-$(PKG_SOURCE_VERSION)
@@ -28,7 +28,7 @@ define Package/sulu/default
CATEGORY:=Utilities
SUBMENU:=SULU
TITLE:=SULU-CE
DEPENDS:=+mosquitto-auth-plugin +usermngr +userinterface +obuspa
DEPENDS:=+mosquitto-auth-shadow +usermngr +userinterface +obuspa
DEPENDS+=+@OBUSPA_LOCAL_MQTT_LISTENER
EXTRA_DEPENDS:=nginx
endef
@@ -98,12 +98,8 @@ define Package/sulu/install/Default
$(INSTALL_DIR) $(1)/sulu/
$(INSTALL_DIR) $(1)/etc/sulu
$(INSTALL_DATA) ./files/maintenance.html $(1)/sulu/
$(LN) /tmp/sulu $(1)/sulu/connection
$(INSTALL_BIN) ./files/etc/sulu/sulu.sh $(1)/etc/sulu/
$(INSTALL_DATA) ./files/etc/sulu/nginx.locations $(1)/etc/sulu/
$(INSTALL_BIN) ./files/etc/sulu/sulu_watcher.sh $(1)/etc/sulu/
$(INSTALL_DIR) $(1)/etc/users/roles
$(INSTALL_DATA) ./files/etc/users/roles/*.json $(1)/etc/users/roles/
@@ -113,8 +109,6 @@ define Package/sulu/install/Default
ifneq ($(CONFIG_SULU_DEFAULT_UI)$(CONFIG_SULU_BUILDER_DEFAULT_UI),)
$(INSTALL_DATA) ./files/etc/uci-defaults/41-make-sulu-default-ui $(1)/etc/uci-defaults/
endif
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/etc/init.d/sulu $(1)/etc/init.d/
endef
define Package/sulu/install/Post

View File

@@ -1,15 +0,0 @@
#!/bin/sh /etc/rc.common
START=9
STOP=01
USE_PROCD=1
PROG=/etc/sulu/sulu_watcher.sh
start_service()
{
procd_open_instance "sulu"
procd_set_param command ${PROG}
procd_close_instance "sulu"
}

View File

@@ -8,10 +8,6 @@ location /sitemap.xml {
return 200 "User-agent: *\nDisallow: /\n";
}
location /maintenance.html {
internal;
}
location /wss {
proxy_pass_request_headers on;
proxy_cache off;
@@ -20,7 +16,7 @@ location /wss {
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;
@@ -52,10 +48,5 @@ location / {
}
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
add_header Pragma 'no-cache';
if (!-f $document_root/connection/ready) {
return 503;
}
expires 0;
}

View File

@@ -1,29 +0,0 @@
#!/bin/sh
if ! command -v obuspa >/dev/null 2>&1; then
exit 0
fi
USP_PATH="/tmp/sulu/"
log() {
logger -t sulu_watcher "$*"
}
wait_for_obuspa() {
while true; do
ENDPOINTID="$(obuspa -c get Device.LocalAgent.EndpointID |grep Device.|awk '{print $3}')"
sleep 2
if [ -n "${ENDPOINTID}" ]; then
break;
fi
done
}
mark_usp_ready() {
mkdir -p "${USP_PATH}"
touch ${USP_PATH}/ready
}
wait_for_obuspa
mark_usp_ready

View File

@@ -33,7 +33,7 @@ add_sulu_config_to_mosquitto()
uci_set mosquitto sulu port '9009'
uci_set mosquitto sulu no_remote_access '1'
uci_set mosquitto sulu protocol 'websockets'
uci_set mosquitto sulu auth_plugin '/usr/lib/mosquitto_auth_plugin.so'
uci_set mosquitto sulu auth_plugin '/usr/lib/mosquitto_auth_shadow.so'
uci_set mosquitto sulu acl_file '/etc/sulu/mqtt.acl'
}
@@ -48,7 +48,6 @@ add_sulu_userinterface_uci()
uci_set userinterface _sulu_s _nginx_ssl_certificate '/etc/nginx/conf.d/_lan.crt'
uci_set userinterface _sulu_s _nginx_ssl_certificate_key '/etc/nginx/conf.d/_lan.key'
uci_set userinterface _sulu_s _nginx_ssl_session_cache 'none'
uci_set userinterface _sulu_s _nginx_error_page '503 /maintenance.html'
uci_set userinterface _sulu_s protocol 'HTTPS'
uci_set userinterface _sulu_s role 'admin user'

View File

@@ -6,7 +6,554 @@
"permission": [
{
"object": "Device.",
"perm": ["PERMIT_ALL"]
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Reboot()",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.SelfTestDiagnostics()",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.FactoryReset()",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DeviceInfo.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Time.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.UPnP.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Bridging.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Ethernet.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DHCPv4.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DHCPv4.Server.Pool.{i}.StaticAddress.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DHCPv6.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Hosts.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.{BBF_VENDOR_PREFIX}ParentalControl.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.{BBF_VENDOR_PREFIX}OpenVPN.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.NAT.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Firewall.",
"perm": [
"PERMIT_GET",
"PERMIT_OBJ_INFO",
"PERMIT_SET",
"PERMIT_SUBS_VAL_CHANGE"
]
},
{
"object": "Device.Firewall.DMZ.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.PPP.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Routing.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.IEEE1905.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.InterfaceStack.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DynamicDNS.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.LANConfigSecurity.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Security.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.RouterAdvertisement.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Services.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.UserInterface.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.PeriodicStatistics.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.SoftwareModules.",
"perm": ["PERMIT_NONE"]
},
{
"object": "Device.Users.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.LocalAgent.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.LocalAgent.Subscription.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.WiFi.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DNS.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.IP.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.SSH.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.LEDs.LED.{i}.CycleElement.{i}.Brightness",
"perm": ["PERMIT_GET", "PERMIT_SET", "PERMIT_GET_INST"]
}
]
}

View File

@@ -2,19 +2,533 @@
"tr181": {
"name": "user",
"instance": 5,
"secure_role": true,
"permission": [
{
"object": "Device.",
"perm": ["PERMIT_ALL"]
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Firewall.Enable",
"perm": ["PERMIT_GET", "PERMIT_SUBS_VAL_CHANGE", "PERMIT_OBJ_INFO"]
"object": "Device.Reboot()",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Firewall.Chain.*.Rule.",
"object": "Device.SelfTestDiagnostics()",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.FactoryReset()",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DeviceInfo.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Time.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.UPnP.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Bridging.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Ethernet.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DHCPv4.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DHCPv4.Server.Pool.{i}.StaticAddress.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DHCPv6.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Hosts.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.{BBF_VENDOR_PREFIX}ParentalControl.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.{BBF_VENDOR_PREFIX}OpenVPN.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.NAT.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Firewall.",
"perm": [
"PERMIT_GET",
"PERMIT_OBJ_INFO",
"PERMIT_SET",
"PERMIT_SUBS_VAL_CHANGE"
]
},
{
"object": "Device.Firewall.DMZ.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.PPP.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Routing.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.IEEE1905.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.InterfaceStack.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DynamicDNS.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.LANConfigSecurity.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Security.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.RouterAdvertisement.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.Services.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.UserInterface.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.PeriodicStatistics.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.SoftwareModules.",
"perm": ["PERMIT_NONE"]
},
{
"object": "Device.Users.User.",
"perm": ["PERMIT_NONE"]
},
{
"object": "Device.LocalAgent.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.LocalAgent.Subscription.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.WiFi.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.DNS.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.IP.",
"perm": [
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
{
"object": "Device.SSH.",
"perm": ["PERMIT_NONE"]
},
{
"object": "Device.LEDs.LED.{i}.CycleElement.{i}.Brightness",
"perm": ["PERMIT_GET", "PERMIT_SET", "PERMIT_GET_INST"]
}
]
}

View File

@@ -1,248 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Router Interface Loading...</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family:
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
sans-serif;
background: linear-gradient(135deg, #3399ff 0%, #012669 100%);
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
.container {
text-align: center;
padding: 2rem;
background: rgba(255, 255, 255, 0.1);
border-radius: 20px;
backdrop-filter: blur(10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
max-width: 400px;
width: 90%;
}
.spinner {
width: 60px;
height: 60px;
margin: 0 auto 2rem;
position: relative;
}
.spinner::before,
.spinner::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #fff;
animation: spin 1.5s ease-in-out infinite;
}
.spinner::after {
animation-delay: 0.15s;
border-top-color: rgba(255, 255, 255, 0.5);
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
h1 {
font-size: 1.8rem;
margin-bottom: 1rem;
font-weight: 600;
}
p {
font-size: 1rem;
opacity: 0.9;
line-height: 1.5;
margin-bottom: 1rem;
}
.status {
font-size: 0.9rem;
opacity: 0.8;
margin-top: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.status-dot {
width: 8px;
height: 8px;
background: #fff;
border-radius: 50%;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
.retry-count {
font-size: 0.85rem;
opacity: 0.7;
margin-top: 0.5rem;
}
.error-message {
background: rgba(255, 59, 48, 0.2);
border: 1px solid rgba(255, 59, 48, 0.5);
padding: 0.75rem;
border-radius: 8px;
margin-top: 1rem;
font-size: 0.9rem;
display: none;
}
</style>
</head>
<body>
<div class="container">
<div class="spinner"></div>
<h1>Router Starting Up</h1>
<p>
The web interface is initializing. You'll be redirected automatically
once it's ready.
</p>
<div class="status">
<span class="status-dot"></span>
<span id="statusText">Checking availability...</span>
</div>
<div class="retry-count" id="retryCount"></div>
<div class="error-message" id="errorMessage"></div>
</div>
<script>
let retryCount = 0;
let checkInterval = 2000; // Start with 2 seconds
let maxInterval = 10000; // Max 10 seconds between checks
let consecutiveFailures = 0;
let maxConsecutiveFailures = 100; // Stop after 100 consecutive failures (~8-10 minutes)
function updateStatus(message) {
document.getElementById("statusText").textContent = message;
}
function updateRetryCount() {
retryCount++;
const retryElement = document.getElementById("retryCount");
retryElement.textContent = `Attempt ${retryCount}`;
}
function showError(message) {
const errorElement = document.getElementById("errorMessage");
errorElement.textContent = message;
errorElement.style.display = "block";
}
async function checkAvailability() {
updateRetryCount();
updateStatus("Connecting to router...");
try {
// Try to fetch the index page
const response = await fetch("/index.html", {
method: "HEAD", // Use HEAD to minimize bandwidth
cache: "no-cache",
mode: "no-cors", // Allow checking even with CORS restrictions
});
// If we get any response (even 404), the server is responding
// For a router, we typically want to redirect on 200 or 304
if (response.ok || response.status === 304) {
updateStatus("Router ready! Redirecting...");
consecutiveFailures = 0;
// Small delay for user feedback
setTimeout(() => {
window.location.reload();
}, 500);
return true;
} else if (response.status !== 503) {
// Server is responding but page not ready yet
updateStatus(`Server responding (${response.status}), waiting...`);
consecutiveFailures = 0;
}
} catch (error) {
// Network error - server not reachable
consecutiveFailures++;
if (consecutiveFailures > maxConsecutiveFailures) {
updateStatus("Connection timeout");
showError(
"Unable to connect to router. Please check your connection and refresh this page.",
);
return true; // Stop checking
}
updateStatus("Router not ready yet...");
// Implement exponential backoff
if (consecutiveFailures > 5) {
checkInterval = Math.min(checkInterval * 1.2, maxInterval);
}
}
return false;
}
async function startChecking() {
// Initial check
const isReady = await checkAvailability();
if (isReady) return;
// Continue checking
const intervalId = setInterval(async () => {
const isReady = await checkAvailability();
if (isReady) {
clearInterval(intervalId);
}
}, checkInterval);
}
// Start checking when page loads
window.addEventListener("DOMContentLoaded", () => {
// Small initial delay to show the UI
setTimeout(startChecking, 500);
});
// Also try to check if user clicks anywhere on the page
document.addEventListener("click", () => {
checkAvailability();
});
</script>
</body>
</html>

View File

@@ -5,11 +5,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sulu-theme-genexis
PKG_VERSION:=5.2.2
PKG_VERSION:=5.1.1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/gnx/sulu-theme-genexis
PKG_SOURCE_VERSION:=d329108aa49a0d57325cd8e639c80ba70c126f3f
PKG_SOURCE_VERSION:=69b72c2e589a3f73db3cb219ee7f59ab40b1bf48
PKG_MIRROR_HASH:=skip
include ../sulu-builder/sulu.mk

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sysmngr
PKG_VERSION:=1.0.31
PKG_VERSION:=1.0.30
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/system/sysmngr.git
PKG_SOURCE_VERSION:=d84dd91e19ec8e2a6baf3efa9ff319bf9d6f746a
PKG_SOURCE_VERSION:=8d150fae12ad42885c270051189572d59255244d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -75,7 +75,6 @@ define Package/usermngr/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/users/roles
$(INSTALL_DIR) $(1)/etc/users/schema
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/etc/uci-defaults/91-sync-shells $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/91-sync-roles $(1)/etc/uci-defaults/
@@ -89,7 +88,6 @@ endif
$(INSTALL_BIN) ./files/etc/init.d/users $(1)/etc/init.d/users
$(INSTALL_BIN) ./files/etc/config/users $(1)/etc/config/users
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/usermngr $(1)/usr/sbin/usermngr
$(CP) ./acl.schema.json $(1)/etc/users/schema/acl.schema.json
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
endef

View File

@@ -1,68 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "TR-181 Permissions Schema",
"type": "object",
"properties": {
"tr181": {
"type": "object",
"required": ["name", "instance", "secure_role", "permission"],
"properties": {
"name": {
"type": "string",
"description": "Name of the TR-181 profile or configuration"
},
"instance": {
"type": "integer",
"description": "Instance identifier"
},
"secure_role": {
"type": "boolean",
"description": "Whether this role is secure"
},
"permission": {
"type": "array",
"description": "List of TR-181 permissions by object path",
"items": {
"type": "object",
"required": ["object", "perm"],
"properties": {
"object": {
"type": "string",
"description": "TR-181 object path or parameter name"
},
"perm": {
"type": "array",
"description": "List of permissions for the given object",
"items": {
"type": "string",
"enum": [
"PERMIT_NONE",
"PERMIT_ALL",
"PERMIT_GET",
"PERMIT_GET_INST",
"PERMIT_OBJ_INFO",
"PERMIT_CMD_INFO",
"PERMIT_SET",
"PERMIT_ADD",
"PERMIT_DEL",
"PERMIT_OPER",
"PERMIT_SUBS_VAL_CHANGE",
"PERMIT_SUBS_OBJ_ADD",
"PERMIT_SUBS_OBJ_DEL",
"PERMIT_SUBS_EVT_OPER_COMP"
]
},
"uniqueItems": true
}
},
"additionalProperties": false
},
"minItems": 1
}
},
"additionalProperties": false
}
},
"required": ["tr181"],
"additionalProperties": false
}

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=wifimngr
PKG_VERSION:=20.1.8
PKG_VERSION:=20.1.7
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=b1c3ea57d027412b3cc9f9ecf8db7c1cea2c5ce5
PKG_SOURCE_VERSION:=3ed71c1a4a46ad38dfa1088339fe92d2f2d44f41
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/wifimngr.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip