#include "vpndbus.h"
#include "vpn_service_daemon.h"
+#include "cynara-client.h"
+#include "cynara-creds-gdbus.h"
+#include "cynara-session.h"
+
#ifdef LOG_TAG
#undef LOG_TAG
#endif
{
LOGD("handle_vpn_init");
- vpnsvc_tun_s handle_s;
int result = VPNSVC_ERROR_NONE;
+
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false
+ || vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_INTERNET) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
+ vpnsvc_tun_s handle_s;
GDBusMessage *msg;
GUnixFDList *fd_list;
int fd_list_length;
LOGD("handle_s.fd : %d, handle_s.index : %d, handle_s.name : %s",
handle_s.fd, handle_s.index, handle_s.name);
+done:
+
vpnsvc_complete_vpn_init(object, invocation, result, handle_s.index, handle_s.name);
return TRUE;
GDBusMethodInvocation *invocation,
const gchar *arg_dev_name)
{
+ LOGD("handle_vpn_deinit");
+
int result = VPNSVC_ERROR_NONE;
- LOGD("handle_vpn_deinit");
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false
+ || vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_INTERNET) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
LOGD("vpn_deinit, %s\n", arg_dev_name);
result = vpn_daemon_deinit(arg_dev_name);
+done:
vpnsvc_complete_vpn_deinit(object, invocation, result);
return TRUE;
GDBusMethodInvocation *invocation,
const gchar *arg_dev_name)
{
+ LOGD("handle_vpn_protect");
+
int result = VPNSVC_ERROR_NONE;
+
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false
+ || vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_INTERNET) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
int socket;
GDBusMessage *msg;
GUnixFDList *fd_list;
int fd_list_length;
const int *fds;
- LOGD("handle_vpn_protect");
-
msg = g_dbus_method_invocation_get_message(invocation);
fd_list = g_dbus_message_get_unix_fd_list(msg);
fds = g_unix_fd_list_peek_fds(fd_list, &fd_list_length);
result = vpn_daemon_protect(socket, arg_dev_name);
+done:
vpnsvc_complete_vpn_protect(object, invocation, result);
return TRUE;
const gchar *arg_dns_suffix,
guint arg_mtu)
{
- int result = VPNSVC_ERROR_NONE;
-
LOGD("handle_vpn_up");
+ int result = VPNSVC_ERROR_NONE;
+
char* routes[arg_nr_routes];
int prefix[arg_nr_routes];
char **dns_servers = NULL;
gchar* route_dest;
gint route_prefix;
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
LOGD("iface_index : %d", arg_iface_index);
LOGD("local ip : %s", arg_local_ip);
LOGD("remote ip : %s", arg_remote_ip);
gint arg_iface_index)
{
LOGD("handle_vpn_down");
+
int result = VPNSVC_ERROR_NONE;
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
LOGD("vpn_down, %d\n", arg_iface_index);
result = vpn_daemon_down(arg_iface_index);
+done:
+
vpnsvc_complete_vpn_down(object, invocation, result);
return TRUE;
guint arg_nr_nets_orig)
{
LOGD("handle_vpn_block_networks");
+
int result = VPNSVC_ERROR_NONE;
char *nets_vpn[arg_nr_nets_vpn];
gchar* route_dest;
gint route_prefix;
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false
+ || vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_INTERNET) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
LOGD("vpn_block_networks");
/* arg_nets_vpn check */
/* call function */
result = vpn_daemon_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig);
+done:
+
vpnsvc_complete_vpn_block_networks(object, invocation, result);
return TRUE;
gboolean handle_vpn_unblock_networks(Vpnsvc *object,
GDBusMethodInvocation *invocation)
{
+ LOGD("handle_vpn_unblock_networks");
+
int result = VPNSVC_ERROR_NONE;
- LOGD("handle_vpn_unblock_networks");
+ /* check privilege */
+ if (vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_VPN_SERVICE_ADMIN) == false
+ || vpn_service_gdbus_check_privilege(invocation, PRIVILEGE_INTERNET) == false) {
+ LOGE("permission denied, and finished request.");
+ result = VPNSVC_ERROR_PERMISSION_DENIED;
+ goto done;
+ }
+
LOGD("vpn_unblock_networks");
result = vpn_daemon_unblock_networks();
+done:
vpnsvc_complete_vpn_unblock_networks(object, invocation, result);
return TRUE;
return;
}
+
+gboolean vpn_service_gdbus_check_privilege(GDBusMethodInvocation *invocation, net_vpn_service_privilege_e _privilege)
+{
+
+ int ret = 0;
+ int pid = 0;
+ char *user;
+ char *client;
+ char *client_session;
+ char *privilege = NULL;
+ cynara *p_cynara = NULL;
+ const char *sender_unique_name;
+ GDBusConnection *connection;
+
+ connection = g_dbus_method_invocation_get_connection(invocation);
+ sender_unique_name = g_dbus_method_invocation_get_sender(invocation);
+
+ ret = cynara_initialize(&p_cynara, NULL);
+ if (ret != CYNARA_API_SUCCESS) {
+ LOGD("cynara_initialize() failed");
+ return FALSE;
+ }
+
+ ret = cynara_creds_gdbus_get_pid(connection, sender_unique_name, &pid);
+ if (ret != CYNARA_API_SUCCESS) {
+ LOGD("cynara_creds_gdbus_get_pid() failed");
+ return FALSE;
+ }
+
+ ret = cynara_creds_gdbus_get_user(connection, sender_unique_name, USER_METHOD_DEFAULT, &user);
+ if (ret != CYNARA_API_SUCCESS) {
+ LOGD("cynara_creds_gdbus_get_user() failed");
+ return FALSE;
+ }
+
+ ret = cynara_creds_gdbus_get_client(connection, sender_unique_name, CLIENT_METHOD_DEFAULT, &client);
+ if (ret != CYNARA_API_SUCCESS) {
+ LOGD("cynara_creds_gdbus_get_client() failed");
+ return FALSE;
+ }
+
+ switch (_privilege)
+ {
+ case PRIVILEGE_VPN_SERVICE:
+ privilege = "http://tizen.org/privilege/vpnservice";
+ break;
+
+ case PRIVILEGE_VPN_SERVICE_ADMIN :
+ privilege = "http://tizen.org/privilege/vpnservice.admin";
+ break;
+
+ case PRIVILEGE_INTERNET :
+ privilege = "http://tizen.org/privilege/internet";
+ break;
+ default :
+ LOGD("Undifined privilege");
+ return FALSE;
+ break;
+ }
+
+ client_session = cynara_session_from_pid(pid);
+
+ ret = cynara_check(p_cynara, client, client_session, user, privilege);
+ if (ret == CYNARA_API_ACCESS_ALLOWED);
+ LOGD("cynara PASS");
+
+ return (ret == CYNARA_API_ACCESS_ALLOWED) ? TRUE : FALSE;
+}
if (reply == NULL) {
if (error != NULL) {
- LOGE("g_dbus_connection_call_sync() failed" //LCOV_EXCL_LINE
- "error [%d: %s]", error->code, error->message);
- *dbus_error = VPNSVC_ERROR_IO_ERROR; //LCOV_EXCL_LINE
- g_error_free(error); //LCOV_EXCL_LINE
+ if (error->code == G_DBUS_ERROR_ACCESS_DENIED){
+ LOGE("g_dbus_connection_call_sync() failed"
+ "error [%d: %s]", error->code, error->message);//LCOV_EXCL_LINE
+ *dbus_error = VPNSVC_ERROR_PERMISSION_DENIED;//LCOV_EXCL_LINE
+ g_error_free(error);//LCOV_EXCL_LINE
+ } else {
+ LOGE("g_dbus_connection_call_sync() failed"
+ "error [%d: %s]", error->code, error->message);//LCOV_EXCL_LINE
+ *dbus_error = VPNSVC_ERROR_IO_ERROR;//LCOV_EXCL_LINE
+ g_error_free(error);//LCOV_EXCL_LINE
+ }
} else {
- LOGE("g_dbus_connection_call_sync() failed"); //LCOV_EXCL_LINE
- *dbus_error = VPNSVC_ERROR_IPC_FAILED; //LCOV_EXCL_LINE
+ LOGE("g_dbus_connection_call_sync() failed");//LCOV_EXCL_LINE
+ *dbus_error = VPNSVC_ERROR_IPC_FAILED;//LCOV_EXCL_LINE
}
return NULL;
g_variant_new("(su)", VPNSVC_DBUS_SERVICE_NAME, 0),
&dbus_result);
+ if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED){
+ return VPNSVC_ERROR_PERMISSION_DENIED;
+ }
+
if (op == NULL) {
_vpnsvc_deinit_vpnsvc_tun_s(tmp_s); //LCOV_EXCL_LINE
LOGD("Service [%s] Start Failed!", VPNSVC_DBUS_SERVICE_NAME); //LCOV_EXCL_LINE
g_variant_new("(s)", tun_s->name),
&dbus_result);
+ if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED){
+ return VPNSVC_ERROR_PERMISSION_DENIED;
+ }
+
if (op == NULL) {
return VPNSVC_ERROR_IPC_FAILED; //LCOV_EXCL_LINE
} else {
socket_fd,
&dbus_result);
+ if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED){
+ return VPNSVC_ERROR_PERMISSION_DENIED;
+ }
+
if (op == NULL) {
return VPNSVC_ERROR_IPC_FAILED; //LCOV_EXCL_LINE
} else {
nets_param_orig, num_allow_routes_orig),
&dbus_result);
+ if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED){
+ return VPNSVC_ERROR_PERMISSION_DENIED;
+ }
+
if (op == NULL) {
return VPNSVC_ERROR_IPC_FAILED; //LCOV_EXCL_LINE
} else {
g_variant_new("()"),
&dbus_result);
+ if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED){
+ return VPNSVC_ERROR_PERMISSION_DENIED;
+ }
+
if (op == NULL) {
return VPNSVC_ERROR_IPC_FAILED; //LCOV_EXCL_LINE
} else {
/**
* @brief De-Initializes VPN interface.
* @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/vpnservice \n
+ * %http://tizen.org/privilege/internet
* @param[in] handle The VPN interface handle
* @return 0 on success. otherwise, a negative error value.
* @retval #VPNSVC_ERROR_NONE Success
* @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon
+ * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied
* @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported
* @pre Before calling this function, VPN interface should be initialized already.
* @see vpnsvc_init()
* @brief Protect a socket from VPN connections.
* @details After protecting, data sent through this socket will go directly to the underlying network.
* @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/vpnservice \n
+ * %http://tizen.org/privilege/internet
* @param[in] handle The VPN interface handle
* @param[in] socket_fd The opened socket file descriptor
* @param[in] iface_name The network interface name (e.g., interface name such as eth0, ppp0, etc) through which the VPN is working
* @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error)
* @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon
+ * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied
* @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported
*/
int vpnsvc_protect(vpnsvc_h handle, int socket_fd, const char* iface_name);
/**
* @brief Blocks all traffics except specified allowing networks.
* @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/vpnservice \n
+ * %http://tizen.org/privilege/internet
* @param[in] handle The VPN interface handle
* @param[in] routes_dest_vpn_addr Destination address of the routes, the list of allowing networks over VPN interface (e.g., VPN interface such as tun0, etc).
* @param[in] routes_vpn_prefix The prefix of VPN interface, netmask length (also called a prefix, e.g. 8, 16, 24, 32).
* @retval #VPNSVC_ERROR_NONE Success
* @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon
+ * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied
* @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported
* @post Please call vpnsvc_unblock_networks() if you want to allow all traffics.
* @see vpnsvc_unblock_networks()
/**
* @brief Removes any restrictions imposed by vpnsvc_block_networks().
* @since_tizen 3.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/vpnservice \n
+ * %http://tizen.org/privilege/internet
* @param[in] handle The VPN interface handle
* @return 0 on success. otherwise, a negative error value.
* @retval #VPNSVC_ERROR_NONE Success
* @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon
+ * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied
* @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported
*/
int vpnsvc_unblock_networks(vpnsvc_h handle);