diff --git a/CMakeLists.txt b/CMakeLists.txt index 60c6a60a5..d0aff45ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1128,6 +1128,14 @@ tde_setup_dbus( dbus-1-tqt ) list( APPEND TDECORE_LIBRARY_DIRS ${DBUS_TQT_LIBRARY_DIRS} ) +##### set POLKIT-1 file locations ################## + +if( NOT DEFINED POLKIT_ACTIONS_DIRECTORY ) + set (POLKIT_ACTIONS_DIRECTORY "/usr/share/polkit-1/actions/" ) + message( STATUS "Using " ${POLKIT_ACTIONS_DIRECTORY} " for Polkit-1 policy action files" ) +endif( NOT DEFINED POLKIT_ACTIONS_DIRECTORY ) + + ##### Add '[KDE4]' to KDE4 menu items ######### if( WITH_KDE4_MENU_SUFFIX ) diff --git a/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt b/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt index 4d1f4618a..d6e75af12 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt +++ b/tdecore/tdehw/hwlibdaemons/dbus/CMakeLists.txt @@ -9,8 +9,10 @@ # ################################################# + include_directories( ${DBUS_INCLUDE_DIRS} + ${DBUS_TQT_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} @@ -19,8 +21,8 @@ include_directories( ##### tde_dbus_hardwarecontrol ################## tde_add_executable( tde_dbus_hardwarecontrol - SOURCES tde_dbus_hardwarecontrol.c - LINK ${DBUS_LIBRARIES} + SOURCES tde_dbus_hardwarecontrol.cpp + LINK ${DBUS_LIBRARIES} ${DBUS_TQT_LIBRARIES} ${TQT_LIBRARIES} DESTINATION ${BIN_INSTALL_DIR} ) @@ -28,10 +30,11 @@ tde_add_executable( tde_dbus_hardwarecontrol configure_file( org.trinitydesktop.hardwarecontrol.service.cmake org.trinitydesktop.hardwarecontrol.service @ONLY ) -install( FILES - org.trinitydesktop.hardwarecontrol.conf - DESTINATION ${DBUS_SYSTEM_CONF_DIRECTORY} ) +install( FILES org.trinitydesktop.hardwarecontrol.conf + DESTINATION ${DBUS_SYSTEM_CONF_DIRECTORY} ) + +install( FILES ${CMAKE_CURRENT_BINARY_DIR}/org.trinitydesktop.hardwarecontrol.service + DESTINATION ${DBUS_SERVICE_DIRECTORY} ) -install( FILES - ${CMAKE_CURRENT_BINARY_DIR}/org.trinitydesktop.hardwarecontrol.service - DESTINATION ${DBUS_SERVICE_DIRECTORY} ) +install( FILES org.trinitydesktop.hardwarecontrol.policy + DESTINATION ${POLKIT_ACTIONS_DIRECTORY} ) diff --git a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf index b897da36b..47fbee050 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf +++ b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.conf @@ -3,14 +3,14 @@ + - - + @@ -36,11 +36,4 @@ - - - - - - - diff --git a/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy new file mode 100644 index 000000000..5183b47cb --- /dev/null +++ b/tdecore/tdehw/hwlibdaemons/dbus/org.trinitydesktop.hardwarecontrol.policy @@ -0,0 +1,60 @@ + + + + + + The Trinity Desktop Environment Project + http://www.trinitydesktop.org + + + Freeze the system. + Authentication is required to freeze the system. + + no + no + yes + + + + + Put the system in standby mode. + Authentication is required to put the system in standby. + + no + no + yes + + + + + Put the system in suspend mode. + Authentication is required to suspend the system. + + no + no + yes + + + + + Put the system in hybrid suspend mode. + Authentication is required to put the system in hybrid suspend mode. + + no + no + yes + + + + + Hibernate the system. + Authentication is required to hibernate the system. + + no + no + yes + + + + diff --git a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp similarity index 80% rename from tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c rename to tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp index 77200334e..8ba765c34 100644 --- a/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.c +++ b/tdecore/tdehw/hwlibdaemons/dbus/tde_dbus_hardwarecontrol.cpp @@ -7,12 +7,63 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + // Input devices #include #define BITS_PER_LONG (sizeof(long) * 8) #define NUM_BITS(x) ((((x) - 1) / BITS_PER_LONG) + 1) +bool checkPolKitAuthorization(DBusMessage* msg, const TQString &action_id) +{ + if (!msg) { + return false; + } + TQT_DBusConnection dbusConn = TQT_DBusConnection::addConnection(TQT_DBusConnection::SystemBus); + if (!dbusConn.isConnected()) { + return false; + } + TQT_DBusProxy polkitProxy("org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", + "org.freedesktop.PolicyKit1.Authority", dbusConn); + if (polkitProxy.canSend()) { + // Check whether the requested action is authorized + TQString sender(dbus_message_get_sender(msg)); + TQT_DBusVariant sysname; + sysname.value = TQT_DBusData::fromString(sender); + sysname.signature = sysname.value.buildDBusSignature(); + TQT_DBusDataMap subjectMap = TQT_DBusDataMap(); + subjectMap.insert(TQString("name"), TQT_DBusData::fromVariant(sysname)); + TQValueList subjectStruct; + subjectStruct << TQT_DBusData::fromString("system-bus-name"); + subjectStruct << TQT_DBusData::fromStringKeyMap(subjectMap); + + TQMap detailsMap; + detailsMap.insert(TQString(""), TQString("")); + TQT_DBusDataMap dbusDetailsMap(detailsMap); + + TQValueList params; + params << TQT_DBusData::fromStruct(subjectStruct); + params << TQT_DBusData::fromString(action_id); + params << TQT_DBusData::fromStringKeyMap(dbusDetailsMap); + params << TQT_DBusData::fromUInt32(0); // No user interaction + params << TQT_DBusData::fromString(""); // No cancellation + + TQT_DBusMessage reply = polkitProxy.sendWithReply("CheckAuthorization", params); + if (reply.type() == TQT_DBusMessage::ReplyMessage && reply.count() == 1) { + return (reply[0].toStruct())[0].toBool(); + } + } + + return false; +} + void reply_Bool(DBusMessage* msg, DBusConnection* conn, int value) { DBusMessage* reply; DBusMessageIter args; @@ -513,7 +564,7 @@ void reply_Introspect(DBusMessage* msg, DBusConnection* conn) { size_t size = 4096; const char* member = dbus_message_get_member(msg); const char *path = dbus_message_get_path(msg); - char *data = malloc(size); + char *data = new char[size]; // compose reply strncpy(data, @@ -632,7 +683,7 @@ void reply_Introspect(DBusMessage* msg, DBusConnection* conn) { // free the reply dbus_message_unref(reply); - free((void*)data); + delete[] data; } void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { @@ -667,11 +718,8 @@ void reply_PropertiesGetAll(DBusMessage* msg, DBusConnection* conn) { } void error_UnknownMessage(DBusMessage* msg, DBusConnection* conn) { - DBusMessage* reply; - dbus_uint32_t serial = 0; const char* member = dbus_message_get_member(msg); const char* interface = dbus_message_get_interface(msg); - // print message fprintf(stderr, "[tde_dbus_hardwarecontrol] Unknown method '%s' called on interface '%s', ignoring\n", member, interface); if (DBUS_MESSAGE_TYPE_METHOD_CALL != dbus_message_get_type(msg)) { @@ -679,12 +727,13 @@ void error_UnknownMessage(DBusMessage* msg, DBusConnection* conn) { } // create a reply from the message - reply = dbus_message_new_error_printf(msg, + DBusMessage* reply = dbus_message_new_error_printf(msg, "org.freedesktop.DBus.Error.UnknownMethod", "Method \"%s\" on interface \"%s\" doesn't exist", member, interface); // send the reply && flush the connection + dbus_uint32_t serial = 0; if (!dbus_connection_send(conn, reply, &serial)) { fprintf(stderr, "[tde_dbus_hardwarecontrol] %s: dbus_connection_send failed\n", member); return; @@ -695,6 +744,23 @@ void error_UnknownMessage(DBusMessage* msg, DBusConnection* conn) { dbus_message_unref(reply); } +void error_PolkitAccessDenied(DBusMessage* msg, DBusConnection* conn) { + // create a reply from the message + DBusMessage* reply = dbus_message_new_error(msg, + "org.freedesktop.DBus.Error.AccessDenied", "Permission denied."); + + // send the reply && flush the connection + dbus_uint32_t serial = 0; + if (!dbus_connection_send(conn, reply, &serial)) { + fprintf(stderr, "[tde_dbus_hardwarecontrol] error_PolkitAccessDenied: dbus_connection_send failed\n"); + return; + } + dbus_connection_flush(conn); + + // free the reply + dbus_message_unref(reply); +} + void listen() { DBusMessage* msg; DBusConnection* conn; @@ -753,69 +819,129 @@ void listen() { reply_SetBrightness(msg, conn); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanFreeze")) { - bool result = CanSetPowerState("freeze", NULL, NULL) || CanSetPowerState("mem", NULL, "s2idle"); - reply_Bool(msg, conn, result); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.freeze"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("freeze", NULL, NULL) || CanSetPowerState("mem", NULL, "s2idle"); + reply_Bool(msg, conn, result); + } } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Freeze")) { - bool result = false; - if (CanSetPowerState("freeze", NULL, NULL)) { - result = SetPowerState("freeze", NULL, NULL); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.freeze"); + if (!result) { + error_PolkitAccessDenied(msg, conn); } - else if (CanSetPowerState("mem", NULL, "s2idle")) { - result = SetPowerState("mem", NULL, "s2idle"); + else { + result = false; + if (CanSetPowerState("freeze", NULL, NULL)) { + result = SetPowerState("freeze", NULL, NULL); + } + else if (CanSetPowerState("mem", NULL, "s2idle")) { + result = SetPowerState("mem", NULL, "s2idle"); + } + reply_Bool(msg, conn, result); } - reply_Bool(msg, conn, result); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanStandby")) { - bool result = CanSetPowerState("standby", NULL, NULL) || CanSetPowerState("mem", NULL, "shallow"); - reply_Bool(msg, conn, result); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.standby"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("standby", NULL, NULL) || CanSetPowerState("mem", NULL, "shallow"); + reply_Bool(msg, conn, result); + } } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Standby")) { - bool result = false; - if (CanSetPowerState("standby", NULL, NULL)) { - result = SetPowerState("standby", NULL, NULL); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.standby"); + if (!result) { + error_PolkitAccessDenied(msg, conn); } - else if (CanSetPowerState("mem", NULL, "shallow")) { - result = SetPowerState("mem", NULL, "shallow"); + else { + result = false; + if (CanSetPowerState("standby", NULL, NULL)) { + result = SetPowerState("standby", NULL, NULL); + } + else if (CanSetPowerState("mem", NULL, "shallow")) { + result = SetPowerState("mem", NULL, "shallow"); + } + reply_Bool(msg, conn, result); } - reply_Bool(msg, conn, result); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSuspend")) { - bool result = (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) || - CanSetPowerState("mem", NULL, "deep"); - reply_Bool(msg, conn, result); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.suspend"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) || + CanSetPowerState("mem", NULL, "deep"); + reply_Bool(msg, conn, result); + } } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Suspend")) { - bool result = false; - if (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) { - result = SetPowerState("mem", NULL, NULL); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.suspend"); + if (!result) { + error_PolkitAccessDenied(msg, conn); } - else if (CanSetPowerState("mem", NULL, "deep")) { - result = SetPowerState("mem", NULL, "deep"); + else { + result = false; + if (CanSetPowerState("mem", NULL, NULL) && access("/sys/power/mem_sleep", R_OK) != 0) { + result = SetPowerState("mem", NULL, NULL); + } + else if (CanSetPowerState("mem", NULL, "deep")) { + result = SetPowerState("mem", NULL, "deep"); + } + reply_Bool(msg, conn, result); } - reply_Bool(msg, conn, result); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHybridSuspend")) { - bool result = CanSetPowerState("disk", "suspend", NULL); - reply_Bool(msg, conn, result); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hybridsuspend"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("disk", "suspend", NULL); + reply_Bool(msg, conn, result); + } } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "HybridSuspend")) { - bool result = SetPowerState("disk", "suspend", NULL); - reply_Bool(msg, conn, result); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hybridsuspend"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = SetPowerState("disk", "suspend", NULL); + reply_Bool(msg, conn, result); + } } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanHibernate")) { - bool result = CanSetPowerState("disk", "shutdown", NULL) || CanSetPowerState("disk", "platform", NULL); - reply_Bool(msg, conn, result); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hibernate"); + if (!result) { + error_PolkitAccessDenied(msg, conn); + } + else { + result = CanSetPowerState("disk", "shutdown", NULL) || CanSetPowerState("disk", "platform", NULL); + reply_Bool(msg, conn, result); + } } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "Hibernate")) { - bool result = false; - if (CanSetPowerState("disk", "shutdown", NULL)) { - result = SetPowerState("disk", "shutdown", NULL); + bool result = checkPolKitAuthorization(msg, "org.trinitydesktop.hardwarecontrol.power.hibernate"); + if (!result) { + error_PolkitAccessDenied(msg, conn); } - else if (CanSetPowerState("disk", "platform", NULL)) { - result = SetPowerState("disk", "platform", NULL); + else { + result = false; + if (CanSetPowerState("disk", "shutdown", NULL)) { + result = SetPowerState("disk", "shutdown", NULL); + } + else if (CanSetPowerState("disk", "platform", NULL)) { + result = SetPowerState("disk", "platform", NULL); + } + reply_Bool(msg, conn, result); } - reply_Bool(msg, conn, result); } else if (dbus_message_is_method_call(msg, "org.trinitydesktop.hardwarecontrol.Power", "CanSetHibernationMethod")) { reply_CanSetHibernationMethod(msg, conn);