Beispiel #1
0
def create_network_for_organization(name=None,
                                    address=None,
                                    mask_length=None,
                                    org_uuid=None):
    """
    Create and return a new Network object that's been associated with the given organization.
    :param name: The name to associate with the network.
    :param address: The address to associate with the network.
    :param mask_length: The mask length to associate with the network.
    :param org_uuid: The UUID of the organization to add the network to.
    :return: The newly-created Network.
    """
    if name is None:
        name = "Auto-gen Network %s" % (
            RandomHelper.get_random_token_of_length(10))
    cidr_wrapper = CidrRangeWrapper.from_cidr_range(address=address,
                                                    mask_length=mask_length)
    address = ConversionHelper.ipv4_to_class_c_prefix(address)
    return Network.new(
        name=name,
        address=address,
        mask_length=mask_length,
        organization_id=org_uuid,
        scanning_enabled=True,
        added_by="ws",
        endpoint_count=pow(2, 32 - mask_length),
        cidr_range=cidr_wrapper.parsed_cidr_range,
        times_scanned=0,
    )
Beispiel #2
0
 def perform_create(self, serializer):
     """
     Handle the creation of a Network for the referenced organization. There is some complicated logic
     here as Web Sight creates networks for organizations, and those networks are not visible by
     end users. The logic here is to check to see if one of the networks added by Web Sight matches
     the network added here, and if so to update that network instead of creating a new one.
     :param serializer: The serializer to save the new network from.
     :return: None
     """
     if not self.request.user.is_superuser and not self.parent_object.can_user_write(
             self.request.user):
         raise PermissionDenied(
             "You do not have permission to modify data associated with that organization."
         )
     cidr_wrapper = CidrRangeWrapper.from_cidr_range(
         address=serializer.validated_data["address"],
         mask_length=serializer.validated_data["mask_length"],
     )
     try:
         existing_network = self.parent_object.networks.get(
             address=cidr_wrapper.parsed_address,
             mask_length=cidr_wrapper.mask_length,
         )
         existing_network.added_by = "user"
         existing_network.name = serializer.validated_data["name"]
         existing_network.save()
     except ObjectDoesNotExist:
         serializer.save()
Beispiel #3
0
 def save(self, *args, **kwargs):
     from lib.parsing import CidrRangeWrapper
     self.endpoint_count = pow(2, 32 - self.mask_length)
     cidr_wrapper = CidrRangeWrapper.from_cidr_range(
         address=self.address, mask_length=self.mask_length)
     self.cidr_range = cidr_wrapper.parsed_cidr_range
     self.address = cidr_wrapper.parsed_address
     return super(Network, self).save(*args, **kwargs)
def get_network_by_range_for_organization(db_session=None,
                                          address=None,
                                          mask_length=None,
                                          org_uuid=None):
    """
    Get a network associated with the given IP address and mask length from the given organization.
    :param db_session: A SQLAlchemy session to use to query a database.
    :param address: The IP address for the network.
    :param mask_length: The mask length for the network.
    :param org_uuid: The UUID of the organization for the network.
    :return: The network associated with the given organization matching the given address
    and mask length.
    """
    cidr_wrapper = CidrRangeWrapper.from_cidr_range(address=address,
                                                    mask_length=mask_length)
    address = cidr_wrapper.parsed_address
    return db_session.query(Network)\
        .filter(Network.address == address)\
        .filter(Network.mask_length == mask_length)\
        .filter(Network.organization_id == org_uuid)\
        .one()
Beispiel #5
0
def quick_scan_organization(request, pk=None):
    """
    Perform a quick scan of the given organization based on the contents of the request submitted
    to the endpoint.
    :param request: The request received by this API handler.
    :param pk: The primary key of the organization to start a scan for.
    :return: A response containing [WHAT].
    """

    # Get the organization

    organization = get_object_or_404(Organization, pk=pk)

    # Make sure the requesting user has permission to scan for the organization

    if not request.user.is_superuser:
        if not organization.can_user_scan(request.user):
            raise PermissionDenied(
                "You do not have permission to initiate scans for that organization."
            )

    # Validate the request data

    serializer = rest.serializers.OrganizationQuickScanSerializer(
        data=request.data)
    serializer.is_valid(raise_exception=True)

    # Retrieve the ScanConfig to associate with the order

    scan_config_uuid = serializer.validated_data.get("scan_config_uuid", None)
    scan_config_data = serializer.validated_data.get("scan_config", None)
    if scan_config_uuid:
        try:
            existing_scan_config = rest.models.ScanConfig.objects.get_config_for_user(
                user=request.user,
                config_uuid=scan_config_uuid,
            )
            scan_config = existing_scan_config.duplicate()
        except rest.models.ScanConfig.DoesNotExist:
            raise NotFound("No scanning configuration found for ID %s." %
                           scan_config_uuid)
    elif scan_config_data:
        scan_config_serializer = rest.serializers.ScanConfigChildrenSerializer(
            data=scan_config_data)
        scan_config_serializer.is_valid(raise_exception=True)
        scan_config = scan_config_serializer.save()
    else:
        scan_config = organization.scan_config.duplicate()

    # Create the targets for the order based on the contents of the targets data

    skipped_targets = []
    new_models = []
    domains = []
    networks = []
    new_order = rest.models.Order.objects.create(
        organization=organization,
        user_email=request.user.email,
        user=request.user,
        scan_config=scan_config,
    )
    for target in serializer.validated_data["targets"]:
        target = target.strip()
        if RegexLib.domain_name_regex.match(target):
            try:
                org_domain = organization.domain_names.get(name=target)
            except rest.models.DomainName.DoesNotExist:
                org_domain = organization.domain_names.create(
                    name=target, added_by="quickscan")
                new_models.append(org_domain)
            new_order.domain_names.create(domain_name=org_domain)
            domains.append(target)
        elif RegexLib.ipv4_cidr_regex.match(target):
            cidr_wrapper = CidrRangeWrapper(target)
            try:
                org_network = organization.networks.get(
                    address=cidr_wrapper.parsed_address,
                    mask_length=cidr_wrapper.mask_length,
                )
            except rest.models.Network.DoesNotExist:
                org_network = organization.networks.create(
                    address=cidr_wrapper.parsed_address,
                    mask_length=cidr_wrapper.mask_length,
                    added_by="quickscan",
                )
                new_models.append(org_network)
            new_order.networks.create(network=org_network)
            networks.append(target)
        elif RegexLib.ipv4_address_regex.match(target):
            try:
                org_network = organization.networks.get(address=target,
                                                        mask_length=32)
            except rest.models.Network.DoesNotExist:
                org_network = organization.networks.create(
                    address=target,
                    mask_length=32,
                    added_by="quickscan",
                )
                new_models.append(org_network)
            new_order.networks.create(network=org_network)
            networks.append("%s/32" % (target, ))
        else:
            skipped_targets.append(target)

    # Override the ScanConfig completion callbacks as necessary

    if "completion_web_hook_url" in serializer.validated_data:
        scan_config.completion_web_hook_url = serializer.validated_data[
            "completion_web_hook_url"]
    if "completion_email_org_users" in serializer.validated_data:
        scan_config.completion_email_org_users = serializer.validated_data[
            "completion_email_org_users"]
    if "completion_email_order_user" in serializer.validated_data:
        scan_config.completion_email_order_user = serializer.validated_data[
            "completion_email_order_user"]

    # Check to make sure that the order has at least one valid target and back out as needed

    targets_count = new_order.domain_names.count() + new_order.networks.count()
    if targets_count == 0:
        scan_config.delete()
        for new_model in new_models:
            new_model.delete()
        new_order.delete()
        return WsQuickScanResponse(
            was_successful=False,
            skipped=skipped_targets,
            description="No valid targets were provided in your request.",
        )

    # Ensure the models are saved and initiate the scan

    scan_config.save()
    new_order.place_order(update_monitored=False)
    new_order.save()
    send_emails_for_placed_order.delay(
        order_uuid=unicode(new_order.uuid),
        receipt_description=new_order.get_receipt_description(),
    )
    handle_placed_order.delay(order_uuid=unicode(new_order.uuid))

    # Return the successful response

    return WsQuickScanResponse(
        order_uuid=str(new_order.uuid),
        was_successful=True,
        domains=domains,
        networks=networks,
        skipped=skipped_targets,
        description="A scan was successfully started for %s targets." %
        (len(domains) + len(networks), ))