From e63fed07f628d12b50a24f90f08cc45e9a6f7459 Mon Sep 17 00:00:00 2001 From: "hyunuk.tak" Date: Thu, 21 May 2020 16:29:38 +0900 Subject: [PATCH] Add to add/remove rule list Change-Id: I2a2aa9339215d95d84fda7086355f274e7e1f978 Signed-off-by: hyunuk.tak --- include/stc-iptables-util.h | 20 ++++ interfaces/stc-iptables-iface.xml | 16 +++ src/helper/helper-ip6tables.c | 98 ++++++++++++++++ src/helper/helper-ip6tables.h | 2 + src/helper/helper-iptables.c | 97 ++++++++++++++++ src/helper/helper-iptables.h | 2 + src/stc-iptables-gdbus.c | 16 +++ src/stc-iptables-util.c | 234 +++++++++++++++++++++++++++++++++++++- 8 files changed, 483 insertions(+), 2 deletions(-) diff --git a/include/stc-iptables-util.h b/include/stc-iptables-util.h index 41d929d..c823cd4 100755 --- a/include/stc-iptables-util.h +++ b/include/stc-iptables-util.h @@ -87,6 +87,16 @@ gboolean handle_iptables_flush_chain(StcChain *object, const gchar *chain, void *user_data); +gboolean handle_iptables_add_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data); + +gboolean handle_iptables_remove_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data); + /* ip6tables */ gboolean handle_ip6tables_add_rule(StcRule *object, GDBusMethodInvocation *invocation, @@ -118,4 +128,14 @@ gboolean handle_ip6tables_flush_chain(StcChain *object, const gchar *chain, void *user_data); +gboolean handle_ip6tables_add_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data); + +gboolean handle_ip6tables_remove_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data); + #endif /* __STC_IPTABLES_UTIL_H__ */ diff --git a/interfaces/stc-iptables-iface.xml b/interfaces/stc-iptables-iface.xml index 6b3415b..8c9f6c0 100755 --- a/interfaces/stc-iptables-iface.xml +++ b/interfaces/stc-iptables-iface.xml @@ -9,6 +9,14 @@ + + + + + + + + @@ -21,6 +29,14 @@ + + + + + + + + diff --git a/src/helper/helper-ip6tables.c b/src/helper/helper-ip6tables.c index 35e6269..a625c22 100755 --- a/src/helper/helper-ip6tables.c +++ b/src/helper/helper-ip6tables.c @@ -503,6 +503,58 @@ int ip6tables_add_rule(ip6tables_rule_s *rule) return STC_ERROR_NONE; } +int ip6tables_add_rule_list(GSList *rule_list) +{ + GSList *list; + ip6t_handle_t *handle; + + handle = ip6tc_init(IP6TC_TABLE); + if (handle == NULL) { + STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + for (list = rule_list; list; list = list->next) { + ip6tables_rule_s *rule = list->data; + const char *chain = rule->chain; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + if (!ip6tc_is_chain(chain, handle)) { + STC_LOGE("chain not present [%s]", ip6tc_strerror(errno)); + continue; + } + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + continue; + } + + if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) { + STC_LOGD("Entry already present"); + continue; + } + + if (!ip6tc_append_entry(chain, (const ip6t_entry_t *)entry, handle)) { + STC_LOGE("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno)); + continue; + } + + STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name); + } + + if (!ip6tc_commit(handle)) { + STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + STC_LOGI("Successed to add rule list"); + ip6tc_free(handle); + return STC_ERROR_NONE; +} + + int ip6tables_insert_rule(ip6tables_rule_s *rule) { ip6t_handle_t *handle; @@ -595,6 +647,52 @@ int ip6tables_remove_rule(ip6tables_rule_s *rule) return STC_ERROR_NONE; } +int ip6tables_remove_rule_list(GSList *rule_list) +{ + GSList *list; + ip6t_handle_t *handle; + + handle = ip6tc_init(IP6TC_TABLE); + if (handle == NULL) { + STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + for (list = rule_list; list; list = list->next) { + ip6tables_rule_s *rule = list->data; + const char *chain = rule->chain; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + if (!ip6tc_is_chain(chain, handle)) { + STC_LOGE("chain not present [%s]", ip6tc_strerror(errno)); + continue; + } + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + continue; + } + + if (!ip6tc_delete_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) { + STC_LOGE("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno)); + continue; + } + + STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name); + } + + if (!ip6tc_commit(handle)) { + STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + STC_LOGI("Successed to remove rule list"); + ip6tc_free(handle); + return STC_ERROR_NONE; +} + int ip6tables_add_chain(const char *chain) { ip6t_handle_t *handle; diff --git a/src/helper/helper-ip6tables.h b/src/helper/helper-ip6tables.h index 8da2f64..a4ff7f4 100755 --- a/src/helper/helper-ip6tables.h +++ b/src/helper/helper-ip6tables.h @@ -103,6 +103,7 @@ typedef struct { * @return 0 on success and negative value if error. */ int ip6tables_add_rule(ip6tables_rule_s *rule); +int ip6tables_add_rule_list(GSList *rule_list);; /** * @desc This function inserts a new ip6tables rule. @@ -115,6 +116,7 @@ int ip6tables_insert_rule(ip6tables_rule_s *rule); * @return 0 on success and negative value if error. */ int ip6tables_remove_rule(ip6tables_rule_s *rule); +int ip6tables_remove_rule_list(GSList *rule_list); /** * @desc This function adds a new ip6tables chain. diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c index e43cc0d..999b40d 100755 --- a/src/helper/helper-iptables.c +++ b/src/helper/helper-iptables.c @@ -494,6 +494,57 @@ int iptables_add_rule(iptables_rule_s *rule) return STC_ERROR_NONE; } +int iptables_add_rule_list(GSList *rule_list) +{ + GSList *list; + ipt_handle_t *handle; + + handle = iptc_init(IPTC_TABLE); + if (handle == NULL) { + STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + for (list = rule_list; list; list = list->next) { + iptables_rule_s *rule = list->data; + const char *chain = rule->chain; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + if (!iptc_is_chain(chain, handle)) { + STC_LOGE("chain not present [%s]", iptc_strerror(errno)); + continue; + } + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + continue; + } + + if (iptc_check_entry(chain, (const ipt_entry_t *)entry, mask, handle)) { + STC_LOGD("Entry already present"); + continue; + } + + if (!iptc_append_entry(chain, (const ipt_entry_t *)entry, handle)) { + STC_LOGE("iptc_append_entry failed [%s]", iptc_strerror(errno)); + continue; + } + + STC_LOGD("Append entry [%s : %s]", rule->chain, rule->nfacct_name); + } + + if (!iptc_commit(handle)) { + STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + STC_LOGI("Successed to add rule list"); + iptc_free(handle); + return STC_ERROR_NONE; +} + int iptables_insert_rule(iptables_rule_s *rule) { ipt_handle_t *handle; @@ -586,6 +637,52 @@ int iptables_remove_rule(iptables_rule_s *rule) return STC_ERROR_NONE; } +int iptables_remove_rule_list(GSList *rule_list) +{ + GSList *list; + ipt_handle_t *handle; + + handle = iptc_init(IPTC_TABLE); + if (handle == NULL) { + STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + for (list = rule_list; list; list = list->next) { + iptables_rule_s *rule = list->data; + const char *chain = rule->chain; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + if (!iptc_is_chain(chain, handle)) { + STC_LOGE("chain not present [%s]", iptc_strerror(errno)); + continue; + } + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + continue; + } + + if (!iptc_delete_entry(chain, (const ipt_entry_t *)entry, mask, handle)) { + STC_LOGE("iptc_delete_entry failed [%s]", iptc_strerror(errno)); + continue; + } + + STC_LOGD("Delete entry [%s : %s]", rule->chain, rule->nfacct_name); + } + + if (!iptc_commit(handle)) { + STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + STC_LOGI("Successed to remove rule list"); + iptc_free(handle); + return STC_ERROR_NONE; +} + int iptables_add_chain(const char *chain) { ipt_handle_t *handle; diff --git a/src/helper/helper-iptables.h b/src/helper/helper-iptables.h index 58a36cf..5c3e176 100755 --- a/src/helper/helper-iptables.h +++ b/src/helper/helper-iptables.h @@ -103,6 +103,7 @@ typedef struct { * @return 0 on success and negative value if error. */ int iptables_add_rule(iptables_rule_s *rule); +int iptables_add_rule_list(GSList *rule_list); /** * @desc This function inserts a new iptables rule. @@ -115,6 +116,7 @@ int iptables_insert_rule(iptables_rule_s *rule); * @return 0 on success and negative value if error. */ int iptables_remove_rule(iptables_rule_s *rule); +int iptables_remove_rule_list(GSList *rule_list); /** * @desc This function adds a new iptables chain. diff --git a/src/stc-iptables-gdbus.c b/src/stc-iptables-gdbus.c index 01c1537..b966726 100755 --- a/src/stc-iptables-gdbus.c +++ b/src/stc-iptables-gdbus.c @@ -133,6 +133,14 @@ static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables) G_CALLBACK(handle_iptables_remove_rule), stc_iptables); + g_signal_connect(rule, "handle-ipt-add-list", + G_CALLBACK(handle_iptables_add_list), + stc_iptables); + + g_signal_connect(rule, "handle-ipt-remove-list", + G_CALLBACK(handle_iptables_remove_list), + stc_iptables); + g_signal_connect(rule, "handle-ip6t-add-rule", G_CALLBACK(handle_ip6tables_add_rule), stc_iptables); @@ -145,6 +153,14 @@ static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables) G_CALLBACK(handle_ip6tables_remove_rule), stc_iptables); + g_signal_connect(rule, "handle-ip6t-add-list", + G_CALLBACK(handle_ip6tables_add_list), + stc_iptables); + + g_signal_connect(rule, "handle-ip6t-remove-list", + G_CALLBACK(handle_ip6tables_remove_list), + stc_iptables); + g_dbus_object_manager_server_export(stc_iptables->obj_mgr, G_DBUS_OBJECT_SKELETON(object)); g_object_unref(object); diff --git a/src/stc-iptables-util.c b/src/stc-iptables-util.c index 7bb99e2..54902cf 100755 --- a/src/stc-iptables-util.c +++ b/src/stc-iptables-util.c @@ -407,8 +407,10 @@ void __stc_extract_6_rule(const char *key, GVariant *value, } } -static void __free_rule(iptables_rule_s *rule) +static void __free_rule(gpointer data) { + iptables_rule_s *rule = (iptables_rule_s *)data; + FREE(rule->chain); FREE(rule->ifname); FREE(rule->nfacct_name); @@ -418,8 +420,10 @@ static void __free_rule(iptables_rule_s *rule) FREE(rule); } -static void __free_6_rule(ip6tables_rule_s *rule) +static void __free_6_rule(gpointer data) { + ip6tables_rule_s *rule = (ip6tables_rule_s *)data; + FREE(rule->chain); FREE(rule->ifname); FREE(rule->nfacct_name); @@ -709,6 +713,120 @@ gboolean handle_iptables_flush_chain(StcChain *object, return TRUE; } +gboolean handle_iptables_add_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data) +{ + __LOG_FUNC_ENTER__; + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + stc_error_e ret = STC_ERROR_NONE; + GSList *iptables_list = NULL; + GVariant *return_parameters = NULL; + struct timespec start, end; + time_t sec; + long int nsec; + + stc_set_keep_alive(TRUE); + + clock_gettime(CLOCK_MONOTONIC, &start); + + g_variant_get(rule_list, "aa{sv}", &iter); + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1); + if (rule != NULL) { + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_rule, + rule); + + iptables_list = g_slist_append(iptables_list, rule); + } + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + + ret = iptables_add_rule_list(iptables_list); + + g_slist_free_full(iptables_list, __free_rule); + + clock_gettime(CLOCK_MONOTONIC, &end); + + sec = end.tv_sec - start.tv_sec; + nsec = end.tv_nsec - start.tv_nsec; + if (nsec < 0) + nsec += 1000000000; + + STC_LOGD("%s to add list [%3ld.%09ld]s", + ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec); + + return_parameters = g_variant_new("(i)", ret); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_iptables_remove_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data) +{ + __LOG_FUNC_ENTER__; + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + stc_error_e ret = STC_ERROR_NONE; + GSList *iptables_list = NULL; + GVariant *return_parameters = NULL; + struct timespec start, end; + time_t sec; + long int nsec; + + stc_set_keep_alive(TRUE); + + clock_gettime(CLOCK_MONOTONIC, &start); + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + g_variant_get(rule_list, "aa{sv}", &iter); + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1); + if (rule != NULL) { + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_rule, + rule); + + iptables_list = g_slist_append(iptables_list, rule); + } + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + + ret = iptables_remove_rule_list(iptables_list); + + g_slist_free_full(iptables_list, __free_rule); + + clock_gettime(CLOCK_MONOTONIC, &end); + + sec = end.tv_sec - start.tv_sec; + nsec = end.tv_nsec - start.tv_nsec; + if (nsec < 0) + nsec += 1000000000; + + STC_LOGD("%s to remove list [%3ld.%09ld]s", + ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec); + + return_parameters = g_variant_new("(i)", ret); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __LOG_FUNC_EXIT__; + return TRUE; +} + gboolean handle_ip6tables_add_rule(StcRule *object, GDBusMethodInvocation *invocation, GVariant *rules, @@ -968,3 +1086,115 @@ gboolean handle_ip6tables_flush_chain(StcChain *object, __LOG_FUNC_EXIT__; return TRUE; } + +gboolean handle_ip6tables_add_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data) +{ + __LOG_FUNC_ENTER__; + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + stc_error_e ret = STC_ERROR_NONE; + GSList *iptables_list = NULL; + GVariant *return_parameters = NULL; + struct timespec start, end; + time_t sec; + long int nsec; + + stc_set_keep_alive(TRUE); + + clock_gettime(CLOCK_MONOTONIC, &start); + + g_variant_get(rule_list, "aa{sv}", &iter); + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1); + if (rule != NULL) { + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_6_rule, + rule); + + iptables_list = g_slist_append(iptables_list, rule); + } + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + + clock_gettime(CLOCK_MONOTONIC, &end); + + ret = ip6tables_add_rule_list(iptables_list); + + g_slist_free_full(iptables_list, __free_6_rule); + + sec = end.tv_sec - start.tv_sec; + nsec = end.tv_nsec - start.tv_nsec; + if (nsec < 0) + nsec += 1000000000; + + STC_LOGD("%s to add list [%3ld.%09ld]s", + ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec); + + return_parameters = g_variant_new("(i)", ret); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_ip6tables_remove_list(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule_list, + void *user_data) +{ + __LOG_FUNC_ENTER__; + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + stc_error_e ret = STC_ERROR_NONE; + GSList *iptables_list = NULL; + GVariant *return_parameters = NULL; + struct timespec start, end; + time_t sec; + long int nsec; + + stc_set_keep_alive(TRUE); + + clock_gettime(CLOCK_MONOTONIC, &start); + + g_variant_get(rule_list, "aa{sv}", &iter); + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1); + if (rule != NULL) { + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_6_rule, + rule); + + iptables_list = g_slist_append(iptables_list, rule); + } + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + + ret = ip6tables_remove_rule_list(iptables_list); + + g_slist_free_full(iptables_list, __free_6_rule); + + clock_gettime(CLOCK_MONOTONIC, &end); + + sec = end.tv_sec - start.tv_sec; + nsec = end.tv_nsec - start.tv_nsec; + if (nsec < 0) + nsec += 1000000000; + + STC_LOGD("%s to add list [%3ld.%09ld]s", + ret == STC_ERROR_NONE ? "Successed" : "Failed", sec, nsec); + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __LOG_FUNC_EXIT__; + return TRUE; +} -- 2.7.4