2 * Network Configuration - VPN Service Module
4 * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <gio/gunixfdlist.h>
26 #include "vpnsvc-internal.h"
30 static Vpnsvc *vpnsvc = NULL;
32 /*********************
35 gboolean handle_vpn_init(Vpnsvc *object,
36 GDBusMethodInvocation *invocation,
37 const gchar *arg_iface_name,
38 guint arg_iface_name_len)
40 DBG("handle_vpn_init");
42 int result = VPNSVC_ERROR_NONE;
44 vpnsvc_tun_s handle_s;
50 DBG("vpn_init, %s, %u\n", arg_iface_name, arg_iface_name_len);
52 msg = g_dbus_method_invocation_get_message(invocation);
53 fd_list = g_dbus_message_get_unix_fd_list(msg);
54 fds = g_unix_fd_list_peek_fds(fd_list, &fd_list_length);
56 if (fd_list_length <= 0)
57 DBG("D-Bus Message doesn't contain any fd!");
61 result = vpn_service_init(arg_iface_name, arg_iface_name_len, *fds, &handle_s);
63 DBG("handle_s.fd : %d, handle_s.index : %d, handle_s.name : %s",
64 handle_s.fd, handle_s.index, handle_s.name);
66 vpnsvc_complete_vpn_init(object, invocation, result, handle_s.index, handle_s.name);
71 gboolean handle_vpn_deinit(Vpnsvc *object,
72 GDBusMethodInvocation *invocation,
73 const gchar *arg_dev_name)
75 DBG("handle_vpn_deinit");
77 int result = VPNSVC_ERROR_NONE;
79 DBG("vpn_deinit, %s\n", arg_dev_name);
81 result = vpn_service_deinit(arg_dev_name);
83 vpnsvc_complete_vpn_deinit(object, invocation, result);
88 gboolean handle_vpn_protect(Vpnsvc *object,
89 GDBusMethodInvocation *invocation,
90 const gchar *arg_dev_name)
92 DBG("handle_vpn_protect");
94 int result = VPNSVC_ERROR_NONE;
102 msg = g_dbus_method_invocation_get_message(invocation);
103 fd_list = g_dbus_message_get_unix_fd_list(msg);
104 fds = g_unix_fd_list_peek_fds(fd_list, &fd_list_length);
105 if (fd_list_length <= 0)
106 DBG("D-Bus Message doesn't contain any fd!");
109 DBG("vpn_protect, %d, %s\n", socket, arg_dev_name);
111 result = vpn_service_protect(socket, arg_dev_name);
113 vpnsvc_complete_vpn_protect(object, invocation, result);
118 gboolean handle_vpn_up(Vpnsvc *object,
119 GDBusMethodInvocation *invocation,
120 gint arg_iface_index,
121 const gchar *arg_local_ip,
122 const gchar *arg_remote_ip,
123 GVariant *arg_routes,
125 GVariant *arg_dns_servers,
127 const gchar *arg_dns_suffix,
130 DBG("handle_vpn_up");
132 int result = VPNSVC_ERROR_NONE;
134 char *routes[arg_nr_routes];
135 int prefix[arg_nr_routes];
136 char **dns_servers = NULL;
139 size_t total_dns_string_cnt = 0;
140 gchar* temp_dns_server;
146 DBG("iface_index : %d", arg_iface_index);
147 DBG("local ip : %s", arg_local_ip);
148 DBG("remote ip : %s", arg_remote_ip);
149 DBG("dns_suffix : %s", arg_dns_suffix);
150 DBG("mtu : %u", arg_mtu);
151 DBG("arg_routes: %p", arg_routes);
152 DBG("nr_routes : %u", arg_nr_routes);
153 DBG("arg_dns_servers: %p", arg_dns_servers);
154 DBG("nr_dns : %u", arg_nr_dns);
156 /* arg_routes check */
157 if (arg_nr_routes > 0) {
158 if (arg_routes != NULL) {
159 GVariant *dict = g_variant_get_variant(arg_routes);
160 g_variant_iter_init(&iter, dict);
162 while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
163 int temp_dest_str_len = strlen(route_dest);
164 routes[i] = g_try_malloc0((sizeof(char) * temp_dest_str_len)+1);
165 strncpy(routes[i], route_dest, temp_dest_str_len);
166 routes[i][temp_dest_str_len] = '\0';
167 prefix[i] = route_prefix;
168 DBG("routes[%d] = %s \t", i, (routes[i] == NULL) ? "" : routes[i]);
169 DBG("prefix[%d] = %d ", i, prefix[i]);
176 /* arg_nr_dns check */
177 if (arg_nr_dns > 0) {
178 if (arg_dns_servers != NULL) {
179 GVariant *array = g_variant_get_variant(arg_dns_servers);
180 dns_servers = (char **)g_try_malloc0(arg_nr_dns*sizeof(char *));
181 if (dns_servers == NULL) {
182 ERR("malloc failed.");
183 result = VPNSVC_ERROR_OUT_OF_MEMORY;
186 g_variant_iter_init(&iter, array);
188 while (g_variant_iter_loop(&iter, "s", &temp_dns_server)) {
189 int temp_dns_str_len = strlen(temp_dns_server);
190 dns_servers[i] = (char *)g_try_malloc0((temp_dns_str_len + 1) * sizeof(char));
191 strncpy(dns_servers[i], temp_dns_server, strlen(temp_dns_server));
192 dns_servers[i][temp_dns_str_len] = '\0';
193 total_dns_string_cnt += temp_dns_str_len;
194 DBG("dns_servers[%d] : %s", i, (dns_servers[i] == NULL) ? "" : dns_servers[i]);
200 result = vpn_service_up(arg_iface_index, arg_local_ip, arg_remote_ip,
201 routes, prefix, arg_nr_routes, dns_servers, arg_nr_dns,
202 total_dns_string_cnt, arg_dns_suffix, arg_mtu);
205 for (i = 0; i < arg_nr_routes; i++) {
211 for (i = 0; i < arg_nr_dns; i++) {
213 g_free(dns_servers[i]);
218 vpnsvc_complete_vpn_up(object, invocation, result);
223 gboolean handle_vpn_down(Vpnsvc *object,
224 GDBusMethodInvocation *invocation,
225 gint arg_iface_index)
227 DBG("handle_vpn_down");
229 int result = VPNSVC_ERROR_NONE;
231 DBG("vpn_down, %d\n", arg_iface_index);
233 result = vpn_service_down(arg_iface_index);
235 vpnsvc_complete_vpn_down(object, invocation, result);
240 gboolean handle_vpn_block_networks(Vpnsvc *object,
241 GDBusMethodInvocation *invocation,
242 GVariant *arg_nets_vpn,
243 guint arg_nr_nets_vpn,
244 GVariant *arg_nets_orig,
245 guint arg_nr_nets_orig)
247 DBG("handle_vpn_block_networks");
249 int result = VPNSVC_ERROR_NONE;
251 char *nets_vpn[arg_nr_nets_vpn];
252 int prefix_vpn[arg_nr_nets_vpn];
254 char *nets_orig[arg_nr_nets_vpn];
255 int prefix_orig[arg_nr_nets_vpn];
262 DBG("vpn_block_networks");
264 /* arg_nets_vpn check */
265 if (arg_nr_nets_vpn > 0) {
266 if (arg_nets_vpn != NULL) {
267 GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn);
268 g_variant_iter_init(&iter, dict_nets_vpn);
270 while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
271 int tmp_route_len = strlen(route_dest);
272 nets_vpn[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
273 strncpy(nets_vpn[i], route_dest, tmp_route_len);
274 nets_vpn[i][tmp_route_len] = '\0';
275 prefix_vpn[i] = route_prefix;
276 DBG("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]);
277 DBG("prefix_vpn[%d] = %d ", i, prefix_vpn[i]);
283 /* arg_nets_orig check */
284 if (arg_nr_nets_orig > 0) {
285 if (arg_nets_orig != NULL) {
286 GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig);
287 g_variant_iter_init(&iter, dict_nets_orig);
289 while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
290 int tmp_route_len = strlen(route_dest);
291 nets_orig[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
292 strncpy(nets_orig[i], route_dest, tmp_route_len);
293 nets_orig[i][tmp_route_len] = '\0';
294 prefix_orig[i] = route_prefix;
295 DBG("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]);
296 DBG("prefix_orig[%d] = %d ", i, prefix_orig[i]);
303 result = vpn_service_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig);
305 for (i = 0; i < arg_nr_nets_vpn; ++i) {
306 g_free(nets_orig[i]);
310 vpnsvc_complete_vpn_block_networks(object, invocation, result);
315 gboolean handle_vpn_unblock_networks(Vpnsvc *object,
316 GDBusMethodInvocation *invocation)
318 DBG("handle_vpn_unblock_networks");
320 int result = VPNSVC_ERROR_NONE;
322 DBG("vpn_unblock_networks");
324 result = vpn_service_unblock_networks();
326 vpnsvc_complete_vpn_unblock_networks(object, invocation, result);
331 /*****************************
332 * Initializations Functions *
333 ****************************/
334 Vpnsvc *get_vpnsvc_object(void)
339 void vpnsvc_create_and_init(void)
341 DBG("Create vpn object.");
342 GDBusInterfaceSkeleton *interface_vpn = NULL;
343 GDBusConnection *connection = NULL;
344 GDBusObjectManagerServer *server = netdbus_get_vpn_manager();
348 connection = netdbus_get_connection();
349 g_dbus_object_manager_server_set_connection(server, connection);
352 vpnsvc = vpnsvc_skeleton_new();
353 interface_vpn = G_DBUS_INTERFACE_SKELETON(vpnsvc);
356 g_signal_connect(vpnsvc, "handle-vpn-init",
357 G_CALLBACK(handle_vpn_init), NULL);
358 g_signal_connect(vpnsvc, "handle-vpn-deinit",
359 G_CALLBACK(handle_vpn_deinit), NULL);
360 g_signal_connect(vpnsvc, "handle-vpn-protect",
361 G_CALLBACK(handle_vpn_protect), NULL);
362 g_signal_connect(vpnsvc, "handle-vpn-up",
363 G_CALLBACK(handle_vpn_up), NULL);
364 g_signal_connect(vpnsvc, "handle-vpn-down",
365 G_CALLBACK(handle_vpn_down), NULL);
366 g_signal_connect(vpnsvc, "handle-vpn-block-networks",
367 G_CALLBACK(handle_vpn_block_networks), NULL);
368 g_signal_connect(vpnsvc, "handle-vpn-unblock-networks",
369 G_CALLBACK(handle_vpn_unblock_networks), NULL);
371 if (!g_dbus_interface_skeleton_export(interface_vpn, connection,
372 NETCONFIG_VPNSVC_PATH, NULL)) {
373 ERR("Export NETCONFIG_VPNSVC_PATH for vpn failed");
379 void vpnsvc_destroy_deinit(void)
381 DBG("Deinit vpn object.");
384 g_object_unref(vpnsvc);