linux pkexec以root身份运行基于qt的应用程序
接上篇
在登录用户为普通用户的情况下,因为我们需要弹窗来供用户输入,以root身份是不需要输入密码的,下面碰到的情况是以普通用户运行时碰到的情况
以 pkexec /home/jin/work/ConfidentialCheckSystem/Client运行我们的客户端
jin@jin:/tmp$ pkexec /home/jin/work/ConfidentialCheckSystem/Client
QXcbConnection: Could not connect to display
已放弃 (核心已转储)
没有弹窗直接核心转储了。
此时可以在/usr/share/polkit-1/actions/目录下添加一个.policy文件件
org.freedesktop.Client.policy 文件名中间的部分不强制要求org.xxx.xxx.policy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<vendor />
<vendor_url />
<!-- 权限ID,这个必须唯一 -->
<action id="org.freedesktop.Client">
<icon_name>folder</icon_name>
<message xml:lang="en_GB">Authentication is required to run the confidentiality check system</message>
<message xml:lang="zh_CN">启动保密检查工具需要授权</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
<!-- 这个defaults节点下的所有子节点可以有这些值no,yes,auth_self,auth_admin,auth_self_keep,auth_admin_keep -->
</defaults>
<!-- 权限提升的可执行文件,需是二进制文件 -->
<annotate key="org.freedesktop.policykit.exec.path">/home/jin/work/ConfidentialCheckSystem/Client</annotate>
<!-- 配置为true-->
<annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
</action>
</policyconfig>
此时我们在执行 pkexec /home/jin/work/ConfidentialCheckSystem/Client就可以弹出界面了。
或者我们也可以设置环境变量,ubuntu官网中说明了 As a result, pkexec will not allow you to run X11 applications as another user since the $ DISPLAY and $ XAUTHORITY environment variables are not set. (pkexec不允许您以另一个用户去运行x11 应用,因为未设置$ DISPLAY和$ XAUTHORITY环境变量)翻译稀碎,见谅。。。懂意思就可以了
所以我们运行
jin@jin:/home$ pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY /home/jin/work/ConfidentialCheckSystem/Client
recognition: no process found
同样可以看到我们的客户端已经运行起来了(客户端就不截图了)
因为添加配置文件不太适用于我们,所以选择使用方案2
以下为ubuntu官网的一段话:
The environment that PROGRAM will run it, will be set to a minimal known and safe
environment in order to avoid injecting code through LD_LIBRARY_PATH or similar
mechanisms. In addition the PKEXEC_UID environment variable is set to the user id of the
process invoking pkexec. As a result, pkexec will not allow you to run X11 applications as
another user since the $DISPLAY and $XAUTHORITY environment variables are not set. These
two variables will be retained if the org.freedesktop.policykit.exec.allow_gui annotation
on an action is set to a nonempty value; this is discouraged, though, and should only be
used for legacy programs.
大概意思是使用了pkexec运行程序,会将运行它的环境变量设置为最小(理解为DISPLAY和XAUTHORITY等这些环境变量发生了变化了,末尾为验证图),避免通过LD_LIBRARY_PATH或类似代码注入代码机制。
所以我们可以先保存当前的DISPALY和XAUTHORITY,然后将其传入给我们需要pkexec的程序,在其中设置这两个环境变量即可,然后我们以普通用户身份去启动这时候可以看到现要求我们输入密码,然后密码输入后可以看到我们的客户端界面了
root@jin:/home/jin/work# cat test.sh
#! /bin/bash
env > ./1.txt
display=$DISPLAY
xauthority=$XAUTHORITY
//以超级用户(root)身份运行1.sh 并且传入display和xauthority两个环境变量
pkexec /home/jin/work/1.sh $display $xauthority
root@jin:/home/jin/work# cat 1.sh
#! /bin/bash
env > ./2.txt
//设置环境变量
export env DISPLAY=$1 XAUTHORITY=$2
env > ./3.txt
cd /home/jin/work/ConfidentialCheckSystem/
//执行需要root权限的程序(客户端)
./Client
另外说明:此时使用pkexec启动程序已经可以看到界面了,但是发现字体和图片有些地方发生了变化,如字体变大,按钮颜色变深,偶有图片加载的效果不对。这是因为这个环境变量$XDG_CURRENT_DESKTOP,在使用pkexec后没有设置,我们将它获取传入就ok了(同前两个环境变量)。
(有兴趣的可以深究一下这三个环境变量)
最后放上验证图:
1.txt
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下