Example #1
0
    def handle_start_scan_command(self, scan_et):
        """ Handles <start_scan> command.

        @return: Response string for <start_scan> command.
        """

        target_str = scan_et.attrib.get('target')
        if target_str is None:
            raise OSPDError('No target attribute', 'start_scan')
        ports_str = scan_et.attrib.get('ports')
        if ports_str is None:
            raise OSPDError('No ports attribute', 'start_scan')
        scan_id = scan_et.attrib.get('scan_id')
        if scan_id is not None and scan_id != '' and not valid_uuid(scan_id):
            raise OSPDError('Invalid scan_id UUID', 'start_scan')

        scanner_params = scan_et.find('scanner_params')
        if scanner_params is None:
            raise OSPDError('No scanner_params element', 'start_scan')

        params = self._preprocess_scan_params(scanner_params)

        # Dry run case.
        if 'dry_run' in params and int(params['dry_run']):
            scan_func = self.dry_run_scan
            scan_params = None
        else:
            scan_func = self.start_scan
            scan_params = self.process_scan_params(params)

        scan_id = self.create_scan(scan_id, target_str, ports_str, scan_params)
        scan_process = multiprocessing.Process(target=scan_func,
                                               args=(scan_id, target_str))
        self.scan_processes[scan_id] = scan_process
        scan_process.start()
        id_ = ET.Element('id')
        id_.text = scan_id
        return simple_response_str('start_scan', 200, 'OK', id_)
Example #2
0
    def handle_xml(self, xml: Element) -> bytes:
        """Handles <start_scan> command.

        Return:
            Response string for <start_scan> command.
        """

        current_queued_scans = self._daemon.get_count_queued_scans()
        if (
            self._daemon.max_queued_scans
            and current_queued_scans >= self._daemon.max_queued_scans
        ):
            logger.info(
                'Maximum number of queued scans set to %d reached.',
                self._daemon.max_queued_scans,
            )
            raise OspdCommandError(
                'Maximum number of queued scans set to %d reached.'
                % self._daemon.max_queued_scans,
                'start_scan',
            )

        target_str = xml.get('target')
        ports_str = xml.get('ports')

        # For backward compatibility, if target and ports attributes are set,
        # <targets> element is ignored.
        if target_str is None or ports_str is None:
            target_element = xml.find('targets/target')
            if target_element is None:
                raise OspdCommandError('No targets or ports', 'start_scan')
            else:
                scan_target = OspRequest.process_target_element(target_element)
        else:
            scan_target = {
                'hosts': target_str,
                'ports': ports_str,
                'credentials': {},
                'exclude_hosts': '',
                'finished_hosts': '',
                'options': {},
            }
            logger.warning(
                "Legacy start scan command format is being used, which "
                "is deprecated since 20.08. Please read the documentation "
                "for start scan command."
            )

        scan_id = xml.get('scan_id')
        if scan_id is not None and scan_id != '' and not valid_uuid(scan_id):
            raise OspdCommandError('Invalid scan_id UUID', 'start_scan')

        if xml.get('parallel'):
            logger.warning(
                "parallel attribute of start_scan will be ignored, sice "
                "parallel scan is not supported by OSPd."
            )

        scanner_params = xml.find('scanner_params')
        if scanner_params is None:
            raise OspdCommandError('No scanner_params element', 'start_scan')

        # params are the parameters we got from the <scanner_params> XML.
        params = self._daemon.preprocess_scan_params(scanner_params)

        # VTS is an optional element. If present should not be empty.
        vt_selection = {}  # type: Dict
        scanner_vts = xml.find('vt_selection')
        if scanner_vts is not None:
            if len(scanner_vts) == 0:
                raise OspdCommandError('VTs list is empty', 'start_scan')
            else:
                vt_selection = OspRequest.process_vts_params(scanner_vts)

        scan_params = self._daemon.process_scan_params(params)
        scan_id_aux = scan_id
        scan_id = self._daemon.create_scan(
            scan_id, scan_target, scan_params, vt_selection
        )

        if not scan_id:
            id_ = Element('id')
            id_.text = scan_id_aux
            return simple_response_str('start_scan', 100, 'Continue', id_)

        logger.info(
            'Scan %s added to the queue in position %d.',
            scan_id,
            current_queued_scans + 1,
        )

        id_ = Element('id')
        id_.text = scan_id

        return simple_response_str('start_scan', 200, 'OK', id_)
Example #3
0
    def handle_xml(self, xml: Element) -> bytes:
        """ Handles <start_scan> command.

        Return:
            Response string for <start_scan> command.
        """

        target_str = xml.get('target')
        ports_str = xml.get('ports')

        # For backward compatibility, if target and ports attributes are set,
        # <targets> element is ignored.
        if target_str is None or ports_str is None:
            target_element = xml.find('targets/target')
            if target_element is None:
                raise OspdCommandError('No targets or ports', 'start_scan')
            else:
                scan_target = OspRequest.process_target_element(target_element)
        else:
            scan_target = {
                'hosts': target_str,
                'ports': ports_str,
                'credentials': {},
                'exclude_hosts': '',
                'finished_hosts': '',
                'options': {},
            }
            logger.warning(
                "Legacy start scan command format is beeing used, which "
                "is deprecated since 20.04. Please read the documentation "
                "for start scan command.")

        scan_id = xml.get('scan_id')
        if scan_id is not None and scan_id != '' and not valid_uuid(scan_id):
            raise OspdCommandError('Invalid scan_id UUID', 'start_scan')

        if xml.get('parallel'):
            logger.warning(
                "parallel attribute of start_scan will be ignored, sice "
                "parallel scan is not supported by OSPd.")

        scanner_params = xml.find('scanner_params')
        if scanner_params is None:
            raise OspdCommandError('No scanner_params element', 'start_scan')

        params = self._daemon.preprocess_scan_params(scanner_params)

        # VTS is an optional element. If present should not be empty.
        vt_selection = {}  # type: Dict
        scanner_vts = xml.find('vt_selection')
        if scanner_vts is not None:
            if len(scanner_vts) == 0:
                raise OspdCommandError('VTs list is empty', 'start_scan')
            else:
                vt_selection = OspRequest.process_vts_params(scanner_vts)

        # Dry run case.
        if 'dry_run' in params and int(params['dry_run']):
            scan_func = self._daemon.dry_run_scan
            scan_params = None
        else:
            scan_func = self._daemon.start_scan
            scan_params = self._daemon.process_scan_params(params)

        scan_id_aux = scan_id
        scan_id = self._daemon.create_scan(scan_id, scan_target, scan_params,
                                           vt_selection)

        if not scan_id:
            id_ = Element('id')
            id_.text = scan_id_aux
            return simple_response_str('start_scan', 100, 'Continue', id_)

        scan_process = create_process(func=scan_func,
                                      args=(scan_id, scan_target))

        self._daemon.scan_processes[scan_id] = scan_process

        scan_process.start()

        id_ = Element('id')
        id_.text = scan_id

        return simple_response_str('start_scan', 200, 'OK', id_)