我正在尝试使用CA捆绑文件验证证书。原始的Bash命令采用两个这样的文件参数;
openssl verify -CAfile ca-ssl.ca cert-ssl.crt
我试图弄清楚如何在python子进程中运行上面的命令,同时将ca-ssl.ca和cert-ssl.crt作为变量字符串(而不是文件)。
如果我在bash中使用变量(而不是文件)运行命令,那么这将起作用;
ca_value=$(<ca-ssl.ca)
cert_value=$(<cert-ssl.crt)
openssl verify -CAfile <(echo "$ca_value") <(echo "$cert_value")
但是,我正在努力弄清楚如何使用Python来完成上述操作,最好不需要使用shell=True
。我尝试了以下但不起作用,而是为openssl打印'help'命令;
certificate = ''' cert string '''
ca_bundle = ''' ca bundle string '''
def ca_valid(cert, ca):
ca_validation = subprocess.Popen(['openssl', 'verify', '-CAfile', ca, cert], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=1)
ca_validation_output = ca_validation.communicate()[0].strip()
ca_validation.wait()
ca_valid(certificate, ca_bundle)
任何关于我需要进一步研究的指导/线索都将受到赞赏。
答案 0 :(得分:1)
最后Bash进程替换--keyFile
提供文件路径作为<(...)
的参数。
您需要创建一个辅助函数来创建此功能,因为Python没有任何运算符允许您将管道数据内联到文件中并显示其路径:
openssl
其中import subprocess
def validate_ca(cert, ca):
with filearg(ca) as ca_path, filearg(cert) as cert_path:
ca_validation = subprocess.Popen(
['openssl', 'verify', '-CAfile', ca_path, cert_path],
stdout=subprocess.PIPE,
)
return ca_validation.communicate()[0].strip()
是一个上下文管理器,它使用您想要的文本创建一个命名的临时文件,关闭它,将路径交给您,然后在filearg
范围结束后删除它。
with
访问此临时文件(如子进程)的任何内容都需要在上下文管理器中工作。
顺便说一下,import os
import tempfile
from contextlib import contextmanager
@contextmanger
def filearg(txt):
with tempfile.NamedTemporaryFile('w', delete=False) as fh:
fh.write(txt)
try:
yield fh.name
finally:
os.remove(fh.name)
是多余的,因为Popen.wait(self)
等待终止。
答案 1 :(得分:-2)
如果您想使用流程替换,您将 使用shell=True
。这是不可避免的。 <(...)
进程替换语法是bash语法;你只需要将bash调用服务来解析并执行这样的代码。
此外,您必须确保调用bash
,而不是sh
。在某些系统上sh
可能引用旧的Bourne shell(而不是Bourne-again shell bash
),在这种情况下,进程替换肯定不起作用。在某些系统sh
将调用bash
,但进程替换仍然不起作用,因为在名称sh
下调用bash
shell时会进入称为POSIX模式的东西。以下是bash
手册页的一些摘录:
...
INVOCATION
...当调用sh时,bash在读取启动文件后进入posix模式。 ....
...
另见
...
http://tiswww.case.edu/~chet/bash/POSIX - posix模式的描述
...
从以上网站链接:
- 无法使用流程替换。
醇>
/bin/sh
似乎是python中的默认shell,无论您是使用os.system()
还是subprocess.Popen()
。因此,如果要指定完整路径,则必须指定参数executable='bash'
或executable='/bin/bash'
。
这对我有用:
subprocess.Popen('printf \'argument: "%s"\\n\' verify -CAfile <(echo ca_value) <(echo cert_value);',executable='bash',shell=True).wait();
## argument: "verify"
## argument: "-CAfile"
## argument: "/dev/fd/63"
## argument: "/dev/fd/62"
## 0
以下是如何实际嵌入变量中的字符串值:
bashEsc = lambda s: "'"+s.replace("'","'\\''")+"'";
ca_value = 'x';
cert_value = 'y';
cmd = 'printf \'argument: "%%s"\\n\' verify -CAfile <(echo %s) <(echo %s);'%(bashEsc(ca_value),bashEsc(cert_value));
subprocess.Popen(cmd,executable='bash',shell=True).wait();
## argument: "verify"
## argument: "-CAfile"
## argument: "/dev/fd/63"
## argument: "/dev/fd/62"
## 0