Compare commits

...

62 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
Jakob Olsson
9944917399 libwifi: 7.22.4 2025-10-27 17:30:35 +01:00
Amin Ben Romdhane
2a25fc0ec7 ieeee1905: 8.7.38 2025-10-27 17:12:52 +01:00
Jakob Olsson
ebd7e68714 map-controller: 6.4.4.4 2025-10-27 16:37:17 +01:00
Jakob Olsson
000762c0cb map-plugins: 1.2.2 2025-10-27 14:21:17 +01:00
Amin Ben Romdhane
c4328f411f decollector: 6.2.2.4 2025-10-24 14:32:49 +02:00
Vivek Kumar Dutta
0428934a69 bbfdm: 1.18.10 2025-10-24 16:30:02 +05:30
Erik Karlsson
580d24e04a logmngr: simplify default PID to 0 logic
Note that the "add" directive only adds if nothing is already present.
2025-10-24 10:28:37 +02:00
Mohd Husaam Mehdi
95778a4262 usermngr: added password expiry extension 2025-10-24 11:37:26 +05:30
Vivek Kumar Dutta
02ee448479 bbfdm: 1.18.9 2025-10-24 09:45:13 +05:30
Jakob Olsson
0dcc9743a2 map-agent: 6.4.3.5 2025-10-23 16:18:58 +02:00
Amin Ben Romdhane
1a1a1e1255 decollector: 6.2.2.3 2025-10-23 13:18:36 +02:00
Vivek Kumar Dutta
9710e46c51 obuspa: Fix group set method 2025-10-23 15:59:17 +05:30
Amin Ben Romdhane
19e69f7b61 decollector: 6.2.2.2 2025-10-23 11:18:47 +02:00
Mohd Husaam Mehdi
e319c85064 logmngr: set pid to 0 when it does not exist 2025-10-23 14:23:11 +05:30
Jakob Olsson
29638a28f7 map-agent: 6.4.3.4 2025-10-23 10:29:20 +02:00
Jakob Olsson
ccb337ecbd map-controller: 6.4.4.3 2025-10-23 10:27:39 +02:00
Amin Ben Romdhane
5474b1c6d0 wifidmd: 1.4.1: Move WiFi.DataElements Object to decollector 2025-10-22 12:40:46 +02:00
Amin Ben Romdhane
8df0ad8e46 decollector: 6.2.2.1: introduce WiFi.DataElements. tree 2025-10-22 12:40:34 +02:00
Jakob Olsson
6e358a6bd1 Revert "decollector: introduce data model"
This reverts commit 20a28db536.
2025-10-22 12:34:01 +02:00
Amin Ben Romdhane
20a28db536 decollector: introduce data model 2025-10-22 10:30:06 +00:00
Sukru Senli
c6ee9114bc netmode: skip obuspa restart 2025-10-22 08:58:33 +02:00
Sukru Senli
89fb4a0857 netmode: enable by default and auto-detect mode 2025-10-22 08:43:15 +02:00
Markus Gothe
8d86188ff1 obuspa: Fix spelling of log messages.
Abbrevations like UCI must be in capital letters.
Add correct punctation.
2025-10-21 16:27:34 +02:00
Jakob Olsson
18d6afea15 map-agent: 6.4.3.3 2025-10-21 10:41:58 +02:00
Vivek Kumar Dutta
0cb9aac1f1 userinterface: vendor extension for FirstLogin 2025-10-21 12:14:16 +05:30
Sukru Senli
dfe2af4643 netmode: fix static mode
and improve other modes
2025-10-20 16:45:09 +02:00
Amin Ben Romdhane
2fe133227d bbfdm: 1.18.8 2025-10-20 13:37:31 +02:00
Sukru Senli
15f17da6e5 netmode: add static mode and vlanid and dns servers as arguments to all modes 2025-10-20 12:52:39 +02:00
Vivek Kumar Dutta
2e56ef292c bbfdm:micro-services: Fix probable segfault during startup 2025-10-17 22:50:51 +05:30
Marina Maslova
65e4bebc0f libwifi: 7.22.3 2025-10-17 15:04:02 +04:00
Jakob Olsson
ceb577a6ab map-controller: config: add zerotouch, rate, bsteer plugins to default 2025-10-17 10:19:46 +02:00
Jakob Olsson
2d45a45126 map-agent: map_genconfig: add dpp_chirp section for 2.4GHz 2025-10-17 10:19:46 +02:00
Vivek Dutta
45294a9f0c usermngr: Only select shadow pam utils with security hardening
(cherry picked from commit 4e33db2700)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-10-17 11:19:59 +05:30
Jakob Olsson
eb5c837353 map-controller: 6.4.4.1 2025-10-16 16:37:54 +02:00
Vivek Kumar Dutta
495d95dcc8 icwmp: 9.10.5 2025-10-16 18:01:44 +05:30
Suvendhu Hansa
32e5dc46b3 usermngr: Vendor extension for Security Hardening parameters 2025-10-16 15:23:34 +05:30
Erik Karlsson
6980c1e2e5 ponmngr: use iopsys-environment for reading production data
U-Boot environment is kept as a fallback for legacy reasons.
2025-10-16 08:55:36 +00:00
Erik Karlsson
da727b4dc1 ponmngr: use get_mac_label to read MAC address 2025-10-16 08:55:36 +00:00
Vivek Kumar Dutta
d8aaacc4c9 obuspa: Optimize startup to avoid db corruption
- Force update values from uci on firmware update
- In case of reload(uci update), old sql db gets deleted and created from uci
- Use In memory sql journal mode
2025-10-16 12:30:35 +05:30
Vivek Kumar Dutta
e036702c16 wifidmd: align with bbfdm 2025-10-15 17:15:32 +05:30
Vivek Kumar Dutta
604a105bc9 usermngr: align with bbfdm 2025-10-15 17:15:32 +05:30
Vivek Kumar Dutta
04bdaa950f timemngr: align with bbfdm 2025-10-15 17:15:32 +05:30
Vivek Kumar Dutta
54fdaf2b43 sysmngr: align with bbfdm 2025-10-15 17:15:32 +05:30
Vivek Kumar Dutta
644e98e595 qosmngr: align with bbfdm 2025-10-15 17:15:31 +05:30
Vivek Kumar Dutta
9fc594d74f periodicstats: align with bbfdm 2025-10-15 17:15:31 +05:30
Vivek Kumar Dutta
ac7cfb581e parental-control: align with bbfdm 2025-10-15 17:15:31 +05:30
Vivek Kumar Dutta
ba75b33fc5 ethmngr: align with bbfdm 2025-10-15 17:15:31 +05:30
Vivek Kumar Dutta
912978164b bulkdata: align with bbfdm 2025-10-15 17:15:30 +05:30
Vivek Kumar Dutta
7a50c328e1 bbfdm: Fix typo in ubus APIs 2025-10-15 17:15:30 +05:30
Vivek Kumar Dutta
f8c9088db7 tr143: 1.1.8 2025-10-15 17:14:35 +05:30
Vivek Kumar Dutta
fd34c3e9f3 ethmngr: 3.1.1 2025-10-15 14:36:01 +05:30
Suvendhu Hansa
70d7d7a64d usermngr: Added password strength validation 2025-10-15 13:48:40 +05:30
Janusz Dziedzic
112f4cb99d wifimngr: 20.1.7 2025-10-15 05:48:52 +00:00
Jakob Olsson
2380a6de86 map-agent: 6.4.3.2 2025-10-14 17:22:30 +02:00
Filip Matusiak
b0c168322e self-diagnostics: get map-agent backhaul status 2025-10-14 16:12:41 +02:00
Filip Matusiak
22d8a0992c map-agent: 6.4.3.1 2025-10-14 16:12:33 +02:00
Janusz Dziedzic
3c075c293c wifimngr: 20.1.6 2025-10-13 16:25:56 +00:00
Suvendhu Hansa
17ae16e5d2 passwdqc: Install pwqcheck tool 2025-10-13 17:56:57 +05:30
Erik Karlsson
46dc9e86d8 logmngr: include pid when migrating also 2025-10-13 10:50:55 +02:00
Mohd Husaam Mehdi
0b3420240d logmngr: include pid in log output by fluent-bit 2025-10-10 19:33:27 +05:30
61 changed files with 1370 additions and 804 deletions

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bbfdm
PKG_VERSION:=1.18.5
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:=1596a6a8c1d5063587e92b61d1b12bdd51240c27
PKG_SOURCE_VERSION:=1a86b8a4432a2c3a9d41a9b18ccfc830bd0083cb
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bulkdata
PKG_VERSION:=2.1.21
PKG_VERSION:=2.1.23
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bulkdata.git
PKG_SOURCE_VERSION:=fdfffad21f1c0c15654c9a9740c5fb7beb6542e5
PKG_SOURCE_VERSION:=f54550f2d587a701c0a8d5cac4a0910a99ce92cf
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -4,4 +4,16 @@ config DECOLLECTOR_EASYMESH_VERSION
int "Support Easymesh version"
default 6
config DECOLLECTOR_BUILD_TR181_PLUGIN
bool "Build TR-181 mapping module (responsible for Device.WiFi.DataElements.)"
default y
config DECOLLECTOR_VENDOR_EXTENSIONS
bool "Iopsys vendor extensions for Device.WiFi.DataElements."
default y
config DECOLLECTOR_VENDOR_PREFIX
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""
endmenu

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=decollector
PKG_VERSION:=6.2.1.13
PKG_VERSION:=6.2.2.4
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=269aa271c2f8048dad9846be786620339a67bcaa
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
@@ -24,6 +24,7 @@ PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/decollector
SECTION:=utils
@@ -66,6 +67,18 @@ MAKE_PATH:=src
TARGET_CFLAGS += -DEASYMESH_VERSION=$(CONFIG_DECOLLECTOR_EASYMESH_VERSION)
ifeq ($(CONFIG_DECOLLECTOR_BUILD_TR181_PLUGIN),y)
MAKE_FLAGS += DECOLLECTOR_BUILD_TR181_PLUGIN=y
ifeq ($(CONFIG_DECOLLECTOR_VENDOR_EXTENSIONS),y)
TARGET_CFLAGS += -DDECOLLECTOR_VENDOR_EXTENSIONS
ifeq ($(CONFIG_DECOLLECTOR_VENDOR_PREFIX),"")
TARGET_CFLAGS += -DCUSTOM_PREFIX=\\\"$(CONFIG_BBF_VENDOR_PREFIX)\\\"
else
TARGET_CFLAGS += -DCUSTOM_PREFIX=\\\"$(CONFIG_DECOLLECTOR_VENDOR_PREFIX)\\\"
endif
endif
endif
EXECS := \
$(if $(CONFIG_PACKAGE_decollector),decollector)
@@ -76,6 +89,7 @@ define Package/decollector/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/decollector.init $(1)/etc/init.d/decollector
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/decollector $(1)/usr/sbin/
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
endef
$(eval $(call BuildPackage,decollector))

View File

@@ -0,0 +1,26 @@
{
"daemon": {
"enable": "1",
"service_name": "decollector",
"unified_daemon": true,
"services": [
{
"parent_dm": "Device.WiFi.",
"object": "DataElements"
}
],
"config": {
"loglevel": "3"
},
"apply_handler": {
"uci": [
{
"file": [
"mapcontroller"
],
"external_handler": "/etc/wifidmd/bbf_config_reload.sh"
}
]
}
}
}

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ethmngr
PKG_VERSION:=3.1.0
PKG_VERSION:=3.1.3
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/ethmngr.git
PKG_SOURCE_VERSION:=da6b25430123f03a74b59369b36dc4a777207d3f
PKG_SOURCE_VERSION:=7bc8297e1a74adb522f7635bab4f93a1a2620216
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=icwmp
PKG_VERSION:=9.10.4
PKG_VERSION:=9.10.5
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/icwmp.git
PKG_SOURCE_VERSION:=505d3d63e06d84b144ce2eb63ea89af723abf0ed
PKG_SOURCE_VERSION:=7f4a159f6ff49584655e57bb801218eb083fba67
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ieee1905
PKG_VERSION:=8.7.37
PKG_VERSION:=8.7.38
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=c711e1e132478d6443ffb5aad15d12b90f0d59b5
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

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libwifi
PKG_VERSION:=7.22.2
PKG_VERSION:=7.22.4
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=cd29f6bcb25f3e48be04244c042d13a908c2b6b1
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

@@ -8,7 +8,7 @@ config source 'default_source'
config template 'default_template'
option name 'default_template'
option expression '{time} {hostname} {ident}: {message}'
option expression '{time} {hostname} {ident}[{pid}]: {message}'
config action 'default_action'
option name 'default_action'

View File

@@ -11,7 +11,7 @@ fi
if ! uci -q get logmngr.default_template > /dev/null; then
uci -q set logmngr.default_template=template
uci -q set logmngr.default_template.name='default_template'
uci -q set logmngr.default_template.expression='{time} {hostname} {ident}: {message}'
uci -q set logmngr.default_template.expression='{time} {hostname} {ident}[{pid}]: {message}'
fi
if uci -q get logmngr.a1 >/dev/null; then

View File

@@ -77,6 +77,12 @@ create_default_filters() {
append_conf " rename msg message"
append_conf ""
append_conf "[FILTER]"
append_conf " name modify"
append_conf " match *"
append_conf " add pid 0"
append_conf ""
append_conf "[FILTER]"
append_conf " name sysinfo"
append_conf " match *"

View File

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

View File

@@ -49,19 +49,16 @@ generate_multiap_config() {
2g)
mode_band=2
priority=2
dpp_chan="81/1"
channels="1 6 11"
;;
5g)
mode_band=5
priority=1
dpp_chan="128/36"
channels="36-64 100-112"
;;
6g)
mode_band=6
priority=0
dpp_chan="133/49"
;;
esac
@@ -162,13 +159,17 @@ generate_multiap_config() {
uci set mapagent.@bsta[-1].band="$mode_band"
uci set mapagent.@bsta[-1].priority="$priority"
#uci add mapagent dpp_uri
#uci set mapagent.@dpp_uri[-1].type="qrcode"
#uci set mapagent.@dpp_uri[-1].device="$device"
#uci set mapagent.@dpp_uri[-1].ifname="$ifname"
#uci set mapagent.@dpp_uri[-1].band="$mode_band"
#uci set mapagent.@dpp_uri[-1].chirp_interval="10"
#uci add_list mapagent.@dpp_uri[-1].dpp_chan="$dpp_chan"
# add dpp_chirp section for 2.4GHz bSTA
if [ $mode_band -eq 2 ]; then
uci add mapagent dpp_chirp
uci set mapagent.@dpp_chirp[-1].type="qrcode"
uci set mapagent.@dpp_chirp[-1].device="$device"
uci set mapagent.@dpp_chirp[-1].ifname="$ifname"
uci set mapagent.@dpp_chirp[-1].band="$mode_band"
for channel in $channels; do
uci add_list mapagent.@dpp_chirp[-1].channel="$channel"
done
fi
if [ $generate_wireless_sta_config -eq 1 ]; then
secname="default_sta_${device}"

View File

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

View File

@@ -9,6 +9,7 @@ config controller 'controller'
option primary_pcp '0'
option stale_sta_timeout '20d'
option de_collect_interval '60'
list plugin 'zerotouch'
config sta_steering 'sta_steering'
option enable_sta_steer '1'
@@ -22,6 +23,8 @@ config sta_steering 'sta_steering'
option plugins_enabled '1'
option plugins_policy 'any'
list plugins 'rcpi'
list plugins 'rate'
list plugins 'bsteer'
config channel_plan 'channel_plan'
option preclear_dfs '0'

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-plugins
PKG_VERSION:=1.2.1
PKG_VERSION:=1.2.2
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=a76610182366cf05ed7e8f5fbac26890b709eeb4
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

@@ -1,4 +1,4 @@
if PACKAGE_mosquitto-auth-shadow
if PACKAGE_mosquitto-auth-plugin
config MOSQUITTO_AUTH_PAM_SUPPORT
bool "Enable support of Linux PAM module for Authentication"

View File

@@ -13,8 +13,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mosquitto-auth-shadow
PKG_VERSION:=1.1.0
PKG_NAME:=mosquitto-auth-plugin
PKG_VERSION:=1.2.0
PKG_MAINTAINER:=Erik Karlsson <erik.karlsson@genexis.eu>
PKG_LICENSE:=EPL-2.0
@@ -24,7 +24,7 @@ PKG_CONFIG_DEPENDS:=CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT
include $(INCLUDE_DIR)/package.mk
define Package/mosquitto-auth-shadow
define Package/mosquitto-auth-plugin
SECTION:=net
CATEGORY:=Network
TITLE:=mosquitto - /etc/shadow authentication plugin
@@ -32,12 +32,12 @@ define Package/mosquitto-auth-shadow
USERID:=mosquitto=200:mosquitto=200 mosquitto=200:shadow=11
endef
define Package/mosquitto-auth-shadow/description
define Package/mosquitto-auth-plugin/description
Plugin for the mosquitto MQTT message broker that authenticates
users using /etc/shadow
endef
define Package/mosquitto-auth-shadow/config
define Package/mosquitto-auth-plugin/config
source "$(SOURCE)/Config.in"
endef
@@ -45,10 +45,10 @@ ifeq ($(CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT),y)
TARGET_CFLAGS+=-DENABLE_PAM_SUPPORT
endif
define Package/mosquitto-auth-shadow/install
define Package/mosquitto-auth-plugin/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_shadow.so $(1)/usr/lib/
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,mosquitto-auth-shadow))
$(eval $(call BuildPackage,mosquitto-auth-plugin))

View File

@@ -11,14 +11,14 @@
# Erik Karlsson - initial implementation
#
TARGETS = mosquitto_auth_shadow.so
TARGETS = mosquitto_auth_plugin.so
all: $(TARGETS)
%.pic.o: %.c
$(CC) $(CFLAGS) -Wall -Werror -fPIC -c -o $@ $<
mosquitto_auth_shadow.so: mosquitto_auth_shadow.pic.o
mosquitto_auth_plugin.so: mosquitto_auth_plugin.pic.o
$(CC) $(LDFLAGS) -shared -o $@ $^ $(if $(filter -DENABLE_PAM_SUPPORT,$(CFLAGS)),-lpam)
clean:

View File

@@ -0,0 +1,530 @@
/*
* Copyright (c) 2022 Genexis B.V.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Erik Karlsson - initial implementation
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <shadow.h>
#include <crypt.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <mosquitto.h>
#include <mosquitto_broker.h>
#include <mosquitto_plugin.h>
#ifdef ENABLE_PAM_SUPPORT
#include <security/pam_appl.h>
#endif
#define MAX_USERS 256
#define MAX_SUBNETS_PER_USER 32
typedef struct {
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;
} user_acl_t;
typedef struct {
user_acl_t users[MAX_USERS];
int user_count;
mosquitto_plugin_id_t *identifier;
} plugin_data_t;
/* Parse CIDR notation (e.g., "192.168.1.0/24") */
static int parse_subnet(const char *cidr, subnet_t *subnet)
{
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';
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;
}
if (inet_pton(AF_INET, ip_str, &addr) != 1)
return -1;
subnet->network = ntohl(addr.s_addr);
subnet->netmask = prefix_len == 0 ? 0 : (~0U << (32 - prefix_len));
subnet->network &= subnet->netmask;
return 0;
}
/* Check if IP is in subnet */
static int ip_in_subnet(uint32_t ip, const subnet_t *subnet)
{
return (ip & subnet->netmask) == subnet->network;
}
/* Check if IP is in any subnet in the list */
static int ip_in_subnet_list(uint32_t ip, const subnet_t *subnets, int count)
{
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;
/* 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;
}
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;
}
/* Parse subnet ACL file
* Format:
* # Comment lines
* subnet allow <username> <cidr>
* subnet deny <username> <cidr>
*/
static int load_subnet_acl_config(plugin_data_t *pdata, const char *config_file)
{
FILE *fp;
char line[512];
int line_num = 0;
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 */
}
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;
line_num++;
/* 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++;
/* 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;
/* 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_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_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_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_WARNING,
"subnet_acl: Missing CIDR at line %d", line_num);
continue;
}
/* 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: 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_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);
} 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);
}
}
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);
}
}
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Loaded subnet restrictions for %d user(s)", pdata->user_count);
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;
}
/* ACL check for subnet validation */
static int acl_check_callback(int event, void *event_data, void *userdata)
{
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_PLUGIN_DEFER;
}
/* Get username from client */
username = mosquitto_client_username(ed->client);
/* Skip anonymous users */
if (username == NULL) {
return MOSQ_ERR_PLUGIN_DEFER;
}
/* Find user's subnet ACL */
user_acl = find_user_acl(pdata, username);
/* 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;
}
/* 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;
}
/* Skip localhost checks - always allow */
if (strcmp(client_address, "127.0.0.1") == 0 || strcmp(client_address, "::1") == 0) {
return MOSQ_ERR_PLUGIN_DEFER;
}
/* 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)
{
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;
}
#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;
}
#endif
static int basic_auth_callback(int event, void *event_data, void *userdata)
{
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
return process_pam_auth_callback(ed);
#else
return process_shadow_auth_callback(ed);
#endif
}
int mosquitto_plugin_version(int supported_version_count,
const int *supported_versions)
{
return 5;
}
int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier,
void **user_data,
struct mosquitto_opt *opts, int opt_count)
{
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;
}
}
pdata = calloc(1, sizeof(plugin_data_t));
if (pdata == NULL)
return MOSQ_ERR_NOMEM;
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;
}
/* 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);
return MOSQ_ERR_SUCCESS;
}
int mosquitto_plugin_cleanup(void *user_data,
struct mosquitto_opt *opts, int opt_count)
{
plugin_data_t *pdata = user_data;
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;
}

View File

@@ -1,153 +0,0 @@
/*
* Copyright (c) 2022 Genexis B.V.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Erik Karlsson - initial implementation
*/
#define _GNU_SOURCE
#include <string.h>
#include <shadow.h>
#include <crypt.h>
#include <stdlib.h>
#include <mosquitto.h>
#include <mosquitto_broker.h>
#include <mosquitto_plugin.h>
#ifdef ENABLE_PAM_SUPPORT
#include <security/pam_appl.h>
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;
}
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;
}
#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;
}
#endif
static int basic_auth_callback(int event, void *event_data, void *userdata)
{
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
return process_pam_auth_callback(ed);
#else
return process_shadow_auth_callback(ed);
#endif
}
int mosquitto_plugin_version(int supported_version_count,
const int *supported_versions)
{
return 5;
}
int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier,
void **user_data,
struct mosquitto_opt *opts, int opt_count)
{
*user_data = identifier;
return mosquitto_callback_register(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL, NULL);
}
int mosquitto_plugin_cleanup(void *user_data,
struct mosquitto_opt *opts, int opt_count)
{
mosquitto_plugin_id_t *identifier = user_data;
return mosquitto_callback_unregister(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
}

View File

@@ -1,2 +1,2 @@
config netmode global
option enabled 0
option enabled 1

View File

@@ -17,6 +17,8 @@ l3_mcast_config() {
l3_network_config() {
logger -s -p user.info -t "netmode" "Generating L3 network configuration"
wandev="$(uci -q get network.WAN.ifname)"
# Configure L3 Network Mode
uci -q set network.lan=interface
uci -q set network.lan.device='br-lan'
@@ -36,11 +38,35 @@ l3_network_config() {
uci -q delete network.wan.disabled
uci -q delete network.wan.username
uci -q delete network.wan.password
uci -q delete network.wan.ipaddr
uci -q delete network.wan.gateway
uci -q delete network.wan.netmask
uci -q set network.wan6=interface
uci -q set network.wan6.proto='dhcpv6'
uci -q delete network.wan6.disabled
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
uci -q set network.vlan_${NETMODE_vlanid}=device
uci -q set network.vlan_${NETMODE_vlanid}.type="8021q"
uci -q set network.vlan_${NETMODE_vlanid}.name="$wandev.$NETMODE_vlanid"
uci -q set network.vlan_${NETMODE_vlanid}.ifname="$wandev"
uci -q set network.vlan_${NETMODE_vlanid}.vid=$NETMODE_vlanid
wandev="$wandev.$NETMODE_vlanid"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.wan6.device="$wandev"
uci -q delete network.wan.dns
if [ -n "$NETMODE_dns_servers" ]; then
dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
for server in $dns_servers; do
uci -q add_list network.wan.dns=$server
done
fi
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
@@ -61,12 +87,6 @@ l3_network_config() {
[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
fi
json_select ..
json_select wan 2>/dev/null
json_get_var device device
if [ -n "$device" ]; then
uci -q set network.wan.device="$device"
uci -q set network.wan6.device="$device"
fi
json_cleanup
fi

View File

@@ -17,6 +17,8 @@ l3_mcast_config() {
l3_network_pppoe_config() {
logger -s -p user.info -t "netmode" "Generating L3 network configuration"
wandev="$(uci -q get network.WAN.ifname)"
# Configure L3 Network Mode
uci -q set network.lan=interface
uci -q set network.lan.device='br-lan'
@@ -36,9 +38,33 @@ l3_network_pppoe_config() {
uci -q set network.wan.username="$NETMODE_username"
uci -q set network.wan.password="$NETMODE_password"
uci -q delete network.wan.disabled
uci -q delete network.wan.ipaddr
uci -q delete network.wan.gateway
uci -q delete network.wan.netmask
uci -q set network.wan6.disabled='1'
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
uci -q set network.vlan_${NETMODE_vlanid}=device
uci -q set network.vlan_${NETMODE_vlanid}.type="8021q"
uci -q set network.vlan_${NETMODE_vlanid}.name="$wandev.$NETMODE_vlanid"
uci -q set network.vlan_${NETMODE_vlanid}.ifname="$wandev"
uci -q set network.vlan_${NETMODE_vlanid}.vid=$NETMODE_vlanid
wandev="$wandev.$NETMODE_vlanid"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.wan6.device="$wandev"
uci -q delete network.wan.dns
if [ -n "$NETMODE_dns_servers" ]; then
dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
for server in $dns_servers; do
uci -q add_list network.wan.dns=$server
done
fi
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
@@ -59,12 +85,6 @@ l3_network_pppoe_config() {
[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
fi
json_select ..
json_select wan 2>/dev/null
json_get_var device device
if [ -n "$device" ]; then
uci -q set network.wan.device="$device"
uci -q set network.wan6.device="$device"
fi
json_cleanup
fi

View File

@@ -0,0 +1,127 @@
#!/bin/sh
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
source "/etc/device_info"
l3_mcast_config() {
# configure L3 mcast config
logger -s -p user.info -t "netmode" "Generating L3 mcast configuration"
rm -f /etc/config/mcast
sh /rom/etc/uci-defaults/61-mcast_config_generate
uci -q commit mcast
}
l3_network_config() {
logger -s -p user.info -t "netmode" "Generating L3 network configuration"
wandev="$(uci -q get network.WAN.ifname)"
# Configure L3 Network Mode
uci -q set network.lan=interface
uci -q set network.lan.device='br-lan'
uci -q set network.lan.proto='static'
uci -q set network.lan.ipaddr='192.168.1.1'
uci -q set network.lan.netmask='255.255.255.0'
uci -q set network.lan.ip6assign='60'
uci -q delete network.lan.vendorid
uci -q delete network.lan.clientid
uci -q delete network.lan.reqopts
uci -q delete network.lan.sendopts
uci -q delete network.lan6
uci -q set network.wan=interface
uci -q set network.wan.device="$wandev"
uci -q set network.wan.proto='static'
uci -q set network.wan.ipaddr="$NETMODE_ipaddr"
uci -q set network.wan.gateway="$NETMODE_gateway"
uci -q set network.wan.netmask="$NETMODE_netmask"
uci -q delete network.wan.disabled
uci -q delete network.wan.username
uci -q delete network.wan.password
uci -q set network.wan6.disabled='1'
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
uci -q set network.vlan_${NETMODE_vlanid}=device
uci -q set network.vlan_${NETMODE_vlanid}.type="8021q"
uci -q set network.vlan_${NETMODE_vlanid}.name="$wandev.$NETMODE_vlanid"
uci -q set network.vlan_${NETMODE_vlanid}.ifname="$wandev"
uci -q set network.vlan_${NETMODE_vlanid}.vid=$NETMODE_vlanid
wandev="$wandev.$NETMODE_vlanid"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.wan6.device="$wandev"
uci -q delete network.wan.dns
if [ -n "$NETMODE_dns_servers" ]; then
dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
for server in $dns_servers; do
uci -q add_list network.wan.dns=$server
done
fi
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
add_port_to_br_lan() {
port="$1"
[ -n "$port" -a -d /sys/class/net/$port ] || continue
uci add_list network.br_lan.ports="$port"
}
if [ -f /etc/board.json ]; then
json_load_file /etc/board.json
json_select network
json_select lan
if json_is_a ports array; then
json_for_each_item add_port_to_br_lan ports
else
json_get_var device device
[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
fi
json_select ..
json_cleanup
fi
uci -q commit network
# Enable DHCP Server
uci -q set dhcp.lan.ignore=0
uci -q set dhcp.wan.ignore=1
uci -q commit dhcp
/etc/init.d/odhcpd enable
# Enable SSDPD
uci -q set ssdpd.ssdp.enabled="1"
uci -q commit ssdpd
# Update CWMP Agent WAN Interface
uci -q set cwmp.cpe.default_wan_interface="wan"
uci -q commit cwmp
# Update gateway WAN Interface
uci -q set gateway.global.wan_interface="wan"
uci -q commit gateway
# Enable firewall
uci -q set firewall.globals.enabled="1"
uci -q commit firewall
}
l3_network_config
l3_mcast_config
# If device is already boot-up, assume netmode changed during runtime
if [ -f /var/run/boot_complete ]; then
/etc/init.d/odhcpd restart 2>/dev/null
for config in network dhcp ssdpd cwmp gateway firewall mcast; do
ubus call uci commit "{\"config\":\"$config\"}"
sleep 1
done
fi

View File

@@ -3,25 +3,90 @@
"supported_modes": [
{
"name": "routed-dhcp",
"description": "WAN with DHCP proto (Layer 3)"
"description": "DHCP",
"supported_args": [
{
"name": "vlanid",
"description": "VLAN ID",
"required": false,
"type": "integer"
},
{
"name": "dns_servers",
"description": "DNS Servers",
"required": false,
"type": "string"
}
]
},
{
"name": "routed-pppoe",
"description": "WAN with PPPoE (Layer 3)",
"description": "PPPoE",
"supported_args": [
{
"name": "username",
"description": "PPPoE username",
"description": "PPPoE Username",
"required": true,
"type": "string",
"type": "string",
"#value": "TestUser"
},
{
"name": "password",
"description": "PPPoE password",
"description": "PPPoE Password",
"required": true,
"type": "string",
"type": "string",
"#value": "TestPassword"
},
{
"name": "vlanid",
"description": "VLAN ID",
"required": false,
"type": "integer"
},
{
"name": "dns_servers",
"description": "DNS Servers",
"required": false,
"type": "string"
}
]
},
{
"name": "routed-static",
"description": "Static",
"supported_args": [
{
"name": "ipaddr",
"description": "IP Address",
"required": true,
"type": "string",
"#value": "93.21.0.104"
},
{
"name": "netmask",
"description": "Subnet Mask",
"required": true,
"type": "string",
"#value": "255.255.255.0"
},
{
"name": "gateway",
"description": "Default Gateway",
"required": true,
"type": "string",
"#value": "93.21.0.1"
},
{
"name": "vlanid",
"description": "VLAN ID",
"required": false,
"type": "integer"
},
{
"name": "dns_servers",
"description": "DNS Servers",
"required": false,
"type": "string"
}
]
}

View File

@@ -0,0 +1,29 @@
#!/bin/sh
enabled="$(uci -q get netmode.global.enabled)"
[ "$enabled" == "1" ] || exit 0
mode="$(uci -q get netmode.global.mode)"
[ -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" ;;
pppoe) curmode="routed-pppoe" ;;
static) curmode="routed-static" ;;
esac
found=0
for md in $(jsonfilter -i /etc/netmodes/supported_modes.json -e "@.supported_modes.*.name"); do
[ "$md" == "$curmode" ] && found=1
done
if [ $found -eq 1 ]; then
uci -q set netmode.global.mode="$curmode"
echo "$curmode" > /etc/netmodes/.last_mode
fi

View File

@@ -19,7 +19,3 @@ fi
if [ -x "/etc/init.d/bbfdmd" ]; then
/etc/init.d/bbfdmd restart
fi
if [ -x "/etc/init.d/obuspa" ]; then
/etc/init.d/obuspa restart
fi

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=obuspa
PKG_VERSION:=10.0.7.4
PKG_VERSION:=10.0.7.5
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/obuspa.git
PKG_SOURCE_VERSION:=84d5ae575134d501b8ca171a5a65c6f410f01d08
PKG_SOURCE_VERSION:=f3b5b79476adadc55830de9466361c0eeced473e
PKG_MAINTAINER:=Vivek Dutta <vivek.dutta@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
@@ -32,8 +32,9 @@ define Package/obuspa
SUBMENU:=TRx69
TITLE:=USP agent
MENU:=1
DEPENDS:=+libopenssl +libuci +libblobmsg-json +libcurl +libsqlite3 +libubox +libubus +libmosquitto-ssl +libwebsockets-openssl +ca-certificates \
+OBUSPA_LOCAL_MQTT_LISTENER:mosquitto-ssl +libjson-c
DEPENDS:=+libopenssl +libcurl +libsqlite3 +libmosquitto-ssl +libwebsockets-openssl
DEPENDS+=+libjson-c +libubox +libubus +libuci +libblobmsg-json
DEPENDS+=+ca-certificates +OBUSPA_LOCAL_MQTT_LISTENER:mosquitto-ssl
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
endef

View File

@@ -6,19 +6,18 @@ USE_PROCD=1
PROG=/usr/sbin/obuspa
CONFIGURATION=obuspa
FIRST_BOOT="/etc/obuspa/boot_marker"
ENV_PROFILE="/root/.profile"
KEEP_FILE="/lib/upgrade/keep.d/obuspa"
RESET_FILE="/tmp/obuspa/fw_defaults"
SQL_DB_FILE="/tmp/obuspa/usp.db"
DB_DUMP="/tmp/obuspa/usp.dump_$(date +%s)"
OBUSPA_BOOT_MARKER="/etc/obuspa/.boot"
BASEPATH=""
INSTANCE_COUNT=0
CLIENT_ID_PREFIX=""
. /lib/functions/network.sh
. /usr/share/libubox/jshn.sh
. /etc/obuspa/usp_utils.sh
global_init()
@@ -30,6 +29,7 @@ global_init()
log()
{
echo "$*"|logger -t obuspa.init -p debug
echo "$*" >/dev/console
}
db_set_reset_file()
@@ -47,37 +47,9 @@ db_set_reset_file()
fi
}
db_set_sql()
{
local param value
param="${1}"
shift
value="$*"
if [ -n "${param}" ] && [ -n "${value}" ]; then
if grep -q "${param} " ${DB_DUMP}; then
value="${value//\//\\/}"
sed -i "s/${param} .*/${param} \"${value}\"/g" ${DB_DUMP}
else
echo "${param} \"${value}\"" >> ${DB_DUMP}
fi
fi
}
db_set()
{
# if sql db dump file present, update it
if [ -f "${DB_DUMP}" ]; then
db_set_sql "$@"
else
db_set_reset_file "$@"
fi
}
dump_db()
{
${PROG} -v0 -f ${SQL_DB_FILE} -c show database |grep "^Internal.\|^Device."|sed '{s/=> /"/g;s/$/"/g}' | sort > ${DB_DUMP}
db_set_reset_file "$@"
}
# if db present then check if it matches with existing instances
@@ -92,21 +64,6 @@ get_base_path()
path=""
count=0
if [ -f "${DB_DUMP}" ]; then
path=$(grep -E "${refpath}\d+.Alias \"${value}\"" ${DB_DUMP})
path=${path%.*}
if [ -z "${path}" ]; then
path=$(grep -oE "${refpath}\d+" ${DB_DUMP} |sort -r|head -n 1)
if [ -n "${path}" ]; then
count=${path##*.}
count=$(( count + 1 ))
else
count=1
fi
path="${refpath}${count}"
fi
fi
if [ -z "${path}" ]; then
INSTANCE_COUNT=$(( INSTANCE_COUNT + 1 ))
path="${refpath}${INSTANCE_COUNT}"
@@ -122,9 +79,7 @@ get_refrence_path()
value="${2}"
path=""
if [ -f "${DB_DUMP}" ]; then
path=$(grep -E "${dmref}\d+.Alias " ${DB_DUMP}|grep -w "${value}")
elif [ -f "${RESET_FILE}" ]; then
if [ -f "${RESET_FILE}" ]; then
path=$(grep -E "${dmref}\d+.Alias " ${RESET_FILE}|grep -w "${value}")
fi
path=${path%.*}
@@ -136,7 +91,7 @@ update_keep()
file=${1}
if [ -z "${file}" ]; then
return;
return 0
fi
if [ ! -f "${KEEP_FILE}" ]; then
@@ -263,7 +218,7 @@ configure_localagent()
validate_localagent_section "${1}" || {
log "Validation of localagent section failed"
return 0;
return 0
}
db_set Device.LocalAgent.EndpointID "${EndpointID}"
@@ -271,7 +226,7 @@ configure_localagent()
update_reset_reason()
{
[ -f "/tmp/reset_reason" ] || return 0;
[ -f "/tmp/reset_reason" ] || return 0
if grep -qwi "defaultreset" /tmp/reset_reason; then
db_set Internal.Reboot.Cause "FactoryReset"
@@ -310,10 +265,6 @@ get_role_index()
val="$(grep "Device.LocalAgent.ControllerTrust.Role.\d.Name" ${CTRUST_RESET_FILE} |grep $name)"
val="$(echo ${val/.Name /,}|cut -d, -f 1)"
echo "$val"
elif [ -f "${DB_DUMP}" ]; then
val="$(grep "Device.LocalAgent.ControllerTrust.Role.\d.Name" ${DB_DUMP} |grep $name)"
val="$(echo ${val/.Name /,}|cut -d, -f 1)"
echo "$val"
else
log "Not able to get role ${name}, use Untrusted role"
echo "${drole}"
@@ -331,19 +282,19 @@ configure_controller()
sec="${1}"
validate_controller_section "${1}" || {
log "Validation of controller section failed"
return 1;
return 1
}
sec="${sec/controller_/cpe-}"
get_base_path "Device.LocalAgent.Controller." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
return 1
fi
if [ -z "${Protocol}" ]; then
log "controller:: Protocol cannot be empty"
return 1;
return 1
fi
dm_ref=""
@@ -439,14 +390,14 @@ configure_subscription()
sec="${1}"
validate_subscription_section "${1}" || {
log "Validation of subscription section failed"
return 1;
return 1
}
sec="${sec/sub_/cpe-}"
get_base_path "Device.LocalAgent.Subscription." "sub_${1}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
return 1
fi
if [ -n "${controller}" ]; then
@@ -483,12 +434,12 @@ configure_challenges()
get_base_path "Device.LocalAgent.ControllerTrust.Challenge." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
return 1
fi
if [ -z "${role_name}" ] && [ -z "${Role}" ]; then
log "Either role_name or Role must defined for a challenge";
return 1;
log "Either role_name or Role must defined for a challenge"
return 1
fi
db_set "${BASEPATH}.Alias" "${sec}"
@@ -515,18 +466,18 @@ configure_mtp() {
sec="${1}"
validate_mtp_section "${1}" || {
log "Validation of mtp section failed"
return 1;
return 1
}
sec="${sec/mtp_/cpe-}"
get_base_path "Device.LocalAgent.MTP." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
return 1
fi
if [ -z "${Protocol}" ]; then
log "Protocol not defined for the mtp[${1}] section"
return 1;
return 1
fi
dm_ref=""
@@ -584,14 +535,14 @@ configure_stomp_connection() {
sec="${1}"
validate_stomp_connection_section "${1}" || {
log "Validation of stomp section failed"
return 1;
return 1
}
sec="${sec/stomp_/cpe-}"
get_base_path "Device.STOMP.Connection." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
return 1
fi
db_set "${BASEPATH}.Alias" "${sec}"
@@ -614,14 +565,18 @@ configure_mqtt_client() {
sec="${1}"
validate_mqtt_client_section "${1}" || {
log "Validation of mqtt section failed"
return 1;
return 1
}
sec="${sec/mqtt_/cpe-}"
get_base_path "Device.MQTT.Client." "${sec}"
if [ -z "${BASEPATH}" ]; then
log "Failed to get path [$BASEPATH]"
return 1;
return 1
fi
if [ -z "${ClientID}" ]; then
ClientID="${CLIENT_ID_PREFIX}-${sec}"
fi
db_set "${BASEPATH}.Alias" "${sec}"
@@ -648,6 +603,9 @@ configure_obuspa() {
fi
if [ -n "${log_level}" ]; then
if [ "${log_level}" -gt "4" ]; then
log_level="4"
fi
procd_append_param command -v "${log_level}"
fi
@@ -676,13 +634,13 @@ configure_obuspa() {
if [ -n "${db_file}" ]; then
update_keep "${db_file}"
procd_append_param command -f "${SQL_DB_FILE}"
procd_append_param command -f "${db_file}"
if [ -f "${db_file}-journal" ]; then
log "SQL Journal detected ..."
fi
fi
if [ -f "${RESET_FILE}" ]; then
if [ -f "${SQL_DB_FILE}" ]; then
mv ${SQL_DB_FILE} ${SQL_DB_FILE}.old
fi
procd_append_param command -r ${RESET_FILE}
fi
@@ -701,306 +659,34 @@ configure_obuspa() {
fi
}
get_instances_from_db_dump()
{
local obj inst
obj="${1}\d+"
if [ ! -f "${DB_DUMP}" ]; then
echo ""
return 0;
fi
inst="$(grep -oE "${obj}" "${DB_DUMP}"|uniq)"
echo "$inst"
}
get_param_value_from_dump()
{
local param value
param="${1}"
if [ -z "${param}" ] || [ ! -f "${DB_DUMP}" ]; then
log "error getting param"
echo ""
return 0
fi
value="$(grep "^${param} " ${DB_DUMP}|awk '{print $2}')"
echo "${value//\"/}"
}
update_uci_sec()
{
local sec tmp
sec="${1}"
stype="${2}"
if [ -z "$sec" ] || [ -z "$stype" ]; then
log "No section name, error"
return 0
fi
tmp="$(uci_get obuspa "${sec}")"
if [ "$tmp" != "$stype" ]; then
uci_add obuspa "${stype}" "${sec}"
fi
}
sync_db_controller()
{
local cntrs copts sec pvalue protocol
copts="Enable EndpointID PeriodicNotifInterval"
popts="Destination Topic Host Port Path EnableEncryption"
cntrs="$(get_instances_from_db_dump Device.LocalAgent.Controller.)"
for cntr in $cntrs; do
sec="$(get_param_value_from_dump "${cntr}".Alias)"
sec="${sec/cpe-/controller_}"
sec="${sec/-/_}"
update_uci_sec "${sec}" controller
for param in ${copts}; do
pvalue="$(get_param_value_from_dump "${cntr}"."${param}")"
uci_set obuspa "${sec}" "${param}" "${pvalue}"
done
uci_set obuspa "${sec}" "_sync" "1"
protocol="$(get_param_value_from_dump "${cntr}".MTP.1.Protocol)"
if [ -z "${protocol}" ]; then
break;
fi
uci_set obuspa "${sec}" "Protocol" "${protocol}"
for param in ${popts}; do
pvalue="$(get_param_value_from_dump "${cntr}".MTP.1."${protocol}"."${param}")"
uci_set obuspa "${sec}" "${param}" "${pvalue}"
done
done
}
sync_db_localagent_mtp()
{
local mtps opts popts sec pvalue protocol
opts="Enable"
popts="ResponseTopicConfigured Destination Port Path EnableEncryption PublishQoS"
mtps="$(get_instances_from_db_dump Device.LocalAgent.MTP.)"
for inst in $mtps; do
sec="$(get_param_value_from_dump "${inst}".Alias)"
sec="${sec/cpe-/mtp_}"
sec="${sec/-/_}"
update_uci_sec "${sec}" mtp
for param in ${opts}; do
pvalue="$(get_param_value_from_dump "${inst}"."${param}")"
uci_set obuspa "${sec}" "${param}" "${pvalue}"
done
uci_set obuspa "${sec}" "_sync" "1"
protocol="$(get_param_value_from_dump "${inst}".Protocol)"
if [ -z "${protocol}" ]; then
break;
fi
uci_set obuspa "${sec}" "Protocol" "${protocol}"
for param in ${popts}; do
pvalue="$(get_param_value_from_dump "${inst}"."${protocol}"."${param}")"
uci_set obuspa "${sec}" "${param}" "${pvalue}"
done
done
}
sync_db_mqtt_client()
{
local mtps copts sec pvalue protocol
opts="Enable BrokerAddress BrokerPort Username ProtocolVersion TransportProtocol ClientID"
mtps="$(get_instances_from_db_dump Device.MQTT.Client.)"
for inst in $mtps; do
sec="$(get_param_value_from_dump "${inst}".Alias)"
sec="${sec/cpe-/mqtt_}"
sec="${sec/-/_}"
update_uci_sec "${sec}" mqtt
for param in ${opts}; do
pvalue="$(get_param_value_from_dump "${inst}"."${param}")"
uci_set obuspa "${sec}" "${param}" "${pvalue}"
done
uci_set obuspa "${sec}" "_sync" "1"
done
}
sync_db_stomp_connection()
{
local mtps copts sec pvalue protocol
opts="Enable Host Port Username EnableEncryption EnableHeartbeats VirtualHost"
mtps="$(get_instances_from_db_dump Device.STOMP.Connection.)"
for inst in $mtps; do
sec="$(get_param_value_from_dump "${inst}".Alias)"
sec="${sec/cpe-/stomp_}"
sec="${sec/-/_}"
update_uci_sec "${sec}" stomp
for param in ${opts}; do
pvalue="$(get_param_value_from_dump "${inst}"."${param}")"
uci_set obuspa "${sec}" "${param}" "${pvalue}"
done
uci_set obuspa "${sec}" "_sync" "1"
done
}
sync_update_sec()
{
local _sync
config_get _sync "${1}" _sync ""
if [ -z "${_sync}" ]; then
uci_remove obuspa "${1}"
log "Deleting obuspa.${1} section ..."
else
uci_remove obuspa "${1}" _sync
fi
}
sync_uci_with_db()
{
if [ ! -f "${DB_DUMP}" ]; then
return 0;
fi
# Skip overriding uci in case of Firstboot
if [ ! -f "${FIRST_BOOT}" ]; then
return 0
fi
log "Syncing obuspa uci with usp.db ...."
config_load obuspa
sync_db_controller
sync_db_localagent_mtp
sync_db_mqtt_client
sync_db_stomp_connection
uci_commit obuspa
config_load obuspa
config_foreach sync_update_sec controller
config_foreach sync_update_sec mtp
config_foreach sync_update_sec mqtt
config_foreach sync_update_sec stomp
uci_commit obuspa
}
delete_sql_db_entry_with_pattern()
{
local params pattern
pattern="${1}"
if [ ! -f "${DB_DUMP}" ]; then
return 0;
fi
if [ "${#pattern}" -lt 7 ]; then
return 0;
fi
#log "Deleting with pattern [${pattern}] from ${DB_DUMP}"
sed -i "/${pattern}/d" ${DB_DUMP}
}
check_n_delete_db()
{
local sec t r path
sec="${1}"
if uci -q get obuspa."${sec}" >/dev/null 2>&1; then
return 0
fi
t="${2}"
r="${3}"
sec="${sec/${t}_/cpe-}"
path=$(grep -E "${r}\d+.Alias \"${sec}\"" ${DB_DUMP})
path=${path%.*}
delete_sql_db_entry_with_pattern "${path}"
}
workaround_remove_download_pattern()
{
local inst
inst="$(cat ${DB_DUMP} |grep -E "Device.DeviceInfo.FirmwareImage.\d.Download()"|grep -oE "Device.LocalAgent.Request.\d.")"
if [ -n "${inst}" ]; then
log "Workaround to remove the old download Request [$inst]"
delete_sql_db_entry_with_pattern "${inst}"
fi
}
reverse_update_db_with_uci()
{
if [ ! -f "${DB_DUMP}" ]; then
return 0;
fi
export UCI_CONFIG_DIR="/tmp/obuspa"
config_load obuspa
config_foreach check_n_delete_db controller controller "Device.LocalAgent.Controller."
config_foreach check_n_delete_db mtp mtp "Device.LocalAgent.MTP."
config_foreach check_n_delete_db mqtt mqtt "Device.MQTT.Client."
config_foreach check_n_delete_db stomp stomp "Device.STOMP.Connection."
unset UCI_CONFIG_DIR
}
# Create factory reset file
db_init()
{
local reason role_file
local reason
reason="${1}"
mkdir -p /tmp/obuspa/
# Load configuration
config_load $CONFIGURATION
config_get SQL_DB_FILE global db_file "/tmp/obuspa/usp.db"
config_get role_file global role_file ""
if [ -f "${SQL_DB_FILE}.old" ] && [ ! -f "${SQL_DB_FILE}" ]; then
log "Copying old db, since new db not present ..."
mv ${SQL_DB_FILE}.old ${SQL_DB_FILE}
# remove usp.db, in case of reload
if [ -f "${OBUSPA_BOOT_MARKER}" ] && [ "${reason}" = "update" ]; then
log "Deleting ${OBUSPA_BOOT_MARKER} in order to enforce values from UCI..."
rm -f "${OBUSPA_BOOT_MARKER}"
fi
# Dump datamodel parameters from DB
if [ -f "${SQL_DB_FILE}" ]; then
dump_db
fi
# In case of Reboot or service restart update the uci
# from usp.db file
if [ -f "${DB_DUMP}" ] && [ "${reason}" != "update" ]; then
# Only do this if db have reasonable data
val="$(awk 'END{print NR}' ${DB_DUMP})"
if [ "$val" -gt 15 ]; then
sync_uci_with_db
fi
fi
# remove entries from db if deleted from uci, only in case of reload
if [ -f "${DB_DUMP}" ] && [ "${reason}" = "update" ] && [ -f "/tmp/obuspa/obuspa" ]; then
log "Deleting entries from usp.db if uci not present ...."
reverse_update_db_with_uci
if [ -f "${OBUSPA_BOOT_MARKER}" ]; then
return 0
fi
# Remove reset file if present
[ -f "${RESET_FILE}" ] && mv ${RESET_FILE} ${RESET_FILE}.old
[ -f "${RESET_FILE}" ] && rm ${RESET_FILE}
CLIENT_ID_PREFIX="$(db -q get device.deviceinfo.ManufacturerOUI)"
CLIENT_ID_PREFIX="${CLIENT_ID_PREFIX}-$(db -q get device.deviceinfo.SerialNumber)"
CLIENT_ID_PREFIX="${CLIENT_ID_PREFIX//+/%2b}"
#log "Create reset file ...."
config_load $CONFIGURATION
config_get dualstack_pref global dualstack_pref "IPv6"
log "Enforcing UCI values, no boot marker found."
global_init
config_foreach configure_localagent localagent
global_init
@@ -1016,22 +702,12 @@ db_init()
global_init
config_foreach configure_challenges challenge
# enforce ctrust only on upgrades, not on reloads
if [ -f "${CTRUST_RESET_FILE}" ] && [ -z "${reason}" ]; then
cat ${CTRUST_RESET_FILE} >> ${RESET_FILE}
fi
update_reset_reason
update_dual_stack_pref "${dualstack_pref}"
uci_commit ${CONFIGURATION}
cp /etc/config/obuspa /tmp/obuspa/
if [ -f "${DB_DUMP}" ]; then
workaround_remove_download_pattern
mv ${DB_DUMP} ${RESET_FILE}
fi
if [ -f "${CTRUST_RESET_FILE}" ]; then
cat ${CTRUST_RESET_FILE} >> ${RESET_FILE}
rm ${CTRUST_RESET_FILE}
fi
[ -f "${FIRST_BOOT}" ] || touch "${FIRST_BOOT}"
}
start_service() {
@@ -1043,8 +719,8 @@ start_service() {
procd_open_instance ${CONFIGURATION}
if [ "${enabled}" -eq 1 ]; then
db_init "${1}"
procd_set_param command ${PROG}
db_init "${1}"
configure_obuspa
procd_set_param respawn \
"${respawn_threshold:-10}" \
@@ -1054,9 +730,7 @@ start_service() {
}
stop_service() {
if command -v timeout >/dev/null 2>&1; then
timeout 5 ${PROG} -c stop
fi
${PROG} -c stop
}
reload_service() {
@@ -1065,5 +739,6 @@ reload_service() {
}
service_triggers() {
export PROCD_RELOAD_DELAY=3000
procd_add_reload_trigger "obuspa"
}

View File

@@ -1,10 +1,12 @@
#!/bin/sh
CTRUST_RESET_FILE="/tmp/obuspa/ctrust_reset"
CTRUST_RESET_FILE="/etc/obuspa/ctrust_reset"
VENDOR_PREFIX_FILE="/etc/obuspa/vendor_prefix"
FW_DEFAULT_ROLE_DIR="/etc/users/roles"
SECURE_ROLES=""
CTRUST_RESET_FILE_TEMP="/tmp/obuspa/ctrust_reset"
mkdir -p /tmp/obuspa/
# include jshn.sh
@@ -23,9 +25,9 @@ db_add()
value="$*"
if [ -n "${param}" ] && [ -n "${value}" ]; then
echo "${param} \"${value}\"">>${CTRUST_RESET_FILE}
echo "${param} \"${value}\"">>${CTRUST_RESET_FILE_TEMP}
else
echo >>${CTRUST_RESET_FILE}
echo >>${CTRUST_RESET_FILE_TEMP}
fi
}
@@ -252,7 +254,10 @@ configure_ctrust_role()
if [ -n "${SECURE_ROLES}" ]; then
db_add Device.LocalAgent.ControllerTrust.SecuredRoles "${SECURE_ROLES}"
fi
if [ -f "${CTRUST_RESET_FILE_TEMP}" ]; then
mv -f "${CTRUST_RESET_FILE_TEMP}" "${CTRUST_RESET_FILE}"
fi
}
# configure_ctrust_role "${@}"

View File

@@ -4,5 +4,3 @@
. /etc/obuspa/usp_utils.sh
configure_ctrust_role
exit 0

View File

@@ -8,6 +8,7 @@ RETRY_MIN_INTERVAL="5"
RETRY_INTERVAL_MUL="2000"
ENDPOINT_ID=""
CONTROLLER_DISCOVERED=0
OBUSPA_BOOT_MARKER="/etc/obuspa/.boot"
log()
{
@@ -272,6 +273,17 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
fi
done
# Check if any of the existing controller section matches with the endpointid
if [ -z "${dhcp_controller}" ] && [ -n "${ENDPOINT_ID}" ]; then
for controller in $controllers; do
endpointid=$(uci -q get obuspa."${controller}".EndpointID)
if [ "${endpointid}" = "${ENDPOINT_ID}" ]; then
dhcp_controller="${controller}"
break
fi
done
fi
if [ -n "${dhcp_controller}" ]; then
cont_proto=$(uci -q get obuspa."${dhcp_controller}".Protocol)
if [ "${cont_proto}" = "MQTT" ]; then
@@ -376,8 +388,7 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
fi
if [ -z "${dhcp_mtp}" ]; then
sec=$(uci -q add obuspa mtp)
uci -q rename obuspa."${sec}"='dhcpmtp'
uci -q set obuspa.dhcpmtp="mtp"
dhcp_mtp="dhcpmtp"
uci -q set obuspa."${dhcp_mtp}".Enable='1'
fi
@@ -394,8 +405,7 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
user="$(uci -q get obuspa.global.username)"
pass="$(uci -q get obuspa.global.password)"
sec=$(uci -q add obuspa mqtt)
uci -q rename obuspa."${sec}"='dhcpmqtt'
uci -q set obuspa.dhcpmqtt="mqtt"
dhcp_mqtt="dhcpmqtt"
uci -q set obuspa."${dhcp_mqtt}".Enable='1'
uci -q set obuspa."${dhcp_mqtt}".Username="${user}"
@@ -408,8 +418,7 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
uci -q set obuspa."${dhcp_mqtt}".ProtocolVersion='5.0'
if [ -z "${dhcp_mtp}" ]; then
sec=$(uci -q add obuspa mtp)
uci -q rename obuspa."${sec}"='dhcpmtp'
uci -q set obuspa.dhcpmtp="mtp"
dhcp_mtp="dhcpmtp"
uci -q set obuspa."${dhcp_mtp}".Enable='1'
fi
@@ -467,64 +476,64 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
fi
fi
else
uci -q delete obuspa.dhcpmtp
uci -q delete obuspa.dhcpmqtt
# Only setup a new controller, only if mandatory param present
if [ -n "${ENDPOINT_ID}" ] && [ -n "${URL}" ]; then
uci -q delete obuspa.dhcpmtp
uci -q delete obuspa.dhcpmqtt
sec=$(uci -q add obuspa controller)
uci -q rename obuspa."${sec}"='dhcpcontroller'
uci -q set obuspa.dhcpcontroller.dhcp_discovered="1"
uci -q set obuspa.dhcpcontroller.EndpointID="${ENDPOINT_ID}"
uci -q set obuspa.dhcpcontroller.ProvisioningCode="${PROV_CODE}"
uci -q set obuspa.dhcpcontroller.Protocol="${offered_proto}"
uci -q set obuspa.dhcpcontroller.assigned_role_name="$(get_access_role)"
uci -q set obuspa.dhcpcontroller.Enable='1'
uci -q set obuspa.dhcpcontroller="controller"
uci -q set obuspa.dhcpcontroller.dhcp_discovered="1"
uci -q set obuspa.dhcpcontroller.EndpointID="${ENDPOINT_ID}"
uci -q set obuspa.dhcpcontroller.ProvisioningCode="${PROV_CODE}"
uci -q set obuspa.dhcpcontroller.Protocol="${offered_proto}"
uci -q set obuspa.dhcpcontroller.assigned_role_name="$(get_access_role)"
uci -q set obuspa.dhcpcontroller.Enable='1'
if [ -n "${offered_proto}" ]; then
if [ "${offered_proto}" = "MQTT" ]; then
user="$(uci -q get obuspa.global.username)"
pass="$(uci -q get obuspa.global.password)"
if [ -n "${offered_proto}" ]; then
if [ "${offered_proto}" = "MQTT" ]; then
user="$(uci -q get obuspa.global.username)"
pass="$(uci -q get obuspa.global.password)"
uci -q set obuspa.dhcpcontroller.Topic="${topic}"
uci -q set obuspa.dhcpcontroller.mqtt='dhcpmqtt'
uci -q set obuspa.dhcpcontroller.Topic="${topic}"
uci -q set obuspa.dhcpcontroller.mqtt='dhcpmqtt'
sec=$(uci -q add obuspa mqtt)
uci -q rename obuspa."${sec}"='dhcpmqtt'
uci -q set obuspa.dhcpmqtt.BrokerAddress="${ip}"
uci -q set obuspa.dhcpmqtt.BrokerPort="${port}"
uci -q set obuspa.dhcpmqtt.TransportProtocol="${mtp_encrypt}"
uci -q set obuspa.dhcpmqtt.Enable='1'
uci -q set obuspa.dhcpmqtt.ProtocolVersion='5.0'
uci -q set obuspa.dhcpmqtt.Username="${user}"
uci -q set obuspa.dhcpmqtt.Password="${pass}"
uci -q set obuspa.dhcpmqtt="mqtt"
uci -q set obuspa.dhcpmqtt.BrokerAddress="${ip}"
uci -q set obuspa.dhcpmqtt.BrokerPort="${port}"
uci -q set obuspa.dhcpmqtt.TransportProtocol="${mtp_encrypt}"
uci -q set obuspa.dhcpmqtt.Enable='1'
uci -q set obuspa.dhcpmqtt.ProtocolVersion='5.0'
uci -q set obuspa.dhcpmqtt.Username="${user}"
uci -q set obuspa.dhcpmqtt.Password="${pass}"
agent_topic=$(get_agent_topic)
sec=$(uci -q add obuspa mtp)
uci -q rename obuspa."${sec}"='dhcpmtp'
uci -q set obuspa.dhcpmtp.Protocol='MQTT'
uci -q set obuspa.dhcpmtp.ResponseTopicConfigured="${agent_topic}"
uci -q set obuspa.dhcpmtp.Enable='1'
uci -q set obuspa.dhcpmtp.mqtt='dhcpmqtt'
else
uci -q set obuspa.dhcpcontroller.Path="${topic}"
uci -q set obuspa.dhcpcontroller.Host="${ip}"
uci -q set obuspa.dhcpcontroller.Port="${port}"
uci -q set obuspa.dhcpcontroller.EnableEncryption="${mtp_encrypt}"
agent_topic=$(get_agent_topic)
uci -q set obuspa.dhcpmtp="mtp"
uci -q set obuspa.dhcpmtp.Protocol='MQTT'
uci -q set obuspa.dhcpmtp.ResponseTopicConfigured="${agent_topic}"
uci -q set obuspa.dhcpmtp.Enable='1'
uci -q set obuspa.dhcpmtp.mqtt='dhcpmqtt'
else
uci -q set obuspa.dhcpcontroller.Path="${topic}"
uci -q set obuspa.dhcpcontroller.Host="${ip}"
uci -q set obuspa.dhcpcontroller.Port="${port}"
uci -q set obuspa.dhcpcontroller.EnableEncryption="${mtp_encrypt}"
sec=$(uci -q add obuspa mtp)
uci -q rename obuspa."${sec}"='dhcpmtp'
uci -q set obuspa.dhcpmtp.Protocol='WebSocket'
uci -q set obuspa.dhcpmtp.Port="${port}"
uci -q set obuspa.dhcpmtp.Enable='1'
uci -q set obuspa.dhcpmtp.EnableEncryption="${mtp_encrypt}"
uci -q set obuspa.dhcpmtp="mtp"
uci -q set obuspa.dhcpmtp.Protocol='WebSocket'
uci -q set obuspa.dhcpmtp.Port="${port}"
uci -q set obuspa.dhcpmtp.Enable='1'
uci -q set obuspa.dhcpmtp.EnableEncryption="${mtp_encrypt}"
fi
fi
uci_change=1
fi
uci_change=1
fi
if [ ${uci_change} -eq 1 ]; then
if [ -f "${OBUSPA_BOOT_MARKER}" ]; then
rm -f "${OBUSPA_BOOT_MARKER}"
fi
log "# Reloading obuspa as dhcp config changed"
ubus call uci commit '{"config":"obuspa"}'
fi

View File

@@ -0,0 +1,28 @@
diff --git a/src/core/database.c b/src/core/database.c
index 7ad9dae..edebd7c 100644
--- a/src/core/database.c
+++ b/src/core/database.c
@@ -955,6 +955,7 @@ void DATABASE_Dump(void)
int OpenUspDatabase(char *db_file)
{
int err;
+ char *err_msg = 0;
// Exit if unable to open the database
err = sqlite3_open(db_file, &db_handle);
@@ -965,6 +966,15 @@ int OpenUspDatabase(char *db_file)
return USP_ERR_INTERNAL_ERROR;
}
+ // Execute the PRAGMA statement
+ const char *sql = "PRAGMA journal_mode = MEMORY;";
+ err = sqlite3_exec(db_handle, sql, 0, 0, &err_msg);
+ if (err != SQLITE_OK) {
+ USP_LOG_Error("%s: Failed to set journal_mode: %s", __func__, err_msg);
+ sqlite3_free(err_msg);
+ return USP_ERR_INTERNAL_ERROR;
+ }
+
// Exit if unable to create the data model parameter table (if it does not already exist)
#define CREATE_TABLE_STR "create table if not exists data_model (hash integer, instances text, value text, primary key (hash, instances));"
err = sqlite3_exec(db_handle, CREATE_TABLE_STR, NULL, NULL, NULL);

View File

@@ -0,0 +1,23 @@
diff --git a/src/core/database.c b/src/core/database.c
index 7ad9dae..0bf9c90 100644
--- a/src/core/database.c
+++ b/src/core/database.c
@@ -1479,3 +1479,7 @@ int GetAllEntriesForParameter(db_hash_t hash, kv_vector_t *kvv)
return result;
}
+void DATABASE_force_reset_file()
+{
+ schedule_factory_reset_init = true;
+}
diff --git a/src/core/database.h b/src/core/database.h
index c88cf3a..376aa7a 100644
--- a/src/core/database.h
+++ b/src/core/database.h
@@ -67,5 +67,6 @@ void DATABASE_Dump(void);
int DATABASE_ReadDataModelInstanceNumbers(bool remove_unknown_params);
db_hash_t DATABASE_GetMigratedHash(db_hash_t hash);
+void DATABASE_force_reset_file();
#endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=parental-control
PKG_VERSION:=1.4.1
PKG_VERSION:=1.4.3
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/parental-control.git
PKG_SOURCE_VERSION:=995bbe59d74a3b589dd3b7f4491875e37aa7e24a
PKG_SOURCE_VERSION:=f7ec652c763bf6ffd550bf7d51b2c125774b79af
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -30,7 +30,7 @@ define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
pam_wrapped
all_wrapped
endef
define Package/$(PKG_NAME)/install
@@ -39,6 +39,9 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/lib/security
$(INSTALL_BIN) $(PKG_BUILD_DIR)/pam_passwdqc.so $(1)/usr/lib/security/
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/pwqcheck $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=periodicstats
PKG_VERSION:=1.6.1
PKG_VERSION:=1.6.3
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/periodicstats.git
PKG_SOURCE_VERSION:=dd8353d84ef9431936d09c7379d0e4b20035cdb3
PKG_SOURCE_VERSION:=351db77e982b1f4887e5878345fe98be72d262fb
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

22
ponmngr/files/common/etc/uci-defaults/60-xpon-generate Executable file → Normal file
View File

@@ -1,13 +1,17 @@
#!/bin/sh
. /lib/functions/system.sh
. /lib/functions/iopsys-environment.sh
configure_serial_number() {
# check if serial number is present in the production data
local production_sn="$(fw_printenv -n gponsn)"
local production_sn="$(get_xpon_serial 2>/dev/null)"
[ ${#production_sn} -eq 12 ] || production_sn="$(fw_printenv -n gponsn)"
if [ ${#production_sn} -eq 12 ]; then
uci set xpon.ani.serial_number="${production_sn}"
else
local macaddr="$(fw_printenv -n ethaddr | tr -d ':' | tr 'a-z' 'A-Z')"
local macaddr="$(get_mac_label | tr -d ':' | tr 'a-z' 'A-Z')"
local vendor_id="IOPS"
local vssn="${macaddr:4:8}"
@@ -20,8 +24,10 @@ configure_ploam_password() {
local passwd="$(uci -q get xpon.ani.ploam_password)"
if [ -z "${passwd}" ]; then
local production_passwd="$(fw_printenv -n gponpswd)"
if [ -n ${#production_passwd} ]; then
local production_passwd="$(get_xpon_password 2>/dev/null)"
[ -n "${production_passwd}" ] || production_passwd="$(fw_printenv -n gponpswd)"
if [ -n "${production_passwd}" ]; then
uci set xpon.ani.ploam_password="${production_passwd}"
uci set xpon.ani.ploam_hexadecimalpassword=0
fi
@@ -36,10 +42,12 @@ configure_loid_authentication() {
local loidpwd="$(uci -q get xpon.ani.loid_password)"
if [ -z "${loid}" ]; then
production_loid="$(fw_printenv -n gponloid)"
production_loid="$(get_xpon_loid 2>/dev/null)"
[ -n "${production_loid}" ] || production_loid="$(fw_printenv -n gponloid)"
fi
if [ -z "${loidpwd}" ]; then
production_loidpwd="$(fw_printenv -n gponloid_password)"
production_loidpwd="$(get_xpon_loid_password 2>/dev/null)"
[ -n "${production_loidpwd}" ] || production_loidpwd="$(fw_printenv -n gponloid_password)"
fi
if [ -n "${production_loid}" ]; then
@@ -48,7 +56,6 @@ configure_loid_authentication() {
if [ -n "${production_loidpwd}" ]; then
uci set xpon.ani.loid_password="${production_loidpwd}"
fi
}
if [ -s "/etc/config/xpon" ]; then
@@ -72,4 +79,3 @@ uci set xpon.ani.enable="1"
configure_serial_number
configure_ploam_password
configure_loid_authentication

View File

@@ -6,13 +6,13 @@ include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=qosmngr
PKG_VERSION:=1.1.0
PKG_VERSION:=1.1.2
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/qosmngr.git
PKG_SOURCE_VERSION:=1a15f1da7a1474d29aad77b8ad3272fcf4b4f6d1
PKG_SOURCE_VERSION:=ee6692438c5d533758c2ea50624c049cda2d07da
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -51,6 +51,10 @@
"description": "MAP Agent Backhaul Info",
"cmd": "ubus call map.agent backhaul_info"
},
{
"description": "MAP Agent Backhaul Status",
"cmd": "ubus call map.agent backhaul"
},
{
"description": "MAP Controller Status",
"cmd": "ubus call map.controller status"

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sysmngr
PKG_VERSION:=1.0.28
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:=5a3b6d0cbb023353c1b16069d68f203589b77e27
PKG_SOURCE_VERSION:=8d150fae12ad42885c270051189572d59255244d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=timemngr
PKG_VERSION:=1.1.11
PKG_VERSION:=1.1.13
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/timemngr.git
PKG_SOURCE_VERSION:=af7ae9ba1f88321294c35ef7afa5a64fa3b459fa
PKG_SOURCE_VERSION:=9817c0ad15dea444258c9e0de6975f43fdc3e99a
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=tr143
PKG_VERSION:=1.1.7
PKG_VERSION:=1.1.8
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/tr143d.git
PKG_SOURCE_VERSION:=366dbb1424bcf17ca47cce6a9f723e7ada35f5ed
PKG_SOURCE_VERSION:=5f8404e01e5e4478de528027fa12717c1a2256f3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -20,4 +20,16 @@ config USERINTERFACE_HTTPACCESS_MIGRATE_NGINX_CONFIG
default n
help
Migrate nginx to userinterface on firmware upgrade
config USERINTERFACE_VENDOR_EXTENSIONS
bool "Include vendor extensions for UserInterface object"
default y
help
Includes datamodel Vendor extensions for UserIntercace object
config USERINTERFACE_VENDOR_PREFIX
depends on USERINTERFACE_VENDOR_EXTENSIONS
string "Vendor Prefix for userinterface datamodel extensions"
default ""
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=userinterface
PKG_VERSION:=1.1.8
PKG_VERSION:=1.1.9
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/userinterface.git
PKG_SOURCE_VERSION:=a5970a83b8ac79c4577edc6a994b850cdbe1c82f
PKG_SOURCE_VERSION:=52f8bff5941c5e91d7ed8eed33cf5adf364960c5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -42,6 +42,15 @@ define Package/$(PKG_NAME)/config
source "$(SOURCE)/Config.in"
endef
ifeq ($(CONFIG_USERINTERFACE_VENDOR_EXTENSIONS),y)
TARGET_CFLAGS += -DUSERINTERFACE_VENDOR_EXTENSIONS
ifeq ($(CONFIG_USERINTERFACE_VENDOR_PREFIX),"")
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(CONFIG_BBF_VENDOR_PREFIX)\\\"
else
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(CONFIG_USERINTERFACE_VENDOR_PREFIX)\\\"
endif
endif
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/userinterface/* $(PKG_BUILD_DIR)/

View File

@@ -5,4 +5,17 @@ config USERMNGR_SECURITY_HARDENING
default y
help
Enable this option to use PAM based faillock, passwdqc, faildelay for security hardening.
config USERMNGR_ENABLE_VENDOR_EXT
depends on USERMNGR_SECURITY_HARDENING
bool "Expose vendor datamodel extensions."
default y
help
Enable this option to expose TR181 vendor extensions.
config USERMNGR_VENDOR_PREFIX
depends on USERMNGR_ENABLE_VENDOR_EXT
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=usermngr
PKG_VERSION:=1.4.1
PKG_VERSION:=1.4.6
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/usermngr.git
PKG_SOURCE_VERSION:=0df79dc0c76bb0d4e903e19b20f85b51de0800a1
PKG_SOURCE_VERSION:=416c49b53ed2fbbc983f404c65b8a8ce722152bd
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -32,10 +32,11 @@ define Package/usermngr
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +bbfdmd
DEPENDS+=+@BUSYBOX_CONFIG_ADDUSER +@BUSYBOX_CONFIG_DELUSER +@BUSYBOX_CONFIG_ADDGROUP +@BUSYBOX_CONFIG_DELGROUP +shadow-usermod
DEPENDS+=+@BUSYBOX_CONFIG_CMP
DEPENDS+=+@SHADOW_UTILS_USE_PAM
DEPENDS+=+@USERMNGR_SECURITY_HARDENING:SHADOW_UTILS_USE_PAM
DEPENDS+=+@USERMNGR_SECURITY_HARDENING:BUSYBOX_CONFIG_PAM
DEPENDS+=+USERMNGR_SECURITY_HARDENING:linux-pam
DEPENDS+=+USERMNGR_SECURITY_HARDENING:passwdqc
DEPENDS+=+USERMNGR_ENABLE_VENDOR_EXT:shadow-chage
TITLE:=Package to add Device.Users. datamodel support
endef
@@ -53,6 +54,22 @@ define Build/Prepare
endef
endif
ifeq ($(CONFIG_USERMNGR_SECURITY_HARDENING),y)
MAKE_FLAGS += USERMNGR_SECURITY_HARDENING=y
endif
ifeq ($(CONFIG_USERMNGR_ENABLE_VENDOR_EXT),y)
MAKE_FLAGS += USERMNGR_ENABLE_VENDOR_EXT=y
endif
ifeq ($(CONFIG_USERMNGR_VENDOR_PREFIX),"")
VENDOR_PREFIX = $(CONFIG_BBF_VENDOR_PREFIX)
else
VENDOR_PREFIX = $(CONFIG_USERMNGR_VENDOR_PREFIX)
endif
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(VENDOR_PREFIX)\\\"
define Package/usermngr/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
@@ -64,6 +81,9 @@ define Package/usermngr/install
ifeq ($(CONFIG_USERMNGR_SECURITY_HARDENING),y)
$(INSTALL_BIN) ./files/etc/uci-defaults/91-security-hardening $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/91-set-ssh-pam $(1)/etc/uci-defaults/
else
$(INSTALL_BIN) ./files/etc/uci-defaults/91-disabled-security $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/91-unset-ssh-pam $(1)/etc/uci-defaults/
endif
$(INSTALL_BIN) ./files/etc/init.d/users $(1)/etc/init.d/users
$(INSTALL_BIN) ./files/etc/config/users $(1)/etc/config/users

View File

@@ -1,17 +1,3 @@
config security_policy 'security_policy'
option enabled '1'
option fail_delay '3'
option faillock_attempts '6'
option faillock_lockout_time '300'
config passwdqc 'passwdqc'
option enabled '1'
option min 'disabled,disabled,disabled,8,8'
option max '20'
option passphrase '0'
option retry '3'
option enforce 'everyone'
config users 'users'
option enabled '1'
option loglevel '3'

View File

@@ -16,10 +16,18 @@ REQUIRED_MODULES="
/usr/lib/security/pam_passwdqc.so
"
log() {
echo "$*" | logger -t user.init -p info
}
log_err() {
echo "$*" | logger -t user.init -p err
}
check_required_modules() {
for mod in $REQUIRED_MODULES; do
if [ ! -f "$mod" ]; then
logger -p err -t usermngr "ERROR: Cannot setup security policy, missing PAM module: $mod"
log_err "ERROR: Cannot setup security policy, missing PAM module: $mod"
return 1
fi
done
@@ -41,7 +49,7 @@ compare_and_replace() {
if [ ! -f "$dst" ] || ! cmp -s "$src" "$dst"; then
cp "$src" "$dst"
logger -t pam_policy_setup "Updated $dst"
log "Updated $dst"
fi
}
@@ -51,17 +59,31 @@ update_auth() {
tmp_file="/tmp/common-auth"
pam_file="/etc/pam.d/common-auth"
local auth_enabled="${1}"
local enabled="${2}"
local faildelay="$(uci -q get users.authentication_policy.fail_delay)"
local faillock_lockout_time="$(uci -q get users.authentication_policy.faillock_lockout_time)"
local faillock_attempts="$(uci -q get users.authentication_policy.faillock_attempts)"
[ -n "$faildelay" ] || faildelay=3
[ -n "$faillock_attempts" ] || faillock_attempts=6
[ -n "$faillock_lockout_time" ] || faillock_lockout_time=300
# Convert seconds to microseconds for pam_faildelay
local faildelay_usec=$((faildelay * 1000000))
rm -f "$tmp_file"
touch "$tmp_file"
if [ "$enabled" != "0" ]; then
if [ "${auth_enabled}" -eq 1 ] && [ "${enabled}" -eq 1 ]; then
write_line "$tmp_file" "auth optional pam_faildelay.so delay=$faildelay_usec"
write_line "$tmp_file" "auth required pam_faillock.so preauth deny=$faillock_attempts even_deny_root unlock_time=$faillock_lockout_time"
fi
write_line "$tmp_file" "auth sufficient pam_unix.so nullok_secure"
if [ "$enabled" != "0" ]; then
if [ "${auth_enabled}" -eq 1 ] && [ "${enabled}" -eq 1 ]; then
write_line "$tmp_file" "auth [default=die] pam_faillock.so authfail audit deny=$faillock_attempts even_deny_root unlock_time=$faillock_lockout_time"
write_line "$tmp_file" ""
fi
@@ -103,7 +125,8 @@ update_password() {
local tmp_file pam_file enabled line
tmp_file="/tmp/common-password"
pam_file="/etc/pam.d/common-password"
enabled=1
local auth_enabled="${1}"
rm -f "$tmp_file"
touch "$tmp_file"
@@ -112,7 +135,7 @@ update_password() {
if uci -q get users.passwdqc >/dev/null 2>&1; then
# if enabled is not present it is assumed to be 0
enabled=$(uci -q get users.passwdqc.enabled || echo "0")
if [ "$enabled" != "0" ]; then
if [ "${auth_enabled}" -eq 1 ] && [ "${enabled}" -eq 1 ]; then
line="$(build_pam_passwdqc_line)"
write_line "$tmp_file" "$line"
fi
@@ -132,10 +155,13 @@ update_account() {
tmp_file="/tmp/common-account"
pam_file="/etc/pam.d/common-account"
local auth_enabled="${1}"
local enabled="${2}"
rm -f "$tmp_file"
touch "$tmp_file"
if [ "$enabled" != "0" ]; then
if [ "${auth_enabled}" -eq 1 ] && [ "${enabled}" -eq 1 ]; then
write_line "$tmp_file" "account required pam_faillock.so"
fi
@@ -147,29 +173,99 @@ update_account() {
compare_and_replace "$tmp_file" "$pam_file"
}
update_password_expiry() {
local user password_expiry shadow_entry lastchg_days lastchg_epoch expiry_epoch expiry_days max_days current_max_days
user="$1"
# Fetch expiry (in yyyy-mm-dd format) from UCI
config_get password_expiry "$user" password_expiry
# Get /etc/shadow entry for the user
shadow_entry="$(grep "^${user}:" /etc/shadow 2>/dev/null)"
if [ -z "$shadow_entry" ]; then
log_err "No shadow entry found for $user, skipping"
return
fi
current_max_days="$(echo "$shadow_entry" | cut -d: -f5)"
# Handle infinite lifetime (no expiry set)
if [ -z "$password_expiry" ]; then
if [ "$current_max_days" = "-1" ] || [ -z "$current_max_days" ]; then
log "Password for $user already set to never expire, no action needed"
else
chage -M -1 "$user"
log "Set password expiry for $user to never expire (previous max_days=$current_max_days)"
fi
return
fi
# option value is of the form 9999-12-31T23:59:59Z, so extract date
# because shadow/chage only allow us to specify expiry date
password_expiry="$(echo "$password_expiry" | cut -d 'T' -f 1)"
# Validate date format (yyyy-mm-dd)
if ! echo "$password_expiry" | grep -Eq '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'; then
log_err "Invalid password_expiry format for $user: '$password_expiry' (expected yyyy-mm-dd)"
return
fi
# Convert expiry date to epoch seconds
expiry_epoch="$(date -d "$password_expiry" +%s 2>/dev/null)"
if [ -z "$expiry_epoch" ]; then
log_err "Failed to parse expiry date '$password_expiry' for $user"
return
fi
# Extract 'lastchg' field (3rd colon-separated field)
lastchg_days="$(echo "$shadow_entry" | cut -d: -f3)"
if [ -z "$lastchg_days" ] || [ "$lastchg_days" = "0" ]; then
log_err "No valid last password change date for $user, skipping"
return
fi
# Convert lastchg_days to epoch seconds
lastchg_epoch=$(( lastchg_days * 86400 ))
# Compute difference in days between expiry and last change
expiry_days=$(( (expiry_epoch - lastchg_epoch) / 86400 ))
# round up to full day, because of this expiry_days can never be 0, but I think that is a non-issue
expiry_days=$(( expiry_days + 1 ))
if [ "$expiry_days" -lt 0 ]; then
log_err "Expiry date for $user ($password_expiry) is before last password change, skipping"
return
fi
max_days="$expiry_days"
# Apply update if changed
if [ "$current_max_days" != "$max_days" ]; then
chage -M "$max_days" "$user"
log "Updated max_days for $user to $max_days (expiry=$password_expiry, lastchg_days=$lastchg_days)"
else
log "max_days for $user already set to $max_days (expiry=$password_expiry), no change"
fi
}
handle_security_policy() {
local enabled faildelay faillock_lockout_time faillock_attempts faildelay_usec
local auth_enabled enabled
config_load users
config_foreach update_password_expiry user
# Read UCI values
enabled="$(uci -q get users.security_policy.enabled)"
faildelay="$(uci -q get users.security_policy.fail_delay)"
faillock_lockout_time="$(uci -q get users.security_policy.faillock_lockout_time)"
faillock_attempts="$(uci -q get users.security_policy.faillock_attempts)"
auth_enabled="$(uci -q get users.users.auth_policy_enable || echo 0)"
enabled="$(uci -q get users.authentication_policy.enabled || echo 0)"
# if any .so files are missing, then we cannot setup security
if ! check_required_modules; then
return
fi
[ -n "$faildelay" ] || faildelay=3
[ -n "$faillock_attempts" ] || faillock_attempts=6
[ -n "$faillock_lockout_time" ] || faillock_lockout_time=300
# Convert seconds to microseconds for pam_faildelay
faildelay_usec=$((faildelay * 1000000))
update_auth
update_account
update_password
update_auth "${auth_enabled}" "${enabled}"
update_account "${auth_enabled}" "${enabled}"
update_password "${auth_enabled}"
}
start_service() {
@@ -196,6 +292,7 @@ reload_service() {
stop
start
else
handle_security_policy
ubus send usermngr.reload
fi

View File

@@ -0,0 +1,16 @@
#!/bin/sh
# Remove auth_policy_enable from global
if uci -q get users.users; then
uci -q set users.users.auth_policy_enable=''
else
uci -q set users.users='users'
fi
# Remove authentication_policy section
uci -q del users.authentication_policy
# Remove passwdqc section
uci -q del users.passwdqc
exit 0

View File

@@ -1,12 +1,19 @@
#!/bin/sh
# Create default security_policy section if missing
if ! uci -q get users.security_policy; then
uci -q set users.security_policy='security_policy'
uci -q set users.security_policy.enabled='1'
uci -q set users.security_policy.fail_delay='3'
uci -q set users.security_policy.faillock_attempts='6'
uci -q set users.security_policy.faillock_lockout_time='300'
# Create global section
if ! uci -q get users.users; then
uci -q set users.users='users'
fi
uci -q set users.users.auth_policy_enable='1'
# Create default authentication_policy section if missing
if ! uci -q get users.authentication_policy; then
uci -q set users.authentication_policy='authentication_policy'
uci -q set users.authentication_policy.enabled='1'
uci -q set users.authentication_policy.fail_delay='3'
uci -q set users.authentication_policy.faillock_attempts='6'
uci -q set users.authentication_policy.faillock_lockout_time='300'
fi
# Create default passwdqc section if missing

View File

@@ -0,0 +1,8 @@
#!/bin/sh
if [ -f /etc/config/sshd ]; then
uci -q set sshd.@sshd[0].UsePAM=0
fi
exit 0

View File

@@ -26,60 +26,6 @@
}
]
}
},
"Device.WiFi.DataElements.Network.Device.{i}.Radio.{i}.BSS.{i}.STA.{i}.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": true,
"{BBF_VENDOR_PREFIX}QoERating": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "-1.0",
"datatype": "string",
"mapping": [
{
"data": "@Parent",
"type": "json",
"key": "Rating"
}
]
}
},
"Device.WiFi.DataElements.Network.Device.{i}.APMLD.{i}.STAMLD.{i}.": {
"type": "object",
"protocols": [
"cwmp",
"usp"
],
"access": false,
"array": true,
"{BBF_VENDOR_PREFIX}QoERating": {
"type": "string",
"read": true,
"write": false,
"protocols": [
"cwmp",
"usp"
],
"default": "-1.0",
"datatype": "string",
"mapping": [
{
"data": "@Parent",
"type": "json",
"key": "Rating"
}
]
}
}
}

View File

@@ -1,13 +1,5 @@
if PACKAGE_wifidmd
config WIFIDMD_DISABLE_LEGACY_WIFI
bool "Disable legacy Wireless Objects like WiFi.Radio., WiFi.SSID., WiFi.AccessPoint. etc"
default n
config WIFIDMD_ENABLE_WIFI_DATAELEMENTS
bool "Enable Device.WiFi.DataElements. Object"
default y
config WIFIDMD_VENDOR_PREFIX
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=wifidmd
PKG_VERSION:=1.3.12
PKG_VERSION:=1.4.1
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/wifidmd.git
PKG_SOURCE_VERSION:=44828c825f13cb93b28b7bc99c600d94bdf5cb92
PKG_SOURCE_VERSION:=006359c351be70a45f5bc1ef3d78e14e270aa7cf
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -53,14 +53,6 @@ endif
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(VENDOR_PREFIX)\\\"
ifeq ($(CONFIG_WIFIDMD_DISABLE_LEGACY_WIFI),y)
MAKE_FLAGS += WIFIDMD_DISABLE_LEGACY_WIFI=y
endif
ifeq ($(CONFIG_WIFIDMD_ENABLE_WIFI_DATAELEMENTS),y)
MAKE_FLAGS += WIFIDMD_ENABLE_WIFI_DATAELEMENTS=y
endif
define Package/wifidmd/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/wifidmd $(1)/usr/sbin/wifidmd

View File

@@ -5,8 +5,28 @@
"unified_daemon": true,
"services": [
{
"parent_dm": "Device.",
"object": "WiFi"
"parent_dm": "Device.WiFi.",
"object": "Radio"
},
{
"parent_dm": "Device.WiFi.",
"object": "SSID"
},
{
"parent_dm": "Device.WiFi.",
"object": "AccessPoint"
},
{
"parent_dm": "Device.WiFi.",
"object": "NeighboringWiFiDiagnostic"
},
{
"parent_dm": "Device.WiFi.",
"object": "EndPoint"
},
{
"parent_dm": "Device.WiFi.",
"object": "Reset()"
}
],
"config": {

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=wifimngr
PKG_VERSION:=20.1.5
PKG_VERSION:=20.1.7
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=7e113a00839d076d2a25c728bf739fbecdd453ec
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