Compare commits

..

261 Commits

Author SHA1 Message Date
arbala
7d29ad2fc9 map-plugins: 1.2.7 2025-12-23 17:14:06 +01:00
arbala
c2e1e4c3e0 map-agent: 6.3.7.19 2025-12-23 17:08:24 +01:00
Anjan Chanda
073deb5828 map-controller: 6.4.4.24 2025-12-19 15:04:09 +01:00
Reidar Cederqvist
5d23c8b5a1 sulu update to version 5.3.10 2025-12-12 11:52:36 +01:00
Reidar Cederqvist
288bbbd640 sulu: update to version 5.3.9 2025-12-11 22:00:35 +01:00
Amin Ben Romdhane
4461233f96 wifidmd: 1.1.33.9 2025-12-09 16:50:26 +01:00
Vivek Kumar Dutta
7784e915bc parental-control: 1.4.6
(cherry picked from commit 9101095a0a)
2025-12-09 18:25:16 +05:30
Vivek Dutta
a2cfd3615f parental-control: disable urlfilter by default
(cherry picked from commit 82183e9e3b)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-12-09 16:37:43 +05:30
Jakob Olsson
a84600031a map-agent: 6.3.7.17 2025-12-09 11:49:08 +01:00
Vivek Kumar Dutta
781967f4aa Revert "parental-control: disable urlfilter by default"
This reverts commit d34671b1d0.
2025-12-08 21:43:43 +05:30
Vivek Dutta
d34671b1d0 parental-control: disable urlfilter by default
(cherry picked from commit 5af1df3493)

5af1df34 parental-control: disable urlfilter by default

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-12-08 21:00:28 +05:30
Vivek Dutta
ee51171fd8 parental-control: read urlbundle definition from json 2025-12-08 14:57:05 +00:00
Reidar Cederqvist
54f08fc89b sulu: update to version 5.3.8 2025-12-08 15:36:55 +01:00
Jakob Olsson
b2d62ee320 ieee1905: 8.7.38 2025-12-08 12:08:51 +01:00
Jakob Olsson
c68ca0390a map-agent: 6.3.7.16 2025-12-08 11:02:37 +01:00
Sukru Senli
a564e3bb8d sulu: 5.3.7 2025-12-05 20:01:37 +01:00
Reidar Cederqvist
1f57adfee5 sulu: update to version 5.3.6 2025-12-05 18:52:55 +01:00
Sukru Senli
4727a315ca netmode: fallback to checking usr_data if /opconf/opconf.json is not available 2025-12-05 17:19:36 +01:00
Reidar Cederqvist
8ff6663501 sulu: update to version 5.3.5 2025-12-05 16:59:40 +01:00
Reidar Cederqvist
8608d4aa01 sulu: update to version 5.3.4 2025-12-05 15:22:34 +01:00
Jakob Olsson
8eff97b281 decollector: 6.2.1.14 2025-12-05 15:14:22 +01:00
Vivek Kumar Dutta
2347dbfaa3 tr143: fix per connection result for upload 2025-12-05 17:54:55 +05:30
Suvendhu Hansa
ad2c6a17a4 tr143: download/upload diagnostics using fastpath for an7581 2025-12-05 16:58:13 +05:30
Vivek Dutta
e529bc2564 bbfdm: increase IPC max len to 20M
(cherry picked from commit 5fd540d5ba)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-12-05 16:11:03 +05:30
Vivek Kumar Dutta
27c1022601 userinterface: Use FirstLogin as false, if not set 2025-12-05 15:05:15 +05:30
Sukru Senli
6002211053 netmode: clean all vlans before creating new ones 2025-12-05 14:37:01 +05:30
Jakob Olsson
9c00a0928b Revert "map-agent: 6.3.7.16"
This reverts commit 2d5570f6a0.
2025-12-05 09:33:16 +01:00
Jakob Olsson
7cdeecb7f7 Revert "map-controller: 6.4.4.14"
This reverts commit 9e5c376576.
2025-12-05 09:33:16 +01:00
Vivek Kumar Dutta
6690b29272 dnsmngr: Fix DNS Client Interface reference 2025-12-05 13:56:18 +05:30
Vivek Kumar Dutta
d39b3ebaa4 logmngr: fix typo 2025-12-04 19:59:58 +05:30
Sukru Senli
1606a6bcd1 netmode: remove wan6 for pppoe and static modes 2025-12-04 15:16:25 +01:00
Jakob Olsson
9e5c376576 map-controller: 6.4.4.14 2025-12-04 15:12:35 +01:00
Mohd Husaam Mehdi
bdc435c392 logmngr: reload fluent-bit on ntp sync event (via hotplug) 2025-12-04 13:53:17 +00:00
Jakob Olsson
2d5570f6a0 map-agent: 6.3.7.16 2025-12-04 14:27:39 +01:00
Vivek Kumar Dutta
09c488c1e6 hostmngr: add uniqueness check for name extn 2025-12-04 18:12:30 +05:30
Vivek Kumar Dutta
9aa6878efc dhcpmngr: vendor extn to set name with static lease 2025-12-04 18:11:14 +05:30
Reidar Cederqvist
35b7e24278 sulu: update to versiohn 5.3.3 2025-12-04 13:22:41 +01:00
Jakob Olsson
0a00e910ba decollector: 6.2.1.13 2025-12-04 11:06:28 +01:00
Suvendhu Hansa
5d9c9d5708 netmode: Fix missing IP interface after wan mode change 2025-12-04 14:09:16 +05:30
Vivek Dutta
401790274c ssdpd: add UPnPIGD param support in UPnP datamodel
(cherry picked from commit 5fcee38906)

Co-authored-by: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
2025-12-03 17:30:16 +05:30
Vivek Kumar Dutta
4989129f2d sysmngr: fix logs prio in reboot method 2025-12-03 17:29:28 +05:30
Suvendhu Hansa
a55324acc3 netmode: Fix switching wan mode from pppoe to other modes 2025-12-03 17:26:49 +05:30
Vivek Kumar Dutta
a9ce2df71a obuspa: Fix revert of services with Transactions 2025-12-03 11:41:57 +05:30
Vivek Kumar Dutta
22f43092f4 dhcpmngr: Fix missing client info in case of lan ip changes 2025-12-03 09:40:58 +05:30
Jakob Olsson
6be2d52199 map-agent: 6.3.7.15 2025-12-02 17:32:18 +01:00
Jakob Olsson
0ec72bec22 map-agent: 6.3.7.14 2025-12-02 14:40:44 +01:00
Jakob Olsson
8b17665845 libdpp: 2.1.3 2025-12-02 12:45:37 +01:00
Vivek Kumar Dutta
d9e9e53361 obuspa: update error log 2025-12-01 19:44:30 +05:30
Jakob Olsson
0fb178476f map-agent: 6.3.7.13 2025-11-28 15:03:45 +01:00
Vivek Kumar Dutta
9ccae677a6 sulu: fix mosquitto acl permission 2025-11-28 19:07:28 +05:30
Reidar Cederqvist
b6a6a37005 sulu: update to version 5.3.2 2025-11-28 11:56:03 +01:00
Vivek Dutta
fe7a0b7d0c netmode: check mode from opconf in uci-default 2025-11-28 15:57:11 +05:30
Vivek Kumar Dutta
d9688d0d7b obuspa: fix schema registration 2025-11-28 13:33:58 +05:30
Reidar Cederqvist
e5769f9b33 sulu: update to version 5.3.1 2025-11-27 16:23:18 +01:00
Vivek Kumar Dutta
b50c9eb386 obuspa: Fix segfault while getting endpointid 2025-11-27 20:23:08 +05:30
Vivek Kumar Dutta
ab5e3a42b9 self-diagnostics: fix datamodel access 2025-11-27 14:18:11 +05:30
Jakob Olsson
14609a860e map-agent: 6.3.7.12 2025-11-26 17:27:13 +01:00
Reidar Cederqvist
d9c18aaf91 sulu: Update sulu to version 5.3.0 2025-11-26 16:41:38 +01:00
Sukru Senli
74f299a687 mosquitto-auth-plugin: add SIGHUP support for dynamic ACL reload
Enable dynamic reloading of subnet ACL configuration via SIGHUP signal
  without disconnecting clients. Register MOSQ_EVT_RELOAD callback to
  reload ACL rules when mosquitto receives SIGHUP.
2025-11-26 12:51:43 +01:00
Vivek Kumar Dutta
e97d29ed6b netmode: 1.1.10 2025-11-25 18:40:49 +05:30
Husaam Mehdi
a9be5ff573 ethmngr: add support for MTU in Ethernet.Link. object 2025-11-25 17:48:49 +05:30
Amin Ben Romdhane
3e6eadcbec bbfdm: 1.16.6.6 2025-11-25 10:53:51 +01:00
Jakob Olsson
84394e3639 map-agent: 6.3.7.11 2025-11-24 17:04:11 +01:00
Amin Ben Romdhane
24f52886b8 bbfdm: 1.16.6.5 2025-11-24 14:09:56 +01:00
Vivek Kumar Dutta
9f6550a827 dhcpmngr: 1.0.8 2025-11-21 12:48:43 +05:30
Vivek Dutta
a04244942b dmcli-plugins: 2.2.6
(cherry picked from commit a0ba20647d)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-11-21 12:47:10 +05:30
Vivek Dutta
2cc9859309 dmcli: 1.9.4
(cherry picked from commit 642544f579)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-11-21 12:47:10 +05:30
Mohd Husaam Mehdi
f918829cb7 firewallmngr: add support for Device.Firewall.Chain.Rule.SourceMAC 2025-11-21 11:49:12 +05:30
Reidar Cederqvist
0dac08d363 sulu: update to version 5.2.12 2025-11-20 17:54:13 +01:00
Vivek Dutta
e4e41c837c netmode: reboot to apply mode change 2025-11-20 21:38:54 +05:30
Vivek Dutta
4a61fc9674 netmode: 1.1.9
(cherry picked from commit 36928bdcb9)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-11-20 20:24:55 +05:30
Vivek Kumar Dutta
012c3e1169 sysmngr: fix compilation without vendor extn 2025-11-20 18:58:06 +05:30
Vivek Kumar Dutta
288dfa9244 bbfdm: ignore trailing dot in reference path 2025-11-20 17:43:22 +05:30
Amin Ben Romdhane
b9e47162d0 map-agent: 6.3.7.10 2025-11-20 11:21:50 +01:00
Amin Ben Romdhane
1f18545faa wifidmd: 1.1.33.8 2025-11-20 11:20:17 +01:00
Jakob Olsson
93e592f583 map-controller: 6.4.4.13 2025-11-19 17:03:58 +01:00
Vivek Kumar Dutta
92b0d5aed2 parental-control: remove dhcp.leases from keep.d 2025-11-19 14:29:20 +05:30
Vivek Kumar Dutta
466a149107 parental-control: remove dhcp.leases usages & add HostRef dm 2025-11-19 14:15:05 +05:30
Reidar Cederqvist
1577a9bf69 sulu: update to version 5.2.11 2025-11-18 12:29:58 +01:00
Amin Ben Romdhane
3e1f65d668 map-agent: 6.3.7.9 2025-11-18 11:59:41 +01:00
Anjan Chanda
08a56514f4 decollector: 6.2.1.12 2025-11-17 10:06:25 +01:00
Vivek Kumar Dutta
34ff04d8bb dhcpmngr: Fix DHCP server pool params configuration 2025-11-14 16:27:50 +05:30
Reidar Cederqvist
1e0b705c8b sulu: update to version 5.2.10 2025-11-14 11:50:12 +01:00
Vivek Kumar Dutta
5b5a9bb231 sulu: Fix overriding config 2025-11-13 23:02:26 +05:30
Reidar Cederqvist
5b6697789b sulu: update to version 5.2.9 2025-11-13 15:45:03 +01:00
Jakob Olsson
172a0066dd map-agent: 6.3.7.8 2025-11-13 14:08:01 +01:00
Amin Ben Romdhane
44cd1ae18e wifidmd: 1.1.33.7 2025-11-13 12:41:48 +01:00
Jakob Olsson
37c2358ca5 map-agent: 6.3.7.7 2025-11-13 12:17:54 +01:00
Amin Ben Romdhane
b3d2b111f0 libeasy: 7.5.1 2025-11-13 11:28:13 +01:00
Anjan Chanda
4ef899324b libeasy: 7.5.0 2025-11-13 11:28:13 +01:00
Vivek Kumar Dutta
d39d28e6d8 obuspa: 10.0.0.18 2025-11-13 12:58:35 +05:30
Jakob Olsson
cb48886ceb map-plugins: 1.2.6 2025-11-12 16:59:06 +01:00
Jakob Olsson
a7bbd943cc map-controller: 6.4.4.11 2025-11-12 16:58:23 +01:00
Vivek Kumar Dutta
f74c2041ec obuspa: Use system CA if not defined 2025-11-12 18:02:30 +05:30
Vivek Kumar Dutta
ae2474d273 usermngr: 1.4.7 2025-11-12 17:06:20 +05:30
Vivek Dutta
153b75395d usermngr: json schema to validate the role acl
(cherry picked from commit fb236949fc)

048c54e8 Install acl.schema.json to /etc/users/schema/acl.schema.json

Co-authored-by: Jouni Ikonen <jouni.ikonen@genexis.eu>
2025-11-12 16:59:37 +05:30
Vivek Dutta
3da4280752 usermngr: fix passwdqc options
(cherry picked from commit 350ced4c32)

920d847d usermngr: Fix libpasswdqc options

Co-authored-by: Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
2025-11-12 16:52:46 +05:30
Vivek Kumar Dutta
95c7cb447b hostmngr: 1.3.5 2025-11-12 15:41:58 +05:30
Vivek Kumar Dutta
c9e9ac9a4e hostmngr: update hostname on dhcp renew 2025-11-11 19:09:15 +05:30
Vivek Dutta
06921165db sysmngr: rename restart option to reboot in upgrade
(cherry picked from commit cfc335aed8)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-11-11 18:52:04 +05:30
Vivek Dutta
5c9a63c2a1 sysmngr: fwbank option to restart with upgrade
(cherry picked from commit 1139c21f34)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-11-11 18:44:36 +05:30
Markus Gothe
57530b8838 qosmngr: Refine fix for QoS on EN7523.
It seems like it is the rules conflicting
and not the overflow itself causing the
issue. Disable the use of custom IFC
rules on EN7523.
2025-11-11 12:37:02 +01:00
Markus Gothe
95a1d6899b qosmngr: airoha: Fix QoS issue with EN7523+IFC.
When the LUT1 IFC table overflows it seems to
affect tagged TCP-based VLAN traffic and
ingress flows are not properly setup in HW NAT.
2025-11-11 12:34:21 +01:00
Vivek Kumar Dutta
724f456e3c firewallmngr: align internal port with external port range 2025-11-11 14:07:33 +05:30
Vivek Kumar Dutta
9ef41069d6 dnsmngr: Fix interface references 2025-11-10 21:46:18 +05:30
Reidar Cederqvist
eda55e9d9d sulu: update to version 5.2.8 2025-11-10 16:12:33 +01:00
Jakob Olsson
bdead2797a map-agent: set START order 97
Map-agent init.d script sets up the appropriate UCI configurations, and must run before map-controller with start order 98
2025-11-10 15:15:05 +01:00
Vivek Kumar Dutta
022b138347 sysmngr: fallback to full backup if usr_data partition missing
(cherry picked from commit f9ad16934c)
2025-11-10 18:24:05 +05:30
Jakob Olsson
9f8a8b5591 ieee1905: 8.7.37 2025-11-07 17:53:08 +01:00
Jakob Olsson
7c8afb8eaf map-controller: 6.4.4.10 2025-11-07 17:41:00 +01:00
Jakob Olsson
56bff31f81 map-agent: 6.3.7.6 2025-11-07 17:40:37 +01:00
Jakob Olsson
59511621c6 libwifi: 7.13.10 2025-11-07 16:57:10 +01:00
Reidar Cederqvist
fe73b36293 sulu: update to version 5.2.7 2025-11-07 16:53:07 +01:00
Jakob Olsson
de85db9fa6 map-controller: uci-defaults: only add installed plugins 2025-11-07 10:31:24 +01:00
Vivek Kumar Dutta
607b546317 firewallmngr: support for RemainingLeaseTime in NAT 2025-11-07 14:40:13 +05:30
Jakob Olsson
47f964bd0d ieee1905: 8.7.36 2025-11-06 12:40:02 +01:00
Reidar Cederqvist
272656caa9 sulu: update to version 5.2.6 2025-11-06 10:45:20 +01:00
Sukru Senli
3ae1ba4530 netmode: set MTU on WAN device section 2025-11-05 15:44:01 +01:00
Reidar Cederqvist
d5c15c995e sulu: update to version 5.2.5 2025-11-05 15:39:31 +01:00
Amin Ben Romdhane
d73b91bdd3 decollector: 6.2.1.11 2025-11-05 14:55:58 +01:00
Sukru Senli
e327dbce29 netmode: expose MTU as supported argument for PPPoE 2025-11-05 13:18:00 +01:00
Vivek Kumar Dutta
92d5156a9f sysmngr: 1.0.28.3
(cherry picked from commit 1f96c3d295)
2025-11-05 16:46:39 +05:30
Vivek Kumar Dutta
63779cf56e icwmp: fix copy_config usages
(cherry picked from commit d1d57ca528)
2025-11-05 16:44:06 +05:30
Amin Ben Romdhane
96de2ee6c5 decollector: 6.2.1.10 2025-11-05 10:25:50 +01:00
Reidar Cederqvist
e768cb4c1d Sulu: update to version 5.2.4 2025-11-05 09:52:55 +01:00
Vivek Kumar Dutta
c02570e234 icwmp: align with opconf
(cherry picked from commit 99fe2c2b2a)
2025-11-04 21:46:10 +05:30
Vivek Kumar Dutta
6750377b0e sysmngr: align with opconf 2025-11-04 21:34:37 +05:30
Jakob Olsson
14eeac7c60 map-controller: 6.4.4.9 2025-11-03 16:58:39 +01:00
arbala
bfb09c7275 mapcontroller, mapagent: add uci-default script for migration from 7.3 to 7.5 2025-11-03 12:53:30 +01:00
Vivek Kumar Dutta
12c617822f icwmp: support to download opconf 2025-11-03 11:53:15 +05:30
Amin Ben Romdhane
71646ac551 ieee1905: 8.7.35 2025-10-30 16:33:48 +01:00
Reidar Cederqvist
740c050cd7 Sulu: update to version 5.2.3 2025-10-30 16:01:23 +01:00
Jakob Olsson
bb4069ce9b map-plugins: 1.2.5 2025-10-30 15:40:02 +01:00
Roman Azarenko
fa994ebd09 iopsys-analytics: move iperf3 from default build to analytics
We're using `iperf3` for development and testing, so there is no need
to include it in the default firmware builds.
2025-10-30 09:45:27 +01:00
Vivek Kumar Dutta
07efbdd3bd tr104: optimize setting of sip network 2025-10-30 14:14:14 +05:30
Vivek Kumar Dutta
d9ef12897c bbfdm: update loglevel in ubus calls 2025-10-30 11:00:53 +05:30
Jakob Olsson
7e0520c1d6 map-controller: set enable_bsta_steer to '1' by default 2025-10-29 17:01:11 +01:00
Jakob Olsson
72bd92c9ea map-controller: 6.4.4.8 2025-10-29 17:00:59 +01:00
Jakob Olsson
dbbc48a93a map-plugin: 1.2.4 2025-10-29 17:00:18 +01:00
Amin Ben Romdhane
a5c6eb86c4 timemngr: 1.1.11 2025-10-29 21:16:07 +05:30
Vivek Dutta
ac0b85f837 timemngr: Added support for SupportedZones object
(cherry picked from commit fea3e1e4ef)

fea3e1e4 timemngr: Added support for SupportedZones object

Co-authored-by: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
2025-10-29 21:14:09 +05:30
Jakob Olsson
38d8d01f27 wifidmd: 1.1.33.6 2025-10-29 14:56:59 +01:00
Jakob Olsson
2ccfa1da43 map-controller: 6.4.4.7 2025-10-29 14:46:07 +01:00
Jakob Olsson
731bd20943 map-plugins: 1.2.3 2025-10-29 14:37:42 +01:00
Jakob Olsson
67b71ce206 map-controler: 6.4.4.6 2025-10-29 13:46:00 +01:00
Erik Karlsson
76713ffa40 sulu: disregard client-provided X-Forwarded-For
This prevents clients from lying about their identity to the MQTT
broker by supplying their own X-Forwarded-For in the request.

(cherry picked from commit 5631c28df4)
2025-10-29 13:03:38 +01:00
Sukru Senli
49d18417db sulu: adapt to mosquitto-auth-shadow->mosquitto-auth-plugin change
(cherry picked from commit 8170684100)
2025-10-29 13:03:29 +01:00
Sukru Senli
a39ffe9ebb mosquitto-auth-plugin: add per-user subnet-based access control with IPv4/IPv6 support
- Implement whitelist/blacklist subnet filtering for MQTT users
- Add full IPv4 and IPv6 CIDR subnet matching support
- Check subnet restrictions during authentication (MOSQ_EVT_BASIC_AUTH)
- Reject login immediately if subnet check fails (return MOSQ_ERR_AUTH)
- Parse subnet ACL files via auth_opt_subnet_acl_file option
- Support multiple subnets per user (up to 32 allow + 32 deny rules)
- Support both IPv4 (e.g., 192.168.1.0/24) and IPv6 (e.g., 2001:db8::/32) CIDR notation
- Deny rules take precedence over allow rules for both IP versions
- Localhost (127.0.0.1 and ::1) always allowed
- 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

(cherry picked from commit 332a35102d)
2025-10-29 13:03:19 +01:00
Sukru Senli
853b5ec8bc rename mosquitto-auth-shadow to mosquitto-auth-plugin
(cherry picked from commit ba5e332b0d)
2025-10-29 13:03:08 +01:00
Reidar Cederqvist
7baa1ac579 sulu: update to version 5.2.2 2025-10-29 12:56:29 +01:00
Jakob Olsson
1d7df80538 map-agent: 6.3.7.5 2025-10-29 10:07:49 +01:00
Jakob Olsson
2e29c5c777 map-agent: 6.3.7.4 2025-10-28 16:39:06 +01:00
Sukru Senli
beda74eaaf sulu: remove sulu-vendorext package 2025-10-28 14:46:30 +01:00
Vivek Kumar Dutta
e461b9d1f6 netmode: 1.1.8 2025-10-28 17:58:09 +05:30
Vivek Kumar Dutta
4265c3d191 netmode: Fix dm-service depedency 2025-10-28 17:57:43 +05:30
Vivek Kumar Dutta
9d5099944e sysmngr: fix set_bootbank status 2025-10-28 15:53:23 +05:30
Jakob Olsson
46a14f82b6 map-controller: 6.4.4.5 2025-10-28 09:58:00 +01:00
Jakob Olsson
f8f8ad7453 ieee1905: 8.7.34 2025-10-27 17:13:39 +01:00
Jakob Olsson
b74e5bcb6f map-controller: 6.4.4.4 2025-10-27 16:36:57 +01:00
Jakob Olsson
0b3ed4c2f2 libwifi: 7.13.9 2025-10-27 16:35:34 +01:00
Jakob Olsson
67a56f09c6 map-plugins: 1.2.2 2025-10-27 14:25:40 +01:00
Reidar Cederqvist
0fbb37f4ed Sulu: update to version 5.2.1 2025-10-24 13:47:40 +02:00
Erik Karlsson
60d395923d logmngr: simplify default PID to 0 logic
Note that the "add" directive only adds if nothing is already present.

(cherry picked from commit 580d24e04a)
2025-10-24 10:53:21 +02:00
Markus Gothe
53a6bd9304 obuspa: Fix spelling of log messages.
Abbrevations like UCI must be in capital letters.
Add correct punctation.

(cherry picked from commit 8d86188ff1)
2025-10-24 10:53:01 +02:00
Jakob Olsson
7354b4d971 libwifi: 7.13.8 2025-10-24 10:40:08 +02:00
Reidar Cederqvist
28da651279 update sulu to version 5.2.0 2025-10-24 08:31:04 +00:00
Husaam Mehdi
a582d6d115 usermngr: added password expiry extension 2025-10-24 13:30:09 +05:30
Vivek Dutta
341a925504 logmngr: set pid to 0 when it does not exist
(cherry picked from commit e319c85064)

Co-authored-by: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
2025-10-23 14:25:55 +05:30
Jakob Olsson
82c54d9422 map-controller: 6.4.4.3 2025-10-23 10:25:22 +02:00
Jakob Olsson
660809e83e map-agent: 6.3.7.3 2025-10-23 10:24:44 +02:00
Erik Karlsson
d34205adb1 sulu-vendorext: remove /etc/init.d/sulu_widgets
This script which hides specific widgets in extender mode is not
needed since we disable the GUI entirely instead in extender mode.
2025-10-22 12:05:59 +00:00
Jakob Olsson
dad2b56c02 map-plugins: 1.1.3 2025-10-22 13:07:35 +02:00
Sukru Senli
e6618e200f netmode: skip obuspa restart 2025-10-22 08:58:09 +02:00
Sukru Senli
c4f4f3e093 netmode: enable by default and auto-detect mode 2025-10-22 08:38:24 +02:00
Jakob Olsson
d454d20716 decollector: 6.2.1.9 2025-10-21 17:22:58 +02:00
Jakob Olsson
12d4d23f6e map-agent: 6.3.7.2 2025-10-21 17:22:01 +02:00
Jakob Olsson
c2310ebb25 wifidmd: 1.1.33.5 2025-10-21 17:21:20 +02:00
Jakob Olsson
be472781d9 map-controller: 6.4.4.2 2025-10-21 17:17:44 +02:00
Vivek Dutta
e4274b9c15 userinterface: vendor extension for FirstLogin
(cherry picked from commit 0cb9aac1f1)

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-10-21 12:20:30 +05:30
Jakob Olsson
16d94a6628 map-agent: 6.3.7.1 2025-10-20 17:11:22 +02:00
Sukru Senli
bb090135b2 netmode: fix static mode
and improve other modes
2025-10-20 16:43:38 +02:00
Sukru Senli
8d7cf1c701 netmode: add static mode and vlanid and dns servers as arguments to all modes 2025-10-20 12:51:04 +02:00
Erik Karlsson
9692cf8bc3 sulu-vendorext: remove unused voip ubus object 2025-10-20 10:23:28 +02:00
Vivek Kumar Dutta
7fa5c901f9 sulu-vendorext: fix compilation 2025-10-17 18:29:48 +05:30
Sukru Senli
7c2cbc4c1a sulu-vendorext: remove AccessPoint management from X_IOWRT_MAPController vendor extension 2025-10-17 14:57:17 +02:00
Sukru Senli
a9bdc41462 sulu-vendorext: remove firewall extension 2025-10-17 14:53:42 +02:00
Amin Ben Romdhane
389485a526 wifidmd: 1.1.33.4 2025-10-17 10:08:35 +02:00
Vivek Kumar Dutta
8087a16cdf firewallmngr: selects nat interface setting 2025-10-17 12:25:29 +05:30
Vivek Kumar Dutta
4e33db2700 usermngr: Only select shadow pam utils with security hardening 2025-10-17 10:46:54 +05:30
Vivek Kumar Dutta
e6b7048775 icwmp: Fix segfault with SMM disabled 2025-10-16 18:11:16 +05:30
Suvendhu Hansa
23c43898a4 usermngr: Vendor extension for Security Hardening parameters 2025-10-16 15:45:03 +05:30
Vivek Kumar Dutta
abebc40733 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 14:44:47 +05:30
Suvendhu Hansa
4823154afb usermngr: Added password strength validation 2025-10-15 18:13:54 +05:30
Vivek Dutta
936ce9be85 passwdqc: Install pwqcheck tool
(cherry picked from commit 17ae16e5d2)

17ae16e5 passwdqc: Install pwqcheck tool

Co-authored-by: Suvendhu Hansa <suvendhu.hansa@iopsys.eu>
2025-10-15 17:35:56 +05:30
Reidar Cederqvist
996c0b1832 sulu: update to version 5.1.8 2025-10-14 17:02:23 +02:00
Jakob Olsson
8c4e77a96b Revert "Revert "map-controller: config: add zerotouch, rate, bsteer plugins to default""
This reverts commit 2c58ce6912.
2025-10-14 09:46:15 +02:00
Jakob Olsson
e647ec0990 Revert "Revert "map-agent: map_genconfig: add dpp_chirp section for 2.4GHz""
This reverts commit ad3028061c.
2025-10-14 09:46:13 +02:00
Vivek Dutta
4cfbb3636f mosquitto-auth-shadow: support libpam based authentication
(cherry picked from commit 082452bfb5)

082452bf mosquitto-auth-shadow: support libpam based authentication

Co-authored-by: Vivek Kumar Dutta <vivek.dutta@iopsys.eu>
2025-10-14 09:35:03 +05:30
Janusz Dziedzic
528ad5cbd2 wifimngr: 17.7.8 2025-10-13 16:15:59 +00:00
Erik Karlsson
def81d62d5 logmngr: include pid when migrating also
(cherry picked from commit 46dc9e86d8)

Co-authored-by: Erik Karlsson <erik.karlsson@iopsys.eu>
2025-10-13 19:21:13 +05:30
Jakob Olsson
ad3028061c Revert "map-agent: map_genconfig: add dpp_chirp section for 2.4GHz"
This reverts commit 8554ccf3fc.
2025-10-13 12:12:08 +02:00
Jakob Olsson
2c58ce6912 Revert "map-controller: config: add zerotouch, rate, bsteer plugins to default"
This reverts commit ba95eec1b5.
2025-10-13 12:11:52 +02:00
Vivek Dutta
064418e23d logmngr: include pid in log output by fluent-bit
(cherry picked from commit 0b3420240d)

Co-authored-by: Mohd Husaam Mehdi <husaam.mehdi@iopsys.eu>
2025-10-12 11:38:13 +05:30
Jakob Olsson
ba95eec1b5 map-controller: config: add zerotouch, rate, bsteer plugins to default 2025-10-10 15:50:30 +02:00
Jakob Olsson
8554ccf3fc map-agent: map_genconfig: add dpp_chirp section for 2.4GHz 2025-10-10 15:47:08 +02:00
Janusz Dziedzic
d6cf506901 wifimngr: 17.7.7 2025-10-10 11:38:06 +00:00
Janusz Dziedzic
263723b795 libwifi: 7.13.7 2025-10-10 11:37:15 +00:00
Jakob Olsson
21724ac691 map-agent: 6.3.7.0: zerotouch 2025-10-10 12:01:47 +02:00
Jakob Olsson
3422f7fc4d map-plugins: 1.1.2 2025-10-10 12:01:47 +02:00
Jakob Olsson
19e4b41368 map-plugins: add zerotouch options 2025-10-10 12:01:47 +02:00
Jakob Olsson
db30526f64 map-controller: 6.4.4.0: add ZEROTOUCH_DPP 2025-10-10 12:01:47 +02:00
Janusz Dziedzic
d4c101f90f libwifi: fix target cflags 2025-10-09 14:27:32 +02:00
Janusz Dziedzic
d90063c7d5 wifimngr: disable scancache by default 2025-10-09 14:27:32 +02:00
Mohd Husaam Mehdi
09323326f4 passwdqc: align with usermngr (move PAM setup to usermngr) 2025-10-09 16:32:40 +05:30
Husaam Mehdi
33b62a44c5 sshmngr: use openssh-with-pam as the default backend 2025-10-09 16:32:17 +05:30
Vivek Kumar Dutta
9d0f9750dc usermngr: 1.4.1 2025-10-09 16:30:50 +05:30
Vivek Kumar Dutta
e68abd6288 usermngr: 1.4.0 2025-10-09 16:30:50 +05:30
Suvendhu Hansa
61559073e8 usermngr: modify password policy 2025-10-09 16:30:50 +05:30
Mohd Husaam Mehdi
ffd8352d38 usermngr: add UCI support for passwdqc parameters 2025-10-09 16:30:50 +05:30
Mohd Husaam Mehdi
d75d3bc3ed usermngr: 1.3.11 2025-10-09 16:30:50 +05:30
Mohd Husaam Mehdi
86ef800f0d usermngr: add support for USERMNGR_SECURITY_HARDENING
* this compile time flag will set up faildelay, lock out upon
  6 failed attempts during login via shell or console and enable
  password strength checks when changing password
* this will set openssh usePam option
* openssh and shadow-utils with PAM backend need to be selected for
  this compile time flag to work
2025-10-09 16:30:50 +05:30
Mohd Husaam Mehdi
130a3e5952 usermngr: set compile time flag to use pam with shadow-utils 2025-10-09 16:30:50 +05:30
Mohd Husaam Mehdi
0d4b4c5399 usermngr: include passwdqc and linux-pam
* passwdqc helps us enforce strong passwords policy
* linux-pam helps in managing failed login attempts
2025-10-09 16:30:50 +05:30
Mohd Husaam Mehdi
2240a84adc linux-pam: align with usermngr (move PAM setup to usermngr) 2025-10-09 10:36:57 +00:00
Mohd Husaam Mehdi
d4dfe767c9 parental-control: improve bundle sync logic
* handle the case when interface comes up after parental-control
* handle the case when bundle size can't be fetched for some reason
2025-10-09 14:09:06 +05:30
Vivek Kumar Dutta
58f141573a tr143: workaround for download byte mismatch 2025-10-09 14:01:05 +05:30
Suvendhu Hansa
91fac0490a firewallmngr: Add compile flag for InterfaceSetting 2025-10-09 13:48:25 +05:30
Sukru Senli
a80713423c sulu-vendorext: remove mldsync script
since changes via tr-181 do not trigger procd config reload trigger
2025-10-08 08:54:01 +02:00
Reidar Cederqvist
d530ffa4ba sulu: update to version 5.1.7 2025-10-07 17:14:47 +02:00
Mohd Husaam Mehdi
2da18cbb7d parental-control: fix handling of tcp and ipv6 based dns responses 2025-10-07 13:44:39 +05:30
Mohd Husaam Mehdi
c89816ac60 parental-control: config option for nfqueue number 2025-10-07 13:44:31 +05:30
Vivek Kumar Dutta
03810c0099 parental-control: 1.3.2 2025-10-07 13:44:24 +05:30
Mohd Husaam Mehdi
aad4bd7db5 parental-control: only flush relevant connections using conntrack 2025-10-07 13:44:18 +05:30
Reidar Cederqvist
f36ba2dc1f Update 3 files
- /sulu/sulu-base/Makefile
- /sulu/sulu-builder/Makefile
- /sulu/sulu-theme-genexis/Makefile
2025-10-04 14:27:19 +00:00
Erik Karlsson
91dced7427 sulu: fix faulty ACL generation logic
Also remove leftovers from QR code generation and pointless uci_load
2025-10-03 10:15:00 +02:00
Jakob Olsson
57ef92af9a map-controller: 6.4.3.5 2025-10-03 09:54:55 +02:00
Jakob Olsson
631122aa04 map-plugins: 1.1.1 2025-10-03 09:52:09 +02:00
Sukru Senli
ede7966809 sulu-vendorext: ap_to_mld_creds_sync: do no hardcode mld_id to 1
set it only if there are unused mld sections
2025-10-02 17:34:54 +02:00
Vivek Kumar Dutta
9a36c0310f sulu: Fix migration scripts 2025-10-02 15:17:18 +00:00
Jakob Olsson
2528cde629 map-controller: 6.4.3.4 2025-10-02 16:47:21 +02:00
Vivek Kumar Dutta
f317c67aed obuspa: Skip overriding of uci in case of firstboot 2025-10-02 12:52:56 +00:00
Jakob Olsson
7f14f8634e map-controller: 6.4.3.3 2025-10-02 13:21:31 +02:00
Jakob Olsson
62552e2269 map-controller: 6.4.3.2 2025-10-02 09:45:14 +02:00
Jakob Olsson
5837b73946 map-agent: 6.3.6.18 2025-10-01 13:32:08 +02:00
Erik Karlsson
22bded8f33 timemngr: do not fail uci-defaults on keep-settings upgrade 2025-09-30 16:15:28 +02:00
Erik Karlsson
1fbf254b3a sulu-vendorext: fix missed heimgard.wan to genexis.wan renaming
Also add proper sanity checks so a catch-all ACCEPT rule cannot be
inadvertently added.
2025-09-30 12:49:15 +02:00
Erik Karlsson
3b6f88daed sulu-builder: fix typo in version 2025-09-30 11:53:35 +02:00
Amin Ben Romdhane
f8ceb6293d wifidmd: 1.1.33.3 2025-09-30 11:24:36 +02:00
Jakob Olsson
d5375c89b1 map-agent: 6.3.6.17 2025-09-29 10:53:48 +02:00
Reidar Cederqvist
1301adc7c6 sulu: update to version 5.1.5 2025-09-26 15:08:51 +02:00
Filip Matusiak
85d7715db7 map-agent: 6.3.6.16 2025-09-26 12:10:25 +02:00
Reidar Cederqvist
25cb059235 sulu update to version 5.1.4 2025-09-25 15:56:29 +00:00
Filip Matusiak
a87b85eba5 map-controller: 6.4.2.10 2025-09-25 14:40:16 +02:00
Vivek Kumar Dutta
49a83e17cb sulu-vendorext: Updated MAPController ext 2025-09-25 14:47:59 +05:30
Sukru Senli
2ec059a373 sulu-vendorext: remove unused vendor extensions 2025-09-25 10:09:58 +02:00
Vivek Kumar Dutta
7193985d39 icwmp: Generate error on duplicate params 2025-09-25 11:55:16 +05:30
Jouni Ikonen
74372dab99 Bug 18049: Use separate file for sulu functions 2025-09-25 09:19:11 +05:30
Vivek Kumar Dutta
6bc7842b0d sulu-vendorext: Fix compilation 2025-09-24 17:35:16 +05:30
Reidar Cederqvist
87c2d0bb10 sulu: update to version 2 (5.1.3) 2025-09-24 01:04:33 +02:00
Sukru Senli
1e2f6161d6 sulu-vendorext: replace X_GENEXIS_EU_mesh with X_IOWRT_EU_MAPController 2025-09-23 10:07:13 +00:00
Jakob Olsson
bbb3df8c17 map-controller: config: add name to unique sections
channel_plan and sta_steering are unique sections, and should be named. Additionally added uci-default script to name the sections if missing
2025-09-23 11:50:17 +02:00
147 changed files with 3391 additions and 4846 deletions

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bbfdm
PKG_VERSION:=1.16.6.2
PKG_VERSION:=1.16.6.6
USE_LOCAL:=0
ifneq ($(USE_LOCAL),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bbfdm.git
PKG_SOURCE_VERSION:=aa480554461c82e6f6f44ee6c23108d3e44fce21
PKG_SOURCE_VERSION:=6317266bdfb0180d75ed2dd830e108f09fe2526a
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -107,7 +107,7 @@ endif
CMAKE_OPTIONS += \
-DBBF_VENDOR_PREFIX:String="$(CONFIG_BBF_VENDOR_PREFIX)" \
-DBBFDMD_MAX_MSG_LEN:Integer=10485760 \
-DBBFDMD_MAX_MSG_LEN:Integer=20971520 \
-DCMAKE_BUILD_TYPE:String="Debug" \

View File

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

12
dhcpmngr/Config.in Normal file
View File

@@ -0,0 +1,12 @@
if PACKAGE_dhcpmngr
config DHCPMNGR_ENABLE_VENDOR_EXT
bool "Use datamodel vendor extensions"
default y
help
Set this option to use bridge BBF vendor extensions.
config DHCPMNGR_VENDOR_PREFIX
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dhcpmngr
PKG_VERSION:=1.0.6
PKG_VERSION:=1.0.10
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/dhcpmngr.git
PKG_SOURCE_VERSION:=986f66608959f4f589009d580b046e250d8c620d
PKG_SOURCE_VERSION:=e238e47fa13153c5b1890056b0d09c65879de8c5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -39,6 +39,22 @@ define Package/dhcpmngr/description
Package to add Device.DHCPv4. and Device.DHCPv6. data model support.
endef
define Package/$(PKG_NAME)/config
source "$(SOURCE)/Config.in"
endef
ifeq ($(CONFIG_DHCPMNGR_ENABLE_VENDOR_EXT),y)
MAKE_FLAGS += DHCPMNGR_ENABLE_VENDOR_EXT=y
endif
ifeq ($(CONFIG_DHCPMNGR_VENDOR_PREFIX),"")
VENDOR_PREFIX = $(CONFIG_BBF_VENDOR_PREFIX)
else
VENDOR_PREFIX = $(CONFIG_DHCPMNGR_VENDOR_PREFIX)
endif
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(VENDOR_PREFIX)\\\"
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/dhcpmngr/* $(PKG_BUILD_DIR)/

48
dmcli-plugins/Makefile Normal file
View File

@@ -0,0 +1,48 @@
#
# Copyright (c) 2023 Genexis Netherlands 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 Netherlands B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dmcli-plugins
PKG_LICENSE:=PROPRIETARY GENEXIS
PKG_VERSION:=2.2.6
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/gnx/dmcli-plugin-easydm.git
PKG_SOURCE_VERSION:=bc8b8527e8a41bdba73cb277a3c6c3b42b045153
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/dmcli-plugins
SECTION:=tools
CATEGORY:=Genexis
TITLE:=Easy-to-use data model on top of TR181
URL:=http://genexis.eu
DEPENDS:=+dmcli
endef
define Package/dmcli-plugins/description
EasyDM offers a user-friendly approach to configuring TR-181
simplifying the process with its intuitive interface.
endef
define Build/Compile
true
endef
define Package/dmcli-plugins/install
$(INSTALL_DIR) $(1)/usr/lib/dmcli/plugins
$(CP) $(PKG_BUILD_DIR)/src/*.js $(1)/usr/lib/dmcli/plugins/
endef
$(eval $(call BuildPackage,dmcli-plugins))

9
dmcli/Config.in Normal file
View File

@@ -0,0 +1,9 @@
if PACKAGE_dmcli
config DMCLI_REMOTE_CONNECTION
bool "Add dmcli remote controller configuration"
default n
help
This adds a usp controller configuration for dmcli remote connection from different machine/laptop/server.
endif

75
dmcli/Makefile Normal file
View File

@@ -0,0 +1,75 @@
#
# Copyright (c) 2021 Genexis Netherlands 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 Netherlands B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dmcli
PKG_LICENSE:=PROPRIETARY GENEXIS
PKG_VERSION:=1.9.4
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/gnx/dmcli.git
PKG_SOURCE_VERSION:=2139e81d0faca09fe1832c503297ef75ea76d6eb
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/dmcli
SECTION:=tools
CATEGORY:=Genexis
TITLE:=DMCLI (datamodel-based CLI)
URL:=http://genexis.eu
DEPENDS:=+usp-js +DMCLI_REMOTE_CONNECTION:mosquitto-auth-plugin +shadow-utils +@BUSYBOX_CONFIG_ADDUSER
endef
define Package/dmcli/description
CLI to view and configure datamodels of CPE
endef
define Package/dmcli/conffiles
/etc/dmcli/dmcli.conf
endef
define Package/dmcli/config
source "$(SOURCE)/Config.in"
endef
define Package/dmcli/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dmcli $(1)/usr/bin/
$(INSTALL_DIR) $(1)/usr/lib/dmcli
$(CP) $(PKG_BUILD_DIR)/common $(1)/usr/lib/dmcli/
mv $(1)/usr/lib/dmcli/common/os_qjs.js $(1)/usr/lib/dmcli/common/os.js
rm $(1)/usr/lib/dmcli/common/os_node.js
$(CP) $(PKG_BUILD_DIR)/core $(1)/usr/lib/dmcli/
$(CP) $(PKG_BUILD_DIR)/cli $(1)/usr/lib/dmcli/
$(CP) $(PKG_BUILD_DIR)/data $(1)/usr/lib/dmcli/
$(CP) $(PKG_BUILD_DIR)/plugins $(1)/usr/lib/dmcli/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) ./files/etc/uci-defaults/36-dmcli $(1)/etc/uci-defaults/
ifeq ($(CONFIG_DMCLI_REMOTE_CONNECTION),y)
$(INSTALL_DATA) ./files/etc/uci-defaults/36-dmcli-remote $(1)/etc/uci-defaults/
else
$(INSTALL_DATA) ./files/etc/uci-defaults/36-dmcli-remote-remove $(1)/etc/uci-defaults/
endif
$(INSTALL_DIR) $(1)/etc/dmcli
$(CP) ./files/etc/dmcli/dmcli.acl $(1)/etc/dmcli/
$(CP) ./files/etc/dmcli/dmcli.conf $(1)/etc/dmcli/
$(INSTALL_DIR) $(1)/etc/users/roles/
$(INSTALL_DATA) ./files/etc/users/roles/operator.json $(1)/etc/users/roles/
endef
$(eval $(call BuildPackage,dmcli))

View File

@@ -0,0 +1,4 @@
user operator
topic read /usp/operator/controller/reply-to
topic read /usp/operator/controller
topic write /usp/operator/endpoint

View File

@@ -0,0 +1,45 @@
{
"Settings": {
"USP": {
"ActiveConnectionProfile": "local",
"ConnectionProfile": [
{
"Name": "local",
"Host": "127.0.0.1",
"Port": 9002,
"Username": "operator",
"Protocol": "ws",
"FromId": "oui:000F94:device-controller-operator",
"PublishEndpoint": "/usp/operator/endpoint",
"SubscribeEndpoint": "/usp/operator/controller"
}
],
"Session": {
"AutoStart": false
},
"Notification": {
"LogTo": "console",
"Format": "brief",
"LogFile": "usp-notification.log"
}
},
"CLI": {
"Home": "/",
"Color": "true",
"Mode": "Command",
"ShowCommandTime": false,
"SortDMTree": false
},
"Prompt": {
"Auto": true,
"Color": "default",
"SelectedBackgroundColor": "yellow",
"PageSize": "3",
"AutoPromptOnEmptyCommand": false,
"AutoPromptInstanceNumbers": false
},
"Log": {
"Level": "Error"
}
}
}

View File

@@ -0,0 +1,120 @@
#!/bin/sh
. /lib/functions.sh
. /lib/functions/iopsys-environment.sh
. /usr/share/libubox/jshn.sh
DMCLI_CONF="/etc/dmcli/dmcli.conf"
CONTROLLER_ID='oui:000F94:device-controller-operator'
DMCLI_RESP_TOPIC="/usp/operator/endpoint"
DMCLI_CTRL_TOPIC="/usp/operator/controller"
DMCLI_PORT="9002"
grep -q "^operator:" /etc/passwd || {
adduser -g 'Operator' -D -H -s /usr/bin/dmcli --home '/usr/lib/dmcli' 'operator'
hash=""
if type get_operator_password_hash > /dev/null 2>&1; then
hash=$(get_operator_password_hash)
fi
if [ -z "$hash" ]; then
hash='$6$zP4Wk/VQJOLwwofC$teuhnYFQBcA8YUZo/Q0quDMi4SsOHmfBcyvt5VNchPnzgwF1nfNNliC3yBVW22NwmwttPEWeBEBfnMTBB0rYs/'
fi
echo "operator:${hash}" | chpasswd -e
}
grep -q "^/usr/bin/dmcli$" /etc/shells || {
echo '/usr/bin/dmcli' >> /etc/shells
}
uci -q del_list sshd.@sshd[0].AllowUsers='operator'
uci -q add_list sshd.@sshd[0].AllowUsers='operator'
uci -q delete users.operator
uci -q set users.operator=user
uci -q set users.operator.enabled=1
uci -q set users.operator.shell='dmcli'
uci -q set users.operator.member_roles='operator'
if [ -f "/etc/config/mosquitto" ]; then
uci_add mosquitto listener dmcli_local
uci_set mosquitto dmcli_local enabled 1
uci_set mosquitto dmcli_local port "${DMCLI_PORT}"
uci_set mosquitto dmcli_local protocol 'websockets'
uci_set mosquitto dmcli_local acl_file '/etc/dmcli/dmcli.acl'
uci_set mosquitto dmcli_local no_remote_access '1'
uci_set mosquitto dmcli_local allow_anonymous '1'
fi
if [ -f "/etc/config/obuspa" ]; then
uci_add obuspa mqtt mqtt_operator
uci_set obuspa mqtt_operator BrokerAddress '127.0.0.1'
uci_set obuspa mqtt_operator BrokerPort '1883'
uci_set obuspa mqtt_operator TransportProtocol 'TCP/IP'
uci_add obuspa mtp mtp_operator
uci_set obuspa mtp_operator Protocol 'MQTT'
uci_set obuspa mtp_operator ResponseTopicConfigured "${DMCLI_RESP_TOPIC}"
uci_set obuspa mtp_operator mqtt 'mqtt_operator'
uci_add obuspa controller controller_operator
uci_set obuspa controller_operator EndpointID "${CONTROLLER_ID}"
uci_set obuspa controller_operator Protocol 'MQTT'
uci_set obuspa controller_operator Topic "${DMCLI_CTRL_TOPIC}"
uci_set obuspa controller_operator mqtt 'mqtt_operator'
uci_set obuspa controller_operator assigned_role_name 'operator'
fi
_get_endpoint_id() {
local id serial oui
id="$(uci -q get obuspa.localagent.EndpointID)"
if [ -n "${id}" ]; then
echo "${id}"
return 0
fi
serial="$(db -q get device.deviceinfo.SerialNumber)"
oui="$(db -q get device.deviceinfo.ManufacturerOUI)"
echo "os::${oui}-${serial//+/%2B}"
}
update_dmcli_conf() {
local endpointid confTmpFile
local port fromid publish subscribe toid
if [ -f "${DMCLI_CONF}" ]; then
endpointid="$(_get_endpoint_id)"
json_load_file "${DMCLI_CONF}" || return
json_select "Settings" || return
json_select "USP" || return
json_select "ConnectionProfile" || return
json_select "1" || return
json_get_var port "Port"
json_get_var fromid "FromId"
json_get_var publish "PublishEndpoint"
json_get_var subscribe "SubscribeEndpoint"
json_get_var toid "ToId"
json_add_int "Port" "${DMCLI_PORT}"
json_add_string "FromId" "${CONTROLLER_ID}"
json_add_string "PublishEndpoint" "${DMCLI_RESP_TOPIC}"
json_add_string "SubscribeEndpoint" "${DMCLI_CTRL_TOPIC}"
json_add_string "ToId" "${endpointid}"
json_select ..
json_select ..
json_select ..
json_select ..
if [ "${port}" != "${DMCLI_PORT}" ] || [ "${fromid}" != "${CONTROLLER_ID}" ] || \
[ "${publish}" != "${DMCLI_RESP_TOPIC}" ] || [ "${subscribe}" != "${DMCLI_CTRL_TOPIC}" ] || \
[ "${toid}" != "${endpointid}" ]; then
confTmpFile="$(mktemp -u -p "$(dirname "$DMCLI_CONF")" "$(basename "$DMCLI_CONF").XXXXXXX")"
json_pretty
json_dump > "${confTmpFile}" || return
mv -f "${confTmpFile}" "${DMCLI_CONF}" || return
fi
fi
}
update_dmcli_conf || exit

View File

@@ -0,0 +1,14 @@
#!/bin/sh
. /lib/functions.sh
if [ -f "/etc/config/mosquitto" ]; then
uci_add mosquitto listener dmcli
uci_set mosquitto dmcli enabled 1
uci_set mosquitto dmcli port '9003'
uci_set mosquitto dmcli protocol 'websockets'
uci_set mosquitto dmcli auth_plugin '/usr/lib/mosquitto_auth_plugin.so'
uci_set mosquitto dmcli acl_file '/etc/dmcli/dmcli.acl'
fi
exit 0

View File

@@ -0,0 +1,9 @@
#!/bin/sh
. /lib/functions.sh
if [ -f "/etc/config/mosquitto" ]; then
uci_remove mosquitto dmcli
fi
exit 0

View File

@@ -0,0 +1,14 @@
{
"tr181": {
"name": "operator",
"instance": 6,
"permission": [
{
"object": "Device.",
"perm": [
"PERMIT_ALL"
]
}
]
}
}

7
dmcli/src/Makefile Normal file
View File

@@ -0,0 +1,7 @@
all: dmcli
dmcli: main.c
$(CC) $(CFLAGS) -Wall -Werror -o $@ $^
clean:
rm -f dmcli

32
dmcli/src/main.c Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2021 Genexis Netherlands 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 Netherlands B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/* C Wrapper for operator to login to the CLI via ssh: the shell in
* the passwd file cannot be a script that requires an interpreter. */
int main(int argc, char *argv[])
{
char *cmd[3 + (argc > 1 ? argc - 1 : 0)];
cmd[0] = "/usr/bin/qjs";
cmd[1] = "/usr/lib/dmcli/cli/main.js";
cmd[2] = NULL;
if (argc > 1) {
memcpy(&cmd[2], &argv[1], (argc - 1) * sizeof(char *));
cmd[2 + argc - 1] = NULL;
}
execv(cmd[0], cmd);
fprintf(stderr, "%s: command not found\n", cmd[0]);
return 127;
}

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmngr
PKG_VERSION:=1.0.18
PKG_VERSION:=1.0.20
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/dnsmngr.git
PKG_SOURCE_VERSION:=80fa147e6f1f0d9c1a62a62a693ff3adaef45363
PKG_SOURCE_VERSION:=448d278734a824f9d4ad1e7a55acd16c222d4c7e
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:=ethmngr
PKG_VERSION:=3.0.8
PKG_VERSION:=3.0.9
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/ethmngr.git
PKG_SOURCE_VERSION:=c73e5b15718ca40b2740bbe6151dfbb2bcca16df
PKG_SOURCE_VERSION:=0bcfd98d64b5bd8d3162944e2abd5740f9bf4b92
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -8,5 +8,11 @@ config FIREWALLMNGR_PORT_TRIGGER
help
Set this option to include support for PortTrigger object.
config FIREWALLMNGR_NAT_INTERFACE_SETTING
bool "Include Device.NAT.InterfaceSetting"
default y
help
Set this option to include support for NAT InterfaceSetting object.
endmenu
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=firewallmngr
PKG_VERSION:=1.0.9
PKG_VERSION:=1.0.9.5
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/firewallmngr.git
PKG_SOURCE_VERSION:=77ad8425b73a3ac63f6160dc217635394ac87907
PKG_SOURCE_VERSION:=02dc90c48d996148b68d02632bac13a28d75cf25
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -52,6 +52,10 @@ ifeq ($(CONFIG_FIREWALLMNGR_PORT_TRIGGER),y)
TARGET_CFLAGS += -DINCLUDE_PORT_TRIGGER
endif
ifeq ($(CONFIG_FIREWALLMNGR_NAT_INTERFACE_SETTING),y)
TARGET_CFLAGS += -DINCLUDE_NAT_IF_SETTING
endif
define Package/firewallmngr/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DIR) $(1)/etc/uci-defaults

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=hostmngr
PKG_VERSION:=1.3.3
PKG_VERSION:=1.3.6
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=fee5bd0067fc1f30498bc2b81e893d170796b459
PKG_SOURCE_VERSION:=624fee52af9cce08c6c69a5f7dd2191691d61aa8
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/hostmngr.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip

View File

@@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=icwmp
PKG_VERSION:=9.9.9.3
PKG_VERSION:=9.9.9.8
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/icwmp.git
PKG_SOURCE_VERSION:=55a64d756afd6249b8bb4cccf2cdaa7e1aa05f91
PKG_SOURCE_VERSION:=cef78dc528690386caac5a7ff6c1afca6dd3d315
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -84,6 +84,7 @@ define Package/icwmp/install
$(INSTALL_BIN) $(PKG_BUILD_DIR)/icwmpd $(1)/usr/sbin/icwmpd
$(INSTALL_DATA) ./files/etc/config/cwmp $(1)/etc/config/cwmp
$(INSTALL_BIN) ./files/etc/init.d/icwmpd $(1)/etc/init.d/icwmpd
$(INSTALL_BIN) ./files/etc/uci-defaults/50-cwmp-align-keep-config $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/85-cwmp-set-userid $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/90-cwmpfirewall $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/95-set-random-inform-time $(1)/etc/uci-defaults/

View File

@@ -43,7 +43,9 @@ config cpe 'cpe'
option periodic_notify_interval '10'
option incoming_rule 'Port_Only'
option active_notif_throttle '0'
option fw_upgrade_keep_settings '1'
#option KeepConfig '1'
#option KeepOpConf '1'
#option ConfigScope 'UserOnly'
option clock_sync_timeout '128'
option disable_datatype_check '0'
#list allowed_cr_ip '10.5.1.0/24'

View File

@@ -97,7 +97,9 @@ validate_cpe_section()
'periodic_notify_enable:bool' \
'enable:bool:1' \
'periodic_notify_interval:uinteger' \
'fw_upgrade_keep_settings:bool'
'KeepConfig:bool' \
'KeepOpConf:bool' \
'ConfigScope:string'
}
validate_defaults() {
@@ -168,13 +170,21 @@ start_service() {
stop_service()
{
local switch_bank
local switch_bank KeepConfig KeepOpConf ConfigScope
copy_cwmp_varstate_files_to_etc
switch_bank=$(uci -q -c /var/state/ get icwmp.cpe.switch_bank)
if [ -n "$switch_bank" ] && [ "$switch_bank" = "1" ]; then
[ -x /etc/sysmngr/fwbank ] && /etc/sysmngr/fwbank call copy_config
if [ "$switch_bank" = "1" ] && [ -x /etc/sysmngr/fwbank ]; then
KeepConfig="$(uci -q get cwmp.cpe.KeepConfig)"
KeepOpConf="$(uci -q get cwmp.cpe.KeepOpConf)"
ConfigScope="$(uci -q get cwmp.cpe.ConfigScope)"
json_init
[ -n "${KeepConfig}" ] && json_add_boolean "keep_config" "${KeepConfig}"
[ -n "${KeepOpConf}" ] && json_add_boolean "keep_opconf" "${KeepOpConf}"
[ -n "${ConfigScope}" ] && json_add_string "config_scope" "${ConfigScope}"
json_dump| /etc/sysmngr/fwbank call copy_config
fi
}

View File

@@ -0,0 +1,7 @@
#!/bin/sh
keep_settings="$(uci -q get cwmp.cpe.fw_upgrade_keep_settings)"
if [ -n "${keep_settings}" ]; then
uci -q delete cwmp.cpe.fw_upgrade_keep_settings
uci -q set cwmp.cpe.KeepConfig="${keep_settings}"
fi

View File

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

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libdpp
PKG_VERSION:=2.1.2
PKG_VERSION:=2.1.3
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=5f1184c52be19f3bfd3bc7e9bc582ef09b0a2b1c
PKG_SOURCE_VERSION:=fdfe23e51ff77ca6d2661ad6208d097758524147
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/libdpp.git
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz

View File

@@ -1,32 +1,28 @@
#
# Copyright (C) 2020-2023 Iopsys
# Copyright (C) 2025 Genexis Sweden AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=libeasy
PKG_VERSION:=7.4.6
PKG_VERSION:=7.5.1
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=ca7b20068c9d373e41045a2e899a9c697576262c
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/libeasy.git
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_SOURCE_VERSION:=b981f7e1bd51f66041cd0c25d15af74ae1e3bc75
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/libeasy.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=LGPL-2.1-only
PKG_LICENSE_FILES:=LICENSE
PKG_LICENSE_FILES:=
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@genexis.eu>
include $(INCLUDE_DIR)/package.mk
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/openssl \
-I$(STAGING_DIR)/usr/include/libnl3
include $(INCLUDE_DIR)/cmake.mk
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
@@ -34,9 +30,6 @@ define Build/Prepare
endef
endif
MAKE_FLAGS += \
CFLAGS="$(TARGET_CFLAGS) -Wall"
define Package/libeasy
SECTION:=libs
CATEGORY:=Libraries
@@ -47,7 +40,7 @@ define Package/libeasy
endef
define Package/libeasy/description
Library provides common utility functions
This package provides libeasy.so for common utility functions.
endef
define Build/InstallDev/libeasy
@@ -67,6 +60,7 @@ define Build/InstallDev/libeasy
endef
define Build/InstallDev
$(call Build/InstallDev/cmake,$(1))
$(call Build/InstallDev/libeasy,$(1),$(2))
endef

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libwifi
PKG_VERSION:=7.13.6
PKG_VERSION:=7.13.10
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=d17ad7415a821e95618c4739507bf129df3fdebf
PKG_SOURCE_VERSION:=5e8d828c01ed7ab2feba9028b603dde9708cb656
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/libwifi.git
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
@@ -61,7 +61,7 @@ else
endif
ifneq ($(CONFIG_PACKAGE_kmod-mt7915e_en7523),)
TARGET_CFLAGS=-DMT7915_VENDOR_EXT
TARGET_CFLAGS +=-DMT7915_VENDOR_EXT
endif
PKG_BUILD_DEPENDS:=PACKAGE_kmod-mt7915e_en7523:mt76_en7523

View File

@@ -31,8 +31,8 @@ MESON_ARGS += \
define Package/linux-pam/install
$(INSTALL_DIR) $(1)/usr/lib/security
$(INSTALL_DIR) $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/pam_faillock.uci_default $(1)/etc/uci-defaults/99-add_pam_faillock
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./linux_pam.init $(1)/etc/init.d/linux_pam
endef
$(eval $(call BuildPackage,linux-pam))

View File

@@ -1,43 +0,0 @@
#!/bin/sh
create_faillock_files()
{
# also create files needed by pam_faillock
touch /var/log/faillock
chmod 700 /var/log/faillock
touch /var/log/btmp
chmod 700 /var/log/btmp
}
update_pam_common_auth()
{
local file="/etc/pam.d/common-auth"
local deny=6
local unlock_time=300
# update pam_unix.so line
sed -i -E 's|^.*pam_unix\.so.*|auth\t sufficient\tpam_unix.so nullok_secure|' "$file"
# Insert pam_faillock lines before and after pam_unix.so
sed -i -E "/pam_unix.so nullok_secure/i auth required pam_faillock.so preauth deny=$deny even_deny_root unlock_time=$unlock_time" "$file"
sed -i -E "/pam_unix.so nullok_secure/a auth [default=die] pam_faillock.so authfail audit deny=$deny even_deny_root unlock_time=$unlock_time" "$file"
}
update_pam_common_account()
{
# update account file
sed -i "/pam_unix.so/ i account required pam_faillock.so" /etc/pam.d/common-account
}
if [ -f "/usr/lib/security/pam_faillock.so" ]; then
update_pam_common_auth
update_pam_common_account
create_faillock_files
fi
if [ -f /etc/config/sshd ]; then
uci -q set sshd.@sshd[0].UsePAM=1
uci commit sshd
fi
exit 0

18
linux-pam/linux_pam.init Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh /etc/rc.common
START=11
STOP=90
USE_PROCD=1
create_faillock_files()
{
# also create files needed by pam_faillock
touch /var/log/faillock
chmod 700 /var/log/faillock
touch /var/log/btmp
chmod 700 /var/log/btmp
}
boot() {
create_faillock_files
}

View File

@@ -65,8 +65,10 @@ define Package/logmngr/install
$(INSTALL_DIR) $(1)/lib/logmngr
ifeq ($(CONFIG_LOGMNGR_BACKEND_FLUENTBIT),y)
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_DIR) $(1)/etc/hotplug.d/ntp/
$(INSTALL_BIN) ./files/logread $(1)/sbin/
$(INSTALL_DATA) ./files/lib/logmngr/fluent-bit.sh $(1)/lib/logmngr/
$(INSTALL_BIN) ./files/etc/hotplug.d/ntp/20-reload_fluent_bit $(1)/etc/hotplug.d/ntp/
else ifeq ($(CONFIG_LOGMNGR_BACKEND_SYSLOG_NG),y)
$(INSTALL_DATA) ./files/lib/logmngr/syslog-ng.sh $(1)/lib/logmngr/
endif

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

@@ -0,0 +1,14 @@
#!/bin/sh
# This hotplug script reloads fluent-bit, so that kmsg logs' timestamp gets in sync
[ "$ACTION" = stratum ] || exit 0
# only once
if ! uci -q get time.global.first_use_date > /dev/null 2>&1; then
flb_pid="$(pidof fluent-bit)"
if [ -n "$flb_pid" ]; then
logger -t "logmngr.hotplug" -p info "reload fluent-bit due to ntp sync"
kill -SIGHUP "$flb_pid"
fi
fi

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

@@ -55,6 +55,10 @@ config AGENT_OPER_CHANNEL_CHANGE_RELAY_MCAST
config AGENT_USE_LIBDPP
bool "Depend on libdpp for DPP EasyConnect"
config AGENT_ZEROTOUCH_DPP
bool "Enable Zero-touch DPP bootstrapping. Depends on libztdpp.so"
default n
config AGENT_CHECK_PARTIAL_WIFI_RELOAD
bool "Option that allow SSID/PSK simple reload"
default y

View File

@@ -1,13 +1,14 @@
#
# Copyright (C) 2020-2023 IOPSYS Software Solutions AB
# Copyright (C) 2020-2024 IOPSYS Software Solutions AB
# Copyright (C) 2025 Genexis Sweden AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=map-agent
PKG_VERSION:=6.3.6.15
PKG_VERSION:=6.3.7.19
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=7b05d265776fca2ff84a63188fcec55c08057e33
PKG_SOURCE_VERSION:=5fbcb1c110e82a8788e359d947ec099328e13164
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@iopsys.eu>
PKG_LICENSE:=BSD-3-Clause
@@ -26,7 +27,7 @@ include $(INCLUDE_DIR)/package.mk
define Package/map-agent
SECTION:=utils
CATEGORY:=Utilities
TITLE:=WiFi multi-AP Agent (EasyMesh R2)
TITLE:=Wi-Fi Multi-AP Agent (EasyMesh R6)
DEPENDS:=+libwifi +libuci +libubox +ubus +libeasy +libieee1905 +ieee1905 \
+ieee1905-map-plugin +ip-bridge +AGENT_USE_LIBDPP:libdpp \
+uuidgen +openssl-util +!TARGET_brcmbca:ebtables-legacy \
@@ -45,9 +46,12 @@ define Package/dynbhd
+ieee1905-map-plugin +map-agent
endef
ifeq ($(CONFIG_AGENT_ZEROTOUCH_DPP),y)
TARGET_CFLAGS += -DZEROTOUCH_DPP
endif
define Package/map-agent/description
This package implements EasyMesh R2 compliant WiFi Agent.
This package provides EasyMesh R6 compliant Wi-Fi Multi-AP Agent.
endef
define Package/dynbhd/description

View File

@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
START=98
START=97
STOP=20
USE_PROCD=1

View File

@@ -0,0 +1,53 @@
#!/bin/sh
. /lib/functions.sh
cfg=mapagent
config_load $cfg
if uci -q get $cfg.agent.partial_wifi_reload >/dev/null; then
uci -q set $cfg.agent.partial_wifi_reload='0'
fi
if uci -q get $cfg.agent.chan_ch_relay_mcast >/dev/null; then
uci -q set $cfg.agent.chan_ch_relay_mcast='0'
fi
rename_dpp_uri() {
local section="$1"
local type device ifname band
local ch_list=""
config_get type "$section" type
config_get device "$section" device
config_get ifname "$section" ifname
config_get band "$section" band
config_get chirp_interval "$section" chirp_interval
append_chan() {
local val="$1"
local chan_num="${val#*/}"
ch_list="$ch_list $chan_num"
}
config_list_foreach "$section" chan append_chan
new_section=$(uci add "$cfg" dpp_chirp)
[ -n "$type" ] && uci set "$cfg.$new_section.type=$type"
[ -n "$device" ] && uci set "$cfg.$new_section.device=$device"
[ -n "$ifname" ] && uci set "$cfg.$new_section.ifname=$ifname"
[ -n "$band" ] && uci set "$cfg.$new_section.band=$band"
if [ -n "$chirp_interval" ]; then
uci set "${cfg}.${new_section}.chirp_interval=$chirp_interval"
fi
for ch in $ch_list; do
uci add_list "$cfg.$new_section.channel=$ch"
done
uci delete "$cfg.$section"
}
uci -q delete "$cfg.@dpp_controller[0]"
config_foreach rename_dpp_uri dpp_uri
exit 0

View File

@@ -44,19 +44,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
@@ -158,13 +155,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

@@ -39,6 +39,10 @@ config CONTROLLER_EASYMESH_VENDOR_EXT_OUI
config CONTROLLER_USE_LIBDPP
bool "Depend on libdpp for DPP EasyConnect"
config CONTROLLER_ZEROTOUCH_DPP
bool "Enable Zero-touch DPP bootstrapping via passphrase."
default n
config CONTROLLER_PROPAGATE_PROBE_REQ
depends on CONTROLLER_EASYMESH_VENDOR_EXT
bool "Enable publishing probe requests vendor specific messages as UBUS events"

View File

@@ -6,9 +6,9 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-controller
PKG_VERSION:=6.4.2.9
PKG_VERSION:=6.4.4.24
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=c427bbaa53ce470a45a59326281f214f1111c3f7
PKG_SOURCE_VERSION:=e149d0c26dc7a382638e7778f8cf1c01f382b76e
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@genexis.eu>
LOCAL_DEV=0
@@ -36,6 +36,9 @@ ifeq ($(CONFIG_CONTROLLER_USE_LIBDPP),y)
TARGET_CFLAGS += -DUSE_LIBDPP
endif
ifeq ($(CONFIG_CONTROLLER_ZEROTOUCH_DPP),y)
TARGET_CFLAGS += -DZEROTOUCH_DPP
endif
define Package/map-controller/description
This package provides WiFi MultiAP Controller as per the EasyMesh-R2 specs.
@@ -81,6 +84,7 @@ define Build/InstallDev
$(CP) $(PKG_BUILD_DIR)/src/cntlr_commands_impl.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/cntlr_commands.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/cntlr_apis.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/cntlr_plugin.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/wifi_opclass.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/steer_module.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/timer.h $(1)/usr/include/map-controller

View File

@@ -10,10 +10,11 @@ config controller 'controller'
option primary_pcp '0'
option stale_sta_timeout '30d'
option de_collect_interval '60'
list plugin 'zerotouch'
config sta_steering
config sta_steering 'sta_steering'
option enable_sta_steer '1'
option enable_bsta_steer '0'
option enable_bsta_steer '1'
option rcpi_threshold_2g '70'
option rcpi_threshold_5g '86'
option rcpi_threshold_6g '86'
@@ -23,8 +24,10 @@ config sta_steering
option plugins_enabled '1'
option plugins_policy 'any'
list plugins 'rcpi'
list plugins 'rate'
list plugins 'bsteer'
config channel_plan
config channel_plan 'channel_plan'
option preclear_dfs '0'
option acs '0'

View File

@@ -0,0 +1,31 @@
#!/bin/sh
. /lib/functions.sh
cfg=mapcontroller
config_load $cfg
uci -q get $cfg.controller.debug >/dev/null 2>&1 && \
uci set $cfg.controller.debug='2'
allow_bgdfs=$(uci -q get $cfg.controller.allow_bgdfs || echo "0")
channel_plan_val=$(uci -q get $cfg.controller.channel_plan || echo "0")
uci -q delete $cfg.controller.allow_bgdfs
uci -q delete $cfg.controller.channel_plan
uci -q get $cfg.controller.stale_sta_timeout >/dev/null 2>&1 || \
uci set $cfg.controller.stale_sta_timeout='30d'
if [ -f /usr/lib/mapcontroller/zerotouch.so ]; then
uci -q del_list $cfg.controller.plugin='zerotouch'
uci -q add_list $cfg.controller.plugin='zerotouch'
fi
if ! uci show $cfg 2>/dev/null | grep -q "=channel_plan"; then
section=$(uci add $cfg channel_plan)
uci set $cfg.$section.preclear_dfs="$allow_bgdfs"
uci set $cfg.$section.acs="$channel_plan_val"
fi
exit 0

View File

@@ -0,0 +1,18 @@
#!/bin/sh
. /lib/functions.sh
cfg=mapcontroller
# singleton sections
sections="channel_plan sta_steering"
for sec in $sections; do
# find unnamed section of given type, only index 0
s=$(uci show $cfg | grep -oE "@${sec}\[0\]" | sort -u)
[ "$s" = "" ] && continue
uci rename $cfg.$s=$sec
done
uci commit $cfg

View File

@@ -21,9 +21,21 @@ adapt_sta_steering() {
uci -q del $cfg.@sta_steering[0].use_usta_metrics
uci -q del $cfg.@sta_steering[0].bandsteer
uci -q del $cfg.@sta_steering[0].diffsnr
if [ -f /usr/lib/mapcontroller/rcpi.so ]; then
uci -q del_list $cfg.@sta_steering[0].plugins="rcpi"
uci -q add_list $cfg.@sta_steering[0].plugins="rcpi"
fi
if [ -f /usr/lib/mapcontroller/rate.so ]; then
uci -q del_list $cfg.@sta_steering[0].plugins="rate"
uci -q add_list $cfg.@sta_steering[0].plugins="rate"
fi
if [ -f /usr/lib/mapcontroller/bsteer.so ]; then
uci -q del_list $cfg.@sta_steering[0].plugins="bsteer"
uci -q add_list $cfg.@sta_steering[0].plugins="bsteer"
fi
uci del_list $cfg.@sta_steering[0].plugins="rcpi"
uci add_list $cfg.@sta_steering[0].plugins="rcpi"
uci -q set $cfg.@sta_steering[0].plugins_enabled="1"
uci -q set $cfg.@sta_steering[0].plugins_policy="any"

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-plugins
PKG_VERSION:=1.0.32
PKG_VERSION:=1.2.7
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=d8b310edad1b9777aed805682394e3f9bb300d81
PKG_SOURCE_VERSION:=5ac759ae1f8cbedc539053d940f2e7d3652e4531
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
@@ -27,12 +27,18 @@ include $(INCLUDE_DIR)/package.mk
include $(wildcard plugins/*.mk)
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/libnl3 \
-D_GNU_SOURCE
MAKE_FLAGS += \
CFLAGS="$(TARGET_CFLAGS) -Wall"
plugins := \
$(if $(CONFIG_PACKAGE_map-plugins-steer-rate),steer-rate) \
$(if $(CONFIG_PACKAGE_map-plugins-bsteer),bsteer)
$(if $(CONFIG_PACKAGE_map-plugins-bsteer),bsteer) \
$(if $(CONFIG_PACKAGE_map-plugins-zero-touch),zero-touch)
ppkg:=$(patsubst plugins/%.mk,map-plugins-%,$(wildcard plugins/*.mk))

View File

@@ -0,0 +1,22 @@
define Package/map-plugins-zero-touch
$(call Package/map-plugins/Default)
TITLE:=Full Zero-touch bootstrapping of Wi-Fi Repeater device(s)
DEPENDS= +libubox +libuci +libubus +libeasy +libnl-genl \
+libjson-c +libblobmsg-json +map-controller \
+map-plugins
endef
define Package/map-plugins-zero-touch/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/lib/mapcontroller
$(CP) $(PKG_BUILD_DIR)/zero-touch/zerotouch.so $(1)/usr/lib/mapcontroller/zerotouch.so
$(CP) $(PKG_BUILD_DIR)/zero-touch/libztdpp.so $(1)/usr/lib/libztdpp.so
endef
define Build/Compile/map-plugins-zero-touch
$(MAKE) -C $(PKG_BUILD_DIR)/zero-touch \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)";
endef

View File

@@ -0,0 +1,7 @@
if PACKAGE_mosquitto-auth-plugin
config MOSQUITTO_AUTH_PAM_SUPPORT
bool "Enable support of Linux PAM module for Authentication"
default y
endif

View File

@@ -13,33 +13,42 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mosquitto-auth-shadow
PKG_VERSION:=1.0.1
PKG_NAME:=mosquitto-auth-plugin
PKG_VERSION:=1.2.1
PKG_MAINTAINER:=Erik Karlsson <erik.karlsson@genexis.eu>
PKG_LICENSE:=EPL-2.0
PKG_BUILD_PARALLEL:=1
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
DEPENDS:=+mosquitto-ssl
DEPENDS:=+mosquitto-ssl +MOSQUITTO_AUTH_PAM_SUPPORT:libpam
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/install
define Package/mosquitto-auth-plugin/config
source "$(SOURCE)/Config.in"
endef
ifeq ($(CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT),y)
TARGET_CFLAGS+=-DENABLE_PAM_SUPPORT
endif
define Package/mosquitto-auth-plugin/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_shadow.so $(1)/usr/lib/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_plugin.so $(1)/usr/lib/
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,mosquitto-auth-shadow))
$(eval $(call BuildPackage,mosquitto-auth-plugin))

View File

@@ -11,15 +11,15 @@
# 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
$(CC) $(LDFLAGS) -shared -o $@ $^
mosquitto_auth_plugin.so: mosquitto_auth_plugin.pic.o
$(CC) $(LDFLAGS) -shared -o $@ $^ $(if $(filter -DENABLE_PAM_SUPPORT,$(CFLAGS)),-lpam)
clean:
rm -f *.o $(TARGETS)

View File

@@ -0,0 +1,670 @@
/*
* 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 {
union {
uint32_t ipv4_network;
uint8_t ipv6_network[16];
};
union {
uint32_t ipv4_netmask;
uint8_t ipv6_netmask[16];
};
int is_ipv6;
} 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;
char *config_file;
} plugin_data_t;
/* Parse CIDR notation for IPv4 or IPv6 (e.g., "192.168.1.0/24" or "2001:db8::/32") */
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;
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);
}
/* 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;
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;
}
/* 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;
}
/* Check if IPv4 address is in subnet */
static int ipv4_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;
}
/* 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)
{
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;
}
/* 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 with simplified format
* 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;
/* Initialize user count */
pdata->user_count = 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;
}
/* 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;
}
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_ERR,
"subnet_acl: Invalid directive '%s' at line %d (expected 'subnet')",
token, line_num);
fclose(fp);
return -1;
}
/* 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;
}
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;
}
/* 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 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;
}
/* 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;
}
/* 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;
}
/* 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++;
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++;
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;
}
/* 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)
{
const user_acl_t *user_acl;
const char *client_address;
/* Skip if no subnet config loaded */
if (pdata == NULL || pdata->user_count == 0)
return MOSQ_ERR_SUCCESS;
/* Skip anonymous users */
if (ed->username == NULL)
return MOSQ_ERR_SUCCESS;
/* Find user's subnet ACL */
user_acl = find_user_acl(pdata, ed->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_SUCCESS;
/* 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;
}
/* 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;
}
}
/* 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;
}
}
/* No subnet rules for this user - allow */
return MOSQ_ERR_SUCCESS;
}
#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;
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 */
#ifdef ENABLE_PAM_SUPPORT
auth_result = process_pam_auth_callback(ed);
#else
auth_result = 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);
}
static int reload_callback(int event, void *event_data, void *userdata)
{
plugin_data_t *pdata = userdata;
if (pdata == NULL)
return MOSQ_ERR_SUCCESS;
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Reloading subnet ACL configuration from '%s'",
pdata->config_file ? pdata->config_file : "(none)");
/* Reload subnet ACL configuration */
if (load_subnet_acl_config(pdata, pdata->config_file) != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to reload subnet ACL configuration, keeping old config");
return MOSQ_ERR_UNKNOWN;
}
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Reload complete, now tracking %d user(s)", pdata->user_count);
return MOSQ_ERR_SUCCESS;
}
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;
int rc;
/* 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;
/* Store config file path for reload */
if (config_file != NULL) {
pdata->config_file = strdup(config_file);
if (pdata->config_file == NULL) {
free(pdata);
return MOSQ_ERR_NOMEM;
}
} else {
pdata->config_file = NULL;
}
/* Load subnet ACL configuration */
if (load_subnet_acl_config(pdata, config_file) != 0) {
free(pdata->config_file);
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->config_file);
free(pdata);
return rc;
}
/* Register reload callback to handle SIGHUP */
rc = mosquitto_callback_register(identifier, MOSQ_EVT_RELOAD,
reload_callback, NULL, pdata);
if (rc != MOSQ_ERR_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to register reload callback");
mosquitto_callback_unregister(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
free(pdata->config_file);
free(pdata);
return rc;
}
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;
}
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_RELOAD,
reload_callback, NULL);
free(pdata->config_file);
free(pdata);
}
return MOSQ_ERR_SUCCESS;
}

View File

@@ -1,81 +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 <mosquitto.h>
#include <mosquitto_broker.h>
#include <mosquitto_plugin.h>
static int basic_auth_callback(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_basic_auth *ed = event_data;
struct spwd spbuf, *sp = NULL;
char buf[256];
struct crypt_data data;
char *hash;
/* Let other plugins or broker decide about anonymous login */
if (ed->username == NULL)
return MOSQ_ERR_PLUGIN_DEFER;
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;
}
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

@@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=netmode
PKG_VERSION:=1.1.5
PKG_VERSION:=1.1.11
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=GPL-2.0-only
@@ -18,6 +18,7 @@ include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/netmode
CATEGORY:=Utilities
TITLE:=Network Modes and Utils
DEPENDS:=+dm-service
endef
define Package/netmode/description

View File

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

View File

@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
START=10
START=11
USE_PROCD=1
. /lib/functions.sh
@@ -117,6 +117,7 @@ start_service() {
config_get_bool enabled global enabled '0'
[ $enabled -eq 0 ] && return
[ -d $MODEDIR ] || mkdir -p $MODEDIR
# Get the desired netmode from config
config_get mode global mode ""
# Check if netmode is set as boot environment parameter
@@ -127,9 +128,12 @@ start_service() {
# Get the last saved mode
lastmode="$(cat $MODEDIR/.last_mode 2>/dev/null)"
# Return if desired mode is same as last saved mode
[ "$mode" == "$lastmode" ] && return
if [ "$mode" = "$lastmode" ]; then
_log "Not switching mode[${mode}], lastmode[${lastmode}]"
return
fi
_log "Switching to [${mode}] Mode" >/dev/console
_log "Switching to [${mode}] Mode"
# Configure env variables
configure_env_vars ${mode}
@@ -147,20 +151,19 @@ start_service() {
# Execute mode specific scripts
if [ -d $MODEDIR/$mode/scripts ]; then
_log "Executing $MODEDIR/$mode/scripts/* scripts"
for script in $(ls $MODEDIR/$mode/scripts/); do
_log "Executing [${mode}], script [${script}]"
sh $MODEDIR/$mode/scripts/$script
done
fi
# Save mode as last mode
echo "$mode" > $MODEDIR/.last_mode
_log "Switching to Mode [${mode}] done, last mode updated"
# Execute netmode generic post-mode-switch scripts
libnetmode_exec "post"
cleanup_env_vars "${mode}"
# Save mode as last mode
[ -d $MODEDIR ] || mkdir -p $MODEDIR
echo "$mode" > $MODEDIR/.last_mode
_log "Switching to Mode [${mode}] done, last mode updated" >/dev/console
}
service_triggers()

View File

@@ -61,8 +61,8 @@ l2_network_config() {
uci -q set network.lan6.device='@lan'
uci -q set network.lan6.reqprefix='no'
uci -q set network.wan.disabled='1'
uci -q set network.wan6.disabled='1'
uci -q delete network.wan
uci -q delete network.wan6
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
@@ -116,12 +116,3 @@ l2_network_config() {
l2_network_config
l2_mcast_config
# If device is already boot-up, assume netmode changed during runtime
if [ -f /var/run/boot_complete ]; then
/etc/init.d/odhcpd stop 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

@@ -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,44 @@ 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 set network.wan6.proto="dhcpv6"
uci -q delete network.wan6.disabled
# Delete all VLAN sections; new ones will be created in next function if required
for vlandev_sec in $(uci show network | grep "type=.*8021q" | cut -d'.' -f1,2); do
uci -q delete $vlandev_sec
done
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
vlandev="$wandev.$NETMODE_vlanid"
vlandev_sec=$(echo $vlandev | tr '.' '_')
uci -q set network.${vlandev_sec}=device
uci -q set network.${vlandev_sec}.type="8021q"
uci -q set network.${vlandev_sec}.name="$vlandev"
uci -q set network.${vlandev_sec}.ifname="$wandev"
uci -q set network.${vlandev_sec}.vid=$NETMODE_vlanid
wandev="$vlandev"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.wan6.device="$wandev"
uci -q set network.WAN.mtu="$NETMODE_mtu"
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 +96,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
@@ -97,12 +126,3 @@ l3_network_config() {
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

@@ -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,8 +38,40 @@ 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'
uci -q delete network.wan6
# Delete all VLAN sections; new ones will be created in next function if required
for vlandev_sec in $(uci show network | grep "type=.*8021q" | cut -d'.' -f1,2); do
uci -q delete $vlandev_sec
done
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
vlandev="$wandev.$NETMODE_vlanid"
vlandev_sec=$(echo $vlandev | tr '.' '_')
uci -q set network.${vlandev_sec}=device
uci -q set network.${vlandev_sec}.type="8021q"
uci -q set network.${vlandev_sec}.name="$vlandev"
uci -q set network.${vlandev_sec}.ifname="$wandev"
uci -q set network.${vlandev_sec}.vid=$NETMODE_vlanid
wandev="$vlandev"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.WAN.mtu="$NETMODE_mtu"
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 +93,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
@@ -95,12 +123,3 @@ l3_network_pppoe_config() {
l3_network_pppoe_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

@@ -0,0 +1,126 @@
#!/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 delete network.wan6
# Delete all VLAN sections; new ones will be created in next function if required
for vlandev_sec in $(uci show network | grep "type=.*8021q" | cut -d'.' -f1,2); do
uci -q delete $vlandev_sec
done
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
vlandev="$wandev.$NETMODE_vlanid"
vlandev_sec=$(echo $vlandev | tr '.' '_')
uci -q set network.${vlandev_sec}=device
uci -q set network.${vlandev_sec}.type="8021q"
uci -q set network.${vlandev_sec}.name="$vlandev"
uci -q set network.${vlandev_sec}.ifname="$wandev"
uci -q set network.${vlandev_sec}.vid=$NETMODE_vlanid
wandev="$vlandev"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.WAN.mtu="$NETMODE_mtu"
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

View File

@@ -3,25 +3,96 @@
"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": "mtu",
"description": "MTU",
"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,60 @@
#!/bin/sh
enabled="$(uci -q get netmode.global.enabled)"
if [ "$enabled" != "1" ]; then
exit 0
fi
opconf_file="/opconf/opconf.json"
[ -f $opconf_file ] || opconf_file="/usr_data/opconf/opconf.json"
# Check if netmode getting provisioned from opconf, in case of opconf
# provisioning, mode setting not required
mode="$(jsonfilter -i $opconf_file -e @.netmode.mode 2>/dev/null)"
if [ -n "${mode}" ]; then
exit 0
fi
# Check if opconf has wan provisioning enabled, if yes, get the proto/mode from opconf
proto="$(jsonfilter -i $opconf_file -e '@.network.wan[@.name="wan"].proto' 2>/dev/null)"
if [ -n "${proto}" ]; then
mode="routed-${proto}"
uci -q set netmode.global.mode="${mode}"
echo "${mode}" > /etc/netmodes/.last_mode
exit 0
fi
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
if [ ! -f "/etc/netmodes/supported_modes.json" ]; then
exit 0
fi
# NetMode is enabled without a Mode being set
# Figure out the current mode from network config
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
else
exit 1
fi

View File

@@ -1,25 +1,17 @@
#!/bin/sh
# This script is to cleanup dmmap and restart datamodel related services
# when wan mode changes
if [ -d "/etc/bbfdm/dmmap/" ]; then
rm -rf /etc/bbfdm/dmmap/*
fi
# If device is booting up, no need to restart services
if [ ! -f /var/run/boot_complete ]; then
return 0
exit 0
fi
if [ -x "/etc/init.d/bbfdm.services" ]; then
/etc/init.d/bbfdm.services restart
if [ -f /etc/bbfdm/dmmap/dmmap_ppp ]; then
rm -f /etc/bbfdm/dmmap/dmmap_ppp
fi
if [ -x "/etc/init.d/bbfdmd" ]; then
/etc/init.d/bbfdmd restart
if [ -f /etc/bbfdm/dmmap/dmmap_network ]; then
rm -f /etc/bbfdm/dmmap/dmmap_network*
fi
if [ -x "/etc/init.d/obuspa" ]; then
/etc/init.d/obuspa restart
fi
sleep 5
reboot -f

View File

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

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=obuspa
PKG_VERSION:=10.0.0.16
PKG_VERSION:=10.0.0.22
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/obuspa.git
PKG_SOURCE_VERSION:=479ffb3582aa245a84829502d9412ca2539eefca
PKG_SOURCE_VERSION:=12991107039ee685fcd1000bb2649dd1c4b344ff
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
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
@@ -691,6 +649,11 @@ configure_obuspa() {
if [ -f "${trust_cert}" ]; then
procd_append_param command -t "${trust_cert}"
fi
else
# Use default CA, if trust store not defined
if [ -f "/etc/ssl/cert.pem" ]; then
procd_append_param command -t "/etc/ssl/cert.pem"
fi
fi
if [ -n "${client_cert}" ]; then
@@ -701,301 +664,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
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
log "Syncing obuspa uci with usp.db ...."
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
@@ -1011,21 +707,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
}
start_service() {
@@ -1033,25 +720,22 @@ start_service() {
mkdir -p /tmp/obuspa/
config_load obuspa
config_get_bool enabled global enabled 0
config_get_bool enabled global enabled 1
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}" \
"${respawn_timeout:-10}" "${respawn_retry:-5}"
#procd_set_param limits core="unlimited"
fi
procd_close_instance ${CONFIGURATION}
}
stop_service() {
if command -v timeout >/dev/null 2>&1; then
timeout 5 ${PROG} -c stop
fi
${PROG} -c stop
}
reload_service() {
@@ -1060,5 +744,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()
{
@@ -57,18 +58,18 @@ get_vivsoi() {
data="${opt125}"
rem_len="${len}"
while [ $rem_len -gt 0 ]; do
while [ "${rem_len}" -gt 0 ]; do
ent_id=${data:0:8}
ent_id=$(printf "%d\n" "0x$ent_id")
if [ $ent_id -ne 3561 ]; then
if [ "${ent_id}" -ne 3561 ]; then
len_val=${data:8:2}
data_len=$(printf "%d\n" "0x$len_val")
# add 4 byte for ent_id and 1 byte for len
data_len=$(( data_len * 2 + 10 ))
# move ahead data to next enterprise id
data=${data:"${data_len}":"${rem_len}"}
rem_len=$(( rem_len - $data_len ))
rem_len=$(( rem_len - data_len ))
continue
fi
@@ -79,7 +80,7 @@ get_vivsoi() {
data_len=$(( data_len * 2 + 10 ))
opt_len=$(printf "%d\n" "0x$len_val")
[ $opt_len -eq 0 ] && return
[ "${opt_len}" -eq 0 ] && return
# populate the option data of enterprise id
sub_data_len=$(( opt_len * 2))
@@ -98,28 +99,28 @@ get_vivsoi() {
sub_opt_len=$(( sub_opt_len * 2 ))
# get the value of sub option starting 4 means starting after length
sub_opt_val=${sub_data:4:${sub_opt_len}}
sub_opt_val=${sub_data:4:"${sub_opt_len}"}
# assign the value found in sub option
case "${sub_opt_id}" in
"25")
URL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
URL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
CONTROLLER_DISCOVERED=1
;;
"26")
PROV_CODE=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
PROV_CODE=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
CONTROLLER_DISCOVERED=1
;;
"27")
RETRY_MIN_INTERVAL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
RETRY_MIN_INTERVAL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
CONTROLLER_DISCOVERED=1
;;
"28")
RETRY_INTERVAL_MUL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
RETRY_INTERVAL_MUL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
CONTROLLER_DISCOVERED=1
;;
"29")
ENDPOINT_ID=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
ENDPOINT_ID=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
CONTROLLER_DISCOVERED=1
;;
esac
@@ -131,7 +132,7 @@ get_vivsoi() {
sub_data_len=$((sub_data_len - sub_opt_end))
# fetch next sub option hex string
sub_data=${sub_data:${sub_opt_end}:${sub_data_len}}
sub_data=${sub_data:"${sub_opt_end}":"${sub_data_len}"}
done
# move ahead data to next enterprise id
@@ -146,7 +147,7 @@ get_access_role()
lan_proto="$(uci -q get network.lan.proto)"
if [ "${lan_proto}" == "dhcp" ]; then
if [ "${lan_proto}" = "dhcp" ]; then
mode="extender"
else
mode="full_access"
@@ -174,7 +175,7 @@ config_get_bool enable_obuspa global enabled 1
config_get wan_intf global interface
config_get_bool dhcp_discovery global dhcp_discovery 1
if [ "$enable_obuspa" = "0" ] || [ "$dhcp_discovery" = "0" ]; then
if [ "${enable_obuspa}" -eq 0 ] || [ "${dhcp_discovery}" -eq 0 ]; then
return 0
fi
@@ -190,9 +191,9 @@ if [ -z "${wan_intf}" ]; then
fi
fi
if [ "${wan_intf}" == "${INTERFACE}" ]; then
if [ "${wan_intf}" = "${INTERFACE}" ]; then
if [ -n "$opt125" ]; then
len=$(printf "$opt125"|wc -c)
len=$(echo -n "${opt125}"|wc -c)
get_vivsoi "$opt125" "$len"
fi
@@ -228,10 +229,10 @@ if [ "${wan_intf}" == "${INTERFACE}" ]; then
;;
*)
# This is an FQDN, perform DNS query
nslookup $URL > /tmp/fqdn_ip
nslookup -type=ptr $URL > /tmp/fqdn_ptr
nslookup -type=srv $URL > /tmp/fqdn_srv
nslookup -type=txt $URL > /tmp/fqdn_srv
nslookup "${URL}" > /tmp/fqdn_ip
nslookup -type=ptr "${URL}" > /tmp/fqdn_ptr
nslookup -type=srv "${URL}" > /tmp/fqdn_srv
nslookup -type=txt "${URL}" > /tmp/fqdn_srv
# TODO extend to collect information from dns-sd records
;;
@@ -247,16 +248,16 @@ if [ "${wan_intf}" == "${INTERFACE}" ]; then
fi
fi
if [ "${proto}" == "mqtt" ] || [ "${proto}" == "mqtts" ]; then
if [ "${proto}" = "mqtt" ] || [ "${proto}" = "mqtts" ]; then
offered_proto="MQTT"
if [ "${proto}" == "mqtt" ]; then
if [ "${proto}" = "mqtt" ]; then
mtp_encrypt="TCP/IP"
else
mtp_encrypt="TLS"
fi
elif [ "${proto}" == "ws" ] || [ "${proto}" == "wss" ]; then
elif [ "${proto}" = "ws" ] || [ "${proto}" = "wss" ]; then
offered_proto="WebSocket"
if [ "${proto}" == "wss" ]; then
if [ "${proto}" = "wss" ]; then
mtp_encrypt="1"
else
mtp_encrypt="0"
@@ -265,35 +266,46 @@ if [ "${wan_intf}" == "${INTERFACE}" ]; then
controllers=$(uci -q show obuspa | grep "=controller" | cut -d'=' -f1 | cut -d'.' -f2)
for controller in $controllers; do
dhcp_disc=$(uci -q get obuspa.$controller.dhcp_discovered)
dhcp_disc=$(uci -q get obuspa."${controller}".dhcp_discovered)
if [ "${dhcp_disc}" -eq 1 ]; then
dhcp_controller="${controller}"
break
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
dhcp_mqtt="$(uci -q get obuspa.$dhcp_controller.mqtt)"
cont_proto=$(uci -q get obuspa."${dhcp_controller}".Protocol)
if [ "${cont_proto}" = "MQTT" ]; then
dhcp_mqtt=$(uci -q get obuspa."${dhcp_controller}".mqtt)
mtps=$(uci -q show obuspa | grep "=mtp" | cut -d'=' -f1 | cut -d'.' -f2)
for mtp in $mtps; do
mtp_mqtt="$(uci -q get obuspa.$mtp.mqtt)"
if [ "${mtp_mqtt}" == "${dhcp_mqtt}" ]; then
mtp_mqtt=$(uci -q get obuspa."${mtp}".mqtt)
if [ "${mtp_mqtt}" = "${dhcp_mqtt}" ]; then
dhcp_mtp="${mtp}"
break
fi
done
elif [ "${cont_proto}" == "WebSocket" ]; then
cont_port="$(uci -q get obuspa.$dhcp_controller.Port)"
cont_encr="$(uci -q get obuspa.$dhcp_controller.EnableEncryption)"
elif [ "${cont_proto}" = "WebSocket" ]; then
cont_port=$(uci -q get obuspa."${dhcp_controller}".Port)
cont_encr=$(uci -q get obuspa."${dhcp_controller}".EnableEncryption)
mtps=$(uci -q show obuspa | grep "=mtp" | cut -d'=' -f1 | cut -d'.' -f2)
for mtp in $mtps; do
mtp_port="$(uci -q get obuspa.$mtp.Port)"
mtp_encr="$(uci -q get obuspa.$mtp.EnableEncryption)"
if [ "${mtp_port}" == "${cont_port}" ] && [ "${mtp_encr}" == "${cont_encr}" ]; then
mtp_port=$(uci -q get obuspa."${mtp}".Port)
mtp_encr=$(uci -q get obuspa."${mtp}".EnableEncryption)
if [ "${mtp_port}" = "${cont_port}" ] && [ "${mtp_encr}" = "${cont_encr}" ]; then
dhcp_mtp="${mtp}"
break
fi
@@ -306,43 +318,43 @@ if [ "${wan_intf}" == "${INTERFACE}" ]; then
if [ -n "${dhcp_controller}" ]; then
## Handling of controller section
ct_endpoint=$(uci -q get obuspa.$dhcp_controller.EndpointID)
ct_proto=$(uci -q get obuspa.$dhcp_controller.Protocol)
ct_prov=$(uci -q get obuspa.$dhcp_controller.ProvisioningCode)
ct_endpoint=$(uci -q get obuspa."${dhcp_controller}".EndpointID)
ct_proto=$(uci -q get obuspa."${dhcp_controller}".Protocol)
ct_prov=$(uci -q get obuspa."${dhcp_controller}".ProvisioningCode)
if [ "${ct_proto}" = "MQTT" ]; then
ct_topic=$(uci -q get obuspa.$dhcp_controller.Topic)
ct_topic=$(uci -q get obuspa."${dhcp_controller}".Topic)
else
ct_topic=$(uci -q get obuspa.$dhcp_controller.Path)
ct_topic=$(uci -q get obuspa."${dhcp_controller}".Path)
fi
if [ -n "${ENDPOINT_ID}" ] && [ "${ct_endpoint}" != "${ENDPOINT_ID}" ]; then
uci -q set obuspa.$dhcp_controller.EndpointID="${ENDPOINT_ID}"
uci -q set obuspa."${dhcp_controller}".EndpointID="${ENDPOINT_ID}"
uci_change=1
fi
if [ -n "${offered_proto}" ] && [ "${ct_proto}" != "${offered_proto}" ]; then
uci -q set obuspa.$dhcp_controller.Protocol="${offered_proto}"
uci -q set obuspa."${dhcp_controller}".Protocol="${offered_proto}"
if [ "${offered_proto}" != "MQTT" ]; then
uci -q set obuspa.$dhcp_controller.mqtt=""
uci -q set obuspa.$dhcp_controller.Topic=""
uci -q set obuspa.$dhcp_controller.Host="${ip}"
uci -q set obuspa.$dhcp_controller.Port="${port}"
uci -q set obuspa.$dhcp_controller.Path="${ct_topic}"
uci -q set obuspa.$dhcp_controller.EnableEncryption="${mtp_encrypt}"
uci -q delete obuspa."${dhcp_controller}".mqtt
uci -q delete obuspa."${dhcp_controller}".Topic
uci -q set obuspa."${dhcp_controller}".Host="${ip}"
uci -q set obuspa."${dhcp_controller}".Port="${port}"
uci -q set obuspa."${dhcp_controller}".Path="${ct_topic}"
uci -q set obuspa."${dhcp_controller}".EnableEncryption="${mtp_encrypt}"
else
uci -q set obuspa.$dhcp_controller.EnableEncryption=""
uci -q set obuspa.$dhcp_controller.Path=""
uci -q set obuspa.$dhcp_controller.Host=""
uci -q set obuspa.$dhcp_controller.Port=""
uci -q delete obuspa."${dhcp_controller}".EnableEncryption
uci -q delete obuspa."${dhcp_controller}".Path
uci -q delete obuspa."${dhcp_controller}".Host
uci -q delete obuspa."${dhcp_controller}".Port
if [ -z "${dhcp_mqtt}" ]; then
uci -q set obuspa.$dhcp_controller.mqtt='dhcpmqtt'
uci -q set obuspa."${dhcp_controller}".mqtt='dhcpmqtt'
else
uci -q set obuspa.$dhcp_controller.mqtt="${dhcp_mqtt}"
uci -q set obuspa."${dhcp_controller}".mqtt="${dhcp_mqtt}"
fi
uci -q set obuspa.$dhcp_controller.Topic="${ct_topic}"
uci -q set obuspa."${dhcp_controller}".Topic="${ct_topic}"
fi
proto_changed=1
@@ -355,38 +367,37 @@ if [ "${wan_intf}" == "${INTERFACE}" ]; then
protocol="${offered_proto}"
fi
if [ "${protocol}" == "MQTT" ]; then
uci -q set obuspa.$dhcp_controller.Topic="${topic}"
if [ "${protocol}" = "MQTT" ]; then
uci -q set obuspa."${dhcp_controller}".Topic="${topic}"
else
uci -q set obuspa.$dhcp_controller.Path="${topic}"
uci -q set obuspa."${dhcp_controller}".Path="${topic}"
fi
uci_change=1
fi
if [ -n "${PROV_CODE}" ] && [ "${ct_prov}" != "${PROV_CODE}" ]; then
uci -q set obuspa.$dhcp_controller.ProvisioningCode="${PROV_CODE}"
uci -q set obuspa."${dhcp_controller}".ProvisioningCode="${PROV_CODE}"
uci_change=1
fi
if [ "${proto_changed}" -eq 1 ]; then
if [ "${offered_proto}" == "WebSocket" ]; then
if [ "${offered_proto}" = "WebSocket" ]; then
if [ -n "${dhcp_mqtt}" ]; then
uci -q del obuspa.$dhcp_mqtt
uci -q delete obuspa."${dhcp_mqtt}"
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'
uci -q set obuspa."${dhcp_mtp}".Enable='1'
fi
uci -q set obuspa.$dhcp_mtp.mqtt=''
uci -q set obuspa.$dhcp_mtp.ResponseTopicConfigured=''
uci -q set obuspa.$dhcp_mtp.Protocol='WebSocket'
uci -q set obuspa.$dhcp_mtp.Port="${port}"
uci -q set obuspa.$dhcp_mtp.EnableEncryption="${mtp_encrypt}"
uci -q set obuspa."${dhcp_mtp}".mqtt=''
uci -q set obuspa."${dhcp_mtp}".ResponseTopicConfigured=''
uci -q set obuspa."${dhcp_mtp}".Protocol='WebSocket'
uci -q set obuspa."${dhcp_mtp}".Port="${port}"
uci -q set obuspa."${dhcp_mtp}".EnableEncryption="${mtp_encrypt}"
uci_change=1
else
@@ -394,137 +405,135 @@ 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}"
uci -q set obuspa.$dhcp_mqtt.Password="${pass}"
uci -q set obuspa."${dhcp_mqtt}".Enable='1'
uci -q set obuspa."${dhcp_mqtt}".Username="${user}"
uci -q set obuspa."${dhcp_mqtt}".Password="${pass}"
fi
uci -q set obuspa.$dhcp_mqtt.BrokerAddress="${ip}"
uci -q set obuspa.$dhcp_mqtt.BrokerPort="${port}"
uci -q set obuspa.$dhcp_mqtt.TransportProtocol="${mtp_encrypt}"
uci -q set obuspa.$dhcp_mqtt.ProtocolVersion='5.0'
uci -q set obuspa."${dhcp_mqtt}".BrokerAddress="${ip}"
uci -q set obuspa."${dhcp_mqtt}".BrokerPort="${port}"
uci -q set obuspa."${dhcp_mqtt}".TransportProtocol="${mtp_encrypt}"
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'
uci -q set obuspa."${dhcp_mtp}".Enable='1'
fi
agent_topic=$(get_agent_topic)
uci -q set obuspa.$dhcp_mtp.Port=""
uci -q set obuspa.$dhcp_mtp.EnableEncryption=""
uci -q set obuspa.$dhcp_mtp.Protocol='MQTT'
uci -q set obuspa.$dhcp_mtp.ResponseTopicConfigured="${agent_topic}"
uci -q set obuspa.$dhcp_mtp.mqtt="${dhcp_mqtt}"
uci -q delete obuspa."${dhcp_mtp}".Port
uci -q delete obuspa."${dhcp_mtp}".EnableEncryption
uci -q set obuspa."${dhcp_mtp}".Protocol='MQTT'
uci -q set obuspa."${dhcp_mtp}".ResponseTopicConfigured="${agent_topic}"
uci -q set obuspa."${dhcp_mtp}".mqtt="${dhcp_mqtt}"
uci_change=1
fi
else
if [ "${ct_proto}" == "WebSocket" ]; then
conf_ip="$(uci -q get obuspa.$dhcp_controller.Host)"
conf_port="$(uci -q get obuspa.$dhcp_mtp.Port)"
conf_encr="$(uci -q get obuspa.$dhcp_mtp.EnableEncryption)"
if [ "${ct_proto}" = "WebSocket" ]; then
conf_ip="$(uci -q get obuspa."${dhcp_controller}".Host)"
conf_port="$(uci -q get obuspa."${dhcp_mtp}".Port)"
conf_encr="$(uci -q get obuspa."${dhcp_mtp}".EnableEncryption)"
if [ -n "${ip}" ] && [ "${conf_ip}" != "${ip}" ]; then
uci -q set obuspa.$dhcp_controller.Host="${ip}"
uci -q set obuspa."${dhcp_controller}".Host="${ip}"
uci_change=1
fi
if [ -n "${port}" ] && [ "${conf_port}" != "${port}" ]; then
uci -q set obuspa.$dhcp_mtp.Port="${port}"
uci -q set obuspa.$dhcp_controller.Port="${port}"
uci -q set obuspa."${dhcp_mtp}".Port="${port}"
uci -q set obuspa."${dhcp_controller}".Port="${port}"
uci_change=1
fi
if [ -n "${mtp_encrypt}" ] && [ "${conf_encr}" != "${mtp_encrypt}" ]; then
uci -q set obuspa.$dhcp_mtp.EnableEncryption="${mtp_encrypt}"
uci -q set obuspa.$dhcp_controller.EnableEncryption="${mtp_encrypt}"
uci -q set obuspa."${dhcp_mtp}".EnableEncryption="${mtp_encrypt}"
uci -q set obuspa."${dhcp_controller}".EnableEncryption="${mtp_encrypt}"
uci_change=1
fi
else
conf_ip="$(uci -q get obuspa.$dhcp_mqtt.BrokerAddress)"
conf_port="$(uci -q get obuspa.$dhcp_mqtt.BrokerPort)"
conf_encr="$(uci -q get obuspa.$dhcp_mqtt.TransportProtocol)"
conf_ip=$(uci -q get obuspa."${dhcp_mqtt}".BrokerAddress)
conf_port=$(uci -q get obuspa."${dhcp_mqtt}".BrokerPort)
conf_encr=$(uci -q get obuspa."${dhcp_mqtt}".TransportProtocol)
if [ -n "${port}" ] && [ "${conf_port}" != "${port}" ]; then
uci -q set obuspa.$dhcp_mqtt.BrokerPort="${port}"
uci -q set obuspa."${dhcp_mqtt}".BrokerPort="${port}"
uci_change=1
fi
if [ -n "${mtp_encrypt}" ] && [ "${conf_encr}" != "${mtp_encrypt}" ]; then
uci -q set obuspa.$dhcp_mqtt.TransportProtocol="${mtp_encrypt}"
uci -q set obuspa."${dhcp_mqtt}".TransportProtocol="${mtp_encrypt}"
uci_change=1
fi
if [ -n "${ip}" ] && [ "${conf_ip}" != "${ip}" ]; then
uci -q set obuspa.$dhcp_mqtt.BrokerAddress="${ip}"
uci -q set obuspa."${dhcp_mqtt}".BrokerAddress="${ip}"
uci_change=1
fi
fi
fi
else
uci -q del obuspa.dhcpmtp
uci -q del 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

@@ -1,176 +0,0 @@
Index: obuspa-10.0.0.2/src/core/device.h
===================================================================
--- obuspa-10.0.0.2.orig/src/core/device.h
+++ obuspa-10.0.0.2/src/core/device.h
@@ -305,6 +305,8 @@ void DEVICE_CTRUST_ApplyPermissionsToSub
char *DEVICE_CTRUST_InstSelToPermTarget(int role_index, void *is, int *perm_instance);
int DEVICE_CTRUST_SetRoleParameter(int instance, char *param_name, char *new_value);
int DEVICE_CTRUST_SetPermissionParameter(int instance1, int instance2, char *param_name, char *new_value);
+bool DEVICE_CTRUST_IsControllerSecured(void);
+
int DEVICE_REQUEST_Init(void);
int DEVICE_REQUEST_Add(char *path, char *command_key, int *instance);
void DEVICE_REQUEST_OperationComplete(int instance, int err_code, char *err_msg, kv_vector_t *output_args);
Index: obuspa-10.0.0.2/src/core/device_ctrust.c
===================================================================
--- obuspa-10.0.0.2.orig/src/core/device_ctrust.c
+++ obuspa-10.0.0.2/src/core/device_ctrust.c
@@ -235,6 +235,7 @@ credential_t *FindCredentialByCertInstan
int Get_CredentialRole(dm_req_t *req, char *buf, int len);
int Get_CredentialCertificate(dm_req_t *req, char *buf, int len);
int Get_CredentialNumEntries(dm_req_t *req, char *buf, int len);
+int Validate_SecuredRoles(dm_req_t *req, char *value);
#ifndef REMOVE_DEVICE_SECURITY
int InitChallengeTable();
@@ -354,6 +355,10 @@ int DEVICE_CTRUST_Init(void)
challenge_response_input_args, NUM_ELEM(challenge_response_input_args),
NULL, 0);
#endif
+
+ // Register Device.LocalAgent.ControllerTrust.SecuredRoles parameter
+ err |= USP_REGISTER_DBParam_ReadWrite(DEVICE_CTRUST_ROOT ".SecuredRoles", "", Validate_SecuredRoles, NULL, DM_STRING);
+
// Exit if any errors occurred
if (err != USP_ERR_OK)
{
@@ -2908,3 +2913,139 @@ exit:
return err;
}
#endif // REMOVE_DEVICE_SECURITY
+
+
+/*********************************************************************//**
+**
+** Validate_SecuredRoles
+**
+** Validates Device.LocalAgent.ControllerTrust.SecuredRoles
+** Each list item MUST be the Path Name of a row in the Device.LocalAgent.ControllerTrust.Role table
+**
+** \param req - pointer to structure identifying the parameter
+** \param value - value that the controller would like to set the parameter to
+**
+** \return USP_ERR_OK if successful
+**
+**************************************************************************/
+int Validate_SecuredRoles(dm_req_t *req, char *value)
+{
+ char *role_path;
+ char *saveptr;
+ char *str;
+ char temp[MAX_DM_PATH];
+ int role_instance;
+ int err;
+
+ // Empty string is valid
+ if (*value == '\0')
+ {
+ return USP_ERR_OK;
+ }
+
+ // Copy the value as strtok_r modifies the string
+ USP_STRNCPY(temp, value, sizeof(temp));
+
+ // Iterate through comma-separated list
+ str = temp;
+ role_path = strtok_r(str, ",", &saveptr);
+ while (role_path != NULL)
+ {
+ // Trim whitespace
+ role_path = TEXT_UTILS_TrimBuffer(role_path);
+
+ // Verify that this path exists in the Role table using DM_ACCESS_ValidateReference
+ err = DM_ACCESS_ValidateReference(role_path, "Device.LocalAgent.ControllerTrust.Role.{i}", &role_instance);
+ if (err != USP_ERR_OK)
+ {
+ USP_ERR_SetMessage("%s: Role path '%s' does not exist in Device.LocalAgent.ControllerTrust.Role table", __FUNCTION__, role_path);
+ return USP_ERR_INVALID_VALUE;
+ }
+
+ role_path = strtok_r(NULL, ",", &saveptr);
+ }
+
+ return USP_ERR_OK;
+}
+
+/*********************************************************************//**
+**
+** DEVICE_CTRUST_IsControllerSecured
+**
+** Determines whether the specified controller has a secured role
+**
+** \param combined_role - pointer to structure containing the role indexes for this controller
+**
+** \return true if the controller has a secured role, false otherwise
+**
+**************************************************************************/
+bool DEVICE_CTRUST_IsControllerSecured()
+{
+ char secured_roles[MAX_DM_PATH];
+ char *role_path;
+ char *saveptr;
+ char *str;
+ char temp[MAX_DM_PATH];
+ int err;
+ role_t *role;
+ int role_instance;
+ combined_role_t combined_role;
+ controller_info_t ci;
+
+ // Exit if unable to get the secured roles
+ err = DATA_MODEL_GetParameterValue("Device.LocalAgent.ControllerTrust.SecuredRoles", secured_roles, sizeof(secured_roles), 0);
+ if (err != USP_ERR_OK)
+ {
+ return false;
+ }
+
+ // Empty string means no secured roles
+ if (*secured_roles == '\0')
+ {
+ return false;
+ }
+
+ MSG_HANDLER_GetControllerInfo(&ci);
+ if (ci.endpoint_id == NULL)
+ {
+ return false;
+ }
+ if(strlen(ci.endpoint_id) == 0)
+ {
+ return false;
+ }
+
+ MSG_HANDLER_GetMsgRole(&combined_role);
+ // Copy the value as strtok_r modifies the string
+ USP_STRNCPY(temp, secured_roles, sizeof(temp));
+
+ // Iterate through comma-separated list
+ str = temp;
+ role_path = strtok_r(str, ",", &saveptr);
+ while (role_path != NULL)
+ {
+ // Trim whitespace
+ role_path = TEXT_UTILS_TrimBuffer(role_path);
+
+ // Extract the instance number from the role path
+ err = DM_ACCESS_ValidateReference(role_path, "Device.LocalAgent.ControllerTrust.Role.{i}", &role_instance);
+ if (err == USP_ERR_OK)
+ {
+ // Find the role in our internal array
+ role = FindRoleByInstance(role_instance);
+ if (role != NULL)
+ {
+ // Check if this role matches either the inherited or assigned role
+ if ((role - roles == combined_role.inherited_index) ||
+ (role - roles == combined_role.assigned_index))
+ {
+ return true;
+ }
+ }
+ }
+
+ role_path = strtok_r(NULL, ",", &saveptr);
+ }
+
+ return false;
+}

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.3.1
PKG_VERSION:=1.4.6
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:=b1e5b3f81f08271bdaf9cb4bda8a7696a27be3c6
PKG_SOURCE_VERSION:=2cada36853091856e3efc2fc630f7cf06aa9c352
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -27,7 +27,7 @@ define Package/parental-control
CATEGORY:=Utilities
TITLE:=URL filter
DEPENDS:=+libuci +libnetfilter-queue +libnfnetlink +iptables-mod-nfqueue +libpthread
DEPENDS+=+libubox +ubus +conntrack +libcurl +cmph
DEPENDS+=+libubox +ubus +conntrack +libcurl +cmph +libjson-c
DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service
endef
@@ -83,18 +83,14 @@ define Package/parental-control/install
$(INSTALL_DATA) ./files/etc/uci-defaults/95-firewall_parentalcontrol.ucidefaults $(1)/etc/uci-defaults/
$(INSTALL_DATA) ./files/etc/uci-defaults/35-migrate_urlfilter.ucidefaults $(1)/etc/uci-defaults/
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/parentalcontrol $(1)/lib/upgrade/keep.d/parentalcontrol
$(BBFDM_REGISTER_SERVICES) -v ${VENDOR_PREFIX} ./bbfdm_service.json $(1) parentalcontrol
$(INSTALL_DATA) ./files/etc/uci-defaults/40-parental_control_update_bundle_path $(1)/etc/uci-defaults/
ifeq ($(CONFIG_PARENTAL_CONTROL_URLFILTERING),y)
$(INSTALL_DATA) ./files/etc/uci-defaults/50-parental_control_add_bundles $(1)/etc/uci-defaults/
$(CP) ./files/urlbundle_override.json $(1)/etc/parentalcontrol/
$(INSTALL_DATA) ./files/etc/parentalcontrol/url_bundles.json $(1)/etc/parentalcontrol/
$(INSTALL_DATA) ./files/etc/parentalcontrol/urlbundle_override.json $(1)/etc/parentalcontrol/
else
$(BBFDM_INSTALL_MS_PLUGIN) -v ${VENDOR_PREFIX} ./files/urlbundle_override.json $(1) parentalcontrol
$(INSTALL_DATA) ./files/etc/uci-defaults/50-parental_control_disable_urlfilter $(1)/etc/uci-defaults/
endif
endef

View File

@@ -1,3 +1,4 @@
config globals 'globals'
option enable '1'
option loglevel '3'
option urlfilter '0'

View File

@@ -12,7 +12,9 @@ validate_global_section() {
uci_validate_section parentalcontrol globals globals \
'enable:bool:1' \
'loglevel:uinteger:3' \
'queue_num:uinteger:53' \
'bundle_path:string' \
'default_wan_interface:string:wan' \
'urlfilter:bool'
}
@@ -24,11 +26,12 @@ remove_fw_rules() {
}
configure_fw_rules() {
local enable urlfilter
local enable urlfilter queue_num
config_load parentalcontrol
config_get_bool enable globals enable 0
config_get_bool urlfilter globals urlfilter 0
config_get queue_num globals queue_num 53
remove_fw_rules
@@ -37,6 +40,11 @@ configure_fw_rules() {
return 0
fi
if [ "${queue_num}" -lt 0 ] || [ "${queue_num}" -gt 65535 ]; then
log "ERROR: queue_num not in 0-65535"
return 1
fi
if [ "${urlfilter}" -eq "1" ]; then
if [ ! -f "${OVERRIDE_JSON}" ]; then
# throw error
@@ -48,11 +56,11 @@ configure_fw_rules() {
hw_nat -! > /dev/null 2>&1
fi
if which conntrack > /dev/null 2>&1; then
conntrack -F > /dev/null 2>&1
flush_conntrack_for_hosts
fi
# this is for urlfilter daemon
add_iptables_nfqueue_rules
add_iptables_nfqueue_rules "$queue_num"
fi
fi
@@ -107,7 +115,7 @@ start_service() {
procd_open_instance "parentalcontrol"
procd_set_param command nice -n 10 "${PROG}" # Lower priority
procd_append_param command -l ${loglevel}
procd_append_param command -l "${loglevel}"
procd_set_param respawn
procd_close_instance
}
@@ -120,11 +128,19 @@ stop_service() {
}
reload_service() {
local arg="$1"
ret=$(ubus call service list '{"name":"parentalcontrol"}' | jsonfilter -qe '@.parentalcontrol.instances.parentalcontrol.running')
if [ "$ret" != "true" ]; then
stop
start
else
if [ "$arg" = "network" ]; then
pidof_sync="$(pidof sync_bundles.sh)"
[ -n "$pidof_sync" ] && kill "$pidof_sync"
sleep 5
fi
configure_fw_rules
copy_dhcp_leases
ubus send parentalcontrol.reload
@@ -132,6 +148,19 @@ reload_service() {
}
service_triggers() {
local enable urlfilter default_wan_interface
validate_global_section || {
return 1
}
if [ "${urlfilter}" = "1" ] && [ "$enable" = "1" ] && [ -n "$default_wan_interface" ]; then
log "Adding interface trigger for $default_wan_interface"
procd_open_trigger
procd_add_interface_trigger "interface.*.up" "$default_wan_interface" /etc/init.d/parentalcontrol reload "network"
procd_close_trigger
fi
procd_add_reload_trigger "parentalcontrol"
procd_add_reload_trigger "schedules"
}

View File

@@ -0,0 +1,76 @@
{
"urlBundles": [
{
"url": "https://blocklistproject.github.io/Lists/alt-version/abuse-nl.txt",
"name": "Abuse"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/ads-nl.txt",
"name": "Ads"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/crypto-nl.txt",
"name": "Crypto"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/drugs-nl.txt",
"name": "Drugs"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/everything-nl.txt",
"name": "Everything else"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/facebook-nl.txt",
"name": "Facebook/Instagram"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/fraud-nl.txt",
"name": "Fraud"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/gambling-nl.txt",
"name": "Gambling"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/malware-nl.txt",
"name": "Malware"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/phishing-nl.txt",
"name": "Phishing"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/piracy-nl.txt",
"name": "Piracy"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/porn-nl.txt",
"name": "Porn"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/ransomware-nl.txt",
"name": "Ransomware"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/redirect-nl.txt",
"name": "Redirect"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/scam-nl.txt",
"name": "Scam"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/tiktok-nl.txt",
"name": "TikTok"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/torrent-nl.txt",
"name": "Torrent"
},
{
"url": "https://blocklistproject.github.io/Lists/alt-version/tracking-nl.txt",
"name": "Tracking"
}
]
}

View File

@@ -25,14 +25,6 @@ check_mounted_app_partition() {
if check_mounted_app_partition; then
uci -q set parentalcontrol.globals.bundle_path="${APPS_DIR}/parentalcontrol"
# configure the urlfilter if not configured
urlfilter="$(uci -q get parentalcontrol.globals.urlfilter)"
if [ -z "${urlfilter}" ]; then
uci -q set parentalcontrol.globals.urlfilter='1'
fi
else
uci -q set parentalcontrol.globals.urlfilter='0'
fi
exit 0

View File

@@ -1,43 +0,0 @@
#!/bin/sh
[ ! -f "/etc/config/parentalcontrol" ] && exit 0
COUNT=1
add_urlbundle()
{
local name url
url="${1}"; shift
name="$*"
uci -q set parentalcontrol.urlbundle_${COUNT}=urlbundle
uci -q set parentalcontrol.urlbundle_${COUNT}.name="${name}"
uci -q set parentalcontrol.urlbundle_${COUNT}.download_url="${url}"
COUNT="$((COUNT+1))"
}
urlfilter="$(uci -q get parentalcontrol.globals.urlfilter)"
if [ "${urlfilter}" -eq "1" ]; then
add_urlbundle "https://blocklistproject.github.io/Lists/alt-version/abuse-nl.txt" "Abuse"
add_urlbundle "https://blocklistproject.github.io/Lists/alt-version/ads-nl.txt" "Ads"
add_urlbundle "https://blocklistproject.github.io/Lists/alt-version/crypto-nl.txt" "Crypto"
add_urlbundle "https://blocklistproject.github.io/Lists/alt-version/drugs-nl.txt" "Drugs"
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/everything-nl.txt' "Everything else"
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/facebook-nl.txt' 'Facebook/Instagram'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/fraud-nl.txt' 'Fraud'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/gambling-nl.txt' 'Gambling'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/malware-nl.txt' 'Malware'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/phishing-nl.txt' 'Phishing'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/piracy-nl.txt' 'Piracy'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/porn-nl.txt' 'Porn'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/ransomware-nl.txt' 'Ransomware'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/redirect-nl.txt' 'Redirect'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/scam-nl.txt' 'Scam'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/tiktok-nl.txt' 'TikTok'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/torrent-nl.txt' 'Torrent'
add_urlbundle 'https://blocklistproject.github.io/Lists/alt-version/tracking-nl.txt' 'Tracking'
fi
exit 0

View File

@@ -1,14 +0,0 @@
#!/bin/sh
. /lib/functions.sh
[ ! -f "/etc/config/parentalcontrol" ] && exit 0
uci -q set parentalcontrol.globals.urlfilter='0'
_delete_urlbundle() {
uci_remove parentalcontrol "${1}"
}
config_load "parentalcontrol"
config_foreach _delete_urlbundle urlbundle

View File

@@ -311,31 +311,6 @@ handle_schedule() {
generate_ip_rule "$utc_start_relative_day" "$utc_end_relative_day" "$utc_start_time" "$utc_stop_time" "$target"
}
# Function that parses input for MAC addresses or hostnames
parse_macs_or_hostnames() {
local input="$1"
local lease_file="/tmp/dhcp.leases"
[ -f "$lease_file" ] || lease_file="/etc/parentalcontrol/dhcp.leases"
[ -f "$lease_file" ] || { log "Error: No DHCP lease file found."; return 1; }
for item in $input; do
case "$item" in
??:??:??:??:??:??)
# It's a MAC address, print it as is
echo "$item"
;;
*)
# Assume it's a hostname and search for its MAC address in the leases file
mac=$(awk -v hostname="$item" '$4 == hostname {print $2}' "$lease_file")
if [ -n "$mac" ]; then
echo "$mac"
fi
;;
esac
done
}
handle_bedtime() {
local mac_addresses="$1"
local mac
@@ -370,38 +345,61 @@ handle_internet_break() {
done
}
parse_macs() {
local maclist="$1"
local m mac
for m in $maclist; do
# trim whitespace
mac="$(echo "$m" | tr -d ' \t\r\n')"
# validate format
if echo "$mac" | grep -qE '^[0-9A-Fa-f]{2}(:[0-9A-Fa-f]{2}){5}$'; then
echo "$mac"
else
log "parse_macs(): Invalid MAC in mac list: '$mac'"
fi
done
}
handle_profile() {
local profile_section="$1"
local internet_break_enable bedtime_enable hostlist
local internet_break_enable bedtime_enable hostlist maclist
config_get hostlist "$profile_section" "host"
config_get_bool internet_break_enable "$profile_section" "internet_break_enable" 0
config_get_bool bedtime_enable "$profile_section" "bedtime_enable" 0
if [ -z "$hostlist" ]; then
if [ $internet_break_enable -eq 0 ] && [ $bedtime_enable -eq 0 ]; then
return
fi
ACCESS_RULE=""
config_get hostlist "$profile_section" "host"
config_get maclist "$profile_section" "mac"
# convert hostnames to mac addresses if needed
# and replace newlines with space because it messes up the for loops in
# handle_internet_break and handle_bedtime functions
local mac_addresses="$(parse_macs_or_hostnames "${hostlist}" | tr '\n' ' ')"
# If both lists are empty, nothing to do
if [ -z "$hostlist" ] && [ -z "$maclist" ]; then
return
fi
# default value of Hosts.AccessControl.{i}.Enable is false,
# so, if not defined in uci as 1, assume 0
config_get_bool internet_break_enable "$profile_section" "internet_break_enable" 0
if [ $internet_break_enable -gt 0 ]; then
handle_internet_break "${mac_addresses}"
# handle_internet_break may have loaded schedules uci
# so, reload parentalcontrol
config_load "parentalcontrol"
fi
ACCESS_RULE=""
config_get_bool bedtime_enable "$profile_section" "bedtime_enable" 0
if [ $bedtime_enable -gt 0 ]; then
handle_bedtime "${mac_addresses}"
fi
# both uci options contain mac addresses
# one is given directly by the user
# other is resolved by the data model from Hosts.Host object
local mac_addresses="$(parse_macs "${hostlist} ${maclist}" | awk '{ if (NF && !seen[$0]++) { print $0 } }' | tr '\n' ' ')"
# default value of Hosts.AccessControl.{i}.Enable is false,
# so, if not defined in uci as 1, assume 0
if [ $internet_break_enable -gt 0 ]; then
handle_internet_break "${mac_addresses}"
# handle_internet_break may have loaded schedules uci
# so, reload parentalcontrol
config_load "parentalcontrol"
fi
if [ $bedtime_enable -gt 0 ]; then
handle_bedtime "${mac_addresses}"
fi
}
add_internet_schedule_rules() {
@@ -438,102 +436,118 @@ add_internet_schedule_rules() {
}
add_iptables_nfqueue_rules() {
local filter_used
local queue_num="$1"
# Check if urlfilter used
if ! uci show parentalcontrol | grep -q profile_urlfilter; then
return
fi
# Check if urlfilter used
if ! uci show parentalcontrol | grep -q profile_urlfilter; then
return
fi
# IPv4 rules
iptables -w -nL FORWARD | grep -iqE "NFQUEUE"
if [ "$?" -ne 0 ]; then
# capture DNS responses (UDP/TCP sport 53) in FORWARD
iptables -w -I FORWARD 1 -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -I FORWARD 1 -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
# IPv4
# FORWARD
if ! iptables -w -nL | grep -q "URLFILTER_FORWARD"; then
iptables -w -N URLFILTER_FORWARD
iptables -w -I FORWARD 1 -j URLFILTER_FORWARD
# INPUT: DNS replies to router, skip loopback
iptables -w -I INPUT 1 -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -I INPUT 1 -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
# capture DNS responses (sport 53)
iptables -w -A URLFILTER_FORWARD -p tcp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass
iptables -w -A URLFILTER_FORWARD -p udp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass
# OUTPUT: DNS replies from router, skip loopback
iptables -w -I OUTPUT 1 -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -I OUTPUT 1 -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
# HTTP/HTTPS flows
iptables -w -A URLFILTER_FORWARD -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass
iptables -w -A URLFILTER_FORWARD -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass
fi
# HTTP/HTTPS flows for urlfilter
iptables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -I FORWARD 1 -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
# INPUT
if ! iptables -w -nL | grep -q "URLFILTER_INPUT"; then
iptables -w -N URLFILTER_INPUT
iptables -w -I INPUT 1 -j URLFILTER_INPUT
# disable acceleration for https packet so that they can be read by urlfilter
ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2> /dev/null
ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2> /dev/null
ebtables --concurrent -A FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2> /dev/null
fi
iptables -w -A URLFILTER_INPUT -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass
iptables -w -A URLFILTER_INPUT -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass
fi
# IPv6 rules
ip6tables -w -nL FORWARD | grep -iqE "NFQUEUE"
if [ "$?" -ne 0 ]; then
# capture DNS responses (UDP/TCP sport 53) in FORWARD
ip6tables -w -I FORWARD 1 -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -I FORWARD 1 -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
# OUTPUT
if ! iptables -w -nL | grep -q "URLFILTER_OUTPUT"; then
iptables -w -N URLFILTER_OUTPUT
iptables -w -I OUTPUT 1 -j URLFILTER_OUTPUT
# INPUT: DNS replies to router, skip loopback
ip6tables -w -I INPUT 1 -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -I INPUT 1 -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -A URLFILTER_OUTPUT -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass
iptables -w -A URLFILTER_OUTPUT -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass
fi
# OUTPUT: DNS replies from router, skip loopback
ip6tables -w -I OUTPUT 1 -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -I OUTPUT 1 -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
# ebtables bypass for IPv4
ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2>/dev/null
ebtables --concurrent -A FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2>/dev/null
ebtables --concurrent -A FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2>/dev/null
# HTTP/HTTPS flows for urlfilter
ip6tables -w -I FORWARD 1 -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -I FORWARD 1 -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
# IPv6
# FORWARD
if ! ip6tables -w -nL | grep -q "URLFILTER_FORWARD6"; then
ip6tables -w -N URLFILTER_FORWARD6
ip6tables -w -I FORWARD 1 -j URLFILTER_FORWARD6
# disable acceleration for https packet so that they can be read by urlfilter
ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2> /dev/null
ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2> /dev/null
ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2> /dev/null
fi
ip6tables -w -A URLFILTER_FORWARD6 -p tcp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass
ip6tables -w -A URLFILTER_FORWARD6 -p udp --sport 53 -j NFQUEUE --queue-num $queue_num --queue-bypass
ip6tables -w -A URLFILTER_FORWARD6 -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass
ip6tables -w -A URLFILTER_FORWARD6 -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num $queue_num --queue-bypass
fi
# INPUT
if ! ip6tables -w -nL | grep -q "URLFILTER_INPUT6"; then
ip6tables -w -N URLFILTER_INPUT6
ip6tables -w -I INPUT 1 -j URLFILTER_INPUT6
ip6tables -w -A URLFILTER_INPUT6 -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass
ip6tables -w -A URLFILTER_INPUT6 -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num $queue_num --queue-bypass
fi
# OUTPUT
if ! ip6tables -w -nL | grep -q "URLFILTER_OUTPUT6"; then
ip6tables -w -N URLFILTER_OUTPUT6
ip6tables -w -I OUTPUT 1 -j URLFILTER_OUTPUT6
ip6tables -w -A URLFILTER_OUTPUT6 -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass
ip6tables -w -A URLFILTER_OUTPUT6 -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num $queue_num --queue-bypass
fi
# ebtables bypass for IPv6
ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2>/dev/null
ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2>/dev/null
ebtables --concurrent -A FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2>/dev/null
}
remove_iptables_nfqueue_rules() {
iptables -w -nL FORWARD | grep -iqE "NFQUEUE"
if [ "$?" -eq 0 ]; then
# DNS response rules
iptables -w -D FORWARD -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -D FORWARD -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -D INPUT -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -D INPUT -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -D OUTPUT -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -D OUTPUT -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
# IPv4
for chain in URLFILTER_FORWARD URLFILTER_INPUT URLFILTER_OUTPUT; do
if iptables -w -nL | grep -q "$chain"; then
iptables -w -D FORWARD -j $chain 2>/dev/null
iptables -w -D INPUT -j $chain 2>/dev/null
iptables -w -D OUTPUT -j $chain 2>/dev/null
iptables -w -F $chain
iptables -w -X $chain
fi
done
# HTTP/HTTPS
iptables -w -D FORWARD -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
iptables -w -D FORWARD -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2>/dev/null
ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2>/dev/null
ebtables --concurrent -D FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2>/dev/null
ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-destination-port 443 -j SKIPLOG 2> /dev/null
ebtables --concurrent -D FORWARD -p ip --ip-protocol 6 --ip-source-port 53 -j SKIPLOG 2> /dev/null
ebtables --concurrent -D FORWARD -p ip --ip-protocol 17 --ip-source-port 53 -j SKIPLOG 2> /dev/null
fi
# IPv6
for chain in URLFILTER_FORWARD6 URLFILTER_INPUT6 URLFILTER_OUTPUT6; do
if ip6tables -w -nL | grep -q "$chain"; then
ip6tables -w -D FORWARD -j $chain 2>/dev/null
ip6tables -w -D INPUT -j $chain 2>/dev/null
ip6tables -w -D OUTPUT -j $chain 2>/dev/null
ip6tables -w -F $chain
ip6tables -w -X $chain
fi
done
ip6tables -w -nL FORWARD | grep -iqE "NFQUEUE"
if [ "$?" -eq 0 ]; then
# DNS response rules
ip6tables -w -D FORWARD -p tcp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -D FORWARD -p udp --sport 53 -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -D INPUT -p tcp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -D INPUT -p udp --sport 53 ! -i lo -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -D OUTPUT -p tcp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -D OUTPUT -p udp --sport 53 ! -o lo -j NFQUEUE --queue-num 0 --queue-bypass
# HTTP/HTTPS
ip6tables -w -D FORWARD -p tcp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
ip6tables -w -D FORWARD -p udp --match multiport --ports 80,443 -j NFQUEUE --queue-num 0 --queue-bypass
ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2> /dev/null
ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2> /dev/null
ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2> /dev/null
fi
ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-destination-port 443 -j SKIPLOG 2>/dev/null
ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 6 --ip6-source-port 53 -j SKIPLOG 2>/dev/null
ebtables --concurrent -D FORWARD -p ip6 --ip6-protocol 17 --ip6-source-port 53 -j SKIPLOG 2>/dev/null
}
remove_internet_schedule_rules() {
@@ -551,6 +565,68 @@ remove_internet_schedule_rules() {
fi
}
get_host_ip_from_mac() {
local mac="$1"
local ip=""
# Validate MAC format
if ! echo "$mac" | grep -qE '^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$'; then
log "get_host_ip_from_mac(): Invalid MAC address format '$mac'"
return 1
fi
# Try to find IP from ARP table
ip="$(cat /proc/net/arp | awk -v mac="$mac" 'tolower($4) == tolower(mac) {print $1; exit}')"
if [ -n "$ip" ]; then
URLFILTER_IPS="${URLFILTER_IPS} ${ip}"
return 0
else
log "get_host_ip_from_mac(): No IP found for MAC $mac in ARP table"
return 1
fi
}
# Global array for resolved IPs
URLFILTER_IPS=""
resolve_profile_hosts() {
local section="$1"
local hostlist maclist h m
config_get hostlist "$section" host
config_get maclist "$section" mac
for h in $hostlist; do
get_host_ip_from_mac "$h"
done
for m in $maclist; do
get_host_ip_from_mac "$m"
done
}
# Main function to collect IPs and delete conntrack entries
flush_conntrack_for_hosts() {
URLFILTER_IPS=""
local count max
config_foreach resolve_profile_hosts profile
URLFILTER_IPS="$(echo "$URLFILTER_IPS" | tr ' ' '\n' | sort -u | xargs)"
for ip in $URLFILTER_IPS; do
count=0
max=1000
while conntrack -D -s "$ip" >/dev/null 2>&1; do
count=$((count+1))
if [ $count -ge $max ]; then
log "Warning: Forced to stop conntrack delete after $max deletions for $ip (possible loop)"
break
fi
done
done
}
OVERRIDE_JSON="/etc/parentalcontrol/urlbundle_override.json"
DM_PLUGIN_PATH="/usr/share/bbfdm/micro_services/parentalcontrol/urlbundle_override.json"

View File

@@ -1,10 +1,12 @@
#!/bin/sh
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
LOCKFILE="/tmp/sync_bundles.lock"
log_level="$(uci -q get parentalcontrol.globals.loglevel)"
log_level="${log_level:-1}"
URLBUNDLE_JSON="/etc/parentalcontrol/url_bundles.json"
DEBUG=0
log_err() {
@@ -85,6 +87,7 @@ update_bundle_file_from_url() {
local success=0
while [ $attempt -le 3 ]; do
if curl -s -o "$temp_file" "$download_url"; then
log_info "Download successful for $download_url"
success=1
break
else
@@ -161,7 +164,23 @@ handle_download_url() {
# If the URL is HTTP, fetch the file size
local bundle_file_size
if echo "$sanitized_url" | grep -qE "^https?://"; then
bundle_file_size="$(curl -I "$sanitized_url" 2>&1 | grep -i 'content-length' | cut -d: -f2 | xargs)"
bundle_file_header="$(curl -Is --max-time 30 "$sanitized_url" 2>/var/log/urlfilter_curl_err.log)"
curl_rc=$?
case $curl_rc in
0)
# Success
;;
6|7|28|35|52|55|56)
log_info "handle_download_url: URL not reachable (curl rc=$curl_rc): ${sanitized_url}"
return 1
;;
*)
log_info "handle_download_url: unexpected curl rc=$curl_rc for ${sanitized_url}"
;;
esac
bundle_file_size="$(echo "$bundle_file_header" | grep -i 'content-length' | cut -d: -f2 | xargs)"
[ -z "$bundle_file_size" ] && bundle_file_size=0
else
# If it's a file:// URL, get the file size from the filesystem
@@ -202,24 +221,33 @@ cleanup_bundle_files() {
# Collect all download_url entries using config_foreach
local urls=""
get_download_url() {
local section="$1"
config_get url "$section" download_url
config_get_bool enable "$1" enable 1
local enable url
json_select "${2}"
json_get_var url url
json_get_var enable enable
enable="${enable:-1}"
if [ "${enable}" -eq 0 ]; then
# bundle is disabled
log_info "get_download_url: Skipping bundle ${name} not enabled"
json_select ..
return 0
fi
url="${url#file://}"
url="${url#https://}"
url="${url#http://}"
url="${url##*/}" # Get everything after the last '/'
urls="$urls $url"
json_select ..
}
config_load parentalcontrol
config_foreach get_download_url urlbundle
json_init
json_load_file "${URLBUNDLE_JSON}"
json_for_each_item get_download_url "urlBundles"
# Loop through all files in the directory
for file in "$dir"/*; do
@@ -278,30 +306,29 @@ handle_filter_for_bundles() {
fi
check_bundle_exists() {
local enable download_url name cfg
local enable url name
cfg="$1"
config_get name "$cfg" name
config_get_bool enable "$cfg" enable 1
config_get download_url "$cfg" download_url
json_select "${2}"
json_get_var name name
json_get_var url url
json_get_var enable enable
enable="${enable:-1}"
if [ "${enable}" -eq 0 ]; then
log_info "Skipping bundle ${name} not enabled"
log_info "check_bundle_exists: Skipping bundle ${name} not enabled"
json_select ..
return 0
fi
handle_download_url "$download_url" "$name"
local exit_status=$?
if [ "$exit_status" -eq 1 ]; then
uci -q set "parentalcontrol.${cfg}.status"="Error"
else
uci -q set "parentalcontrol.${cfg}.status"=""
fi
uci commit parentalcontrol
handle_download_url "${url}" "${name}"
json_select ..
}
config_foreach check_bundle_exists urlbundle
json_init
json_load_file "${URLBUNDLE_JSON}"
json_for_each_item check_bundle_exists "urlBundles"
}
# Open file descriptor 200 for locking

View File

@@ -1 +0,0 @@
/etc/parentalcontrol/dhcp.leases

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
@@ -40,8 +40,8 @@ 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)/etc/uci-defaults/
$(INSTALL_BIN) ./files/passwdqc.uci_default $(1)/etc/uci-defaults/99-add_passwdqc_pam
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/pwqcheck $(1)/usr/sbin/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -1,19 +0,0 @@
#!/bin/sh
CONFIG_FILE="/etc/pam.d/common-password"
# for some reason setting to 8 makes passwdqc accept minimum 12 letter password with this configuration
# if we set it to 12 then we need atleast 16 characters and so on
# passphrase = 0 means no space separated words
# rest can be figured out from passwdqc man page
MODULE_LINE="password requisite pam_passwdqc.so min=disabled,disabled,disabled,disabled,8 max=20 passphrase=0 retry=3 enforce=everyone"
# Ensure the file exists before modifying
[ -f "$CONFIG_FILE" ] || exit 0
# Check if pam_passwdqc is already in the file
if ! grep -q "pam_passwdqc.so" "$CONFIG_FILE"; then
# Insert before pam_unix.so
sed -i "/pam_unix.so/ i\\$MODULE_LINE" "$CONFIG_FILE"
fi
exit 0

View File

@@ -406,33 +406,35 @@ hw_commit_all() {
/userfs/bin/qosrule discpline Enable 0
fi
if [ -x /userfs/bin/blapi_cmd ]; then
echo 1 > /proc/ifc_send_to_ppe
for tc in $(seq 0 7); do
if [ -s "/tmp/qos/dscp_values_${tc}_4" ]; then
sort -un "/tmp/qos/dscp_values_${tc}_4" | awk 'NR==1{first=$1;last=$1;next}
$1 == last+1 {last=$1;next}
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1");first=$1;last=first}
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1")}'
fi
if [ -s "/tmp/qos/dscp_values_${tc}_6" ]; then
[ -s "/tmp/qos/dscp_values_${tc}_4" ] && sort -un "/tmp/qos/dscp_values_${tc}_6" | awk 'NR==1{first=$1;last=$1;next}
$1 == last+1 {last=$1;next}
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 0");first=$1;last=first}
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 0")}'
sort -un "/tmp/qos/dscp_values_${tc}_6" | awk 'NR==1{first=$1;last=$1;next}
$1 == last+1 {last=$1;next}
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1");first=$1;last=first}
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1")}'
fi
done
fi
if ! strings /proc/device-tree/compatible | grep -qFx econet,en7523; then
if [ -x /userfs/bin/blapi_cmd ]; then
echo 1 > /proc/ifc_send_to_ppe
for tc in $(seq 0 7); do
if [ -s "/tmp/qos/dscp_values_${tc}_4" ]; then
sort -un "/tmp/qos/dscp_values_${tc}_4" | awk 'NR==1{first=$1;last=$1;next}
$1 == last+1 {last=$1;next}
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1");first=$1;last=first}
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1")}'
fi
if [ -s "/tmp/qos/dscp_values_${tc}_6" ]; then
[ -s "/tmp/qos/dscp_values_${tc}_4" ] && sort -un "/tmp/qos/dscp_values_${tc}_6" | awk 'NR==1{first=$1;last=$1;next}
$1 == last+1 {last=$1;next}
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 0");first=$1;last=first}
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 0")}'
sort -un "/tmp/qos/dscp_values_${tc}_6" | awk 'NR==1{first=$1;last=$1;next}
$1 == last+1 {last=$1;next}
{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1");first=$1;last=first}
END{system("/userfs/bin/blapi_cmd traffic set_traffic_class DSCP " first*4 " " or(last*4, 0x3) " 1")}'
fi
done
fi
if [ -x /userfs/bin/ifc ]; then
echo 1 > /proc/ifc_send_to_ppe
for pbit in $(seq 0 7); do
/userfs/bin/ifc add vip pbit $pbit
done
if [ -x /userfs/bin/ifc ]; then
echo 1 > /proc/ifc_send_to_ppe
for pbit in $(seq 0 7); do
/userfs/bin/ifc add vip pbit $pbit
done
fi
fi
hw_nat -! > /dev/null 2>&1

View File

@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=self-diagnostics
PKG_VERSION:=1.0.16
PKG_VERSION:=1.0.17
PKG_RELEASE:=1
PKG_LICENSE:=GPL-2.0-only

View File

@@ -1,39 +0,0 @@
#!/bin/sh
BIN="/usr/sbin/self-diagnostics"
. /usr/share/libubox/jshn.sh
case "$1" in
list)
echo '{"list": {}, "generate" : {"modules":"String"}}'
;;
call)
case "$2" in
generate)
read -t 1 -r input
local out
json_load "${input}"
json_get_var modules modules
if [ -z "${modules}" ]; then
out="$(${BIN} -j)"
else
out="$(${BIN} -j -m "${modules}")"
fi
if [ -z "${out}" ]; then
echo '{}'
else
echo "${out}"
fi
;;
list)
out="$(${BIN} -j -l)"
if [ -z "${out}" ]; then
echo '{}'
else
echo "${out}"
fi
;;
esac
;;
esac

View File

@@ -1,11 +1,12 @@
#!/bin/sh
# shellcheck disable=SC1091
. /usr/share/libubox/jshn.sh
JSON_OUT=0
SPEC_DIR="/usr/share/self-diagnostics/spec"
SPEC_EXT_DIR="/etc/self-diagnostics/spec"
REPORT_PATH="/var/log/"
REPORT_PATH="/var/log"
REPORT_TEMP_DIR="$(mktemp -p ${REPORT_PATH} -d)"
REPORT_NAME="self-test-diagnostics"
VERBOSE=0
@@ -17,18 +18,19 @@ log()
{
log_file="${REPORT_TEMP_DIR}/execution.log"
if [ "$VERBOSE" -eq 1 ]; then
logger -p debug -t $0 "$*"
logger -p debug -t "$0" "$*"
fi
echo "[$(date +%Y:%m:%d-%H:%M:%S)] $*" >> ${log_file}
echo "[$(date +%Y:%m:%d-%H:%M:%S)] $*" >> "${log_file}"
}
err_log()
{
log_file="${REPORT_TEMP_DIR}/execution.log"
logger -p err -t $0 "$*"
echo "[$(date +%Y:%m:%d-%H:%M:%S) ERR] $*" >> ${log_file}
logger -p err -t "$0" "$*"
echo "[$(date +%Y:%m:%d-%H:%M:%S) ERR] $*" >> "${log_file}"
}
# shellcheck disable=SC3043
generate_report()
{
local filename
@@ -39,19 +41,19 @@ generate_report()
[ -f "${filename}.tar.gz" ] && rm "${filename}.tar.gz"
log "# Report generation completed #"
cd ${REPORT_TEMP_DIR} && {
cd "${REPORT_TEMP_DIR}" && {
filename="${filename}.tar"
tar -cf "${filename}" *
tar -cf "${filename}" ./*.log
}
if [ -n "$COMPOPTS" ]; then
gzip -${COMPOPTS} -f "${filename}"
gzip -"${COMPOPTS}" -f "${filename}"
filename="${filename}.gz"
fi
# Move logs if failed to generate tar
if [ ! -f "${filename}" ]; then
mv ${REPORT_TEMP_DIR}/*.log ${REPORT_PATH}/
mv "${REPORT_TEMP_DIR}"/*.log "${REPORT_PATH}"/
fi
if [ "${JSON_OUT}" -eq 1 ]; then
@@ -78,7 +80,7 @@ cleanup()
{
if [ -d "${REPORT_TEMP_DIR}" ]; then
generate_report
rm -rf ${REPORT_TEMP_DIR}
rm -rf "${REPORT_TEMP_DIR}"
fi
}
@@ -87,7 +89,7 @@ term_cleanup()
if [ -d "${REPORT_TEMP_DIR}" ]; then
err_log "Exiting due to TERM/INT signal"
generate_report
rm -rf ${REPORT_TEMP_DIR}
rm -rf "${REPORT_TEMP_DIR}"
fi
}
@@ -111,8 +113,8 @@ help()
# Alias ubus to have a smaller 5-second timeout on all subsequent calls
ubus()
{
if [ "${1}" == "call" ]; then
if command ubus list $2 >/dev/null 2>&1; then
if [ "${1}" = "call" ]; then
if command ubus list >/dev/null 2>&1; then
command ubus "$@";
fi
else
@@ -121,6 +123,7 @@ ubus()
}
# shellcheck disable=SC3043,SC3060,SC2034
config_load()
{
local temp
@@ -157,7 +160,7 @@ config_load()
temp="$(uci -q get self-diagnostics.globals.report_name)"
[ -n "${temp}" ] && \
REPORT_NAME="$(eval echo ${temp})"
REPORT_NAME="$(eval echo "${temp}")"
REPORT_NAME="${REPORT_NAME//[ \/]/_}"
@@ -170,9 +173,42 @@ config_load()
VERBOSE="${temp}"
}
# shellcheck disable=SC2129,SC3043
run_cmd()
{
local exec_timeout name cmd description
local export_path rc start_time end_time
exec_timeout="${1}"; shift
name="${1}"; shift
cmd="${1}"; shift
description="${*}"
start_time="$(date +%s)"
export_path="${REPORT_TEMP_DIR}/${name}.log"
log "Executing $cmd with timeout $exec_timeout"
echo "##########################################" >> "$export_path"
echo "# $description #">> "$export_path"
echo "# Exec [$cmd], timeout [$exec_timeout], start_time [$(date +%Y:%m:%d-%H:%M:%S)] #" >> "$export_path"
echo "##########################################" >> "$export_path"
eval timeout "${exec_timeout}" "$cmd" >> "$export_path" 2>&1
rc=$?
end_time="$(date +%s)"
echo "######## Execution done in [$((end_time - start_time)) ], return code $rc ######" >> "$export_path"
if [ "$rc" -eq 0 ]; then
log "Execution [$cmd] completed"
else
err_log "Execution [$cmd] Failed/Timeout with $rc exit code"
fi
echo >> "$export_path"
}
# shellcheck disable=SC2154,SC3060,SC3043
exec_spec()
{
local json_file exec_skip name timeout exec_timeout rc start_time end_time
local json_file exec_skip name timeout exec_timeout start_time end_time
start_time="$(date +%s)"
json_file="$1"
@@ -189,20 +225,18 @@ exec_spec()
return 1
}
name="$(basename ${json_file})"
export_path="${REPORT_TEMP_DIR}/${name//.json/.log}"
name="$(basename "${json_file}")"
exec_skip=0
if json_is_a dependency array; then
json_select "dependency"
json_get_keys ekeys
for key in $ekeys; do
if json_is_a $key object; then
json_select $key
if json_is_a "$key" object; then
json_select "$key"
json_get_var type type
if [ "$type" == "file" ]; then
if [ "$type" = "file" ]; then
json_get_var file file
if [ ! -e "$file" ]; then
err_log "${json_file} has unmet file dependency $file"
@@ -230,8 +264,8 @@ exec_spec()
json_get_keys keys
for key in $keys; do
if json_is_a $key object; then
json_select $key
if json_is_a "$key" object; then
json_select "${key}"
local cmd_skip file
cmd_skip=0
@@ -240,13 +274,13 @@ exec_spec()
json_select "dependency"
json_get_keys d_keys
for d_key in $d_keys; do
if json_is_a $d_key object; then
json_select $d_key
for d_key in ${d_keys}; do
if json_is_a "${d_key}" object; then
json_select "${d_key}"
json_get_var type type
if [ "$type" == "file" ]; then
if [ "$type" = "file" ]; then
json_get_var file file
if [ ! -e $file ]; then
if [ ! -e "${file}" ]; then
json_select ..
cmd_skip=1
continue
@@ -273,22 +307,7 @@ exec_spec()
else
exec_timeout=$TIMEOUT
fi
log "Executing $cmd with timeout $exec_timeout"
echo "##########################################" >> $export_path
echo "# $description #">> $export_path
echo "# Exec [$cmd], timeout [$exec_timeout] #" >> $export_path
echo "##########################################" >> $export_path
eval timeout ${exec_timeout} $cmd >> $export_path 2>&1
rc=$?
echo "######## Execution done return code $rc ######" >> $export_path
if [ "$rc" -eq 0 ]; then
log "Execution [$cmd] completed"
else
err_log "Execution [$cmd] Failed/Timeout with $rc exit code"
fi
echo >> $export_path
run_cmd "${exec_timeout}" "${name//.json/}" "${cmd}" "${description}"
json_select ..
fi
done
@@ -300,20 +319,21 @@ exec_spec()
log ""
}
# shellcheck disable=SC3043,SC3060
generate_module()
{
local modules="${@}"
local modules="${*}"
local file module
config_load
log "Modules [$@]"
log "Modules [$*]"
for module in $modules; do
module="${module/.json/}"
file="$(find $SPEC_DIR -type f -name ${module}.json)"
file="$(find "${SPEC_DIR}" -type f -name "${module}.json")"
[ -z "$file" ] && {
[ -d "${SPEC_EXT_DIR}" ] && \
file="$(find $SPEC_EXT_DIR -type f -name ${module}.json)"
file="$(find "${SPEC_EXT_DIR}" -type f -name "${module}.json")"
}
[ -f "$file" ] && \
@@ -321,15 +341,16 @@ generate_module()
done
}
# shellcheck disable=SC3043
generate_all()
{
local files
config_load
files="$(find ${SPEC_DIR} -type f -name *.json)"
files="$(find "${SPEC_DIR}" -type f -name "*.json")"
[ -d "${SPEC_EXT_DIR}" ] && \
files="${files} $(find $SPEC_EXT_DIR -type f -name *.json)"
files="${files} $(find "${SPEC_EXT_DIR}" -type f -name "*.json")"
[ -z "$files" ] && {
return 0
@@ -341,6 +362,7 @@ generate_all()
}
# shellcheck disable=SC3060,SC3043
list_modules()
{
local files
@@ -354,7 +376,7 @@ list_modules()
fi
cd ${SPEC_DIR} && {
for file in $(ls); do
for file in *.json; do
if [ "${JSON_OUT}" -eq 1 ]; then
json_add_string "" "${file/.json/}"
else
@@ -372,7 +394,7 @@ list_modules()
fi
cd ${SPEC_EXT_DIR} && {
for file in $(ls); do
for file in *.json; do
if [ "${JSON_OUT}" -eq 1 ]; then
json_add_string "" "${file/.json/}"
else
@@ -411,6 +433,10 @@ while getopts "m:hlj" opts; do
m)
modules="$modules ${OPTARG}"
;;
*)
help
exit
;;
esac
done
@@ -422,5 +448,5 @@ fi
if [ -z "${modules}" ]; then
generate_all
else
generate_module ${modules}
generate_module "${modules}"
fi

View File

@@ -54,18 +54,35 @@ int get_operate_args_SelfTest(char *refparam, struct dmctx *ctx, void *data, cha
int operate_Device_SelfTest(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
char cmd[512] = {0};
char output[512] = {0};
char buffer[512] = {0};
json_object *jobj = NULL;
const char *filename;
snprintf(cmd, sizeof(cmd), "sh %s", DIAG_BIN);
snprintf(cmd, sizeof(cmd), "sh %s -j 2>/dev/null", DIAG_BIN);
if (run_cmd(cmd, output, sizeof(output)) != 0)
if (run_cmd(cmd, buffer, sizeof(buffer)) != 0) {
BBFDM_ERR("Failed to run cmd[%s]", cmd);
goto err;
}
// truncate the new line char from end
remove_new_line(output);
if (!file_exists(output))
if (DM_STRLEN(buffer) == 0) {
BBFDM_ERR("No output from cmd[%s]", cmd);
goto err;
}
jobj = json_tokener_parse(buffer);
if (jobj == NULL) {
BBFDM_ERR("Fail to parse output[%s] in json", buffer);
goto err;
}
filename = dmjson_get_value(jobj, 1, "result");
snprintf(buffer, sizeof(buffer), "%s", filename);
json_object_put(jobj);
if (!file_exists(filename)) {
BBFDM_ERR("File [%s] does not exists or not accessible", filename);
goto err;
}
/* Add in dmmap_logmngr */
struct uci_section *s = get_origin_section_from_dmmap("dmmap_logmngr", "self_test", "self_test_log");
@@ -74,7 +91,7 @@ int operate_Device_SelfTest(char *refparam, struct dmctx *ctx, void *data, char
dmuci_rename_section_by_section(s, "self_test_log");
}
dmuci_set_value_by_section(s, "log_file", output);
dmuci_set_value_by_section(s, "log_file", filename);
dmuci_commit_package_bbfdm("dmmap_logmngr");
/* Get self test log instance */

View File

@@ -341,6 +341,30 @@ static int set_UPnPDevice_Enable(char *refparam, struct dmctx *ctx, void *data,
return 0;
}
/*#Device.UPnP.Device.UPnPIGD!UCI:upnpd/upnpd,config/igdv1*/
static int get_UPnPDevice_UPnPIGD(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = dmuci_get_option_value_fallback_def("upnpd", "config", "igdv1", "1");
return 0;
}
static int set_UPnPDevice_UPnPIGD(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
{
bool b;
switch (action) {
case VALUECHECK:
if (bbfdm_validate_boolean(ctx, value))
return FAULT_9007;
return 0;
case VALUESET:
string_to_bool(value, &b);
dmuci_set_value("upnpd", "config", "igdv1", b ? "1" : "0");
return 0;
}
return 0;
}
static int get_UPnPDeviceCapabilities_UPnPArchitecture(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
*value = "1";
@@ -809,12 +833,12 @@ DMLEAF tUPnPDeviceCapabilitiesParams[] = {
DMLEAF tUPnPDeviceParams[] = {
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
{"Enable", &DMWRITE, DMT_BOOL, get_UPnPDevice_Enable, set_UPnPDevice_Enable, BBFDM_BOTH},
{"UPnPIGD", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPIGD, set_UPnPDevice_UPnPIGD, BBFDM_BOTH},
//{"UPnPMediaServer", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPMediaServer, set_UPnPDevice_UPnPMediaServer, BBFDM_BOTH},
//{"UPnPMediaRenderer", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPMediaRenderer, set_UPnPDevice_UPnPMediaRenderer, BBFDM_BOTH},
//{"UPnPWLANAccessPoint", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPWLANAccessPoint, set_UPnPDevice_UPnPWLANAccessPoint, BBFDM_BOTH},
//{"UPnPQoSDevice ", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPQoSDevice , set_UPnPDevice_UPnPQoSDevice , BBFDM_BOTH},
//{"UPnPQoSPolicyHolder", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPQoSPolicyHolder, set_UPnPDevice_UPnPQoSPolicyHolder, BBFDM_BOTH},
//{"UPnPIGD", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPIGD, set_UPnPDevice_UPnPIGD, BBFDM_BOTH},
//{"UPnPDMBasicMgmt", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPDMBasicMgmt, set_UPnPDevice_UPnPDMBasicMgmt, BBFDM_BOTH},
//{"UPnPDMConfigurationMgmt", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPDMConfigurationMgmt, set_UPnPDevice_UPnPDMConfigurationMgmt, BBFDM_BOTH},
//{"UPnPDMSoftwareMgmt", &DMWRITE, DMT_BOOL, get_UPnPDevice_UPnPDMSoftwareMgmt, set_UPnPDevice_UPnPDMSoftwareMgmt, BBFDM_BOTH},

View File

@@ -1,7 +1,7 @@
if PACKAGE_sshmngr
choice
prompt "Select backend for SSH management"
default SSHMNGR_BACKEND_OPENSSH
default SSHMNGR_BACKEND_OPENSSH_PAM
depends on PACKAGE_sshmngr
help
Select which backend daemon to use for SSH

View File

@@ -5,11 +5,11 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sulu-base
PKG_VERSION:=5.1.2
PKG_VERSION:=5.3.10
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/websdk/sulu.git
PKG_SOURCE_VERSION:=6ee43863415b54c312a56e113a7a91d5ae25df28
PKG_SOURCE_VERSION:=15f36f48dee8a675d7829181bf508a75c0a66a8a
PKG_MIRROR_HASH:=skip
SULU_MOD:=core

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sulu-builder
PKG_VERSION:=5.1.2
PKG_VERSION:=5.3.10
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/websdk/sulu-builder.git
PKG_SOURCE_VERSION:=cca6a777e46584c888a1a06fafa75f7a063b803d
PKG_SOURCE_VERSION:=6a82c845c5203a7e33737d668659e60203f9f68f
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-shadow +usermngr +userinterface +obuspa +sulu-vendorext
DEPENDS:=+mosquitto-auth-plugin +usermngr +userinterface +obuspa
DEPENDS+=+@OBUSPA_LOCAL_MQTT_LISTENER
EXTRA_DEPENDS:=nginx
endef

View File

@@ -20,7 +20,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 $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Port $server_port;

View File

@@ -4,10 +4,10 @@
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
#. /lib/functions/iopsys-environment.sh
RESTART_REQ=0
_RESTART_SERVICES="0"
SULU_CON_CONFIG="/sulu/presets/connection-config.json"
SULU_ACL_FILE=""
SULU_CON_ROLES=""
slog() {
echo "$*" | logger -t sulu.sh -p debug
@@ -28,49 +28,21 @@ _get_agent_id() {
fi
}
_get_sulu_user_roles() {
roles=$(uci -q get userinterface._sulu_s.role)
for role in ${roles}; do
sulu_user_roles="${sulu_user_roles} ${role}"
done
if [ -n "${sulu_user_roles}" ]; then
sulu_user_roles=$(echo -e "${sulu_user_roles// /\\n}" | sort | uniq)
fi
echo "${sulu_user_roles}"
}
_get_sulu_root() {
local root
root="$(uci -q get nginx._sulu_s.root)"
echo "${root:-/sulu}"
}
_get_sulu_connection_config() {
local config
config="$(_get_sulu_root)/presets/connection-config.json"
echo "${config}"
}
_get_sulu_session_mode() {
uci -q get sulu.global.SessionMode
}
_get_sulu_acl_file() {
uci -q get mosquitto.sulu.acl_file
}
_sulu_conn_config_users() {
for user in ${SULU_CON_ROLES}; do
json_add_object "${user}"
json_add_string 'fromId' "self::sulu-${user}"
json_add_string 'publishEndpoint' "/usp/$(_get_agent_id)/${user}/endpoint"
json_add_string 'subscribeEndpoint' "/usp/$(_get_agent_id)/${user}/controller"
json_close_object
done
}
generate_sulu_conn_config() {
local users SCONFIG session
users="$(_get_sulu_user_roles)"
session="$(_get_sulu_session_mode)"
SCONFIG="$(_get_sulu_connection_config)"
json_init
json_add_string 'Current-connection' 'main'
json_add_object 'Connections'
@@ -80,41 +52,25 @@ generate_sulu_conn_config() {
json_add_string 'toId' "os::$(_get_agent_id)"
json_add_string 'port' "auto"
json_add_string 'path' "/wss"
if [ "${session}" = "Require" ]; then
json_add_boolean 'useSession' 1
fi
json_add_string 'protocol' 'autoWs'
json_add_object 'overrides'
{
for user in ${users}; do
json_add_object "${user}"
{
json_add_string 'fromId' "self::sulu-${user}"
json_add_string 'publishEndpoint' "/usp/$(_get_agent_id)/${user}/endpoint"
json_add_string 'subscribeEndpoint' "/usp/$(_get_agent_id)/${user}/controller"
json_close_object
}
done
_sulu_conn_config_users
json_close_object
}
json_close_object
}
json_close_object
}
json_dump >"${SCONFIG}"
json_dump >"${SULU_CON_CONFIG}"
}
_update_obuspa_config_rbac() {
local agent users session
update_obuspa_config() {
local agent
agent="$(_get_agent_id)"
users="$(_get_sulu_user_roles)"
session="$(_get_sulu_session_mode)"
for user in ${users}; do
for user in ${SULU_CON_ROLES}; do
local section
# Add mqtt
@@ -124,7 +80,6 @@ _update_obuspa_config_rbac() {
uci_set obuspa "${section}" BrokerAddress "127.0.0.1"
uci_set obuspa "${section}" BrokerPort "1883"
uci_set obuspa "${section}" TransportProtocol "TCP/IP"
RESTART_REQ=1
fi
# Add mtp
@@ -134,7 +89,6 @@ _update_obuspa_config_rbac() {
uci_set obuspa "${section}" Protocol "MQTT"
uci_set obuspa "${section}" ResponseTopicConfigured "/usp/${agent}/${user}/endpoint"
uci_set obuspa "${section}" mqtt "mqtt_sulu_$user"
RESTART_REQ=1
fi
# Add controller
@@ -146,88 +100,61 @@ _update_obuspa_config_rbac() {
uci_set obuspa "${section}" Topic "/usp/${agent}/${user}/controller"
uci_set obuspa "${section}" mqtt "mqtt_sulu_$user"
uci_set obuspa "${section}" assigned_role_name "$user"
RESTART_REQ=1
fi
obMode="$(uci_get obuspa "${section}" SessionMode)"
if [ "${session}" != "${obMode}" ]; then
uci_set obuspa "${section}" SessionMode "${session}"
RESTART_REQ=1
fi
done
}
_create_mosquitto_acl() {
local agentid users
local ACL_FILE acl_users
create_mosquitto_acl() {
local agentid
local acl_users
RESTART_REQ="0"
ACL_FILE="$(_get_sulu_acl_file)"
if [ -z "${ACL_FILE}" ]; then
SULU_ACL_FILE="$(_get_sulu_acl_file)"
if [ -z "${SULU_ACL_FILE}" ]; then
return 0
fi
users="$(_get_sulu_user_roles)"
if [ -f "${ACL_FILE}" ]; then
acl_users="$(awk '/^user/ {print $2}' "${ACL_FILE}")"
for user in ${users}; do
if ! grep -q "$user" "${acl_users}"; then
rm -f "${ACL_FILE}"
fi
done
fi
touch "${ACL_FILE}"
echo > "${SULU_ACL_FILE}"
agentid="$(_get_agent_id)"
for user in ${users}; do
if ! grep -q "user $user" "${ACL_FILE}"; then
for user in ${SULU_CON_ROLES}; do
if ! grep -qxF "user $user" "${SULU_ACL_FILE}"; then
{
echo "user ${user}"
echo "topic read /usp/${agentid}/${user}/controller/reply-to"
echo "topic write /usp/${agentid}/${user}/endpoint"
echo "topic read /usp/${agentid}/${user}/controller"
echo ""
} >> "${ACL_FILE}"
RESTART_REQ="1"
} >> "${SULU_ACL_FILE}"
fi
done
chown mosquitto:mosquitto "${SULU_ACL_FILE}"
chmod 640 "${SULU_ACL_FILE}"
}
if [ "${_RESTART_SERVICES}" -eq "1" ] && [ "${RESTART_REQ}" -gt "0" ]; then
slog "Restarting mosquitto..."
ubus call uci commit '{"config":"mosquitto"}'
get_sulu_roles() {
local sec path_prefix redirect role
sec="${1}"
config_get path_prefix "${sec}" path_prefix ""
config_get redirect "${sec}" redirect ""
config_get role "${sec}" role ""
if [ -n "${redirect}" ]; then
return 0
fi
if [ "${path_prefix}" != "/sulu" ]; then
return 0
fi
if [ -n "${role}" ]; then
SULU_CON_ROLES="${SULU_CON_ROLES} ${role}"
fi
}
update_obuspa_config() {
config_load userinterface
config_foreach get_sulu_roles http_access
RESTART_REQ=0
uci_load obuspa
_update_obuspa_config_rbac
uci_commit obuspa
if [ "${_RESTART_SERVICES}" -eq "1" ] && [ "${RESTART_REQ}" -gt "0" ]; then
slog "Restarting obuspa..."
ubus call uci commit '{"config":"obuspa"}'
fi
}
configure_sulu() {
_create_mosquitto_acl
update_obuspa_config
generate_sulu_conn_config
}
while getopts ":rq" opt; do
case ${opt} in
r)
_RESTART_SERVICES="1"
;;
*)
slog "Invalid option: ${OPTARG}"
exit 1
;;
esac
done
configure_sulu
generate_sulu_conn_config
create_mosquitto_acl
update_obuspa_config

Some files were not shown because too many files have changed in this diff Show More