Add initial source codes for gtest
[platform/core/connectivity/stc-manager.git] / src / helper / helper-iptables.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-iptables.h"
19
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"
35
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"
42
43 static void __add_rule_info_to_builder(GVariantBuilder *builder,
44                                        iptables_rule_s *rule)
45 {
46         if (builder == NULL || rule == NULL)
47                 return; //LCOV_EXCL_LINE
48
49         g_variant_builder_add(builder, "{sv}", RULE_CHAIN,
50                               g_variant_new_string(rule->chain));
51
52         g_variant_builder_add(builder, "{sv}", RULE_TYPE,
53                               g_variant_new_uint32(rule->direction));
54
55         if (rule->ifname)
56                 g_variant_builder_add(builder, "{sv}", RULE_IFNAME,
57                                       g_variant_new_string(rule->ifname));
58
59         if (rule->classid > 0)
60                 g_variant_builder_add(builder, "{sv}", RULE_CGROUP,
61                                       g_variant_new_uint32(rule->classid));
62
63         if (rule->nfacct_name)
64                 g_variant_builder_add(builder, "{sv}", RULE_NFACCT,
65                                       g_variant_new_string(rule->nfacct_name));
66
67         if (rule->target)
68                 g_variant_builder_add(builder, "{sv}", RULE_TARGET,
69                                       g_variant_new_string(rule->target));
70
71 }
72
73 static int __iptables_rule_add(GDBusConnection *connection,
74                                iptables_rule_s *rule)
75 {
76         int result = 0;
77         GVariantBuilder *builder = NULL;
78         GVariant *params = NULL;
79         GVariant *message = NULL;
80
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);
85
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,
91                                               params);
92
93         if (message == NULL) {
94                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
95                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
96         }
97
98         g_variant_get(message, "(i)", &result);
99         STC_LOGD("Successfully Add Rule [%d]", result);
100         g_variant_unref(message);
101
102         return STC_ERROR_NONE;
103 }
104
105 static int __iptables_rule_remove(GDBusConnection *connection,
106                                   iptables_rule_s *rule)
107 {
108         int result = 0;
109         GVariantBuilder *builder = NULL;
110         GVariant *params = NULL;
111         GVariant *message = NULL;
112
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);
117
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,
123                                               params);
124
125         if (message == NULL) {
126                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
127                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
128         }
129
130         g_variant_get(message, "(i)", &result);
131         STC_LOGD("Successfully Remove Rule [%d]", result);
132         g_variant_unref(message);
133
134         return STC_ERROR_NONE;
135 }
136
137 static int __ip6tables_rule_add(GDBusConnection *connection,
138                                 iptables_rule_s *rule)
139 {
140         int result = 0;
141         GVariantBuilder *builder = NULL;
142         GVariant *params = NULL;
143         GVariant *message = NULL;
144
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);
149
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,
155                                               params);
156
157         if (message == NULL) {
158                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
159                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
160         }
161
162         g_variant_get(message, "(i)", &result);
163         STC_LOGD("Successfully Add 6 Rule [%d]", result);
164         g_variant_unref(message);
165
166         return STC_ERROR_NONE;
167 }
168
169 static int __ip6tables_rule_remove(GDBusConnection *connection,
170                                    iptables_rule_s *rule)
171 {
172         int result = 0;
173         GVariantBuilder *builder = NULL;
174         GVariant *params = NULL;
175         GVariant *message = NULL;
176
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);
181
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,
187                                               params);
188
189         if (message == NULL) {
190                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
191                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
192         }
193
194         g_variant_get(message, "(i)", &result);
195         STC_LOGD("Successfully Remove 6 Rule [%d]", result);
196         g_variant_unref(message);
197
198         return STC_ERROR_NONE;
199 }
200
201 static int __iptables_add_chain(GDBusConnection *connection,
202                                 const char *chain)
203 {
204         int result = 0;
205         GVariant *message = NULL;
206
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));
213
214         if (message == NULL) {
215                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
216                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
217         }
218
219         g_variant_get(message, "(i)", &result);
220         STC_LOGD("Successfully added ipv4 chain [%d]", result);
221         g_variant_unref(message);
222
223         return STC_ERROR_NONE;
224 }
225
226 static int __ip6tables_add_chain(GDBusConnection *connection,
227                                  const char *chain)
228 {
229         int result = 0;
230         GVariant *message = NULL;
231
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));
238
239         if (message == NULL) {
240                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
241                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
242         }
243
244         g_variant_get(message, "(i)", &result);
245         STC_LOGD("Successfully added ipv6 chain [%d]", result);
246         g_variant_unref(message);
247
248         return STC_ERROR_NONE;
249 }
250
251 static int __iptables_remove_chain(GDBusConnection *connection,
252                                    const char *chain)
253 {
254         int result = 0;
255         GVariant *message = NULL;
256
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));
263
264         if (message == NULL) {
265                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
266                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
267         }
268
269         g_variant_get(message, "(i)", &result);
270         STC_LOGD("Successfully removed ipv4 chain [%d]", result);
271         g_variant_unref(message);
272
273         return STC_ERROR_NONE;
274 }
275
276 static int __ip6tables_remove_chain(GDBusConnection *connection,
277                                     const char *chain)
278 {
279         int result = 0;
280         GVariant *message = NULL;
281
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));
288
289         if (message == NULL) {
290                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
291                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
292         }
293
294         g_variant_get(message, "(i)", &result);
295         STC_LOGD("Successfully removed ipv6 chain [%d]", result);
296         g_variant_unref(message);
297
298         return STC_ERROR_NONE;
299 }
300
301 static int __iptables_flush_chain(GDBusConnection *connection,
302                                   const char *chain)
303 {
304         int result = 0;
305         GVariant *message = NULL;
306
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));
313
314         if (message == NULL) {
315                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
316                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
317         }
318
319         g_variant_get(message, "(i)", &result);
320         STC_LOGD("Successfully flushed ipv4 chain [%d]", result);
321         g_variant_unref(message);
322
323         return STC_ERROR_NONE;
324 }
325
326 static int __ip6tables_flush_chain(GDBusConnection *connection,
327                                    const char *chain)
328 {
329         int result = 0;
330         GVariant *message = NULL;
331
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));
338
339         if (message == NULL) {
340                 STC_LOGE("Failed to invoke dbus method"); //LCOV_EXCL_LINE
341                 return STC_ERROR_FAIL; //LCOV_EXCL_LINE
342         }
343
344         g_variant_get(message, "(i)", &result);
345         STC_LOGD("Successfully flushed ipv6 chain [%d]", result);
346         g_variant_unref(message);
347
348         return STC_ERROR_NONE;
349 }
350
351 static int __iptables_add_chain_jump_rule(const char *chain,
352                                           const char *target)
353 {
354         stc_error_e ret = STC_ERROR_NONE;
355         iptables_rule_s iptables_rule;
356         memset(&iptables_rule, 0, sizeof(iptables_rule_s));
357
358         iptables_rule.target = g_strdup(target);
359         iptables_rule.chain = g_strdup(chain);
360
361         ret = iptables_add(&iptables_rule);
362
363         g_free(iptables_rule.target);
364         g_free(iptables_rule.chain);
365
366         return ret;
367 }
368
369 stc_error_e iptables_add(iptables_rule_s *rule)
370 {
371         stc_error_e ret = STC_ERROR_NONE;
372         stc_s *stc = stc_get_manager();
373
374         if (!stc || !stc->connection)
375                 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
376
377         ret = __iptables_rule_add(stc->connection, rule);
378         if (ret != STC_ERROR_NONE)
379                 goto done; //LCOV_EXCL_LINE
380
381         ret = __ip6tables_rule_add(stc->connection, rule);
382 done:
383         return ret;
384 }
385
386 stc_error_e iptables_remove(iptables_rule_s *rule)
387 {
388         stc_error_e ret = STC_ERROR_NONE;
389         stc_s *stc = stc_get_manager();
390
391         if (!stc || !stc->connection)
392                 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
393
394         ret = __iptables_rule_remove(stc->connection, rule);
395         if (ret != STC_ERROR_NONE)
396                 goto done; //LCOV_EXCL_LINE
397
398         ret = __ip6tables_rule_remove(stc->connection, rule);
399 done:
400         return ret;
401 }
402
403 stc_error_e iptables_flush_chains(void)
404 {
405         stc_error_e ret = STC_ERROR_NONE;
406         stc_s *stc = stc_get_manager();
407
408         if (!stc || !stc->connection)
409                 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
410
411         ret = __iptables_flush_chain(stc->connection, STC_IN_CHAIN);
412         if (ret != STC_ERROR_NONE)
413                 goto done; //LCOV_EXCL_LINE
414
415         ret = __iptables_flush_chain(stc->connection, STC_OUT_CHAIN);
416         if (ret != STC_ERROR_NONE)
417                 goto done; //LCOV_EXCL_LINE
418
419         ret = __iptables_flush_chain(stc->connection, STC_FRWD_CHAIN);
420         if (ret != STC_ERROR_NONE)
421                 goto done; //LCOV_EXCL_LINE
422
423         ret = __ip6tables_flush_chain(stc->connection, STC_IN_CHAIN);
424         if (ret != STC_ERROR_NONE)
425                 goto done; //LCOV_EXCL_LINE
426
427         ret = __ip6tables_flush_chain(stc->connection, STC_OUT_CHAIN);
428         if (ret != STC_ERROR_NONE)
429                 goto done; //LCOV_EXCL_LINE
430
431         ret = __ip6tables_flush_chain(stc->connection, STC_FRWD_CHAIN);
432 done:
433         return ret;
434 }
435
436 stc_error_e iptables_init(void)
437 {
438         __STC_LOG_FUNC_ENTER__;
439
440         stc_error_e ret = STC_ERROR_NONE;
441         stc_s *stc = stc_get_manager();
442
443         if (!stc || !stc->connection) {
444                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
445                 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
446         }
447
448         ret = __iptables_add_chain(stc->connection, STC_IN_CHAIN);
449         if (ret != STC_ERROR_NONE) {
450                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
451                 goto done; //LCOV_EXCL_LINE
452         }
453
454         ret = __iptables_add_chain(stc->connection, STC_OUT_CHAIN);
455         if (ret != STC_ERROR_NONE) {
456                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
457                 goto done; //LCOV_EXCL_LINE
458         }
459
460         ret = __iptables_add_chain(stc->connection, STC_FRWD_CHAIN);
461         if (ret != STC_ERROR_NONE) {
462                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
463                 goto done; //LCOV_EXCL_LINE
464         }
465
466         ret = __ip6tables_add_chain(stc->connection, STC_IN_CHAIN);
467         if (ret != STC_ERROR_NONE) {
468                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
469                 goto done; //LCOV_EXCL_LINE
470         }
471
472         ret = __ip6tables_add_chain(stc->connection, STC_OUT_CHAIN);
473         if (ret != STC_ERROR_NONE) {
474                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
475                 goto done; //LCOV_EXCL_LINE
476         }
477
478         ret = __ip6tables_add_chain(stc->connection, STC_FRWD_CHAIN);
479         if (ret != STC_ERROR_NONE) {
480                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
481                 goto done; //LCOV_EXCL_LINE
482         }
483
484         ret = __iptables_add_chain_jump_rule("INPUT", STC_IN_CHAIN);
485         if (ret != STC_ERROR_NONE) {
486                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
487                 goto done; //LCOV_EXCL_LINE
488         }
489
490         ret = __iptables_add_chain_jump_rule("OUTPUT", STC_OUT_CHAIN);
491         if (ret != STC_ERROR_NONE) {
492                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
493                 goto done; //LCOV_EXCL_LINE
494         }
495
496         ret = __iptables_add_chain_jump_rule("FORWARD", STC_FRWD_CHAIN);
497 done:
498         return ret;
499 }
500
501 stc_error_e iptables_deinit(void)
502 {
503         __STC_LOG_FUNC_ENTER__;
504
505         stc_error_e ret = STC_ERROR_NONE;
506         stc_s *stc = stc_get_manager();
507
508         if (!stc || !stc->connection) {
509                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
510                 return STC_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
511         }
512
513         ret = __iptables_remove_chain(stc->connection, STC_IN_CHAIN);
514         if (ret != STC_ERROR_NONE) {
515                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
516                 goto done; //LCOV_EXCL_LINE
517         }
518
519         ret = __iptables_remove_chain(stc->connection, STC_OUT_CHAIN);
520         if (ret != STC_ERROR_NONE) {
521                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
522                 goto done; //LCOV_EXCL_LINE
523         }
524
525         ret = __iptables_remove_chain(stc->connection, STC_FRWD_CHAIN);
526         if (ret != STC_ERROR_NONE) {
527                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
528                 goto done; //LCOV_EXCL_LINE
529         }
530
531         ret = __ip6tables_remove_chain(stc->connection, STC_IN_CHAIN);
532         if (ret != STC_ERROR_NONE) {
533                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
534                 goto done; //LCOV_EXCL_LINE
535         }
536
537         ret = __ip6tables_remove_chain(stc->connection, STC_OUT_CHAIN);
538         if (ret != STC_ERROR_NONE) {
539                 __STC_LOG_FUNC_EXIT__; //LCOV_EXCL_LINE
540                 goto done; //LCOV_EXCL_LINE
541         }
542
543         ret = __ip6tables_remove_chain(stc->connection, STC_FRWD_CHAIN);
544 done:
545         return ret;
546 }