示例#1
0
    def _client_handshake(self, client_tx, client_rx):
        """
        Perform handshake/authentication with a connecting client

        Outline:
        1. Client connects
        2. We fake RFB 3.8 protocol and require VNC authentication
           [processing also supports RFB 3.3]
        3. Client accepts authentication method
        4. We send an authentication challenge
        5. Client sends the authentication response
        6. We check the authentication

        Upon return, self.client socket is connected to the client.

        """
        client_tx.send(rfb.RFB_VERSION_3_8 + "\n")
        client_version_str = client_rx.recv(1024)
        client_version = rfb.check_version(client_version_str)
        if not client_version:
            self.error("Invalid version: %s", client_version_str)
            raise gevent.GreenletExit

        # Both for RFB 3.3 and 3.8
        self.debug("Requesting authentication")
        auth_request = rfb.make_auth_request(rfb.RFB_AUTHTYPE_VNC,
                                             version=client_version)
        client_tx.send(auth_request)

        # The client gets to propose an authtype only for RFB 3.8
        if client_version == rfb.RFB_VERSION_3_8:
            res = client_rx.recv(1024)
            type = rfb.parse_client_authtype(res)
            if type == rfb.RFB_AUTHTYPE_ERROR:
                self.warn("Client refused authentication: %s", res[1:])
            else:
                self.debug("Client requested authtype %x", type)

            if type != rfb.RFB_AUTHTYPE_VNC:
                self.error("Wrong auth type: %d", type)
                client_tx.send(rfb.to_u32(rfb.RFB_AUTH_ERROR))
                raise gevent.GreenletExit

        # Generate the challenge
        challenge = os.urandom(16)
        client_tx.send(challenge)
        response = client_rx.recv(1024)
        if len(response) != 16:
            self.error("Wrong response length %d, should be 16", len(response))
            raise gevent.GreenletExit

        if rfb.check_password(challenge, response, self.password):
            self.debug("Authentication successful")
        else:
            self.warn("Authentication failed")
            client_tx.send(rfb.to_u32(rfb.RFB_AUTH_ERROR))
            raise gevent.GreenletExit

        # Accept the authentication
        client_tx.send(rfb.to_u32(rfb.RFB_AUTH_SUCCESS))
示例#2
0
    def _client_handshake(self, client_tx, client_rx):
        """
        Perform handshake/authentication with a connecting client

        Outline:
        1. Client connects
        2. We fake RFB 3.8 protocol and require VNC authentication
           [processing also supports RFB 3.3]
        3. Client accepts authentication method
        4. We send an authentication challenge
        5. Client sends the authentication response
        6. We check the authentication

        Upon return, self.client socket is connected to the client.

        """
        client_tx.send(rfb.RFB_VERSION_3_8 + "\n")
        client_version_str = client_rx.recv(1024)
        client_version = rfb.check_version(client_version_str)
        if not client_version:
            self.error("Invalid version: %s", client_version_str)
            raise gevent.GreenletExit

        # Both for RFB 3.3 and 3.8
        self.debug("Requesting authentication")
        auth_request = rfb.make_auth_request(rfb.RFB_AUTHTYPE_VNC,
                                             version=client_version)
        client_tx.send(auth_request)

        # The client gets to propose an authtype only for RFB 3.8
        if client_version == rfb.RFB_VERSION_3_8:
            res = client_rx.recv(1024)
            type = rfb.parse_client_authtype(res)
            if type == rfb.RFB_AUTHTYPE_ERROR:
                self.warn("Client refused authentication: %s", res[1:])
            else:
                self.debug("Client requested authtype %x", type)

            if type != rfb.RFB_AUTHTYPE_VNC:
                self.error("Wrong auth type: %d", type)
                client_tx.send(rfb.to_u32(rfb.RFB_AUTH_ERROR))
                raise gevent.GreenletExit

        # Generate the challenge
        challenge = os.urandom(16)
        client_tx.send(challenge)
        response = client_rx.recv(1024)
        if len(response) != 16:
            self.error("Wrong response length %d, should be 16", len(response))
            raise gevent.GreenletExit

        if rfb.check_password(challenge, response, self.password):
            self.debug("Authentication successful")
        else:
            self.warn("Authentication failed")
            client_tx.send(rfb.to_u32(rfb.RFB_AUTH_ERROR))
            raise gevent.GreenletExit

        # Accept the authentication
        client_tx.send(rfb.to_u32(rfb.RFB_AUTH_SUCCESS))
示例#3
0
    def _perform_server_handshake(self):
        """
        Initiate a connection with the backend server and perform basic
        RFB 3.8 handshake with it.

        Return a socket connected to the backend server.

        """
        server = None

        tries = VncAuthProxy.connect_retries
        while tries:
            tries -= 1

            # Initiate server connection
            for res in socket.getaddrinfo(self.daddr, self.dport,
                                          socket.AF_UNSPEC, socket.SOCK_STREAM,
                                          0, socket.AI_PASSIVE):
                af, socktype, proto, canonname, sa = res
                try:
                    server = socket.socket(af, socktype, proto)
                except socket.error:
                    server = None
                    continue

                # Set socket timeout for the initial handshake
                server.settimeout(VncAuthProxy.server_timeout)

                try:
                    self.debug("Connecting to %s:%s", *sa[:2])
                    server.connect(sa)
                    self.debug("Connection to %s:%s successful", *sa[:2])
                except socket.error:
                    self.debug("Failed to perform sever hanshake, retrying...")
                    server.close()
                    server = None
                    continue

                # We succesfully connected to the server
                tries = 0
                break

            # Wait and retry
            gevent.sleep(VncAuthProxy.retry_wait)

        if server is None:
            raise InternalError("Failed to connect to server")

        version = server.recv(1024)
        if not rfb.check_version(version):
            raise InternalError("Unsupported RFB version: %s" %
                                version.strip())

        server.send(rfb.RFB_VERSION_3_8 + "\n")

        res = server.recv(1024)
        types = rfb.parse_auth_request(res)
        if not types:
            raise InternalError("Error handshaking with the server")

        else:
            self.debug("Supported authentication types: %s",
                       " ".join([str(x) for x in types]))

        if rfb.RFB_AUTHTYPE_NONE not in types:
            raise InternalError("Error, server demands authentication")

        server.send(rfb.to_u8(rfb.RFB_AUTHTYPE_NONE))

        # Check authentication response
        res = server.recv(4)
        res = rfb.from_u32(res)

        if res != 0:
            raise InternalError("Authentication error")

        # Reset the timeout for the rest of the session
        server.settimeout(None)

        self.server = server
示例#4
0
    def _perform_server_handshake(self):
        """
        Initiate a connection with the backend server and perform basic
        RFB 3.8 handshake with it.

        Return a socket connected to the backend server.

        """
        server = None

        tries = VncAuthProxy.connect_retries
        while tries:
            tries -= 1

            # Initiate server connection
            for res in socket.getaddrinfo(self.daddr, self.dport,
                                          socket.AF_UNSPEC,
                                          socket.SOCK_STREAM, 0,
                                          socket.AI_PASSIVE):
                af, socktype, proto, canonname, sa = res
                try:
                    server = socket.socket(af, socktype, proto)
                except socket.error:
                    server = None
                    continue

                # Set socket timeout for the initial handshake
                server.settimeout(VncAuthProxy.server_timeout)

                try:
                    self.debug("Connecting to %s:%s", *sa[:2])
                    server.connect(sa)
                    self.debug("Connection to %s:%s successful", *sa[:2])
                except socket.error:
                    self.debug("Failed to perform sever hanshake, retrying...")
                    server.close()
                    server = None
                    continue

                # We succesfully connected to the server
                tries = 0
                break

            # Wait and retry
            gevent.sleep(VncAuthProxy.retry_wait)

        if server is None:
            raise InternalError("Failed to connect to server")

        version = server.recv(1024)
        if not rfb.check_version(version):
            raise InternalError("Unsupported RFB version: %s"
                                % version.strip())

        server.send(rfb.RFB_VERSION_3_8 + "\n")

        res = server.recv(1024)
        types = rfb.parse_auth_request(res)
        if not types:
            raise InternalError("Error handshaking with the server")

        else:
            self.debug("Supported authentication types: %s",
                       " ".join([str(x) for x in types]))

        if rfb.RFB_AUTHTYPE_NONE not in types:
            raise InternalError("Error, server demands authentication")

        server.send(rfb.to_u8(rfb.RFB_AUTHTYPE_NONE))

        # Check authentication response
        res = server.recv(4)
        res = rfb.from_u32(res)

        if res != 0:
            raise InternalError("Authentication error")

        # Reset the timeout for the rest of the session
        server.settimeout(None)

        self.server = server