gpt4 book ai didi

perl - 如何为 IPC::Run 提供由用户输入设置的包含嵌入空格的参数

转载 作者:行者123 更新时间:2023-12-02 03:10:38 26 4
gpt4 key购买 nike

centos-6.8 perl,v5.10.1 (*) 为 x86_64-linux-thread-multi 构建

这个问题源于这个Where is the shell command called which invokes OpenSSL commands? .简而言之,我正在破解一个非常古老的 Perl 脚本,用于维护内部私有(private) PKI,以便默认签名哈希和 key 大小满足当前浏览器的要求。

我有这些代码片段:

. . .    
$args->{keypass} = $self->getPassword("Private key password",1)
unless $args->{keypass};
$self->warn("# Password argument: $args->{keypass}\n") if $ENV{CSPDEBUG};
my $cmd = "-out $args->{keyfile} $args->{keysize}";
$cmd = "-des3 -passout pass:$args->{keypass} ".$cmd if defined($args->{keypass});
$self->{openssl}->cmd('genrsa',$cmd,$args);
. . .
$self->{openssl}->cmd('req',"-x509 $common_args -new -out $cacert",$args);
. . .
use IPC::Run qw( start pump finish timeout new_appender new_chunker);
. . .
sub cmd
{
my $self = shift;
my $cmd = shift;
my $cmdline = shift;
my $args = shift;
my $conf;
my $cfgcmd;
. . .
$self->{_handle}->pump while length ${$self->{_in}};
. . .

如果用户提供的密码参数值不包含空格,则此代码会按预期执行。如果它确实包含嵌入的空格,那么代码会自动失败。如果传递给 keypass 的参数与开始和结束单引号连接在一起,那么代码同样会静默失败。在这两种失败的情况下,脚本仍然会报告成功。

为什么?

无论用户输入是否包含空格,都需要进行哪些更改才能使此代码正常工作?

最佳答案

要回答你的字面问题,让我 quote the IPC::Run manual :

"run(), start(), and harness() can all take a harness specification as input. A harness specification is either a single string to be passed to the systems' shell […] or a list of commands, io operations, and/or timers/timeouts to execute."

为了防止命令参数被 shell 解析(这是当参数包含空格时导致事情中断的原因),你不应该将它们作为单个字符串传递,而是作为对包含每个单独参数的数组的引用作为单个字符串,像这样:

my @cmd = ("-out", $args->{keyfile}, $args->{keysize});
unshift @cmd, ("-des3", "-passout", "pass:$args->{keypass}") if defined $args->{keypass};
# ...
my $h = start ["openssl", "genrsa", @cmd], \$in, \$out; # or something equivalent

(您发布的代码似乎是通过一些自定义界面层使用 IPC::Run;由于您没有向我们展示该层的确切外观,我已将其替换为对 IPC 的简单调用: :运行::开始。)


无论如何,请注意在命令行上传递密码通常被认为是不安全的:如果任何不受信任的用户可以在同一台服务器上运行代码(即使是在非特权帐户下),他们只需运行 ps ax 就可以看到密码. openssl manual注意到这一点,并警告 pass:<i>password</i> “只应在安全性不重要的情况下使用。”

一个更安全的选择是 send the password over a separate file descriptor .方便的是,IPC::Run 使这变得非常简单:

my @cmd = ("-out", $args->{keyfile}, $args->{keysize});
unshift @cmd, ("-des3", "-passout", "fd:3") if defined $args->{keypass};
# ...
my $h = start ["openssl", "genrsa", @cmd], '<', \$in, '>', \$out, '3<', \$args->{keypass};

此处,密码通过文件描述符编号 3 传递;如果需要传入多个密码,可以使用文件描述符 4、5 等。 (描述符 0、1 和 2 是标准输入、标准输出和标准错误。)

免责声明:显然,这是所有未经测试的代码。我不是 IPC::Run 方面的专家,所以我可能犯了一些愚蠢的命令语法错误或其他错误。使用前请彻底测试!

关于perl - 如何为 IPC::Run 提供由用户输入设置的包含嵌入空格的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40248701/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com