From 05feefe0fb049bb0f7c59584058ee0350462920c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 20:01:53 +0100 Subject: [PATCH] dbus: properly generate UnknownInterface, UnknownProperty and PropertyReadOnly errors --- src/dbus-automount.c | 6 +++++- src/dbus-device.c | 6 +++++- src/dbus-job.c | 6 +++++- src/dbus-manager.c | 6 +++++- src/dbus-mount.c | 6 +++++- src/dbus-path.c | 6 +++++- src/dbus-service.c | 6 +++++- src/dbus-snapshot.c | 6 +++++- src/dbus-socket.c | 6 +++++- src/dbus-swap.c | 6 +++++- src/dbus-target.c | 6 +++++- src/dbus-timer.c | 6 +++++- src/dbus-unit.h | 4 ++++ src/dbus.c | 38 +++++++++++++++++++++++++++++++++++--- src/dbus.h | 15 ++++++++++++++- src/util.c | 13 +++++++++++++ src/util.h | 2 ++ 17 files changed, 128 insertions(+), 16 deletions(-) diff --git a/src/dbus-automount.c b/src/dbus-automount.c index af277af3..eccad37e 100644 --- a/src/dbus-automount.c +++ b/src/dbus-automount.c @@ -38,6 +38,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Automount\0" + const char bus_automount_interface[] _introspect_("Automount") = BUS_AUTOMOUNT_INTERFACE; DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { @@ -48,5 +52,5 @@ DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBus { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-device.c b/src/dbus-device.c index 9b2861de..b046eae9 100644 --- a/src/dbus-device.c +++ b/src/dbus-device.c @@ -37,6 +37,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Device\0" + const char bus_device_interface[] _introspect_("Device") = BUS_DEVICE_INTERFACE; const char bus_device_invalidating_properties[] = @@ -49,5 +53,5 @@ DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMes { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-job.c b/src/dbus-job.c index 95367c42..b66d2360 100644 --- a/src/dbus-job.c +++ b/src/dbus-job.c @@ -45,6 +45,10 @@ const char bus_job_interface[] _introspect_("Job") = BUS_JOB_INTERFACE; +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Job\0" + #define INVALIDATING_PROPERTIES \ "State\0" @@ -99,7 +103,7 @@ static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connec job_finish_and_invalidate(j, JOB_CANCELED); } else - return bus_default_message_handler(j->manager, connection, message, INTROSPECTION, properties); + return bus_default_message_handler(j->manager, connection, message, INTROSPECTION, INTERFACES_LIST, properties); if (reply) { if (!dbus_connection_send(connection, reply, NULL)) diff --git a/src/dbus-manager.c b/src/dbus-manager.c index 7d4703b8..2edbc37b 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -206,6 +206,10 @@ #define INTROSPECTION_END \ "\n" +#define INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Manager\0" + const char bus_manager_interface[] _introspect_("Manager") = BUS_MANAGER_INTERFACE; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_manager_append_running_as, manager_running_as, ManagerRunningAs); @@ -1021,7 +1025,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, m->environment = e; } else - return bus_default_message_handler(m, connection, message, NULL, properties); + return bus_default_message_handler(m, connection, message, NULL, INTERFACES_LIST, properties); if (job_type != _JOB_TYPE_INVALID) { const char *name, *smode, *old_name = NULL; diff --git a/src/dbus-mount.c b/src/dbus-mount.c index e3a793d1..5fb9a3f0 100644 --- a/src/dbus-mount.c +++ b/src/dbus-mount.c @@ -50,6 +50,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Mount\0" + const char bus_mount_interface[] _introspect_("Mount") = BUS_MOUNT_INTERFACE; const char bus_mount_invalidating_properties[] = @@ -150,5 +154,5 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMess { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-path.c b/src/dbus-path.c index 6155792d..cb1d4f09 100644 --- a/src/dbus-path.c +++ b/src/dbus-path.c @@ -41,6 +41,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Path\0" + const char bus_path_interface[] _introspect_("Path") = BUS_PATH_INTERFACE; static int bus_path_append_paths(Manager *m, DBusMessageIter *i, const char *property, void *data) { @@ -94,5 +98,5 @@ DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessa { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-service.c b/src/dbus-service.c index 1b6c7f47..6bb6a9d6 100644 --- a/src/dbus-service.c +++ b/src/dbus-service.c @@ -90,6 +90,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Service\0" + const char bus_service_interface[] _introspect_("Service") = BUS_SERVICE_INTERFACE; const char bus_service_invalidating_properties[] = @@ -144,5 +148,5 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connectio { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, connection, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, connection, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-snapshot.c b/src/dbus-snapshot.c index a9903ec4..cc12b1bd 100644 --- a/src/dbus-snapshot.c +++ b/src/dbus-snapshot.c @@ -38,6 +38,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Snapshot\0" + const char bus_snapshot_interface[] _introspect_("Snapshot") = BUS_SNAPSHOT_INTERFACE; DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { @@ -60,7 +64,7 @@ DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusM goto oom; } else - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); if (reply) { if (!dbus_connection_send(c, reply, NULL)) diff --git a/src/dbus-socket.c b/src/dbus-socket.c index 3fda76db..5b068b45 100644 --- a/src/dbus-socket.c +++ b/src/dbus-socket.c @@ -64,6 +64,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Socket\0" + const char bus_socket_interface[] _introspect_("Socket") = BUS_SOCKET_INTERFACE; const char bus_socket_invalidating_properties[] = @@ -109,5 +113,5 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMes { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-swap.c b/src/dbus-swap.c index 723cd64a..079912a5 100644 --- a/src/dbus-swap.c +++ b/src/dbus-swap.c @@ -47,6 +47,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Swap\0" + const char bus_swap_interface[] _introspect_("Swap") = BUS_SWAP_INTERFACE; const char bus_swap_invalidating_properties[] = @@ -92,5 +96,5 @@ DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessa { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-target.c b/src/dbus-target.c index 1eb3c249..1cbeccb5 100644 --- a/src/dbus-target.c +++ b/src/dbus-target.c @@ -38,6 +38,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Target\0" + const char bus_target_interface[] _introspect_("Target") = BUS_TARGET_INTERFACE; DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { @@ -46,5 +50,5 @@ DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMes { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-timer.c b/src/dbus-timer.c index eed05e69..e44f4e2f 100644 --- a/src/dbus-timer.c +++ b/src/dbus-timer.c @@ -42,6 +42,10 @@ BUS_INTROSPECTABLE_INTERFACE \ "\n" +#define INTERFACES_LIST \ + BUS_UNIT_INTERFACES_LIST \ + "org.freedesktop.systemd1.Timer\0" + const char bus_timer_interface[] _introspect_("Timer") = BUS_TIMER_INTERFACE; const char bus_timer_invalidating_properties[] = @@ -118,5 +122,5 @@ DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMess { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, INTERFACES_LIST, properties); } diff --git a/src/dbus-unit.h b/src/dbus-unit.h index b51fe4eb..4e46fc48 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -104,6 +104,10 @@ " \n" \ " \n" +#define BUS_UNIT_INTERFACES_LIST \ + BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.systemd1.Unit\0" + #define BUS_UNIT_PROPERTIES \ { "org.freedesktop.systemd1.Unit", "Id", bus_property_append_string, "s", u->meta.id }, \ { "org.freedesktop.systemd1.Unit", "Names", bus_unit_append_names, "as", u }, \ diff --git a/src/dbus.c b/src/dbus.c index dae5f9ec..af03c574 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -1213,12 +1213,20 @@ oom: return -ENOMEM; } -DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char*introspection, const BusProperty *properties) { +DBusHandlerResult bus_default_message_handler( + Manager *m, + DBusConnection *c, + DBusMessage *message, + const char *introspection, + const char *interfaces, + const BusProperty *properties) { + DBusError error; DBusMessage *reply = NULL; int r; assert(m); + assert(c); assert(message); dbus_error_init(&error); @@ -1269,6 +1277,13 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!dbus_message_iter_close_container(&iter, &sub)) goto oom; + } else { + if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(m, c, message, &error, -EINVAL); } } else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "GetAll") && properties) { @@ -1283,6 +1298,11 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu DBUS_TYPE_INVALID)) return bus_send_error_reply(m, c, message, &error, -EINVAL); + if (interface[0] && !nulstr_contains(interfaces, interface)) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(m, c, message, &error, -EINVAL); + } + if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -1367,8 +1387,20 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBu if (!(reply = dbus_message_new_method_return(message))) goto oom; - } else - return bus_send_error_reply(m, c, message, NULL, -EINVAL); + } else { + if (p->property) + dbus_set_error_const(&error, DBUS_ERROR_PROPERTY_READ_ONLY, "Property read-only"); + else if (!nulstr_contains(interfaces, interface)) + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + else + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); + + return bus_send_error_reply(m, c, message, &error, -EINVAL); + } + + } else if (!nulstr_contains(interfaces, dbus_message_get_interface(message))) { + dbus_set_error_const(&error, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); + return bus_send_error_reply(m, c, message, &error, -EINVAL); } if (reply) { diff --git a/src/dbus.h b/src/dbus.h index 2aaeb474..f93ad620 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -32,6 +32,14 @@ #define DBUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface" #endif +#ifndef DBUS_ERROR_UNKNOWN_PROPERTY +#define DBUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" +#endif + +#ifndef DBUS_ERROR_PROPERTY_READ_ONLY +#define DBUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly" +#endif + #include "manager.h" typedef int (*BusPropertyCallback)(Manager *m, DBusMessageIter *iter, const char *property, void *data); @@ -84,6 +92,11 @@ typedef struct BusProperty { " \n" \ "\n" +#define BUS_GENERIC_INTERFACES_LIST \ + "org.freedesktop.DBus.Properties\0" \ + "org.freedesktop.DBus.Introspectable\0" \ + "org.freedesktop.DBus.Peer\0" + int bus_init(Manager *m, bool try_bus_connect); void bus_done(Manager *m); @@ -94,7 +107,7 @@ void bus_timeout_event(Manager *m, Watch *w, int events); int bus_query_pid(Manager *m, const char *name); -DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char* introspection, const BusProperty *properties); +DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char* introspection, const char *interfaces, const BusProperty *properties); DBusHandlerResult bus_send_error_reply(Manager *m, DBusConnection *c, DBusMessage *message, DBusError *bus_error, int error); int bus_broadcast(Manager *m, DBusMessage *message); diff --git a/src/util.c b/src/util.c index 4acb3c30..c02b39e0 100644 --- a/src/util.c +++ b/src/util.c @@ -4079,6 +4079,19 @@ int kill_and_sigcont(pid_t pid, int sig) { return r; } +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/src/util.h b/src/util.h index a2e3b944..13e5f620 100644 --- a/src/util.h +++ b/src/util.h @@ -386,6 +386,8 @@ void execute_directory(const char *directory, DIR *_d, char *argv[]); int kill_and_sigcont(pid_t pid, int sig); +bool nulstr_contains(const char*nulstr, const char *needle); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) -- 2.39.5