Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source/firewall/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if ONESTACK_PRODUCT_REQ
AM_LDFLAGS += -lrdkb_feature_mode_gate
endif

firewall_SOURCES = firewall_ipv6.c firewall.c firewall_priv.c firewall_interface.c firewall_ext.c
firewall_SOURCES = firewall_ipv6.c firewall.c firewall_priv.c firewall_interface.c firewall_ext.c firewall_utils.c
if CPC_FIREWALL_ENABLE
firewall_SOURCES += firewall_lib.c firewall_dsl.c rabid.c
AM_LDFLAGS += -lrdkconfig
Expand Down
28 changes: 3 additions & 25 deletions source/firewall/firewall.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,8 +740,6 @@ int rfstatus;
* For simplicity purposes we cap the number of syscfg entries within a
* specific namespace. This cap is controlled by MAX_SYSCFG_ENTRIES
*/
#define MAX_PORT 65535

#define MAX_NAMESPACE 64

#define MAX_SRC_IP_TABLE_ROW 10 /*RDKB-7145, CID-33123, defining max size for src_ip[MAX_SRC_IP_TABLE_ENTRY][]*/
Expand Down Expand Up @@ -9129,14 +9127,6 @@ static int do_parcon_device_cloud_mgmt(FILE *fp, int iptype, FILE *cron_fp)
return(0);
}

static int validate_port(char* port_num)
{
int port = atoi(port_num);
if ( port <= 0 || port > MAX_PORT )
return -1;

return 0;
}
/*
* add parental control managed service(ports) rules
*/
Expand Down Expand Up @@ -10123,21 +10113,9 @@ static int do_lan2wan_misc(FILE *filter_fp)
else if (strcmp(query,"ACCEPT") == 0) {
fprintf(filter_fp, "-A lan2wan_misc -p tcp --dport 1723 -j ACCEPT\n");
}
char sites_enabled[MAX_QUERY];
sites_enabled[0] = '\0';
syscfg_get(NULL, "managedsites_enabled", sites_enabled, sizeof(sites_enabled));
if (sites_enabled[0] != '\0' && sites_enabled[0] == '0') // managed site list enabled
{
syscfg_get("blockssl", "result", query, sizeof(query));
if (strcmp(query,"DROP") == 0) {
fprintf(filter_fp, "-A lan2wan_misc -p udp --dport 443 -j DROP\n");
fprintf(filter_fp, "-A lan2wan_misc -p tcp --dport 443 -j DROP\n");
}
else if(strcmp(query,"ACCEPT") == 0) {
fprintf(filter_fp, "-A lan2wan_misc -p udp --dport 443 -j ACCEPT\n");
fprintf(filter_fp, "-A lan2wan_misc -p tcp --dport 443 -j ACCEPT\n");
}
}

// Apply SSL blocking rule
do_ssl_blocking_rules(filter_fp, "lan2wan_misc");
}
#endif

Expand Down
29 changes: 29 additions & 0 deletions source/firewall/firewall.h
Original file line number Diff line number Diff line change
Expand Up @@ -1246,3 +1246,32 @@ void proxy_dns(FILE *nat_fp,int family);
*/
void get_iface_ipaddr_ula(const char* ifname,char* ipaddr, int max_ip_size);
#endif

#define MAX_PORT 65535

/**
* @brief Validate if a port number string is valid.
*
* @param[in] port_num - Pointer to the port number string.
*
* @return The status of the operation.
* @retval 0 if port is valid (1-65535).
* @retval -1 if port is invalid.
*
*/
int validate_port(const char* port_num);

/**
* @brief Apply SSL blocking rules based on managed sites/services configuration.
*
* Checks if managed sites or managed services (with port 443) are enabled,
* and emits appropriate SSL blocking (DROP/ACCEPT) rules for port 443.
* Rules are skipped per protocol if managed services covers that protocol on port 443.
*
* @param[in] fp - Pointer to the FILE stream for writing firewall rules.
* @param[in] chain_name - The iptables chain name (e.g., "lan2wan_misc" or "lan2wan_misc_ipv6").
*
* @return None.
*
*/
void do_ssl_blocking_rules(FILE *fp, const char *chain_name);
17 changes: 2 additions & 15 deletions source/firewall/firewall_ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -1744,22 +1744,9 @@ void do_ipv6_filter_table(FILE *fp){
fprintf(fp, "-A lan2wan_misc_ipv6 -p udp --dport 500 -j ACCEPT\n");
fprintf(fp, "-A lan2wan_misc_ipv6 -p udp --dport 4500 -j ACCEPT\n");
}
char sites_enabled[MAX_QUERY];
sites_enabled[0] = '\0';
syscfg_get(NULL, "managedsites_enabled", sites_enabled, sizeof(sites_enabled));
if (sites_enabled[0] != '\0' && sites_enabled[0] == '0') // managed site list enabled
{
queryv6[0] = '\0';
// Apply SSL blocking rules
do_ssl_blocking_rules(fp, "lan2wan_misc_ipv6");

if((0 == syscfg_get(NULL, "blockssl::result", queryv6, sizeof(queryv6))) && strcmp(queryv6,"DROP") == 0){
fprintf(fp, "-A lan2wan_misc_ipv6 -p udp --dport 443 -j DROP\n");
fprintf(fp, "-A lan2wan_misc_ipv6 -p tcp --dport 443 -j DROP\n");
}
else if(strcmp(queryv6,"ACCEPT") == 0){
fprintf(fp, "-A lan2wan_misc_ipv6 -p udp --dport 443 -j ACCEPT\n");
fprintf(fp, "-A lan2wan_misc_ipv6 -p tcp --dport 443 -j ACCEPT\n");
}
}
queryv6[0] = '\0';

if((0 == syscfg_get(NULL, "blockl2tp::result", queryv6, sizeof(queryv6))) && strcmp(queryv6,"DROP") == 0){
Expand Down
140 changes: 140 additions & 0 deletions source/firewall/firewall_utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* If not stated otherwise in this file or this component's Licenses.txt file the
* following copyright and licenses apply:
*
* Copyright 2026 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "firewall.h"

/**
* @brief Validate if a port number string is valid.
*
* @param[in] port_num - Pointer to the port number string.
*
* @return The status of the operation.
* @retval 0 if port is valid (1-65535).
* @retval -1 if port is invalid.
*/
int validate_port(const char* port_num)
{
int port = atoi(port_num);
if (port <= 0 || port > MAX_PORT)
return -1;
return 0;
}

/**
* @brief Apply SSL blocking rules based on managed sites/services configuration.
*
* Checks if managed sites or managed services (with port 443) are enabled,
* and emits appropriate SSL blocking (DROP/ACCEPT) rules for port 443.
* Rules are skipped per protocol if managed services already covers that
* protocol on port 443.
*
*
* @param[in] fp - Pointer to the FILE stream for writing firewall rules.
* @param[in] chain_name - The iptables chain name (e.g., "lan2wan_misc" or "lan2wan_misc_ipv6").
*/
void do_ssl_blocking_rules(FILE *fp, const char *chain_name)
{
int ms_has_tcp_443 = 0;
int ms_has_udp_443 = 0;
char sites_enabled[MAX_QUERY] = {0};
char services_enabled[MAX_QUERY] = {0};

syscfg_get(NULL, "managedsites_enabled", sites_enabled, sizeof(sites_enabled));

/* If managed sites is enabled, skip SSL blocking entirely */
if (sites_enabled[0] != '\0' && sites_enabled[0] != '0') {
ms_has_tcp_443 = 1;
ms_has_udp_443 = 1;
} else {
/* Check managed services for port 443 */
syscfg_get(NULL, "managedservices_enabled", services_enabled, sizeof(services_enabled));
if (services_enabled[0] != '\0' && services_enabled[0] != '0') {
char ms_count_str[MAX_QUERY] = {0};
int ms_count = 0;
syscfg_get(NULL, "ManagedServiceBlockCount", ms_count_str, sizeof(ms_count_str));
if (ms_count_str[0] != '\0') {
ms_count = atoi(ms_count_str);
}
if (ms_count < 0) {
ms_count = 0;
} else if (ms_count > MAX_SYSCFG_ENTRIES) {
ms_count = MAX_SYSCFG_ENTRIES;
}
for (int i = 1; i <= ms_count && !(ms_has_tcp_443 && ms_has_udp_443); i++) {
char ns[MAX_QUERY] = {0}, prot[10] = {0};
char ms_namespace_key[MAX_QUERY] = {0};

snprintf(ms_namespace_key, sizeof(ms_namespace_key), "ManagedServiceBlock_%d", i);
if (syscfg_get(NULL, ms_namespace_key, ns, sizeof(ns)) != 0 || ns[0] == '\0')
continue;

/* Get protocol to check if we can skip this entry */
if (syscfg_get(ns, "proto", prot, sizeof(prot)) != 0) {
prot[0] = '\0';
}

/* Skip if this protocol is already covered */
if ((strncasecmp("tcp", prot, 3) == 0 && ms_has_tcp_443) ||
(strncasecmp("udp", prot, 3) == 0 && ms_has_udp_443)) {
continue;
}

/* Check port range */
char start_port[16] = {0}, end_port[16] = {0};
syscfg_get(ns, "start_port", start_port, sizeof(start_port));
if (start_port[0] == '\0' || validate_port(start_port) != 0) {
continue;
}
syscfg_get(ns, "end_port", end_port, sizeof(end_port));
if (end_port[0] == '\0' || validate_port(end_port) != 0) {
continue;
Comment thread
suriya-prem marked this conversation as resolved.
}

int sp = atoi(start_port);
int ep = atoi(end_port);
if (sp > 443 || ep < 443) continue; /* Port 443 not in range */

/* Set flags based on protocol */
if (prot[0] == '\0' || strncasecmp("both", prot, 4) == 0) {
ms_has_tcp_443 = ms_has_udp_443 = 1;
break;
} else if (strncasecmp("tcp", prot, 3) == 0) {
ms_has_tcp_443 = 1;
} else if (strncasecmp("udp", prot, 3) == 0) {
ms_has_udp_443 = 1;
}
}
}
}

/* Emit SSL blocking rules for protocols not covered by managed services */
if (!(ms_has_tcp_443 && ms_has_udp_443)) {
char query[MAX_QUERY] = {0};
if (0 == syscfg_get(NULL, "blockssl::result", query, sizeof(query))) {
if (strcmp(query, "DROP") == 0 || strcmp(query, "ACCEPT") == 0) {
if (!ms_has_udp_443) {
fprintf(fp, "-A %s -p udp --dport 443 -j %s\n", chain_name, query);
}
if (!ms_has_tcp_443) {
fprintf(fp, "-A %s -p tcp --dport 443 -j %s\n", chain_name, query);
}
}
}
}
Comment thread
suriya-prem marked this conversation as resolved.
}
Loading