示例#1
0
def get_virus_record_by_id(session, vid):
    try:
        q = session.query(VirusFile).filter(VirusFile.vid == vid)
        return q.first()
    except Exception as e:
        logger.warning('Failed to get virus record by id: %s.', e)
        return None
示例#2
0
 def add_virus_record(self, records):
     try:
         self.edb_session.add_all(VirusFile(repo_id, commit_id, file_path, 0) \
                                  for repo_id, commit_id, file_path in records)
         self.edb_session.commit()
         self.edb_session.remove()
         return 0
     except Exception as e:
         logger.warning('Failed to add virus records to db: %s.', e)
         return -1
示例#3
0
def handle_virus_record(session, vid):
    try:
        q = session.query(VirusFile).filter(VirusFile.vid == vid)
        r = q.first()
        r.has_handle = 1
        session.commit()
        return 0
    except Exception as e:
        logger.warning('Failed to handle virus record: %s.', e)
        return -1
示例#4
0
 def run(self):
     while True:
         try:
             task = self.task_queue.get()
             if task is None:
                 break
             self.do_work(task)
         except Exception as e:
             logger.warning('Failed to execute task: %s' % e)
         finally:
             self.task_queue.task_done()
示例#5
0
    def update_vscan_record(self, repo_id, scan_commit_id):
        try:
            q = self.edb_session.query(VirusScanRecord).filter(
                VirusScanRecord.repo_id == repo_id)
            r = q.first()
            if not r:
                vrecord = VirusScanRecord(repo_id, scan_commit_id)
                self.edb_session.add(vrecord)
            else:
                r.scan_commit_id = scan_commit_id

            self.edb_session.commit()
            self.edb_session.remove()
        except Exception as e:
            logger.warning('Failed to update virus scan record from db: %s.',
                           e)
示例#6
0
    def get_repo_list(self):
        repo_list = []
        try:
            self.sdb_cursor.execute(
                'select r.repo_id, b.commit_id from Repo r, Branch b '
                'where r.repo_id = b.repo_id and b.name = "master" and '
                'r.repo_id not in (select repo_id from VirtualRepo)')
            rows = self.sdb_cursor.fetchall()
            for row in rows:
                repo_id, commit_id = row
                scan_commit_id = self.get_scan_commit_id(repo_id)
                repo_list.append((repo_id, commit_id, scan_commit_id))
        except Exception as e:
            logger.warning('Failed to fetch repo list from db: %s.', e)
            repo_list = None

        return repo_list
示例#7
0
def get_virus_record(session, repo_id, start, limit):
    if start < 0:
        logger.error('start must be non-negative')
        raise RuntimeError('start must be non-negative')

    if limit <= 0:
        logger.error('limit must be positive')
        raise RuntimeError('limit must be positive')

    try:
        q = session.query(VirusFile)
        if repo_id:
            q = q.filter(VirusFile.repo_id == repo_id)
        q = q.slice(start, start + limit)
        return q.all()
    except Exception as e:
        logger.warning('Failed to get virus record from db: %s.', e)
        return None
示例#8
0
    def scan_file_virus(self, repo_id, file_id, file_path):
        try:
            tfd, tpath = tempfile.mkstemp()
            seafile = fs_mgr.load_seafile(repo_id, 1, file_id)
            for blk_id in seafile.blocks:
                os.write(tfd, block_mgr.load_block(repo_id, 1, blk_id))

            with open(os.devnull, 'w') as devnull:
                ret_code = subprocess.call([self.settings.scan_cmd, tpath],
                                           stdout=devnull,
                                           stderr=devnull)

            return self.parse_scan_result(ret_code)

        except Exception as e:
            logger.warning('Virus scan for file %s encounter error: %s.',
                           file_path, e)
            return -1
        finally:
            if tfd > 0:
                os.close(tfd)
                os.unlink(tpath)
示例#9
0
    def scan_virus(self, scan_task):
        try:
            sroot_id = None
            hroot_id = None

            if scan_task.scan_commit_id:
                sroot_id = commit_mgr.get_commit_root_id(
                    scan_task.repo_id, 1, scan_task.scan_commit_id)
            if scan_task.head_commit_id:
                hroot_id = commit_mgr.get_commit_root_id(
                    scan_task.repo_id, 1, scan_task.head_commit_id)

            differ = CommitDiffer(scan_task.repo_id, 1, sroot_id, hroot_id)
            scan_files = differ.diff()

            if len(scan_files) == 0:
                logger.debug('No change occur for repo %.8s, skip virus scan.',
                             scan_task.repo_id)
                self.db_oper.update_vscan_record(scan_task.repo_id,
                                                 scan_task.head_commit_id)
                return
            else:
                logger.info('Start to scan virus for repo %.8s.',
                            scan_task.repo_id)

            vnum = 0
            nvnum = 0
            nfailed = 0
            vrecords = []

            for scan_file in scan_files:
                fpath, fid, fsize = scan_file
                if not self.should_scan_file(fpath, fsize):
                    continue

                ret = self.scan_file_virus(scan_task.repo_id, fid, fpath)

                if ret == 0:
                    logger.debug('File %s virus scan by %s: OK.', fpath,
                                 self.settings.scan_cmd)
                    nvnum += 1
                elif ret == 1:
                    logger.info('File %s virus scan by %s: Found virus.',
                                fpath, self.settings.scan_cmd)
                    vnum += 1
                    fpath = fpath if isinstance(
                        fpath, unicode) else fpath.decode('utf-8')
                    vrecords.append(
                        (scan_task.repo_id, scan_task.head_commit_id, fpath))
                else:
                    logger.debug('File %s virus scan by %s: Failed.', fpath,
                                 self.settings.scan_cmd)
                    nfailed += 1

            if nfailed == 0:
                ret = 0
                if len(vrecords) > 0:
                    ret = self.db_oper.add_virus_record(vrecords)
                    if ret == 0 and self.settings.enable_send_mail:
                        self.send_email(vrecords)
                if ret == 0:
                    self.db_oper.update_vscan_record(scan_task.repo_id,
                                                     scan_task.head_commit_id)

            logger.info(
                'Virus scan for repo %.8s finished: %d virus, %d non virus, %d failed.',
                scan_task.repo_id, vnum, nvnum, nfailed)

        except Exception as e:
            logger.warning('Failed to scan virus for repo %.8s: %s.',
                           scan_task.repo_id, e)