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 vpnsvc_complete_vpn_init(object, invocation, VPNSVC_ERROR_IO_ERROR, 0, "");
67 result = vpn_service_init(arg_iface_name, arg_iface_name_len, *fds, &handle_s);
69 DBG("handle_s.fd : %d, handle_s.index : %d, handle_s.name : %s",
70 handle_s.fd, handle_s.index, handle_s.name);
72 vpnsvc_complete_vpn_init(object, invocation, result, handle_s.index, handle_s.name);
77 gboolean handle_vpn_deinit(Vpnsvc *object,
78 GDBusMethodInvocation *invocation,
79 const gchar *arg_dev_name)
81 DBG("handle_vpn_deinit");
83 int result = VPNSVC_ERROR_NONE;
85 DBG("vpn_deinit, %s\n", arg_dev_name);
87 result = vpn_service_deinit(arg_dev_name);
89 vpnsvc_complete_vpn_deinit(object, invocation, result);
94 gboolean handle_vpn_protect(Vpnsvc *object,
95 GDBusMethodInvocation *invocation,
96 const gchar *arg_dev_name)
98 DBG("handle_vpn_protect");
100 int result = VPNSVC_ERROR_NONE;
104 GUnixFDList *fd_list;
108 msg = g_dbus_method_invocation_get_message(invocation);
109 fd_list = g_dbus_message_get_unix_fd_list(msg);
110 fds = g_unix_fd_list_peek_fds(fd_list, &fd_list_length);
111 if (fd_list_length <= 0)
112 DBG("D-Bus Message doesn't contain any fd!");
116 vpnsvc_complete_vpn_protect(object, invocation, VPNSVC_ERROR_IO_ERROR);
121 DBG("vpn_protect, %d, %s\n", socket, arg_dev_name);
123 result = vpn_service_protect(socket, arg_dev_name);
125 vpnsvc_complete_vpn_protect(object, invocation, result);
130 gboolean handle_vpn_up(Vpnsvc *object,
131 GDBusMethodInvocation *invocation,
132 const gchar *arg_iface_name)
134 DBG("handle_vpn_up");
136 int result = VPNSVC_ERROR_NONE;
138 result = vpn_service_up(arg_iface_name);
140 vpnsvc_complete_vpn_up(object, invocation, result);
145 gboolean handle_vpn_down(Vpnsvc *object,
146 GDBusMethodInvocation *invocation,
147 const gchar *arg_iface_name)
149 DBG("handle_vpn_down");
151 int result = VPNSVC_ERROR_NONE;
153 result = vpn_service_down(arg_iface_name);
155 vpnsvc_complete_vpn_down(object, invocation, result);
160 #define MAX_NUM_ROUTE_RULE 255
162 gboolean handle_vpn_block_networks(Vpnsvc *object,
163 GDBusMethodInvocation *invocation,
164 GVariant *arg_nets_vpn,
165 guint arg_nr_nets_vpn,
166 GVariant *arg_nets_orig,
167 guint arg_nr_nets_orig)
169 DBG("handle_vpn_block_networks");
171 int result = VPNSVC_ERROR_NONE;
172 if (arg_nr_nets_vpn > MAX_NUM_ROUTE_RULE) {
173 ERR("Number of allowing networks over VPN interface is exceeded %d,"
174 " Limit is %d", arg_nr_nets_vpn, MAX_NUM_ROUTE_RULE);
175 result = VPNSVC_ERROR_INVALID_PARAMETER;
176 goto method_complete;
179 if (arg_nr_nets_orig > MAX_NUM_ROUTE_RULE) {
180 ERR("Number of allowing networks over original interface is exceeded"
181 " %d, Limit is %d", arg_nr_nets_orig, MAX_NUM_ROUTE_RULE);
182 result = VPNSVC_ERROR_INVALID_PARAMETER;
183 goto method_complete;
187 char *nets_vpn[arg_nr_nets_vpn];
188 int prefix_vpn[arg_nr_nets_vpn];
190 char *nets_orig[arg_nr_nets_orig];
191 int prefix_orig[arg_nr_nets_orig];
198 DBG("vpn_block_networks");
200 memset(nets_vpn, 0, sizeof(char *) * arg_nr_nets_vpn);
201 memset(prefix_vpn, 0, sizeof(int) * arg_nr_nets_vpn);
202 memset(nets_orig, 0, sizeof(char *) * arg_nr_nets_orig);
203 memset(prefix_orig, 0, sizeof(int) * arg_nr_nets_orig);
205 /* arg_nets_vpn check */
206 if (arg_nr_nets_vpn > 0) {
207 if (arg_nets_vpn != NULL) {
208 GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn);
209 g_variant_iter_init(&iter, dict_nets_vpn);
211 while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
212 if (i >= arg_nr_nets_vpn) {
213 WARN("No more space for allowing network over VPN interface."
214 " next index %d / space size %d", i, arg_nr_nets_vpn);
218 int tmp_route_len = strlen(route_dest);
219 nets_vpn[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
221 strncpy(nets_vpn[i], route_dest, tmp_route_len);
222 nets_vpn[i][tmp_route_len] = '\0';
223 prefix_vpn[i] = route_prefix;
224 DBG("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]);
225 DBG("prefix_vpn[%d] = %d ", i, prefix_vpn[i]);
232 /* arg_nets_orig check */
233 if (arg_nr_nets_orig > 0) {
234 if (arg_nets_orig != NULL) {
235 GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig);
236 g_variant_iter_init(&iter, dict_nets_orig);
238 while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) {
239 if (i >= arg_nr_nets_orig) {
240 WARN("No more space for allowing network over VPN interface."
241 " next index %d / space size %d", i, arg_nr_nets_orig);
245 int tmp_route_len = strlen(route_dest);
246 nets_orig[i] = g_try_malloc0(sizeof(char) * tmp_route_len + 1);
248 strncpy(nets_orig[i], route_dest, tmp_route_len);
249 nets_orig[i][tmp_route_len] = '\0';
250 prefix_orig[i] = route_prefix;
251 DBG("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]);
252 DBG("prefix_orig[%d] = %d ", i, prefix_orig[i]);
260 result = vpn_service_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig);
262 for (i = 0; i < arg_nr_nets_vpn; ++i) {
266 for (i = 0; i < arg_nr_nets_orig; ++i) {
267 g_free(nets_orig[i]);
272 vpnsvc_complete_vpn_block_networks(object, invocation, result);
277 gboolean handle_vpn_unblock_networks(Vpnsvc *object,
278 GDBusMethodInvocation *invocation)
280 DBG("handle_vpn_unblock_networks");
282 int result = VPNSVC_ERROR_NONE;
284 DBG("vpn_unblock_networks");
286 result = vpn_service_unblock_networks();
288 vpnsvc_complete_vpn_unblock_networks(object, invocation, result);
293 gboolean handle_vpn_update_settings(Vpnsvc *object,
294 GDBusMethodInvocation *invocation,
295 gint arg_iface_index,
296 const gchar *arg_local_ip,
297 const gchar *arg_remote_ip,
300 int result = VPNSVC_ERROR_NONE;
301 DBG("handle_vpn_update_settings");
303 result = vpn_service_update_settings(arg_iface_index, arg_local_ip, arg_remote_ip, arg_mtu);
305 vpnsvc_complete_vpn_update_settings(object, invocation, result);
310 gboolean handle_vpn_add_route(Vpnsvc *object,
311 GDBusMethodInvocation *invocation,
312 gchar *arg_iface_name,
313 const gchar *arg_route,
316 DBG("handle_vpn_add_route");
318 int result = VPNSVC_ERROR_NONE;
320 result = vpn_service_add_route(arg_iface_name, arg_route, arg_prefix);
322 vpnsvc_complete_vpn_add_route(object, invocation, result);
327 gboolean handle_vpn_remove_route(Vpnsvc *object,
328 GDBusMethodInvocation *invocation,
329 gchar *arg_iface_name,
330 const gchar *arg_route,
334 DBG("handle_vpn_remove_route");
336 int result = VPNSVC_ERROR_NONE;
338 result = vpn_service_remove_route(arg_iface_name, arg_route, arg_prefix);
340 vpnsvc_complete_vpn_remove_route(object, invocation, result);
345 gboolean handle_vpn_add_dns_server(Vpnsvc *object,
346 GDBusMethodInvocation *invocation,
347 gchar *arg_iface_name,
348 const gchar *arg_dns_server)
350 DBG("handle_vpn_add_dns_server");
352 int result = VPNSVC_ERROR_NONE;
354 result = vpn_service_add_dns_server(arg_iface_name, arg_dns_server);
356 vpnsvc_complete_vpn_add_dns_server(object, invocation, result);
361 /*****************************
362 * Initializations Functions *
363 ****************************/
364 Vpnsvc *get_vpnsvc_object(void)
369 void vpnsvc_create_and_init(void)
371 DBG("Create vpn object.");
372 GDBusInterfaceSkeleton *interface_vpn = NULL;
373 GDBusConnection *connection = NULL;
374 GDBusObjectManagerServer *server = netdbus_get_vpn_manager();
378 connection = netdbus_get_connection();
379 g_dbus_object_manager_server_set_connection(server, connection);
382 vpnsvc = vpnsvc_skeleton_new();
383 interface_vpn = G_DBUS_INTERFACE_SKELETON(vpnsvc);
386 g_signal_connect(vpnsvc, "handle-vpn-init",
387 G_CALLBACK(handle_vpn_init), NULL);
388 g_signal_connect(vpnsvc, "handle-vpn-deinit",
389 G_CALLBACK(handle_vpn_deinit), NULL);
390 g_signal_connect(vpnsvc, "handle-vpn-protect",
391 G_CALLBACK(handle_vpn_protect), NULL);
392 g_signal_connect(vpnsvc, "handle-vpn-up",
393 G_CALLBACK(handle_vpn_up), NULL);
394 g_signal_connect(vpnsvc, "handle-vpn-down",
395 G_CALLBACK(handle_vpn_down), NULL);
396 g_signal_connect(vpnsvc, "handle-vpn-block-networks",
397 G_CALLBACK(handle_vpn_block_networks), NULL);
398 g_signal_connect(vpnsvc, "handle-vpn-unblock-networks",
399 G_CALLBACK(handle_vpn_unblock_networks), NULL);
400 g_signal_connect(vpnsvc, "handle-vpn-update-settings",
401 G_CALLBACK(handle_vpn_update_settings), NULL);
402 g_signal_connect(vpnsvc, "handle-vpn-add-route",
403 G_CALLBACK(handle_vpn_add_route), NULL);
404 g_signal_connect(vpnsvc, "handle-vpn-remove-route",
405 G_CALLBACK(handle_vpn_remove_route), NULL);
406 g_signal_connect(vpnsvc, "handle-vpn-add-dns-server",
407 G_CALLBACK(handle_vpn_add_dns_server), NULL);
409 if (!g_dbus_interface_skeleton_export(interface_vpn, connection,
410 NETCONFIG_VPNSVC_PATH, NULL)) {
411 ERR("Export NETCONFIG_VPNSVC_PATH for vpn failed");
417 void vpnsvc_destroy_deinit(void)
419 DBG("Deinit vpn object.");
422 g_object_unref(vpnsvc);