简体   繁体   English

Python STDOUT 与 openssl 子流程一起归档

[英]Python STDOUT to file with openssl subprocess

I am trying to write a python script to automate the process of checking for SSL renegotiation through openSSL and output the results to a file. I am trying to write a python script to automate the process of checking for SSL renegotiation through openSSL and output the results to a file. I have run into 2 problems.我遇到了2个问题。

My first problem is that the output from the initial handshake gets written to the file, however the actual renegotiation part does not.我的第一个问题是初始握手中的 output 被写入文件,但实际的重新协商部分没有。 It is instead displayed on the console.而是显示在控制台上。

subprocess.call("echo \"R\" | openssl s_client -connect example.com:443", 
        shell=True, stdout=FILE)

My other problem (although this may be the wrong spot for it) is that I cannot get the openSSL command to work for sending the GET command.我的另一个问题(尽管这可能是错误的地方)是我无法让 openSSL 命令用于发送 GET 命令。

subprocess.call("echo -e \"GET / HTTP/1.1\r\n\r\n\" | openssl s_client -connect
        example.com:443", shell=True)   

Again, the initial connection is set up but then openSSL exists, it does not process the GET request.同样,初始连接已建立,但随后 openSSL 存在,它不处理 GET 请求。

Any help would be greatly appreciated.任何帮助将不胜感激。 Thanks.谢谢。

There's no reason to use shell=True for inputs.没有理由使用shell=True作为输入。 Instead, use stdin=subprocess.PIPE .相反,使用stdin=subprocess.PIPE Also, note that your request is not valid since HTTP 1.1 requires the Host header.另外,请注意您的请求无效,因为 HTTP 1.1 需要Host header。 Additionally, I can't think of a reason to use the command line openssl instead of the ssl module .此外,我想不出使用命令行 openssl 代替ssl 模块的理由。

That being said, here's a working example:话虽如此,这是一个工作示例:

import subprocess

f = open('http_answer', 'w')
_,log = subprocess.Popen(
    ['openssl', 's_client', '-quiet', '-connect', 'twitter.com:443'],
    stdout=f, stderr=subprocess.PIPE, stdin=subprocess.PIPE
).communicate('GET / HTTP/1.0\r\n\r\n')
print('Output of SSL:\n' + log)

@phihag I have made slight changes to your scrip and is working well for me. @phihag 我对你的脚本做了一些细微的改动,对我来说效果很好。

import subprocess

f = open('http_answer', 'w')
_,log = subprocess.Popen(
    ['openssl', 's_client', '-quiet', '-connect', 'twitter.com:443','-sess_out', 'session.txt'],
    stdout=f, stderr=subprocess.PIPE, stdin=subprocess.PIPE ).communicate('GET / HTTP/1.0\r\nHOST: twitter.com\r\n\r\n') print('Output of SSL:\n' + log)

Listing the changes 1. added 'sess_out' 'session.txt' parameters which preserves all the SSL Session paramerters which can be views using the following openssl command列出更改 1. 添加 'sess_out' 'session.txt' 参数,保留所有 SSL Session 参数,可以使用以下 Z50955D4B2031271F8FDA1764C1A66 命令查看

$openssl sess_id -in test.txt -text -cert -noout
  1. Added host information to the GET command, as the newer section respond well only with the HOST option.将主机信息添加到 GET 命令,因为较新的部分仅使用 HOST 选项响应良好。

    'GET / HTTP/1.0\r\nHOST: twitter.com\r\n\r\n' 'GET / HTTP/1.0\r\n主机:twitter.com\r\n\r\n'

@Drew, Its too late but I hope this is bit helpful. @Drew,为时已晚,但我希望这有点帮助。 Thank you.谢谢你。

Keep in mind that openssl s_client uses also stderr for some of the output.请记住,openssl s_client 还对某些 output 使用 stderr。 You need to check whether the renegotiation goes to stderr, which I believe it does, though my memory might be fading.您需要检查重新谈判是否进入 stderr,我相信它确实如此,尽管我的 memory 可能正在消失。

I've accomplished this in a different way, though not in python.我以不同的方式完成了这项工作,但不是在 python 中。 I've created a process and hooked the stdin, stdout, stderr file descriptors to ones I can read/write and I actually drive the input and read the output.我创建了一个进程并将标准输入、标准输出、标准错误文件描述符连接到我可以读/写的文件描述符上,我实际上驱动输入并读取 output。 It is a bit more work, but you have full control over what is going on and interacting with the process.这需要更多的工作,但您可以完全控制正在发生的事情并与流程进行交互。 I've done this in php and the test is available online at http://netsekure.org/2009/11/tls-renegotiation-test/ .我已经在 php 中完成了这项工作,该测试可在http://netsekure.org/2009/11/tls-renegotiation-test/在线获得。

Alternatively, you can just try using python to program openssl itself, instead of using the s_client, but this is more work and I've used the previous approach.或者,您可以尝试使用 python 对 openssl 本身进行编程,而不是使用 s_client,但这是更多的工作,我使用了以前的方法。

There are two things you can be checking and you didn't make it clear which one you are interested in:您可以检查两件事情,但您没有明确说明您对哪一件感兴趣:

  • checking whether remote server supports client initiated renegotiation检查远程服务器是否支持客户端发起的重新协商
  • checking whether remote server supports the secure renegotiation extension检查远程服务器是否支持安全重新协商扩展

Both of these can be simply deduced by just doing s_client and grep for the keywords applicable to both cases.只需对适用于这两种情况的关键字执行 s_client 和 grep 即可简单地推断出这两种情况。 It all depends on how much control/sophistication you need.这完全取决于您需要多少控制/复杂性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM