def handle(self, connection_id, message_content):
        # check to see if there is a public key
        public_key = self._network.connection_id_to_public_key(connection_id)

        if public_key is None:
            LOGGER.debug(
                "No public key found, %s is not permitted. "
                "Close connection.", connection_id)
            violation = AuthorizationViolation(
                violation=RoleType.Value("NETWORK"))
            self._gossip.unregister_peer(connection_id)
            return HandlerResult(
                HandlerStatus.RETURN_AND_CLOSE,
                message_out=violation,
                message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        # check public key against network/default role
        permitted = self._permission_verifier.check_network_role(public_key)

        if not permitted:
            LOGGER.debug("Public key not permitted, %s is not permitted",
                         connection_id)
            self._gossip.unregister_peer(connection_id)
            violation = AuthorizationViolation(
                violation=RoleType.Value("NETWORK"))
            return HandlerResult(
                HandlerStatus.RETURN_AND_CLOSE,
                message_out=violation,
                message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        # if allowed pass message
        return HandlerResult(HandlerStatus.PASS)
示例#2
0
    def handle(self, connection_id, message_content):
        """
        If the connection wants to take on a role that requires a challenge to
        be signed, it will request the challenge by sending an
        AuthorizationChallengeRequest to the validator it wishes to connect to.
        The validator will send back a random payload that must be signed.
        If the connection has not sent a ConnectionRequest or the connection
        has already recieved an AuthorizationChallengeResponse, an
        AuthorizationViolation will be returned and the connection will be
        closed.
        """
        if self._network.get_connection_status(connection_id) != \
                ConnectionStatus.CONNECTION_REQUEST:
            LOGGER.debug(
                "Connection's previous message was not a"
                " ConnectionRequest, Remove connection to %s", connection_id)
            violation = AuthorizationViolation(
                violation=RoleType.Value("NETWORK"))
            return HandlerResult(
                HandlerStatus.RETURN_AND_CLOSE,
                message_out=violation,
                message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        random_payload = os.urandom(PAYLOAD_LENGTH)
        self._challenge_payload_cache[connection_id] = random_payload
        auth_challenge_response = AuthorizationChallengeResponse(
            payload=random_payload)

        self._network.update_connection_status(
            connection_id, ConnectionStatus.AUTH_CHALLENGE_REQUEST)

        return HandlerResult(HandlerStatus.RETURN,
                             message_out=auth_challenge_response,
                             message_type=validator_pb2.Message.
                             AUTHORIZATION_CHALLENGE_RESPONSE)
    def handle(self, connection_id, message_content):
        message = GossipMessage()
        message.ParseFromString(message_content)
        if message.content_type == "BLOCK":
            public_key = \
                self._network.connection_id_to_public_key(connection_id)
            block = Block()
            block.ParseFromString(message.content)
            header = BlockHeader()
            header.ParseFromString(block.header)
            if header.signer_public_key == public_key:
                permitted = \
                    self._permission_verifier.check_network_consensus_role(
                        public_key)
                if not permitted:
                    LOGGER.debug(
                        "Public key is not permitted to publish block, "
                        "remove connection: %s", connection_id)
                    self._gossip.unregister_peer(connection_id)
                    violation = AuthorizationViolation(
                        violation=RoleType.Value("NETWORK"))
                    return HandlerResult(HandlerStatus.RETURN_AND_CLOSE,
                                         message_out=violation,
                                         message_type=validator_pb2.Message.
                                         AUTHORIZATION_VIOLATION)

        # if allowed pass message
        return HandlerResult(HandlerStatus.PASS)
示例#4
0
 def _network_violation_result():
     violation = AuthorizationViolation(
         violation=RoleType.Value("NETWORK"))
     return HandlerResult(
         HandlerStatus.RETURN_AND_CLOSE,
         message_out=violation,
         message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)
示例#5
0
    def handle(self, connection_id, message_content):

        request = PingRequest()
        request.ParseFromString(message_content)

        ack = PingResponse()
        if self._network.get_connection_status(connection_id) == \
                ConnectionStatus.CONNECTED:

            if connection_id in self._last_message:
                del self._last_message[connection_id]

            return HandlerResult(
                HandlerStatus.RETURN,
                message_out=ack,
                message_type=validator_pb2.Message.PING_RESPONSE)

        if connection_id in self._last_message:
            ping_frequency = time.time() - self._last_message[connection_id]

            if ping_frequency < self._allowed_frequency:
                LOGGER.warning("Too many Pings (%s) in %s seconds before "
                               "authorization is complete: %s",
                               ping_frequency,
                               self._allowed_frequency,
                               connection_id)
                violation = AuthorizationViolation(
                    violation=RoleType.Value("NETWORK"))

                return HandlerResult(
                    HandlerStatus.RETURN_AND_CLOSE,
                    message_out=violation,
                    message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        self._last_message[connection_id] = time.time()

        return HandlerResult(
            HandlerStatus.RETURN,
            message_out=ack,
            message_type=validator_pb2.Message.PING_RESPONSE)
示例#6
0
    def handle(self, connection_id, message_content):

        request = PingRequest()
        request.ParseFromString(message_content)
        #LOGGER.debug("PingHandler PingRequest %s(%s)",connection_id[:8],self._network.connection_id_to_endpoint(connection_id))
        ack = PingResponse()
        if self._network.get_connection_status(
                connection_id) == ConnectionStatus.CONNECTED:

            if connection_id in self._last_message:
                del self._last_message[connection_id]
            """
            Here we can ask SYNC with this peer -in case we have no sync yet
            """
            #LOGGER.debug("PingRequest from CONNECTED %s(%s)",connection_id[:8],self._network.connection_id_to_endpoint(connection_id))
            return HandlerResult(
                HandlerStatus.RETURN,
                message_out=ack,
                message_type=validator_pb2.Message.PING_RESPONSE)

        if connection_id in self._last_message:
            if time.time(
            ) - self._last_message[connection_id] < self._allowed_frequency:
                LOGGER.debug(
                    "Too many Pings in %s seconds before authorization is complete: %s",
                    self._allowed_frequency, connection_id)
                violation = AuthorizationViolation(
                    violation=RoleType.Value("NETWORK"))

                return HandlerResult(
                    HandlerStatus.RETURN_AND_CLOSE,
                    message_out=violation,
                    message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        self._last_message[connection_id] = time.time()

        return HandlerResult(HandlerStatus.RETURN,
                             message_out=ack,
                             message_type=validator_pb2.Message.PING_RESPONSE)
示例#7
0
    def handle(self, connection_id, message_content):

        request = PingRequest()
        request.ParseFromString(message_content)

        ack = NetworkAcknowledgement()
        ack.status = ack.OK
        if self._network.get_connection_status(connection_id) == \
                ConnectionStatus.CONNECTED:

            if connection_id in self._last_message:
                del self._last_message[connection_id]

            return HandlerResult(
                HandlerStatus.RETURN,
                message_out=ack,
                message_type=validator_pb2.Message.NETWORK_ACK)

        if connection_id in self._last_message:
            if time.time() - self._last_message[connection_id] < \
                    self._allowed_frequency:
                LOGGER.debug(
                    "Too many Pings in %s seconds before"
                    "authorization is complete: %s", self._allowed_frequency,
                    connection_id)
                violation = AuthorizationViolation(
                    violation=RoleType.Value("NETWORK"))

                return HandlerResult(
                    HandlerStatus.RETURN_AND_CLOSE,
                    message_out=violation,
                    message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        self._last_message[connection_id] = time.time()

        return HandlerResult(HandlerStatus.RETURN,
                             message_out=ack,
                             message_type=validator_pb2.Message.NETWORK_ACK)
示例#8
0
    def handle(self, connection_id, message_content):
        """
        The simplest authorization type will be Trust. If Trust authorization
        is enabled, the validator will trust the connection and approve any
        roles requested that are available on that endpoint. If the requester
        wishes to gain access to every role it has permission to access, it can
        request access to the role ALL, and the validator will respond with all
        available roles. If the permission verifier deems the connection to not
        have access to a role, the connection has not sent a ConnectionRequest
        or a the connection has already recieved a AuthorizationTrustResponse,
        an AuthorizatinViolation will be returned and the connection will be
        closed.
        """
        if self._network.get_connection_status(connection_id) != \
                ConnectionStatus.CONNECTION_REQUEST:
            LOGGER.debug(
                "Connection's previous message was not a"
                " ConnectionRequest, Remove connection to %s", connection_id)
            violation = AuthorizationViolation(
                violation=RoleType.Value("NETWORK"))
            return HandlerResult(
                HandlerStatus.RETURN_AND_CLOSE,
                message_out=violation,
                message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        request = AuthorizationTrustRequest()
        request.ParseFromString(message_content)

        # Check that the connection's public key is allowed by the network role
        roles = self._network.roles
        for role in request.roles:
            if role == RoleType.Value("NETWORK") or role == \
                    RoleType.Value("ALL"):
                permitted = False
                if "network" in roles:
                    permitted = self._permission_verifier.check_network_role(
                        request.public_key)
                if not permitted:
                    violation = AuthorizationViolation(
                        violation=RoleType.Value("NETWORK"))
                    return HandlerResult(HandlerStatus.RETURN_AND_CLOSE,
                                         message_out=violation,
                                         message_type=validator_pb2.Message.
                                         AUTHORIZATION_VIOLATION)

        self._network.update_connection_public_key(connection_id,
                                                   request.public_key)

        if RoleType.Value("NETWORK") in request.roles:
            # Need to send ConnectionRequest to authorize ourself with the
            # connection if they initialized the connection
            try:
                is_outbound_connection = self._network.is_outbound_connection(
                    connection_id)
            except KeyError:
                # Connection has gone away, drop message
                return HandlerResult(HandlerStatus.DROP)

            if not is_outbound_connection:
                self._network.send_connect_request(connection_id)
            else:
                # If this is an outbound connection, authorization is complete
                # for both connections and peering can begin.
                self._gossip.connect_success(connection_id)

        auth_trust_response = AuthorizationTrustResponse(
            roles=[RoleType.Value("NETWORK")])

        LOGGER.debug("Connection: %s is approved", connection_id)

        self._network.update_connection_status(connection_id,
                                               ConnectionStatus.CONNECTED)

        return HandlerResult(
            HandlerStatus.RETURN,
            message_out=auth_trust_response,
            message_type=validator_pb2.Message.AUTHORIZATION_TRUST_RESPONSE)
示例#9
0
    def handle(self, connection_id, message_content):
        """
        When the validator receives an AuthorizationChallengeSubmit message, it
        will verify the public key against the signature. If the public key is
        verified, the requested roles will be checked against the stored roles
        to see if the public key is included in the policy. If the node’s
        response is accepted, the node’s public key will be stored and the
        requester may start sending messages for the approved roles.

        If the requester wanted a role that is either not available on the
        endpoint, the requester does not have access to one of the roles
        requested, or the previous message was not an
        AuthorizationChallengeRequest, the challenge will be rejected and the
        connection will be closed.
        """
        if self._network.get_connection_status(connection_id) != \
                ConnectionStatus.AUTH_CHALLENGE_REQUEST:
            LOGGER.debug(
                "Connection's previous message was not a"
                " AuthorizationChallengeRequest, Remove connection to"
                "%s", connection_id)
            violation = AuthorizationViolation(
                violation=RoleType.Value("NETWORK"))
            return HandlerResult(
                HandlerStatus.RETURN_AND_CLOSE,
                message_out=violation,
                message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        auth_challenge_submit = AuthorizationChallengeSubmit()
        auth_challenge_submit.ParseFromString(message_content)

        if not signing.verify(auth_challenge_submit.payload,
                              auth_challenge_submit.signature,
                              auth_challenge_submit.public_key):
            LOGGER.warning(
                "Signature was not able to be verifed. Remove "
                "connection to %s", connection_id)
            violation = AuthorizationViolation(
                violation=RoleType.Value("NETWORK"))
            return HandlerResult(
                HandlerStatus.RETURN_AND_CLOSE,
                message_out=violation,
                message_type=validator_pb2.Message.AUTHORIZATION_VIOLATION)

        roles = self._network.roles
        for role in auth_challenge_submit.roles:
            if role == RoleType.Value("NETWORK") or role == \
                    RoleType.Value("ALL"):
                permitted = False
                if "network" in roles:
                    permitted = self._permission_verifier.check_network_role(
                        auth_challenge_submit.public_key)
                if not permitted:
                    violation = AuthorizationViolation(
                        violation=RoleType.Value("NETWORK"))
                    return HandlerResult(HandlerStatus.RETURN_AND_CLOSE,
                                         message_out=violation,
                                         message_type=validator_pb2.Message.
                                         AUTHORIZATION_VIOLATION)
        self._network.update_connection_public_key(
            connection_id, auth_challenge_submit.public_key)

        if RoleType.Value("NETWORK") in auth_challenge_submit.roles:
            # Need to send ConnectionRequest to authorize ourself with the
            # connection if they initialized the connection
            try:
                is_outbound_connection = self._network.is_outbound_connection(
                    connection_id)
            except KeyError:
                # Connection has gone away, drop message
                return HandlerResult(HandlerStatus.DROP)

            if not is_outbound_connection:
                self._network.send_connect_request(connection_id)
            else:
                # If this is an outbound connection, authorization is complete
                # for both connections and peering/topology build out can
                # begin.
                self._gossip.connect_success(connection_id)

        auth_challenge_result = AuthorizationChallengeResult(
            roles=[RoleType.Value("NETWORK")])

        LOGGER.debug("Connection: %s is approved", connection_id)
        self._network.update_connection_status(connection_id,
                                               ConnectionStatus.CONNECTED)
        return HandlerResult(
            HandlerStatus.RETURN,
            message_out=auth_challenge_result,
            message_type=validator_pb2.Message.AUTHORIZATION_CHALLENGE_RESULT)