2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "stc-manager-gdbus.h"
18 #include "helper-iptables.h"
20 #define STC_IPTABLES_DBUS_SERVICE "net.stc.iptables"
21 #define STC_IPTABLES_DBUS_RULE_INTERFACE STC_IPTABLES_DBUS_SERVICE ".rule"
22 #define STC_IPTABLES_DBUS_CHAIN_INTERFACE STC_IPTABLES_DBUS_SERVICE ".chain"
23 #define STC_IPTABLES_DBUS_RULE_PATH "/net/stc/iptables/rule"
24 #define STC_IPTABLES_DBUS_CHAIN_PATH "/net/stc/iptables/chain"
25 #define STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN "IptAddChain"
26 #define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN "IptRemoveChain"
27 #define STC_IPTABLES_DBUS_METHOD_IPT_FLUSH_CHAIN "IptFlushChain"
28 #define STC_IPTABLES_DBUS_METHOD_IP6T_ADD_CHAIN "Ip6tAddChain"
29 #define STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_CHAIN "Ip6tRemoveChain"
30 #define STC_IPTABLES_DBUS_METHOD_IP6T_FLUSH_CHAIN "Ip6tFlushChain"
31 #define STC_IPTABLES_DBUS_METHOD_IPT_ADD_RULE "IptAddRule"
32 #define STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE "IptRemoveRule"
33 #define STC_IPTABLES_DBUS_METHOD_IP6T_ADD_RULE "Ip6tAddRule"
34 #define STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_RULE "Ip6tRemoveRule"
36 #define RULE_CHAIN "chain"
37 #define RULE_DIRECTION "direction"
38 #define RULE_IFNAME "ifname"
39 #define RULE_CGROUP "cgroup"
40 #define RULE_NFACCT "nfacct"
41 #define RULE_TARGET "target"
43 static void __add_rule_info_to_builder(GVariantBuilder *builder,
44 iptables_rule_s *rule)
46 if (builder == NULL || rule == NULL)
47 return; //LCOV_EXCL_LINE
49 g_variant_builder_add(builder, "{sv}", RULE_CHAIN,
50 g_variant_new_string(rule->chain));
52 g_variant_builder_add(builder, "{sv}", RULE_DIRECTION,
53 g_variant_new_uint16(rule->direction));
56 g_variant_builder_add(builder, "{sv}", RULE_IFNAME,
57 g_variant_new_string(rule->ifname));
59 if (rule->classid > 0)
60 g_variant_builder_add(builder, "{sv}", RULE_CGROUP,
61 g_variant_new_uint32(rule->classid));
63 if (rule->nfacct_name)
64 g_variant_builder_add(builder, "{sv}", RULE_NFACCT,
65 g_variant_new_string(rule->nfacct_name));
68 g_variant_builder_add(builder, "{sv}", RULE_TARGET,
69 g_variant_new_string(rule->target));
73 static int __iptables_rule_add(GDBusConnection *connection,
74 iptables_rule_s *rule)
77 GVariantBuilder *builder = NULL;
78 GVariant *params = NULL;
79 GVariant *message = NULL;
81 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
82 __add_rule_info_to_builder(builder, rule);
83 params = g_variant_new("(a{sv})", builder);
84 g_variant_builder_unref(builder);
86 message = stc_manager_gdbus_call_sync(connection,
87 STC_IPTABLES_DBUS_SERVICE,
88 STC_IPTABLES_DBUS_RULE_PATH,
89 STC_IPTABLES_DBUS_RULE_INTERFACE,
90 STC_IPTABLES_DBUS_METHOD_IPT_ADD_RULE,
93 if (message == NULL) {
94 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
95 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
98 g_variant_get(message, "(i)", &result);
100 STC_LOGD("Successfully Add Rule [%d:%s]", result, rule->nfacct_name);
101 g_variant_unref(message);
103 return STC_ERROR_NONE;
106 static int __iptables_rule_remove(GDBusConnection *connection,
107 iptables_rule_s *rule)
110 GVariantBuilder *builder = NULL;
111 GVariant *params = NULL;
112 GVariant *message = NULL;
114 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
115 __add_rule_info_to_builder(builder, rule);
116 params = g_variant_new("(a{sv})", builder);
117 g_variant_builder_unref(builder);
119 message = stc_manager_gdbus_call_sync(connection,
120 STC_IPTABLES_DBUS_SERVICE,
121 STC_IPTABLES_DBUS_RULE_PATH,
122 STC_IPTABLES_DBUS_RULE_INTERFACE,
123 STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE,
126 if (message == NULL) {
127 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
128 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
131 g_variant_get(message, "(i)", &result);
133 STC_LOGD("Successfully Remove Rule [%d:%s]", result, rule->nfacct_name);
134 g_variant_unref(message);
136 return STC_ERROR_NONE;
139 static int __ip6tables_rule_add(GDBusConnection *connection,
140 iptables_rule_s *rule)
143 GVariantBuilder *builder = NULL;
144 GVariant *params = NULL;
145 GVariant *message = NULL;
147 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
148 __add_rule_info_to_builder(builder, rule);
149 params = g_variant_new("(a{sv})", builder);
150 g_variant_builder_unref(builder);
152 message = stc_manager_gdbus_call_sync(connection,
153 STC_IPTABLES_DBUS_SERVICE,
154 STC_IPTABLES_DBUS_RULE_PATH,
155 STC_IPTABLES_DBUS_RULE_INTERFACE,
156 STC_IPTABLES_DBUS_METHOD_IP6T_ADD_RULE,
159 if (message == NULL) {
160 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
161 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
164 g_variant_get(message, "(i)", &result);
166 STC_LOGD("Successfully Add 6 Rule [%d:%s]", result, rule->nfacct_name);
167 g_variant_unref(message);
169 return STC_ERROR_NONE;
172 static int __ip6tables_rule_remove(GDBusConnection *connection,
173 iptables_rule_s *rule)
176 GVariantBuilder *builder = NULL;
177 GVariant *params = NULL;
178 GVariant *message = NULL;
180 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
181 __add_rule_info_to_builder(builder, rule);
182 params = g_variant_new("(a{sv})", builder);
183 g_variant_builder_unref(builder);
185 message = stc_manager_gdbus_call_sync(connection,
186 STC_IPTABLES_DBUS_SERVICE,
187 STC_IPTABLES_DBUS_RULE_PATH,
188 STC_IPTABLES_DBUS_RULE_INTERFACE,
189 STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_RULE,
192 if (message == NULL) {
193 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
194 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
197 g_variant_get(message, "(i)", &result);
199 STC_LOGD("Successfully Remove 6 Rule [%d:%s]", result, rule->nfacct_name);
200 g_variant_unref(message);
202 return STC_ERROR_NONE;
205 static int __iptables_add_chain(GDBusConnection *connection,
209 GVariant *message = NULL;
211 message = stc_manager_gdbus_call_sync(connection,
212 STC_IPTABLES_DBUS_SERVICE,
213 STC_IPTABLES_DBUS_CHAIN_PATH,
214 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
215 STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN,
216 g_variant_new("(s)", chain));
218 if (message == NULL) {
219 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
220 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
223 g_variant_get(message, "(i)", &result);
224 STC_LOGD("Successfully added ipv4 chain [%d:%s]", result, chain);
225 g_variant_unref(message);
227 return STC_ERROR_NONE;
230 static int __ip6tables_add_chain(GDBusConnection *connection,
234 GVariant *message = NULL;
236 message = stc_manager_gdbus_call_sync(connection,
237 STC_IPTABLES_DBUS_SERVICE,
238 STC_IPTABLES_DBUS_CHAIN_PATH,
239 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
240 STC_IPTABLES_DBUS_METHOD_IP6T_ADD_CHAIN,
241 g_variant_new("(s)", chain));
243 if (message == NULL) {
244 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
245 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
248 g_variant_get(message, "(i)", &result);
249 STC_LOGD("Successfully added ipv6 chain [%d:%s]", result, chain);
250 g_variant_unref(message);
252 return STC_ERROR_NONE;
255 static int __iptables_remove_chain(GDBusConnection *connection,
259 GVariant *message = NULL;
261 message = stc_manager_gdbus_call_sync(connection,
262 STC_IPTABLES_DBUS_SERVICE,
263 STC_IPTABLES_DBUS_CHAIN_PATH,
264 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
265 STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN,
266 g_variant_new("(s)", chain));
268 if (message == NULL) {
269 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
270 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
273 g_variant_get(message, "(i)", &result);
274 STC_LOGD("Successfully removed ipv4 chain [%d:%s]", result, chain);
275 g_variant_unref(message);
277 return STC_ERROR_NONE;
280 static int __ip6tables_remove_chain(GDBusConnection *connection,
284 GVariant *message = NULL;
286 message = stc_manager_gdbus_call_sync(connection,
287 STC_IPTABLES_DBUS_SERVICE,
288 STC_IPTABLES_DBUS_CHAIN_PATH,
289 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
290 STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_CHAIN,
291 g_variant_new("(s)", chain));
293 if (message == NULL) {
294 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
295 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
298 g_variant_get(message, "(i)", &result);
299 STC_LOGD("Successfully removed ipv6 chain [%d:%s]", result, chain);
300 g_variant_unref(message);
302 return STC_ERROR_NONE;
305 static int __iptables_flush_chain(GDBusConnection *connection,
309 GVariant *message = NULL;
311 message = stc_manager_gdbus_call_sync(connection,
312 STC_IPTABLES_DBUS_SERVICE,
313 STC_IPTABLES_DBUS_CHAIN_PATH,
314 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
315 STC_IPTABLES_DBUS_METHOD_IPT_FLUSH_CHAIN,
316 g_variant_new("(s)", chain));
318 if (message == NULL) {
319 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
320 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
323 g_variant_get(message, "(i)", &result);
324 STC_LOGD("Successfully flushed ipv4 chain [%d:%s]", result, chain);
325 g_variant_unref(message);
327 return STC_ERROR_NONE;
330 static int __ip6tables_flush_chain(GDBusConnection *connection,
334 GVariant *message = NULL;
336 message = stc_manager_gdbus_call_sync(connection,
337 STC_IPTABLES_DBUS_SERVICE,
338 STC_IPTABLES_DBUS_CHAIN_PATH,
339 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
340 STC_IPTABLES_DBUS_METHOD_IP6T_FLUSH_CHAIN,
341 g_variant_new("(s)", chain));
343 if (message == NULL) {
344 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
345 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
348 g_variant_get(message, "(i)", &result);
349 STC_LOGD("Successfully flushed ipv6 chain [%d:%s]", result, chain);
350 g_variant_unref(message);
352 return STC_ERROR_NONE;
355 static int __iptables_add_chain_jump_rule(const char *chain,
358 stc_error_e ret = STC_ERROR_NONE;
359 iptables_rule_s iptables_rule;
360 memset(&iptables_rule, 0, sizeof(iptables_rule_s));
362 iptables_rule.target = g_strdup(target);
363 iptables_rule.chain = g_strdup(chain);
365 ret = iptables_add(&iptables_rule, IP_TYPE_IPV4_IPV6);
367 g_free(iptables_rule.target);
368 g_free(iptables_rule.chain);
373 stc_error_e iptables_add(iptables_rule_s *rule, iptables_ip_type_e iptype)
375 stc_error_e ret = STC_ERROR_NONE;
376 stc_s *stc = stc_get_manager();
378 if (!stc || !stc->connection)
379 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
381 if (iptype == IP_TYPE_IPV4 ||
382 iptype == IP_TYPE_IPV4_IPV6) {
383 ret = __iptables_rule_add(stc->connection, rule);
384 if (ret != STC_ERROR_NONE)
385 goto done; //LCOV_EXCL_LINE
388 if (iptype == IP_TYPE_IPV6 ||
389 iptype == IP_TYPE_IPV4_IPV6)
390 ret = __ip6tables_rule_add(stc->connection, rule);
396 stc_error_e iptables_remove(iptables_rule_s *rule, iptables_ip_type_e iptype)
398 stc_error_e ret = STC_ERROR_NONE;
399 stc_s *stc = stc_get_manager();
401 if (!stc || !stc->connection)
402 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
404 if (iptype == IP_TYPE_IPV4 ||
405 iptype == IP_TYPE_IPV4_IPV6) {
406 ret = __iptables_rule_remove(stc->connection, rule);
407 if (ret != STC_ERROR_NONE)
408 goto done; //LCOV_EXCL_LINE
411 if (iptype == IP_TYPE_IPV6 ||
412 iptype == IP_TYPE_IPV4_IPV6)
413 ret = __ip6tables_rule_remove(stc->connection, rule);
419 stc_error_e iptables_flush_chains(void)
421 stc_error_e ret = STC_ERROR_NONE;
422 stc_s *stc = stc_get_manager();
424 if (!stc || !stc->connection)
425 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
427 ret = __iptables_flush_chain(stc->connection, STC_IN_CHAIN);
428 if (ret != STC_ERROR_NONE)
429 goto done; //LCOV_EXCL_LINE
431 ret = __iptables_flush_chain(stc->connection, STC_OUT_CHAIN);
432 if (ret != STC_ERROR_NONE)
433 goto done; //LCOV_EXCL_LINE
435 ret = __iptables_flush_chain(stc->connection, STC_FRWD_CHAIN);
436 if (ret != STC_ERROR_NONE)
437 goto done; //LCOV_EXCL_LINE
439 ret = __ip6tables_flush_chain(stc->connection, STC_IN_CHAIN);
440 if (ret != STC_ERROR_NONE)
441 goto done; //LCOV_EXCL_LINE
443 ret = __ip6tables_flush_chain(stc->connection, STC_OUT_CHAIN);
444 if (ret != STC_ERROR_NONE)
445 goto done; //LCOV_EXCL_LINE
447 ret = __ip6tables_flush_chain(stc->connection, STC_FRWD_CHAIN);
452 stc_error_e iptables_init(void)
454 __STC_LOG_FUNC_ENTER__;
456 stc_error_e ret = STC_ERROR_NONE;
457 stc_s *stc = stc_get_manager();
459 if (!stc || !stc->connection) {
460 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
461 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
464 ret = __iptables_add_chain(stc->connection, STC_IN_CHAIN);
465 if (ret != STC_ERROR_NONE) {
466 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
467 goto done; //LCOV_EXCL_LINE
470 ret = __iptables_add_chain(stc->connection, STC_OUT_CHAIN);
471 if (ret != STC_ERROR_NONE) {
472 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
473 goto done; //LCOV_EXCL_LINE
476 ret = __iptables_add_chain(stc->connection, STC_FRWD_CHAIN);
477 if (ret != STC_ERROR_NONE) {
478 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
479 goto done; //LCOV_EXCL_LINE
482 ret = __ip6tables_add_chain(stc->connection, STC_IN_CHAIN);
483 if (ret != STC_ERROR_NONE) {
484 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
485 goto done; //LCOV_EXCL_LINE
488 ret = __ip6tables_add_chain(stc->connection, STC_OUT_CHAIN);
489 if (ret != STC_ERROR_NONE) {
490 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
491 goto done; //LCOV_EXCL_LINE
494 ret = __ip6tables_add_chain(stc->connection, STC_FRWD_CHAIN);
495 if (ret != STC_ERROR_NONE) {
496 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
497 goto done; //LCOV_EXCL_LINE
500 ret = __iptables_add_chain_jump_rule("INPUT", STC_IN_CHAIN);
501 if (ret != STC_ERROR_NONE) {
502 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
503 goto done; //LCOV_EXCL_LINE
506 ret = __iptables_add_chain_jump_rule("OUTPUT", STC_OUT_CHAIN);
507 if (ret != STC_ERROR_NONE) {
508 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
509 goto done; //LCOV_EXCL_LINE
512 ret = __iptables_add_chain_jump_rule("FORWARD", STC_FRWD_CHAIN);
517 stc_error_e iptables_deinit(void)
519 __STC_LOG_FUNC_ENTER__;
521 stc_error_e ret = STC_ERROR_NONE;
522 stc_s *stc = stc_get_manager();
524 if (!stc || !stc->connection) {
525 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
526 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
529 ret = __iptables_remove_chain(stc->connection, STC_IN_CHAIN);
530 if (ret != STC_ERROR_NONE) {
531 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
532 goto done; //LCOV_EXCL_LINE
535 ret = __iptables_remove_chain(stc->connection, STC_OUT_CHAIN);
536 if (ret != STC_ERROR_NONE) {
537 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
538 goto done; //LCOV_EXCL_LINE
541 ret = __iptables_remove_chain(stc->connection, STC_FRWD_CHAIN);
542 if (ret != STC_ERROR_NONE) {
543 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
544 goto done; //LCOV_EXCL_LINE
547 ret = __ip6tables_remove_chain(stc->connection, STC_IN_CHAIN);
548 if (ret != STC_ERROR_NONE) {
549 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
550 goto done; //LCOV_EXCL_LINE
553 ret = __ip6tables_remove_chain(stc->connection, STC_OUT_CHAIN);
554 if (ret != STC_ERROR_NONE) {
555 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
556 goto done; //LCOV_EXCL_LINE
559 ret = __ip6tables_remove_chain(stc->connection, STC_FRWD_CHAIN);