问题描述
我在 TypeScript 中为我的一个项目创建了一个自动安装脚本(编译为 JavaScript 并在 Node.js 下运行),该脚本曾经运行良好,但现在因“需要交互式身份验证”错误而失败来自 polkit
,这显然是 Raspbian 使用的安全策略服务。
脚本是使用 sudo
启动的,因此对于失败的事情,它应该以完全管理员权限运行,即停止我自己的服务 (service weatherService stop
),并在其中创建或修改文件/etc/default/
和 /etc/init.d/
定义了该服务。
我能猜到的是最近的一些安全更新让我感到悲伤,但具体是什么,我不知道。当我在谷歌上搜索我收到的特定错误消息以及关于 polkit
时,大多数讨论似乎都集中在哪些用户是 sudo 用户以及 sudo 用户可以做什么。但是,我作为“pi”用户尝试做的所有事情,在使用 sudo
运行时,我仍然可以在终端窗口中做而没有任何问题,并且没有任何“交互式身份验证”弹出来强迫我验证任何东西。
代码太大,无法在此处发布,但可以在 Github 上找到:https://github.com/kshetline/aw-clock/
...特别是在这个文件中:https://github.com/kshetline/aw-clock/b ... r/build.ts
以下是一些关键片段:
try {
await monitorProcess(spawn('service',['weatherService','stop']),spin,ErrorMode.ANY_ERROR);
}
catch (err) {
const msg = err.message || err.toString();
// Grief from polkit?
if (/Interactive authentication required/i.test(msg)) {
// Blah,blah,blah...
}
}
import { ChildProcess,execSync,spawn as nodeSpawn } from 'child_process';
export function spawn(command: string,args: string[],options?: any): ChildProcess;
export function spawn(command: string,uid?: number,args?: string[],uidOrArgs?: string[] | number,optionsOrArgs?: any,options?: any): ChildProcess {
let uid: number;
let args: string[];
if (isNumber(uidOrArgs)) {
uid = uidOrArgs;
args = optionsOrArgs || [];
}
else {
args = uidOrArgs || [];
options = optionsOrArgs;
uid = options?.uid;
}
if (uid != null) {
options = options ?? {};
options.uid = uid;
if (!options.env) {
options.env = {};
Object.assign(options.env,process.env);
}
options.env.HOME = userHome;
options.env.LOGNAME = sudoUser;
options.env.npm_config_cache = userHome + '/.npm';
options.env.USER = sudoUser;
}
if (isWindows) {
if (/^(chmod|chown|id)$/.test(command)) {
// Effectively a "noop"
command = 'rundll32';
args = [];
}
else if (command === 'rm') {
// Ad hoc,not a general solution conversion of rm!
command = 'rmdir';
args = ['/S','/Q',args[1].replace(/\//g,'\\')];
}
else if (command === 'which')
command = 'where';
const cmd = process.env.comspec || 'cmd';
if (options?.uid != null) {
options = Object.assign({},options);
delete options.uid;
}
return nodeSpawn(cmd,['/c',command,...args],options);
}
else
return nodeSpawn(command,args,options);
}
export function monitorProcess(proc: ChildProcess,markTime: () => void = undefined,errorMode = ErrorMode.DEFAULT): Promise<string> {
let errors = '';
let output = '';
return new Promise<string>((resolve,reject) => {
const slowSpin = unref(setInterval(markTime || NO_OP,MAX_MARK_TIME_DELAY));
proc.stderr.on('data',data => {
(markTime || NO_OP)();
data = stripformatting(data.toString());
// This gets confusing,because a lot of non-error progress messaging goes to stderr,and the
// webpack process doesn't exit with an error for compilation errors unless you make it do so.
if (/(\[webpack.Progress])|Warning\b/.test(data))
return;
errors += data;
});
proc.stdout.on('data',data => {
(markTime || NO_OP)();
data = data.toString();
output += data;
if (errorish(data))
errors = errors ? errors + '\n' + data : data;
});
proc.on('error',err => {
clearInterval(slowSpin);
if (errorMode !== ErrorMode.NO_ERRORS)
resolve(output);
else
reject(err);
});
proc.on('close',() => {
clearInterval(slowSpin);
if (errorMode !== ErrorMode.NO_ERRORS && errors && (errorMode === ErrorMode.ANY_ERROR || errorish(errors)))
reject(errors.replace(/\bE:\s+/g,'').trim());
else
resolve(output);
});
});
}
尽管上面的代码很复杂,用于监控进程输出流、处理不同的操作系统和设置一些环境变量,但它实际上只是对 Node.js 的 spawn
函数的包装,事实上我曾经能够成功生成的命令现在因这个 polkit
问题而失败。
polkit
服务似乎是一个巨大的蠕虫罐,有许多独立的复杂策略文件,定义了谁可以用什么做什么。由于我试图用我的脚本做的就是做 sudo-er 通常有权做的事情,我什至不知道为什么 polkit
关心,或者这个“交互式身份验证”甚至是什么样子 - - 用户或我的脚本无论如何都不会尝试与之交互的提示出现。
我真正希望(对成功的期望很低)是有人在阅读本文时会“哦,那个问题!”反应。除此之外,对于不熟悉类似问题的任何人来说,这个故障真的很难描述得足够好。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)