From 3f6eecfa8769249f0877a2c6ebe2563c33c8dcd1 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Wed, 16 May 2012 19:40:01 +0200 Subject: daemon: Add utilities to create private DBus servers GDM creates private off-the-bus dbus servers for facilitating communication between its various processes. This commit adds a new function: gdm_dbus_setup_private_server that performs the work necessary to create a private server, including code for generating the socket address, and code for handling new connections. The ultimate goal is to drop our dependency on dbus-glib, and instead use GDBus. gdm_dbus_setup_private_server uses GDBus, so this is one step toward that goal. https://bugzilla.gnome.org/show_bug.cgi?id=622888 --- daemon/gdm-dbus-util.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 daemon/gdm-dbus-util.c (limited to 'daemon/gdm-dbus-util.c') diff --git a/daemon/gdm-dbus-util.c b/daemon/gdm-dbus-util.c new file mode 100644 index 00000000..f77bc92d --- /dev/null +++ b/daemon/gdm-dbus-util.c @@ -0,0 +1,125 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Giovanni Campagna + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#include "gdm-dbus-util.h" +#include + +/* a subset of org.freedesktop.DBus interface, to be used by internal servers */ +static const char *dbus_introspection = +"" +" " +" " +" " +" " +" " +""; + +static void +handle_bus_method (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + g_dbus_method_invocation_return_value (invocation, NULL); +} + +static gboolean +handle_connection (GDBusServer *server, + GDBusConnection *new_connection, + gpointer user_data) +{ + GDBusInterfaceVTable bus_vtable = { handle_bus_method }; + GDBusNodeInfo *bus_info; + + bus_info = g_dbus_node_info_new_for_xml (dbus_introspection, + NULL); + + g_debug ("GdmDBusServer: new connection %p", new_connection); + + g_dbus_connection_register_object (new_connection, + "/org/freedesktop/DBus", + bus_info->interfaces[0], + &bus_vtable, + NULL, NULL, NULL); + g_dbus_node_info_unref (bus_info); + + /* We're not handling the signal */ + return FALSE; +} + +/* Note: Use abstract sockets like dbus does by default on Linux. Abstract + * sockets are only available on Linux. + */ +static char * +generate_address (void) +{ + char *path; + + if (g_unix_socket_address_abstract_names_supported ()) { + int i; + char tmp[9]; + + for (i = 0; i < 8; i++) { + if (g_random_int_range (0, 2) == 0) { + tmp[i] = g_random_int_range ('a', 'z' + 1); + } else { + tmp[i] = g_random_int_range ('A', 'Z' + 1); + } + } + tmp[8] = '\0'; + + path = g_strdup_printf ("unix:abstract=/tmp/gdm-greeter-%s", tmp); + } else { + path = g_strdup ("unix:tmpdir=/tmp"); + } + + return path; +} + +GDBusServer * +gdm_dbus_setup_private_server (GDBusAuthObserver *observer, + GError **error) +{ + char *address, *guid; + GDBusServer *server; + + address = generate_address (); + guid = g_dbus_generate_guid (); + + server = g_dbus_server_new_sync (address, + G_DBUS_SERVER_FLAGS_NONE, + guid, + observer, + NULL, + error); + + g_signal_connect (server, "new-connection", + G_CALLBACK (handle_connection), + NULL); + + g_free (address); + g_free (guid); + + return server; +} -- cgit v1.2.1