Example #1
0
 def _apply_mask(data, mask, length=None, offset=0):
     if length is None:
         length = len(data)
     cnt = range(length)
     return b''.join(
         six.int2byte(six.indexbytes(data, i) ^ mask[(offset + i) % 4])
         for i in cnt)
Example #2
0
    def test_receiving_doesnt_block_if_there_is_already_decrypted_buffered_data(self):
        # Here's what could (and would) happen before the relevant bug was fixed (assuming method
        # M was trampolining unconditionally before actually reading):
        # 1. One side sends n bytes, leaves connection open (important)
        # 2. The other side uses method M to read m (where m < n) bytes, the underlying SSL
        #    implementation reads everything from the underlying socket, decrypts all n bytes,
        #    returns m of them and buffers n-m to be read later.
        # 3. The other side tries to read the remainder of the data (n-m bytes), this blocks
        #    because M trampolines uncoditionally and trampoline will hang because reading from
        #    the underlying socket would block. It would block because there's no data to be read
        #    and the connection is still open; leaving the connection open /mentioned in 1./ is
        #    important because otherwise trampoline would return immediately and the test would pass
        #    even with the bug still present in the code).
        #
        # The solution is to first request data from the underlying SSL implementation and only
        # trampoline if we actually need to read some data from the underlying socket.
        #
        # GreenSSLSocket.recv() wasn't broken but I've added code to test it as well for
        # completeness.
        content = b'xy'

        def recv(sock, expected):
            assert sock.recv(len(expected)) == expected

        def recv_into(sock, expected):
            buf = bytearray(len(expected))
            assert sock.recv_into(buf, len(expected)) == len(expected)
            assert buf == expected

        for read_function in [recv, recv_into]:
            print('Trying %s...' % (read_function,))
            listener = listen_ssl_socket()

            def accept(listener):
                sock, addr = listener.accept()
                sock.sendall(content)
                return sock

            accepter = eventlet.spawn(accept, listener)

            client_to_server = None
            try:
                client_to_server = ssl.wrap_socket(eventlet.connect(listener.getsockname()))
                for character in six.iterbytes(content):
                    character = six.int2byte(character)
                    print('We have %d already decrypted bytes pending, expecting: %s' % (
                        client_to_server.pending(), character))
                    read_function(client_to_server, character)
            finally:
                if client_to_server is not None:
                    client_to_server.close()
                server_to_client = accepter.wait()

                # Very important: we only want to close the socket *after* the other side has
                # read the data it wanted already, otherwise this would defeat the purpose of the
                # test (see the comment at the top of this test).
                server_to_client.close()

                listener.close()
Example #3
0
    def test_pipe_writes_large_messages(self):
        r, w = os.pipe()

        r = greenio.GreenPipe(r, 'rb')
        w = greenio.GreenPipe(w, 'wb')

        large_message = b"".join([1024 * six.int2byte(i) for i in range(65)])

        def writer():
            w.write(large_message)
            w.close()

        gt = eventlet.spawn(writer)

        for i in range(65):
            buf = r.read(1024)
            expected = 1024 * six.int2byte(i)
            self.assertEqual(
                buf, expected, "expected=%r..%r, found=%r..%r iter=%d" %
                (expected[:4], expected[-4:], buf[:4], buf[-4:], i))
        gt.wait()
Example #4
0
    def test_pipe_writes_large_messages(self):
        r, w = os.pipe()

        r = greenio.GreenPipe(r, 'rb')
        w = greenio.GreenPipe(w, 'wb')

        large_message = b"".join([1024 * six.int2byte(i) for i in range(65)])

        def writer():
            w.write(large_message)
            w.close()

        gt = eventlet.spawn(writer)

        for i in range(65):
            buf = r.read(1024)
            expected = 1024 * six.int2byte(i)
            self.assertEqual(
                buf, expected,
                "expected=%r..%r, found=%r..%r iter=%d"
                % (expected[:4], expected[-4:], buf[:4], buf[-4:], i))
        gt.wait()
Example #5
0
 def _apply_mask(data, mask, length=None, offset=0):
     if length is None:
         length = len(data)
     cnt = range(length)
     return b''.join(six.int2byte(six.indexbytes(data, i) ^ mask[(offset + i) % 4]) for i in cnt)