(analyst, obj, rcpts, preview,
                      relation_choices=[], confirmed=False)
return ret
:param analyst The analyst triggering this TAXII service call
    :param obj The context object being shared
    :param rcpts The list of sources to which the TAXII message is being sent
    :param preview If true, generate and return the STIX doc, rather
                   than sending via TAXII
    :param relation_choices The list of items related to OBJ that have
                            been chosen for sharing
    :param confirmed True if user has accepted & approved releasability updates
:param analyst The analyst triggering this TAXII service call
    :param obj The context object being shared
    :param rcpts The list of sources to which the TAXII message is being sent
    :param preview If true, generate and return the STIX doc, rather
                   than sending via TAXII
    :param relation_choices The list of items related to OBJ that have
                            been chosen for sharing
    :param confirmed True if user has accepted & approved releasability updates
: param analyst The analyst triggering this TAXII service call : param obj The context object being shared : param rcpts The list of sources to which the TAXII message is being sent : param preview If true generate and return the STIX doc rather than sending via TAXII : param relation_choices The list of items related to OBJ that have been chosen for sharing : param confirmed True if user has accepted & approved releasability updates
def run_taxii_service(analyst, obj, rcpts, preview,
                      relation_choices=[], confirmed=False):
    """
    :param analyst The analyst triggering this TAXII service call
    :param obj The context object being shared
    :param rcpts The list of sources to which the TAXII message is being sent
    :param preview If true, generate and return the STIX doc, rather
                   than sending via TAXII
    :param relation_choices The list of items related to OBJ that have
                            been chosen for sharing
    :param confirmed True if user has accepted & approved releasability updates
    """
    ret = {
            'success': False, # tells client if any message was sent successfully
            'rcpts': [], # list of sources the message was sent
            'failed_rcpts': [], # list of sources to which message failed to send
          }

    if not obj: # no item (shouldn't occur unless someone is really trying to break things.)
        ret['reason'] = "No object found."
        return ret

    if not rcpts and not preview: # no recipients selected in TAXII form (ok for preview)
        ret['reason'] = "No recipients selected."
        return ret

    # If dealing with an event context, make sure at least one related item is
    # selected. Events have no real sharing value without related information.
    if obj._meta['crits_type'] == Event._meta['crits_type'] and len(relation_choices) == 0:
        ret['reason'] = "Need at least one related item to send."
        return ret

    # Set the XML namespace for STIX documents
    sc = get_config('taxii_service')
    set_id_namespace({sc['namespace']: sc['ns_prefix']})

    # Get list of recipient sources
    rcpt_srcs = []
    for rcpt in rcpts:
        (svr, fid) = rcpt.split(' - ')
        rcpt_srcs.append(sc['taxii_servers'][svr]['feeds'][fid]['source'])

    # Convert object and chosen related items to STIX/CybOX
    try:
        stix_msg = to_stix(obj, relation_choices, bin_fmt="base64")
        stix_doc = stix_msg['stix_obj']
    except UnsupportedCybOXObjectTypeError as e:
        ret['reason'] = e.message
        return ret

    # if doing a preview of content, return content now
    if preview:
        ret['preview'] = stix_doc.to_xml()
        return ret
    elif not confirmed: # if user has not accepted responsibility for releasability
        release = verify_releasability(rcpt_srcs, stix_msg['final_objects'],
                                       analyst, False)
        if release: # if releasability needs to change
            ret['release_changes'] = release
            return ret # make user confirm changes, instead of sending messages

    # 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)

    # The minimum required info has been provided by user via the TAXII form.
    # Form configuration and validation ensures the form is valid.
    #
    # NOTE: this does not guarantee that the message will send to
    # each/any recipient feed successfully.

    # Loop through each recipient
    for feed in rcpts:
        try: # try to get config
            (svr, fid) = feed.split(' - ')
            scfg = sc['taxii_servers'][svr]
            fcfg = sc['taxii_servers'][svr]['feeds'][fid]
            hostname = scfg['hostname']
            version = scfg['version']
            https = scfg['https']
            lcert = scfg['lcert']
            path = scfg['ipath']
            port = scfg['port']
            akey = scfg['keyfile']
            user = scfg.get('user')
            pword = scfg.get('pword')
            feedname = fcfg['feedname']
            source = fcfg['source']
            fcert = fcfg['fcert']
            rcpt = "%s - %s" % (svr, feedname)
            if not port:
                port = None

        except KeyError as e: # if can't find necessary config info, do next
            ret['failed_rcpts'].append((feed, 'None/Bad Configuration'))
            continue

        #TODO: this doesn't confirm that 'hostname' is a TAXII server...
        # This doesn't work if a proxy is needed for internet access
        if not settings.HTTP_PROXY and not resolve_taxii_server(hostname):
            msg = "Cannot contact TAXII Server at: %s" % hostname
            ret['failed_rcpts'].append((rcpt, msg))
            continue

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

        # generate and send inbox messages
        # one message per feed, with appropriate TargetFeed header specified

        failed = True
        status = ""

        # if version=0, Poll using 1.1 then 1.0 if that fails.
        try:
            while True:
                if version in ('0', '1.1'):
                    content_block = build_content_block(tm11, stix_doc, fcert)
                    result = gen_send(tm11, client, content_block, hostname,
                                      t.VID_TAXII_XML_11,
                                      dcn = [feedname],
                                      url = path,
                                      port = port)
                else: # '1.0' should be the only other option
                    content_block = build_content_block(tm, stix_doc, fcert)
                    result = gen_send(tm, client, content_block, hostname,
                                    t.VID_TAXII_XML_10,
                                    eh = {'TargetFeed': feedname},
                                    url = path,
                                    port = port)
                if len(result) == 2:
                    res = result[1]
                    if res.status_type == tm11.ST_SUCCESS:
                        failed = False
                        ret['rcpts'].append(rcpt)
                        break
                    else:
                        status += "Server Response: " + res.message
                else:
                    status += "Error: " + cgi.escape(result[0])

                if version == '0': # if version is unknown & '1.1' failed
                    status = 'TAXII 1.1 ' + status + '<br><br>TAXII 1.0 '
                    version = '1.0' # try '1.0'
                else: # specific version provided, so done
                    break
        except IOError as e:
            msg = "Error reading encryption certificate - %s" % e
            ret['failed_rcpts'].append((rcpt, msg))
            continue

        if failed:
            ret['failed_rcpts'].append((rcpt, status))
        else: # update releasability for successful TAXII messages
            verify_releasability([source], stix_msg['final_objects'],
                                 analyst, True)

    ret['success'] = True
    return ret
def run_taxii_service ( analyst , obj , rcpts , preview , relation_choices = [ ] , confirmed = False ) : ret = { 'success' : False , # tells client if any message was sent successfully 'rcpts' : [ ] , # list of sources the message was sent 'failed_rcpts' : [ ] , # list of sources to which message failed to send } if not obj : # no item (shouldn't occur unless someone is really trying to break things.) ret [ 'reason' ] = "No object found." return ret if not rcpts and not preview : # no recipients selected in TAXII form (ok for preview) ret [ 'reason' ] = "No recipients selected." return ret # If dealing with an event context, make sure at least one related item is # selected. Events have no real sharing value without related information. if obj . _meta [ 'crits_type' ] == Event . _meta [ 'crits_type' ] and len ( relation_choices ) == 0 : ret [ 'reason' ] = "Need at least one related item to send." return ret # Set the XML namespace for STIX documents sc = get_config ( 'taxii_service' ) set_id_namespace ( { sc [ 'namespace' ] : sc [ 'ns_prefix' ] } ) # Get list of recipient sources rcpt_srcs = [ ] for rcpt in rcpts : ( svr , fid ) = rcpt . split ( ' - ' ) rcpt_srcs . append ( sc [ 'taxii_servers' ] [ svr ] [ 'feeds' ] [ fid ] [ 'source' ] ) # Convert object and chosen related items to STIX/CybOX try : stix_msg = to_stix ( obj , relation_choices , bin_fmt = "base64" ) stix_doc = stix_msg [ 'stix_obj' ] except UnsupportedCybOXObjectTypeError as e : ret [ 'reason' ] = e . message return ret # if doing a preview of content, return content now if preview : ret [ 'preview' ] = stix_doc . to_xml ( ) return ret elif not confirmed : # if user has not accepted responsibility for releasability release = verify_releasability ( rcpt_srcs , stix_msg [ 'final_objects' ] , analyst , False ) if release : # if releasability needs to change ret [ 'release_changes' ] = release return ret # make user confirm changes, instead of sending messages # 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 ) # The minimum required info has been provided by user via the TAXII form. # Form configuration and validation ensures the form is valid. # # NOTE: this does not guarantee that the message will send to # each/any recipient feed successfully. # Loop through each recipient for feed in rcpts : try : # try to get config ( svr , fid ) = feed . split ( ' - ' ) scfg = sc [ 'taxii_servers' ] [ svr ] fcfg = sc [ 'taxii_servers' ] [ svr ] [ 'feeds' ] [ fid ] hostname = scfg [ 'hostname' ] version = scfg [ 'version' ] https = scfg [ 'https' ] lcert = scfg [ 'lcert' ] path = scfg [ 'ipath' ] port = scfg [ 'port' ] akey = scfg [ 'keyfile' ] user = scfg . get ( 'user' ) pword = scfg . get ( 'pword' ) feedname = fcfg [ 'feedname' ] source = fcfg [ 'source' ] fcert = fcfg [ 'fcert' ] rcpt = "%s - %s" % ( svr , feedname ) if not port : port = None except KeyError as e : # if can't find necessary config info, do next ret [ 'failed_rcpts' ] . append ( ( feed , 'None/Bad Configuration' ) ) continue #TODO: this doesn't confirm that 'hostname' is a TAXII server... # This doesn't work if a proxy is needed for internet access if not settings . HTTP_PROXY and not resolve_taxii_server ( hostname ) : msg = "Cannot contact TAXII Server at: %s" % hostname ret [ 'failed_rcpts' ] . append ( ( rcpt , msg ) ) continue # Setup client authentication and proxy communication if https : client . setUseHttps ( True ) if akey and lcert and user : client . setAuthType ( tc . HttpClient . AUTH_CERT_BASIC ) client . setAuthCredentials ( { 'key_file' : akey , 'cert_file' : lcert , 'username' : user , 'password' : pword } ) elif akey and lcert : client . setAuthType ( tc . HttpClient . AUTH_CERT ) client . setAuthCredentials ( { 'key_file' : akey , 'cert_file' : lcert } ) elif user : client . setAuthType ( tc . HttpClient . AUTH_BASIC ) client . setAuthCredentials ( { 'username' : user , 'password' : pword } ) # generate and send inbox messages # one message per feed, with appropriate TargetFeed header specified failed = True status = "" # if version=0, Poll using 1.1 then 1.0 if that fails. try : while True : if version in ( '0' , '1.1' ) : content_block = build_content_block ( tm11 , stix_doc , fcert ) result = gen_send ( tm11 , client , content_block , hostname , t . VID_TAXII_XML_11 , dcn = [ feedname ] , url = path , port = port ) else : # '1.0' should be the only other option content_block = build_content_block ( tm , stix_doc , fcert ) result = gen_send ( tm , client , content_block , hostname , t . VID_TAXII_XML_10 , eh = { 'TargetFeed' : feedname } , url = path , port = port ) if len ( result ) == 2 : res = result [ 1 ] if res . status_type == tm11 . ST_SUCCESS : failed = False ret [ 'rcpts' ] . append ( rcpt ) break else : status += "Server Response: " + res . message else : status += "Error: " + cgi . escape ( result [ 0 ] ) if version == '0' : # if version is unknown & '1.1' failed status = 'TAXII 1.1 ' + status + '<br><br>TAXII 1.0 ' version = '1.0' # try '1.0' else : # specific version provided, so done break except IOError as e : msg = "Error reading encryption certificate - %s" % e ret [ 'failed_rcpts' ] . append ( ( rcpt , msg ) ) continue if failed : ret [ 'failed_rcpts' ] . append ( ( rcpt , status ) ) else : # update releasability for successful TAXII messages verify_releasability ( [ source ] , stix_msg [ 'final_objects' ] , analyst , True ) ret [ 'success' ] = True return ret