Ejemplo n.º 1
0
    def connect(self):
        try:
            connection = self.makesocket()

            if self.spoof_source_address:
                try:
                    # 19 is `IP_TRANSPARENT`, which is only available on Python 3.3+ on some OSes
                    if not connection.getsockopt(socket.SOL_IP, 19):
                        connection.setsockopt(socket.SOL_IP, 19, 1)
                except socket.error as e:
                    raise exceptions.TcpException(
                        "Failed to spoof the source address: " + e.strerror
                    )
            if self.source_address:
                connection.bind(self.source_address())
            connection.connect(self.address())
            self.source_address = Address(connection.getsockname())
        except (socket.error, IOError) as err:
            raise exceptions.TcpException(
                'Error connecting to "%s": %s' %
                (self.address.host, err)
            )
        self.connection = connection
        self.ip_address = Address(connection.getpeername())
        self._makefile()
        return ConnectionCloser(self)
Ejemplo n.º 2
0
 def connect(self):
     try:
         connection = self.create_connection()
     except (socket.error, IOError) as err:
         raise exceptions.TcpException('Error connecting to "%s": %s' %
                                       (self.address[0], err))
     self.connection = connection
     self.source_address = connection.getsockname()
     self.ip_address = connection.getpeername()
     self._makefile()
     return ConnectionCloser(self)
Ejemplo n.º 3
0
    def create_connection(self, timeout=None):
        # Based on the official socket.create_connection implementation of Python 3.6.
        # https://github.com/python/cpython/blob/3cc5817cfaf5663645f4ee447eaed603d2ad290a/Lib/socket.py

        err = None
        idle_timeout = self.connection_idle_seconds
        if idle_timeout != -1:
            timeout = idle_timeout
        for res in socket.getaddrinfo(self.address[0], self.address[1], 0,
                                      socket.SOCK_STREAM):
            af, socktype, proto, canonname, sa = res
            sock = None
            try:
                sock = self.makesocket(af, socktype, proto)
                if timeout:
                    sock.settimeout(timeout)
                if self.source_address:
                    sock.bind(self.source_address)
                if self.spoof_source_address:
                    try:
                        if not sock.getsockopt(socket.SOL_IP,
                                               socket.IP_TRANSPARENT):
                            sock.setsockopt(
                                socket.SOL_IP, socket.IP_TRANSPARENT, 1
                            )  # pragma: windows no cover  pragma: osx no cover
                    except Exception as e:
                        # socket.IP_TRANSPARENT might not be available on every OS and Python version
                        if sock is not None:
                            sock.close()
                        raise exceptions.TcpException(
                            "Failed to spoof the source address: " + str(e))
                sock.connect(sa)
                return sock

            except socket.error as _:
                err = _
                self.ip_address = sa
                if sock is not None:
                    sock.close()

        if err is not None:
            raise err
        else:
            raise socket.error(
                "getaddrinfo returns an empty list")  # pragma: no cover
Ejemplo n.º 4
0
 def connect(self, flow=None):
     try:
         if self.channel is not None and flow is not None:
             self.channel.ask("tcp_resolving_server_address_started", flow)
         connection = self.create_connection()
         if self.dns_resolving_delay_ms > 0:
             time.sleep(self.dns_resolving_delay_ms / 1000)
     except (socket.error, IOError) as err:
         raise exceptions.TcpException('Error connecting to "%s": %s' %
                                       (self.address[0], err)) from err
     finally:
         if self.channel is not None and flow is not None:
             self.channel.ask("tcp_resolving_server_address_finished", flow)
     self.connection = connection
     self.source_address = connection.getsockname()
     self.ip_address = connection.getpeername()
     self._makefile()
     return ConnectionCloser(self)
Ejemplo n.º 5
0
    def create_connection(self, timeout=None):
        # Based on the official socket.create_connection implementation of Python 3.6.
        # https://github.com/python/cpython/blob/3cc5817cfaf5663645f4ee447eaed603d2ad290a/Lib/socket.py

        err = None
        for res in socket.getaddrinfo(self.address[0], self.address[1], 0, socket.SOCK_STREAM):
            af, socktype, proto, canonname, sa = res

            host = sa[0]
            if not ip_address(host).is_global:
                raise exceptions.NonGlobalAddressException("The address %s is not a global address" % host)

            try:
                sock = self.makesocket(af, socktype, proto)
                if timeout:
                    sock.settimeout(timeout)
                if self.source_address:
                    sock.bind(self.source_address)
                if self.spoof_source_address:
                    try:
                        if not sock.getsockopt(socket.SOL_IP, socket.IP_TRANSPARENT):
                            sock.setsockopt(socket.SOL_IP, socket.IP_TRANSPARENT, 1)
                    except Exception as e:
                        # socket.IP_TRANSPARENT might not be available on every OS and Python version
                        raise exceptions.TcpException(
                            "Failed to spoof the source address: " + e.strerror
                        )
                sock.connect(sa)
                return sock

            except socket.error as _:
                err = _
                if sock is not None:
                    sock.close()

        if err is not None:
            raise err
        else:
            raise socket.error("getaddrinfo returns an empty list")
Ejemplo n.º 6
0
    def peek(self, length):
        """
        Tries to peek into the underlying file object.

        Returns:
            Up to the next N bytes if peeking is successful.

        Raises:
            exceptions.TcpException if there was an error with the socket
            TlsException if there was an error with pyOpenSSL.
            NotImplementedError if the underlying file object is not a [pyOpenSSL] socket
        """
        if isinstance(self.o, socket_fileobject):
            try:
                return self.o._sock.recv(length, socket.MSG_PEEK)
            except socket.error as e:
                raise exceptions.TcpException(repr(e))
        elif isinstance(self.o, SSL.Connection):
            try:
                return self.o.recv(length, socket.MSG_PEEK)
            except SSL.Error as e:
                raise exceptions.TlsException(str(e))
        else:
            raise NotImplementedError("Can only peek into (pyOpenSSL) sockets")