2014-10-02 4 views
4

Я пытаюсь создать t.w.c.BrowserLikePolicyForHTTPS для использования в качестве ContextFactory для t.w.c.Agent. Я использую внутренний ЦС для всех серверов, с которыми я хочу, чтобы Агент связывался, поэтому я хотел бы сказать, чтобы загрузить загрузку сертификата CA (формат PEM) и использовать его в качестве аргумента trustRoot для BrowserLikePolicyForHTTPS. Я прочитал документы и посмотрел на источник, но я понятия не имею, что я должен предлагать в качестве аргументов. Я попытался предоставление объекта PyOPenSSL x509, но я получаю сообщение об ошибке:Twisted Python Как создать файл twisted.web.client.BrowserLikePolicyForHTTPS с пользовательским trustRoot?

exceptions.TypeError: ('Could not adapt', <OpenSSL.crypto.X509 object at 0x280b290>, <InterfaceClass twisted.internet._sslverify.IOpenSSLTrustRoot>) 

я могу увидеть в коде в t.i._sslverify, что OpenSSLCertificateAuthorities какие-то образом получает адаптированные к IOpenSSLTrustRoot, но это не совсем понятно, как это происходит.

Я знаю, что агент по продаже не проводит сертификацию. Я работаю с вилкой treq и экспериментирую с добавлением опции для предоставления настраиваемого агента.

Любая помощь с аргументом trustRoot будет оценена по достоинству. Если я собираюсь сделать это с трудом, сообщите мне об этом.

ответ

6

Ваш вопрос здесь подчеркивает страшный надзор в документации; как в документации по API, так и в описательной документации. Если Жан-Поль не может понять «правильный путь», чтобы сделать это, то нет надежды на обычного пользователя. I have filed a bug to correct this oversight.

В то же время, пожалуйста, избегайте решения Жан-Поля. Хотя он функциональный, он включает в себя методы, которые почти наверняка будут развенчаны без предупреждения в будущих выпусках (как он четко отмечает). К счастью, поддерживаются способы сделать это.Если у вас есть один альтернативный доверительный корень, Certificate можно использовать в качестве значения для параметра trustRoot. Вы можете использовать его как так (я тестировал следующий пример с рассеченной 14.0.2):

from __future__ import print_function 
from twisted.web.client import Agent, BrowserLikePolicyForHTTPS 
from twisted.internet.task import react 
from twisted.internet.ssl import Certificate 
from twisted.internet.protocol import Protocol 
from twisted.python.filepath import FilePath 
from twisted.internet.defer import inlineCallbacks, Deferred 

@inlineCallbacks 
def main(reactor): 
    customPolicy = BrowserLikePolicyForHTTPS(
     Certificate.loadPEM(FilePath("your-trust-root.pem").getContent()) 
    ) 
    agent = Agent(reactor, customPolicy) 
    response = yield agent.request(
     "GET", "https://your-web-site.example.com/" 
    ) 
    done = Deferred() 
    class CaptureString(Protocol): 
     def dataReceived(self, data): 
      print("Received:", data) 
     def connectionLost(self, reason): 
      done.callback(None) 
    response.deliverBody(CaptureString()) 
    yield done 

react(main) 
+1

Это немного сложнее сделать, если у вас несколько альтернативных приемлемых корней доверия, и я также подал билет Twisted, чтобы обратиться к этому адресу: https://twistedmatrix.com/trac/ticket/7671. – Glyph

+0

Будет ли # 7671 также адресовать объединение собственных корней доверия с корнями доверия системы? Бывают ситуации, когда я хотел бы использовать пакет OS CA плюс мой собственный сертификат CA. Я не уверен, что предлагаемое решение в билете учитывает это, если только вы не можете просто указать путь туда, где хранится пакет ОС. – Carl

+0

Думаю, это должно произойти. Прошу прокомментировать билет для дальнейшего обсуждения, хотя :). (Кроме того, если вы не возражаете изменить этот ответ на «принято», я бы предпочел, чтобы люди приняли этот совет, чем Жан-Поль в этом случае.) – Glyph

0

IOpenSSLTrustRoot - это немного глупости API.

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

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

Если вы пишете какой-то код, который зависит от этого интерфейса, он всегда работает так, как будто он работает, тогда вы, вероятно, можете, по крайней мере, опубликовать его в списке Twisted listing и сказать это, и люди, вероятно, попытаются не разорвать ваше приложение.

Как сказано выше, каждая часть этого является частной. Twisted's заявлено политики нет никаких гарантий обратной совместимости здесь. Так что продолжайте на свой страх и риск.

В любом случае, вы можете написать что-то вроде этого:

from zope.interface import implementer 

from characteristic import attributes 

from twisted.internet._sslverify import IOpenSSLTrustRoot 

@implementer(IOpenSSLTrustRoot) 
@attributes(["root_certificate_path"]) 
class MyCATrustRoot(object): 
    def _addCACertsToContext(self, context): 
     context.load_verify_locations(self.root_certificate_path) 

Затем используйте MyCATrustRoot экземпляр в качестве аргумента trustRootBrowserLikePolicyForHTTPS. Убедитесь, что вы используете хотя бы Twisted 14.0.2, потому что более ранние версии фактически игнорировали trustRoot, которые вы передали BrowserLikePolicyForHTTPS.

Например, если ваш доверенный «CA» сертификат на /foo/ca.pem:

from twisted.web.client import BrowserLikePolicyForHTTPS, Agent 
from twisted.internet import reactor 

agent = Agent(reactor, BrowserLikePolicyForHTTPS(
    MyCATrustRoot(root_certificate_path="/foo/ca.pem"))) 
+0

В вашем последнем примере класс MyCATrustRoot предполагается использовать в явном виде, или есть какое-то адаптация магия происходит на? – Carl

+0

К сожалению, ошибка в коде. Закрепление. –

+0

Кроме того, еще одно редактирование, чтобы быть понятным о характере частных интерфейсов в Twisted. –

Смежные вопросы