Merge "Maintain list for active wifi interfaces" into tizen
[platform/core/connectivity/net-config.git] / src / vpnsvc.c
index f83bd2e..922502a 100755 (executable)
@@ -117,103 +117,13 @@ gboolean handle_vpn_protect(Vpnsvc *object,
 
 gboolean handle_vpn_up(Vpnsvc *object,
                                                                GDBusMethodInvocation *invocation,
-                                                               gint arg_iface_index,
-                                                               const gchar *arg_local_ip,
-                                                               const gchar *arg_remote_ip,
-                                                               GVariant *arg_routes,
-                                                               guint arg_nr_routes,
-                                                               GVariant *arg_dns_servers,
-                                                               guint arg_nr_dns,
-                                                               const gchar *arg_dns_suffix,
-                                                               guint arg_mtu)
+                                                               const gchar *arg_iface_name)
 {
        DBG("handle_vpn_up");
 
        int result = VPNSVC_ERROR_NONE;
 
-       char *routes[arg_nr_routes];
-       int prefix[arg_nr_routes];
-       char **dns_servers = NULL;
-
-       unsigned int i = 0;
-       size_t total_dns_string_cnt = 0;
-       gchar* temp_dns_server;
-       GVariantIter iter;
-
-       gchar* route_dest;
-       gint route_prefix;
-
-       DBG("iface_index : %d", arg_iface_index);
-       DBG("local ip : %s", arg_local_ip);
-       DBG("remote ip : %s", arg_remote_ip);
-       DBG("dns_suffix : %s", arg_dns_suffix);
-       DBG("mtu : %u", arg_mtu);
-       DBG("arg_routes: %p", arg_routes);
-       DBG("nr_routes : %u", arg_nr_routes);
-       DBG("arg_dns_servers: %p", arg_dns_servers);
-       DBG("nr_dns : %u", arg_nr_dns);
-
-       /* arg_routes check */
-       if (arg_nr_routes > 0) {
-               if (arg_routes != NULL) {
-                       GVariant *dict = g_variant_get_variant(arg_routes);
-                       g_variant_iter_init(&iter, dict);
-                       i = 0;
-                       while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
-                               int temp_dest_str_len = strlen(route_dest);
-                               routes[i] = g_try_malloc0((sizeof(char) * temp_dest_str_len)+1);
-                               strncpy(routes[i], route_dest, temp_dest_str_len);
-                               routes[i][temp_dest_str_len] = '\0';
-                               prefix[i] = route_prefix;
-                               DBG("routes[%d] = %s \t", i, (routes[i] == NULL) ? "" : routes[i]);
-                               DBG("prefix[%d] = %d ", i, prefix[i]);
-                               i++;
-                       }
-               }
-       }
-
-
-       /* arg_nr_dns check */
-       if (arg_nr_dns > 0) {
-               if (arg_dns_servers != NULL) {
-                       GVariant *array = g_variant_get_variant(arg_dns_servers);
-                       dns_servers = (char **)g_try_malloc0(arg_nr_dns*sizeof(char *));
-                       if (dns_servers == NULL) {
-                               ERR("malloc failed.");
-                               result = VPNSVC_ERROR_OUT_OF_MEMORY;
-                               goto done;
-                       }
-                       g_variant_iter_init(&iter, array);
-                       i = 0;
-                       while (g_variant_iter_loop(&iter, "s", &temp_dns_server)) {
-                               int temp_dns_str_len = strlen(temp_dns_server);
-                               dns_servers[i] = (char *)g_try_malloc0((temp_dns_str_len + 1) * sizeof(char));
-                               strncpy(dns_servers[i], temp_dns_server, strlen(temp_dns_server));
-                               dns_servers[i][temp_dns_str_len] = '\0';
-                               total_dns_string_cnt += temp_dns_str_len;
-                               DBG("dns_servers[%d] : %s", i, (dns_servers[i] == NULL) ? "" : dns_servers[i]);
-                               i++;
-                       }
-               }
-       }
-
-       result = vpn_service_up(arg_iface_index, arg_local_ip, arg_remote_ip,
-                       routes, prefix, arg_nr_routes, dns_servers, arg_nr_dns,
-                       total_dns_string_cnt, arg_dns_suffix, arg_mtu);
-done:
-       /* free pointers */
-       for (i = 0; i < arg_nr_routes; i++) {
-               if (routes[i])
-                       g_free(routes[i]);
-       }
-
-       if (dns_servers) {
-               for (i = 0; i < arg_nr_dns; i++) {
-                       if (dns_servers[i])
-                               g_free(dns_servers[i]);
-               }
-               g_free(dns_servers);
-       }
+       result = vpn_service_up(arg_iface_name);
 
        vpnsvc_complete_vpn_up(object, invocation, result);
 
@@ -222,21 +132,21 @@ done:
 
 gboolean handle_vpn_down(Vpnsvc *object,
                                                                        GDBusMethodInvocation *invocation,
-                                                                       gint arg_iface_index)
+                                                                       const gchar *arg_iface_name)
 {
        DBG("handle_vpn_down");
 
        int result = VPNSVC_ERROR_NONE;
 
-       DBG("vpn_down, %d\n", arg_iface_index);
-
-       result = vpn_service_down(arg_iface_index);
+       result = vpn_service_down(arg_iface_name);
 
        vpnsvc_complete_vpn_down(object, invocation, result);
 
        return TRUE;
 }
 
+#define MAX_NUM_ROUTE_RULE 255
+
 gboolean handle_vpn_block_networks(Vpnsvc *object,
                                                                                        GDBusMethodInvocation *invocation,
                                                                                        GVariant *arg_nets_vpn,
@@ -247,66 +157,102 @@ gboolean handle_vpn_block_networks(Vpnsvc *object,
        DBG("handle_vpn_block_networks");
 
        int result = VPNSVC_ERROR_NONE;
+       if (arg_nr_nets_vpn > MAX_NUM_ROUTE_RULE) {
+               ERR("Number of allowing networks over VPN interface is exceeded %d,"
+                                               " Limit is %d", arg_nr_nets_vpn, MAX_NUM_ROUTE_RULE);
+               result = VPNSVC_ERROR_INVALID_PARAMETER;
+               goto method_complete;
+       }
 
-       char *nets_vpn[arg_nr_nets_vpn];
-       int prefix_vpn[arg_nr_nets_vpn];
-
-       char *nets_orig[arg_nr_nets_vpn];
-       int prefix_orig[arg_nr_nets_vpn];
-
-       int i = 0;
-       GVariantIter iter;
-       gchar* route_dest;
-       gint route_prefix;
-
-       DBG("vpn_block_networks");
-
-       /* arg_nets_vpn check */
-       if (arg_nr_nets_vpn > 0) {
-               if (arg_nets_vpn != NULL) {
-                       GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn);
-                       g_variant_iter_init(&iter, dict_nets_vpn);
-                       i = 0;
-                       while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
-                               int tmp_route_len = strlen(route_dest);
-                               nets_vpn[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
-                               strncpy(nets_vpn[i], route_dest, tmp_route_len);
-                               nets_vpn[i][tmp_route_len] = '\0';
-                               prefix_vpn[i] = route_prefix;
-                               DBG("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]);
-                               DBG("prefix_vpn[%d] = %d ", i, prefix_vpn[i]);
-                               i++;
+       if (arg_nr_nets_orig > MAX_NUM_ROUTE_RULE) {
+               ERR("Number of allowing networks over original interface is exceeded"
+                                               " %d, Limit is %d", arg_nr_nets_orig, MAX_NUM_ROUTE_RULE);
+               result = VPNSVC_ERROR_INVALID_PARAMETER;
+               goto method_complete;
+       }
+
+       do {
+               char *nets_vpn[arg_nr_nets_vpn];
+               int prefix_vpn[arg_nr_nets_vpn];
+
+               char *nets_orig[arg_nr_nets_orig];
+               int prefix_orig[arg_nr_nets_orig];
+
+               int i = 0;
+               GVariantIter iter;
+               gchar* route_dest;
+               gint route_prefix;
+
+               DBG("vpn_block_networks");
+
+               memset(nets_vpn, 0, sizeof(char *) * arg_nr_nets_vpn);
+               memset(prefix_vpn, 0, sizeof(int) * arg_nr_nets_vpn);
+               memset(nets_orig, 0, sizeof(char *) * arg_nr_nets_orig);
+               memset(prefix_orig, 0, sizeof(int) * arg_nr_nets_orig);
+
+               /* arg_nets_vpn check */
+               if (arg_nr_nets_vpn > 0) {
+                       if (arg_nets_vpn != NULL) {
+                               GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn);
+                               g_variant_iter_init(&iter, dict_nets_vpn);
+                               i = 0;
+                               while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
+                                       if (i >= arg_nr_nets_vpn) {
+                                               WARN("No more space for allowing network over VPN interface."
+                                                               " next index %d / space size %d", i, arg_nr_nets_vpn);
+                                               g_free(route_dest);
+                                               break;
+                                       }
+                                       int tmp_route_len = strlen(route_dest);
+                                       nets_vpn[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
+                                       strncpy(nets_vpn[i], route_dest, tmp_route_len);
+                                       nets_vpn[i][tmp_route_len] = '\0';
+                                       prefix_vpn[i] = route_prefix;
+                                       DBG("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]);
+                                       DBG("prefix_vpn[%d] = %d ", i, prefix_vpn[i]);
+                                       i++;
+                               }
                        }
                }
-       }
 
-       /* arg_nets_orig check */
-       if (arg_nr_nets_orig > 0) {
-               if (arg_nets_orig != NULL) {
-                       GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig);
-                       g_variant_iter_init(&iter, dict_nets_orig);
-                       i = 0;
-                       while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
-                               int tmp_route_len = strlen(route_dest);
-                               nets_orig[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
-                               strncpy(nets_orig[i], route_dest, tmp_route_len);
-                               nets_orig[i][tmp_route_len] = '\0';
-                               prefix_orig[i] = route_prefix;
-                               DBG("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]);
-                               DBG("prefix_orig[%d] = %d ", i, prefix_orig[i]);
-                               i++;
+               /* arg_nets_orig check */
+               if (arg_nr_nets_orig > 0) {
+                       if (arg_nets_orig != NULL) {
+                               GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig);
+                               g_variant_iter_init(&iter, dict_nets_orig);
+                               i = 0;
+                               while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
+                                       if (i >= arg_nr_nets_orig) {
+                                               WARN("No more space for allowing network over VPN interface."
+                                                               " next index %d / space size %d", i, arg_nr_nets_orig);
+                                               g_free(route_dest);
+                                               break;
+                                       }
+                                       int tmp_route_len = strlen(route_dest);
+                                       nets_orig[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
+                                       strncpy(nets_orig[i], route_dest, tmp_route_len);
+                                       nets_orig[i][tmp_route_len] = '\0';
+                                       prefix_orig[i] = route_prefix;
+                                       DBG("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]);
+                                       DBG("prefix_orig[%d] = %d ", i, prefix_orig[i]);
+                                       i++;
+                               }
                        }
                }
-       }
 
-       /* call function */
-       result = vpn_service_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig);
+               /* call function */
+               result = vpn_service_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig);
 
-       for (i = 0; i < arg_nr_nets_vpn; ++i) {
-               g_free(nets_orig[i]);
-               g_free(nets_vpn[i]);
-       }
+               for (i = 0; i < arg_nr_nets_vpn; ++i) {
+                       g_free(nets_vpn[i]);
+               }
+
+               for (i = 0; i < arg_nr_nets_orig; ++i) {
+                       g_free(nets_orig[i]);
+               }
+       } while(0);
 
+method_complete:
        vpnsvc_complete_vpn_block_networks(object, invocation, result);
 
        return TRUE;
@@ -328,6 +274,74 @@ gboolean handle_vpn_unblock_networks(Vpnsvc *object,
        return TRUE;
 }
 
+gboolean handle_vpn_update_settings(Vpnsvc *object,
+                                                               GDBusMethodInvocation *invocation,
+                                                               gint arg_iface_index,
+                                                               const gchar *arg_local_ip,
+                                                               const gchar *arg_remote_ip,
+                                                               guint arg_mtu)
+{
+       int result = VPNSVC_ERROR_NONE;
+       DBG("handle_vpn_update_settings");
+
+       result = vpn_service_update_settings(arg_iface_index, arg_local_ip, arg_remote_ip, arg_mtu);
+
+       vpnsvc_complete_vpn_update_settings(object, invocation, result);
+
+       return TRUE;
+}
+
+gboolean handle_vpn_add_route(Vpnsvc *object,
+                                                               GDBusMethodInvocation *invocation,
+                                                               gchar *arg_iface_name,
+                                                               const gchar *arg_route,
+                                                               gint arg_prefix)
+{
+       DBG("handle_vpn_add_route");
+
+       int result = VPNSVC_ERROR_NONE;
+
+       result = vpn_service_add_route(arg_iface_name, arg_route, arg_prefix);
+
+       vpnsvc_complete_vpn_add_route(object, invocation, result);
+
+       return TRUE;
+}
+
+gboolean handle_vpn_remove_route(Vpnsvc *object,
+                                                               GDBusMethodInvocation *invocation,
+                                                               gchar *arg_iface_name,
+                                                               const gchar *arg_route,
+                                                               gint arg_prefix)
+
+{
+       DBG("handle_vpn_remove_route");
+
+       int result = VPNSVC_ERROR_NONE;
+
+       result = vpn_service_remove_route(arg_iface_name, arg_route, arg_prefix);
+
+       vpnsvc_complete_vpn_remove_route(object, invocation, result);
+
+       return TRUE;
+}
+
+gboolean handle_vpn_add_dns_server(Vpnsvc *object,
+                                                               GDBusMethodInvocation *invocation,
+                                                               gchar *arg_iface_name,
+                                                               const gchar *arg_dns_server)
+{
+       DBG("handle_vpn_add_dns_server");
+
+       int result = VPNSVC_ERROR_NONE;
+
+       result = vpn_service_add_dns_server(arg_iface_name, arg_dns_server);
+
+       vpnsvc_complete_vpn_add_dns_server(object, invocation, result);
+
+       return TRUE;
+}
+
 /*****************************
  * Initializations Functions *
  ****************************/
@@ -367,6 +381,14 @@ void vpnsvc_create_and_init(void)
                        G_CALLBACK(handle_vpn_block_networks), NULL);
        g_signal_connect(vpnsvc, "handle-vpn-unblock-networks",
                        G_CALLBACK(handle_vpn_unblock_networks), NULL);
+       g_signal_connect(vpnsvc, "handle-vpn-update-settings",
+                       G_CALLBACK(handle_vpn_update_settings), NULL);
+       g_signal_connect(vpnsvc, "handle-vpn-add-route",
+                       G_CALLBACK(handle_vpn_add_route), NULL);
+       g_signal_connect(vpnsvc, "handle-vpn-remove-route",
+                       G_CALLBACK(handle_vpn_remove_route), NULL);
+       g_signal_connect(vpnsvc, "handle-vpn-add-dns-server",
+                       G_CALLBACK(handle_vpn_add_dns_server), NULL);
 
        if (!g_dbus_interface_skeleton_export(interface_vpn, connection,
                        NETCONFIG_VPNSVC_PATH, NULL)) {