Merge "Return errors to caller" into tizen_5.5
[platform/core/connectivity/stc-manager.git] / src / helper / helper-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-manager-gdbus.h"
18 #include "helper-firewall.h"
19
20 #define STC_FIREWALL_DBUS_SERVICE                    "net.stc.iptables"
21 #define STC_FIREWALL_DBUS_RULE_INTERFACE             STC_FIREWALL_DBUS_SERVICE ".rule"
22 #define STC_FIREWALL_DBUS_CHAIN_INTERFACE            STC_FIREWALL_DBUS_SERVICE ".chain"
23 #define STC_FIREWALL_DBUS_RULE_PATH                  "/net/stc/iptables/rule"
24 #define STC_FIREWALL_DBUS_CHAIN_PATH                 "/net/stc/iptables/chain"
25
26 #define STC_FIREWALL_DBUS_METHOD_ADD_CHAIN           "IptAddChain"
27 #define STC_FIREWALL_DBUS_METHOD_REMOVE_CHAIN        "IptRemoveChain"
28 #define STC_FIREWALL_DBUS_METHOD_FLUSH_CHAIN         "IptFlushChain"
29 #define STC_FIREWALL6_DBUS_METHOD_ADD_CHAIN          "Ip6tAddChain"
30 #define STC_FIREWALL6_DBUS_METHOD_REMOVE_CHAIN       "Ip6tRemoveChain"
31 #define STC_FIREWALL6_DBUS_METHOD_FLUSH_CHAIN        "Ip6tFlushChain"
32
33 #define STC_FIREWALL_DBUS_METHOD_ADD_RULE            "IptAddRule"
34 #define STC_FIREWALL_DBUS_METHOD_INSERT_RULE         "IptInsertRule"
35 #define STC_FIREWALL_DBUS_METHOD_REMOVE_RULE         "IptRemoveRule"
36 #define STC_FIREWALL6_DBUS_METHOD_ADD_RULE           "Ip6tAddRule"
37 #define STC_FIREWALL6_DBUS_METHOD_INSERT_RULE        "Ip6tInsertRule"
38 #define STC_FIREWALL6_DBUS_METHOD_REMOVE_RULE        "Ip6tRemoveRule"
39
40 #define BUF_SIZE_FOR_IP 64
41
42 static void __fw_add_rule_info_to_builder(GVariantBuilder *builder,
43                                        firewall_rule_s *rule)
44 {
45         if (builder == NULL || rule == NULL)
46                 return;
47
48         g_variant_builder_add(builder, "{sv}", RULE_CHAIN,
49                         g_variant_new_string(rule->chain));
50
51         if (rule->direction != STC_FW_DIRECTION_NONE) {
52                 g_variant_builder_add(builder, "{sv}", RULE_DIRECTION,
53                                 g_variant_new_uint16(rule->direction));
54
55                 if (rule->ifname && rule->ifname[0] != '\0')
56                         g_variant_builder_add(builder, "{sv}", RULE_IFNAME,
57                                         g_variant_new_string(rule->ifname));
58         }
59
60         switch (rule->family) {
61         case STC_FW_FAMILY_V4:
62                 if (rule->s_ip_type != STC_FW_IP_NONE) {
63                         g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE,
64                                 g_variant_new_uint16(rule->s_ip_type));
65
66                         if (rule->s_ip1.Ipv4.s_addr)
67                                 g_variant_builder_add(builder, "{sv}", RULE_SIP1,
68                                                 g_variant_new_uint32(rule->s_ip1.Ipv4.s_addr));
69
70                         if (rule->s_ip2.Ipv4.s_addr)
71                                 g_variant_builder_add(builder, "{sv}", RULE_SIP2,
72                                                 g_variant_new_uint32(rule->s_ip2.Ipv4.s_addr));
73                 }
74
75                 if (rule->d_ip_type != STC_FW_IP_NONE) {
76                         g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE,
77                                 g_variant_new_uint16(rule->d_ip_type));
78
79                         if (rule->d_ip1.Ipv4.s_addr)
80                                 g_variant_builder_add(builder, "{sv}", RULE_DIP1,
81                                                 g_variant_new_uint32(rule->d_ip1.Ipv4.s_addr));
82
83                         if (rule->d_ip2.Ipv4.s_addr)
84                                 g_variant_builder_add(builder, "{sv}", RULE_DIP2,
85                                                 g_variant_new_uint32(rule->d_ip2.Ipv4.s_addr));
86                 }
87
88                 break;
89         case STC_FW_FAMILY_V6:
90                 {
91                         char buf[BUF_SIZE_FOR_IP];
92
93                         if (rule->s_ip_type != STC_FW_IP_NONE) {
94                                 g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE,
95                                         g_variant_new_uint16(rule->s_ip_type));
96
97                                 if (rule->s_ip1.Ipv6.s6_addr32[0] || rule->s_ip1.Ipv6.s6_addr32[1] ||
98                                         rule->s_ip1.Ipv6.s6_addr32[2] || rule->s_ip1.Ipv6.s6_addr32[3]) {
99                                         memset(buf, 0, sizeof(buf));
100                                         snprintf(buf, sizeof(buf), "%08x:%08x:%08x:%08x",
101                                                 rule->s_ip1.Ipv6.s6_addr32[0], rule->s_ip1.Ipv6.s6_addr32[1],
102                                                 rule->s_ip1.Ipv6.s6_addr32[2], rule->s_ip1.Ipv6.s6_addr32[3]);
103                                         g_variant_builder_add(builder, "{sv}", RULE_SIP1,
104                                                                 g_variant_new_string(buf));
105                                 }
106
107                                 if (rule->s_ip2.Ipv6.s6_addr32[0] || rule->s_ip2.Ipv6.s6_addr32[1] ||
108                                         rule->s_ip2.Ipv6.s6_addr32[2] || rule->s_ip2.Ipv6.s6_addr32[3]) {
109                                         memset(buf, 0, sizeof(buf));
110                                         snprintf(buf, sizeof(buf), "%08x:%08x:%08x:%08x",
111                                                 rule->s_ip2.Ipv6.s6_addr32[0], rule->s_ip2.Ipv6.s6_addr32[1],
112                                                 rule->s_ip2.Ipv6.s6_addr32[2], rule->s_ip2.Ipv6.s6_addr32[3]);
113                                         g_variant_builder_add(builder, "{sv}", RULE_SIP2,
114                                                                 g_variant_new_string(buf));
115                                 }
116                         }
117
118                         if (rule->d_ip_type != STC_FW_IP_NONE) {
119                                 g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE,
120                                         g_variant_new_uint16(rule->d_ip_type));
121
122                                 if (rule->d_ip1.Ipv6.s6_addr32[0] || rule->d_ip1.Ipv6.s6_addr32[1] ||
123                                         rule->d_ip1.Ipv6.s6_addr32[2] || rule->d_ip1.Ipv6.s6_addr32[3]) {
124                                         memset(buf, 0, sizeof(buf));
125                                         snprintf(buf, sizeof(buf), "%08x:%08x:%08x:%08x",
126                                                 rule->d_ip1.Ipv6.s6_addr32[0], rule->d_ip1.Ipv6.s6_addr32[1],
127                                                 rule->d_ip1.Ipv6.s6_addr32[2], rule->d_ip1.Ipv6.s6_addr32[3]);
128                                         g_variant_builder_add(builder, "{sv}", RULE_DIP1,
129                                                                 g_variant_new_string(buf));
130                                 }
131
132                                 if (rule->d_ip2.Ipv6.s6_addr32[0] || rule->d_ip2.Ipv6.s6_addr32[1] ||
133                                         rule->d_ip2.Ipv6.s6_addr32[2] || rule->d_ip2.Ipv6.s6_addr32[3]) {
134                                         memset(buf, 0, sizeof(buf));
135                                         snprintf(buf, sizeof(buf), "%08x:%08x:%08x:%08x",
136                                                 rule->d_ip2.Ipv6.s6_addr32[0], rule->d_ip2.Ipv6.s6_addr32[1],
137                                                 rule->d_ip2.Ipv6.s6_addr32[2], rule->d_ip2.Ipv6.s6_addr32[3]);
138                                         g_variant_builder_add(builder, "{sv}", RULE_DIP2,
139                                                                 g_variant_new_string(buf));
140                                 }
141                         }
142
143                 }
144                 break;
145         default:
146                 break;
147         }
148
149         if (rule->protocol != STC_FW_PROTOCOL_NONE) {
150                 g_variant_builder_add(builder, "{sv}", RULE_PROTOCOL,
151                                 g_variant_new_uint16(rule->protocol));
152
153                 if (rule->s_port_type != STC_FW_PORT_NONE) {
154                         g_variant_builder_add(builder, "{sv}", RULE_SPORTTYPE,
155                                         g_variant_new_uint16(rule->s_port_type));
156
157                         if (rule->s_port1)
158                                 g_variant_builder_add(builder, "{sv}", RULE_SPORT1,
159                                                 g_variant_new_uint32(rule->s_port1));
160
161                         if (rule->s_port2)
162                                 g_variant_builder_add(builder, "{sv}", RULE_SPORT2,
163                                                 g_variant_new_uint32(rule->s_port2));
164                 }
165
166                 if (rule->d_port_type != STC_FW_PORT_NONE) {
167                         g_variant_builder_add(builder, "{sv}", RULE_DPORTTYPE,
168                                         g_variant_new_uint16(rule->d_port_type));
169
170                         if (rule->d_port1)
171                                 g_variant_builder_add(builder, "{sv}", RULE_DPORT1,
172                                                 g_variant_new_uint32(rule->d_port1));
173
174                         if (rule->d_port2)
175                                 g_variant_builder_add(builder, "{sv}", RULE_DPORT2,
176                                                 g_variant_new_uint32(rule->d_port2));
177                 }
178         }
179
180         if (rule->target_str && rule->target_str[0] != '\0')
181                 g_variant_builder_add(builder, "{sv}", RULE_TARGET,
182                                 g_variant_new_string(rule->target_str));
183
184         if (rule->target != STC_FW_RULE_TARGET_NONE)
185                 g_variant_builder_add(builder, "{sv}", RULE_TARGETTYPE,
186                                 g_variant_new_uint16(rule->target));
187
188         switch (rule->target) {
189         case STC_FW_RULE_TARGET_LOG:
190                 g_variant_builder_add(builder, "{sv}", RULE_LOG_LEVEL,
191                                 g_variant_new_uint16(rule->log_level));
192
193                 if (rule->log_prefix && rule->log_prefix[0] != '\0')
194                         g_variant_builder_add(builder, "{sv}", RULE_LOG_PREFIX,
195                                         g_variant_new_string(rule->log_prefix));
196                 break;
197         case STC_FW_RULE_TARGET_NFLOG:
198                 g_variant_builder_add(builder, "{sv}", RULE_NFLOG_GROUP,
199                                 g_variant_new_uint16(rule->nflog_group));
200
201                 if (rule->nflog_prefix && rule->nflog_prefix[0] != '\0')
202                         g_variant_builder_add(builder, "{sv}", RULE_NFLOG_PREFIX,
203                                         g_variant_new_string(rule->nflog_prefix));
204
205                 g_variant_builder_add(builder, "{sv}", RULE_NFLOG_RANGE,
206                                 g_variant_new_uint16(rule->nflog_range));
207
208                 g_variant_builder_add(builder, "{sv}", RULE_NFLOG_THRESHOLD,
209                                 g_variant_new_uint16(rule->nflog_threshold));
210                 break;
211         default:
212                 break;
213         }
214 }
215
216 static int __fw_add_chain(GDBusConnection *connection,
217                                 const char *chain)
218 {
219         int result = 0;
220         GVariant *message = NULL;
221
222         message = stc_manager_gdbus_call_sync(connection,
223                                               STC_FIREWALL_DBUS_SERVICE,
224                                               STC_FIREWALL_DBUS_CHAIN_PATH,
225                                               STC_FIREWALL_DBUS_CHAIN_INTERFACE,
226                                               STC_FIREWALL_DBUS_METHOD_ADD_CHAIN,
227                                               g_variant_new("(s)", chain));
228
229         if (message == NULL) {
230                 STC_LOGE("Failed to invoke dbus method");
231                 return STC_ERROR_FAIL;
232         }
233
234         g_variant_get(message, "(i)", &result);
235         STC_LOGD("Successfully added firewall chain [%d:%s]", result, chain);
236         g_variant_unref(message);
237
238         return STC_ERROR_NONE;
239 }
240
241 static int __fw6_add_chain(GDBusConnection *connection,
242                                  const char *chain)
243 {
244         int result = 0;
245         GVariant *message = NULL;
246
247         message = stc_manager_gdbus_call_sync(connection,
248                                               STC_FIREWALL_DBUS_SERVICE,
249                                               STC_FIREWALL_DBUS_CHAIN_PATH,
250                                               STC_FIREWALL_DBUS_CHAIN_INTERFACE,
251                                               STC_FIREWALL6_DBUS_METHOD_ADD_CHAIN,
252                                               g_variant_new("(s)", chain));
253
254         if (message == NULL) {
255                 STC_LOGE("Failed to invoke dbus method");
256                 return STC_ERROR_FAIL;
257         }
258
259         g_variant_get(message, "(i)", &result);
260         STC_LOGD("Successfully added firewall6 chain [%d:%s]", result, chain);
261         g_variant_unref(message);
262
263         return STC_ERROR_NONE;
264 }
265
266 static int __fw_remove_chain(GDBusConnection *connection,
267                                    const char *chain)
268 {
269         int result = 0;
270         GVariant *message = NULL;
271
272         message = stc_manager_gdbus_call_sync(connection,
273                                               STC_FIREWALL_DBUS_SERVICE,
274                                               STC_FIREWALL_DBUS_CHAIN_PATH,
275                                               STC_FIREWALL_DBUS_CHAIN_INTERFACE,
276                                               STC_FIREWALL_DBUS_METHOD_REMOVE_CHAIN,
277                                               g_variant_new("(s)", chain));
278
279         if (message == NULL) {
280                 STC_LOGE("Failed to invoke dbus method");
281                 return STC_ERROR_FAIL;
282         }
283
284         g_variant_get(message, "(i)", &result);
285         STC_LOGD("Successfully removed firewall chain [%d:%s]", result, chain);
286         g_variant_unref(message);
287
288         return STC_ERROR_NONE;
289 }
290
291 static int __fw6_remove_chain(GDBusConnection *connection,
292                                     const char *chain)
293 {
294         int result = 0;
295         GVariant *message = NULL;
296
297         message = stc_manager_gdbus_call_sync(connection,
298                                               STC_FIREWALL_DBUS_SERVICE,
299                                               STC_FIREWALL_DBUS_CHAIN_PATH,
300                                               STC_FIREWALL_DBUS_CHAIN_INTERFACE,
301                                               STC_FIREWALL6_DBUS_METHOD_REMOVE_CHAIN,
302                                               g_variant_new("(s)", chain));
303
304         if (message == NULL) {
305                 STC_LOGE("Failed to invoke dbus method");
306                 return STC_ERROR_FAIL;
307         }
308
309         g_variant_get(message, "(i)", &result);
310         STC_LOGD("Successfully removed firewall6 chain [%d:%s]", result, chain);
311         g_variant_unref(message);
312
313         return STC_ERROR_NONE;
314 }
315
316 static int __fw_flush_chain(GDBusConnection *connection,
317                                   const char *chain)
318 {
319         int result = 0;
320         GVariant *message = NULL;
321
322         message = stc_manager_gdbus_call_sync(connection,
323                                               STC_FIREWALL_DBUS_SERVICE,
324                                               STC_FIREWALL_DBUS_CHAIN_PATH,
325                                               STC_FIREWALL_DBUS_CHAIN_INTERFACE,
326                                               STC_FIREWALL_DBUS_METHOD_FLUSH_CHAIN,
327                                               g_variant_new("(s)", chain));
328
329         if (message == NULL) {
330                 STC_LOGE("Failed to invoke dbus method");
331                 return STC_ERROR_FAIL;
332         }
333
334         g_variant_get(message, "(i)", &result);
335         STC_LOGD("Successfully flushed firewall chain [%d:%s]", result, chain);
336         g_variant_unref(message);
337
338         return STC_ERROR_NONE;
339 }
340
341 static int __fw6_flush_chain(GDBusConnection *connection,
342                                    const char *chain)
343 {
344         int result = 0;
345         GVariant *message = NULL;
346
347         message = stc_manager_gdbus_call_sync(connection,
348                                               STC_FIREWALL_DBUS_SERVICE,
349                                               STC_FIREWALL_DBUS_CHAIN_PATH,
350                                               STC_FIREWALL_DBUS_CHAIN_INTERFACE,
351                                               STC_FIREWALL6_DBUS_METHOD_FLUSH_CHAIN,
352                                               g_variant_new("(s)", chain));
353
354         if (message == NULL) {
355                 STC_LOGE("Failed to invoke dbus method");
356                 return STC_ERROR_FAIL;
357         }
358
359         g_variant_get(message, "(i)", &result);
360         STC_LOGD("Successfully flushed firewall6 chain [%d:%s]", result, chain);
361         g_variant_unref(message);
362
363         return STC_ERROR_NONE;
364 }
365
366 static int __fw_set_chain(firewall_chain_s *chain)
367 {
368         stc_error_e ret = STC_ERROR_NONE;
369         firewall_rule_s rule;
370         memset(&rule, 0, sizeof(firewall_rule_s));
371
372         switch (chain->target) {
373         case STC_FW_CHAIN_TARGET_INPUT:
374                 rule.chain = g_strdup(FIREWALL_CHAIN_TARGET_IN);
375                 break;
376         case STC_FW_CHAIN_TARGET_OUTPUT:
377                 rule.chain = g_strdup(FIREWALL_CHAIN_TARGET_OUT);
378                 break;
379         default:
380                 return STC_ERROR_INVALID_PARAMETER;
381         }
382
383         rule.target_str = g_strdup(chain->chain);
384         ret = firewall_rule_insert(&rule);
385
386         g_free(rule.chain);
387         g_free(rule.target_str);
388
389         return ret;
390 }
391
392 static int __fw_unset_chain(firewall_chain_s *chain)
393 {
394         stc_error_e ret = STC_ERROR_NONE;
395         firewall_rule_s rule;
396         memset(&rule, 0, sizeof(firewall_rule_s));
397
398         switch (chain->target) {
399         case STC_FW_CHAIN_TARGET_INPUT:
400                 rule.chain = g_strdup(FIREWALL_CHAIN_TARGET_IN);
401                 break;
402         case STC_FW_CHAIN_TARGET_OUTPUT:
403                 rule.chain = g_strdup(FIREWALL_CHAIN_TARGET_OUT);
404                 break;
405         default:
406                 return STC_ERROR_INVALID_PARAMETER;
407         }
408
409         rule.target_str = g_strdup(chain->chain);
410         ret = firewall_rule_remove(&rule);
411
412         g_free(rule.chain);
413         g_free(rule.target_str);
414
415         return ret;
416 }
417
418 static int __fw_append_rule(GDBusConnection *connection,
419                                firewall_rule_s *rule)
420 {
421         int result = 0;
422         GVariantBuilder *builder = NULL;
423         GVariant *params = NULL;
424         GVariant *message = NULL;
425
426         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
427         __fw_add_rule_info_to_builder(builder, rule);
428         params = g_variant_new("(a{sv})", builder);
429         g_variant_builder_unref(builder);
430
431         message = stc_manager_gdbus_call_sync(connection,
432                                               STC_FIREWALL_DBUS_SERVICE,
433                                               STC_FIREWALL_DBUS_RULE_PATH,
434                                               STC_FIREWALL_DBUS_RULE_INTERFACE,
435                                               STC_FIREWALL_DBUS_METHOD_ADD_RULE,
436                                               params);
437
438         if (message == NULL) {
439                 STC_LOGE("Failed to invoke dbus method");
440                 return STC_ERROR_FAIL;
441         }
442
443         g_variant_get(message, "(i)", &result);
444         STC_LOGD("Successfully added firewall rule [%d:%s]",
445                                 result, rule->chain);
446         g_variant_unref(message);
447
448         return STC_ERROR_NONE;
449 }
450
451 static int __fw_insert_rule(GDBusConnection *connection,
452                                firewall_rule_s *rule)
453 {
454         int result = 0;
455         GVariantBuilder *builder = NULL;
456         GVariant *params = NULL;
457         GVariant *message = NULL;
458
459         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
460         __fw_add_rule_info_to_builder(builder, rule);
461         params = g_variant_new("(a{sv})", builder);
462         g_variant_builder_unref(builder);
463
464         message = stc_manager_gdbus_call_sync(connection,
465                                               STC_FIREWALL_DBUS_SERVICE,
466                                               STC_FIREWALL_DBUS_RULE_PATH,
467                                               STC_FIREWALL_DBUS_RULE_INTERFACE,
468                                               STC_FIREWALL_DBUS_METHOD_INSERT_RULE,
469                                               params);
470
471         if (message == NULL) {
472                 STC_LOGE("Failed to invoke dbus method");
473                 return STC_ERROR_FAIL;
474         }
475
476         g_variant_get(message, "(i)", &result);
477         STC_LOGD("Successfully inserted firewall rule [%d:%s]",
478                                 result, rule->chain);
479         g_variant_unref(message);
480
481         return STC_ERROR_NONE;
482 }
483
484 static int __fw6_append_rule(GDBusConnection *connection,
485                                 firewall_rule_s *rule)
486 {
487         int result = 0;
488         GVariantBuilder *builder = NULL;
489         GVariant *params = NULL;
490         GVariant *message = NULL;
491
492         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
493         __fw_add_rule_info_to_builder(builder, rule);
494         params = g_variant_new("(a{sv})", builder);
495         g_variant_builder_unref(builder);
496
497         message = stc_manager_gdbus_call_sync(connection,
498                                               STC_FIREWALL_DBUS_SERVICE,
499                                               STC_FIREWALL_DBUS_RULE_PATH,
500                                               STC_FIREWALL_DBUS_RULE_INTERFACE,
501                                               STC_FIREWALL6_DBUS_METHOD_ADD_RULE,
502                                               params);
503
504         if (message == NULL) {
505                 STC_LOGE("Failed to invoke dbus method");
506                 return STC_ERROR_FAIL;
507         }
508
509         g_variant_get(message, "(i)", &result);
510         STC_LOGD("Successfully added firewall6 rule [%d:%s]",
511                                 result, rule->chain);
512         g_variant_unref(message);
513
514         return STC_ERROR_NONE;
515 }
516
517 static int __fw6_insert_rule(GDBusConnection *connection,
518                                 firewall_rule_s *rule)
519 {
520         int result = 0;
521         GVariantBuilder *builder = NULL;
522         GVariant *params = NULL;
523         GVariant *message = NULL;
524
525         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
526         __fw_add_rule_info_to_builder(builder, rule);
527         params = g_variant_new("(a{sv})", builder);
528         g_variant_builder_unref(builder);
529
530         message = stc_manager_gdbus_call_sync(connection,
531                                               STC_FIREWALL_DBUS_SERVICE,
532                                               STC_FIREWALL_DBUS_RULE_PATH,
533                                               STC_FIREWALL_DBUS_RULE_INTERFACE,
534                                               STC_FIREWALL6_DBUS_METHOD_INSERT_RULE,
535                                               params);
536
537         if (message == NULL) {
538                 STC_LOGE("Failed to invoke dbus method");
539                 return STC_ERROR_FAIL;
540         }
541
542         g_variant_get(message, "(i)", &result);
543         STC_LOGD("Successfully inserted firewall6 rule [%d:%s]",
544                                 result, rule->chain);
545         g_variant_unref(message);
546
547         return STC_ERROR_NONE;
548 }
549
550 static int __fw_remove_rule(GDBusConnection *connection,
551                                   firewall_rule_s *rule)
552 {
553         int result = 0;
554         GVariantBuilder *builder = NULL;
555         GVariant *params = NULL;
556         GVariant *message = NULL;
557
558         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
559         __fw_add_rule_info_to_builder(builder, rule);
560         params = g_variant_new("(a{sv})", builder);
561         g_variant_builder_unref(builder);
562
563         message = stc_manager_gdbus_call_sync(connection,
564                                               STC_FIREWALL_DBUS_SERVICE,
565                                               STC_FIREWALL_DBUS_RULE_PATH,
566                                               STC_FIREWALL_DBUS_RULE_INTERFACE,
567                                               STC_FIREWALL_DBUS_METHOD_REMOVE_RULE,
568                                               params);
569
570         if (message == NULL) {
571                 STC_LOGE("Failed to invoke dbus method");
572                 return STC_ERROR_FAIL;
573         }
574
575         g_variant_get(message, "(i)", &result);
576         STC_LOGD("Successfully removed firewall rule [%d:%s]",
577                                 result, rule->chain);
578         g_variant_unref(message);
579
580         return STC_ERROR_NONE;
581 }
582
583 static int __fw6_remove_rule(GDBusConnection *connection,
584                                    firewall_rule_s *rule)
585 {
586         int result = 0;
587         GVariantBuilder *builder = NULL;
588         GVariant *params = NULL;
589         GVariant *message = NULL;
590
591         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
592         __fw_add_rule_info_to_builder(builder, rule);
593         params = g_variant_new("(a{sv})", builder);
594         g_variant_builder_unref(builder);
595
596         message = stc_manager_gdbus_call_sync(connection,
597                                               STC_FIREWALL_DBUS_SERVICE,
598                                               STC_FIREWALL_DBUS_RULE_PATH,
599                                               STC_FIREWALL_DBUS_RULE_INTERFACE,
600                                               STC_FIREWALL6_DBUS_METHOD_REMOVE_RULE,
601                                               params);
602
603         if (message == NULL) {
604                 STC_LOGE("Failed to invoke dbus method");
605                 return STC_ERROR_FAIL;
606         }
607
608         g_variant_get(message, "(i)", &result);
609         STC_LOGD("Successfully removed firewall6 rule [%d:%s]",
610                                 result, rule->chain);
611         g_variant_unref(message);
612
613         return STC_ERROR_NONE;
614 }
615
616 API stc_error_e firewall_chain_add(firewall_chain_s *chain)
617 {
618         __STC_LOG_FUNC_ENTER__;
619
620         stc_error_e ret = STC_ERROR_NONE;
621         stc_s *stc = stc_get_manager();
622
623         if (!stc || !stc->connection) {
624                 __STC_LOG_FUNC_EXIT__;
625                 return STC_ERROR_UNINITIALIZED;
626         }
627
628         ret = __fw_add_chain(stc->connection, chain->chain);
629         if (ret != STC_ERROR_NONE) {
630                 __STC_LOG_FUNC_EXIT__;
631                 return ret;
632         }
633
634         ret = __fw6_add_chain(stc->connection, chain->chain);
635         if (ret != STC_ERROR_NONE) {
636                 __STC_LOG_FUNC_EXIT__;
637                 return ret;
638         }
639
640         __STC_LOG_FUNC_EXIT__;
641         return ret;
642 }
643
644 API stc_error_e firewall_chain_remove(firewall_chain_s *chain)
645 {
646         __STC_LOG_FUNC_ENTER__;
647
648         stc_error_e ret = STC_ERROR_NONE;
649         stc_s *stc = stc_get_manager();
650
651         if (!stc || !stc->connection) {
652                 __STC_LOG_FUNC_EXIT__;
653                 return STC_ERROR_UNINITIALIZED;
654         }
655
656         ret = __fw_remove_chain(stc->connection, chain->chain);
657         if (ret != STC_ERROR_NONE) {
658                 __STC_LOG_FUNC_EXIT__;
659                 return ret;
660         }
661
662         ret = __fw6_remove_chain(stc->connection, chain->chain);
663         if (ret != STC_ERROR_NONE) {
664                 __STC_LOG_FUNC_EXIT__;
665                 return ret;
666         }
667
668         __STC_LOG_FUNC_EXIT__;
669         return ret;
670 }
671
672 stc_error_e firewall_chain_flush(firewall_chain_s *chain)
673 {
674         __STC_LOG_FUNC_ENTER__;
675
676         stc_error_e ret = STC_ERROR_NONE;
677         stc_s *stc = stc_get_manager();
678
679         if (!stc || !stc->connection) {
680                 __STC_LOG_FUNC_EXIT__;
681                 return STC_ERROR_UNINITIALIZED;
682         }
683
684         ret = __fw_flush_chain(stc->connection, chain->chain);
685         if (ret != STC_ERROR_NONE) {
686                 __STC_LOG_FUNC_EXIT__;
687                 return ret;
688         }
689
690         ret = __fw6_flush_chain(stc->connection, chain->chain);
691         if (ret != STC_ERROR_NONE) {
692                 __STC_LOG_FUNC_EXIT__;
693                 return ret;
694         }
695
696         __STC_LOG_FUNC_EXIT__;
697         return ret;
698 }
699
700 API stc_error_e firewall_chain_set(firewall_chain_s *chain)
701 {
702         __STC_LOG_FUNC_ENTER__;
703
704         stc_error_e ret = STC_ERROR_NONE;
705         ret = __fw_set_chain(chain);
706
707         __STC_LOG_FUNC_EXIT__;
708         return ret;
709 }
710
711 API stc_error_e firewall_chain_unset(firewall_chain_s *chain)
712 {
713         __STC_LOG_FUNC_ENTER__;
714
715         stc_error_e ret = STC_ERROR_NONE;
716         ret = __fw_unset_chain(chain);
717
718         __STC_LOG_FUNC_EXIT__;
719         return ret;
720 }
721
722 API stc_error_e firewall_rule_append(firewall_rule_s *rule)
723 {
724         stc_error_e ret = STC_ERROR_NONE;
725         stc_s *stc = stc_get_manager();
726
727         if (!stc || !stc->connection) {
728                 __STC_LOG_FUNC_EXIT__;
729                 return STC_ERROR_UNINITIALIZED;
730         }
731
732         switch (rule->family) {
733         case STC_FW_FAMILY_V4:
734                 ret = __fw_append_rule(stc->connection, rule);
735                 if (ret != STC_ERROR_NONE) {
736                         __STC_LOG_FUNC_EXIT__;
737                         return ret;
738                 }
739                 break;
740         case STC_FW_FAMILY_V6:
741                 ret = __fw6_append_rule(stc->connection, rule);
742                 if (ret != STC_ERROR_NONE) {
743                         __STC_LOG_FUNC_EXIT__;
744                         return ret;
745                 }
746                 break;
747         default:
748                 ret = __fw_append_rule(stc->connection, rule);
749                 if (ret != STC_ERROR_NONE) {
750                         __STC_LOG_FUNC_EXIT__;
751                         return ret;
752                 }
753
754                 ret = __fw6_append_rule(stc->connection, rule);
755                 if (ret != STC_ERROR_NONE) {
756                         __STC_LOG_FUNC_EXIT__;
757                         return ret;
758                 }
759                 break;
760         }
761
762         return ret;
763 }
764
765 stc_error_e firewall_rule_insert(firewall_rule_s *rule)
766 {
767         stc_error_e ret = STC_ERROR_NONE;
768         stc_s *stc = stc_get_manager();
769
770         if (!stc || !stc->connection) {
771                 __STC_LOG_FUNC_EXIT__;
772                 return STC_ERROR_UNINITIALIZED;
773         }
774
775         switch (rule->family) {
776         case STC_FW_FAMILY_V4:
777                 ret = __fw_insert_rule(stc->connection, rule);
778                 if (ret != STC_ERROR_NONE) {
779                         __STC_LOG_FUNC_EXIT__;
780                         return ret;
781                 }
782                 break;
783         case STC_FW_FAMILY_V6:
784                 ret = __fw6_insert_rule(stc->connection, rule);
785                 if (ret != STC_ERROR_NONE) {
786                         __STC_LOG_FUNC_EXIT__;
787                         return ret;
788                 }
789                 break;
790         default:
791                 ret = __fw_insert_rule(stc->connection, rule);
792                 if (ret != STC_ERROR_NONE) {
793                         __STC_LOG_FUNC_EXIT__;
794                         return ret;
795                 }
796
797                 ret = __fw6_insert_rule(stc->connection, rule);
798                 if (ret != STC_ERROR_NONE) {
799                         __STC_LOG_FUNC_EXIT__;
800                         return ret;
801                 }
802                 break;
803         }
804
805         return ret;
806 }
807
808 stc_error_e firewall_rule_remove(firewall_rule_s *rule)
809 {
810         stc_error_e ret = STC_ERROR_NONE;
811         stc_s *stc = stc_get_manager();
812
813         if (!stc || !stc->connection) {
814                 __STC_LOG_FUNC_EXIT__;
815                 return STC_ERROR_UNINITIALIZED;
816         }
817
818         switch (rule->family) {
819         case STC_FW_FAMILY_V4:
820                 ret = __fw_remove_rule(stc->connection, rule);
821                 if (ret != STC_ERROR_NONE) {
822                         __STC_LOG_FUNC_EXIT__;
823                         return ret;
824                 }
825                 break;
826         case STC_FW_FAMILY_V6:
827                 ret = __fw6_remove_rule(stc->connection, rule);
828                 if (ret != STC_ERROR_NONE) {
829                         __STC_LOG_FUNC_EXIT__;
830                         return ret;
831                 }
832                 break;
833         default:
834                 ret = __fw_remove_rule(stc->connection, rule);
835                 if (ret != STC_ERROR_NONE) {
836                         __STC_LOG_FUNC_EXIT__;
837                         return ret;
838                 }
839
840                 ret = __fw6_remove_rule(stc->connection, rule);
841                 if (ret != STC_ERROR_NONE) {
842                         __STC_LOG_FUNC_EXIT__;
843                         return ret;
844                 }
845                 break;
846         }
847
848         return ret;
849 }