Add to insert firewall rule
[platform/core/connectivity/stc-manager.git] / src / helper / helper-firewall.c
index 14dff41..644ab75 100755 (executable)
 #define STC_FIREWALL6_DBUS_METHOD_FLUSH_CHAIN        "Ip6tFlushChain"
 
 #define STC_FIREWALL_DBUS_METHOD_ADD_RULE            "IptAddRule"
+#define STC_FIREWALL_DBUS_METHOD_INSERT_RULE         "IptInsertRule"
 #define STC_FIREWALL_DBUS_METHOD_REMOVE_RULE         "IptRemoveRule"
 #define STC_FIREWALL6_DBUS_METHOD_ADD_RULE           "Ip6tAddRule"
+#define STC_FIREWALL6_DBUS_METHOD_INSERT_RULE        "Ip6tInsertRule"
 #define STC_FIREWALL6_DBUS_METHOD_REMOVE_RULE        "Ip6tRemoveRule"
 
 #define BUF_SIZE_FOR_IP 64
@@ -46,33 +48,21 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder,
        g_variant_builder_add(builder, "{sv}", RULE_CHAIN,
                        g_variant_new_string(rule->chain));
 
-       if (rule->direction != STC_FW_DIRECTION_NONE)
+       if (rule->direction != STC_FW_DIRECTION_NONE) {
                g_variant_builder_add(builder, "{sv}", RULE_DIRECTION,
                                g_variant_new_uint16(rule->direction));
 
-       if (rule->s_ip_type != STC_FW_IP_NONE)
-               g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE,
-                               g_variant_new_uint16(rule->s_ip_type));
-
-       if (rule->d_ip_type != STC_FW_IP_NONE)
-               g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE,
-                               g_variant_new_uint16(rule->d_ip_type));
-
-       if (rule->s_port_type != STC_FW_PORT_NONE)
-               g_variant_builder_add(builder, "{sv}", RULE_SPORTTYPE,
-                               g_variant_new_uint16(rule->s_port_type));
-
-       if (rule->d_port_type != STC_FW_PORT_NONE)
-               g_variant_builder_add(builder, "{sv}", RULE_DPORTTYPE,
-                               g_variant_new_uint16(rule->d_port_type));
-
-       if (rule->protocol != STC_FW_PROTOCOL_NONE)
-               g_variant_builder_add(builder, "{sv}", RULE_PROTOCOL,
-                               g_variant_new_uint16(rule->protocol));
+               if (rule->ifname && rule->ifname[0] != '\0')
+                       g_variant_builder_add(builder, "{sv}", RULE_IFNAME,
+                                       g_variant_new_string(rule->ifname));
+       }
 
        switch (rule->family) {
        case STC_FW_FAMILY_V4:
                if (rule->s_ip_type != STC_FW_IP_NONE) {
+                       g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE,
+                               g_variant_new_uint16(rule->s_ip_type));
+
                        if (rule->s_ip1.Ipv4.s_addr)
                                g_variant_builder_add(builder, "{sv}", RULE_SIP1,
                                                g_variant_new_uint32(rule->s_ip1.Ipv4.s_addr));
@@ -83,6 +73,9 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder,
                }
 
                if (rule->d_ip_type != STC_FW_IP_NONE) {
+                       g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE,
+                               g_variant_new_uint16(rule->d_ip_type));
+
                        if (rule->d_ip1.Ipv4.s_addr)
                                g_variant_builder_add(builder, "{sv}", RULE_DIP1,
                                                g_variant_new_uint32(rule->d_ip1.Ipv4.s_addr));
@@ -98,6 +91,9 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder,
                        char buf[BUF_SIZE_FOR_IP];
 
                        if (rule->s_ip_type != STC_FW_IP_NONE) {
+                               g_variant_builder_add(builder, "{sv}", RULE_SIPTYPE,
+                                       g_variant_new_uint16(rule->s_ip_type));
+
                                if (rule->s_ip1.Ipv6.s6_addr32[0] || rule->s_ip1.Ipv6.s6_addr32[1] ||
                                        rule->s_ip1.Ipv6.s6_addr32[2] || rule->s_ip1.Ipv6.s6_addr32[3]) {
                                        memset(buf, 0, sizeof(buf));
@@ -120,6 +116,9 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder,
                        }
 
                        if (rule->d_ip_type != STC_FW_IP_NONE) {
+                               g_variant_builder_add(builder, "{sv}", RULE_DIPTYPE,
+                                       g_variant_new_uint16(rule->d_ip_type));
+
                                if (rule->d_ip1.Ipv6.s6_addr32[0] || rule->d_ip1.Ipv6.s6_addr32[1] ||
                                        rule->d_ip1.Ipv6.s6_addr32[2] || rule->d_ip1.Ipv6.s6_addr32[3]) {
                                        memset(buf, 0, sizeof(buf));
@@ -147,30 +146,35 @@ static void __fw_add_rule_info_to_builder(GVariantBuilder *builder,
                break;
        }
 
-       if (rule->s_port_type != STC_FW_PORT_NONE) {
-               if (rule->s_port1)
-                       g_variant_builder_add(builder, "{sv}", RULE_SPORT1,
-                                       g_variant_new_uint32(rule->s_port1));
+       if (rule->protocol != STC_FW_PROTOCOL_NONE) {
+               g_variant_builder_add(builder, "{sv}", RULE_PROTOCOL,
+                               g_variant_new_uint16(rule->protocol));
 
-               if (rule->s_port2)
-                       g_variant_builder_add(builder, "{sv}", RULE_SPORT2,
-                                       g_variant_new_uint32(rule->s_port2));
-       }
+               if (rule->s_port_type != STC_FW_PORT_NONE) {
+                       g_variant_builder_add(builder, "{sv}", RULE_SPORTTYPE,
+                                       g_variant_new_uint16(rule->s_port_type));
 
-       if (rule->s_port_type != STC_FW_PORT_NONE) {
-               if (rule->d_port1)
-                       g_variant_builder_add(builder, "{sv}", RULE_DPORT1,
-                                       g_variant_new_uint32(rule->d_port1));
+                       if (rule->s_port1)
+                               g_variant_builder_add(builder, "{sv}", RULE_SPORT1,
+                                               g_variant_new_uint32(rule->s_port1));
 
-               if (rule->d_port2)
-                       g_variant_builder_add(builder, "{sv}", RULE_DPORT2,
-                                       g_variant_new_uint32(rule->d_port2));
-       }
+                       if (rule->s_port2)
+                               g_variant_builder_add(builder, "{sv}", RULE_SPORT2,
+                                               g_variant_new_uint32(rule->s_port2));
+               }
 
-       if (rule->direction != STC_FW_DIRECTION_NONE) {
-               if (rule->ifname && rule->ifname[0] != '\0')
-                       g_variant_builder_add(builder, "{sv}", RULE_IFNAME,
-                                       g_variant_new_string(rule->ifname));
+               if (rule->d_port_type != STC_FW_PORT_NONE) {
+                       g_variant_builder_add(builder, "{sv}", RULE_DPORTTYPE,
+                                       g_variant_new_uint16(rule->d_port_type));
+
+                       if (rule->d_port1)
+                               g_variant_builder_add(builder, "{sv}", RULE_DPORT1,
+                                               g_variant_new_uint32(rule->d_port1));
+
+                       if (rule->d_port2)
+                               g_variant_builder_add(builder, "{sv}", RULE_DPORT2,
+                                               g_variant_new_uint32(rule->d_port2));
+               }
        }
 
        if (rule->target_str && rule->target_str[0] != '\0')
@@ -377,7 +381,7 @@ static int __fw_set_chain(firewall_chain_s *chain)
        }
 
        rule.target_str = g_strdup(chain->chain);
-       ret = firewall_rule_add(&rule);
+       ret = firewall_rule_insert(&rule);
 
        g_free(rule.chain);
        g_free(rule.target_str);
@@ -411,7 +415,7 @@ static int __fw_unset_chain(firewall_chain_s *chain)
        return ret;
 }
 
-static int __fw_add_rule(GDBusConnection *connection,
+static int __fw_append_rule(GDBusConnection *connection,
                               firewall_rule_s *rule)
 {
        int result = 0;
@@ -444,7 +448,40 @@ static int __fw_add_rule(GDBusConnection *connection,
        return STC_ERROR_NONE;
 }
 
-static int __fw6_add_rule(GDBusConnection *connection,
+static int __fw_insert_rule(GDBusConnection *connection,
+                              firewall_rule_s *rule)
+{
+       int result = 0;
+       GVariantBuilder *builder = NULL;
+       GVariant *params = NULL;
+       GVariant *message = NULL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       __fw_add_rule_info_to_builder(builder, rule);
+       params = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+
+       message = stc_manager_gdbus_call_sync(connection,
+                                             STC_FIREWALL_DBUS_SERVICE,
+                                             STC_FIREWALL_DBUS_RULE_PATH,
+                                             STC_FIREWALL_DBUS_RULE_INTERFACE,
+                                             STC_FIREWALL_DBUS_METHOD_INSERT_RULE,
+                                             params);
+
+       if (message == NULL) {
+               STC_LOGE("Failed to invoke dbus method");
+               return STC_ERROR_FAIL;
+       }
+
+       g_variant_get(message, "(i)", &result);
+       STC_LOGD("Successfully inserted firewall rule [%d:%s]",
+                               result, rule->chain);
+       g_variant_unref(message);
+
+       return STC_ERROR_NONE;
+}
+
+static int __fw6_append_rule(GDBusConnection *connection,
                                firewall_rule_s *rule)
 {
        int result = 0;
@@ -477,6 +514,39 @@ static int __fw6_add_rule(GDBusConnection *connection,
        return STC_ERROR_NONE;
 }
 
+static int __fw6_insert_rule(GDBusConnection *connection,
+                               firewall_rule_s *rule)
+{
+       int result = 0;
+       GVariantBuilder *builder = NULL;
+       GVariant *params = NULL;
+       GVariant *message = NULL;
+
+       builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+       __fw_add_rule_info_to_builder(builder, rule);
+       params = g_variant_new("(a{sv})", builder);
+       g_variant_builder_unref(builder);
+
+       message = stc_manager_gdbus_call_sync(connection,
+                                             STC_FIREWALL_DBUS_SERVICE,
+                                             STC_FIREWALL_DBUS_RULE_PATH,
+                                             STC_FIREWALL_DBUS_RULE_INTERFACE,
+                                             STC_FIREWALL6_DBUS_METHOD_INSERT_RULE,
+                                             params);
+
+       if (message == NULL) {
+               STC_LOGE("Failed to invoke dbus method");
+               return STC_ERROR_FAIL;
+       }
+
+       g_variant_get(message, "(i)", &result);
+       STC_LOGD("Successfully inserted firewall6 rule [%d:%s]",
+                               result, rule->chain);
+       g_variant_unref(message);
+
+       return STC_ERROR_NONE;
+}
+
 static int __fw_remove_rule(GDBusConnection *connection,
                                  firewall_rule_s *rule)
 {
@@ -649,7 +719,50 @@ stc_error_e firewall_chain_unset(firewall_chain_s *chain)
        return ret;
 }
 
-stc_error_e firewall_rule_add(firewall_rule_s *rule)
+stc_error_e firewall_rule_append(firewall_rule_s *rule)
+{
+       stc_error_e ret = STC_ERROR_NONE;
+       stc_s *stc = stc_get_manager();
+
+       if (!stc || !stc->connection) {
+               __STC_LOG_FUNC_EXIT__;
+               return STC_ERROR_UNINITIALIZED;
+       }
+
+       switch (rule->family) {
+       case STC_FW_FAMILY_V4:
+               ret = __fw_append_rule(stc->connection, rule);
+               if (ret != STC_ERROR_NONE) {
+                       __STC_LOG_FUNC_EXIT__;
+                       return ret;
+               }
+               break;
+       case STC_FW_FAMILY_V6:
+               ret = __fw6_append_rule(stc->connection, rule);
+               if (ret != STC_ERROR_NONE) {
+                       __STC_LOG_FUNC_EXIT__;
+                       return ret;
+               }
+               break;
+       default:
+               ret = __fw_append_rule(stc->connection, rule);
+               if (ret != STC_ERROR_NONE) {
+                       __STC_LOG_FUNC_EXIT__;
+                       return ret;
+               }
+
+               ret = __fw6_append_rule(stc->connection, rule);
+               if (ret != STC_ERROR_NONE) {
+                       __STC_LOG_FUNC_EXIT__;
+                       return ret;
+               }
+               break;
+       }
+
+       return ret;
+}
+
+stc_error_e firewall_rule_insert(firewall_rule_s *rule)
 {
        stc_error_e ret = STC_ERROR_NONE;
        stc_s *stc = stc_get_manager();
@@ -661,27 +774,27 @@ stc_error_e firewall_rule_add(firewall_rule_s *rule)
 
        switch (rule->family) {
        case STC_FW_FAMILY_V4:
-               ret = __fw_add_rule(stc->connection, rule);
+               ret = __fw_insert_rule(stc->connection, rule);
                if (ret != STC_ERROR_NONE) {
                        __STC_LOG_FUNC_EXIT__;
                        return ret;
                }
                break;
        case STC_FW_FAMILY_V6:
-               ret = __fw6_add_rule(stc->connection, rule);
+               ret = __fw6_insert_rule(stc->connection, rule);
                if (ret != STC_ERROR_NONE) {
                        __STC_LOG_FUNC_EXIT__;
                        return ret;
                }
                break;
        default:
-               ret = __fw_add_rule(stc->connection, rule);
+               ret = __fw_insert_rule(stc->connection, rule);
                if (ret != STC_ERROR_NONE) {
                        __STC_LOG_FUNC_EXIT__;
                        return ret;
                }
 
-               ret = __fw6_add_rule(stc->connection, rule);
+               ret = __fw6_insert_rule(stc->connection, rule);
                if (ret != STC_ERROR_NONE) {
                        __STC_LOG_FUNC_EXIT__;
                        return ret;