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_TYPE "type"
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_TYPE,
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);
99 STC_LOGD("Successfully Add Rule [%d:%s]", result, rule->nfacct_name);
100 g_variant_unref(message);
102 return STC_ERROR_NONE;
105 static int __iptables_rule_remove(GDBusConnection *connection,
106 iptables_rule_s *rule)
109 GVariantBuilder *builder = NULL;
110 GVariant *params = NULL;
111 GVariant *message = NULL;
113 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
114 __add_rule_info_to_builder(builder, rule);
115 params = g_variant_new("(a{sv})", builder);
116 g_variant_builder_unref(builder);
118 message = stc_manager_gdbus_call_sync(connection,
119 STC_IPTABLES_DBUS_SERVICE,
120 STC_IPTABLES_DBUS_RULE_PATH,
121 STC_IPTABLES_DBUS_RULE_INTERFACE,
122 STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_RULE,
125 if (message == NULL) {
126 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
127 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
130 g_variant_get(message, "(i)", &result);
131 STC_LOGD("Successfully Remove Rule [%d:%s]", result, rule->nfacct_name);
132 g_variant_unref(message);
134 return STC_ERROR_NONE;
137 static int __ip6tables_rule_add(GDBusConnection *connection,
138 iptables_rule_s *rule)
141 GVariantBuilder *builder = NULL;
142 GVariant *params = NULL;
143 GVariant *message = NULL;
145 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
146 __add_rule_info_to_builder(builder, rule);
147 params = g_variant_new("(a{sv})", builder);
148 g_variant_builder_unref(builder);
150 message = stc_manager_gdbus_call_sync(connection,
151 STC_IPTABLES_DBUS_SERVICE,
152 STC_IPTABLES_DBUS_RULE_PATH,
153 STC_IPTABLES_DBUS_RULE_INTERFACE,
154 STC_IPTABLES_DBUS_METHOD_IP6T_ADD_RULE,
157 if (message == NULL) {
158 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
159 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
162 g_variant_get(message, "(i)", &result);
163 STC_LOGD("Successfully Add 6 Rule [%d:%s]", result, rule->nfacct_name);
164 g_variant_unref(message);
166 return STC_ERROR_NONE;
169 static int __ip6tables_rule_remove(GDBusConnection *connection,
170 iptables_rule_s *rule)
173 GVariantBuilder *builder = NULL;
174 GVariant *params = NULL;
175 GVariant *message = NULL;
177 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
178 __add_rule_info_to_builder(builder, rule);
179 params = g_variant_new("(a{sv})", builder);
180 g_variant_builder_unref(builder);
182 message = stc_manager_gdbus_call_sync(connection,
183 STC_IPTABLES_DBUS_SERVICE,
184 STC_IPTABLES_DBUS_RULE_PATH,
185 STC_IPTABLES_DBUS_RULE_INTERFACE,
186 STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_RULE,
189 if (message == NULL) {
190 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
191 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
194 g_variant_get(message, "(i)", &result);
195 STC_LOGD("Successfully Remove 6 Rule [%d:%s]", result, rule->nfacct_name);
196 g_variant_unref(message);
198 return STC_ERROR_NONE;
201 static int __iptables_add_chain(GDBusConnection *connection,
205 GVariant *message = NULL;
207 message = stc_manager_gdbus_call_sync(connection,
208 STC_IPTABLES_DBUS_SERVICE,
209 STC_IPTABLES_DBUS_CHAIN_PATH,
210 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
211 STC_IPTABLES_DBUS_METHOD_IPT_ADD_CHAIN,
212 g_variant_new("(s)", chain));
214 if (message == NULL) {
215 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
216 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
219 g_variant_get(message, "(i)", &result);
220 STC_LOGD("Successfully added ipv4 chain [%d:%s]", result, chain);
221 g_variant_unref(message);
223 return STC_ERROR_NONE;
226 static int __ip6tables_add_chain(GDBusConnection *connection,
230 GVariant *message = NULL;
232 message = stc_manager_gdbus_call_sync(connection,
233 STC_IPTABLES_DBUS_SERVICE,
234 STC_IPTABLES_DBUS_CHAIN_PATH,
235 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
236 STC_IPTABLES_DBUS_METHOD_IP6T_ADD_CHAIN,
237 g_variant_new("(s)", chain));
239 if (message == NULL) {
240 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
241 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
244 g_variant_get(message, "(i)", &result);
245 STC_LOGD("Successfully added ipv6 chain [%d:%s]", result, chain);
246 g_variant_unref(message);
248 return STC_ERROR_NONE;
251 static int __iptables_remove_chain(GDBusConnection *connection,
255 GVariant *message = NULL;
257 message = stc_manager_gdbus_call_sync(connection,
258 STC_IPTABLES_DBUS_SERVICE,
259 STC_IPTABLES_DBUS_CHAIN_PATH,
260 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
261 STC_IPTABLES_DBUS_METHOD_IPT_REMOVE_CHAIN,
262 g_variant_new("(s)", chain));
264 if (message == NULL) {
265 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
266 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
269 g_variant_get(message, "(i)", &result);
270 STC_LOGD("Successfully removed ipv4 chain [%d:%s]", result, chain);
271 g_variant_unref(message);
273 return STC_ERROR_NONE;
276 static int __ip6tables_remove_chain(GDBusConnection *connection,
280 GVariant *message = NULL;
282 message = stc_manager_gdbus_call_sync(connection,
283 STC_IPTABLES_DBUS_SERVICE,
284 STC_IPTABLES_DBUS_CHAIN_PATH,
285 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
286 STC_IPTABLES_DBUS_METHOD_IP6T_REMOVE_CHAIN,
287 g_variant_new("(s)", chain));
289 if (message == NULL) {
290 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
291 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
294 g_variant_get(message, "(i)", &result);
295 STC_LOGD("Successfully removed ipv6 chain [%d:%s]", result, chain);
296 g_variant_unref(message);
298 return STC_ERROR_NONE;
301 static int __iptables_flush_chain(GDBusConnection *connection,
305 GVariant *message = NULL;
307 message = stc_manager_gdbus_call_sync(connection,
308 STC_IPTABLES_DBUS_SERVICE,
309 STC_IPTABLES_DBUS_CHAIN_PATH,
310 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
311 STC_IPTABLES_DBUS_METHOD_IPT_FLUSH_CHAIN,
312 g_variant_new("(s)", chain));
314 if (message == NULL) {
315 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
316 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
319 g_variant_get(message, "(i)", &result);
320 STC_LOGD("Successfully flushed ipv4 chain [%d:%s]", result, chain);
321 g_variant_unref(message);
323 return STC_ERROR_NONE;
326 static int __ip6tables_flush_chain(GDBusConnection *connection,
330 GVariant *message = NULL;
332 message = stc_manager_gdbus_call_sync(connection,
333 STC_IPTABLES_DBUS_SERVICE,
334 STC_IPTABLES_DBUS_CHAIN_PATH,
335 STC_IPTABLES_DBUS_CHAIN_INTERFACE,
336 STC_IPTABLES_DBUS_METHOD_IP6T_FLUSH_CHAIN,
337 g_variant_new("(s)", chain));
339 if (message == NULL) {
340 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
341 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
344 g_variant_get(message, "(i)", &result);
345 STC_LOGD("Successfully flushed ipv6 chain [%d:%s]", result, chain);
346 g_variant_unref(message);
348 return STC_ERROR_NONE;
351 static int __iptables_add_chain_jump_rule(const char *chain,
354 stc_error_e ret = STC_ERROR_NONE;
355 iptables_rule_s iptables_rule;
356 memset(&iptables_rule, 0, sizeof(iptables_rule_s));
358 iptables_rule.target = g_strdup(target);
359 iptables_rule.chain = g_strdup(chain);
361 ret = iptables_add(&iptables_rule, IP_TYPE_IPV4_IPV6);
363 g_free(iptables_rule.target);
364 g_free(iptables_rule.chain);
369 stc_error_e iptables_add(iptables_rule_s *rule, iptables_ip_type_e iptype)
371 stc_error_e ret = STC_ERROR_NONE;
372 stc_s *stc = stc_get_manager();
374 if (!stc || !stc->connection)
375 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
377 if (iptype == IP_TYPE_IPV4 ||
378 iptype == IP_TYPE_IPV4_IPV6) {
379 ret = __iptables_rule_add(stc->connection, rule);
380 if (ret != STC_ERROR_NONE)
381 goto done; //LCOV_EXCL_LINE
384 if (iptype == IP_TYPE_IPV6 ||
385 iptype == IP_TYPE_IPV4_IPV6)
386 ret = __ip6tables_rule_add(stc->connection, rule);
392 stc_error_e iptables_remove(iptables_rule_s *rule, iptables_ip_type_e iptype)
394 stc_error_e ret = STC_ERROR_NONE;
395 stc_s *stc = stc_get_manager();
397 if (!stc || !stc->connection)
398 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
400 if (iptype == IP_TYPE_IPV4 ||
401 iptype == IP_TYPE_IPV4_IPV6) {
402 ret = __iptables_rule_remove(stc->connection, rule);
403 if (ret != STC_ERROR_NONE)
404 goto done; //LCOV_EXCL_LINE
407 if (iptype == IP_TYPE_IPV6 ||
408 iptype == IP_TYPE_IPV4_IPV6)
409 ret = __ip6tables_rule_remove(stc->connection, rule);
415 stc_error_e iptables_flush_chains(void)
417 stc_error_e ret = STC_ERROR_NONE;
418 stc_s *stc = stc_get_manager();
420 if (!stc || !stc->connection)
421 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
423 ret = __iptables_flush_chain(stc->connection, STC_IN_CHAIN);
424 if (ret != STC_ERROR_NONE)
425 goto done; //LCOV_EXCL_LINE
427 ret = __iptables_flush_chain(stc->connection, STC_OUT_CHAIN);
428 if (ret != STC_ERROR_NONE)
429 goto done; //LCOV_EXCL_LINE
431 ret = __iptables_flush_chain(stc->connection, STC_FRWD_CHAIN);
432 if (ret != STC_ERROR_NONE)
433 goto done; //LCOV_EXCL_LINE
435 ret = __ip6tables_flush_chain(stc->connection, STC_IN_CHAIN);
436 if (ret != STC_ERROR_NONE)
437 goto done; //LCOV_EXCL_LINE
439 ret = __ip6tables_flush_chain(stc->connection, STC_OUT_CHAIN);
440 if (ret != STC_ERROR_NONE)
441 goto done; //LCOV_EXCL_LINE
443 ret = __ip6tables_flush_chain(stc->connection, STC_FRWD_CHAIN);
448 stc_error_e iptables_init(void)
450 __STC_LOG_FUNC_ENTER__;
452 stc_error_e ret = STC_ERROR_NONE;
453 stc_s *stc = stc_get_manager();
455 if (!stc || !stc->connection) {
456 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
457 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
460 ret = __iptables_add_chain(stc->connection, STC_IN_CHAIN);
461 if (ret != STC_ERROR_NONE) {
462 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
463 goto done; //LCOV_EXCL_LINE
466 ret = __iptables_add_chain(stc->connection, STC_OUT_CHAIN);
467 if (ret != STC_ERROR_NONE) {
468 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
469 goto done; //LCOV_EXCL_LINE
472 ret = __iptables_add_chain(stc->connection, STC_FRWD_CHAIN);
473 if (ret != STC_ERROR_NONE) {
474 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
475 goto done; //LCOV_EXCL_LINE
478 ret = __ip6tables_add_chain(stc->connection, STC_IN_CHAIN);
479 if (ret != STC_ERROR_NONE) {
480 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
481 goto done; //LCOV_EXCL_LINE
484 ret = __ip6tables_add_chain(stc->connection, STC_OUT_CHAIN);
485 if (ret != STC_ERROR_NONE) {
486 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
487 goto done; //LCOV_EXCL_LINE
490 ret = __ip6tables_add_chain(stc->connection, STC_FRWD_CHAIN);
491 if (ret != STC_ERROR_NONE) {
492 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
493 goto done; //LCOV_EXCL_LINE
496 ret = __iptables_add_chain_jump_rule("INPUT", STC_IN_CHAIN);
497 if (ret != STC_ERROR_NONE) {
498 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
499 goto done; //LCOV_EXCL_LINE
502 ret = __iptables_add_chain_jump_rule("OUTPUT", STC_OUT_CHAIN);
503 if (ret != STC_ERROR_NONE) {
504 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
505 goto done; //LCOV_EXCL_LINE
508 ret = __iptables_add_chain_jump_rule("FORWARD", STC_FRWD_CHAIN);
513 stc_error_e iptables_deinit(void)
515 __STC_LOG_FUNC_ENTER__;
517 stc_error_e ret = STC_ERROR_NONE;
518 stc_s *stc = stc_get_manager();
520 if (!stc || !stc->connection) {
521 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
522 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
525 ret = __iptables_remove_chain(stc->connection, STC_IN_CHAIN);
526 if (ret != STC_ERROR_NONE) {
527 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
528 goto done; //LCOV_EXCL_LINE
531 ret = __iptables_remove_chain(stc->connection, STC_OUT_CHAIN);
532 if (ret != STC_ERROR_NONE) {
533 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
534 goto done; //LCOV_EXCL_LINE
537 ret = __iptables_remove_chain(stc->connection, STC_FRWD_CHAIN);
538 if (ret != STC_ERROR_NONE) {
539 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
540 goto done; //LCOV_EXCL_LINE
543 ret = __ip6tables_remove_chain(stc->connection, STC_IN_CHAIN);
544 if (ret != STC_ERROR_NONE) {
545 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
546 goto done; //LCOV_EXCL_LINE
549 ret = __ip6tables_remove_chain(stc->connection, STC_OUT_CHAIN);
550 if (ret != STC_ERROR_NONE) {
551 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
552 goto done; //LCOV_EXCL_LINE
555 ret = __ip6tables_remove_chain(stc->connection, STC_FRWD_CHAIN);