remote-desktop, screen-cast: Fail session method calls from other peers

Only accept method calls on the session objects from the same peer that
created the session.

https://bugzilla.gnome.org/show_bug.cgi?id=784199
This commit is contained in:
Jonas Ådahl 2017-08-25 15:19:53 +08:00
parent 921b18f713
commit 6e46ad9f3a
6 changed files with 120 additions and 2 deletions

View File

@ -42,6 +42,8 @@ struct _MetaRemoteDesktopSession
{ {
MetaDBusRemoteDesktopSessionSkeleton parent; MetaDBusRemoteDesktopSessionSkeleton parent;
char *peer_name;
char *session_id; char *session_id;
char *object_path; char *object_path;
@ -165,6 +167,7 @@ meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSession *ses
MetaRemoteDesktopSession * MetaRemoteDesktopSession *
meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop, meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
const char *peer_name,
GError **error) GError **error)
{ {
GDBusInterfaceSkeleton *interface_skeleton; GDBusInterfaceSkeleton *interface_skeleton;
@ -173,6 +176,8 @@ meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL); session = g_object_new (META_TYPE_REMOTE_DESKTOP_SESSION, NULL);
session->peer_name = g_strdup (peer_name);
interface_skeleton = G_DBUS_INTERFACE_SKELETON (session); interface_skeleton = G_DBUS_INTERFACE_SKELETON (session);
connection = meta_remote_desktop_get_connection (remote_desktop); connection = meta_remote_desktop_get_connection (remote_desktop);
if (!g_dbus_interface_skeleton_export (interface_skeleton, if (!g_dbus_interface_skeleton_export (interface_skeleton,
@ -187,6 +192,14 @@ meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
return session; return session;
} }
static gboolean
check_permission (MetaRemoteDesktopSession *session,
GDBusMethodInvocation *invocation)
{
return g_strcmp0 (session->peer_name,
g_dbus_method_invocation_get_sender (invocation)) == 0;
}
static gboolean static gboolean
handle_start (MetaDBusRemoteDesktopSession *skeleton, handle_start (MetaDBusRemoteDesktopSession *skeleton,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
@ -194,6 +207,14 @@ handle_start (MetaDBusRemoteDesktopSession *skeleton,
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
GError *error = NULL; GError *error = NULL;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
if (!meta_remote_desktop_session_start (session, &error)) if (!meta_remote_desktop_session_start (session, &error))
{ {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@ -218,6 +239,14 @@ handle_stop (MetaDBusRemoteDesktopSession *skeleton,
{ {
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
meta_remote_desktop_session_close (session); meta_remote_desktop_session_close (session);
meta_dbus_remote_desktop_session_complete_stop (skeleton, invocation); meta_dbus_remote_desktop_session_complete_stop (skeleton, invocation);
@ -232,9 +261,16 @@ handle_notify_keyboard_keysym (MetaDBusRemoteDesktopSession *skeleton,
gboolean pressed) gboolean pressed)
{ {
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
ClutterKeyState state; ClutterKeyState state;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
if (pressed) if (pressed)
state = CLUTTER_KEY_STATE_PRESSED; state = CLUTTER_KEY_STATE_PRESSED;
else else
@ -281,6 +317,14 @@ handle_notify_pointer_button (MetaDBusRemoteDesktopSession *skeleton,
uint32_t button; uint32_t button;
ClutterButtonState state; ClutterButtonState state;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
button = translate_to_clutter_button (button_code); button = translate_to_clutter_button (button_code);
if (pressed) if (pressed)
@ -324,6 +368,14 @@ handle_notify_pointer_axis_discrete (MetaDBusRemoteDesktopSession *skeleton,
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
ClutterScrollDirection direction; ClutterScrollDirection direction;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
if (axis <= 1) if (axis <= 1)
{ {
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@ -369,6 +421,14 @@ handle_notify_pointer_motion_absolute (MetaDBusRemoteDesktopSession *skeleton,
{ {
MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton); MetaRemoteDesktopSession *session = META_REMOTE_DESKTOP_SESSION (skeleton);
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
clutter_virtual_input_device_notify_absolute_motion (session->virtual_pointer, clutter_virtual_input_device_notify_absolute_motion (session->virtual_pointer,
CLUTTER_CURRENT_TIME, CLUTTER_CURRENT_TIME,
x, y); x, y);
@ -409,6 +469,7 @@ meta_remote_desktop_session_finalize (GObject *object)
g_assert (!meta_remote_desktop_session_is_running (session)); g_assert (!meta_remote_desktop_session_is_running (session));
g_free (session->peer_name);
g_free (session->session_id); g_free (session->session_id);
g_free (session->object_path); g_free (session->object_path);

View File

@ -44,6 +44,7 @@ gboolean meta_remote_desktop_session_register_screen_cast (MetaRemoteDesktopSess
void meta_remote_desktop_session_close (MetaRemoteDesktopSession *session); void meta_remote_desktop_session_close (MetaRemoteDesktopSession *session);
MetaRemoteDesktopSession * meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop, MetaRemoteDesktopSession * meta_remote_desktop_session_new (MetaRemoteDesktop *remote_desktop,
const char *peer_name,
GError **error); GError **error);
#endif /* META_REMOTE_DESKTOP_SESSION_H */ #endif /* META_REMOTE_DESKTOP_SESSION_H */

View File

@ -94,13 +94,16 @@ handle_create_session (MetaDBusRemoteDesktop *skeleton,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
{ {
MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (skeleton); MetaRemoteDesktop *remote_desktop = META_REMOTE_DESKTOP (skeleton);
const char *peer_name;
MetaRemoteDesktopSession *session; MetaRemoteDesktopSession *session;
GError *error = NULL; GError *error = NULL;
char *session_id; char *session_id;
char *session_path; char *session_path;
const char *client_dbus_name; const char *client_dbus_name;
peer_name = g_dbus_method_invocation_get_sender (invocation);
session = meta_remote_desktop_session_new (remote_desktop, session = meta_remote_desktop_session_new (remote_desktop,
peer_name,
&error); &error);
if (!session) if (!session)
{ {

View File

@ -35,6 +35,8 @@ struct _MetaScreenCastSession
{ {
MetaDBusScreenCastSessionSkeleton parent; MetaDBusScreenCastSessionSkeleton parent;
char *peer_name;
MetaScreenCastSessionType session_type; MetaScreenCastSessionType session_type;
char *object_path; char *object_path;
@ -101,6 +103,14 @@ meta_screen_cast_session_get_object_path (MetaScreenCastSession *session)
return session->object_path; return session->object_path;
} }
static gboolean
check_permission (MetaScreenCastSession *session,
GDBusMethodInvocation *invocation)
{
return g_strcmp0 (session->peer_name,
g_dbus_method_invocation_get_sender (invocation)) == 0;
}
static gboolean static gboolean
handle_start (MetaDBusScreenCastSession *skeleton, handle_start (MetaDBusScreenCastSession *skeleton,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
@ -108,6 +118,14 @@ handle_start (MetaDBusScreenCastSession *skeleton,
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
GError *error = NULL; GError *error = NULL;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
switch (session->session_type) switch (session->session_type)
{ {
case META_SCREEN_CAST_SESSION_TYPE_NORMAL: case META_SCREEN_CAST_SESSION_TYPE_NORMAL:
@ -141,6 +159,14 @@ handle_stop (MetaDBusScreenCastSession *skeleton,
{ {
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton); MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
switch (session->session_type) switch (session->session_type)
{ {
case META_SCREEN_CAST_SESSION_TYPE_NORMAL: case META_SCREEN_CAST_SESSION_TYPE_NORMAL:
@ -185,6 +211,14 @@ handle_record_monitor (MetaDBusScreenCastSession *skeleton,
MetaScreenCastStream *stream; MetaScreenCastStream *stream;
char *stream_path; char *stream_path;
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton); interface_skeleton = G_DBUS_INTERFACE_SKELETON (skeleton);
connection = g_dbus_interface_skeleton_get_connection (interface_skeleton); connection = g_dbus_interface_skeleton_get_connection (interface_skeleton);
@ -238,6 +272,16 @@ handle_record_window (MetaDBusScreenCastSession *skeleton,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
GVariant *properties_variant) GVariant *properties_variant)
{ {
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (skeleton);
if (!check_permission (session, invocation))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
"Permission denied");
return TRUE;
}
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
G_DBUS_ERROR_FAILED, G_DBUS_ERROR_FAILED,
"Recording a window not yet supported"); "Recording a window not yet supported");
@ -268,6 +312,7 @@ meta_dbus_session_init_iface (MetaDbusSessionInterface *iface)
MetaScreenCastSession * MetaScreenCastSession *
meta_screen_cast_session_new (MetaScreenCast *screen_cast, meta_screen_cast_session_new (MetaScreenCast *screen_cast,
MetaScreenCastSessionType session_type, MetaScreenCastSessionType session_type,
const char *peer_name,
GError **error) GError **error)
{ {
GDBusInterfaceSkeleton *interface_skeleton; GDBusInterfaceSkeleton *interface_skeleton;
@ -277,6 +322,7 @@ meta_screen_cast_session_new (MetaScreenCast *screen_cast,
session = g_object_new (META_TYPE_SCREEN_CAST_SESSION, NULL); session = g_object_new (META_TYPE_SCREEN_CAST_SESSION, NULL);
session->session_type = session_type; session->session_type = session_type;
session->peer_name = g_strdup (peer_name);
session->object_path = session->object_path =
g_strdup_printf (META_SCREEN_CAST_SESSION_DBUS_PATH "/u%u", g_strdup_printf (META_SCREEN_CAST_SESSION_DBUS_PATH "/u%u",
++global_session_number); ++global_session_number);
@ -297,6 +343,7 @@ meta_screen_cast_session_finalize (GObject *object)
{ {
MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (object); MetaScreenCastSession *session = META_SCREEN_CAST_SESSION (object);
g_free (session->peer_name);
g_free (session->object_path); g_free (session->object_path);
G_OBJECT_CLASS (meta_screen_cast_session_parent_class)->finalize (object); G_OBJECT_CLASS (meta_screen_cast_session_parent_class)->finalize (object);

View File

@ -40,6 +40,7 @@ char * meta_screen_cast_session_get_object_path (MetaScreenCastSession *session)
MetaScreenCastSession * meta_screen_cast_session_new (MetaScreenCast *screen_cast, MetaScreenCastSession * meta_screen_cast_session_new (MetaScreenCast *screen_cast,
MetaScreenCastSessionType session_type, MetaScreenCastSessionType session_type,
const char *peer_name,
GError **error); GError **error);
gboolean meta_screen_cast_session_start (MetaScreenCastSession *session, gboolean meta_screen_cast_session_start (MetaScreenCastSession *session,

View File

@ -100,6 +100,7 @@ handle_create_session (MetaDBusScreenCast *skeleton,
GVariant *properties) GVariant *properties)
{ {
MetaScreenCast *screen_cast = META_SCREEN_CAST (skeleton); MetaScreenCast *screen_cast = META_SCREEN_CAST (skeleton);
const char *peer_name;
MetaScreenCastSession *session; MetaScreenCastSession *session;
GError *error = NULL; GError *error = NULL;
const char *session_path; const char *session_path;
@ -115,7 +116,11 @@ handle_create_session (MetaDBusScreenCast *skeleton,
else else
session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL; session_type = META_SCREEN_CAST_SESSION_TYPE_NORMAL;
session = meta_screen_cast_session_new (screen_cast, session_type, &error); peer_name = g_dbus_method_invocation_get_sender (invocation);
session = meta_screen_cast_session_new (screen_cast,
session_type,
peer_name,
&error);
if (!session) if (!session)
{ {
g_warning ("Failed to create screen cast session: %s", g_warning ("Failed to create screen cast session: %s",