Separate monitoring function plugin
[platform/core/connectivity/stc-manager.git] / src / stc-firewall.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "stc-db.h"
18 #include "table-firewall.h"
19 #include "helper-firewall.h"
20 #include "stc-firewall.h"
21 #include "stc-manager-gdbus.h"
22
23 #define IDENTIFIER_LEN     512
24
25 #define LOCK_NAME          "admin"
26
27 #define CHAIN_NAME         "chain"
28 #define CHAIN_TARGET       "target"
29 #define CHAIN_PRIORITY     "priority"
30
31 #define RULE_IDENTIFIER    "identifier"
32 #define RULE_KEY           "key"
33
34 #define FIREWALL_DBUS_ERROR_NAME "net.stc.firewall.Error.Failed"
35
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)])
40
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__; \
47                 return TRUE; \
48         } \
49 } while (0)
50
51 static const gchar *stc_err_strs[] = {
52         "ERROR_NONE",
53         "FAIL",
54         "DB_FAILED",
55         "OUT_OF_MEMORY",
56         "INVALID_PARAMETER",
57         "NO_DATA",
58         "ALREADY_DATA",
59         "UNINITIALIZED",
60         "PERMISSION_DENIED",
61         "NOTIMPL"
62 };
63
64 static GHashTable *g_firewalls = NULL;
65 static int g_lock_state = FIREWALL_UNKONWN;
66 static uint g_chain_priority = 0;
67
68 static void __fw_rule_copy(firewall_rule_s *rule,
69                                 const firewall_rule_s *info)
70 {
71         if (info->chain) {
72                 FREE(rule->chain);
73                 rule->chain = g_strdup(info->chain);
74         }
75
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;
83
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;
88
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;
93
94         if (info->ifname) {
95                 FREE(rule->ifname);
96                 rule->ifname = g_strdup(info->ifname);
97         }
98
99         rule->target = info->target;
100
101         if (info->target_str) {
102                 FREE(rule->target_str);
103                 rule->target_str = g_strdup(info->target_str);
104         }
105
106         rule->log_level = info->log_level;
107
108         if (info->log_prefix) {
109                 FREE(rule->log_prefix);
110                 rule->log_prefix = g_strdup(info->log_prefix);
111         }
112
113         rule->nflog_group = info->nflog_group;
114         rule->nflog_range = info->nflog_range;
115         rule->nflog_threshold = info->nflog_threshold;
116
117         if (info->nflog_prefix) {
118                 FREE(rule->nflog_prefix);
119                 rule->nflog_prefix = g_strdup(info->nflog_prefix);
120         }
121
122         if (info->identifier) {
123                 FREE(rule->identifier);
124                 rule->identifier = g_strdup(info->identifier);
125         }
126
127         rule->key = info->key;
128 }
129
130 static void __fw_rule_make_key(firewall_rule_s *rule,
131                                 firewall_rule_s *info)
132 {
133         GString *str;
134
135         if (!rule->chain)
136                 return;
137
138         str = g_string_sized_new(IDENTIFIER_LEN);
139         if (!str)
140                 return;
141
142         g_string_append_printf(str, "%s", rule->chain);
143
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);
147
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);
152
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]);
166
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]);
176         }
177
178         g_string_append_printf(str, "_%04x", rule->s_port1);
179         g_string_append_printf(str, "%04x", rule->s_port2);
180
181         g_string_append_printf(str, "_%04x", rule->d_port1);
182         g_string_append_printf(str, "%04x", rule->d_port2);
183
184         g_string_append_printf(str, "_%s", (rule->ifname) ? rule->ifname : "");
185         g_string_append_printf(str, "_%u", rule->target);
186
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);
191                 break;
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);
197                 break;
198         default:
199                 break;
200         }
201
202         FREE(rule->identifier);
203         rule->identifier = g_string_free(str, FALSE);
204         rule->key = g_str_hash(rule->identifier);
205
206         FREE(info->identifier);
207         info->identifier = g_strdup(rule->identifier);
208         info->key = rule->key;
209
210         if (STC_DEBUG_LOG && STC_FW_LOG) {
211                 STC_LOGD("Identifier [%s]", rule->identifier);
212                 STC_LOGD("Key [%u]", rule->key);
213         }
214 }
215
216 static void __fw_rule_free(void *data)
217 {
218         firewall_rule_s *rule = (firewall_rule_s *)data;
219
220         FREE(rule->chain);
221         FREE(rule->ifname);
222         FREE(rule->target_str);
223         FREE(rule->log_prefix);
224         FREE(rule->nflog_prefix);
225         FREE(rule->identifier);
226         FREE(rule);
227 }
228
229 static void __fw_data_free(gpointer value)
230 {
231         stc_fw_data_s *data = (stc_fw_data_s *)value;
232
233         g_slist_free_full(data->rules, __fw_rule_free);
234         data->rules = NULL;
235
236         FREE(data);
237 }
238
239 static gint __fw_rule_comp(gconstpointer a, gconstpointer b)
240 {
241         firewall_rule_s *data = (firewall_rule_s *)a;
242         firewall_rule_s *rule = (firewall_rule_s *)b;
243
244         if ((data->key == rule->key) &&
245                 (g_strcmp0(data->identifier, rule->identifier) == 0))
246                 return 0;
247
248         return -1;
249 }
250
251 static stc_error_e __fw_chain_add(const char *chain)
252 {
253         stc_fw_data_s *data;
254         stc_fw_data_s *lookup;
255
256         ret_value_msg_if(g_firewalls == NULL,
257                 STC_ERROR_FAIL,
258                 "firewall is not initialized!");
259
260         lookup = g_hash_table_lookup(g_firewalls, chain);
261         if (lookup) {
262                 if (STC_DEBUG_LOG && STC_FW_LOG)
263                         STC_LOGD("chain already present");
264                 return STC_ERROR_ALREADY_DATA;
265         }
266
267         data = MALLOC0(stc_fw_data_s, 1);
268         if (!data) {
269                 if (STC_DEBUG_LOG && STC_FW_LOG)
270                         STC_LOGE("data allocation failed");
271                 return STC_ERROR_OUT_OF_MEMORY;
272         }
273
274         data->target = STC_FW_CHAIN_TARGET_NONE;
275         data->priority = 0;
276         data->rules = NULL;
277
278         g_hash_table_insert(g_firewalls, g_strdup(chain), data);
279
280         return STC_ERROR_NONE;
281 }
282
283 static stc_error_e __fw_chain_remove(const char *chain)
284 {
285         stc_fw_data_s *lookup;
286
287         ret_value_msg_if(g_firewalls == NULL,
288                 STC_ERROR_FAIL,
289                 "firewall is not initialized!");
290
291         lookup = g_hash_table_lookup(g_firewalls, chain);
292         if (!lookup) {
293                 if (STC_DEBUG_LOG && STC_FW_LOG)
294                         STC_LOGE("chain not found");
295                 return STC_ERROR_NO_DATA;
296         }
297
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;
302         }
303
304         g_slist_free_full(lookup->rules, __fw_rule_free);
305         lookup->rules = NULL;
306
307         g_hash_table_remove(g_firewalls, chain);
308
309         return STC_ERROR_NONE;
310 }
311
312 static stc_error_e __fw_chain_flush(const char *chain)
313 {
314         stc_fw_data_s *lookup;
315
316         ret_value_msg_if(g_firewalls == NULL,
317                 STC_ERROR_FAIL,
318                 "firewall is not initialized!");
319
320         lookup = g_hash_table_lookup(g_firewalls, chain);
321         if (!lookup) {
322                 if (STC_DEBUG_LOG && STC_FW_LOG)
323                         STC_LOGE("chain not found");
324                 return STC_ERROR_NO_DATA;
325         }
326
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;
331         }
332
333         g_slist_free_full(lookup->rules, __fw_rule_free);
334         lookup->rules = NULL;
335
336         return STC_ERROR_NONE;
337 }
338
339 static stc_error_e __fw_chain_set(const char *chain, stc_fw_data_s value)
340 {
341         stc_fw_data_s *lookup;
342
343         ret_value_msg_if(g_firewalls == NULL,
344                 STC_ERROR_FAIL,
345                 "firewall is not initialized!");
346
347         lookup = g_hash_table_lookup(g_firewalls, chain);
348         if (!lookup) {
349                 if (STC_DEBUG_LOG && STC_FW_LOG)
350                         STC_LOGE("chain not found");
351                 return STC_ERROR_NO_DATA;
352         }
353
354         lookup->target = value.target;
355         lookup->priority = value.priority;
356
357         return STC_ERROR_NONE;
358 }
359
360 static stc_fw_data_s *__fw_chain_get(const char *chain)
361 {
362         stc_fw_data_s *lookup;
363
364         ret_value_msg_if(g_firewalls == NULL, NULL,
365                 "firewall is not initialized!");
366
367         lookup = g_hash_table_lookup(g_firewalls, chain);
368         if (!lookup) {
369                 if (STC_DEBUG_LOG && STC_FW_LOG)
370                         STC_LOGE("chain not found");
371                 return NULL;
372         }
373
374         return lookup;
375 }
376
377 static stc_error_e __fw_chain_unset(const char *chain)
378 {
379         stc_error_e ret = STC_ERROR_NONE;
380         stc_fw_data_s *lookup;
381
382         ret_value_msg_if(g_firewalls == NULL,
383                 STC_ERROR_FAIL,
384                 "firewall is not initialized!");
385
386         lookup = g_hash_table_lookup(g_firewalls, chain);
387         if (!lookup) {
388                 if (STC_DEBUG_LOG && STC_FW_LOG)
389                         STC_LOGE("chain not found");
390                 return STC_ERROR_NO_DATA;
391         }
392
393         lookup->target = STC_FW_CHAIN_TARGET_NONE;
394         lookup->priority = 0;
395
396         return ret;
397 }
398
399 static void __fw_chain_make_params(gpointer key, gpointer value,
400                                 gpointer user_data)
401 {
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;
406
407         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
408
409         g_variant_builder_add(&sub_builder, "{sv}", CHAIN_NAME,
410                                         g_variant_new_string(chain));
411
412         g_variant_builder_add(&sub_builder, "{sv}", CHAIN_PRIORITY,
413                                 g_variant_new_uint32(data->priority));
414
415         g_variant_builder_add(&sub_builder, "{sv}", CHAIN_TARGET,
416                                 g_variant_new_uint16(data->target));
417
418         g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
419 }
420
421 static void __fw_rule_make_params(gpointer data, gpointer user_data)
422 {
423         firewall_rule_s *rule = (firewall_rule_s *)data;
424         GVariantBuilder *builder = (GVariantBuilder *)user_data;
425         GVariantBuilder sub_builder;
426
427         g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}"));
428
429         g_variant_builder_add(&sub_builder, "{sv}", RULE_CHAIN,
430                                         g_variant_new_string(rule->chain));
431
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));
435
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));
439
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));
443
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));
447
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));
451
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));
455
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));
459
460         if (rule->family == STC_FW_FAMILY_V4) {
461                 char *addr = NULL;
462
463                 switch (rule->s_ip_type) {
464                 case STC_FW_IP_RANGE:
465                         /* fall through */
466                 case STC_FW_IP_MASK:
467                         addr = g_try_malloc0(INET_ADDRSTRLEN);
468                         if (addr) {
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));
472                                 FREE(addr);
473                         }
474                         /* fall through */
475                 case STC_FW_IP_SINGLE:
476                         addr = g_try_malloc0(INET_ADDRSTRLEN);
477                         if (addr) {
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));
481                                 FREE(addr);
482                         }
483                         break;
484                 default:
485                         break;
486                 }
487
488                 switch (rule->d_ip_type) {
489                 case STC_FW_IP_RANGE:
490                         /* fall through */
491                 case STC_FW_IP_MASK:
492                         addr = g_try_malloc0(INET_ADDRSTRLEN);
493                         if (addr) {
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));
497                                 FREE(addr);
498                         }
499                         /* fall through */
500                 case STC_FW_IP_SINGLE:
501                         addr = g_try_malloc0(INET_ADDRSTRLEN);
502                         if (addr) {
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));
506                                 FREE(addr);
507                         }
508                         break;
509                 default:
510                         break;
511                 }
512         } else if (rule->family == STC_FW_FAMILY_V6) {
513                 char *addr = NULL;
514
515                 switch (rule->s_ip_type) {
516                 case STC_FW_IP_RANGE:
517                         /* fall through */
518                 case STC_FW_IP_MASK:
519                         addr = g_try_malloc0(INET6_ADDRSTRLEN);
520                         if (addr) {
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));
524                                 FREE(addr);
525                         }
526                         /* fall through */
527                 case STC_FW_IP_SINGLE:
528                         addr = g_try_malloc0(INET6_ADDRSTRLEN);
529                         if (addr) {
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));
533                                 FREE(addr);
534                         }
535                         break;
536                 default:
537                         break;
538                 }
539
540                 switch (rule->d_ip_type) {
541                 case STC_FW_IP_RANGE:
542                         /* fall through */
543                 case STC_FW_IP_MASK:
544                         addr = g_try_malloc0(INET6_ADDRSTRLEN);
545                         if (addr) {
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));
549                                 FREE(addr);
550                         }
551                         /* fall through */
552                 case STC_FW_IP_SINGLE:
553                         addr = g_try_malloc0(INET6_ADDRSTRLEN);
554                         if (addr) {
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));
558                                 FREE(addr);
559                         }
560                         break;
561                 default:
562                         break;
563                 }
564         }
565
566         g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORT1,
567                                 g_variant_new_uint32(rule->s_port1));
568
569         g_variant_builder_add(&sub_builder, "{sv}", RULE_SPORT2,
570                                 g_variant_new_uint32(rule->s_port2));
571
572         g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORT1,
573                                 g_variant_new_uint32(rule->d_port1));
574
575         g_variant_builder_add(&sub_builder, "{sv}", RULE_DPORT2,
576                                 g_variant_new_uint32(rule->d_port2));
577
578         if (rule->ifname)
579                 g_variant_builder_add(&sub_builder, "{sv}", RULE_IFNAME,
580                                         g_variant_new_string(rule->ifname));
581
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));
585
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));
590
591                 if (rule->log_prefix)
592                         g_variant_builder_add(&sub_builder, "{sv}", RULE_LOG_PREFIX,
593                                                 g_variant_new_string(rule->log_prefix));
594                 break;
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));
598
599                 if (rule->nflog_prefix)
600                         g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_PREFIX,
601                                                 g_variant_new_string(rule->nflog_prefix));
602
603                 g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_RANGE,
604                                         g_variant_new_uint16(rule->nflog_range));
605
606                 g_variant_builder_add(&sub_builder, "{sv}", RULE_NFLOG_THRESHOLD,
607                                         g_variant_new_uint16(rule->nflog_threshold));
608                 break;
609         default:
610                 break;
611         }
612
613         g_variant_builder_add(&sub_builder, "{sv}", RULE_IDENTIFIER,
614                                 g_variant_new_string(rule->identifier));
615
616         g_variant_builder_add(&sub_builder, "{sv}", RULE_KEY,
617                                 g_variant_new_uint32(rule->key));
618
619         g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder));
620 }
621
622 static void __fw_rule_set_to_chain(gpointer data, gpointer user_data)
623 {
624         firewall_rule_s *rule = (firewall_rule_s *)data;
625         char *chain = (char *)user_data;
626
627         if (chain && (g_strcmp0(rule->chain, chain) != 0))
628                 return;
629
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);
634                 break;
635         case STC_FW_RULE_TARGET_DROP:
636                 FREE(rule->target_str);
637                 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_DROP);
638                 break;
639         case STC_FW_RULE_TARGET_LOG:
640                 FREE(rule->target_str);
641                 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_LOG);
642                 break;
643         case STC_FW_RULE_TARGET_NFLOG:
644                 FREE(rule->target_str);
645                 rule->target_str = g_strdup(FIREWALL_RULE_TARGET_NFLOG);
646                 break;
647         default:
648                 break;
649         }
650
651         firewall_rule_append(rule);
652 }
653
654 static void __fw_rule_print_rules(gpointer data, gpointer user_data)
655 {
656         firewall_rule_s *rule = (firewall_rule_s *)data;
657
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,
661                 rule->protocol,
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);
667
668         switch (rule->family) {
669         case STC_FW_FAMILY_V4:
670                 STC_LOGD("[%d][%d][%08x][%08x][%d][%08x][%08x]",
671                         rule->family,
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);
674                 break;
675         case STC_FW_FAMILY_V6:
676                 STC_LOGD("[%d][%d][%08x:%08x:%08x:%08x]"
677                         "[%d][%08x:%08x:%08x:%08x]",
678                         rule->family,
679                         rule->s_ip_type,
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],
682                         rule->d_ip_type,
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]);
685                 break;
686         default:
687                 break;
688         }
689 }
690
691 static void __fw_foreach_to_print_rule(gpointer key, gpointer value,
692                                 gpointer user_data)
693 {
694         stc_fw_data_s *data = (stc_fw_data_s *)value;
695
696         g_slist_foreach(data->rules, __fw_rule_print_rules, user_data);
697 }
698
699 static void __fw_foreach_to_make_rule_param(gpointer key, gpointer value,
700                                 gpointer user_data)
701 {
702         stc_fw_data_s *data = (stc_fw_data_s *)value;
703
704         g_slist_foreach(data->rules, __fw_rule_make_params, user_data);
705 }
706
707 static void __fw_foreach_to_set_rule_to_chain(gpointer key, gpointer value,
708                                 gpointer user_data)
709 {
710         stc_fw_data_s *data = (stc_fw_data_s *)value;
711         char *chain = (char *)user_data;
712
713         if (chain || (data->target != STC_FW_CHAIN_TARGET_NONE))
714                 g_slist_foreach(data->rules, __fw_rule_set_to_chain, user_data);
715 }
716
717 static void __fw_foreach_to_set_chain(gpointer key, gpointer value,
718                                 gpointer user_data)
719 {
720         char *chain = (char *)key;
721         stc_fw_data_s *data = (stc_fw_data_s *)value;
722
723         if (data->target != STC_FW_CHAIN_TARGET_NONE) {
724                 firewall_chain_s info;
725                 memset(&info, 0, sizeof(firewall_chain_s));
726                 info.chain = chain;
727                 info.target = data->target;
728                 info.priority = data->priority;
729                 firewall_chain_set(&info);
730         }
731 }
732
733 static void __fw_foreach_to_add_chain(gpointer key, gpointer value,
734                                 gpointer user_data)
735 {
736         char *chain = (char *)key;
737         stc_fw_data_s *data = (stc_fw_data_s *)value;
738
739         if (data->target != STC_FW_CHAIN_TARGET_NONE) {
740                 firewall_chain_s info;
741                 memset(&info, 0, sizeof(firewall_chain_s));
742                 info.chain = chain;
743                 info.target = data->target;
744                 info.priority = data->priority;
745                 firewall_chain_add(&info);
746         }
747 }
748
749 static void __fw_chain_foreach(GHFunc func, void *user_data)
750 {
751         g_hash_table_foreach(g_firewalls, func, user_data);
752 }
753
754 stc_cb_ret_e __fw_table_chain_info_cb(const firewall_chain_s *info,
755                                 void *user_data)
756 {
757         stc_fw_data_s *data;
758
759         data = MALLOC0(stc_fw_data_s, 1);
760         if (!data) {
761                 if (STC_DEBUG_LOG && STC_FW_LOG)
762                         STC_LOGE("data allocation failed");
763                 return STC_CONTINUE;
764         }
765
766         data->target = info->target;
767         data->priority = info->priority;
768         data->rules = NULL;
769
770         g_hash_table_insert(g_firewalls, g_strdup(info->chain), data);
771
772         return STC_CONTINUE;
773 }
774
775 stc_cb_ret_e __fw_table_rule_info_cb(const firewall_rule_s *info,
776                                 void *user_data)
777 {
778         stc_fw_data_s *lookup;
779         firewall_rule_s *rule;
780
781         lookup = g_hash_table_lookup(g_firewalls, info->chain);
782         if (!lookup) {
783                 if (STC_DEBUG_LOG && STC_FW_LOG)
784                         STC_LOGE("chain not found");
785                 return STC_CONTINUE;
786         }
787
788         rule = MALLOC0(firewall_rule_s, 1);
789         if (!rule) {
790                 if (STC_DEBUG_LOG && STC_FW_LOG)
791                         STC_LOGE("rule allocation failed");
792                 return STC_CONTINUE;
793         }
794
795         memset(rule, 0, sizeof(firewall_rule_s));
796         __fw_rule_copy(rule, info);
797
798         lookup->rules = g_slist_append(lookup->rules, rule);
799
800         return STC_CONTINUE;
801 }
802
803 static stc_error_e __fw_rule_add(firewall_rule_s *info)
804 {
805         stc_fw_data_s *lookup;
806         firewall_rule_s *rule;
807         GSList *comp;
808
809         ret_value_msg_if(g_firewalls == NULL,
810                 STC_ERROR_FAIL,
811                 "firewall is not initialized!");
812
813         lookup = g_hash_table_lookup(g_firewalls, info->chain);
814         if (!lookup) {
815                 if (STC_DEBUG_LOG && STC_FW_LOG)
816                         STC_LOGE("chain not found");
817                 return STC_ERROR_NO_DATA;
818         }
819
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;
824         }
825
826         rule = MALLOC0(firewall_rule_s, 1);
827         if (!rule) {
828                 if (STC_DEBUG_LOG && STC_FW_LOG)
829                         STC_LOGE("rule allocation failed");
830                 return STC_ERROR_OUT_OF_MEMORY;
831         }
832
833         memset(rule, 0, sizeof(firewall_rule_s));
834         __fw_rule_copy(rule, info);
835         __fw_rule_make_key(rule, info);
836
837         comp = g_slist_find_custom(lookup->rules, rule, __fw_rule_comp);
838         if (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;
843         }
844
845         lookup->rules = g_slist_append(lookup->rules, rule);
846
847         return STC_ERROR_NONE;
848 }
849
850 static stc_error_e __fw_rule_remove(const firewall_rule_s *info)
851 {
852         stc_fw_data_s *lookup;
853         GSList *rule_list;
854         GSList *comp;
855         firewall_rule_s *rule;
856
857         ret_value_msg_if(g_firewalls == NULL,
858                 STC_ERROR_FAIL,
859                 "firewall is not initialized!");
860
861         lookup = g_hash_table_lookup(g_firewalls, info->chain);
862         if (!lookup) {
863                 if (STC_DEBUG_LOG && STC_FW_LOG)
864                         STC_LOGE("chain not found");
865                 return STC_ERROR_NO_DATA;
866         }
867
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;
872         }
873
874         rule_list = lookup->rules;
875         comp = g_slist_find_custom(rule_list, info, __fw_rule_comp);
876         if (!comp) {
877                 if (STC_DEBUG_LOG && STC_FW_LOG)
878                         STC_LOGD("rule not found");
879                 return STC_ERROR_NO_DATA;
880         }
881
882         rule = comp->data;
883         lookup->rules = g_slist_remove(lookup->rules, rule);
884         __fw_rule_free(rule);
885
886         return STC_ERROR_NONE;
887 }
888
889 static stc_error_e __fw_rule_update(firewall_rule_s *info)
890 {
891         stc_fw_data_s *lookup;
892         GSList *rule_list;
893         GSList *comp;
894         firewall_rule_s *origin_rule;
895         firewall_rule_s *update_rule;
896
897         ret_value_msg_if(g_firewalls == NULL,
898                 STC_ERROR_FAIL,
899                 "firewall is not initialized!");
900
901         lookup = g_hash_table_lookup(g_firewalls, info->chain);
902         if (!lookup) {
903                 if (STC_DEBUG_LOG && STC_FW_LOG)
904                         STC_LOGE("chain not found");
905                 return STC_ERROR_NO_DATA;
906         }
907
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;
912         }
913
914         rule_list = lookup->rules;
915         comp = g_slist_find_custom(rule_list, info, __fw_rule_comp);
916         if (!comp) {
917                 if (STC_DEBUG_LOG && STC_FW_LOG)
918                         STC_LOGD("rule not found");
919                 return STC_ERROR_NO_DATA;
920         }
921
922         origin_rule = comp->data;
923
924         update_rule = MALLOC0(firewall_rule_s, 1);
925         if (!update_rule) {
926                 if (STC_DEBUG_LOG && STC_FW_LOG)
927                         STC_LOGE("rule allocation failed");
928                 return STC_ERROR_OUT_OF_MEMORY;
929         }
930
931         memset(update_rule, 0, sizeof(firewall_rule_s));
932         __fw_rule_copy(update_rule, info);
933         __fw_rule_make_key(update_rule, info);
934
935         comp = g_slist_find_custom(lookup->rules, update_rule, __fw_rule_comp);
936         if (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;
941         }
942
943         lookup->rules = g_slist_remove(lookup->rules, origin_rule);
944         __fw_rule_free(origin_rule);
945
946         lookup->rules = g_slist_append(lookup->rules, update_rule);
947
948         return STC_ERROR_NONE;
949 }
950
951 static void __fw_rule_extract(const char *key, GVariant *value,
952                         void *user_data)
953 {
954         firewall_rule_s *rule = (firewall_rule_s *)user_data;
955         if (rule == NULL) {
956                 __STC_LOG_FUNC_EXIT__;
957                 return;
958         }
959
960         if (g_strcmp0(key, RULE_CHAIN) == 0) {
961                 guint str_length;
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);
965
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);
969
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);
973
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);
977
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);
981
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);
985
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);
989
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);
993
994         } else if (g_strcmp0(key, RULE_SIP1) == 0) {
995                 if (rule->s_ip_type != STC_FW_IP_NONE) {
996                         guint str_length;
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]);
1006                         }
1007                 }
1008
1009         } else if (g_strcmp0(key, RULE_SIP2) == 0) {
1010                 if (rule->s_ip_type != STC_FW_IP_NONE) {
1011                         guint str_length;
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]);
1021                         }
1022                 }
1023
1024         } else if (g_strcmp0(key, RULE_DIP1) == 0) {
1025                 if (rule->d_ip_type != STC_FW_IP_NONE) {
1026                         guint str_length;
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]);
1036                         }
1037                 }
1038
1039         } else if (g_strcmp0(key, RULE_DIP2) == 0) {
1040                 if (rule->d_ip_type != STC_FW_IP_NONE) {
1041                         guint str_length;
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]);
1051                         }
1052                 }
1053
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);
1058                 }
1059
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);
1064                 }
1065
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);
1070                 }
1071
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);
1076                 }
1077
1078         } else if (g_strcmp0(key, RULE_IFNAME) == 0) {
1079                 if (rule->direction != STC_FW_DIRECTION_NONE) {
1080                         guint str_length;
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);
1084                 }
1085
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);
1089
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);
1094                 }
1095
1096         } else if (g_strcmp0(key, RULE_LOG_PREFIX) == 0) {
1097                 if (rule->target == STC_FW_RULE_TARGET_LOG) {
1098                         guint str_length;
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);
1102                 }
1103
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);
1108                 }
1109
1110         } else if (g_strcmp0(key, RULE_NFLOG_PREFIX) == 0) {
1111                 if (rule->target == STC_FW_RULE_TARGET_NFLOG) {
1112                         guint str_length;
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);
1116                 }
1117
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);
1122                 }
1123
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);
1128                 }
1129
1130         } else if (g_strcmp0(key, RULE_IDENTIFIER) == 0) {
1131                 guint str_length;
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);
1135
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);
1139
1140         } else {
1141                 STC_LOGD("Unknown rule [%s]", key);
1142         }
1143 }
1144
1145 gboolean __validate_fw_rule(firewall_rule_s *rule)
1146 {
1147         __STC_LOG_FUNC_ENTER__;
1148
1149         if (rule == NULL) {
1150                 __STC_LOG_FUNC_EXIT__;
1151                 return FALSE;
1152         }
1153
1154         if (rule->chain == NULL) {
1155                 __STC_LOG_FUNC_EXIT__;
1156                 return FALSE;
1157         }
1158
1159         if (rule->direction > STC_FW_DIRECTION_OUT) {
1160                 __STC_LOG_FUNC_EXIT__;
1161                 return FALSE;
1162         }
1163
1164         if (rule->s_ip_type > STC_FW_IP_RANGE) {
1165                 __STC_LOG_FUNC_EXIT__;
1166                 return FALSE;
1167         }
1168
1169         if (rule->d_ip_type > STC_FW_IP_RANGE) {
1170                 __STC_LOG_FUNC_EXIT__;
1171                 return FALSE;
1172         }
1173
1174         if (rule->s_port_type > STC_FW_PORT_RANGE) {
1175                 __STC_LOG_FUNC_EXIT__;
1176                 return FALSE;
1177         }
1178
1179         if (rule->d_port_type > STC_FW_PORT_RANGE) {
1180                 __STC_LOG_FUNC_EXIT__;
1181                 return FALSE;
1182         }
1183
1184         if (rule->protocol > STC_FW_PROTOCOL_ALL) {
1185                 __STC_LOG_FUNC_EXIT__;
1186                 return FALSE;
1187         }
1188
1189         if (rule->family > STC_FW_FAMILY_V6) {
1190                 __STC_LOG_FUNC_EXIT__;
1191                 return FALSE;
1192         }
1193
1194         if (rule->target >= STC_FW_RULE_TARGET_MAX) {
1195                 __STC_LOG_FUNC_EXIT__;
1196                 return FALSE;
1197         }
1198
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__;
1203                 return FALSE;
1204         }
1205
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__;
1210                 return FALSE;
1211         }
1212
1213         __STC_LOG_FUNC_EXIT__;
1214         return TRUE;
1215 }
1216
1217 void stc_firewall_init(void)
1218 {
1219         __STC_LOG_FUNC_ENTER__;
1220
1221         int ret = STC_ERROR_NONE;
1222
1223         g_firewalls = g_hash_table_new_full(g_str_hash,
1224                                         g_str_equal, g_free, __fw_data_free);
1225
1226         ret = table_firewall_get_lock(LOCK_NAME, &g_lock_state);
1227         if (ret != STC_ERROR_NONE)
1228                 table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1229
1230         if (g_lock_state == FIREWALL_UNKONWN)
1231                 g_lock_state = FIREWALL_UNLOCKED;
1232
1233         table_firewall_foreach_chain(__fw_table_chain_info_cb, NULL);
1234         table_firewall_foreach_rule(__fw_table_rule_info_cb, NULL);
1235
1236         __STC_LOG_FUNC_EXIT__;
1237 }
1238
1239 API void stc_firewall_update(void)
1240 {
1241         __STC_LOG_FUNC_ENTER__;
1242
1243         __fw_chain_foreach(__fw_foreach_to_add_chain, NULL);
1244         __fw_chain_foreach(__fw_foreach_to_set_rule_to_chain, NULL);
1245         __fw_chain_foreach(__fw_foreach_to_set_chain, NULL);
1246
1247         __STC_LOG_FUNC_EXIT__;
1248 }
1249
1250 void stc_firewall_deinit(void)
1251 {
1252         __STC_LOG_FUNC_ENTER__;
1253
1254         if (g_firewalls) {
1255                 g_hash_table_destroy(g_firewalls);
1256                 g_firewalls = NULL;
1257         }
1258
1259         __STC_LOG_FUNC_EXIT__;
1260 }
1261
1262 gboolean handle_firewall_lock(StcFirewall *object,
1263                                         GDBusMethodInvocation *invocation,
1264                                         void *user_data)
1265 {
1266         __STC_LOG_FUNC_ENTER__;
1267         int ret = STC_ERROR_NONE;
1268
1269         ret = table_firewall_update_lock(LOCK_NAME, FIREWALL_LOCKED);
1270         if (ret != STC_ERROR_NONE)
1271                 table_firewall_insert_lock(LOCK_NAME, FIREWALL_LOCKED);
1272
1273         g_lock_state = FIREWALL_LOCKED;
1274
1275         STC_DBUS_REPLY_ERROR_NONE(invocation);
1276         __STC_LOG_FUNC_EXIT__;
1277         return TRUE;
1278 }
1279
1280 gboolean handle_firewall_unlock(StcFirewall *object,
1281                                         GDBusMethodInvocation *invocation,
1282                                         void *user_data)
1283 {
1284         __STC_LOG_FUNC_ENTER__;
1285         int ret = STC_ERROR_NONE;
1286
1287         ret = table_firewall_update_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1288         if (ret != STC_ERROR_NONE)
1289                 table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1290
1291         g_lock_state = FIREWALL_UNLOCKED;
1292
1293         STC_DBUS_REPLY_ERROR_NONE(invocation);
1294         __STC_LOG_FUNC_EXIT__;
1295         return TRUE;
1296 }
1297
1298 gboolean handle_firewall_get_lock(StcFirewall *object,
1299                                         GDBusMethodInvocation *invocation,
1300                                         void *user_data)
1301 {
1302         __STC_LOG_FUNC_ENTER__;
1303         int ret = STC_ERROR_NONE;
1304         GVariant *return_parameters = NULL;
1305
1306         if (g_lock_state == FIREWALL_UNKONWN) {
1307                 ret = table_firewall_get_lock(LOCK_NAME, &g_lock_state);
1308                 if (ret != STC_ERROR_NONE)
1309                         table_firewall_insert_lock(LOCK_NAME, FIREWALL_UNLOCKED);
1310
1311                 if (g_lock_state == FIREWALL_UNKONWN)
1312                         g_lock_state = FIREWALL_UNLOCKED;
1313         }
1314
1315         return_parameters = g_variant_new("(i)", g_lock_state);
1316         STC_DBUS_REPLY(invocation, return_parameters);
1317         __STC_LOG_FUNC_EXIT__;
1318         return TRUE;
1319 }
1320
1321 gboolean handle_firewall_add_chain(StcFirewall *object,
1322                                         GDBusMethodInvocation *invocation,
1323                                         gchar *chain,
1324                                         void *user_data)
1325 {
1326         __STC_LOG_FUNC_ENTER__;
1327         firewall_chain_s info;
1328         int ret = STC_ERROR_NONE;
1329
1330         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1331
1332         if (chain == NULL) {
1333                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1334                                                 STC_ERROR_INVALID_PARAMETER);
1335                 __STC_LOG_FUNC_EXIT__;
1336                 return TRUE;
1337         }
1338
1339         ret = __fw_chain_add(chain);
1340         if (ret == STC_ERROR_NONE) {
1341                 memset(&info, 0, sizeof(firewall_chain_s));
1342                 info.chain = chain;
1343                 info.priority = 0;
1344                 info.target = STC_FW_CHAIN_TARGET_NONE;
1345                 table_firewall_insert_chain(&info);
1346         } else {
1347                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1348                 __STC_LOG_FUNC_EXIT__;
1349                 return TRUE;
1350         }
1351
1352         STC_DBUS_REPLY_ERROR_NONE(invocation);
1353         __STC_LOG_FUNC_EXIT__;
1354         return TRUE;
1355 }
1356
1357 gboolean handle_firewall_remove_chain(StcFirewall *object,
1358                                         GDBusMethodInvocation *invocation,
1359                                         gchar *chain,
1360                                         void *user_data)
1361 {
1362         __STC_LOG_FUNC_ENTER__;
1363         firewall_chain_s info;
1364         int ret = STC_ERROR_NONE;
1365
1366         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1367
1368         if (chain == NULL) {
1369                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1370                                                 STC_ERROR_INVALID_PARAMETER);
1371                 __STC_LOG_FUNC_EXIT__;
1372                 return TRUE;
1373         }
1374
1375         ret = __fw_chain_remove(chain);
1376         if (ret == STC_ERROR_NONE) {
1377                 memset(&info, 0, sizeof(firewall_chain_s));
1378                 info.chain = chain;
1379                 table_firewall_flush_chain(&info);
1380                 table_firewall_delete_chain(&info);
1381         } else {
1382                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1383                 __STC_LOG_FUNC_EXIT__;
1384                 return TRUE;
1385         }
1386
1387         STC_DBUS_REPLY_ERROR_NONE(invocation);
1388         __STC_LOG_FUNC_EXIT__;
1389         return TRUE;
1390 }
1391
1392 gboolean handle_firewall_flush_chain(StcFirewall *object,
1393                                         GDBusMethodInvocation *invocation,
1394                                         gchar *chain,
1395                                         void *user_data)
1396 {
1397         __STC_LOG_FUNC_ENTER__;
1398         firewall_chain_s info;
1399         int ret = STC_ERROR_NONE;
1400
1401         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1402
1403         if (chain == NULL) {
1404                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1405                                                 STC_ERROR_INVALID_PARAMETER);
1406                 __STC_LOG_FUNC_EXIT__;
1407                 return TRUE;
1408         }
1409
1410         ret = __fw_chain_flush(chain);
1411         if (ret == STC_ERROR_NONE) {
1412                 memset(&info, 0, sizeof(firewall_chain_s));
1413                 info.chain = chain;
1414                 table_firewall_flush_chain(&info);
1415         } else {
1416                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1417                 __STC_LOG_FUNC_EXIT__;
1418                 return TRUE;
1419         }
1420
1421         STC_DBUS_REPLY_ERROR_NONE(invocation);
1422         __STC_LOG_FUNC_EXIT__;
1423         return TRUE;
1424 }
1425
1426 gboolean handle_firewall_get_all_chain(StcFirewall *object,
1427                                         GDBusMethodInvocation *invocation,
1428                                         void *user_data)
1429 {
1430         __STC_LOG_FUNC_ENTER__;
1431         GVariantBuilder *builder = NULL;
1432         GVariant *return_parameters = NULL;
1433
1434         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1435
1436         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
1437
1438         __fw_chain_foreach(__fw_chain_make_params, builder);
1439
1440         return_parameters = g_variant_new("(aa{sv})", builder);
1441         g_variant_builder_unref(builder);
1442
1443         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
1444         STC_DBUS_REPLY(invocation, return_parameters);
1445         __STC_LOG_FUNC_EXIT__;
1446         return TRUE;
1447 }
1448
1449 gboolean handle_firewall_set_chain(StcFirewall *object,
1450                                         GDBusMethodInvocation *invocation,
1451                                         gchar *chain,
1452                                         unsigned int target,
1453                                         void *user_data)
1454 {
1455         __STC_LOG_FUNC_ENTER__;
1456         stc_fw_data_s *lookup = NULL;
1457         stc_fw_data_s data;
1458         firewall_chain_s info;
1459         uint priority;
1460         int ret = STC_ERROR_NONE;
1461
1462         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1463
1464         if (chain == NULL ||
1465                 target >= STC_FW_CHAIN_TARGET_MAX) {
1466                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1467                                                 STC_ERROR_INVALID_PARAMETER);
1468                 __STC_LOG_FUNC_EXIT__;
1469                 return TRUE;
1470         }
1471
1472         lookup = __fw_chain_get(chain);
1473         if (lookup == NULL) {
1474                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1475                                                 STC_ERROR_NO_DATA);
1476                 __STC_LOG_FUNC_EXIT__;
1477                 return TRUE;
1478         }
1479
1480         if (lookup->target != STC_FW_CHAIN_TARGET_NONE) {
1481                 STC_LOGE("chain is already set");
1482                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1483                                                 STC_ERROR_INVALID_PARAMETER);
1484                 __STC_LOG_FUNC_EXIT__;
1485                 return TRUE;
1486         }
1487
1488         /* stc-iptables */
1489         memset(&info, 0, sizeof(firewall_chain_s));
1490         info.chain = chain;
1491         info.target = target;
1492
1493         ret = firewall_chain_add(&info);
1494         if (ret != STC_ERROR_NONE) {
1495                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1496                 __STC_LOG_FUNC_EXIT__;
1497                 return TRUE;
1498         }
1499
1500         __fw_chain_foreach(__fw_foreach_to_set_rule_to_chain, chain);
1501         ret = firewall_chain_set(&info);
1502         if (ret != STC_ERROR_NONE) {
1503                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1504                 __STC_LOG_FUNC_EXIT__;
1505                 return TRUE;
1506         }
1507         /* stc-iptables */
1508
1509         priority = g_chain_priority + 1;
1510
1511         memset(&data, 0, sizeof(stc_fw_data_s));
1512         data.target = target;
1513         data.priority = priority;
1514
1515         ret = __fw_chain_set(chain, data);
1516         if (ret == STC_ERROR_NONE) {
1517                 info.priority = priority;
1518                 table_firewall_update_chain(&info);
1519                 g_chain_priority = priority;
1520         } else {
1521                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1522                 __STC_LOG_FUNC_EXIT__;
1523                 return TRUE;
1524         }
1525
1526         STC_DBUS_REPLY_ERROR_NONE(invocation);
1527         __STC_LOG_FUNC_EXIT__;
1528         return TRUE;
1529 }
1530
1531 gboolean handle_firewall_unset_chain(StcFirewall *object,
1532                                         GDBusMethodInvocation *invocation,
1533                                         gchar *chain,
1534                                         void *user_data)
1535 {
1536         __STC_LOG_FUNC_ENTER__;
1537         stc_fw_data_s *lookup = NULL;
1538         firewall_chain_s info;
1539         int ret = STC_ERROR_NONE;
1540
1541         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1542
1543         if (chain == NULL) {
1544                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1545                                                 STC_ERROR_INVALID_PARAMETER);
1546                 __STC_LOG_FUNC_EXIT__;
1547                 return TRUE;
1548         }
1549
1550         lookup = __fw_chain_get(chain);
1551         if (lookup == NULL) {
1552                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1553                                                 STC_ERROR_NO_DATA);
1554                 __STC_LOG_FUNC_EXIT__;
1555                 return TRUE;
1556         }
1557
1558         if (lookup->target == STC_FW_CHAIN_TARGET_NONE) {
1559                 if (STC_DEBUG_LOG && STC_FW_LOG)
1560                         STC_LOGE("chain is not set");
1561                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1562                                                 STC_ERROR_INVALID_PARAMETER);
1563                 __STC_LOG_FUNC_EXIT__;
1564                 return TRUE;
1565         }
1566
1567         /* stc-iptables */
1568         memset(&info, 0, sizeof(firewall_chain_s));
1569         info.chain = chain;
1570         info.target = lookup->target;
1571
1572         ret = firewall_chain_unset(&info);
1573         if (ret != STC_ERROR_NONE) {
1574                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1575                 __STC_LOG_FUNC_EXIT__;
1576                 return TRUE;
1577         }
1578
1579         ret = firewall_chain_remove(&info);
1580         if (ret != STC_ERROR_NONE) {
1581                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1582                 __STC_LOG_FUNC_EXIT__;
1583                 return TRUE;
1584         }
1585         /* stc-iptables */
1586
1587         ret = __fw_chain_unset(chain);
1588         if (ret == STC_ERROR_NONE) {
1589                 info.target = STC_FW_CHAIN_TARGET_NONE;
1590                 info.priority = 0;
1591                 table_firewall_update_chain(&info);
1592         } else {
1593                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1594                 __STC_LOG_FUNC_EXIT__;
1595                 return TRUE;
1596         }
1597
1598         STC_DBUS_REPLY_ERROR_NONE(invocation);
1599         __STC_LOG_FUNC_EXIT__;
1600         return TRUE;
1601 }
1602
1603 gboolean handle_firewall_add_rule(StcFirewall *object,
1604                                    GDBusMethodInvocation *invocation,
1605                                    GVariant *parameters,
1606                                    void *user_data)
1607 {
1608         __STC_LOG_FUNC_ENTER__;
1609         GVariantIter *iter = NULL;
1610         firewall_rule_s *rule;
1611         int ret = STC_ERROR_NONE;
1612
1613         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1614
1615         rule = MALLOC0(firewall_rule_s, 1);
1616         if (!rule) {
1617                 if (STC_DEBUG_LOG && STC_FW_LOG)
1618                         STC_LOGE("rule allocation failed");
1619                 return STC_ERROR_OUT_OF_MEMORY;
1620         }
1621
1622         memset(rule, 0, sizeof(firewall_rule_s));
1623
1624         g_variant_get(parameters, "a{sv}", &iter);
1625         if (iter != NULL) {
1626                 stc_manager_gdbus_dict_foreach(iter,
1627                                                __fw_rule_extract,
1628                                                rule);
1629                 g_variant_iter_free(iter);
1630         }
1631
1632         if (__validate_fw_rule(rule) == FALSE) {
1633                 __fw_rule_free(rule);
1634                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1635                                                  STC_ERROR_INVALID_PARAMETER);
1636                 __STC_LOG_FUNC_EXIT__;
1637                 return TRUE;
1638         }
1639
1640         ret = __fw_rule_add(rule);
1641         if (ret == STC_ERROR_NONE) {
1642                 table_firewall_insert_rule(rule);
1643         } else {
1644                 __fw_rule_free(rule);
1645                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1646                 __STC_LOG_FUNC_EXIT__;
1647                 return TRUE;
1648         }
1649
1650         __fw_rule_free(rule);
1651         STC_DBUS_REPLY_ERROR_NONE(invocation);
1652         __STC_LOG_FUNC_EXIT__;
1653         return TRUE;
1654 }
1655
1656 gboolean handle_firewall_remove_rule(StcFirewall *object,
1657                                    GDBusMethodInvocation *invocation,
1658                                    GVariant *parameters,
1659                                    void *user_data)
1660 {
1661         __STC_LOG_FUNC_ENTER__;
1662         GVariantIter *iter = NULL;
1663         firewall_rule_s *rule;
1664         int ret = STC_ERROR_NONE;
1665
1666         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1667
1668         rule = MALLOC0(firewall_rule_s, 1);
1669         if (!rule) {
1670                 if (STC_DEBUG_LOG && STC_FW_LOG)
1671                         STC_LOGE("rule allocation failed");
1672                 return STC_ERROR_OUT_OF_MEMORY;
1673         }
1674
1675         memset(rule, 0, sizeof(firewall_rule_s));
1676
1677         g_variant_get(parameters, "a{sv}", &iter);
1678         if (iter != NULL) {
1679                 stc_manager_gdbus_dict_foreach(iter,
1680                                                __fw_rule_extract,
1681                                                rule);
1682                 g_variant_iter_free(iter);
1683         }
1684
1685         if (__validate_fw_rule(rule) == FALSE) {
1686                 __fw_rule_free(rule);
1687                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1688                                                  STC_ERROR_INVALID_PARAMETER);
1689                 __STC_LOG_FUNC_EXIT__;
1690                 return TRUE;
1691         }
1692
1693         ret = __fw_rule_remove(rule);
1694         if (ret == STC_ERROR_NONE) {
1695                 table_firewall_delete_rule(rule);
1696         } else {
1697                 __fw_rule_free(rule);
1698                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1699                 __STC_LOG_FUNC_EXIT__;
1700                 return TRUE;
1701         }
1702
1703         __fw_rule_free(rule);
1704         STC_DBUS_REPLY_ERROR_NONE(invocation);
1705         __STC_LOG_FUNC_EXIT__;
1706         return TRUE;
1707 }
1708
1709 gboolean handle_firewall_update_rule(StcFirewall *object,
1710                                    GDBusMethodInvocation *invocation,
1711                                    GVariant *parameters,
1712                                    void *user_data)
1713 {
1714         __STC_LOG_FUNC_ENTER__;
1715         GVariantIter *iter = NULL;
1716         firewall_rule_s *rule;
1717         guint key;
1718         int ret = STC_ERROR_NONE;
1719
1720         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1721
1722         rule = MALLOC0(firewall_rule_s, 1);
1723         if (!rule) {
1724                 if (STC_DEBUG_LOG && STC_FW_LOG)
1725                         STC_LOGE("rule allocation failed");
1726                 return STC_ERROR_OUT_OF_MEMORY;
1727         }
1728
1729         memset(rule, 0, sizeof(firewall_rule_s));
1730
1731         g_variant_get(parameters, "a{sv}", &iter);
1732         if (iter != NULL) {
1733                 stc_manager_gdbus_dict_foreach(iter,
1734                                                __fw_rule_extract,
1735                                                rule);
1736                 g_variant_iter_free(iter);
1737         }
1738
1739         if (__validate_fw_rule(rule) == FALSE) {
1740                 __fw_rule_free(rule);
1741                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation,
1742                                                  STC_ERROR_INVALID_PARAMETER);
1743                 __STC_LOG_FUNC_EXIT__;
1744                 return TRUE;
1745         }
1746
1747         key = rule->key;
1748         ret = __fw_rule_update(rule);
1749         if (ret == STC_ERROR_NONE) {
1750                 table_firewall_update_rule(rule, key);
1751         } else {
1752                 __fw_rule_free(rule);
1753                 STC_FIREWALL_DBUS_REPLY_ERROR(invocation, ret);
1754                 __STC_LOG_FUNC_EXIT__;
1755                 return TRUE;
1756         }
1757
1758         __fw_rule_free(rule);
1759         STC_DBUS_REPLY_ERROR_NONE(invocation);
1760         __STC_LOG_FUNC_EXIT__;
1761         return TRUE;
1762 }
1763
1764 gboolean handle_firewall_get_all_rule(StcFirewall *object,
1765                                    GDBusMethodInvocation *invocation,
1766                                    void *user_data)
1767 {
1768         __STC_LOG_FUNC_ENTER__;
1769         GVariantBuilder *builder = NULL;
1770         GVariant *return_parameters = NULL;
1771
1772         STC_FIREWALL_CHECK_LOCK_STATE(invocation);
1773
1774         builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}"));
1775
1776         __fw_chain_foreach(__fw_foreach_to_make_rule_param, builder);
1777         __fw_chain_foreach(__fw_foreach_to_print_rule, NULL);
1778
1779         return_parameters = g_variant_new("(aa{sv})", builder);
1780         g_variant_builder_unref(builder);
1781
1782         DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters);
1783         STC_DBUS_REPLY(invocation, return_parameters);
1784         __STC_LOG_FUNC_EXIT__;
1785         return TRUE;
1786 }