diff options
Diffstat (limited to 'src/ka-dbus.c')
-rw-r--r-- | src/ka-dbus.c | 273 |
1 files changed, 200 insertions, 73 deletions
diff --git a/src/ka-dbus.c b/src/ka-dbus.c index f8a00d6..4a7be2c 100644 --- a/src/ka-dbus.c +++ b/src/ka-dbus.c @@ -1,6 +1,6 @@ /* Krb5 Auth Applet -- Acquire and release kerberos tickets * - * (C) 2008,2009 Guido Guenther <agx@sigxcpu.org> + * (C) 2008,2009,2011 Guido Guenther <agx@sigxcpu.org> * * 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 @@ -20,100 +20,227 @@ #include "config.h" -#include <dbus/dbus-glib.h> #include "ka-applet-priv.h" #include "ka-dialog.h" #include "ka-dbus.h" -#include "ka-dbus-glue.h" -static DBusGConnection *session; +static guint dbus_owner_id; +static GDBusConnection *dbus_connection; +static const char *dbus_object_path = "/org/gnome/KrbAuthDialog"; +static const char *dbus_interface_name = "org.gnome.KrbAuthDialog"; +static GDBusNodeInfo *introspection_data; + gboolean ka_dbus_acquire_tgt (KaApplet *applet, - const gchar *principal, DBusGMethodInvocation *context) + const gchar *principal) { - gboolean success; + gboolean success; - KA_DEBUG("Getting TGT for '%s'", principal); - success = ka_check_credentials(applet, principal); - dbus_g_method_return(context, success); - return TRUE; + KA_DEBUG ("Getting TGT for '%s'", principal); + success = ka_check_credentials (applet, principal); + return success; } gboolean -ka_dbus_destroy_ccache(KaApplet* applet, DBusGMethodInvocation *context) +ka_dbus_destroy_ccache (KaApplet *applet) { - gboolean success; + gboolean success; - KA_DEBUG("Destroying ticket cache"); - success = ka_destroy_ccache (applet); - dbus_g_method_return(context, success); - return TRUE; + KA_DEBUG ("Destroying ticket cache"); + success = ka_destroy_ccache (applet); + return success; } -gboolean -ka_dbus_service(KaApplet* applet) +static const gchar ka_dbus_introspection_xml[] = + "<node>" + " <interface name='org.gnome.KrbAuthDialog'>" + " <method name='acquireTgt'>" + " <arg type='s' name='principal' direction='in' />" + " <arg type='b' name='success' direction='out'/>" + " </method>" + " <method name='destroyCCache'>" + " <arg type='b' name='success' direction='out'/>" + " </method>" + " <signal name='krb_tgt_acquired'>" + " <arg type='s' name='principal' direction ='out'/>" + " <arg type='u' name='expiry' direction ='out'/>" + " </signal>" + " <signal name='krb_tgt_renewed'>" + " <arg type='s' name='principal' direction ='out'/>" + " <arg type='u' name='expiry' direction ='out'/>" + " </signal>" + " <signal name='krb_tgt_expired'>" + " <arg type='s' name='principal' direction ='out'/>" + " <arg type='u' name='expiry' direction ='out'/>" + " </signal>" + " </interface>" + "</node>"; + + +static void +ka_dbus_handle_method_call (GDBusConnection *connection G_GNUC_UNUSED, + const gchar *sender G_GNUC_UNUSED, + const gchar *object_path G_GNUC_UNUSED, + const gchar *interface_name G_GNUC_UNUSED, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - dbus_g_connection_register_g_object (session, - "/org/gnome/KrbAuthDialog", - G_OBJECT(applet)); - return TRUE; + KaApplet *applet = user_data; + gboolean ret; + + g_warn_if_fail (applet != NULL); + + if (g_strcmp0 (method_name, "acquireTgt") == 0) { + const char *principal; + + g_variant_get (parameters, "(s)", &principal); + ret = ka_dbus_acquire_tgt (applet, principal); + g_dbus_method_invocation_return_value (invocation, + g_variant_new("(b)", ret)); + } else if (g_strcmp0 (method_name, "destroyCCache") == 0) { + ret = ka_dbus_destroy_ccache (applet); + g_dbus_method_invocation_return_value (invocation, + g_variant_new("(b)", ret)); + } +} + +static gchar* ka_dbus_signal_name (const gchar *name) +{ + gchar *c; + gchar *signal_name = g_strdup(name); + + /* The DBus signal names use underscores */ + for (c = signal_name; *c != '\0'; c++ ) { + if (*c == '-') + *c = '_'; + } + + return signal_name; +} + +/* Emit DBus signals */ +static void +ka_dbus_signal_cb (gpointer *applet G_GNUC_UNUSED, + gchar *princ, + guint when, gpointer user_data) +{ + GError *error = NULL; + gchar *signal_name; + + signal_name = ka_dbus_signal_name(user_data); + if (!g_dbus_connection_emit_signal (dbus_connection, + NULL, + dbus_object_path, + dbus_interface_name, + signal_name, + g_variant_new ("(su)", + princ, + when), + &error)) { + g_warning ("Failed to emit DBus signal %s: %s", + signal_name, + error->message); + g_clear_error (&error); + } + g_free (signal_name); +} + + +static void +ka_dbus_connect_signals(KaApplet *applet) +{ + int i; + + for (i = 0; i < KA_SIGNAL_COUNT; i++) { + g_signal_connect (applet, ka_signal_names[i], + G_CALLBACK (ka_dbus_signal_cb), + (gpointer)ka_signal_names[i]); + } +} + + +static const GDBusInterfaceVTable interface_vtable = +{ + .method_call = ka_dbus_handle_method_call, +}; + + +static void +ka_dbus_on_name_acquired (GDBusConnection *connection, + const gchar *name G_GNUC_UNUSED, + gpointer user_data) +{ + KaApplet *applet = user_data; + guint id; + + introspection_data = g_dbus_node_info_new_for_xml ( + ka_dbus_introspection_xml, + NULL); + + id = g_dbus_connection_register_object (connection, + "/org/gnome/KrbAuthDialog", + introspection_data->interfaces[0], + &interface_vtable, + applet, + NULL, /* user_data_free_func */ + NULL); /* GError** */ + if (!id) + g_error ("Failed to regiester DBus object"); + ka_dbus_connect_signals (applet); + + dbus_connection = connection; +} + + +static void +ka_dbus_on_name_lost (GDBusConnection *connection G_GNUC_UNUSED, + const gchar *name G_GNUC_UNUSED, + gpointer user_data) +{ + KaApplet *applet = user_data; + + g_warning ("Cannot acquire DBUS name"); + ka_applet_destroy (applet); +} + + +void +ka_dbus_disconnect () +{ + if (introspection_data) { + g_dbus_node_info_unref (introspection_data); + introspection_data = NULL; + } + + if (dbus_owner_id) { + g_bus_unown_name (dbus_owner_id); + dbus_owner_id = 0; + } + dbus_connection = NULL; } gboolean -ka_dbus_connect(unsigned int* status) +ka_dbus_connect (KaApplet *applet) { - guint request_name_reply; - unsigned int flags; - DBusGProxy *bus_proxy; - GError *error = NULL; - - /* Connect to the session bus so we get exit-on-disconnect semantics. */ - session = dbus_g_bus_get(DBUS_BUS_SESSION, &error); - if (session == NULL) { - g_error ("couldn't connect to session bus: %s", (error) ? error->message : "(null)"); - *status = 1; - g_clear_error (&error); - return FALSE; - } - flags = DBUS_NAME_FLAG_DO_NOT_QUEUE; - bus_proxy = dbus_g_proxy_new_for_name (session, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - - dbus_g_object_type_install_info(KA_TYPE_APPLET, - &dbus_glib_krb5_auth_dialog_object_info); - - if (!dbus_g_proxy_call (bus_proxy, - "RequestName", - &error, - G_TYPE_STRING, - "org.gnome.KrbAuthDialog", - G_TYPE_UINT, - flags, - G_TYPE_INVALID, - G_TYPE_UINT, - &request_name_reply, - G_TYPE_INVALID)) { - g_warning ("Failed to invoke RequestName: %s", - error->message); - } - g_clear_error (&error); - g_object_unref (bus_proxy); - - if (request_name_reply == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER - || request_name_reply == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) - ; - else if (request_name_reply == DBUS_REQUEST_NAME_REPLY_EXISTS - || request_name_reply == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { - *status = 0; - return FALSE; - } else { - g_assert_not_reached(); - } - return TRUE; + g_return_val_if_fail (applet != 0, FALSE); + + dbus_owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, + "org.gnome.KrbAuthDialog", + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, + NULL, + ka_dbus_on_name_acquired, + ka_dbus_on_name_lost, + applet, + NULL); + return TRUE; } + +/* + * vim:ts=4:sts=4:sw=4:et: + */ |