2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "table-firewall.h"
19 #include "helper-firewall.h"
20 #include "stc-firewall.h"
21 #include "stc-manager-gdbus.h"
23 #define IDENTIFIER_LEN 512
25 #define LOCK_NAME "admin"
27 #define CHAIN_NAME "chain"
28 #define CHAIN_TARGET "target"
29 #define CHAIN_PRIORITY "priority"
31 #define RULE_IDENTIFIER "identifier"
32 #define RULE_KEY "key"
34 #define FIREWALL_DBUS_ERROR_NAME "net.stc.firewall.Error.Failed"
36 #define STC_FIREWALL_DBUS_REPLY_ERROR(invocation, err_num) \
37 g_dbus_method_invocation_return_dbus_error((invocation), \
38 FIREWALL_DBUS_ERROR_NAME, \
39 stc_err_strs[-(err_num)])
41 #define STC_FIREWALL_CHECK_LOCK_STATE(invocation) do { \
42 if (g_lock_state == FIREWALL_LOCKED) { \
43 STC_LOGD("Firewall is locked"); \
44 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, \
45 STC_ERROR_PERMISSION_DENIED); \
46 __STC_LOG_FUNC_EXIT__; \
51 static const gchar *stc_err_strs[] = {
64 static GHashTable *g_firewalls = NULL;
65 static int g_lock_state = FIREWALL_UNKONWN;
66 static uint g_chain_priority = 0;
68 static void __fw_rule_copy(firewall_rule_s *rule,
69 const firewall_rule_s *info)
73 rule->chain = g_strdup(info->chain);
76 rule->direction = info->direction;
77 rule->s_ip_type = info->s_ip_type;
78 rule->d_ip_type = info->d_ip_type;
79 rule->s_port_type = info->s_port_type;
80 rule->d_port_type = info->d_port_type;
81 rule->protocol = info->protocol;
82 rule->family = info->family;
84 rule->s_ip1 = info->s_ip1;
85 rule->s_ip2 = info->s_ip2;
86 rule->d_ip1 = info->d_ip1;
87 rule->d_ip2 = info->d_ip2;
89 rule->s_port1 = info->s_port1;
90 rule->s_port2 = info->s_port2;
91 rule->d_port1 = info->d_port1;
92 rule->d_port2 = info->d_port2;
96 rule->ifname = g_strdup(info->ifname);
99 rule->target = info->target;
101 if (info->target_str) {
102 FREE(rule->target_str);
103 rule->target_str = g_strdup(info->target_str);
106 rule->log_level = info->log_level;
108 if (info->log_prefix) {
109 FREE(rule->log_prefix);
110 rule->log_prefix = g_strdup(info->log_prefix);
113 rule->nflog_group = info->nflog_group;
114 rule->nflog_range = info->nflog_range;
115 rule->nflog_threshold = info->nflog_threshold;
117 if (info->nflog_prefix) {
118 FREE(rule->nflog_prefix);
119 rule->nflog_prefix = g_strdup(info->nflog_prefix);
122 if (info->identifier) {
123 FREE(rule->identifier);
124 rule->identifier = g_strdup(info->identifier);
127 rule->key = info->key;
130 static void __fw_rule_make_key(firewall_rule_s *rule,
131 firewall_rule_s *info)
138 str = g_string_sized_new(IDENTIFIER_LEN);
142 g_string_append_printf(str, "%s", rule->chain);
144 g_string_append_printf(str, "_%u%u%u%u%u%u%u", rule->direction,
145 rule->s_ip_type, rule->d_ip_type, rule->s_port_type,
146 rule->d_port_type, rule->protocol, rule->family);
148 if (rule->family == STC_FW_FAMILY_V4) {
149 g_string_append_printf(str, "_");
150 g_string_append_printf(str, "%08x", rule->s_ip1.Ipv4.s_addr);
151 g_string_append_printf(str, "%08x", rule->s_ip2.Ipv4.s_addr);
153 g_string_append_printf(str, "_");
154 g_string_append_printf(str, "%08x", rule->d_ip1.Ipv4.s_addr);
155 g_string_append_printf(str, "%08x", rule->d_ip2.Ipv4.s_addr);
156 } else if (rule->family == STC_FW_FAMILY_V6) {
157 g_string_append_printf(str, "_");
158 g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[0]);
159 g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[1]);
160 g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[2]);
161 g_string_append_printf(str, "%08x", rule->s_ip1.Ipv6.s6_addr32[3]);
162 g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[0]);
163 g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[1]);
164 g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[2]);
165 g_string_append_printf(str, "%08x", rule->s_ip2.Ipv6.s6_addr32[3]);
167 g_string_append_printf(str, "_");
168 g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[0]);
169 g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[1]);
170 g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[2]);
171 g_string_append_printf(str, "%08x", rule->d_ip1.Ipv6.s6_addr32[3]);
172 g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[0]);
173 g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[1]);
174 g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[2]);
175 g_string_append_printf(str, "%08x", rule->d_ip2.Ipv6.s6_addr32[3]);
178 g_string_append_printf(str, "_%04x", rule->s_port1);
179 g_string_append_printf(str, "%04x", rule->s_port2);
181 g_string_append_printf(str, "_%04x", rule->d_port1);
182 g_string_append_printf(str, "%04x", rule->d_port2);
184 g_string_append_printf(str, "_%s", (rule->ifname) ? rule->ifname : "");
185 g_string_append_printf(str, "_%u", rule->target);
187 switch (rule->target) {
188 case STC_FW_RULE_TARGET_LOG:
189 g_string_append_printf(str, "_%u", rule->log_level);
190 g_string_append_printf(str, "_%s", rule->log_prefix);
192 case STC_FW_RULE_TARGET_NFLOG:
193 g_string_append_printf(str, "_%u", rule->nflog_group);
194 g_string_append_printf(str, "_%s", rule->nflog_prefix);
195 g_string_append_printf(str, "_%u", rule->nflog_range);
196 g_string_append_printf(str, "_%u", rule->nflog_threshold);
202 FREE(rule->identifier);
203 rule->identifier = g_string_free(str, FALSE);
204 rule->key = g_str_hash(rule->identifier);
206 FREE(info->identifier);
207 info->identifier = g_strdup(rule->identifier);
208 info->key = rule->key;
210 if (STC_DEBUG_LOG && STC_FW_LOG) {
211 STC_LOGD("Identifier [%s]", rule->identifier);
212 STC_LOGD("Key [%u]", rule->key);
216 static void __fw_rule_free(void *data)
218 firewall_rule_s *rule = (firewall_rule_s *)data;
222 FREE(rule->target_str);
223 FREE(rule->log_prefix);
224 FREE(rule->nflog_prefix);
225 FREE(rule->identifier);
229 static void __fw_data_free(gpointer value)
231 stc_fw_data_s *data = (stc_fw_data_s *)value;
233 g_slist_free_full(data->rules, __fw_rule_free);
239 static gint __fw_rule_comp(gconstpointer a, gconstpointer b)
241 firewall_rule_s *data = (firewall_rule_s *)a;
242 firewall_rule_s *rule = (firewall_rule_s *)b;
244 if ((data->key == rule->key) &&
245 (g_strcmp0(data->identifier, rule->identifier) == 0))
251 static stc_error_e __fw_chain_add(const char *chain)
254 stc_fw_data_s *lookup;
256 ret_value_msg_if(g_firewalls == NULL,
258 "firewall is not initialized!");
260 lookup = g_hash_table_lookup(g_firewalls, chain);
262 if (STC_DEBUG_LOG && STC_FW_LOG)
263 STC_LOGD("chain already present");
264 return STC_ERROR_ALREADY_DATA;
267 data = MALLOC0(stc_fw_data_s, 1);
269 if (STC_DEBUG_LOG && STC_FW_LOG)
270 STC_LOGE("data allocation failed");
271 return STC_ERROR_OUT_OF_MEMORY;
274 data->target = STC_FW_CHAIN_TARGET_NONE;
278 g_hash_table_insert(g_firewalls, g_strdup(chain), data);
280 return STC_ERROR_NONE;
283 static stc_error_e __fw_chain_remove(const char *chain)
285 stc_fw_data_s *lookup;
287 ret_value_msg_if(g_firewalls == NULL,
289 "firewall is not initialized!");
291 lookup = g_hash_table_lookup(g_firewalls, chain);
293 if (STC_DEBUG_LOG && STC_FW_LOG)
294 STC_LOGE("chain not found");
295 return STC_ERROR_NO_DATA;
298 if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
299 if (STC_DEBUG_LOG && STC_FW_LOG)
300 STC_LOGE("can't be applied bcz chain is set");
301 return STC_ERROR_INVALID_PARAMETER;
304 g_slist_free_full(lookup->rules, __fw_rule_free);
305 lookup->rules = NULL;
307 g_hash_table_remove(g_firewalls, chain);
309 return STC_ERROR_NONE;
312 static stc_error_e __fw_chain_flush(const char *chain)
314 stc_fw_data_s *lookup;
316 ret_value_msg_if(g_firewalls == NULL,
318 "firewall is not initialized!");
320 lookup = g_hash_table_lookup(g_firewalls, chain);
322 if (STC_DEBUG_LOG && STC_FW_LOG)
323 STC_LOGE("chain not found");
324 return STC_ERROR_NO_DATA;
327 if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
328 if (STC_DEBUG_LOG && STC_FW_LOG)
329 STC_LOGE("can't be applied bcz chain is set");
330 return STC_ERROR_INVALID_PARAMETER;
333 g_slist_free_full(lookup->rules, __fw_rule_free);
334 lookup->rules = NULL;
336 return STC_ERROR_NONE;
339 static stc_error_e __fw_chain_set(const char *chain, stc_fw_data_s value)
341 stc_fw_data_s *lookup;
343 ret_value_msg_if(g_firewalls == NULL,
345 "firewall is not initialized!");
347 lookup = g_hash_table_lookup(g_firewalls, chain);
349 if (STC_DEBUG_LOG && STC_FW_LOG)
350 STC_LOGE("chain not found");
351 return STC_ERROR_NO_DATA;
354 lookup->target = value.target;
355 lookup->priority = value.priority;
357 return STC_ERROR_NONE;
360 static stc_fw_data_s *__fw_chain_get(const char *chain)
362 stc_fw_data_s *lookup;
364 ret_value_msg_if(g_firewalls == NULL, NULL,
365 "firewall is not initialized!");
367 lookup = g_hash_table_lookup(g_firewalls, chain);
369 if (STC_DEBUG_LOG && STC_FW_LOG)
370 STC_LOGE("chain not found");
377 static stc_error_e __fw_chain_unset(const char *chain)
379 stc_error_e ret = STC_ERROR_NONE;
380 stc_fw_data_s *lookup;
382 ret_value_msg_if(g_firewalls == NULL,
384 "firewall is not initialized!");
386 lookup = g_hash_table_lookup(g_firewalls, chain);
388 if (STC_DEBUG_LOG && STC_FW_LOG)
389 STC_LOGE("chain not found");
390 return STC_ERROR_NO_DATA;
393 lookup->target = STC_FW_CHAIN_TARGET_NONE;
394 lookup->priority = 0;
399 static void __fw_chain_make_params(gpointer key, gpointer value,
402 char *chain = (char *)key;
403 stc_fw_data_s *data = (stc_fw_data_s *)value;
404 GVariantBuilder *builder = (GVariantBuilder *)user_data;
405 GVariantBuilder sub_builder;
407 g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
409 g_variant_builder_add(&sub_builder, "{sv}", CHAIN_NAME,
410 g_variant_new_string(chain));
412 g_variant_builder_add(&sub_builder, "{sv}", CHAIN_PRIORITY,
413 g_variant_new_uint32(data->priority));
415 g_variant_builder_add(&sub_builder, "{sv}", CHAIN_TARGET,
416 g_variant_new_uint16(data->target));
418 g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
421 static void __fw_rule_make_params(gpointer data, gpointer user_data)
423 firewall_rule_s *rule = (firewall_rule_s *)data;
424 GVariantBuilder *builder = (GVariantBuilder *)user_data;
425 GVariantBuilder sub_builder;
427 g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
429 g_variant_builder_add(&sub_builder, "{sv}", RULE_CHAIN,
430 g_variant_new_string(rule->chain));
432 if (rule->direction != STC_FW_DIRECTION_NONE)
433 g_variant_builder_add(&sub_builder, "{sv}", RULE_DIRECTION,
434 g_variant_new_uint16(rule->direction));
436 if (rule->s_ip_type != STC_FW_IP_NONE)
437 g_variant_builder_add(&sub_builder, "{sv}", RULE_SIPTYPE,
438 g_variant_new_uint16(rule->s_ip_type));
440 if (rule->d_ip_type != STC_FW_IP_NONE)
441 g_variant_builder_add(&sub_builder, "{sv}", RULE_DIPTYPE,
442 g_variant_new_uint16(rule->d_ip_type));
444 if (rule->s_port_type != STC_FW_PORT_NONE)
445 g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORTTYPE,
446 g_variant_new_uint16(rule->s_port_type));
448 if (rule->d_port_type != STC_FW_PORT_NONE)
449 g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORTTYPE,
450 g_variant_new_uint16(rule->d_port_type));
452 if (rule->protocol != STC_FW_PROTOCOL_NONE)
453 g_variant_builder_add(&sub_builder, "{sv}", RULE_PROTOCOL,
454 g_variant_new_uint16(rule->protocol));
456 if (rule->family != STC_FW_FAMILY_NONE)
457 g_variant_builder_add(&sub_builder, "{sv}", RULE_FAMILY,
458 g_variant_new_uint16(rule->family));
460 if (rule->family == STC_FW_FAMILY_V4) {
463 switch (rule->s_ip_type) {
464 case STC_FW_IP_RANGE:
467 addr = g_try_malloc0(INET_ADDRSTRLEN);
469 inet_ntop(AF_INET, &(rule->s_ip2.Ipv4), addr, INET_ADDRSTRLEN);
470 g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP2,
471 g_variant_new_string(addr));
475 case STC_FW_IP_SINGLE:
476 addr = g_try_malloc0(INET_ADDRSTRLEN);
478 inet_ntop(AF_INET, &(rule->s_ip1.Ipv4), addr, INET_ADDRSTRLEN);
479 g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP1,
480 g_variant_new_string(addr));
488 switch (rule->d_ip_type) {
489 case STC_FW_IP_RANGE:
492 addr = g_try_malloc0(INET_ADDRSTRLEN);
494 inet_ntop(AF_INET, &(rule->d_ip2.Ipv4), addr, INET_ADDRSTRLEN);
495 g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP2,
496 g_variant_new_string(addr));
500 case STC_FW_IP_SINGLE:
501 addr = g_try_malloc0(INET_ADDRSTRLEN);
503 inet_ntop(AF_INET, &(rule->d_ip1.Ipv4), addr, INET_ADDRSTRLEN);
504 g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP1,
505 g_variant_new_string(addr));
512 } else if (rule->family == STC_FW_FAMILY_V6) {
515 switch (rule->s_ip_type) {
516 case STC_FW_IP_RANGE:
519 addr = g_try_malloc0(INET6_ADDRSTRLEN);
521 inet_ntop(AF_INET6, &(rule->s_ip2.Ipv6), addr, INET6_ADDRSTRLEN);
522 g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP2,
523 g_variant_new_string(addr));
527 case STC_FW_IP_SINGLE:
528 addr = g_try_malloc0(INET6_ADDRSTRLEN);
530 inet_ntop(AF_INET6, &(rule->s_ip1.Ipv6), addr, INET6_ADDRSTRLEN);
531 g_variant_builder_add(&sub_builder, "{sv}", RULE_SIP1,
532 g_variant_new_string(addr));
540 switch (rule->d_ip_type) {
541 case STC_FW_IP_RANGE:
544 addr = g_try_malloc0(INET6_ADDRSTRLEN);
546 inet_ntop(AF_INET6, &(rule->d_ip2.Ipv6), addr, INET6_ADDRSTRLEN);
547 g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP2,
548 g_variant_new_string(addr));
552 case STC_FW_IP_SINGLE:
553 addr = g_try_malloc0(INET6_ADDRSTRLEN);
555 inet_ntop(AF_INET6, &(rule->d_ip1.Ipv6), addr, INET6_ADDRSTRLEN);
556 g_variant_builder_add(&sub_builder, "{sv}", RULE_DIP1,
557 g_variant_new_string(addr));
566 g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORT1,
567 g_variant_new_uint32(rule->s_port1));
569 g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORT2,
570 g_variant_new_uint32(rule->s_port2));
572 g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORT1,
573 g_variant_new_uint32(rule->d_port1));
575 g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORT2,
576 g_variant_new_uint32(rule->d_port2));
579 g_variant_builder_add(&sub_builder, "{sv}", RULE_IFNAME,
580 g_variant_new_string(rule->ifname));
582 if (rule->target != STC_FW_RULE_TARGET_NONE)
583 g_variant_builder_add(&sub_builder, "{sv}", RULE_TARGET,
584 g_variant_new_uint16(rule->target));
586 switch (rule->target) {
587 case STC_FW_RULE_TARGET_LOG:
588 g_variant_builder_add(&sub_builder, "{sv}", RULE_LOG_LEVEL,
589 g_variant_new_uint16(rule->log_level));
591 if (rule->log_prefix)
592 g_variant_builder_add(&sub_builder, "{sv}", RULE_LOG_PREFIX,
593 g_variant_new_string(rule->log_prefix));
595 case STC_FW_RULE_TARGET_NFLOG:
596 g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_GROUP,
597 g_variant_new_uint16(rule->nflog_group));
599 if (rule->nflog_prefix)
600 g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_PREFIX,
601 g_variant_new_string(rule->nflog_prefix));
603 g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_RANGE,
604 g_variant_new_uint16(rule->nflog_range));
606 g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_THRESHOLD,
607 g_variant_new_uint16(rule->nflog_threshold));
613 g_variant_builder_add(&sub_builder, "{sv}", RULE_IDENTIFIER,
614 g_variant_new_string(rule->identifier));
616 g_variant_builder_add(&sub_builder, "{sv}", RULE_KEY,
617 g_variant_new_uint32(rule->key));
619 g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
622 static void __fw_rule_set_to_chain(gpointer data, gpointer user_data)
624 firewall_rule_s *rule = (firewall_rule_s *)data;
625 char *chain = (char *)user_data;
627 if (chain && (g_strcmp0(rule->chain, chain) != 0))
630 switch (rule->target) {
631 case STC_FW_RULE_TARGET_ACCEPT:
632 FREE(rule->target_str);
633 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_ACCEPT);
635 case STC_FW_RULE_TARGET_DROP:
636 FREE(rule->target_str);
637 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_DROP);
639 case STC_FW_RULE_TARGET_LOG:
640 FREE(rule->target_str);
641 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_LOG);
643 case STC_FW_RULE_TARGET_NFLOG:
644 FREE(rule->target_str);
645 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_NFLOG);
651 firewall_rule_append(rule);
654 static void __fw_rule_print_rules(gpointer data, gpointer user_data)
656 firewall_rule_s *rule = (firewall_rule_s *)data;
658 STC_LOGD("[%s][%d][%s][%d][%d][%04x][%04x]"
659 "[%d][%04x][%04x][%d][%s][%d][%s][%d][%d]",
660 rule->chain, rule->direction, rule->ifname,
662 rule->s_port_type, rule->s_port1, rule->s_port2,
663 rule->d_port_type, rule->d_port1, rule->d_port2,
664 rule->target, rule->target_str,
665 rule->nflog_group, rule->nflog_prefix,
666 rule->nflog_range, rule->nflog_threshold);
668 switch (rule->family) {
669 case STC_FW_FAMILY_V4:
670 STC_LOGD("[%d][%d][%08x][%08x][%d][%08x][%08x]",
672 rule->s_ip_type, rule->s_ip1.Ipv4.s_addr, rule->s_ip2.Ipv4.s_addr,
673 rule->d_ip_type, rule->d_ip1.Ipv4.s_addr, rule->d_ip2.Ipv4.s_addr);
675 case STC_FW_FAMILY_V6:
676 STC_LOGD("[%d][%d][%08x:%08x:%08x:%08x]"
677 "[%d][%08x:%08x:%08x:%08x]",
680 rule->s_ip1.Ipv6.s6_addr32[0], rule->s_ip1.Ipv6.s6_addr32[1],
681 rule->s_ip1.Ipv6.s6_addr32[2], rule->s_ip1.Ipv6.s6_addr32[3],
683 rule->d_ip1.Ipv6.s6_addr32[0], rule->d_ip1.Ipv6.s6_addr32[1],
684 rule->d_ip1.Ipv6.s6_addr32[2], rule->d_ip1.Ipv6.s6_addr32[3]);
691 static void __fw_foreach_to_print_rule(gpointer key, gpointer value,
694 stc_fw_data_s *data = (stc_fw_data_s *)value;
696 g_slist_foreach(data->rules, __fw_rule_print_rules, user_data);
699 static void __fw_foreach_to_make_rule_param(gpointer key, gpointer value,
702 stc_fw_data_s *data = (stc_fw_data_s *)value;
704 g_slist_foreach(data->rules, __fw_rule_make_params, user_data);
707 static void __fw_foreach_to_set_rule_to_chain(gpointer key, gpointer value,
710 stc_fw_data_s *data = (stc_fw_data_s *)value;
711 char *chain = (char *)user_data;
713 if (chain || (data->target != STC_FW_CHAIN_TARGET_NONE))
714 g_slist_foreach(data->rules, __fw_rule_set_to_chain, user_data);
717 static void __fw_foreach_to_set_chain(gpointer key, gpointer value,
720 char *chain = (char *)key;
721 stc_fw_data_s *data = (stc_fw_data_s *)value;
723 if (data->target != STC_FW_CHAIN_TARGET_NONE) {
724 firewall_chain_s info;
725 memset(&info, 0, sizeof(firewall_chain_s));
727 info.target = data->target;
728 info.priority = data->priority;
729 firewall_chain_set(&info);
733 static void __fw_foreach_to_add_chain(gpointer key, gpointer value,
736 char *chain = (char *)key;
737 stc_fw_data_s *data = (stc_fw_data_s *)value;
739 if (data->target != STC_FW_CHAIN_TARGET_NONE) {
740 firewall_chain_s info;
741 memset(&info, 0, sizeof(firewall_chain_s));
743 info.target = data->target;
744 info.priority = data->priority;
745 firewall_chain_add(&info);
749 static void __fw_chain_foreach(GHFunc func, void *user_data)
751 g_hash_table_foreach(g_firewalls, func, user_data);
754 stc_cb_ret_e __fw_table_chain_info_cb(const firewall_chain_s *info,
759 data = MALLOC0(stc_fw_data_s, 1);
761 if (STC_DEBUG_LOG && STC_FW_LOG)
762 STC_LOGE("data allocation failed");
766 data->target = info->target;
767 data->priority = info->priority;
770 g_hash_table_insert(g_firewalls, g_strdup(info->chain), data);
775 stc_cb_ret_e __fw_table_rule_info_cb(const firewall_rule_s *info,
778 stc_fw_data_s *lookup;
779 firewall_rule_s *rule;
781 lookup = g_hash_table_lookup(g_firewalls, info->chain);
783 if (STC_DEBUG_LOG && STC_FW_LOG)
784 STC_LOGE("chain not found");
788 rule = MALLOC0(firewall_rule_s, 1);
790 if (STC_DEBUG_LOG && STC_FW_LOG)
791 STC_LOGE("rule allocation failed");
795 memset(rule, 0, sizeof(firewall_rule_s));
796 __fw_rule_copy(rule, info);
798 lookup->rules = g_slist_append(lookup->rules, rule);
803 static stc_error_e __fw_rule_add(firewall_rule_s *info)
805 stc_fw_data_s *lookup;
806 firewall_rule_s *rule;
809 ret_value_msg_if(g_firewalls == NULL,
811 "firewall is not initialized!");
813 lookup = g_hash_table_lookup(g_firewalls, info->chain);
815 if (STC_DEBUG_LOG && STC_FW_LOG)
816 STC_LOGE("chain not found");
817 return STC_ERROR_NO_DATA;
820 if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
821 if (STC_DEBUG_LOG && STC_FW_LOG)
822 STC_LOGE("can't be applied bcz chain is set");
823 return STC_ERROR_INVALID_PARAMETER;
826 rule = MALLOC0(firewall_rule_s, 1);
828 if (STC_DEBUG_LOG && STC_FW_LOG)
829 STC_LOGE("rule allocation failed");
830 return STC_ERROR_OUT_OF_MEMORY;
833 memset(rule, 0, sizeof(firewall_rule_s));
834 __fw_rule_copy(rule, info);
835 __fw_rule_make_key(rule, info);
837 comp = g_slist_find_custom(lookup->rules, rule, __fw_rule_comp);
839 if (STC_DEBUG_LOG && STC_FW_LOG)
840 STC_LOGD("rule already present");
841 __fw_rule_free(rule);
842 return STC_ERROR_ALREADY_DATA;
845 lookup->rules = g_slist_append(lookup->rules, rule);
847 return STC_ERROR_NONE;
850 static stc_error_e __fw_rule_remove(const firewall_rule_s *info)
852 stc_fw_data_s *lookup;
855 firewall_rule_s *rule;
857 ret_value_msg_if(g_firewalls == NULL,
859 "firewall is not initialized!");
861 lookup = g_hash_table_lookup(g_firewalls, info->chain);
863 if (STC_DEBUG_LOG && STC_FW_LOG)
864 STC_LOGE("chain not found");
865 return STC_ERROR_NO_DATA;
868 if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
869 if (STC_DEBUG_LOG && STC_FW_LOG)
870 STC_LOGE("can't be applied bcz chain is set");
871 return STC_ERROR_INVALID_PARAMETER;
874 rule_list = lookup->rules;
875 comp = g_slist_find_custom(rule_list, info, __fw_rule_comp);
877 if (STC_DEBUG_LOG && STC_FW_LOG)
878 STC_LOGD("rule not found");
879 return STC_ERROR_NO_DATA;
883 lookup->rules = g_slist_remove(lookup->rules, rule);
884 __fw_rule_free(rule);
886 return STC_ERROR_NONE;
889 static stc_error_e __fw_rule_update(firewall_rule_s *info)
891 stc_fw_data_s *lookup;
894 firewall_rule_s *origin_rule;
895 firewall_rule_s *update_rule;
897 ret_value_msg_if(g_firewalls == NULL,
899 "firewall is not initialized!");
901 lookup = g_hash_table_lookup(g_firewalls, info->chain);
903 if (STC_DEBUG_LOG && STC_FW_LOG)
904 STC_LOGE("chain not found");
905 return STC_ERROR_NO_DATA;
908 if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
909 if (STC_DEBUG_LOG && STC_FW_LOG)
910 STC_LOGE("can't be applied bcz chain is set");
911 return STC_ERROR_INVALID_PARAMETER;
914 rule_list = lookup->rules;
915 comp = g_slist_find_custom(rule_list, info, __fw_rule_comp);
917 if (STC_DEBUG_LOG && STC_FW_LOG)
918 STC_LOGD("rule not found");
919 return STC_ERROR_NO_DATA;
922 origin_rule = comp->data;
924 update_rule = MALLOC0(firewall_rule_s, 1);
926 if (STC_DEBUG_LOG && STC_FW_LOG)
927 STC_LOGE("rule allocation failed");
928 return STC_ERROR_OUT_OF_MEMORY;
931 memset(update_rule, 0, sizeof(firewall_rule_s));
932 __fw_rule_copy(update_rule, info);
933 __fw_rule_make_key(update_rule, info);
935 comp = g_slist_find_custom(lookup->rules, update_rule, __fw_rule_comp);
937 if (STC_DEBUG_LOG && STC_FW_LOG)
938 STC_LOGD("rule already present");
939 __fw_rule_free(update_rule);
940 return STC_ERROR_ALREADY_DATA;
943 lookup->rules = g_slist_remove(lookup->rules, origin_rule);
944 __fw_rule_free(origin_rule);
946 lookup->rules = g_slist_append(lookup->rules, update_rule);
948 return STC_ERROR_NONE;
951 static void __fw_rule_extract(const char *key, GVariant *value,
954 firewall_rule_s *rule = (firewall_rule_s *)user_data;
956 __STC_LOG_FUNC_EXIT__;
960 if (g_strcmp0(key, RULE_CHAIN) == 0) {
962 const gchar *str = g_variant_get_string(value, &str_length);
963 rule->chain = g_strdup(str);
964 STC_LOGD("%s: [%s]", RULE_CHAIN, rule->chain);
966 } else if (g_strcmp0(key, RULE_DIRECTION) == 0) {
967 rule->direction = g_variant_get_uint16(value);
968 STC_LOGD("%s: [%u]", RULE_DIRECTION, rule->direction);
970 } else if (g_strcmp0(key, RULE_SIPTYPE) == 0) {
971 rule->s_ip_type = g_variant_get_uint16(value);
972 STC_LOGD("%s: [%u]", RULE_SIPTYPE, rule->s_ip_type);
974 } else if (g_strcmp0(key, RULE_DIPTYPE) == 0) {
975 rule->d_ip_type = g_variant_get_uint16(value);
976 STC_LOGD("%s: [%u]", RULE_DIPTYPE, rule->d_ip_type);
978 } else if (g_strcmp0(key, RULE_SPORTTYPE) == 0) {
979 rule->s_port_type = g_variant_get_uint16(value);
980 STC_LOGD("%s: [%u]", RULE_SPORTTYPE, rule->s_port_type);
982 } else if (g_strcmp0(key, RULE_DPORTTYPE) == 0) {
983 rule->d_port_type = g_variant_get_uint16(value);
984 STC_LOGD("%s: [%u]", RULE_DPORTTYPE, rule->d_port_type);
986 } else if (g_strcmp0(key, RULE_PROTOCOL) == 0) {
987 rule->protocol = g_variant_get_uint16(value);
988 STC_LOGD("%s: [%u]", RULE_PROTOCOL, rule->protocol);
990 } else if (g_strcmp0(key, RULE_FAMILY) == 0) {
991 rule->family = g_variant_get_uint16(value);
992 STC_LOGD("%s: [%u]", RULE_FAMILY, rule->family);
994 } else if (g_strcmp0(key, RULE_SIP1) == 0) {
995 if (rule->s_ip_type != STC_FW_IP_NONE) {
997 const gchar *str = g_variant_get_string(value, &str_length);
998 if (rule->family == STC_FW_FAMILY_V4) {
999 inet_pton(AF_INET, str, &(rule->s_ip1.Ipv4));
1000 STC_LOGD("%s: [%08x]", RULE_SIP1, rule->s_ip1.Ipv4.s_addr);
1001 } else if (rule->family == STC_FW_FAMILY_V6) {
1002 inet_pton(AF_INET6, str, &(rule->s_ip1.Ipv6));
1003 STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP1,
1004 rule->s_ip1.Ipv6.s6_addr32[0], rule->s_ip1.Ipv6.s6_addr32[1],
1005 rule->s_ip1.Ipv6.s6_addr32[2], rule->s_ip1.Ipv6.s6_addr32[3]);
1009 } else if (g_strcmp0(key, RULE_SIP2) == 0) {
1010 if (rule->s_ip_type != STC_FW_IP_NONE) {
1012 const gchar *str = g_variant_get_string(value, &str_length);
1013 if (rule->family == STC_FW_FAMILY_V4) {
1014 inet_pton(AF_INET, str, &(rule->s_ip2.Ipv4));
1015 STC_LOGD("%s: [%08x]", RULE_SIP2, rule->s_ip2.Ipv4.s_addr);
1016 } else if (rule->family == STC_FW_FAMILY_V6) {
1017 inet_pton(AF_INET6, str, &(rule->s_ip2.Ipv6));
1018 STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_SIP2,
1019 rule->s_ip2.Ipv6.s6_addr32[0], rule->s_ip2.Ipv6.s6_addr32[1],
1020 rule->s_ip2.Ipv6.s6_addr32[2], rule->s_ip2.Ipv6.s6_addr32[3]);
1024 } else if (g_strcmp0(key, RULE_DIP1) == 0) {
1025 if (rule->d_ip_type != STC_FW_IP_NONE) {
1027 const gchar *str = g_variant_get_string(value, &str_length);
1028 if (rule->family == STC_FW_FAMILY_V4) {
1029 inet_pton(AF_INET, str, &(rule->d_ip1.Ipv4));
1030 STC_LOGD("%s: [%08x]", RULE_DIP1, rule->d_ip1.Ipv4.s_addr);
1031 } else if (rule->family == STC_FW_FAMILY_V6) {
1032 inet_pton(AF_INET6, str, &(rule->d_ip1.Ipv6));
1033 STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP1,
1034 rule->d_ip1.Ipv6.s6_addr32[0], rule->d_ip1.Ipv6.s6_addr32[1],
1035 rule->d_ip1.Ipv6.s6_addr32[2], rule->d_ip1.Ipv6.s6_addr32[3]);
1039 } else if (g_strcmp0(key, RULE_DIP2) == 0) {
1040 if (rule->d_ip_type != STC_FW_IP_NONE) {
1042 const gchar *str = g_variant_get_string(value, &str_length);
1043 if (rule->family == STC_FW_FAMILY_V4) {
1044 inet_pton(AF_INET, str, &(rule->d_ip2.Ipv4));
1045 STC_LOGD("%s: [%08x]", RULE_DIP2, rule->d_ip2.Ipv4.s_addr);
1046 } else if (rule->family == STC_FW_FAMILY_V6) {
1047 inet_pton(AF_INET6, str, &(rule->d_ip2.Ipv6));
1048 STC_LOGD("%s: [%08x:%08x:%08x:%08x]", RULE_DIP2,
1049 rule->d_ip2.Ipv6.s6_addr32[0], rule->d_ip2.Ipv6.s6_addr32[1],
1050 rule->d_ip2.Ipv6.s6_addr32[2], rule->d_ip2.Ipv6.s6_addr32[3]);
1054 } else if (g_strcmp0(key, RULE_SPORT1) == 0) {
1055 if (rule->s_port_type != STC_FW_PORT_NONE) {
1056 rule->s_port1 = g_variant_get_uint32(value);
1057 STC_LOGD("%s: [%04x]", RULE_SPORT1, rule->s_port1);
1060 } else if (g_strcmp0(key, RULE_SPORT2) == 0) {
1061 if (rule->s_port_type != STC_FW_PORT_NONE) {
1062 rule->s_port2 = g_variant_get_uint32(value);
1063 STC_LOGD("%s: [%04x]", RULE_SPORT2, rule->s_port2);
1066 } else if (g_strcmp0(key, RULE_DPORT1) == 0) {
1067 if (rule->d_port_type != STC_FW_PORT_NONE) {
1068 rule->d_port1 = g_variant_get_uint32(value);
1069 STC_LOGD("%s: [%04x]", RULE_DPORT1, rule->d_port1);
1072 } else if (g_strcmp0(key, RULE_DPORT2) == 0) {
1073 if (rule->d_port_type != STC_FW_PORT_NONE) {
1074 rule->d_port2 = g_variant_get_uint32(value);
1075 STC_LOGD("%s: [%04x]", RULE_DPORT2, rule->d_port2);
1078 } else if (g_strcmp0(key, RULE_IFNAME) == 0) {
1079 if (rule->direction != STC_FW_DIRECTION_NONE) {
1081 const gchar *str = g_variant_get_string(value, &str_length);
1082 rule->ifname = g_strdup(str);
1083 STC_LOGD("%s: [%s]", RULE_IFNAME, rule->ifname);
1086 } else if (g_strcmp0(key, RULE_TARGET) == 0) {
1087 rule->target = g_variant_get_uint16(value);
1088 STC_LOGD("%s: [%u]", RULE_TARGET, rule->target);
1090 } else if (g_strcmp0(key, RULE_LOG_LEVEL) == 0) {
1091 if (rule->target == STC_FW_RULE_TARGET_LOG) {
1092 rule->log_level = g_variant_get_uint16(value);
1093 STC_LOGD("%s: [%u]", RULE_LOG_LEVEL, rule->log_level);
1096 } else if (g_strcmp0(key, RULE_LOG_PREFIX) == 0) {
1097 if (rule->target == STC_FW_RULE_TARGET_LOG) {
1099 const gchar *str = g_variant_get_string(value, &str_length);
1100 rule->log_prefix = g_strdup(str);
1101 STC_LOGD("%s: [%s]", RULE_LOG_PREFIX, rule->log_prefix);
1104 } else if (g_strcmp0(key, RULE_NFLOG_GROUP) == 0) {
1105 if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
1106 rule->nflog_group = g_variant_get_uint16(value);
1107 STC_LOGD("%s: [%u]", RULE_NFLOG_GROUP, rule->nflog_group);
1110 } else if (g_strcmp0(key, RULE_NFLOG_PREFIX) == 0) {
1111 if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
1113 const gchar *str = g_variant_get_string(value, &str_length);
1114 rule->nflog_prefix = g_strdup(str);
1115 STC_LOGD("%s: [%s]", RULE_NFLOG_PREFIX, rule->nflog_prefix);
1118 } else if (g_strcmp0(key, RULE_NFLOG_RANGE) == 0) {
1119 if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
1120 rule->nflog_range = g_variant_get_uint16(value);
1121 STC_LOGD("%s: [%u]", RULE_NFLOG_RANGE, rule->nflog_range);
1124 } else if (g_strcmp0(key, RULE_NFLOG_THRESHOLD) == 0) {
1125 if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
1126 rule->nflog_threshold = g_variant_get_uint16(value);
1127 STC_LOGD("%s: [%u]", RULE_NFLOG_THRESHOLD, rule->nflog_threshold);
1130 } else if (g_strcmp0(key, RULE_IDENTIFIER) == 0) {
1132 const gchar *str = g_variant_get_string(value, &str_length);
1133 rule->identifier = g_strdup(str);
1134 STC_LOGD("%s: [%s]", RULE_IDENTIFIER, rule->identifier);
1136 } else if (g_strcmp0(key, RULE_KEY) == 0) {
1137 rule->key = g_variant_get_uint32(value);
1138 STC_LOGD("%s: [%u]", RULE_KEY, rule->key);
1141 STC_LOGD("Unknown rule [%s]", key);
1145 gboolean __validate_fw_rule(firewall_rule_s *rule)
1147 __STC_LOG_FUNC_ENTER__;
1150 __STC_LOG_FUNC_EXIT__;
1154 if (rule->chain == NULL) {
1155 __STC_LOG_FUNC_EXIT__;
1159 if (rule->direction > STC_FW_DIRECTION_OUT) {
1160 __STC_LOG_FUNC_EXIT__;
1164 if (rule->s_ip_type > STC_FW_IP_RANGE) {
1165 __STC_LOG_FUNC_EXIT__;
1169 if (rule->d_ip_type > STC_FW_IP_RANGE) {
1170 __STC_LOG_FUNC_EXIT__;
1174 if (rule->s_port_type > STC_FW_PORT_RANGE) {
1175 __STC_LOG_FUNC_EXIT__;
1179 if (rule->d_port_type > STC_FW_PORT_RANGE) {
1180 __STC_LOG_FUNC_EXIT__;
1184 if (rule->protocol > STC_FW_PROTOCOL_ALL) {
1185 __STC_LOG_FUNC_EXIT__;
1189 if (rule->family > STC_FW_FAMILY_V6) {
1190 __STC_LOG_FUNC_EXIT__;
1194 if (rule->target >= STC_FW_RULE_TARGET_MAX) {
1195 __STC_LOG_FUNC_EXIT__;
1199 if (rule->target == STC_FW_RULE_TARGET_LOG &&
1200 (rule->log_prefix == NULL ||
1201 rule->log_prefix[0] == '\0')) {
1202 __STC_LOG_FUNC_EXIT__;
1206 if (rule->target == STC_FW_RULE_TARGET_NFLOG &&
1207 (rule->nflog_prefix == NULL ||
1208 rule->nflog_prefix[0] == '\0')) {
1209 __STC_LOG_FUNC_EXIT__;
1213 __STC_LOG_FUNC_EXIT__;
1217 void stc_firewall_init(void)
1219 int ret = STC_ERROR_NONE;
1221 g_firewalls = g_hash_table_new_full(g_str_hash,
1222 g_str_equal, g_free, __fw_data_free);
1224 ret = table_firewall_get_lock(LOCK_NAME, &g_lock_state);
1225 if (ret != STC_ERROR_NONE)
1226 table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1228 if (g_lock_state == FIREWALL_UNKONWN)
1229 g_lock_state = FIREWALL_UNLOCKED;
1231 table_firewall_foreach_chain(__fw_table_chain_info_cb, NULL);
1232 table_firewall_foreach_rule(__fw_table_rule_info_cb, NULL);
1235 void stc_firewall_update(void)
1237 __fw_chain_foreach(__fw_foreach_to_add_chain, NULL);
1238 __fw_chain_foreach(__fw_foreach_to_set_rule_to_chain, NULL);
1239 __fw_chain_foreach(__fw_foreach_to_set_chain, NULL);
1242 void stc_firewall_deinit(void)
1245 g_hash_table_destroy(g_firewalls);
1250 gboolean handle_firewall_lock(StcFirewall *object,
1251 GDBusMethodInvocation *invocation,
1254 __STC_LOG_FUNC_ENTER__;
1255 int ret = STC_ERROR_NONE;
1257 ret = table_firewall_update_lock(LOCK_NAME, FIREWALL_LOCKED);
1258 if (ret != STC_ERROR_NONE)
1259 table_firewall_insert_lock(LOCK_NAME, FIREWALL_LOCKED);
1261 g_lock_state = FIREWALL_LOCKED;
1263 STC_DBUS_REPLY_ERROR_NONE(invocation);
1264 __STC_LOG_FUNC_EXIT__;
1268 gboolean handle_firewall_unlock(StcFirewall *object,
1269 GDBusMethodInvocation *invocation,
1272 __STC_LOG_FUNC_ENTER__;
1273 int ret = STC_ERROR_NONE;
1275 ret = table_firewall_update_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1276 if (ret != STC_ERROR_NONE)
1277 table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1279 g_lock_state = FIREWALL_UNLOCKED;
1281 STC_DBUS_REPLY_ERROR_NONE(invocation);
1282 __STC_LOG_FUNC_EXIT__;
1286 gboolean handle_firewall_get_lock(StcFirewall *object,
1287 GDBusMethodInvocation *invocation,
1290 __STC_LOG_FUNC_ENTER__;
1291 int ret = STC_ERROR_NONE;
1292 GVariant *return_parameters = NULL;
1294 if (g_lock_state == FIREWALL_UNKONWN) {
1295 ret = table_firewall_get_lock(LOCK_NAME, &g_lock_state);
1296 if (ret != STC_ERROR_NONE)
1297 table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1299 if (g_lock_state == FIREWALL_UNKONWN)
1300 g_lock_state = FIREWALL_UNLOCKED;
1303 return_parameters = g_variant_new("(i)", g_lock_state);
1304 STC_DBUS_REPLY(invocation, return_parameters);
1305 __STC_LOG_FUNC_EXIT__;
1309 gboolean handle_firewall_add_chain(StcFirewall *object,
1310 GDBusMethodInvocation *invocation,
1314 __STC_LOG_FUNC_ENTER__;
1315 firewall_chain_s info;
1316 int ret = STC_ERROR_NONE;
1318 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1320 if (chain == NULL) {
1321 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1322 STC_ERROR_INVALID_PARAMETER);
1323 __STC_LOG_FUNC_EXIT__;
1327 ret = __fw_chain_add(chain);
1328 if (ret == STC_ERROR_NONE) {
1329 memset(&info, 0, sizeof(firewall_chain_s));
1332 info.target = STC_FW_CHAIN_TARGET_NONE;
1333 table_firewall_insert_chain(&info);
1335 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1336 __STC_LOG_FUNC_EXIT__;
1340 STC_DBUS_REPLY_ERROR_NONE(invocation);
1341 __STC_LOG_FUNC_EXIT__;
1345 gboolean handle_firewall_remove_chain(StcFirewall *object,
1346 GDBusMethodInvocation *invocation,
1350 __STC_LOG_FUNC_ENTER__;
1351 firewall_chain_s info;
1352 int ret = STC_ERROR_NONE;
1354 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1356 if (chain == NULL) {
1357 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1358 STC_ERROR_INVALID_PARAMETER);
1359 __STC_LOG_FUNC_EXIT__;
1363 ret = __fw_chain_remove(chain);
1364 if (ret == STC_ERROR_NONE) {
1365 memset(&info, 0, sizeof(firewall_chain_s));
1367 table_firewall_flush_chain(&info);
1368 table_firewall_delete_chain(&info);
1370 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1371 __STC_LOG_FUNC_EXIT__;
1375 STC_DBUS_REPLY_ERROR_NONE(invocation);
1376 __STC_LOG_FUNC_EXIT__;
1380 gboolean handle_firewall_flush_chain(StcFirewall *object,
1381 GDBusMethodInvocation *invocation,
1385 __STC_LOG_FUNC_ENTER__;
1386 firewall_chain_s info;
1387 int ret = STC_ERROR_NONE;
1389 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1391 if (chain == NULL) {
1392 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1393 STC_ERROR_INVALID_PARAMETER);
1394 __STC_LOG_FUNC_EXIT__;
1398 ret = __fw_chain_flush(chain);
1399 if (ret == STC_ERROR_NONE) {
1400 memset(&info, 0, sizeof(firewall_chain_s));
1402 table_firewall_flush_chain(&info);
1404 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1405 __STC_LOG_FUNC_EXIT__;
1409 STC_DBUS_REPLY_ERROR_NONE(invocation);
1410 __STC_LOG_FUNC_EXIT__;
1414 gboolean handle_firewall_get_all_chain(StcFirewall *object,
1415 GDBusMethodInvocation *invocation,
1418 __STC_LOG_FUNC_ENTER__;
1419 GVariantBuilder *builder = NULL;
1420 GVariant *return_parameters = NULL;
1422 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1424 builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
1426 __fw_chain_foreach(__fw_chain_make_params, builder);
1428 return_parameters = g_variant_new("(aa{sv})", builder);
1429 g_variant_builder_unref(builder);
1431 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
1432 STC_DBUS_REPLY(invocation, return_parameters);
1433 __STC_LOG_FUNC_EXIT__;
1437 gboolean handle_firewall_set_chain(StcFirewall *object,
1438 GDBusMethodInvocation *invocation,
1440 unsigned int target,
1443 __STC_LOG_FUNC_ENTER__;
1444 stc_fw_data_s *lookup = NULL;
1446 firewall_chain_s info;
1448 int ret = STC_ERROR_NONE;
1450 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1452 if (chain == NULL ||
1453 target >= STC_FW_CHAIN_TARGET_MAX) {
1454 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1455 STC_ERROR_INVALID_PARAMETER);
1456 __STC_LOG_FUNC_EXIT__;
1460 lookup = __fw_chain_get(chain);
1461 if (lookup == NULL) {
1462 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1464 __STC_LOG_FUNC_EXIT__;
1468 if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
1469 STC_LOGE("chain is already set");
1470 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1471 STC_ERROR_INVALID_PARAMETER);
1472 __STC_LOG_FUNC_EXIT__;
1477 memset(&info, 0, sizeof(firewall_chain_s));
1479 info.target = target;
1481 ret = firewall_chain_add(&info);
1482 if (ret != STC_ERROR_NONE) {
1483 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1484 __STC_LOG_FUNC_EXIT__;
1488 __fw_chain_foreach(__fw_foreach_to_set_rule_to_chain, chain);
1489 ret = firewall_chain_set(&info);
1490 if (ret != STC_ERROR_NONE) {
1491 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1492 __STC_LOG_FUNC_EXIT__;
1497 priority = g_chain_priority + 1;
1499 memset(&data, 0, sizeof(stc_fw_data_s));
1500 data.target = target;
1501 data.priority = priority;
1503 ret = __fw_chain_set(chain, data);
1504 if (ret == STC_ERROR_NONE) {
1505 info.priority = priority;
1506 table_firewall_update_chain(&info);
1507 g_chain_priority = priority;
1509 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1510 __STC_LOG_FUNC_EXIT__;
1514 STC_DBUS_REPLY_ERROR_NONE(invocation);
1515 __STC_LOG_FUNC_EXIT__;
1519 gboolean handle_firewall_unset_chain(StcFirewall *object,
1520 GDBusMethodInvocation *invocation,
1524 __STC_LOG_FUNC_ENTER__;
1525 stc_fw_data_s *lookup = NULL;
1526 firewall_chain_s info;
1527 int ret = STC_ERROR_NONE;
1529 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1531 if (chain == NULL) {
1532 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1533 STC_ERROR_INVALID_PARAMETER);
1534 __STC_LOG_FUNC_EXIT__;
1538 lookup = __fw_chain_get(chain);
1539 if (lookup == NULL) {
1540 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1542 __STC_LOG_FUNC_EXIT__;
1546 if (lookup->target == STC_FW_CHAIN_TARGET_NONE) {
1547 if (STC_DEBUG_LOG && STC_FW_LOG)
1548 STC_LOGE("chain is not set");
1549 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1550 STC_ERROR_INVALID_PARAMETER);
1551 __STC_LOG_FUNC_EXIT__;
1556 memset(&info, 0, sizeof(firewall_chain_s));
1558 info.target = lookup->target;
1560 ret = firewall_chain_unset(&info);
1561 if (ret != STC_ERROR_NONE) {
1562 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1563 __STC_LOG_FUNC_EXIT__;
1567 ret = firewall_chain_remove(&info);
1568 if (ret != STC_ERROR_NONE) {
1569 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1570 __STC_LOG_FUNC_EXIT__;
1575 ret = __fw_chain_unset(chain);
1576 if (ret == STC_ERROR_NONE) {
1577 info.target = STC_FW_CHAIN_TARGET_NONE;
1579 table_firewall_update_chain(&info);
1581 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1582 __STC_LOG_FUNC_EXIT__;
1586 STC_DBUS_REPLY_ERROR_NONE(invocation);
1587 __STC_LOG_FUNC_EXIT__;
1591 gboolean handle_firewall_add_rule(StcFirewall *object,
1592 GDBusMethodInvocation *invocation,
1593 GVariant *parameters,
1596 __STC_LOG_FUNC_ENTER__;
1597 GVariantIter *iter = NULL;
1598 firewall_rule_s *rule;
1599 int ret = STC_ERROR_NONE;
1601 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1603 rule = MALLOC0(firewall_rule_s, 1);
1605 if (STC_DEBUG_LOG && STC_FW_LOG)
1606 STC_LOGE("rule allocation failed");
1607 return STC_ERROR_OUT_OF_MEMORY;
1610 memset(rule, 0, sizeof(firewall_rule_s));
1612 g_variant_get(parameters, "a{sv}", &iter);
1614 stc_manager_gdbus_dict_foreach(iter,
1617 g_variant_iter_free(iter);
1620 if (__validate_fw_rule(rule) == FALSE) {
1621 __fw_rule_free(rule);
1622 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1623 STC_ERROR_INVALID_PARAMETER);
1624 __STC_LOG_FUNC_EXIT__;
1628 ret = __fw_rule_add(rule);
1629 if (ret == STC_ERROR_NONE) {
1630 table_firewall_insert_rule(rule);
1632 __fw_rule_free(rule);
1633 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1634 __STC_LOG_FUNC_EXIT__;
1638 __fw_rule_free(rule);
1639 STC_DBUS_REPLY_ERROR_NONE(invocation);
1640 __STC_LOG_FUNC_EXIT__;
1644 gboolean handle_firewall_remove_rule(StcFirewall *object,
1645 GDBusMethodInvocation *invocation,
1646 GVariant *parameters,
1649 __STC_LOG_FUNC_ENTER__;
1650 GVariantIter *iter = NULL;
1651 firewall_rule_s *rule;
1652 int ret = STC_ERROR_NONE;
1654 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1656 rule = MALLOC0(firewall_rule_s, 1);
1658 if (STC_DEBUG_LOG && STC_FW_LOG)
1659 STC_LOGE("rule allocation failed");
1660 return STC_ERROR_OUT_OF_MEMORY;
1663 memset(rule, 0, sizeof(firewall_rule_s));
1665 g_variant_get(parameters, "a{sv}", &iter);
1667 stc_manager_gdbus_dict_foreach(iter,
1670 g_variant_iter_free(iter);
1673 if (__validate_fw_rule(rule) == FALSE) {
1674 __fw_rule_free(rule);
1675 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1676 STC_ERROR_INVALID_PARAMETER);
1677 __STC_LOG_FUNC_EXIT__;
1681 ret = __fw_rule_remove(rule);
1682 if (ret == STC_ERROR_NONE) {
1683 table_firewall_delete_rule(rule);
1685 __fw_rule_free(rule);
1686 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1687 __STC_LOG_FUNC_EXIT__;
1691 __fw_rule_free(rule);
1692 STC_DBUS_REPLY_ERROR_NONE(invocation);
1693 __STC_LOG_FUNC_EXIT__;
1697 gboolean handle_firewall_update_rule(StcFirewall *object,
1698 GDBusMethodInvocation *invocation,
1699 GVariant *parameters,
1702 __STC_LOG_FUNC_ENTER__;
1703 GVariantIter *iter = NULL;
1704 firewall_rule_s *rule;
1706 int ret = STC_ERROR_NONE;
1708 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1710 rule = MALLOC0(firewall_rule_s, 1);
1712 if (STC_DEBUG_LOG && STC_FW_LOG)
1713 STC_LOGE("rule allocation failed");
1714 return STC_ERROR_OUT_OF_MEMORY;
1717 memset(rule, 0, sizeof(firewall_rule_s));
1719 g_variant_get(parameters, "a{sv}", &iter);
1721 stc_manager_gdbus_dict_foreach(iter,
1724 g_variant_iter_free(iter);
1727 if (__validate_fw_rule(rule) == FALSE) {
1728 __fw_rule_free(rule);
1729 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1730 STC_ERROR_INVALID_PARAMETER);
1731 __STC_LOG_FUNC_EXIT__;
1736 ret = __fw_rule_update(rule);
1737 if (ret == STC_ERROR_NONE) {
1738 table_firewall_update_rule(rule, key);
1740 __fw_rule_free(rule);
1741 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1742 __STC_LOG_FUNC_EXIT__;
1746 __fw_rule_free(rule);
1747 STC_DBUS_REPLY_ERROR_NONE(invocation);
1748 __STC_LOG_FUNC_EXIT__;
1752 gboolean handle_firewall_get_all_rule(StcFirewall *object,
1753 GDBusMethodInvocation *invocation,
1756 __STC_LOG_FUNC_ENTER__;
1757 GVariantBuilder *builder = NULL;
1758 GVariant *return_parameters = NULL;
1760 STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1762 builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
1764 __fw_chain_foreach(__fw_foreach_to_make_rule_param, builder);
1765 __fw_chain_foreach(__fw_foreach_to_print_rule, NULL);
1767 return_parameters = g_variant_new("(aa{sv})", builder);
1768 g_variant_builder_unref(builder);
1770 DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
1771 STC_DBUS_REPLY(invocation, return_parameters);
1772 __STC_LOG_FUNC_EXIT__;