Beispiel #1
0
    def deserialize_header(cls, data):
        """ Deserialize message's header

        :param data: bytes
        :return: datastructures.MessageHeader
        """
        try:
            header = datastructures.MessageHeader(
                *struct.unpack(cls.HDR_FORMAT, data), )
        except (struct.error, TypeError) as e:
            raise exceptions.HeaderError() from e

        logger.debug("deserialize_header(): %r", header)
        if not settings.MIN_TIMESTAMP < header.timestamp < \
                settings.MAX_TIMESTAMP:
            raise exceptions.HeaderError(
                "Invalid timestamp {got}. Should be between {min_} and {max_}".
                format(
                    got=header.timestamp,
                    min_=settings.MIN_TIMESTAMP,
                    max_=settings.MAX_TIMESTAMP,
                ))

        from golem_messages.message import registered_message_types

        if header.type_ not in registered_message_types:
            raise exceptions.HeaderError(
                "Unknown message type {got}".format(got=header.type_), )
        return header
Beispiel #2
0
def override_timestamp(msg: 'Message', timestamp: int) -> None:
    new_hdr = datastructures.MessageHeader(
        msg.TYPE,
        timestamp,
        msg.encrypted,
    )
    msg.header = new_hdr
Beispiel #3
0
 def test_inequal_header_type(self):
     msg1 = message.RandVal(rand_val=1)
     msg2 = clone_message(msg1)
     msg2.header = datastructures.MessageHeader(
         msg1.header.type_ + 1,
         msg1.header.timestamp,
         msg1.header.encrypted,
     )
     self.assertNotEqual(msg1, msg2)
Beispiel #4
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
Beispiel #5
0
    def test_verify_updated_header(self):
        msg = message.Hello()
        self.add_sig(msg)

        msg2 = factories.helpers.clone_message(
            msg,
            override_header=datastructures.MessageHeader(
                msg.TYPE,
                msg.timestamp + 667,
                msg.encrypted,
            ))

        with self.assertRaises(exceptions.InvalidSignature):
            msg2.verify_signature(self.keys.raw_pubkey)
Beispiel #6
0
    def __init__(self,
                 header: datastructures.MessageHeader = None,
                 sig=None,
                 slots=None,
                 deserialized=False,
                 **kwargs):
        """Create a new message
        :param deserialized: was message created by .deserialize()?
        """

        # Child message slots
        try:
            self.load_slots(slots)
        except exceptions.FieldError:
            raise
        except Exception as e:
            raise exceptions.MessageError('Load slots failed') from e

        # Set attributes
        for key in kwargs:
            if getattr(self, key, None) is None:
                try:
                    setattr(self, key, kwargs[key])
                except AttributeError:
                    raise AttributeError("Can't set attribute `%s` on `%s`" %
                                         (key, self.__class__.__name__))

        if deserialized and not (header and header.timestamp):
            warnings.warn('Message without header {}'.format(self),
                          RuntimeWarning)

        # Header
        if header is None:
            header = datastructures.MessageHeader(
                self.TYPE,
                # Since epoch differs between OS, we use calendar.timegm()
                # instead of time.time() to unify it.
                calendar.timegm(time.gmtime()),
                False,
            )
        self.header = header
        self.sig = sig
    def test_timestamp_and_timezones(self, *_):
        epoch_t = 1475238345

        def set_tz(tz):
            os.environ['TZ'] = tz
            try:
                time.tzset()
            except AttributeError:
                raise unittest.SkipTest("tzset required")

        set_tz('Europe/Warsaw')
        warsaw_time = time.localtime(epoch_t)
        msg_pre = message.Hello(header=datastructures.MessageHeader(
            message.Hello.TYPE,
            epoch_t,
            False,
        ))
        data = shortcuts.dump(msg_pre, None, None)
        set_tz('US/Eastern')
        msg_post = shortcuts.load(data, None, None)
        newyork_time = time.localtime(msg_post.timestamp)
        self.assertNotEqual(warsaw_time, newyork_time)
        self.assertEqual(time.gmtime(epoch_t), time.gmtime(msg_post.timestamp))
Beispiel #8
0
 def encrypted(self, value):
     self.header = datastructures.MessageHeader(
         self.header.type_,
         self.header.timestamp,
         value,
     )