コード例 #1
0
def send_to_concent(msg: message.base.Message, signing_key: bytes,
                    concent_variant: dict) -> typing.Optional[bytes]:
    """Sends a message to the concent server

    :return: Raw reply message, None or exception
    :rtype: Bytes|None
    """

    logger.debug('send_to_concent(): Updating timestamp msg %r', msg)
    # Delayed messages are prepared before they're needed
    # and only sent to Concent if they're not cancelled
    # before. This can cause a situation where previously
    # prepared message will be too old to send when enqueued.
    # Also messages with no delay could have stayed in queue
    # long enough to eat significant amount of Message Transport Time
    # SEE: golem_messages.constants
    header = msg_datastructures.MessageHeader(
        msg.header.type_,
        # Using this tricky approach instead of time.time()
        # because of AppVeyor issues.
        calendar.timegm(time.gmtime()),
        msg.header.encrypted,
    )
    msg.header = header

    logger.debug('send_to_concent(): Encrypting msg %r', msg)
    # if signature already exists, it must be set to None explicitly
    if msg.sig is not None:
        msg.sig = None
    data = golem_messages.dump(msg, signing_key, concent_variant['pubkey'])
    logger.debug('send_to_concent(): data: %r', data)
    concent_post_url = urljoin(concent_variant['url'], '/api/v1/send/')
    headers = {
        'Content-Type': 'application/octet-stream',
        'X-Golem-Messages': golem_messages.__version__,
    }
    try:
        logger.debug(
            'send_to_concent(): POST %r hdr: %r',
            concent_post_url,
            headers,
        )
        response = requests.post(
            concent_post_url,
            data=data,
            headers=headers,
            **ssl_kwargs(concent_variant),
        )
    except requests.exceptions.RequestException as e:
        logger.warning('Concent RequestException %r', e)
        response = e.response

    verify_response(response)
    return response.content or None
コード例 #2
0
def is_golem_message_signed_with_key(
    public_key: bytes,
    golem_message: message.base.Message,
) -> bool:
    """
    Validates if given Golem message is signed with given public key.

    :param golem_message: Instance of golem_messages.base.Message object.
    :param public_key: Client public key in bytes.
    :return: True if given Golem message is signed with given public key, otherwise False.
    """
    assert isinstance(golem_message, message.base.Message)

    validate_bytes_public_key(public_key, 'public_key')

    try:
        is_valid = golem_message.verify_signature(public_key)
    except MessageError as exception:
        is_valid = False
        log_error_message(
            logger,
            f'There was an exception when validating if golem_message {golem_message.__class__.__name__} is signed '
            f'with public key {public_key}, exception: {exception}.'
        )

    return is_valid
コード例 #3
0
ファイル: validation.py プロジェクト: etsangsplk/concent
def validate_golem_message_signed_with_key(
    golem_message: message.base.Message,
    public_key: bytes,
):
    assert isinstance(golem_message, message.base.Message)

    validate_bytes_public_key(public_key, 'public_key')

    try:
        golem_message.verify_signature(public_key)
    except MessageError as exception:
        error_message = join_messages(
            'There was an exception when validating if golem_message {} is signed with public key {}.'
            .format(
                golem_message.TYPE,
                public_key,
            ), str(exception))
        raise Http400(
            error_message,
            error_code=ErrorCode.MESSAGE_SIGNATURE_WRONG,
        )
コード例 #4
0
def get_validated_client_public_key_from_client_message(golem_message: message.base.Message):
    if isinstance(golem_message, message.concents.ForcePayment):
        if (
            isinstance(golem_message.subtask_results_accepted_list, list) and
            len(golem_message.subtask_results_accepted_list) > 0
        ):
            task_to_compute = golem_message.subtask_results_accepted_list[0].task_to_compute
        else:
            raise ConcentValidationError(
                "subtask_results_accepted_list must be a list type and contains at least one message",
                error_code=ErrorCode.MESSAGE_VALUE_WRONG_LENGTH,
            )

    elif isinstance(golem_message, message.tasks.TaskMessage):
        if not golem_message.is_valid():
            raise GolemMessageValidationError(
                "Golem message invalid",
                error_code=ErrorCode.MESSAGE_INVALID
            )
        task_to_compute = golem_message.task_to_compute
    else:
        raise ConcentValidationError(
            "Unknown message type",
            error_code=ErrorCode.MESSAGE_UNKNOWN,
        )

    if task_to_compute is not None:
        if isinstance(golem_message, (
            message.ForceReportComputedTask,
            message.concents.ForceSubtaskResults,
            message.concents.ForcePayment,
            message.concents.SubtaskResultsVerify,
        )):
            client_public_key = task_to_compute.provider_public_key
            validate_hex_public_key(client_public_key, 'provider_public_key')
        elif isinstance(golem_message, (
            message.AckReportComputedTask,
            message.RejectReportComputedTask,
            message.concents.ForceGetTaskResult,
            message.concents.ForceSubtaskResultsResponse,
        )):
            client_public_key = task_to_compute.requestor_public_key
            validate_hex_public_key(client_public_key, 'requestor_public_key')
        else:
            raise ConcentValidationError(
                "Unknown message type",
                error_code=ErrorCode.MESSAGE_UNKNOWN,
            )

        return hex_to_bytes_convert(client_public_key)

    return None