Python STDOUT в файл с подпроцессом openssl - PullRequest
3 голосов
/ 15 июля 2011

Я пытаюсь написать скрипт на python, чтобы автоматизировать процесс проверки повторного согласования SSL через openSSL и вывести результаты в файл. Я столкнулся с 2 проблемами.

Моя первая проблема заключается в том, что выходные данные первоначального рукопожатия записываются в файл, а фактическая часть повторного согласования - нет. Вместо этого он отображается на консоли.

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

Моя другая проблема (хотя это может быть неправильное место) заключается в том, что я не могу заставить команду openSSL работать для отправки команды GET.

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

Опять же, первоначальное соединение установлено, но затем существует openSSL, он не обрабатывает запрос GET.

Любая помощь будет принята с благодарностью. Спасибо.

Ответы [ 3 ]

5 голосов
/ 15 июля 2011

Нет причин использовать shell=True для ввода. Вместо этого используйте stdin=subprocess.PIPE. Также обратите внимание, что ваш запрос недействителен, поскольку для HTTP 1.1 требуется заголовок Host. Кроме того, я не могу придумать причину использовать командную строку openssl вместо ssl module .

Как говорится, вот рабочий пример:

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)
1 голос
/ 03 мая 2016

@ 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)

Перечисление изменений 1. добавлены параметры 'sess_out' 'session.txt', которые сохраняют все сеанс SSLпараметры, которые можно просматривать с помощью следующей команды openssl

$openssl sess_id -in test.txt -text -cert -noout

Добавлена ​​информация о хосте в команду GET, так как новый раздел хорошо отвечает только с опцией HOST.

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

@ Дрю, уже слишком поздно, но я надеюсьэто немного полезно.Спасибо.

1 голос
/ 15 июля 2011

Имейте в виду, что openssl s_client также использует stderr для некоторых выходных данных. Вам нужно проверить, переходит ли перезаключение к stderr, что, я полагаю, делает, хотя моя память может исчезать.

Я сделал это по-другому, но не в Python. Я создал процесс и подключил дескрипторы файлов stdin, stdout, stderr к тем, которые я могу читать / записывать, и я фактически управляю вводом и читаю вывод. Это немного больше работы, но у вас есть полный контроль над тем, что происходит и взаимодействует с процессом. Я сделал это в php, и тест доступен онлайн на http://netsekure.org/2009/11/tls-renegotiation-test/.

В качестве альтернативы, вы можете просто попробовать использовать python для программирования самого openssl вместо s_client, но это больше работы, и я использовал предыдущий подход.

Есть две вещи, которые вы можете проверять, и вы не дали понять, какая из них вас интересует:

  • проверка того, поддерживает ли удаленный сервер повторное согласование, инициированное клиентом
  • проверка того, поддерживает ли удаленный сервер расширение безопасного повторного согласования

Оба из них можно просто вывести, просто выполнив s_client и grep для ключевых слов, применимых к обоим случаям. Все зависит от того, сколько вам нужно управления / сложности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...