Beispiel #1
0
def get_message_from_urllib_addinfourl(http_response, in_response_to):
    """ This function should not be called by libtaxii users directly. """
    taxii_content_type = http_response.info().getheader('X-TAXII-Content-Type')
    response_message = http_response.read()

    if taxii_content_type is None:  # Treat it as a Failure Status Message, per the spec

        message = []
        header_dict = http_response.info().dict.iteritems()
        for k, v in header_dict:
            message.append(k + ': ' + v + '\r\n')
        message.append('\r\n')
        message.append(response_message)

        m = ''.join(message)

        return tm11.StatusMessage(message_id='0', in_response_to=in_response_to, status_type=ST_FAILURE, message=m)

    elif taxii_content_type == VID_TAXII_XML_10:  # It's a TAXII XML 1.0 message
        return tm10.get_message_from_xml(response_message)
    elif taxii_content_type == VID_TAXII_XML_11:  # It's a TAXII XML 1.1 message
        return tm11.get_message_from_xml(response_message)
    elif taxii_content_type == VID_CERT_EU_JSON_10:
        return tm10.get_message_from_json(response_message)
    else:
        raise ValueError('Unsupported X-TAXII-Content-Type: %s' % taxii_content_type)

    return None
Beispiel #2
0
def get_message_from_urllib2_httperror(http_response, in_response_to):
    """ This function should not be called by libtaxii users directly. """
    info = http_response.info()

    if hasattr(info, 'getheader'):
        taxii_content_type = info.getheader('X-TAXII-Content-Type')
        _, params = cgi.parse_header(info.getheader('Content-Type'))
    else:
        taxii_content_type = info.get('X-TAXII-Content-Type')
        _, params = cgi.parse_header(info.get('Content-Type'))

    encoding = params.get('charset', 'utf-8')
    response_message = http_response.read()

    if taxii_content_type is None:
        m = str(http_response) + '\r\n' + str(
            http_response.info()) + '\r\n' + response_message
        return tm11.StatusMessage(message_id='0',
                                  in_response_to=in_response_to,
                                  status_type=ST_FAILURE,
                                  message=m)
    elif taxii_content_type == VID_TAXII_XML_10:  # It's a TAXII XML 1.0 message
        return tm10.get_message_from_xml(response_message, encoding)
    elif taxii_content_type == VID_TAXII_XML_11:  # It's a TAXII XML 1.1 message
        return tm11.get_message_from_xml(response_message, encoding)
    elif taxii_content_type == VID_CERT_EU_JSON_10:
        return tm10.get_message_from_json(response_message, encoding)
    else:
        raise ValueError('Unsupported X-TAXII-Content-Type: %s' %
                         taxii_content_type)
Beispiel #3
0
def get_message_from_httplib_http_response(http_response, in_response_to):
    """ This function should not be called by libtaxii users directly. """
    if hasattr(http_response, 'getheader'):
        taxii_content_type = http_response.getheader('X-TAXII-Content-Type')
        _, params = cgi.parse_header(http_response.getheader('Content-Type'))
    else:
        taxii_content_type = http_response.get('X-TAXII-Content-Type')
        _, params = cgi.parse_header(http_response.get('Content-Type'))

    encoding = params.get('charset', 'utf-8')
    response_message = http_response.read()

    if taxii_content_type is None:  # Treat it as a Failure Status Message, per the spec

        message = []
        header_tuples = http_response.getheaders()
        for k, v in header_tuples:
            message.append(k + ': ' + v + '\r\n')
        message.append('\r\n')
        message.append(response_message)

        m = ''.join(message)

        return tm11.StatusMessage(message_id='0',
                                  in_response_to=in_response_to,
                                  status_type=ST_FAILURE,
                                  message=m)

    elif taxii_content_type == VID_TAXII_XML_10:  # It's a TAXII XML 1.0 message
        return tm10.get_message_from_xml(response_message, encoding)
    elif taxii_content_type == VID_TAXII_XML_11:  # It's a TAXII XML 1.1 message
        return tm11.get_message_from_xml(response_message, encoding)
    else:
        raise ValueError('Unsupported X-TAXII-Content-Type: %s' %
                         taxii_content_type)
    def handle_message(cls, inbox_service, inbox_message, django_request):
        """
        """

        collections = inbox_service.validate_destination_collection_names(
            None,  # Inbox 1.0 doesn't have a DCN
            inbox_message.message_id)

        # Store certain information about this Inbox Message in the database for bookkeeping
        inbox_message_db = models.InboxMessage.from_inbox_message_10(
            inbox_message, django_request, received_via=inbox_service)
        inbox_message_db.save()

        saved_blocks = 0
        for content_block in inbox_message.content_blocks:
            inbox_support_info = inbox_service.is_content_supported(
                content_block.content_binding)
            if inbox_support_info.is_supported is False:
                continue

            cls.save_content_block(content_block)
            saved_blocks += 1

        # Update the Inbox Message model with the number of ContentBlocks that were saved
        inbox_message_db.content_blocks_saved = saved_blocks
        inbox_message_db.save()

        # Create and return a Status Message indicating success
        status_message = tm11.StatusMessage(
            message_id=generate_message_id(),
            in_response_to=inbox_message.message_id,
            status_type=ST_SUCCESS)
        return status_message
Beispiel #5
0
 def to_status_message_11(self):
     """
     Creates a TAXII 1.1 Status Message based on the
     properties of this object
     """
     sm = tm11.StatusMessage(message_id=generate_message_id(),
                             in_response_to=self.in_response_to,
                             extended_headers=self.extended_headers,
                             status_type=self.status_type,
                             status_detail=self.status_detail,
                             message=self.message)
     return sm
    def handle_message(cls, service, request):

        collections = service.validate_destination_collection_names(
            request.destination_collection_names, request.message_id)

        inbox_message = service.server.persistence.create_inbox_message(
            inbox_message_to_inbox_message_entity(request,
                                                  service_id=service.id,
                                                  version=11))

        for content_block in request.content_blocks:

            is_supported = service.is_content_supported(
                content_block.content_binding, version=11)

            # FIXME: is it correct to skip unsupported content blocks?
            # 3.2 Inbox Exchange
            # version1.1/TAXII_Services_Specification.pdf
            if not is_supported:
                log.warning("Content binding is not supported: {}".format(
                    content_block.content_binding))
                continue

            supporting_collections = []
            for collection in collections:

                if collection.is_content_supported(
                        content_block.content_binding):

                    supporting_collections.append(collection)

            if len(supporting_collections) == 0 and not is_supported:
                # There's nothing to add this content block to
                log.warning(
                    "No collection that support binding {} were found".format(
                        content_block.content_binding))
                continue

            block = content_block_to_content_block_entity(content_block,
                                                          version=11)

            service.server.persistence.create_content(
                block,
                collections=supporting_collections,
                service_id=service.id,
                inbox_message_id=inbox_message.id)

        # Create and return a Status Message indicating success
        status_message = tm11.StatusMessage(message_id=cls.generate_id(),
                                            in_response_to=request.message_id,
                                            status_type=ST_SUCCESS)

        return status_message
Beispiel #7
0
def exception_to_status(exception, format_version):
    data = dict(message_id=generate_message_id(),
                in_response_to=exception.in_response_to,
                extended_headers=exception.extended_headers,
                status_type=exception.status_type,
                status_detail=exception.status_details,
                message=exception.message)
    if format_version == VID_TAXII_XML_11:
        sm = tm11.StatusMessage(**data)
    elif format_version == VID_TAXII_XML_10:
        sm = tm10.StatusMessage(**data)
    else:
        raise ValueError("Unknown version: %s" % format_version)
    return sm
Beispiel #8
0
    def create_pending_response(cls, poll_service, prp, content):
        """
        Arguments:
            poll_service (models.PollService) - The TAXII Poll Service being invoked
            prp (util.PollRequestProperties) - The Poll Request Properties of the Poll Request
            content - A list of content (nominally, models.ContentBlock objects).

        This method returns a StatusMessage with a Status Type
        of Pending OR raises a StatusMessageException
        based on the following table::

            asynch | Delivery_Params | can_push || Response Type
            ----------------------------------------------------
            True   | -               | -        || Pending - Asynch
            False  | Yes             | Yes      || Pending - Push
            False  | Yes             | No       || StatusMessageException
            False  | No              | -        || StatusMessageException
        """

        # Identify the Exception conditions first (e.g., rows #3 and #4)
        if (prp.allow_asynch is False and
            (prp.delivery_parameters is None or prp.can_push is False)):

            raise StatusMessageException(
                prp.message_id, ST_FAILURE,
                "The content was not available now and \
                                         the request had allow_asynch=False and no \
                                         Delivery Parameters were specified.")

        # Rows #1 and #2 are both Status Messages with a type of Pending
        result_set = cls.create_result_set(content, prp, poll_service)
        sm = tm11.StatusMessage(message_id=generate_message_id(),
                                in_response_to=prp.message_id,
                                status_type=ST_PENDING)
        if prp.allow_asynch:
            sm.status_details = {
                SD_ESTIMATED_WAIT: 300,
                SD_RESULT_ID: result_set.pk,
                SD_WILL_PUSH: False
            }
        else:
            # TODO: Check and see if the requested delivery parameters are supported
            sm.status_details = {
                SD_ESTIMATED_WAIT: 300,
                SD_RESULT_ID: result_set.pk,
                SD_WILL_PUSH: True
            }
            # TODO: Need to try pushing or something.
        return sm
Beispiel #9
0
        def _wrapped_view(request, *args, **kwargs):

            if request.method != 'POST':
                raise StatusMessageException('0', ST_BAD_MESSAGE,
                                             'Request method was not POST!')

            # If requested, attempt to validate
            # TODO: Validation has changed!
            if do_validate:
                try:
                    validate(request)
                except Exception as e:
                    raise StatusMessageException('0', ST_BAD_MESSAGE,
                                                 e.message)

            # Attempt to deserialize
            try:
                message = deserialize(request)
            except Exception as e:
                raise StatusMessageException('0', ST_BAD_MESSAGE, e.message)

            try:
                if message_types is None:
                    pass  # No checking was requested
                elif isinstance(message_types, list):
                    if message.__class__ not in message_types:
                        raise ValueError(
                            'Message type not allowed. Must be one of: %s' %
                            message_types)
                elif isinstance(message_types, object):
                    if not isinstance(message, message_types):
                        raise ValueError(
                            'Message type not allowed. Must be: %s' %
                            message_types)
                elif message_types is not None:
                    raise ValueError(
                        'Something strange happened with message_types! Was not a list or object!'
                    )
            except ValueError as e:
                msg = tm11.StatusMessage(generate_message_id(),
                                         message.message_id,
                                         status_type='FAILURE',
                                         message=e.message)
                return HttpResponseTaxii(msg.to_xml(), response_headers)

            kwargs['taxii_message'] = message
            return view_func(request, *args, **kwargs)
Beispiel #10
0
    def handle_inbox_message(s, msg):

        # Process each content block
        for cb in msg.content_blocks:

            content = cb.content

            for collection in msg.destination_collection_names:
                
                s.received(content, collection)

        resp = tm11.StatusMessage(message_id=tm11.generate_message_id(),
                                  in_response_to=msg.message_id,
                                  status_type=tm11.ST_SUCCESS)

        # Respond
        s.respond(resp.to_xml())
Beispiel #11
0
def get_message_from_urllib2_httperror(http_response, in_response_to):
    """ This function should not be called by libtaxii users directly. """
    taxii_content_type = http_response.info().getheader('X-TAXII-Content-Type')
    response_message = http_response.read()

    if taxii_content_type is None:
        m = str(http_response.info()) + '\r\n' + response_message
        return tm11.StatusMessage(message_id='0', in_response_to=in_response_to, status_type=ST_FAILURE, message=m)
    elif taxii_content_type == VID_TAXII_XML_10:  # It's a TAXII XML 1.0 message
        return tm10.get_message_from_xml(response_message)
    elif taxii_content_type == VID_TAXII_XML_11:  # It's a TAXII XML 1.1 message
        return tm11.get_message_from_xml(response_message)
    elif taxii_content_type == VID_CERT_EU_JSON_10:
        return tm10.get_message_from_json(response_message)
    else:
        raise ValueError('Unsupported X-TAXII-Content-Type: %s' % taxii_content_type)

    return None
def get_message_from_client_response(resp, in_response_to):
    """ helper func"""

    taxii_content_type = resp.get('X-TAXII-Content-Type', None)
    response_message = resp.content

    if taxii_content_type is None:
        m = str(resp) + '\r\n' + response_message
        return tm11.StatusMessage(message_id='0', in_response_to=in_response_to, status_type=ST_FAILURE, message=m)
    elif taxii_content_type == VID_TAXII_XML_10:  # It's a TAXII XML 1.0 message
        return tm10.get_message_from_xml(response_message)
    elif taxii_content_type == VID_TAXII_XML_11:  # It's a TAXII XML 1.1 message
        return tm11.get_message_from_xml(response_message)
    elif taxii_content_type == VID_CERT_EU_JSON_10:
        return tm10.get_message_from_json(response_message)
    else:
        raise ValueError('Unsupported X-TAXII-Content-Type: %s' % taxii_content_type)

    return None
Beispiel #13
0
def get_message_from_urllib_addinfourl(http_response, in_response_to):
    """ This function should not be called by libtaxii users directly. """
    info = http_response.info()

    if hasattr(info, 'getheader'):
        taxii_content_type = info.getheader('X-TAXII-Content-Type')
        _, params = cgi.parse_header(info.getheader('Content-Type'))
    else:
        taxii_content_type = info.get('X-TAXII-Content-Type')
        _, params = cgi.parse_header(info.get('Content-Type'))

    encoding = params.get('charset', 'utf-8')
    response_message = six.ensure_text(http_response.read(), errors='replace')

    if taxii_content_type is None:  # Treat it as a Failure Status Message, per the spec

        message = []
        header_dict = six.iteritems(http_response.info().dict)
        for k, v in header_dict:
            message.append(k + ': ' + v + '\r\n')
        message.append('\r\n')
        message.append(response_message)

        m = ''.join(message)

        return tm11.StatusMessage(message_id='0',
                                  in_response_to=in_response_to,
                                  status_type=ST_FAILURE,
                                  message=m)

    elif taxii_content_type == VID_TAXII_XML_10:  # It's a TAXII XML 1.0 message
        return tm10.get_message_from_xml(response_message, encoding)
    elif taxii_content_type == VID_TAXII_XML_11:  # It's a TAXII XML 1.1 message
        return tm11.get_message_from_xml(response_message, encoding)
    elif taxii_content_type == VID_CERT_EU_JSON_10:
        return tm10.get_message_from_json(response_message, encoding)
    else:
        raise ValueError('Unsupported X-TAXII-Content-Type: %s' %
                         taxii_content_type)
Beispiel #14
0
    def do_POST(s):

        # Get the HTTP bdoy
        varLen = int(s.headers['Content-Length'])
        data = s.rfile.read(varLen)

        # Parse body as TAXII message.
        msg = tm11.get_message_from_xml(data)

        # If it's a poll request, handle it.
        if type(msg) == tm11.PollRequest:
            s.handle_poll_request(msg)
            return

        if type(msg) == tm11.InboxMessage:
            s.handle_inbox_message(msg)
            return

        if type(msg) == tm11.DiscoveryRequest:
            s.handle_discovery_request(msg)
            return

        if type(msg) == tm11.CollectionInformationRequest:
            s.handle_collection_information_request(msg)
            return

        if type(msg) == tm11.ManageCollectionSubscriptionRequest:
            s.handle_manage_collection_subscription_request(msg)
            return

        # Sorry, I only handle inbox and poll requests.

        resp = tm11.StatusMessage(message_id=tm11.generate_message_id(),
                                  in_response_to=msg.message_id,
                                  status_type=tm11.ST_FAILURE,
                                  message="Your request type not supported.")
        s.respond(resp.to_xml())
Beispiel #15
0
    def prepare_poll_response(cls,
                              service,
                              collection,
                              in_response_to,
                              timeframe=None,
                              content_bindings=None,
                              result_part=1,
                              allow_async=False,
                              return_content=True,
                              result_id=None,
                              subscription_id=None):

        timeframe = timeframe or (None, None)

        if not any(timeframe) and not content_bindings:
            total_count = collection.volume
        else:
            try:
                total_count = service.get_content_blocks_count(
                    collection,
                    timeframe=timeframe,
                    content_bindings=content_bindings)
            except ResultsNotReady:
                if not allow_async:
                    message = ("The content is not available now and "
                               "the request has allow_asynch set to false")

                    raise_failure(message=message,
                                  in_response_to=in_response_to)

                result_set = service.create_result_set(
                    collection,
                    timeframe=timeframe,
                    content_bindings=content_bindings)

                return tm11.StatusMessage(message_id=generate_message_id(),
                                          in_response_to=in_response_to,
                                          status_type=ST_PENDING,
                                          status_details={
                                              SD_ESTIMATED_WAIT:
                                              service.wait_time,
                                              SD_RESULT_ID: result_set.id,
                                              SD_WILL_PUSH: service.can_push
                                          })

        # TODO: temporary fix, pending:
        # https://github.com/TAXIIProject/libtaxii/issues/191
        result_part = int(result_part)

        # dividing instead of multiplying to be safe from overflow
        has_more = (float(total_count) / service.max_result_size) > result_part

        capped_count = min(service.max_result_count, total_count)
        is_partial = (capped_count < total_count)

        if has_more and not result_id:
            result_set = service.create_result_set(
                collection,
                timeframe=timeframe,
                content_bindings=content_bindings)
            result_id = result_set.id

        response = tm11.PollResponse(
            message_id=generate_message_id(),
            in_response_to=in_response_to,
            collection_name=collection.name,
            more=has_more,
            result_id=result_id,
            result_part_number=result_part,
            exclusive_begin_timestamp_label=timeframe[0],
            inclusive_end_timestamp_label=timeframe[1],
            # TODO: Temporararily make capped_count an int, pending:
            # https://github.com/TAXIIProject/libtaxii/issues/191
            record_count=tm11.RecordCount(int(capped_count), is_partial),
            subscription_id=subscription_id)

        if return_content:

            content_blocks = service.get_content_blocks(
                collection,
                timeframe=timeframe,
                content_bindings=content_bindings,
                part_number=result_part)

            for block in content_blocks:
                response.content_blocks.append(
                    content_block_entity_to_content_block(block, version=11))

        return response
    def handle_message(cls, service, request):

        collections = service.validate_destination_collection_names(
            request.destination_collection_names, request.message_id)

        inbox_message = service.server.persistence.create_inbox_message(
            inbox_message_to_inbox_message_entity(
                request,
                service_id=service.id,
                version=11
            )
        )

        failure = False
        failure_message = ""

        for content_block in request.content_blocks:

            is_supported = service.is_content_supported(
                content_block.content_binding, version=11)

            # FIXME: is it correct to skip unsupported content blocks?
            # 3.2 Inbox Exchange
            # version1.1/TAXII_Services_Specification.pdf
            if not is_supported:
                failure = True
                failure_message = (
                   "Content binding is not supported by this"
                   " Inbox service: {}".format(content_block.content_binding)
                )
                log.warning(failure_message)
                continue

            supporting_collections = []
            for collection in collections:

                if collection.is_content_supported(
                        content_block.content_binding):

                    supporting_collections.append(collection)

            if len(supporting_collections) == 0 and not is_supported:
                # There's nothing to add this content block to
                failure = True
                failure_message = (
                    "No collection that supports binding"
                    " {} were found".format(content_block.content_binding)
                )
                log.warning(failure_message)
                continue

            # Validate that the STIX content is actually STIX content with
            # the STIX Validator
            results = service.verify_content_is_valid(
                content_block.content,
                content_block.content_binding,
                request.message_id
            )
            if results.is_valid:
                block = content_block_to_content_block_entity(
                    content_block,
                    version=11
                )

                service.server.persistence.create_content(
                    block,
                    collections=supporting_collections,
                    service_id=service.id,
                    inbox_message_id=inbox_message.id
                    if inbox_message else None
                )
            else:
                failure = True
                failure_message = results.message
                log.warning(failure_message)
                continue

        # If we had an error then indicate a failure
        if failure:
            status_message = tm11.StatusMessage(
                message=failure_message,
                message_id=cls.generate_id(),
                in_response_to=request.message_id,
                status_type=ST_FAILURE
            )
        else:
            # Create and return a Status Message indicating success
            status_message = tm11.StatusMessage(
                message_id=cls.generate_id(),
                in_response_to=request.message_id,
                status_type=ST_SUCCESS
            )

        return status_message
    def handle_message(cls, inbox_service, inbox_message, django_request):
        """
        Attempts to save all Content Blocks in the Inbox Message into the
        database.

        Workflow:
            #. Validate the request's Destination Collection Names against the InboxService model
            #. Create an InboxMessage model object for bookkeeping
            #. Iterate over each Content Block in the request:

             #. Identify which of the request's destination collections support the Content Block's Content Binding
             #. Call `save_content_block(tm11.ContentBlock, <list of Data Collections from 3a>)`

            #. Return Status Message with a Status Type of Success

        Raises:
            A StatusMessageException for errors
        """

        collections = inbox_service.validate_destination_collection_names(
            inbox_message.destination_collection_names,
            inbox_message.message_id)

        # Store certain information about this Inbox Message in the database for bookkeeping
        inbox_message_db = models.InboxMessage.from_inbox_message_11(
            inbox_message, django_request, received_via=inbox_service)
        inbox_message_db.save()

        # Iterate over the ContentBlocks in the InboxMessage and try to add
        # them to the database
        saved_blocks = 0
        for content_block in inbox_message.content_blocks:
            # 3a. Identify whether the InboxService supports the Content Block's Content Binding
            # TODO: Is this useful?
            inbox_support_info = inbox_service.is_content_supported(
                content_block.content_binding)

            supporting_collections = []
            for collection in collections:
                collection_support_info = collection.is_content_supported(
                    content_block.content_binding)
                if collection_support_info.is_supported:
                    supporting_collections.append(collection)

            if len(supporting_collections
                   ) == 0 and not inbox_support_info.is_supported:
                # There's nothing to add this content block to
                continue

            cls.save_content_block(content_block, supporting_collections)

            saved_blocks += 1

        # Update the Inbox Message model with the number of ContentBlocks that were saved
        inbox_message_db.content_blocks_saved = saved_blocks
        inbox_message_db.save()

        # Create and return a Status Message indicating success
        status_message = tm11.StatusMessage(
            message_id=generate_message_id(),
            in_response_to=inbox_message.message_id,
            status_type=ST_SUCCESS)
        return status_message