コード例 #1
0
ファイル: proxy.py プロジェクト: isotoma/badgerproxy
    def action_rewrite_ssl(self, host, ip, port, resturi, headers, data, clientproto):
        class FakeFactory:
            def log(self, meh):
                pass
        FakeFactory.host = host
        FakeFactory.port = port
        FakeFactory.root = self.channel.factory.root
        rp = ReverseProxy()
        rp.factory = FakeFactory()

        contextFactory = ssl.DefaultOpenSSLContextFactory(sibpath('server.key'), sibpath('server.crt'))

        class FakeFactory2:
            _contextFactory = contextFactory
            _isClient = False
            def registerProtocol(self, meh):
                pass
            def unregisterProtocol(self, meh):
                pass
        ssl_rp = TLSMemoryBIOProtocol(FakeFactory2(), rp)

        self.channel._registerTunnel(ssl_rp)
        ssl_rp.makeConnection(self.transport)

        self.setResponseCode(200)
        self.write("")
コード例 #2
0
ファイル: test_tls.py プロジェクト: bluemutedwisdom/twisted
    def test_loseConnectionTwice(self):
        """
        If TLSMemoryBIOProtocol.loseConnection is called multiple times, all
        but the first call have no effect.
        """
        wrapperFactory = TLSMemoryBIOFactory(ClientContextFactory(),
                                             True, ClientFactory())
        tlsProtocol = TLSMemoryBIOProtocol(wrapperFactory, Protocol())
        transport = StringTransport()
        tlsProtocol.makeConnection(transport)
        self.assertEqual(tlsProtocol.disconnecting, False)

        # Make sure loseConnection calls _shutdownTLS the first time (mostly
        # to make sure we've overriding it correctly):
        calls = []
        def _shutdownTLS(shutdown=tlsProtocol._shutdownTLS):
            calls.append(1)
            return shutdown()
        tlsProtocol._shutdownTLS = _shutdownTLS
        tlsProtocol.loseConnection()
        self.assertEqual(tlsProtocol.disconnecting, True)
        self.assertEqual(calls, [1])

        # Make sure _shutdownTLS isn't called a second time:
        tlsProtocol.loseConnection()
        self.assertEqual(calls, [1])
コード例 #3
0
        def startTLS(self, contextFactory, normal=True):
            """
            @see: L{ITLSTransport.startTLS}
            """
            # Figure out which direction the SSL goes in.  If normal is True,
            # we'll go in the direction indicated by the subclass.  Otherwise,
            # we'll go the other way (client = not normal ^ _tlsClientDefault,
            # in other words).
            if normal:
                client = self._tlsClientDefault
            else:
                client = not self._tlsClientDefault

            tlsFactory = TLSMemoryBIOFactory(contextFactory, client, None)
            tlsProtocol = TLSMemoryBIOProtocol(tlsFactory, self.protocol,
                                               False)
            self.protocol = tlsProtocol

            self.getHandle = tlsProtocol.getHandle
            self.getPeerCertificate = tlsProtocol.getPeerCertificate

            # Mark the transport as secure.
            directlyProvides(self, interfaces.ISSLTransport)

            # Remember we did this so that write and writeSequence can send the
            # data to the right place.
            self._tls = True

            # Hook it up
            self.protocol.makeConnection(_BypassTLS(self))
コード例 #4
0
 def test_renderSecureRequest(self):
     """
     When the rendered request is over HTTPS, L{WebSocketsResource} wraps
     the protocol of the C{TLSMemoryBIOProtocol} instance.
     """
     request = DummyRequest("/")
     request.requestHeaders = Headers()
     transport = StringTransportWithDisconnection()
     secureProtocol = TLSMemoryBIOProtocol(Factory(), Protocol())
     transport.protocol = secureProtocol
     request.transport = transport
     request.headers.update({
         "upgrade": "Websocket",
         "connection": "Upgrade",
         "sec-websocket-key": "secure",
         "sec-websocket-version": "13"
     })
     result = self.resource.render(request)
     self.assertEqual(NOT_DONE_YET, result)
     self.assertEqual(
         {
             "connection": "Upgrade",
             "upgrade": "WebSocket",
             "sec-websocket-accept": "oYBv54i42V5dw6KnZqOFroecUTc="
         }, request.outgoingHeaders)
     self.assertEqual([""], request.written)
     self.assertEqual(101, request.responseCode)
     self.assertIdentical(None, request.transport)
     self.assertIsInstance(transport.protocol.wrappedProtocol,
                           WebSocketsProtocol)
     self.assertIsInstance(transport.protocol.wrappedProtocol._receiver,
                           SavingEchoReceiver)
コード例 #5
0
ファイル: test_tls.py プロジェクト: MayuraVerma/Kannada
 def test_interfaces(self):
     """
     L{TLSMemoryBIOProtocol} instances provide L{ISSLTransport} and
     L{ISystemHandle}.
     """
     proto = TLSMemoryBIOProtocol(None, None)
     self.assertTrue(ISSLTransport.providedBy(proto))
     self.assertTrue(ISystemHandle.providedBy(proto))
コード例 #6
0
def startTLS(transport, contextFactory, normal, bypass):
    """
    Add a layer of SSL to a transport.

    @param transport: The transport which will be modified.  This can either by
        a L{FileDescriptor<twisted.internet.abstract.FileDescriptor>} or a
        L{FileHandle<twisted.internet.iocpreactor.abstract.FileHandle>}.  The
        actual requirements of this instance are that it have:

          - a C{_tlsClientDefault} attribute indicating whether the transport is
            a client (C{True}) or a server (C{False})
          - a settable C{TLS} attribute which can be used to mark the fact
            that SSL has been started
          - settable C{getHandle} and C{getPeerCertificate} attributes so
            these L{ISSLTransport} methods can be added to it
          - a C{protocol} attribute referring to the L{IProtocol} currently
            connected to the transport, which can also be set to a new
            L{IProtocol} for the transport to deliver data to

    @param contextFactory: An SSL context factory defining SSL parameters for
        the new SSL layer.
    @type contextFactory: L{twisted.internet.ssl.ContextFactory}

    @param normal: A flag indicating whether SSL will go in the same direction
        as the underlying transport goes.  That is, if the SSL client will be
        the underlying client and the SSL server will be the underlying server.
        C{True} means it is the same, C{False} means they are switched.
    @type param: L{bool}

    @param bypass: A transport base class to call methods on to bypass the new
        SSL layer (so that the SSL layer itself can send its bytes).
    @type bypass: L{type}
    """
    # Figure out which direction the SSL goes in.  If normal is True,
    # we'll go in the direction indicated by the subclass.  Otherwise,
    # we'll go the other way (client = not normal ^ _tlsClientDefault,
    # in other words).
    if normal:
        client = transport._tlsClientDefault
    else:
        client = not transport._tlsClientDefault

    tlsFactory = TLSMemoryBIOFactory(contextFactory, client, None)
    tlsProtocol = TLSMemoryBIOProtocol(tlsFactory, transport.protocol, False)
    transport.protocol = tlsProtocol

    transport.getHandle = tlsProtocol.getHandle
    transport.getPeerCertificate = tlsProtocol.getPeerCertificate

    # Mark the transport as secure.
    directlyProvides(transport, ISSLTransport)

    # Remember we did this so that write and writeSequence can send the
    # data to the right place.
    transport.TLS = True

    # Hook it up
    transport.protocol.makeConnection(_BypassTLS(bypass, transport))
コード例 #7
0
ファイル: test_tls.py プロジェクト: bluemutedwisdom/twisted
    def test_connectionLostOnlyAfterUnderlyingCloses(self):
        """
        The user protocol's connectionLost is only called when transport
        underlying TLS is disconnected.
        """
        class LostProtocol(Protocol):
            disconnected = None
            def connectionLost(self, reason):
                self.disconnected = reason
        wrapperFactory = TLSMemoryBIOFactory(ClientContextFactory(),
                                             True, ClientFactory())
        protocol = LostProtocol()
        tlsProtocol = TLSMemoryBIOProtocol(wrapperFactory, protocol)
        transport = StringTransport()
        tlsProtocol.makeConnection(transport)

        # Pretend TLS shutdown finished cleanly; the underlying transport
        # should be told to close, but the user protocol should not yet be
        # notified:
        tlsProtocol._tlsShutdownFinished(None)
        self.assertEqual(transport.disconnecting, True)
        self.assertEqual(protocol.disconnected, None)

        # Now close the underlying connection; the user protocol should be
        # notified with the given reason (since TLS closed cleanly):
        tlsProtocol.connectionLost(Failure(ConnectionLost("ono")))
        self.assertTrue(protocol.disconnected.check(ConnectionLost))
        self.assertEqual(protocol.disconnected.value.args, ("ono",))
コード例 #8
0
ファイル: test_tls.py プロジェクト: Almad/twisted
    def test_getHandle(self):
        """
        L{TLSMemoryBIOProtocol.getHandle} returns the L{OpenSSL.SSL.Connection}
        instance it uses to actually implement TLS.

        This may seem odd.  In fact, it is.  The L{OpenSSL.SSL.Connection} is
        not actually the "system handle" here, nor even an object the reactor
        knows about directly.  However, L{twisted.internet.ssl.Certificate}'s
        C{peerFromTransport} and C{hostFromTransport} methods depend on being
        able to get an L{OpenSSL.SSL.Connection} object in order to work
        properly.  Implementing L{ISystemHandle.getHandle} like this is the
        easiest way for those APIs to be made to work.  If they are changed,
        then it may make sense to get rid of this implementation of
        L{ISystemHandle} and return the underlying socket instead.
        """
        factory = ClientFactory()
        contextFactory = ClientContextFactory()
        wrapperFactory = TLSMemoryBIOFactory(contextFactory, True, factory)
        proto = TLSMemoryBIOProtocol(wrapperFactory, Protocol())
        transport = StringTransport()
        proto.makeConnection(transport)
        self.assertIsInstance(proto.getHandle(), ConnectionType)
コード例 #9
0
ファイル: test_tls.py プロジェクト: MayuraVerma/Kannada
    def test_getHandle(self):
        """
        L{TLSMemoryBIOProtocol.getHandle} returns the L{OpenSSL.SSL.Connection}
        instance it uses to actually implement TLS.

        This may seem odd.  In fact, it is.  The L{OpenSSL.SSL.Connection} is
        not actually the "system handle" here, nor even an object the reactor
        knows about directly.  However, L{twisted.internet.ssl.Certificate}'s
        C{peerFromTransport} and C{hostFromTransport} methods depend on being
        able to get an L{OpenSSL.SSL.Connection} object in order to work
        properly.  Implementing L{ISystemHandle.getHandle} like this is the
        easiest way for those APIs to be made to work.  If they are changed,
        then it may make sense to get rid of this implementation of
        L{ISystemHandle} and return the underlying socket instead.
        """
        factory = ClientFactory()
        contextFactory = ClientContextFactory()
        wrapperFactory = TLSMemoryBIOFactory(contextFactory, True, factory)
        proto = TLSMemoryBIOProtocol(wrapperFactory, Protocol())
        transport = StringTransport()
        proto.makeConnection(transport)
        self.assertIsInstance(proto.getHandle(), ConnectionType)
コード例 #10
0
    def startTLS(self, contextFactory, client, bytes=None):
        """
        Add a layer of TLS, with SSL parameters defined by the given
        contextFactory.

        If *client* is True, this side of the connection will be an
        SSL client.  Otherwise it will be an SSL server.

        If extra bytes which may be (or almost certainly are) part of
        the SSL handshake were received by the protocol running on top
        of OnionProtocol, they must be passed here as the **bytes**
        parameter.
        """
        # The newest TLS session is spliced in between the previous
        # and the application protocol at the tail end of the list.
        tlsProtocol = TLSMemoryBIOProtocol(None, self._tailProtocol, False)
        tlsProtocol.factory = TLSMemoryBIOFactory(contextFactory, client, None)

        if self._currentProtocol is self._tailProtocol:
            # This is the first and thus outermost TLS session.  The
            # transport is the immutable sentinel that no startTLS or
            # stopTLS call will move within the linked list stack.
            # The wrappedProtocol will remain this outermost session
            # until it's terminated.
            self.wrappedProtocol = tlsProtocol
            nextTransport = PopOnDisconnectTransport(original=self.transport,
                                                     pop=self._pop)
            # Store the proxied transport as the list's head sentinel
            # to enable an easy identity check in _pop.
            self._headTransport = nextTransport
        else:
            # This a later TLS session within the stack.  The previous
            # TLS session becomes its transport.
            nextTransport = PopOnDisconnectTransport(
                original=self._currentProtocol, pop=self._pop)

        # Splice the new TLS session into the linked list stack.
        # wrappedProtocol serves as the link, so the protocol at the
        # current position takes our new TLS session as its
        # wrappedProtocol.
        self._currentProtocol.wrappedProtocol = tlsProtocol
        # Move down one position in the linked list.
        self._currentProtocol = tlsProtocol
        # Expose the new, innermost TLS session as the transport to
        # the application protocol.
        self.transport = self._currentProtocol
        # Connect the new TLS session to the previous transport.  The
        # transport attribute also serves as the previous link.
        tlsProtocol.makeConnection(nextTransport)

        # Left over bytes are part of the latest handshake.  Pass them
        # on to the innermost TLS session.
        if bytes is not None:
            tlsProtocol.dataReceived(bytes)
コード例 #11
0
    def clientConnectionForTLS(
        self, tls_protocol: TLSMemoryBIOProtocol
    ) -> SSL.Connection:
        context = self._ctx
        connection = SSL.Connection(context, None)

        # as per twisted.internet.ssl.ClientTLSOptions, we set the application
        # data to our TLSMemoryBIOProtocol...
        connection.set_app_data(tls_protocol)

        # ... and we also gut-wrench a '_synapse_tls_verifier' attribute into the
        # tls_protocol so that the SSL context's info callback has something to
        # call to do the cert verification.
        tls_protocol._synapse_tls_verifier = self._verifier  # type: ignore[attr-defined]
        return connection
コード例 #12
0
 def test_renderSecureRequest(self):
     """
     When the rendered request is over HTTPS, L{WebSocketsResource} wraps
     the protocol of the C{TLSMemoryBIOProtocol} instance.
     """
     request = DummyRequest(b"/")
     request.requestHeaders = Headers(
         {b"user-agent": [b"user-agent"], b"host": [b"host"]}
     )
     transport = StringTransportWithDisconnection()
     secureProtocol = TLSMemoryBIOProtocol(Factory(), Protocol())
     transport.protocol = secureProtocol
     request.transport = transport
     self.update_headers(
         request,
         headers={
             b"upgrade": b"Websocket",
             b"connection": b"Upgrade",
             b"sec-websocket-key": b"secure",
             b"sec-websocket-version": b"13",
         },
     )
     result = self.resource.render(request)
     self.assertEqual(NOT_DONE_YET, result)
     self.assertEqual(
         {
             b"Connection": [b"Upgrade"],
             b"Upgrade": [b"WebSocket"],
             b"Sec-Websocket-Accept": [b"oYBv54i42V5dw6KnZqOFroecUTc="],
         },
         {
             name: value
             for name, value in request.responseHeaders.getAllRawHeaders()
         },
     )
     self.assertEqual([b""], request.written)
     self.assertEqual(101, request.responseCode)
     self.assertIsNone(request.transport)
     self.assertIsInstance(
         transport.protocol.wrappedProtocol, WebSocketsProtocol
     )
     self.assertIsInstance(
         transport.protocol.wrappedProtocol._receiver, SavingEchoReceiver
     )