(hostname=None, https=None, port=None, path=None,
                        version="0", feed=None, akey=None, acert=None,
                        subID=None, analyst=None, user=None, pword=None,
                       ecert=None, ekey=None, start=None, end=None,
                       import_now=False)
return ret
Poll a single feed using the provided parameters, if import_now is False,
    write the data to the database, if import_now is True, return the
    results of the import.

    :param hostname: Hostname of the TAXII server
    :type hostname: string
    :param https: If True, instruct client to use HTTPS
    :type https: bool
    :param port: TAXII server port to which to connect
    :type port: string
    :param path: Path component of the TAXII server URL
    :type path: string
    :param version: TAXII version to be used
    :type version: string
    :param feed: Name of the TAXII feed/collection
    :type feed: string
    :param akey: Path to the authentication key file
    :type akey: string
    :param acert: Path to the authentication certificate file
    :type acert: string
    :param subID: Subscription ID for the selected TAXII feed
    :type subID: string
    :param analyst: Userid of the anaylst making this request
    :type analyst: string
    :param user: Username used to authenticate to the TAXII server
    :type user: string
    :param pword: Password used to authenticate to the TAXII server
    :type pword: string
    :param ecert: Path to a certificate file used for encryption of TAXII content
    :type ecert: string
    :param ekey: Path to a key file used for encryption of TAXII content
    :type ekey: string
    :param start: Exclusive begin component of the timerange to be polled
    :type start: :class:`datetime.datetime`
    :param end: Inclusive end component of the timerange to be polled
    :type end: :class:`datetime.datetime`
    :param import_now: If True, import the data directly into CRITs
    :type import_now: boolean
    :returns: dict with keys:
              "failures" (list) - Failure messages
              "blk_count" (int) - The count of content blocks retrieved
              "start" (string) - Exclusive begin component of the timerange that was polled
              "end" (string) - Inclusive end component of the timerange that was polled
              "taxii_msg_id" (string) - TAXII Message ID of the poll
              "import" (dict) - The results of the import, if any
Poll a single feed using the provided parameters, if import_now is False,
    write the data to the database, if import_now is True, return the
    results of the import.
Poll a single feed using the provided parameters if import_now is False write the data to the database if import_now is True return the results of the import .
def execute_taxii_agent(hostname=None, https=None, port=None, path=None,
                        version="0", feed=None, akey=None, acert=None,
                        subID=None, analyst=None, user=None, pword=None,
                       ecert=None, ekey=None, start=None, end=None,
                       import_now=False):
    """
    Poll a single feed using the provided parameters, if import_now is False,
    write the data to the database, if import_now is True, return the
    results of the import.

    :param hostname: Hostname of the TAXII server
    :type hostname: string
    :param https: If True, instruct client to use HTTPS
    :type https: bool
    :param port: TAXII server port to which to connect
    :type port: string
    :param path: Path component of the TAXII server URL
    :type path: string
    :param version: TAXII version to be used
    :type version: string
    :param feed: Name of the TAXII feed/collection
    :type feed: string
    :param akey: Path to the authentication key file
    :type akey: string
    :param acert: Path to the authentication certificate file
    :type acert: string
    :param subID: Subscription ID for the selected TAXII feed
    :type subID: string
    :param analyst: Userid of the anaylst making this request
    :type analyst: string
    :param user: Username used to authenticate to the TAXII server
    :type user: string
    :param pword: Password used to authenticate to the TAXII server
    :type pword: string
    :param ecert: Path to a certificate file used for encryption of TAXII content
    :type ecert: string
    :param ekey: Path to a key file used for encryption of TAXII content
    :type ekey: string
    :param start: Exclusive begin component of the timerange to be polled
    :type start: :class:`datetime.datetime`
    :param end: Inclusive end component of the timerange to be polled
    :type end: :class:`datetime.datetime`
    :param import_now: If True, import the data directly into CRITs
    :type import_now: boolean
    :returns: dict with keys:
              "failures" (list) - Failure messages
              "blk_count" (int) - The count of content blocks retrieved
              "start" (string) - Exclusive begin component of the timerange that was polled
              "end" (string) - Inclusive end component of the timerange that was polled
              "taxii_msg_id" (string) - TAXII Message ID of the poll
              "import" (dict) - The results of the import, if any
    """

    ret = {
            'failures': [],
            'blk_count': 0,
            'poll_id': None,
            'start': start,
            'end': end,
            'taxii_msg_id': None,
          }

    save_datetimes = False

    # Last document's end time is our start time.
    if not start:
        save_datetimes = True
        last = taxii.Taxii.get_last(hostname + ':' + feed)
        if last:
            start = pytz.utc.localize(last.end)

    # If start is a string, convert it to a datetime
    # YYYY-MM-DD HH:MM:SS
    if isinstance(start, str):
        start = pytz.utc.localize(parse(start, fuzzy=True))
    elif isinstance(start, datetime) and not start.tzinfo:
        start = start.replace(tzinfo=pytz.utc)

    # store the current time as the time of this request
    runtime = datetime.now(tzutc())

    # End time is always now, unless specified.
    if not end:
        end = runtime

    # If end is a string, convert it to a datetime
    # YYYY-MM-DD HH:MM:SS
    if isinstance(end, str):
        end = pytz.utc.localize(parse(end, fuzzy=True))
    elif isinstance(end, datetime) and not end.tzinfo:
        end = end.replace(tzinfo=pytz.utc)

    if start:
        ret['start'] = start.strftime('%Y-%m-%d %H:%M:%S')
    else:
        ret['start'] = 'None'
    ret['end'] = end.strftime('%Y-%m-%d %H:%M:%S')

    # compare start and end to make sure:
    # 1) start time is before end time
    # 2) end time is not in the future
    if (start != None and start >= end):
        ret['failures'].append("Start time must be before end time")
        return ret
    if end > runtime:
        ret['failures'].append("End time cannot be in the future")
        return ret

    # subID & port must be none if not provided
    if not subID:
        subID = None
    if not port:
        port = None

    # Instantiate TAXII client class
    client = tc.HttpClient()

    # Setup proxy communication, if needed
    if settings.HTTP_PROXY:
        proxy = settings.HTTP_PROXY
        if not proxy.startswith('http://'):
            proxy = 'http://' + proxy
        client.setProxy(proxy)

    # Setup client authentication
    if https:
        client.setUseHttps(True)
    if akey and acert and user:
        client.setAuthType(tc.HttpClient.AUTH_CERT_BASIC)
        client.setAuthCredentials({'key_file': akey, 'cert_file': acert,
                                   'username': user, 'password': pword})
    elif akey and acert:
        client.setAuthType(tc.HttpClient.AUTH_CERT)
        client.setAuthCredentials({'key_file': akey, 'cert_file': acert})
    elif user:
        client.setAuthType(tc.HttpClient.AUTH_BASIC)
        client.setAuthCredentials({'username': user, 'password': pword})

    crits_taxii = taxii.Taxii()
    crits_taxii.runtime = runtime
    crits_taxii.end = end
    crits_taxii.feed = hostname + ':' + feed

    # if version=0, Poll using 1.1 then 1.0 if that fails.
    while True:
        status = ""
        if version in ('0', '1.1'):
            if subID:
                pprams = None
            else:
                pprams = tm11.PollRequest.PollParameters()
            poll_msg = tm11.PollRequest(message_id=tm11.generate_message_id(),
                                        collection_name=feed,
                                        poll_parameters=pprams,
                                        exclusive_begin_timestamp_label=start,
                                        inclusive_end_timestamp_label=end,
                                        subscription_id=subID)
            xml_msg_binding = t.VID_TAXII_XML_11
            tm_ = tm11

        else: # '1.0' should be the only other option
            poll_msg = tm.PollRequest(message_id=tm.generate_message_id(),
                                      feed_name=feed,
                                      exclusive_begin_timestamp_label=start,
                                      inclusive_end_timestamp_label=end,
                                      subscription_id=subID)
            xml_msg_binding = t.VID_TAXII_XML_10
            tm_ = tm

        try:
            response = client.callTaxiiService2(hostname, path,
                                                xml_msg_binding,
                                                poll_msg.to_xml(), port)
        except Exception as e:
            if "alert unknown ca" in str(e):
                ret['failures'].append("Certficate Error - TAXII Server does not "
                                       "recognize your certificate: %s" % e)
            else:
                ret['failures'].append("TAXII Server Communication Error: %s" % e)
            return ret

        # If server says it's a different TAXII version than selected, notify
        if (version == '1.1' and
            response.info().getheader('X-TAXII-Content-Type') == t.VID_TAXII_XML_10):
            ret['failures'].append('Error - TAXII 1.1 selected, but server is TAXII 1.0')
            return ret
        if (version == '1.0' and
            response.info().getheader('X-TAXII-Content-Type') == t.VID_TAXII_XML_11):
            if status:
                status += 'Server response content type is TAXII 1.1'
            else:
                ret['failures'].append('Error - TAXII 1.0 selected, but server is TAXII 1.1')
            return ret

        try:
            taxii_msg = t.get_message_from_http_response(response,
                                                         poll_msg.message_id)

            if (response.getcode() != 200
                or taxii_msg.message_type == tm_.MSG_STATUS_MESSAGE):
                status += "Server Response: %s"
                msg = (taxii_msg.status_type, taxii_msg.message)
                status = status % ' - '.join(x for x in msg if x)
            else:
                break

        except Exception as e:
            status += str(e)
            if version == '1.0' and "taxii_xml_binding-1.1" in str(e):
                status += ". Try selecting TAXII Version 1.1 in settings."

        if version == '0':
            ret['failures'].append('TAXII 1.1 ' + status)
            version = '1.0' # try '1.0'
        else:
            ret['failures'].append('TAXII %s ' % version + status)
            return ret

    valid = tm_.validate_xml(taxii_msg.to_xml())
    if valid != True:
        ret['failures'].append("Invalid XML: %s" % valid)
        return ret

    if taxii_msg.message_type != tm_.MSG_POLL_RESPONSE:
        msg = "No poll response. Unexpected message type: %s"
        ret['failures'].append(msg % taxii_msg.message_type)
        return ret

    mid = taxii_msg.message_id
    ret['taxii_msg_id'] = mid
    if not taxii_msg.content_blocks:
        if save_datetimes:
            crits_taxii.save()
        return ret

    if import_now:
        import_result = {
                'successes': 0,
                'failures': [],
                'Certificate': [],
                'Domain': [],
                'Email': [],
                'Event': [],
                'Indicator': [],
                'IP': [],
                'PCAP': [],
                'RawData': [],
                'Sample': [],
               }

    for content_block in taxii_msg.content_blocks:
        label = content_block.timestamp_label.strftime("%Y-%m-%d %H:%M:%S")
        data = parse_content_block(content_block, tm_, ekey, ecert)
        errors = ["%s: %s" % ("Content Block", data[1])] if data[1] else []

        content = taxii.TaxiiContent()
        content.populate(data[0], analyst, mid, hostname, feed, label, start,
                         end, poll_time=runtime, errors=errors)
        if import_now:
            ic_ret = import_content([content], analyst)
            if ic_ret and ic_ret['status']:
                for k in import_result:
                    if k == 'successes':
                        import_result[k] += ic_ret[k]
                    else:
                        import_result[k].extend(ic_ret[k])
        else:
            content.save()
        ret['blk_count'] += 1
        t_offset = runtime.replace(tzinfo=None)-datetime(1970,1,1)
        ret['poll_id'] = '%.3f' % (int(t_offset.total_seconds() * 1000)/1000.0)
    if save_datetimes:
        crits_taxii.save()
    if import_now:
        ret['import'] = import_result

    return ret
def execute_taxii_agent ( hostname = None , https = None , port = None , path = None , version = "0" , feed = None , akey = None , acert = None , subID = None , analyst = None , user = None , pword = None , ecert = None , ekey = None , start = None , end = None , import_now = False ) : ret = { 'failures' : [ ] , 'blk_count' : 0 , 'poll_id' : None , 'start' : start , 'end' : end , 'taxii_msg_id' : None , } save_datetimes = False # Last document's end time is our start time. if not start : save_datetimes = True last = taxii . Taxii . get_last ( hostname + ':' + feed ) if last : start = pytz . utc . localize ( last . end ) # If start is a string, convert it to a datetime # YYYY-MM-DD HH:MM:SS if isinstance ( start , str ) : start = pytz . utc . localize ( parse ( start , fuzzy = True ) ) elif isinstance ( start , datetime ) and not start . tzinfo : start = start . replace ( tzinfo = pytz . utc ) # store the current time as the time of this request runtime = datetime . now ( tzutc ( ) ) # End time is always now, unless specified. if not end : end = runtime # If end is a string, convert it to a datetime # YYYY-MM-DD HH:MM:SS if isinstance ( end , str ) : end = pytz . utc . localize ( parse ( end , fuzzy = True ) ) elif isinstance ( end , datetime ) and not end . tzinfo : end = end . replace ( tzinfo = pytz . utc ) if start : ret [ 'start' ] = start . strftime ( '%Y-%m-%d %H:%M:%S' ) else : ret [ 'start' ] = 'None' ret [ 'end' ] = end . strftime ( '%Y-%m-%d %H:%M:%S' ) # compare start and end to make sure: # 1) start time is before end time # 2) end time is not in the future if ( start != None and start >= end ) : ret [ 'failures' ] . append ( "Start time must be before end time" ) return ret if end > runtime : ret [ 'failures' ] . append ( "End time cannot be in the future" ) return ret # subID & port must be none if not provided if not subID : subID = None if not port : port = None # Instantiate TAXII client class client = tc . HttpClient ( ) # Setup proxy communication, if needed if settings . HTTP_PROXY : proxy = settings . HTTP_PROXY if not proxy . startswith ( 'http://' ) : proxy = 'http://' + proxy client . setProxy ( proxy ) # Setup client authentication if https : client . setUseHttps ( True ) if akey and acert and user : client . setAuthType ( tc . HttpClient . AUTH_CERT_BASIC ) client . setAuthCredentials ( { 'key_file' : akey , 'cert_file' : acert , 'username' : user , 'password' : pword } ) elif akey and acert : client . setAuthType ( tc . HttpClient . AUTH_CERT ) client . setAuthCredentials ( { 'key_file' : akey , 'cert_file' : acert } ) elif user : client . setAuthType ( tc . HttpClient . AUTH_BASIC ) client . setAuthCredentials ( { 'username' : user , 'password' : pword } ) crits_taxii = taxii . Taxii ( ) crits_taxii . runtime = runtime crits_taxii . end = end crits_taxii . feed = hostname + ':' + feed # if version=0, Poll using 1.1 then 1.0 if that fails. while True : status = "" if version in ( '0' , '1.1' ) : if subID : pprams = None else : pprams = tm11 . PollRequest . PollParameters ( ) poll_msg = tm11 . PollRequest ( message_id = tm11 . generate_message_id ( ) , collection_name = feed , poll_parameters = pprams , exclusive_begin_timestamp_label = start , inclusive_end_timestamp_label = end , subscription_id = subID ) xml_msg_binding = t . VID_TAXII_XML_11 tm_ = tm11 else : # '1.0' should be the only other option poll_msg = tm . PollRequest ( message_id = tm . generate_message_id ( ) , feed_name = feed , exclusive_begin_timestamp_label = start , inclusive_end_timestamp_label = end , subscription_id = subID ) xml_msg_binding = t . VID_TAXII_XML_10 tm_ = tm try : response = client . callTaxiiService2 ( hostname , path , xml_msg_binding , poll_msg . to_xml ( ) , port ) except Exception as e : if "alert unknown ca" in str ( e ) : ret [ 'failures' ] . append ( "Certficate Error - TAXII Server does not " "recognize your certificate: %s" % e ) else : ret [ 'failures' ] . append ( "TAXII Server Communication Error: %s" % e ) return ret # If server says it's a different TAXII version than selected, notify if ( version == '1.1' and response . info ( ) . getheader ( 'X-TAXII-Content-Type' ) == t . VID_TAXII_XML_10 ) : ret [ 'failures' ] . append ( 'Error - TAXII 1.1 selected, but server is TAXII 1.0' ) return ret if ( version == '1.0' and response . info ( ) . getheader ( 'X-TAXII-Content-Type' ) == t . VID_TAXII_XML_11 ) : if status : status += 'Server response content type is TAXII 1.1' else : ret [ 'failures' ] . append ( 'Error - TAXII 1.0 selected, but server is TAXII 1.1' ) return ret try : taxii_msg = t . get_message_from_http_response ( response , poll_msg . message_id ) if ( response . getcode ( ) != 200 or taxii_msg . message_type == tm_ . MSG_STATUS_MESSAGE ) : status += "Server Response: %s" msg = ( taxii_msg . status_type , taxii_msg . message ) status = status % ' - ' . join ( x for x in msg if x ) else : break except Exception as e : status += str ( e ) if version == '1.0' and "taxii_xml_binding-1.1" in str ( e ) : status += ". Try selecting TAXII Version 1.1 in settings." if version == '0' : ret [ 'failures' ] . append ( 'TAXII 1.1 ' + status ) version = '1.0' # try '1.0' else : ret [ 'failures' ] . append ( 'TAXII %s ' % version + status ) return ret valid = tm_ . validate_xml ( taxii_msg . to_xml ( ) ) if valid != True : ret [ 'failures' ] . append ( "Invalid XML: %s" % valid ) return ret if taxii_msg . message_type != tm_ . MSG_POLL_RESPONSE : msg = "No poll response. Unexpected message type: %s" ret [ 'failures' ] . append ( msg % taxii_msg . message_type ) return ret mid = taxii_msg . message_id ret [ 'taxii_msg_id' ] = mid if not taxii_msg . content_blocks : if save_datetimes : crits_taxii . save ( ) return ret if import_now : import_result = { 'successes' : 0 , 'failures' : [ ] , 'Certificate' : [ ] , 'Domain' : [ ] , 'Email' : [ ] , 'Event' : [ ] , 'Indicator' : [ ] , 'IP' : [ ] , 'PCAP' : [ ] , 'RawData' : [ ] , 'Sample' : [ ] , } for content_block in taxii_msg . content_blocks : label = content_block . timestamp_label . strftime ( "%Y-%m-%d %H:%M:%S" ) data = parse_content_block ( content_block , tm_ , ekey , ecert ) errors = [ "%s: %s" % ( "Content Block" , data [ 1 ] ) ] if data [ 1 ] else [ ] content = taxii . TaxiiContent ( ) content . populate ( data [ 0 ] , analyst , mid , hostname , feed , label , start , end , poll_time = runtime , errors = errors ) if import_now : ic_ret = import_content ( [ content ] , analyst ) if ic_ret and ic_ret [ 'status' ] : for k in import_result : if k == 'successes' : import_result [ k ] += ic_ret [ k ] else : import_result [ k ] . extend ( ic_ret [ k ] ) else : content . save ( ) ret [ 'blk_count' ] += 1 t_offset = runtime . replace ( tzinfo = None ) - datetime ( 1970 , 1 , 1 ) ret [ 'poll_id' ] = '%.3f' % ( int ( t_offset . total_seconds ( ) * 1000 ) / 1000.0 ) if save_datetimes : crits_taxii . save ( ) if import_now : ret [ 'import' ] = import_result return ret