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);