Exemple #1
0
    async def get_file(self, srcode, file, session=None, raw=None):
        """ Get file details in a scan identified by srcode

        :param srcode: scan retrieval code value
        :param file: file or file id
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the file associated with the srcode and file

        """
        route = "/scan_retrieval_codes/{}/files_ext/{}".format(
                apiid(srcode),
                apiid(file))
        res = await self._get(route, session)
        return self._format(res, raw, schema=FileExtSchema.dynschema)
Exemple #2
0
    async def search(
            self, query=None, offset=None, limit=None, session=None, raw=None):
        """ List a page of matching results of a query on files

        :param query: parameters of the query. It must only contains the keys
            'name', 'hash' an 'tags' (default None ie. no filter)
        :param offset: offset for pagination (default None)
        :param limit: custom limit for pagination (default None)
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the queried page of the list of files
        :raises: IrmaError

        """
        if query and isinstance(query.get("tags"), list):
            query["tags"] = ','.join(str(apiid(i)) for i in query["tags"])
        query = self._askpage(offset, limit, query)
        try:
            res = await self._get("/files", session, query)
            schema = Paginated(
                    FileExtSchema,
                    exclude=('probe_results',)
                )(exclude=('data',))
            return self._format(res, raw, schema=schema)
        except aiohttp.ClientResponseError as e:
            logger.warning(e)
            raise IrmaError("Bad resquest")
Exemple #3
0
    async def cancel(self, scan, session=None, raw=None):
        """ Cancel a running scan

        :param scan: uuid or scan to cancel
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the canceled scan
        :raises: aiohttp.ClientResponseError
        :raises: IrmaError if the scan is already finished

        """
        route = "/scans/{}/cancel".format(apiid(scan))
        try:
            res = await self._post(route, session)
            return self._format(res, raw, schema=ScanSchema())
        except aiohttp.ClientResponseError as e:
            if e.status == 400:
                raise IrmaError(
                    "Scan {} finished, cannot cancel it".format(apiid(scan)))
            raise
Exemple #4
0
    async def get(self, srcode, session=None, raw=None):
        """ Get a scan by srcode

        :param srcode: scan retrieval code value
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the scan associated with the srcode

        """
        route = "/scan_retrieval_codes/{}".format(apiid(srcode))
        res = await self._get(route, session)
        return self._format(res, raw, schema=SRScanSchema())
Exemple #5
0
    async def new(self, scan, session=None, raw=None):
        """ Create a new scan retrieval code

        :param scan: scan or scan id
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: a newly created srcode

        """
        data = {"scan_id": apiid(scan)}
        res = await self._post("/scan_retrieval_codes", session, data=data)
        return self._format(res, raw, schema=ScanRetrievalCodeSchema())
Exemple #6
0
    async def remove_tag(
            self, file, tag, quiet=False, session=None):
        """ Remove a tag from a file

        :param file: file or sha256 to remove the tag from
        :param tag: tag or id to remove
        :param quiet: bool, do not raise an exception if the file is not
            tagged with this tag (default False)
        :param session: custom session to use (default None)
        :raises: aiohttp.ClientResponseError
        :raises: IrmaError when tag cant be removed

        """
        route = "/files/{}/tags/{}/remove".format(apiid(file), apiid(tag))
        try:
            await self._get(route, session)
        except aiohttp.ClientResponseError as e:
            logger.warning(e)
            if not (quiet and e.status == 400):
                raise IrmaError("File {} is already NOT tagged with tag {}."
                                .format(file, tag))
Exemple #7
0
    async def get(self, scan, session=None, raw=None):
        """ Query a scan

        :param scan: uuid or scan to query
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the queried scan
        :raises: aiohttp.ClientResponseError

        """
        route = "/scans/{}".format(apiid(scan))
        res = await self._get(route, session)
        return self._format(res, raw, schema=ScanSchema())
Exemple #8
0
    async def download(
            self, file, dstpath, session=None):
        """ Download a file from the API

        :param file: file or sha256 to download
        :param dstpath: path to write the downloaded file on
        :param session: custom session to use (default None)
        :raises: aiohttp.ClientResponseError

        """
        route = '/files/{}/download'.format(apiid(file))
        with dstpath.open('wb') as fd:
            await self._get(route, session, stream=fd)
Exemple #9
0
    async def add_tag(
            self, file, tag, quiet=False, session=None):
        """ Add a tag to a file

        :param file: file or sha256 to add the tag to
        :param tag: tag or id to add
        :param quiet: bool, do not raise an exception if the file is
            already tagged with this tag (default False)
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :raises: aiohttp.ClientResponseError
        :raises: IrmaError when tag is already present

        """
        route = "/files/{}/tags/{}/add".format(apiid(file), apiid(tag))
        try:
            await self._get(route, session)
        except aiohttp.ClientResponseError as e:
            logger.warning(e)
            if not (quiet and e.status == 400):
                raise IrmaError("File {} is already tagged with tag {}."
                                .format(file, tag))
Exemple #10
0
    async def download_file(
            self, srcode, file, dstpath, session=None):
        """ Download a file from the API

        :param srcode: scan retrieval code value
        :param file: file id to download
        :param dstpath: path to write the downloaded file on
        :param session: custom session to use (default None)
        :raises: aiohttp.ClientResponseError
        :raises: IrmaError on wrong srcode, scan not finished or file
        potentially harmful

        """
        try:
            route = '/scan_retrieval_codes/{}/files_ext/{}/download'.format(
                    apiid(srcode),
                    apiid(file))
            with dstpath.open('wb') as fd:
                await self._get(route, session, stream=fd)
        except aiohttp.ClientResponseError as e:
            logger.warning(e)
            if e.status == 403:
                raise IrmaError("Download forbidden")
Exemple #11
0
    async def result(self, fileext, full=False, session=None, raw=None):
        """ Get detailed results on a specific scanned file

        :param fileext: fileext or uuid to get results of
        :param full: bool, get full results or shortened ones (default False)
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the detailed results

        """
        route = "/files_ext/{}".format(apiid(fileext))
        query = {"formatted": "no"} if full else {}
        res = await self._get(route, session, query)
        return self._format(res, raw, schema=FileExtSchema.dynschema)
Exemple #12
0
    async def results(
            self, file, offset=None, limit=None, session=None, raw=None):
        """ List a page of the results associated to file

        :param file: file or sha256
        :param offset: offset for pagination (default None)
        :param limit: custom limit for pagination (default None)
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :returns: the queried page of the list of results
        :raises: aiohttp.ClientResponseError

        """
        route = "/files/{}".format(apiid(file))
        query = self._askpage(offset, limit)
        res = await self._get(route, session, query)
        return self._format(res, raw, schema=FileResultSchema())
Exemple #13
0
    async def launch(
            self, fileexts, session=None, raw=None, linger=False, *,
            probes=None, force=None, mimetype_filtering=None,
            resubmit_files=None):
        """ Create and launch a scan on already uploaded files

        :param fileexts: list of fileexts or uuids to enclose
        :param session: custom session to use (default None)
        :param raw: bool, return unprocessed bytes (default None)
        :param linger: bool, wait for the scan to complete (default False)
        :param probes: probes to run on (default None ie. all)
        :param force, mimetype_filtering, resubmit_files: scan options (default
            None)
        :returns: a newly created scan
        :raises: aiohttp.ClientResponseError

        """
        options = {}
        if force is not None:
            options['force'] = force
        if probes is not None:
            options['probes'] = probes
        if resubmit_files is not None:
            options['resubmit_files'] = resubmit_files
        if mimetype_filtering is not None:
            options['mimetype_filtering'] = mimetype_filtering

        data = {
            "files": [apiid(fe) for fe in fileexts],
            "options": options,
        }
        res = await self._post("/scans", session, json=data)
        if linger:
            scan = self._format(res, raw=False, schema=ScanSchema())
            return await self.waitfor(scan, session, raw)
        else:
            return self._format(res, raw, schema=ScanSchema())