diff --git a/bin/dde-system-daemon/power.go b/bin/dde-system-daemon/power.go
index 528697af6..47d940218 100644
--- a/bin/dde-system-daemon/power.go
+++ b/bin/dde-system-daemon/power.go
@@ -28,6 +28,10 @@ const (
dsettingsPowerName = "org.deepin.dde.daemon.power"
dsettingsIdleStatePath = "idleStatePath"
dsettingsIdleScreenStatePath = "idleScreenStatePath"
+
+ // polkit action ids used by checkAuth for SetIdleState / SetScreenState
+ actionSetIdleState = "org.deepin.dde.daemon.set-idle-state"
+ actionSetScreenState = "org.deepin.dde.daemon.set-screen-state"
)
func isStrInList(item string, items []string) bool {
@@ -172,12 +176,20 @@ func (d *Daemon) setState(file string, state bool) error {
return nil
}
-func (d *Daemon) SetIdleState(state bool) *dbus.Error {
+func (d *Daemon) SetIdleState(sender dbus.Sender, state bool) *dbus.Error {
+ err := checkAuth(actionSetIdleState, string(sender))
+ if err != nil {
+ return dbusutil.ToError(err)
+ }
logger.Infof("SetIdleState %s try set state: %v", d.idleStatePath, state)
return dbusutil.ToError(d.setState(d.idleStatePath, state))
}
-func (d *Daemon) SetScreenState(state bool) *dbus.Error {
+func (d *Daemon) SetScreenState(sender dbus.Sender, state bool) *dbus.Error {
+ err := checkAuth(actionSetScreenState, string(sender))
+ if err != nil {
+ return dbusutil.ToError(err)
+ }
logger.Infof("SetScreenState %s try set state: %v", d.idleScreenStatePath, state)
return dbusutil.ToError(d.setState(d.idleScreenStatePath, state))
}
diff --git a/misc/polkit-action/org.deepin.dde.daemon.system.policy.in b/misc/polkit-action/org.deepin.dde.daemon.system.policy.in
index e12eecb97..bda2ac11b 100644
--- a/misc/polkit-action/org.deepin.dde.daemon.system.policy.in
+++ b/misc/polkit-action/org.deepin.dde.daemon.system.policy.in
@@ -24,5 +24,23 @@
auth_admin
+
+ Set short idle state
+ Authentication is required to set the short idle state
+
+ no
+ no
+ yes
+
+
+
+ Set screen idle state
+ Authentication is required to set the screen idle state
+
+ no
+ no
+ yes
+
+
diff --git a/misc/polkit-action/org.deepin.dde.inputdevices.policy b/misc/polkit-action/org.deepin.dde.inputdevices.policy
new file mode 100644
index 000000000..e8523c759
--- /dev/null
+++ b/misc/polkit-action/org.deepin.dde.inputdevices.policy
@@ -0,0 +1,19 @@
+
+
+
+ LinuxDeepin
+ https://www.deepin.com/
+
+
+ Enable or disable the touchpad
+ Authentication is required to enable or disable the touchpad
+
+ no
+ no
+ yes
+
+
+
+
diff --git a/misc/polkit-action/org.deepin.dde.power.policy b/misc/polkit-action/org.deepin.dde.power.policy
index 418e0aff4..5ecaf5b12 100644
--- a/misc/polkit-action/org.deepin.dde.power.policy
+++ b/misc/polkit-action/org.deepin.dde.power.policy
@@ -27,4 +27,22 @@
Check Authentication
Tämän toiminnon suorittaminen edellyttää todennusta
+
+ Set short idle state
+ Authentication is required to set the short idle state
+
+ no
+ no
+ yes
+
+
+
+ Set TLP power mode
+ Authentication is required to set the TLP power mode
+
+ no
+ no
+ yes
+
+
diff --git a/misc/polkit-rules/org.deepin.dde.inputdevices.rules b/misc/polkit-rules/org.deepin.dde.inputdevices.rules
new file mode 100644
index 000000000..a026c88b1
--- /dev/null
+++ b/misc/polkit-rules/org.deepin.dde.inputdevices.rules
@@ -0,0 +1,12 @@
+polkit.addRule(function(action, subject) {
+ // Allow root internal callers (e.g. keyevent1 running inside
+ // dde-system-daemon invoking org.deepin.dde.InputDevices1.Touchpad
+ // .SetTouchpadEnable over the system bus) to toggle the touchpad.
+ // Root has no active local session, so the allow_active:yes default in
+ // the .policy does not match and would otherwise fall back to
+ // allow_any:no and silently deny the call.
+ if (action.id === "org.deepin.dde.inputdevices.set-touchpad-enable" &&
+ subject.user === "root") {
+ return polkit.Result.YES;
+ }
+});
diff --git a/misc/polkit-rules/org.deepin.dde.power.rules b/misc/polkit-rules/org.deepin.dde.power.rules
new file mode 100644
index 000000000..44e620ea6
--- /dev/null
+++ b/misc/polkit-rules/org.deepin.dde.power.rules
@@ -0,0 +1,11 @@
+polkit.addRule(function(action, subject) {
+ // Allow root internal callers (e.g. dde-system-daemon invoking
+ // org.deepin.dde.Power1.SetShortIdleState over the system bus) to set
+ // the short idle state. Root has no active local session, so the
+ // allow_active:yes default in the .policy does not match and would
+ // otherwise fall back to allow_any:no and silently deny the call.
+ if (action.id === "org.deepin.dde.power.set-short-idle-state" &&
+ subject.user === "root") {
+ return polkit.Result.YES;
+ }
+});
diff --git a/system/inputdevices1/daemon.go b/system/inputdevices1/daemon.go
index 364e4f47f..2edb7d451 100644
--- a/system/inputdevices1/daemon.go
+++ b/system/inputdevices1/daemon.go
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
+// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -16,6 +16,9 @@ const (
dbusServiceName = "org.deepin.dde.InputDevices1"
dbusPath = "/org/deepin/dde/InputDevices1"
dbusInterface = dbusServiceName
+
+ // polkit action id used by checkAuthorization for SetTouchpadEnable
+ actionSetTouchpadEnable = "org.deepin.dde.inputdevices.set-touchpad-enable"
)
func init() {
diff --git a/system/inputdevices1/inputdevices_ifc.go b/system/inputdevices1/inputdevices_ifc.go
index 2e13291fb..6d4e96372 100644
--- a/system/inputdevices1/inputdevices_ifc.go
+++ b/system/inputdevices1/inputdevices_ifc.go
@@ -1,11 +1,14 @@
-// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd.
+// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later
package inputdevices1
import (
+ "errors"
+
"github.com/godbus/dbus/v5"
+ polkit "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.policykit1"
"github.com/linuxdeepin/go-lib/dbusutil"
)
@@ -13,3 +16,27 @@ func (m *InputDevices) SetWakeupDevices(sender dbus.Sender, path string, value s
err := m.setWakeupDevices(path, value)
return dbusutil.ToError(err)
}
+
+// checkAuthorization verifies that the caller identified by sysBusName is
+// allowed to perform the polkit action identified by actionId. It mirrors
+// the pattern used by system/airplane_mode1 so that active local users are
+// allowed without an authentication dialog (allow_active: yes).
+func checkAuthorization(actionId string, sysBusName string) error {
+ systemBus, err := dbus.SystemBus()
+ if err != nil {
+ return err
+ }
+ authority := polkit.NewAuthority(systemBus)
+ subject := polkit.MakeSubject(polkit.SubjectKindSystemBusName)
+ subject.SetDetail("name", sysBusName)
+
+ ret, err := authority.CheckAuthorization(0, subject, actionId,
+ nil, polkit.CheckAuthorizationFlagsAllowUserInteraction, "")
+ if err != nil {
+ return err
+ }
+ if !ret.IsAuthorized {
+ return errors.New("not authorized")
+ }
+ return nil
+}
diff --git a/system/inputdevices1/touchpad.go b/system/inputdevices1/touchpad.go
index 6f1a77993..5d4329522 100644
--- a/system/inputdevices1/touchpad.go
+++ b/system/inputdevices1/touchpad.go
@@ -79,8 +79,13 @@ func (t *Touchpad) handleDeviceChange(devices []string) {
logger.Infof("touchpad devices updated: %d device(s)", len(devices))
}
-func (t *Touchpad) SetTouchpadEnable(enabled bool) *dbus.Error {
- err := t.setTouchpadEnable(enabled)
+func (t *Touchpad) SetTouchpadEnable(sender dbus.Sender, enabled bool) *dbus.Error {
+ err := checkAuthorization(actionSetTouchpadEnable, string(sender))
+ if err != nil {
+ logger.Warningf("checkAuthorization failed, err: %v, actionId=%v", err, actionSetTouchpadEnable)
+ return dbusutil.ToError(err)
+ }
+ err = t.setTouchpadEnable(enabled)
return dbusutil.ToError(err)
}
diff --git a/system/power1/manager_ifc.go b/system/power1/manager_ifc.go
index 4e663d136..9ff425ee7 100644
--- a/system/power1/manager_ifc.go
+++ b/system/power1/manager_ifc.go
@@ -9,6 +9,7 @@ import (
"fmt"
dbus "github.com/godbus/dbus/v5"
+ polkit "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.policykit1"
"github.com/linuxdeepin/go-lib/dbusutil"
)
@@ -16,6 +17,10 @@ const (
dbusServiceName = "org.deepin.dde.Power1"
dbusPath = "/org/deepin/dde/Power1"
dbusInterface = dbusServiceName
+
+ // polkit action ids used by checkAuthorization for the Power1 setters
+ actionSetTlpMode = "org.deepin.dde.power.set-tlp-mode"
+ actionSetShortIdleState = "org.deepin.dde.power.set-short-idle-state"
)
func (*Manager) GetInterfaceName() string {
@@ -106,13 +111,23 @@ func (m *Manager) SetMode(mode string) *dbus.Error {
return nil
}
-func (m *Manager) SetTlpMode(mode string) *dbus.Error {
+func (m *Manager) SetTlpMode(sender dbus.Sender, mode string) *dbus.Error {
logger.Info("SetTlpMode : ", mode)
+ err := checkAuthorization(actionSetTlpMode, string(sender))
+ if err != nil {
+ logger.Warningf("checkAuthorization failed, err: %v, actionId=%v", err, actionSetTlpMode)
+ return dbusutil.ToError(err)
+ }
return dbusutil.ToError(m.setTlpMode(mode))
}
-func (m *Manager) SetShortIdleState(state bool) *dbus.Error {
+func (m *Manager) SetShortIdleState(sender dbus.Sender, state bool) *dbus.Error {
logger.Info(" SetShortIdleState : ", state)
+ err := checkAuthorization(actionSetShortIdleState, string(sender))
+ if err != nil {
+ logger.Warningf("checkAuthorization failed, err: %v, actionId=%v", err, actionSetShortIdleState)
+ return dbusutil.ToError(err)
+ }
m.setShortIdleState(state)
return nil
}
@@ -141,3 +156,27 @@ func (m *Manager) LockCpuFreq(governor string, lockTime int32) *dbus.Error {
return nil
}
+
+// checkAuthorization verifies that the caller identified by sysBusName is
+// allowed to perform the polkit action identified by actionId. It mirrors
+// the pattern used by system/airplane_mode1 so that active local users are
+// allowed without an authentication dialog (allow_active: yes).
+func checkAuthorization(actionId string, sysBusName string) error {
+ systemBus, err := dbus.SystemBus()
+ if err != nil {
+ return err
+ }
+ authority := polkit.NewAuthority(systemBus)
+ subject := polkit.MakeSubject(polkit.SubjectKindSystemBusName)
+ subject.SetDetail("name", sysBusName)
+
+ ret, err := authority.CheckAuthorization(0, subject, actionId,
+ nil, polkit.CheckAuthorizationFlagsAllowUserInteraction, "")
+ if err != nil {
+ return err
+ }
+ if !ret.IsAuthorized {
+ return errors.New("not authorized")
+ }
+ return nil
+}