static void on_get_connection_unix_process_id (DBusPendingCall *pending, gpointer user_data) { on_get_connection_unix_process_id_args *args = user_data; DBusMessage *reply = NULL; DBusError error = DBUS_ERROR_INIT; dbus_uint32_t caller_pid = 0; GkdSecretService *self; ServiceClient *client; const gchar *caller; g_return_if_fail (GKD_SECRET_IS_SERVICE (args->self)); self = args->self; /* Get the resulting process ID */ reply = dbus_pending_call_steal_reply (pending); g_return_if_fail (reply); caller = dbus_message_get_sender (args->message); g_return_if_fail (caller); client = g_hash_table_lookup (self->clients, caller); if (client == NULL) { /* An error returned from GetConnectionUnixProcessID */ if (dbus_set_error_from_message (&error, reply)) { g_message ("couldn't get the caller's unix process id: %s", error.message); caller_pid = 0; dbus_error_free (&error); /* A PID was returned from GetConnectionUnixProcessID */ } else { if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &caller_pid, DBUS_TYPE_INVALID)) g_return_if_reached (); } /* Initialize the client object */ client = g_new0 (ServiceClient, 1); client->caller_peer = g_strdup (caller); client->caller_pid = caller_pid; if (caller_pid != 0) client->caller_exec = egg_unix_credentials_executable (caller_pid); client->app.applicationData = client; client->sessions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, dispose_and_unref); client->prompts = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, dispose_and_unref); g_hash_table_replace (self->clients, client->caller_peer, client); /* Update default collection each time someone connects */ update_default (self, TRUE); } dbus_message_unref (reply); /* Dispatch the original message again */ service_dispatch_message (self, args->message); }
static DBusHandlerResult gkd_secret_service_filter_handler (DBusConnection *conn, DBusMessage *message, gpointer user_data) { GkdSecretService *self = user_data; const gchar *object_name; const gchar *old_owner; const gchar *new_owner; const gchar *path; const gchar *interface; g_return_val_if_fail (conn && message, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), DBUS_HANDLER_RESULT_NOT_YET_HANDLED); /* org.freedesktop.DBus.NameOwnerChanged(STRING name, STRING old_owner, STRING new_owner) */ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged") && dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &object_name, DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID)) { /* * A peer is connecting or disconnecting from the bus, * remove any client info, when client gone. */ g_return_val_if_fail (object_name && new_owner, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); if (g_str_equal (new_owner, "") && object_name[0] == ':') g_hash_table_remove (self->clients, object_name); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } /* * If the path is a within our object tree, then we do our own dispatch. */ path = dbus_message_get_path (message); switch (dbus_message_get_type (message)) { /* Dispatch any method call on our interfaces, for our objects */ case DBUS_MESSAGE_TYPE_METHOD_CALL: if (object_path_has_prefix (path, SECRET_SERVICE_PATH)) { interface = dbus_message_get_interface (message); if (interface == NULL || g_str_has_prefix (interface, SECRET_INTERFACE_PREFIX) || g_str_equal (interface, DBUS_INTERFACE_PROPERTIES) || g_str_equal (interface, INTERNAL_SERVICE_INTERFACE) || g_str_equal (interface, DBUS_INTERFACE_INTROSPECTABLE)) { service_dispatch_message (self, message); return DBUS_HANDLER_RESULT_HANDLED; } } break; /* Dispatch any signal for one of our objects */ case DBUS_MESSAGE_TYPE_SIGNAL: if (object_path_has_prefix (path, SECRET_SERVICE_PATH)) { service_dispatch_message (self, message); return DBUS_HANDLER_RESULT_HANDLED; } break; default: break; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }