Example #1
0
def add_new_ip(data, rowData, request, errors, is_validate_only=False, cache={}):
    """
    Add a new IP to CRITs.

    :param data: Data for the IP address.
    :type data: dict
    :param rowData: Extra data from rows used by mass object uploader.
    :type rowData: dict
    :param request: The request for adding this IP.
    :type request: :class:`django.http.HttpRequest`
    :param errors: A list of current errors prior to processing this IP.
    :type errors: list
    :param is_validate_only: Whether or not we should validate or add.
    :type is_validate_only: bool
    :param cache: Cached data, typically for performance enhancements
                  during bulk operations.
    :type cache: dict
    :returns: tuple with (<result>, <errors>, <retval>)
    """

    result = False
    retVal = {}

    ip = data.get('ip')
    ip_type = data.get('ip_type')
    campaign = data.get('campaign')
    confidence = data.get('confidence')
    source = data.get('source_name')
    source_method = data.get('source_method')
    source_reference = data.get('source_reference')
    source_tlp = data.get('source_tlp')
    user = request.user
    is_add_indicator = data.get('add_indicator')
    bucket_list = data.get(form_consts.Common.BUCKET_LIST_VARIABLE_NAME)
    ticket = data.get(form_consts.Common.TICKET_VARIABLE_NAME)
    indicator_reference = data.get('indicator_reference')
    related_id = data.get('related_id')
    related_type = data.get('related_type')
    relationship_type = data.get('relationship_type')
    description = data.get('description')

    retVal = ip_add_update(ip, ip_type,
            source=source,
            source_method=source_method,
            source_reference=source_reference,
            source_tlp=source_tlp,
            campaign=campaign,
            confidence=confidence,
            user=user,
            is_add_indicator=is_add_indicator,
            indicator_reference=indicator_reference,
            bucket_list=bucket_list,
            ticket=ticket,
            is_validate_only=is_validate_only,
            cache=cache,
            related_id=related_id,
            related_type=related_type,
            relationship_type=relationship_type,
            description = description)

    if not retVal['success']:
        errors.append(retVal.get('message'))
        retVal['message'] = ""

    # This block tries to add objects to the item
    if retVal['success'] == True or is_validate_only == True:
        result = True
        objectsData = rowData.get(form_consts.Common.OBJECTS_DATA)

        # add new objects if they exist
        if objectsData:
            objectsData = json.loads(objectsData)

            for object_row_counter, objectData in enumerate(objectsData, 1):
                new_ip = retVal.get('object')

                if new_ip != None and is_validate_only == False:
                    objectDict = object_array_to_dict(objectData,
                                                      "IP", new_ip.id)
                else:
                    if new_ip != None:
                        if new_ip.id:
                            objectDict = object_array_to_dict(objectData,
                                                              "IP", new_ip.id)
                        else:
                            objectDict = object_array_to_dict(objectData,
                                                              "IP", "")
                    else:
                        objectDict = object_array_to_dict(objectData,
                                                          "IP", "")

                (obj_result,
                 errors,
                 obj_retVal) = validate_and_add_new_handler_object(
                        None, objectDict, request, errors, object_row_counter,
                        is_validate_only=is_validate_only, cache=cache)

                if not obj_result:
                    retVal['success'] = False

    return result, errors, retVal
Example #2
0
def add_new_domain(data,
                   request,
                   errors,
                   rowData=None,
                   is_validate_only=False,
                   cache={}):
    """
    Add a new domain to CRITs.

    :param data: The data about the domain.
    :type data: dict
    :param request: The Django request.
    :type request: :class:`django.http.HttpRequest`
    :param errors: A list of current errors to append to.
    :type errors: list
    :param rowData: Any objects that need to be added to the domain.
    :type rowData: dict
    :param is_validate_only: Only validate the data and return any errors.
    :type is_validate_only: boolean
    :param cache: Cached data, typically for performance enhancements
                  during bulk uperations.
    :type cache: dict
    :returns: tuple
    """

    username = request.user.username
    result = False
    retVal = {}
    reference = data.get('domain_reference')
    name = data.get('domain_source')
    method = data.get('domain_method')
    source = [
        create_embedded_source(name,
                               reference=reference,
                               method=method,
                               analyst=username)
    ]
    bucket_list = data.get(form_consts.Common.BUCKET_LIST_VARIABLE_NAME)
    ticket = data.get(form_consts.Common.TICKET_VARIABLE_NAME)

    if data.get('campaign') and data.get('confidence'):
        campaign = [
            EmbeddedCampaign(name=data.get('campaign'),
                             confidence=data.get('confidence'),
                             analyst=username)
        ]
    else:
        campaign = []

    (sdomain, fqdn) = get_domain(data['domain'])
    if sdomain == "no_tld_found_error":
        errors.append(u"Error: Invalid domain: " + data['domain'])
    elif is_validate_only == False:
        retVal = upsert_domain(sdomain,
                               fqdn,
                               source,
                               username,
                               campaign,
                               bucket_list=bucket_list,
                               ticket=ticket,
                               cache=cache)
        ip_result = None

        if retVal['success']:
            new_domain = retVal['object']
            add_ip = data.get('add_ip')
            if add_ip:
                ip = data.get('ip')
                ip_type = data.get('ip_type')
                if data.get('same_source'):
                    ip_source = data.get('domain_source')
                    ip_method = data.get('domain_method')
                    ip_reference = reference
                else:
                    ip_source = data.get('ip_source')
                    ip_method = data.get('ip_method')
                    ip_reference = data.get('ip_reference')
                from crits.ips.handlers import ip_add_update
                ip_result = ip_add_update(ip,
                                          ip_type,
                                          ip_source,
                                          ip_method,
                                          ip_reference,
                                          campaign=campaign,
                                          analyst=username,
                                          bucket_list=bucket_list,
                                          ticket=ticket,
                                          cache=cache)
                if not ip_result['success']:
                    errors.append(ip_result['message'])
                else:
                    #add a relationship with the new IP address
                    new_ip = ip_result['object']
                    if new_domain and new_ip:
                        new_domain.add_relationship(rel_item=new_ip,
                                                    rel_type='Resolved_To',
                                                    analyst=username,
                                                    get_rels=False)
                        new_domain.save(username=username)
                        new_ip.save(username=username)

            #set the URL for viewing the new data
            resp_url = reverse('crits.domains.views.domain_detail',
                               args=[fqdn])

            if retVal['is_domain_new'] == True:
                retVal['message'] = (
                    'Success! Click here to view the new domain: '
                    '<a href="%s">%s</a>' % (resp_url, fqdn))
            else:
                message = ('Updated existing domain: <a href="%s">%s</a>' %
                           (resp_url, fqdn))
                retVal['message'] = message
                retVal[form_consts.Status.
                       STATUS_FIELD] = form_consts.Status.DUPLICATE
                retVal['warning'] = message

            #add indicators
            if data.get('add_indicators'):
                from crits.indicators.handlers import create_indicator_from_obj
                # If we have an IP object, add an indicator for that.
                if ip_result and ip_result['success']:
                    obj = ip_result['object']
                    result = create_indicator_from_obj('Address - ipv4-addr',
                                                       'IP', obj.id, obj.ip,
                                                       username)
                    if result['success'] == False:
                        errors.append(result['message'])

                # Add an indicator for the domain.
                result = create_indicator_from_obj('URI - Domain Name',
                                                   'Domain', new_domain.id,
                                                   sdomain, username)
                if result['success'] == False:
                    errors.append(result['message'])
                # If we have an FQDN (ie: it is not the same as sdomain)
                # then add that also.
                if fqdn != sdomain:
                    result = create_indicator_from_obj('URI - Domain Name',
                                                       'Domain', new_domain.id,
                                                       fqdn, username)
                    if result['success'] == False:
                        errors.append(result['message'])
            result = True

        elif 'message' in retVal:  #database error? (!c_dom)
            errors.append(
                retVal['message'])  #u"Unknown error: unable to add domain")

    elif is_validate_only == True:
        domain = data['domain']
        fqdn_domain = retrieve_domain(domain, cache)

        if fqdn_domain:
            if isinstance(fqdn_domain, Domain):
                resp_url = reverse('crits.domains.views.domain_detail',
                                   args=[fqdn])
                message = ('Warning: Domain already exists: '
                           '<a href="%s">%s</a>' % (resp_url, fqdn))
                retVal['message'] = message
                retVal['status'] = form_consts.Status.DUPLICATE
                retVal['warning'] = message
        else:
            result_cache = cache.get(form_consts.Domain.CACHED_RESULTS)
            result_cache[domain.lower()] = True

    # This block tries to add objects to the item
    if retVal.get('success') or is_validate_only == True:
        if rowData:
            objectsData = rowData.get(form_consts.Common.OBJECTS_DATA)

            # add new objects if they exist
            if objectsData:
                objectsData = json.loads(objectsData)
                current_domain = retrieve_domain(fqdn, cache)
                for object_row_counter, objectData in enumerate(
                        objectsData, 1):
                    if current_domain != None:
                        # if the domain exists then try to add objects to it
                        if isinstance(current_domain, Domain) == True:
                            objectDict = object_array_to_dict(
                                objectData, "Domain", current_domain.id)
                        else:
                            objectDict = object_array_to_dict(
                                objectData, "Domain", "")
                            current_domain = None
                    else:
                        objectDict = object_array_to_dict(
                            objectData, "Domain", "")

                    (object_result, object_errors,
                     object_retVal) = validate_and_add_new_handler_object(
                         None,
                         objectDict,
                         request,
                         errors,
                         object_row_counter,
                         is_validate_only=is_validate_only,
                         cache=cache,
                         obj=current_domain)

                    if object_retVal.get('success') == False:
                        retVal['success'] = False
                    if object_retVal.get('message'):
                        errors.append(object_retVal['message'])

    return result, errors, retVal
Example #3
0
def add_new_domain(data,
                   request,
                   errors,
                   rowData=None,
                   is_validate_only=False,
                   cache={}):
    """
    Add a new domain to CRITs.

    :param data: The data about the domain.
    :type data: dict
    :param request: The Django request.
    :type request: :class:`django.http.HttpRequest`
    :param errors: A list of current errors to append to.
    :type errors: list
    :param rowData: Any objects that need to be added to the domain.
    :type rowData: dict
    :param is_validate_only: Only validate the data and return any errors.
    :type is_validate_only: boolean
    :param cache: Cached data, typically for performance enhancements
                  during bulk operations.
    :type cache: dict
    :returns: tuple (<result>, <errors>, <retVal>)
    """

    result = False
    retVal = {}
    domain = data['domain']
    add_ip = data.get('add_ip')
    ip = data.get('ip')
    ip_type = data.get('ip_type')

    if add_ip:
        error = validate_and_normalize_ip(ip, ip_type)[1]
        if error:
            errors.append(error)

    if is_validate_only:
        error = get_valid_root_domain(domain)[2]
        if error:
            errors.append(error)

        # check for duplicate domains
        fqdn_domain = retrieve_domain(domain, cache)

        if fqdn_domain:
            if isinstance(fqdn_domain, Domain):
                resp_url = reverse('crits.domains.views.domain_detail',
                                   args=[domain])
                message = ('Warning: Domain already exists: '
                           '<a href="%s">%s</a>' % (resp_url, domain))
                retVal['message'] = message
                retVal['status'] = form_consts.Status.DUPLICATE
                retVal['warning'] = message
        else:
            result_cache = cache.get(form_consts.Domain.CACHED_RESULTS)
            result_cache[domain.lower()] = True

    elif not errors:
        username = request.user.username
        reference = data.get('domain_reference')
        source_name = data.get('domain_source')
        method = data.get('domain_method')
        source = [
            create_embedded_source(source_name,
                                   reference=reference,
                                   method=method,
                                   analyst=username)
        ]
        bucket_list = data.get(form_consts.Common.BUCKET_LIST_VARIABLE_NAME)
        ticket = data.get(form_consts.Common.TICKET_VARIABLE_NAME)

        if data.get('campaign') and data.get('confidence'):
            campaign = [
                EmbeddedCampaign(name=data.get('campaign'),
                                 confidence=data.get('confidence'),
                                 analyst=username)
            ]
        else:
            campaign = []

        retVal = upsert_domain(domain,
                               source,
                               username,
                               campaign,
                               bucket_list=bucket_list,
                               ticket=ticket,
                               cache=cache)

        if not retVal['success']:
            errors.append(retVal.get('message'))
            retVal['message'] = ""

        else:
            new_domain = retVal['object']
            ip_result = {}
            if add_ip:
                if data.get('same_source'):
                    ip_source = source_name
                    ip_method = method
                    ip_reference = reference
                else:
                    ip_source = data.get('ip_source')
                    ip_method = data.get('ip_method')
                    ip_reference = data.get('ip_reference')
                from crits.ips.handlers import ip_add_update
                ip_result = ip_add_update(ip,
                                          ip_type,
                                          ip_source,
                                          ip_method,
                                          ip_reference,
                                          campaign=campaign,
                                          analyst=username,
                                          bucket_list=bucket_list,
                                          ticket=ticket,
                                          cache=cache)
                if not ip_result['success']:
                    errors.append(ip_result['message'])
                else:
                    #add a relationship with the new IP address
                    new_ip = ip_result['object']
                    if new_domain and new_ip:
                        new_domain.add_relationship(rel_item=new_ip,
                                                    rel_type='Resolved_To',
                                                    analyst=username,
                                                    get_rels=False)
                        new_domain.save(username=username)
                        new_ip.save(username=username)

            #set the URL for viewing the new data
            resp_url = reverse('crits.domains.views.domain_detail',
                               args=[domain])

            if retVal['is_domain_new'] == True:
                retVal['message'] = (
                    'Success! Click here to view the new domain: '
                    '<a href="%s">%s</a>' % (resp_url, domain))
            else:
                message = ('Updated existing domain: <a href="%s">%s</a>' %
                           (resp_url, domain))
                retVal['message'] = message
                retVal[form_consts.Status.
                       STATUS_FIELD] = form_consts.Status.DUPLICATE
                retVal['warning'] = message

            #add indicators
            if data.get('add_indicators'):
                from crits.indicators.handlers import create_indicator_from_tlo
                # If we have an IP object, add an indicator for that.
                if ip_result.get('success'):
                    ip = ip_result['object']
                    result = create_indicator_from_tlo('IP',
                                                       ip,
                                                       username,
                                                       ip_source,
                                                       add_domain=False)
                    ip_ind = result.get('indicator')
                    if not result['success']:
                        errors.append(result['message'])

                # Add an indicator for the domain.
                result = create_indicator_from_tlo('Domain',
                                                   new_domain,
                                                   username,
                                                   source_name,
                                                   add_domain=False)

                if not result['success']:
                    errors.append(result['message'])
                elif ip_result.get('success') and ip_ind:
                    forge_relationship(left_class=result['indicator'],
                                       right_class=ip_ind,
                                       rel_type='Resolved_To',
                                       analyst=username)
            result = True

    # This block validates, and may also add, objects to the Domain
    if retVal.get('success') or is_validate_only == True:
        if rowData:
            objectsData = rowData.get(form_consts.Common.OBJECTS_DATA)

            # add new objects if they exist
            if objectsData:
                objectsData = json.loads(objectsData)
                current_domain = retrieve_domain(domain, cache)
                for object_row_counter, objectData in enumerate(
                        objectsData, 1):
                    if current_domain != None:
                        # if the domain exists then try to add objects to it
                        if isinstance(current_domain, Domain) == True:
                            objectDict = object_array_to_dict(
                                objectData, "Domain", current_domain.id)
                        else:
                            objectDict = object_array_to_dict(
                                objectData, "Domain", "")
                            current_domain = None
                    else:
                        objectDict = object_array_to_dict(
                            objectData, "Domain", "")

                    (obj_result, errors,
                     obj_retVal) = validate_and_add_new_handler_object(
                         None,
                         objectDict,
                         request,
                         errors,
                         object_row_counter,
                         is_validate_only=is_validate_only,
                         cache=cache,
                         obj=current_domain)
                    if not obj_result:
                        retVal['success'] = False

    return result, errors, retVal
Example #4
0
def add_new_domain(data, request, errors, rowData=None, is_validate_only=False, cache={}):
    """
    Add a new domain to CRITs.

    :param data: The data about the domain.
    :type data: dict
    :param request: The Django request.
    :type request: :class:`django.http.HttpRequest`
    :param errors: A list of current errors to append to.
    :type errors: list
    :param rowData: Any objects that need to be added to the domain.
    :type rowData: dict
    :param is_validate_only: Only validate the data and return any errors.
    :type is_validate_only: boolean
    :param cache: Cached data, typically for performance enhancements
                  during bulk operations.
    :type cache: dict
    :returns: tuple (<result>, <errors>, <retVal>)
    """

    result = False
    retVal = {}
    domain = data['domain']
    add_ip = data.get('add_ip')
    ip = data.get('ip')
    ip_type = data.get('ip_type')

    if add_ip:
        error = validate_and_normalize_ip(ip, ip_type)[1]
        if error:
             errors.append(error)

    if is_validate_only:
        error = get_valid_root_domain(domain)[2]
        if error:
            errors.append(error)

        # check for duplicate domains
        fqdn_domain = retrieve_domain(domain, cache)

        if fqdn_domain:
            if isinstance(fqdn_domain, Domain):
                resp_url = reverse('crits.domains.views.domain_detail', args=[domain])
                message = ('Warning: Domain already exists: '
                                     '<a href="%s">%s</a>' % (resp_url, domain))
                retVal['message'] = message
                retVal['status'] = form_consts.Status.DUPLICATE
                retVal['warning'] = message
        else:
            result_cache = cache.get(form_consts.Domain.CACHED_RESULTS);
            result_cache[domain.lower()] = True

    elif not errors:
        username = request.user.username
        reference = data.get('domain_reference')
        source_name = data.get('domain_source')
        method = data.get('domain_method')
        source = [create_embedded_source(source_name, reference=reference,
                                         method=method, analyst=username)]
        bucket_list = data.get(form_consts.Common.BUCKET_LIST_VARIABLE_NAME)
        ticket = data.get(form_consts.Common.TICKET_VARIABLE_NAME)

        if data.get('campaign') and data.get('confidence'):
            campaign = [EmbeddedCampaign(name=data.get('campaign'),
                                         confidence=data.get('confidence'),
                                         analyst=username)]
        else:
            campaign = []

        retVal = upsert_domain(domain, source, username, campaign,
                               bucket_list=bucket_list, ticket=ticket, cache=cache)

        if not retVal['success']:
            errors.append(retVal.get('message'))
            retVal['message'] = ""

        else:
            new_domain = retVal['object']
            ip_result = {}
            if add_ip:
                if data.get('same_source'):
                    ip_source = source_name
                    ip_method = method
                    ip_reference = reference
                else:
                    ip_source = data.get('ip_source')
                    ip_method = data.get('ip_method')
                    ip_reference = data.get('ip_reference')
                from crits.ips.handlers import ip_add_update
                ip_result = ip_add_update(ip,
                                          ip_type,
                                          ip_source,
                                          ip_method,
                                          ip_reference,
                                          campaign=campaign,
                                          analyst=username,
                                          bucket_list=bucket_list,
                                          ticket=ticket,
                                          cache=cache)
                if not ip_result['success']:
                    errors.append(ip_result['message'])
                else:
                    #add a relationship with the new IP address
                    new_ip = ip_result['object']
                    if new_domain and new_ip:
                        new_domain.add_relationship(new_ip,
                                                    'Resolved_To',
                                                    analyst=username,
                                                    get_rels=False)
                        new_domain.save(username=username)

            #set the URL for viewing the new data
            resp_url = reverse('crits.domains.views.domain_detail', args=[domain])

            if retVal['is_domain_new'] == True:
                retVal['message'] = ('Success! Click here to view the new domain: '
                                     '<a href="%s">%s</a>' % (resp_url, domain))
            else:
                message = ('Updated existing domain: <a href="%s">%s</a>' % (resp_url, domain))
                retVal['message'] = message
                retVal[form_consts.Status.STATUS_FIELD] = form_consts.Status.DUPLICATE
                retVal['warning'] = message

            #add indicators
            if data.get('add_indicators'):
                from crits.indicators.handlers import create_indicator_from_tlo
                # If we have an IP object, add an indicator for that.
                if ip_result.get('success'):
                    ip = ip_result['object']
                    result = create_indicator_from_tlo('IP',
                                                       ip,
                                                       username,
                                                       ip_source,
                                                       add_domain=False)
                    ip_ind = result.get('indicator')
                    if not result['success']:
                        errors.append(result['message'])

                # Add an indicator for the domain.
                result = create_indicator_from_tlo('Domain',
                                                   new_domain,
                                                   username,
                                                   source_name,
                                                   add_domain=False)

                if not result['success']:
                    errors.append(result['message'])
                elif ip_result.get('success') and ip_ind:
                    forge_relationship(left_class=result['indicator'],
                                       right_class=ip_ind,
                                       rel_type='Resolved_To',
                                       analyst=username)
            result = True

    # This block validates, and may also add, objects to the Domain
    if retVal.get('success') or is_validate_only == True:
        if rowData:
            objectsData = rowData.get(form_consts.Common.OBJECTS_DATA)

            # add new objects if they exist
            if objectsData:
                objectsData = json.loads(objectsData)
                current_domain = retrieve_domain(domain, cache)
                for object_row_counter, objectData in enumerate(objectsData, 1):
                    if current_domain != None:
                        # if the domain exists then try to add objects to it
                        if isinstance(current_domain, Domain) == True:
                            objectDict = object_array_to_dict(objectData,
                                                              "Domain",
                                                              current_domain.id)
                        else:
                            objectDict = object_array_to_dict(objectData,
                                                              "Domain",
                                                              "")
                            current_domain = None;
                    else:
                        objectDict = object_array_to_dict(objectData,
                                                          "Domain",
                                                          "")

                    (obj_result,
                     errors,
                     obj_retVal) = validate_and_add_new_handler_object(
                        None, objectDict, request, errors, object_row_counter,
                        is_validate_only=is_validate_only,
                        cache=cache, obj=current_domain)
                    if not obj_result:
                        retVal['success'] = False

    return result, errors, retVal
Example #5
0
def add_new_ip(data, rowData, request, errors, is_validate_only=False, cache={}):
    """
    Add a new IP to CRITs.

    :param data: Data for the IP address.
    :type data: dict
    :param rowData: Extra data from rows used by mass object uploader.
    :type rowData: dict
    :param request: The request for adding this IP.
    :type request: :class:`django.http.HttpRequest`
    :param errors: A list of current errors prior to processing this IP.
    :type errors: list
    :param is_validate_only: Whether or not we should validate or add.
    :type is_validate_only: bool
    :param cache: Cached data, typically for performance enhancements
                  during bulk operations.
    :type cache: dict
    :returns: tuple with (<result>, <errors>, <retval>)
    """

    result = False
    retVal = {}

    ip = data.get('ip')
    ip_type = data.get('ip_type')
    analyst = data.get('analyst')
    campaign = data.get('campaign')
    confidence = data.get('confidence')
    source = data.get('source')
    source_reference = data.get('source_reference')
    is_add_indicator = data.get('add_indicator')
    bucket_list = data.get(form_consts.Common.BUCKET_LIST_VARIABLE_NAME)
    ticket = data.get(form_consts.Common.TICKET_VARIABLE_NAME)
    indicator_reference = data.get('indicator_reference')

    retVal = ip_add_update(ip, ip_type,
            source=source,
            source_reference=source_reference,
            campaign=campaign,
            confidence=confidence,
            analyst=analyst,
            is_add_indicator=is_add_indicator,
            indicator_reference=indicator_reference,
            bucket_list=bucket_list,
            ticket=ticket,
            is_validate_only=is_validate_only,
            cache=cache)

    # This block tries to add objects to the item
    if retVal['success'] == True or is_validate_only == True:
        result = True

        objectsData = rowData.get(form_consts.Common.OBJECTS_DATA)

        # add new objects if they exist
        if objectsData:
            objectsData = json.loads(objectsData)
            object_row_counter = 1

            for objectData in objectsData:
                new_ip = retVal.get('object')

                if new_ip != None and is_validate_only == False:
                    objectDict = object_array_to_dict(objectData, "IP", new_ip.id)
                else:
                    if new_ip != None:
                        if new_ip.id:
                            objectDict = object_array_to_dict(objectData, "IP", new_ip.id)
                        else:
                            objectDict = object_array_to_dict(objectData, "IP", "")
                    else:
                        objectDict = object_array_to_dict(objectData, "IP", "")

                (object_result, object_errors, object_retVal) = validate_and_add_new_handler_object(
                        None, objectDict, request, errors, object_row_counter,
                        is_validate_only=is_validate_only, cache=cache)

                if object_retVal.get('success') == False:
                    retVal['success'] = False
                if object_retVal.get('message'):
                    errors.append(object_retVal['message'])

                object_row_counter += 1
    else:
        errors += "Failed to add IP: " + str(ip)

    return result, errors, retVal
Example #6
0
def add_new_domain(data, request, errors, rowData=None, is_validate_only=False, cache={}):
    """
    Add a new domain to CRITs.

    :param data: The data about the domain.
    :type data: dict
    :param request: The Django request.
    :type request: :class:`django.http.HttpRequest`
    :param errors: A list of current errors to append to.
    :type errors: list
    :param rowData: Any objects that need to be added to the domain.
    :type rowData: dict
    :param is_validate_only: Only validate the data and return any errors.
    :type is_validate_only: boolean
    :param cache: Cached data, typically for performance enhancements
                  during bulk uperations.
    :type cache: dict
    :returns: tuple
    """

    username = request.user.username
    result = False
    retVal = {}
    reference = data.get('domain_reference')
    name = data.get('domain_source')
    method = data.get('domain_method')
    source = [create_embedded_source(name, reference=reference, method=method,
                                     analyst=username)]
    bucket_list = data.get(form_consts.Common.BUCKET_LIST_VARIABLE_NAME)
    ticket = data.get(form_consts.Common.TICKET_VARIABLE_NAME)

    if data.get('campaign') and data.get('confidence'):
        campaign = [EmbeddedCampaign(name=data.get('campaign'),
                                     confidence=data.get('confidence'),
                                     analyst=username)]
    else:
        campaign = []

    (sdomain, fqdn) = get_domain(data['domain'])
    if sdomain == "no_tld_found_error":
        errors.append(u"Error: Invalid domain: " + data['domain'])
    elif is_validate_only == False:
        retVal = upsert_domain(sdomain, fqdn, source, username, campaign,
                               bucket_list=bucket_list, ticket=ticket, cache=cache)
        ip_result = None

        if retVal['success']:
            add_ip = data.get('add_ip')
            if add_ip:
                ip = data.get('ip')
                if data.get('same_source'):
                    ip_source = data.get('domain_source')
                    ip_method = data.get('domain_method')
                    ip_reference = reference
                else:
                    ip_source = data.get('ip_source')
                    ip_method = data.get('ip_method')
                    ip_reference = data.get('ip_reference')
                from crits.ips.handlers import ip_add_update
                ip_result = ip_add_update(ip,
                                          None,
                                          ip_source,
                                          ip_method,
                                          ip_reference,
                                          campaign=campaign,
                                          analyst=username,
                                          bucket_list=bucket_list,
                                          ticket=ticket,
                                          cache=cache)
                if not ip_result['success']:
                    errors.append(ip_result['message'])
                else:
                    #add a relationship with the new IP address
                    new_domain = retVal['object']
                    new_ip = ip_result['object']
                    if new_domain and new_ip:
                        new_domain.add_relationship(rel_item=new_ip,
                                                    rel_type='Resolved_To',
                                                    analyst=username,
                                                    get_rels=False)
                        new_domain.save(username=username)
                        new_ip.save(username=username)

            #set the URL for viewing the new data
            resp_url = reverse('crits.domains.views.domain_detail', args=[fqdn])

            if retVal['is_domain_new'] == True:
                retVal['message'] = ('Success! Click here to view the new domain: '
                                     '<a href="%s">%s</a>' % (resp_url, fqdn))
            else:
                message = ('Updated existing domain: <a href="%s">%s</a>' % (resp_url, fqdn))
                retVal['message'] = message
                retVal[form_consts.Status.STATUS_FIELD] = form_consts.Status.DUPLICATE
                retVal['warning'] = message

            #add indicators
            # add_indicators_for_domain handles adding relationships as well
            if data.get('add_indicators'):
                analyst = username
                from crits.indicators.handlers import add_indicators_for_domain
                if ip_result and ip_result['success']:
                    obj = ip_result['object']
                    errors += add_indicators_for_domain(sdomain,
                                                        fqdn,
                                                        source,
                                                        analyst,
                                                        reference,
                                                        obj,
                                                        bucket_list=bucket_list,
                                                        ticket=ticket)['errors']
                else:
                    errors += add_indicators_for_domain(sdomain,
                                                        fqdn,
                                                        source,
                                                        analyst,
                                                        reference,
                                                        bucket_list=bucket_list,
                                                        ticket=ticket)['errors']
            result = True

        elif 'message' in retVal: #database error? (!c_dom)
            errors.append(retVal['message']) #u"Unknown error: unable to add domain")

    elif is_validate_only == True:
        domain = data['domain']
        fqdn_domain = retrieve_domain(domain, cache);

        if fqdn_domain:
            if isinstance(fqdn_domain, Domain):
                resp_url = reverse('crits.domains.views.domain_detail', args=[fqdn])
                message = ('Warning: Domain already exists: '
                                     '<a href="%s">%s</a>' % (resp_url, fqdn))
                retVal['message'] = message;
                retVal['status'] = form_consts.Status.DUPLICATE;
                retVal['warning'] = message;
        else:
            result_cache = cache.get(form_consts.Domain.CACHED_RESULTS);
            result_cache[domain.lower()] = True;

    # This block tries to add objects to the item
    if retVal.get('success') or is_validate_only == True:
        if rowData:
            objectsData = rowData.get(form_consts.Common.OBJECTS_DATA)

            # add new objects if they exist
            if objectsData:
                objectsData = json.loads(objectsData)
                object_row_counter = 1
                current_domain = retrieve_domain(fqdn, cache)
                for objectData in objectsData:
                    if current_domain != None:
                        # if the domain exists then try to add objects to it
                        if isinstance(current_domain, Domain) == True:
                            objectDict = object_array_to_dict(objectData, "Domain", current_domain.id)
                        else:
                            objectDict = object_array_to_dict(objectData, "Domain", "")
                            current_domain = None;
                    else:
                        objectDict = object_array_to_dict(objectData, "Domain", "")

                    (object_result, object_errors, object_retVal) = validate_and_add_new_handler_object(
                            None, objectDict, request, errors, object_row_counter,
                            is_validate_only=is_validate_only,
                            cache=cache, obj=current_domain)

                    if object_retVal.get('success') == False:
                        retVal['success'] = False
                    if object_retVal.get('message'):
                        errors.append(object_retVal['message'])

                    object_row_counter += 1

    return result, errors, retVal