Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
292 changes: 226 additions & 66 deletions packages/cpp/dbus-proxy/dbus-proxy/callback-handling.cpp

Large diffs are not rendered by default.

46 changes: 43 additions & 3 deletions packages/cpp/dbus-proxy/dbus-proxy/callback-rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,29 @@

#include "dbus_proxy.h"

const gchar* nm_agent_methods[] = {"GetSecrets", "CancelGetSecrets", "SaveSecrets", "DeleteSecrets",
nullptr};
const GDBusMethodTable nm_agent_methods[] = {{"GetSecrets", "a{sa{sv}}osasu", "a{sa{sv}}"},
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
{"CancelGetSecrets", "os", ""},
{"SaveSecrets", "a{sa{sv}}o", ""},
{"DeleteSecrets", "a{sa{sv}}o", ""},
{nullptr, nullptr, nullptr}};

const GDBusMethodTable bluez_agent_methods[] = {
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
{"RequestPinCode", "o", "s"}, {"DisplayPinCode", "os", ""},
{"RequestPasskey", "o", "u"}, {"DisplayPasskey", "ouq", ""},
{"RequestConfirmation", "ou", ""}, {"RequestAuthorization", "o", ""},
{"AuthorizeService", "os", ""}, {"Cancel", "", ""},
{nullptr, nullptr, nullptr}};

const GDBusMethodTable obex_agent_methods[] = {
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
{"CreateSession", "s", "sa{sv}"}, {"RemoveSession", "o", ""}, {nullptr, nullptr, nullptr}};

const AgentRule callbacks_rules[] = {
{.bus_name = DBUS_NETWORK_MANAGER_NAME,
.manager_path = "/org/freedesktop/NetworkManager/AgentManager",
.manager_interface = "org.freedesktop.NetworkManager.AgentManager",
.register_method = "Register",
.unregister_method = "Unregister",
.use_object_path_on_unregister = FALSE,
.object_path_customisable = FALSE,
.client_object_path = DBUS_NM_AGENT_PATH,
.client_interface = DBUS_INTERFACE_SECRET_AGENT,
Expand All @@ -24,12 +38,38 @@ const AgentRule callbacks_rules[] = {
.manager_interface = "org.freedesktop.NetworkManager.AgentManager",
.register_method = "RegisterWithCapabilities",
.unregister_method = "Unregister",
.use_object_path_on_unregister = FALSE,
.object_path_customisable = FALSE,

.client_object_path = DBUS_NM_AGENT_PATH,
.client_interface = DBUS_INTERFACE_SECRET_AGENT,
.client_methods = nm_agent_methods},
{nullptr, nullptr, nullptr, nullptr, nullptr, FALSE, nullptr, nullptr, nullptr}};

{.bus_name = DBUS_BLUEZ_NAME,
.manager_path = "/org/bluez",
.manager_interface = "org.bluez.AgentManager1",
.register_method = "RegisterAgent",
.unregister_method = "UnregisterAgent",
.use_object_path_on_unregister = TRUE,
.object_path_customisable = FALSE,

.client_object_path = DBUS_BLUEZ_AGENT_PATH,
.client_interface = DBUS_BLUEZ_AGENT_INTERFACE,
.client_methods = bluez_agent_methods},

{.bus_name = DBUS_OBEX_NAME,
.manager_path = "/org/bluez/obex",
.manager_interface = "org.bluez.obex.AgentManager1",
.register_method = "RegisterAgent",
.unregister_method = "UnregisterAgent",
.use_object_path_on_unregister = FALSE,
.object_path_customisable = FALSE,

.client_object_path = DBUS_OBEX_AGENT_PATH,
.client_interface = DBUS_OBEX_AGENT_INTERFACE,
.client_methods = obex_agent_methods},

{nullptr, nullptr, nullptr, nullptr, nullptr, FALSE, FALSE, nullptr, nullptr, nullptr}};

const AgentRule* get_callback_rule(const gchar* bus_name, const gchar* interface_name,
const gchar* method_name) {
Expand Down
24 changes: 16 additions & 8 deletions packages/cpp/dbus-proxy/dbus-proxy/callback-rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,27 @@
#ifndef CALLBACK_RULES_H
#define CALLBACK_RULES_H

typedef struct {
const gchar* name; // method name
const gchar* in_signature; // e.g. "os", "a{sv}", "" (or nullptr)
const gchar* out_signature; // e.g. "", "b", "o"
} GDBusMethodTable;

struct AgentRule {
const gchar* bus_name; // "org.bluez"
const gchar* manager_path; // "/org/freedesktop/NetworkManager/AgentManager"
const gchar* manager_interface; // "org.bluez.AgentManager1"
const gchar* register_method; // "RegisterAgent"
const gchar* unregister_method; // "UnregisterAgent"
const gchar* bus_name; // "org.bluez"
const gchar* manager_path; // "/org/freedesktop/NetworkManager/AgentManager"
const gchar* manager_interface; // "org.bluez.AgentManager1"
const gchar* register_method; // "RegisterAgent"
const gchar* unregister_method; // "UnregisterAgent"
const gboolean use_object_path_on_unregister; // whether to use the object path or unique path
// for unregistration
// set to true when client sends its agent object path
// which can be customized
const gboolean object_path_customisable;

const gchar* client_object_path; // "/org/bluez/agent"
const gchar* client_interface; // "org.bluez.Agent1"
const gchar** client_methods; // NULL-terminated array of method names
const gchar* client_object_path; // "/org/bluez/agent"
const gchar* client_interface; // "org.bluez.Agent1"
const GDBusMethodTable* client_methods; // NULL-terminated array of method tables
};

extern const AgentRule callbacks_rules[];
Expand Down
18 changes: 10 additions & 8 deletions packages/cpp/dbus-proxy/dbus-proxy/dbus_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ typedef struct {
guint catch_interfaces_removed_subscription_id;
GHashTable* proxied_objects;
GHashTable* node_info_cache;
GPtrArray* agents_registry; /* jarekk: temporary, to be replaced */
GHashTable* senders_registry;
GPtrArray* agents_registry;
GRWLock rw_lock;
guint sigint_source_id;
guint sigterm_source_id;
guint message_count;
GMainLoop* main_loop;
} ProxyState;

Expand All @@ -68,6 +68,7 @@ struct AgentData {
struct MethodCallContext {
GDBusMethodInvocation* invocation;
gchar* forward_bus_name;
guint call_number; // For logging purposes
};

extern ProxyState* proxy_state;
Expand Down Expand Up @@ -124,7 +125,7 @@ void handle_method_call_generic(GDBusConnection* connection, const gchar* sender
GBusType parse_bus_type(const gchar* bus_str);
void validateProxyConfigOrExit(ProxyConfig* config);
void method_call_reply_callback(GObject* source, GAsyncResult* res, gpointer user_data);
GDBusInterfaceInfo* build_interface_info(const gchar* iface_name, const gchar** methods);
GDBusInterfaceInfo* build_interface_info(const AgentRule* rule);
void free_interface_info(GDBusInterfaceInfo* iface);
const gchar* get_agent_name(const gchar* object_path, const gchar* interface_name,
const gchar* method_name);
Expand All @@ -135,14 +136,15 @@ gboolean register_agent_callback(const gchar* sender, const gchar* object_path,
GDBusInterfaceInfo* ifac);
gboolean handle_agent_register_call(const gchar* sender, const gchar* object_path,
const gchar* interface_name, const gchar* method_name,
GVariant* parameters);
gboolean handle_agent_unregister_call(const gchar* sender, const gchar* object_path,
const gchar* interface_name, const gchar* method_name,
GVariant* parameters);
GVariant* parameters, GDBusMethodInvocation* invocation,
guint message_count);
void handle_agent_unregister_call(const gchar* sender, const gchar* object_path,
const gchar* interface_name, const gchar* method_name,
GVariant* parameters, GDBusMethodInvocation* invocation,
guint message_count);
void unregister_all_agent_registrations();
void free_agent_callback_data(gpointer ptr);
GDBusConnection* get_sender_dbus_connection(const gchar* sender_name);
// jarekk gchar *get_sender_name_from_connection(GDBusConnection *connection);
GHashTable* get_sender_callbacks(const gchar* sender_name);

#endif // GHAF_DBUS_PROXY_H
9 changes: 6 additions & 3 deletions packages/cpp/dbus-proxy/dbus-proxy/gdbusprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ constexpr const gchar* DBUS_NETWORK_MANAGER_NAME = "org.freedesktop.NetworkManag
constexpr const gchar* DBUS_INTERFACE_SECRET_AGENT = "org.freedesktop.NetworkManager.SecretAgent";
constexpr const gchar* DBUS_NM_AGENT_PATH = "/org/freedesktop/NetworkManager/SecretAgent";

constexpr const gchar* DBUS_BT_AGENT_PATH = "/org/bluez/agent";
constexpr const gchar* DBUS_INTERFACE_BT_AGENT = "org.bluez.Agent1";
constexpr const gchar* DBUS_BLUEZ_NAME = "org.bluez";
constexpr const gchar* DBUS_BLUEZ_AGENT_PATH = "/org/bluez/agent";
constexpr const gchar* DBUS_BLUEZ_AGENT_INTERFACE = "org.bluez.Agent1";

constexpr const gchar* DBUS_OBJECT_PATH_NETWORK_MANAGER = "/org/freedesktop/NetworkManager";
constexpr const gchar* DBUS_OBEX_NAME = "org.bluez.obex";
constexpr const gchar* DBUS_OBEX_AGENT_PATH = "/org/bluez/obex";
constexpr const gchar* DBUS_OBEX_AGENT_INTERFACE = "org.bluez.obex.Agent";

// SNI (StatusNotifierItem) protocol constants
constexpr const gchar* SNI_WATCHER_INTERFACE = "org.kde.StatusNotifierWatcher";
Expand Down
44 changes: 21 additions & 23 deletions packages/cpp/dbus-proxy/dbus-proxy/handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ static void proxy_return_error(GDBusMethodInvocation* invocation, GError* error)

if (remote) {
g_dbus_method_invocation_return_dbus_error(invocation, remote, error->message);
g_free((gpointer)remote);
} else {
g_dbus_method_invocation_return_gerror(invocation, error);
}
Expand All @@ -29,17 +30,19 @@ void method_call_reply_callback(GObject* source, GAsyncResult* res, gpointer use
GVariant* result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);

if (result) {
Log::verbose() << "Method call successful, returning result";
Log::verbose() << "Method call [" << context->call_number
<< "] successful, returning result";
g_dbus_method_invocation_return_value(context->invocation, result);
g_variant_unref(result);
} else {
Log::error() << "Method call failed: " << (error ? error->message : "Unknown error");
Log::error() << "Method call [" << context->call_number
<< "] failed: " << (error ? error->message : "Unknown error");
proxy_return_error(context->invocation, error);
g_clear_error(&error);
}

g_object_unref(context->invocation);
g_free(context->forward_bus_name);
g_free((gpointer)context->forward_bus_name);
g_free(context);
}

Expand All @@ -49,11 +52,13 @@ void handle_method_call_generic(GDBusConnection* connection, const gchar* sender
const gchar* method_name, GVariant* parameters,
GDBusMethodInvocation* invocation, gpointer user_data) {

const gchar* target_object_path = static_cast<const gchar*>(user_data);
const gchar* target_object_path =
user_data ? static_cast<const gchar*>(user_data) : object_path;
guint message_count = ++proxy_state->message_count; // Increment message count for logging

Log::verbose() << "Method call: " << interface_name << "." << method_name << " on "
<< object_path << " from " << sender << " (forwarding to " << target_object_path
<< ")";
Log::verbose() << "Method call [" << message_count << "]: " << interface_name << "."
<< method_name << " on " << object_path << " from " << sender
<< " (forwarding to " << target_object_path << ")";

GDBusConnection* forward_bus = nullptr;
gchar* forward_bus_name = nullptr;
Expand All @@ -64,27 +69,19 @@ void handle_method_call_generic(GDBusConnection* connection, const gchar* sender

// Handle Register/Unregister methods
if (g_str_has_prefix(method_name, "Register")) {
// Add client's agent callback to our registry
// Skip forwarding the call if the agent is already registered
// Handle agent registration method, extract agent path from parameters,
// register callback and store in registry and handle call to
// the server if registration is successful
if (handle_agent_register_call(sender, object_path, interface_name, method_name,
parameters)) {
// Generate DBus reply indicating success, predending we handled the
// registration
g_dbus_method_invocation_return_value(invocation, nullptr);
parameters, invocation, message_count)) {

return;
};
} else if (g_str_has_prefix(method_name, "Unregister")) {
// Check if method name starts with Unregister
Log::error() << "Method " << method_name << " detected as unregistration method";
// Remove client's agent callback from our registry
// Skip forwarding the call if the agent is already unregistered
if (handle_agent_unregister_call(sender, object_path, interface_name, method_name,
parameters)) {
// Generate DBus reply indicating success, predending we handled the
// unregistration
g_dbus_method_invocation_return_value(invocation, nullptr);
return;
}
handle_agent_unregister_call(sender, object_path, interface_name, method_name,
parameters, invocation, message_count);
return;
}
} else { // call comes from source bus, forward back to client

Expand All @@ -109,6 +106,7 @@ void handle_method_call_generic(GDBusConnection* connection, const gchar* sender
MethodCallContext* context = g_new0(MethodCallContext, 1);
context->invocation = invocation;
context->forward_bus_name = forward_bus_name;
context->call_number = message_count; // Set call number for logging

g_object_ref(invocation);

Expand Down
16 changes: 6 additions & 10 deletions packages/cpp/dbus-proxy/dbus-proxy/proxy_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ gboolean init_proxy_state(const ProxyConfig* config) {
proxy_state->sigterm_source_id =
g_unix_signal_add(SIGTERM, signal_handler, GINT_TO_POINTER(SIGTERM));

// Initialize message count for logging purposes
proxy_state->message_count = 0;

return TRUE;
}

Expand Down Expand Up @@ -377,9 +380,7 @@ gboolean proxy_single_object(const gchar* object_path, GDBusNodeInfo* node_info,

GError* error = nullptr;
guint registration_id = g_dbus_connection_register_object(
proxy_state->target_bus, object_path, iface, &vtable,
g_strdup(object_path), // Pass object path as user_data for forwarding
g_free, &error);
proxy_state->target_bus, object_path, iface, &vtable, nullptr, g_free, &error);

if (registration_id == 0) {
Log::error() << "Failed to register interface " << iface->name << " on " << object_path
Expand Down Expand Up @@ -464,9 +465,8 @@ gboolean register_single_interface(const gchar* object_path, const gchar* interf
.set_property = nullptr,
.padding = {nullptr}};

guint registration_id =
g_dbus_connection_register_object(proxy_state->target_bus, object_path, iface_info, &vtable,
g_strdup(object_path), g_free, &error);
guint registration_id = g_dbus_connection_register_object(
proxy_state->target_bus, object_path, iface_info, &vtable, nullptr, g_free, &error);

if (registration_id == 0) {
Log::error() << "Failed to register interface " << interface_name << " on " << object_path
Expand Down Expand Up @@ -660,10 +660,6 @@ void cleanup_proxy_state() {
}

unregister_all_agent_registrations();
if (proxy_state->senders_registry) {
g_hash_table_destroy(proxy_state->senders_registry);
proxy_state->senders_registry = nullptr;
}

if (proxy_state->introspection_data) {
g_dbus_node_info_unref(proxy_state->introspection_data);
Expand Down
6 changes: 3 additions & 3 deletions packages/cpp/dbus-proxy/dbus-proxy/sni/proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@
item->cached_pixmap.reset(pix);
Log::info() << "[ICON] Cached pixmap for " << item->source_bus_name;
}
}

Check notice

Code scanning / CodeQL

Short global name Note

Poor global variable name 'err'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo).
// cached_menu_path already set by early fetch; log if not set
if (item->cached_menu_path.empty())
Log::info() << "[MENU] No menu path for " << item->source_bus_name;
Expand Down Expand Up @@ -1665,15 +1665,15 @@
[](GObject* source, GAsyncResult* res, gpointer user_data) {
auto ctx = std::unique_ptr<SniMethodCallContext>(
static_cast<SniMethodCallContext*>(user_data));
GError* error = nullptr;
GError* err = nullptr;
Comment thread
jkuro-tii marked this conversation as resolved.
GVariant* result =
g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error);
Comment thread
jkuro-tii marked this conversation as resolved.
g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &err);
if (result) {
Log::info() << "[REPLY] RegisterStatusNotifierItem to target watcher OK";
g_variant_unref(result);
} else {
Log::error() << "[REPLY] RegisterStatusNotifierItem to target watcher failed";
g_clear_error(&error);
Comment thread
jkuro-tii marked this conversation as resolved.
g_clear_error(&err);
}
// ctx unique_ptr destructor frees forward_bus_name
},
Expand Down
Loading