From 23fcf6d6bb0a8e166618a28ce9c9bdbb9a7ab42b Mon Sep 17 00:00:00 2001 From: Pavan Kumar Reddy B Date: Fri, 21 Aug 2026 13:34:34 +0530 Subject: [PATCH 1/9] Guardian --- .../actionHandler/ajaxSet_guardian_config.jst | 47 + source/Styles/xb3/jst/guardian.jst | 1331 +++++++++++++++++ 2 files changed, 1378 insertions(+) create mode 100644 source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst create mode 100644 source/Styles/xb3/jst/guardian.jst diff --git a/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst b/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst new file mode 100644 index 0000000..820e39e --- /dev/null +++ b/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst @@ -0,0 +1,47 @@ + + + +alert("Please Login First!"); location.href="../index.jst";'); + exit(0); +} + +$guardianConfigPath = "/var/tmp/upd_guardian.cfg"; +$configInfo = $_POST['configInfo']; +$configInfo = str_replace("\r\n", "\n", $configInfo); +$configInfo = str_replace("\r", "\n", $configInfo); +$configInfo = str_replace("\0", "", $configInfo); + +$response = {"status": "failure"}; +if (!file_exists($guardianConfigPath)) { + $guardianBootstrapFile = fopen($guardianConfigPath, "w"); + if ($guardianBootstrapFile != false) { + fclose($guardianBootstrapFile); + } +} +$guardianFile = fopen($guardianConfigPath, "w"); +if ($guardianFile != false) { + fwrite($guardianFile, $configInfo); + fclose($guardianFile); + $response['status'] = "success"; +} + +echo( htmlspecialchars(json_encode($response), ENT_NOQUOTES, 'UTF-8')); +?> diff --git a/source/Styles/xb3/jst/guardian.jst b/source/Styles/xb3/jst/guardian.jst new file mode 100644 index 0000000..17912a2 --- /dev/null +++ b/source/Styles/xb3/jst/guardian.jst @@ -0,0 +1,1331 @@ + +/dev/null", $guardianConfigLines, $guardianReadStatus); + exec("cat "+$guardianLogPath+" 2>/dev/null", $guardianFlowPreviewLines, $guardianFlowReadStatus); + $guardianFlowPreview = (0 == $guardianFlowReadStatus && !empty($guardianFlowPreviewLines)) ? implode("\n", $guardianFlowPreviewLines) : ""; + if (0 == $guardianReadStatus && !empty($guardianConfigLines)) { + $guardianCurrentSection = ""; + for ($cfgIdx = 0; $cfgIdx < count($guardianConfigLines); $cfgIdx++) { + $guardianLine = trim($guardianConfigLines[$cfgIdx]); + if ("" == $guardianLine || "#" == substr($guardianLine, 0, 1)) { + continue; + } + $guardianSavedState['hasConfig'] = true; + $guardianSectionMatch = []/*p2j-array*/; + if (preg_match('/^\[(.+)\]$/', $guardianLine, $guardianSectionMatch)) { + $guardianCurrentSection = strtolower($guardianSectionMatch[1]); + continue; + } + + if ("gateway" == $guardianCurrentSection) { + $gatewayParts = preg_split('/\s+/', $guardianLine); + if (count($gatewayParts) >= 2) { + $guardianSavedState['gatewayIp'] = $gatewayParts[1]; + } + } + else if ("groups" == $guardianCurrentSection) { + $groupParts = preg_split('/\s+/', $guardianLine); + if (count($groupParts) >= 2) { + $guardianSavedState['groupIds'][strtoupper($groupParts[0])] = intval($groupParts[1]); + } + } + else if ("devices" == $guardianCurrentSection) { + $deviceParts = preg_split('/\s+/', $guardianLine); + if (count($deviceParts) >= 2) { + $guardianSavedState['deviceGroups'][strtolower($deviceParts[0])] = strtoupper($deviceParts[1]); + } + } + else if ("policy" == $guardianCurrentSection) { + $policyParts = preg_split('/\s+/', $guardianLine); + if (count($policyParts) >= 3) { + $policySrc = strtoupper($policyParts[0]); + $policyDst = strtoupper($policyParts[1]); + if (!isset($guardianSavedState['policy'][$policySrc])) { + $guardianSavedState['policy'][$policySrc] = {}; + } + $guardianSavedState['policy'][$policySrc][$policyDst] = strtolower($policyParts[2]); + array_push($guardianSavedState['groupPolicyRules'], { + 'src': $policySrc, + 'dst': $policyDst, + 'service': 'ANY', + 'action': strtolower($policyParts[2]) + }); + } + } + else if ("group_policy" == $guardianCurrentSection) { + $policyParts = preg_split('/\s+/', $guardianLine); + if (count($policyParts) >= 4) { + array_push($guardianSavedState['groupPolicyRules'], { + 'src': strtoupper($policyParts[0]), + 'dst': strtoupper($policyParts[1]), + 'service': strtoupper($policyParts[2]), + 'action': strtolower($policyParts[3]) + }); + } + } + else if ("intra_group_policy" == $guardianCurrentSection) { + $intraParts = preg_split('/\s+/', $guardianLine); + if (count($intraParts) >= 3) { + array_push($guardianSavedState['intraGroupPolicyRules'], { + 'group': strtoupper($intraParts[0]), + 'service': strtoupper($intraParts[1]), + 'action': strtolower($intraParts[2]) + }); + } + } + else if ("quarantine" == $guardianCurrentSection) { + array_push($guardianSavedState['quarantine'], strtolower($guardianLine)); + } + else if ("exceptions" == $guardianCurrentSection) { + $exceptionParts = preg_split('/\s+/', $guardianLine); + if (count($exceptionParts) >= 3) { + array_push($guardianSavedState['exceptions'], { + 'src': strtolower($exceptionParts[0]), + 'dst': strtolower($exceptionParts[1]), + 'action': strtolower($exceptionParts[2]) + }); + } + } + else if ("services" == $guardianCurrentSection) { + $serviceLine = $guardianLine; + $serviceDesc = ""; + if (false !== strpos($guardianLine, "#")) { + $serviceDescParts = explode("#", $guardianLine, 2); + $serviceLine = trim($serviceDescParts[0]); + $serviceDesc = trim($serviceDescParts[1]); + } + $serviceParts = preg_split('/\s+/', $serviceLine); + if (count($serviceParts) >= 4 && preg_match('/^(tcp|udp|sctp)$/i', $serviceParts[1])) { + array_push($guardianSavedState['services'], { + 'target': strtolower($serviceParts[0]), + 'proto': strtolower($serviceParts[1]), + 'port': intval($serviceParts[2]), + 'group': strtoupper($serviceParts[3]), + 'desc': $serviceDesc, + 'action': 'allow', + 'serviceName': '' + }); + } + else if (count($serviceParts) >= 3 && preg_match('/^(tcp|udp|sctp)$/i', $serviceParts[1])) { + $serviceName = strtoupper($serviceParts[0]); + $guardianSavedState['serviceDefinitions'][$serviceName] = { + 'name': $serviceName, + 'proto': strtolower($serviceParts[1]), + 'port': $serviceParts[2], + 'desc': $serviceDesc + }; + } + } + else if ("service_macros" == $guardianCurrentSection) { + $macroParts = preg_split('/\s+/', $guardianLine, 2); + if (count($macroParts) >= 2) { + $guardianSavedState['serviceMacros'][strtoupper($macroParts[0])] = trim($macroParts[1]); + } + } + else if ("defaults" == $guardianCurrentSection) { + $defaultParts = preg_split('/\s+/', $guardianLine, 2); + if (count($defaultParts) >= 2) { + $guardianSavedState['defaults'][strtolower($defaultParts[0])] = strtolower(trim($defaultParts[1])); + } + } + else if ("device_policy" == $guardianCurrentSection) { + $devicePolicyParts = preg_split('/\s+/', $guardianLine); + if (count($devicePolicyParts) >= 4) { + array_push($guardianSavedState['devicePolicyRules'], { + 'src': strtoupper($devicePolicyParts[0]), + 'dst': strtolower($devicePolicyParts[1]), + 'service': strtoupper($devicePolicyParts[2]), + 'action': strtolower($devicePolicyParts[3]) + }); + } + } + } + } + function guardianDeviceGroup($hostName, $deviceType) { + if (stristr($deviceType, "printer") || stristr($hostName, "printer")) { + return "PRINTER"; + } + if (stristr($deviceType, "camera") || stristr($hostName, "camera")) { + return "CAMERA"; + } + if ( + stristr($deviceType, "iot") || stristr($deviceType, "speaker") || stristr($deviceType, "tv") || + stristr($deviceType, "thermostat") || stristr($deviceType, "sensor") || stristr($deviceType, "appliance") || + stristr($hostName, "plug") || stristr($hostName, "iot") || stristr($hostName, "thermostat") + ) { + return "IOT"; + } + if (stristr($hostName, "work") || stristr($deviceType, "laptop") || stristr($deviceType, "pc")) { + return "WORK"; + } + return "PERSONAL"; + } + + $guardianDevices = []/*p2j-array*/; + $rootObjName = "Device.Hosts.Host."; + $paramNameArray = [$rootObjName]/*p2j-array*/; + $mapping_array = ["PhysAddress", "HostName", "Active", "IPv4Address.1.IPAddress", "IPv6Address.1.IPAddress", "IPv6Address.2.IPAddress", "IPv6Address.3.IPAddress", "X_RDKCENTRAL-COM_DeviceType"]/*p2j-array*/; + $HostIndexArr = DmExtGetInstanceIds($rootObjName); + $HostNum = 0; + if (0 == $HostIndexArr[0]) { + $HostNum = count($HostIndexArr) - 1; + } + if (!empty($HostNum)) { + $Host = getParaValues($rootObjName, $paramNameArray, $mapping_array, true); + if (!empty($Host)) { + for ($i = 0; $i < $HostNum; $i++) { + $hostEntry = $Host[$i.toString()]; + $macAddress = strtolower($hostEntry['PhysAddress']); + if ("" == $macAddress) { + continue; + } + $hostName = $hostEntry['HostName']; + if ((strlen($hostName) == 0) || !isValidHostname($hostName)) { + $hostName = strtoupper($macAddress); + } + $deviceInfo = {}; + $deviceInfo['mac'] = $macAddress; + $deviceInfo['name'] = $hostName; + $deviceInfo['ip'] = ("" != $hostEntry['IPv4Address.1.IPAddress']) ? $hostEntry['IPv4Address.1.IPAddress'] : "--"; + $deviceInfo['online'] = !strcasecmp("true", $hostEntry['Active']); + $deviceInfo['isConfigured'] = ($guardianSavedState['hasConfig'] && isset($guardianSavedState['deviceGroups'][$macAddress])); + $deviceInfo['group'] = $deviceInfo['isConfigured'] ? $guardianSavedState['deviceGroups'][$macAddress] : "PERSONAL"; + $deviceInfo['ipv6'] = resolve_IPV6_global_address($hostEntry['IPv6Address.1.IPAddress'], $hostEntry['IPv6Address.3.IPAddress']); + $deviceInfo['ipv6Local'] = $hostEntry['IPv6Address.2.IPAddress']; + $deviceInfo['deviceType'] = $hostEntry['X_RDKCENTRAL-COM_DeviceType']; + array_push($guardianDevices, $deviceInfo); + } + } + } +?> + + + + + +Shield Home Guardian + + + + +
+
πŸ›‘
+

Shield Home Guardian

+
+ + Policy Active + Gateway: +
+
+ +
+
Devices
+
Group Policy
+
Service Rules
+
Quarantine
+
Exceptions
+
Config Output
+
+ +
+ + +
+
0
Connected Devices
+
0
Active Groups
+
0
Service Rules
+
0
Quarantined
+
0
OVS Flows
+
+ + +
+
+
+

Connected Devices

+
+ + +
+
+
+ + + +
StatusHostnameMAC AddressIP AddressGroupActions
+
+
+
+ + +
+
+
+

Group-to-Group Policy Matrix

+
+ Click a cell to toggle ALLOW / DROP + +
+
+
+
+
+
+
+ + +
+
+
+

Service Rules (Port/Protocol)

+
+ + +
+
+
+ + + +
TargetProtocolPortAllowed GroupDescriptionActions
+ +
+
+
+ + +
+
+
+

Quarantined Devices

+
+ Quarantined devices are fully isolated β€” no traffic in or out + +
+
+
+ + + +
MAC AddressHostnameReasonActions
+
No quarantined devices
+
+
+
+ + +
+
+
+

Device Exceptions (MAC-pair overrides)

+
+ + +
+
+
+ + + +
Source DeviceDestination DeviceActionRemove
+
No exceptions configured
+
+
+
+ + +
+
+
+

Generated Configuration

+
+ + +
+
+
+
+
+
+
+

Dry-Run Flow Preview

+
+
+
+
+
+ +
+ + + + + + + + +
+ + + + From fe967d16a9a148fc2132096b965eb87524c0d21d Mon Sep 17 00:00:00 2001 From: Pavan Kumar Reddy B Date: Fri, 21 Aug 2026 22:03:18 +0530 Subject: [PATCH 2/9] guardian update 1 --- .../actionHandler/ajaxSet_guardian_config.jst | 64 ++++++++----------- source/Styles/xb3/jst/guardian.jst | 31 ++++++++- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst b/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst index 820e39e..143a9fd 100644 --- a/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst +++ b/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst @@ -1,46 +1,36 @@ - - alert("Please Login First!"); location.href="../index.jst";'); - exit(0); -} - -$guardianConfigPath = "/var/tmp/upd_guardian.cfg"; -$configInfo = $_POST['configInfo']; -$configInfo = str_replace("\r\n", "\n", $configInfo); -$configInfo = str_replace("\r", "\n", $configInfo); -$configInfo = str_replace("\0", "", $configInfo); +$guardianConfigPath = "/var/tmp/guardian.cfg"; +$action = isset($_POST['action']) ? strtolower(trim($_POST['action'])) : ""; $response = {"status": "failure"}; -if (!file_exists($guardianConfigPath)) { - $guardianBootstrapFile = fopen($guardianConfigPath, "w"); - if ($guardianBootstrapFile != false) { - fclose($guardianBootstrapFile); + +if ("apply" == $action) { + $guardianApplyOutput = []/*p2j-array*/; + $guardianApplyStatus = 1; + exec("bash /var/tmp/guardian.sh /var/tmp/guardian.cfg apply 2>&1", $guardianApplyOutput, $guardianApplyStatus); + if (0 == $guardianApplyStatus) { + $response['status'] = "success"; } } -$guardianFile = fopen($guardianConfigPath, "w"); -if ($guardianFile != false) { - fwrite($guardianFile, $configInfo); - fclose($guardianFile); - $response['status'] = "success"; +else { + $configInfo = isset($_POST['configInfo']) ? $_POST['configInfo'] : ""; + $configInfo = str_replace("\r\n", "\n", $configInfo); + $configInfo = str_replace("\r", "\n", $configInfo); + $configInfo = str_replace("\0", "", $configInfo); + + if (!file_exists($guardianConfigPath)) { + $guardianBootstrapFile = fopen($guardianConfigPath, "w"); + if ($guardianBootstrapFile != false) { + fclose($guardianBootstrapFile); + } + } + $guardianFile = fopen($guardianConfigPath, "w"); + if ($guardianFile != false) { + fwrite($guardianFile, $configInfo); + fclose($guardianFile); + $response['status'] = "success"; + } } echo( htmlspecialchars(json_encode($response), ENT_NOQUOTES, 'UTF-8')); diff --git a/source/Styles/xb3/jst/guardian.jst b/source/Styles/xb3/jst/guardian.jst index 17912a2..9695d15 100644 --- a/source/Styles/xb3/jst/guardian.jst +++ b/source/Styles/xb3/jst/guardian.jst @@ -364,7 +364,7 @@ select:focus, input:focus { outline: none; border-color: var(--accent); }
-
πŸ›‘
+
🛡

Shield Home Guardian

@@ -380,6 +380,7 @@ select:focus, input:focus { outline: none; border-color: var(--accent); }
Quarantine
Exceptions
Config Output
+
@@ -579,7 +580,6 @@ const GUARDIAN_DEFAULTS = Object.assign({ stateful: 'true', policy_precedence: 'specific-first' }, INITIAL_GUARDIAN_STATE.defaults || {}); -const token = ; let gateway = {mac: , ip: INITIAL_GUARDIAN_STATE.gatewayIp || }; let devices = ; @@ -1019,7 +1019,7 @@ function uploadGuardianConfig(successMessage) { toast('Unable to save Guardian configuration', 'danger'); } }; - xhr.send(`configInfo=${encodeURIComponent(generateConfig())}&csrfp_token=${encodeURIComponent(token)}`); + xhr.send(`configInfo=${encodeURIComponent(generateConfig())}`); } function savePolicy() { @@ -1042,6 +1042,31 @@ function saveExceptions() { uploadGuardianConfig('Exceptions saved'); } +function applySettings() { + const xhr = new XMLHttpRequest(); + xhr.open('POST', 'actionHandler/ajaxSet_guardian_config.jst', true); + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); + xhr.onreadystatechange = function() { + if (xhr.readyState !== 4) return; + if (xhr.status >= 200 && xhr.status < 300) { + let response = null; + try { + response = JSON.parse(xhr.responseText); + } catch (err) { + console.warn('Unable to parse Guardian apply response', err); + } + if (response && response.status === 'success') { + toast('Guardian settings applied'); + } else { + toast('Unable to apply Guardian settings', 'danger'); + } + } else { + toast('Unable to apply Guardian settings', 'danger'); + } + }; + xhr.send('action=apply'); +} + function renderServices() { const tb = document.getElementById('service-table'); const ns = document.getElementById('no-services'); From 740d33275ef9f6e2068e53b8b831be91e22f0050 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Reddy B Date: Mon, 24 Aug 2026 13:06:03 +0530 Subject: [PATCH 3/9] guardian update 2 --- .../actionHandler/ajaxSet_guardian_config.jst | 7 ++- source/Styles/xb3/jst/guardian.jst | 43 ++++++++++++++----- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst b/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst index 143a9fd..c580ac7 100644 --- a/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst +++ b/source/Styles/xb3/jst/actionHandler/ajaxSet_guardian_config.jst @@ -6,11 +6,14 @@ $action = isset($_POST['action']) ? strtolower(trim($_POST['action'])) : ""; $response = {"status": "failure"}; if ("apply" == $action) { - $guardianApplyOutput = []/*p2j-array*/; + $guardianApplyOutput = []; $guardianApplyStatus = 1; - exec("bash /var/tmp/guardian.sh /var/tmp/guardian.cfg apply 2>&1", $guardianApplyOutput, $guardianApplyStatus); + exec("/bin/bash /var/tmp/guardian.sh /var/tmp/guardian.cfg apply", $guardianApplyOutput, $guardianApplyStatus); if (0 == $guardianApplyStatus) { $response['status'] = "success"; + $response['message'] = implode("\n", $guardianApplyOutput); + } else { + $response['message'] = implode("\n", $guardianApplyOutput); } } else { diff --git a/source/Styles/xb3/jst/guardian.jst b/source/Styles/xb3/jst/guardian.jst index 9695d15..daa22c8 100644 --- a/source/Styles/xb3/jst/guardian.jst +++ b/source/Styles/xb3/jst/guardian.jst @@ -2,7 +2,7 @@ /dev/null", $guardianConfigLines, $guardianReadStatus); - exec("cat "+$guardianLogPath+" 2>/dev/null", $guardianFlowPreviewLines, $guardianFlowReadStatus); + $guardianConfigFp = fopen($guardianConfigPath, "r"); + if ($guardianConfigFp != false) { + $guardianConfigSize = filesize($guardianConfigPath); + if ($guardianConfigSize > 0) { + $guardianConfigContent = fread($guardianConfigFp, $guardianConfigSize); + $guardianConfigLines = explode("\n", $guardianConfigContent); + $guardianReadStatus = 0; + } + fclose($guardianConfigFp); + } + $guardianLogFp = fopen($guardianLogPath, "r"); + if ($guardianLogFp != false) { + $guardianLogSize = filesize($guardianLogPath); + if ($guardianLogSize > 0) { + $guardianLogContent = fread($guardianLogFp, $guardianLogSize); + $guardianFlowPreviewLines = explode("\n", $guardianLogContent); + $guardianFlowReadStatus = 0; + } + fclose($guardianLogFp); + } $guardianFlowPreview = (0 == $guardianFlowReadStatus && !empty($guardianFlowPreviewLines)) ? implode("\n", $guardianFlowPreviewLines) : ""; if (0 == $guardianReadStatus && !empty($guardianConfigLines)) { $guardianCurrentSection = ""; @@ -45,9 +63,8 @@ continue; } $guardianSavedState['hasConfig'] = true; - $guardianSectionMatch = []/*p2j-array*/; - if (preg_match('/^\[(.+)\]$/', $guardianLine, $guardianSectionMatch)) { - $guardianCurrentSection = strtolower($guardianSectionMatch[1]); + if ("[" == substr($guardianLine, 0, 1) && "]" == substr($guardianLine, strlen($guardianLine) - 1)) { + $guardianCurrentSection = strtolower(substr($guardianLine, 1, strlen($guardianLine) - 2)); continue; } @@ -571,6 +588,12 @@ select:focus, input:focus { outline: none; border-color: var(--accent); }