''' Filesystem scanners for sagator. (c) 2003-2016,2019 Jan ONDREJ (SAL) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. ''' from avlib import * __all__=['filesys'] class filesys(ascanner): ''' Scanner which uses filesystem scanners. Usage: filesys(prefix='/tmp/fs', logfile='', regexp='') Where: '/prefix' is a string, which defines directory and a part of filename to store scanned files, by default '/tmp/fs' 'logfile' is a string, which defines full path and filename of logfile, by default not logfile used 'regexp' is a string, which defines how to parse logfile New in version 0.7.0. ''' name = 'filesys()' req_lines = 1 ignored_virnames = [] virname_to_return_value = {} def __init__(self, prefix='/tmp/fs', logfile='', regexp=''): self.prefix = prefix self.logfile = logfile self.reg = re.compile(regexp,re.IGNORECASE) self.hdr = fromhdr() def scanbuffer(self, buffer, args={}): level = 0.0 detected = b'' virlist = [] # save email t = mktemp(self.prefix, '.eml', 'w', 0o600).autorm() # open logfile log = None if self.logfile: try: log = open(self.logfile, 'r') log.seek(0, 2) # end of file except IOError: pass try: os.write(t.fd, self.hdr+buffer) t.f.close() ts = os.open(t.root_name, os.O_RDONLY) # OSError 13 raised when virus found if os.fstat(ts)[6]!=len(self.hdr+buffer): level,detected,virlist = self.get_vir_info( log, (t.root_name, t.name), 13, 'File truncated %d:%d' % (os.fstat(ts)[6], len(self.hdr+buffer))) os.close(ts) except OSError as err: (ec,es) = err.args if ec==13: # permission denied level,detected,virlist = self.get_vir_info( log,(t.root_name,t.name),ec,es) else: debug.traceback(9, 'filesys(): ') raise # close log if log: log.close() return level,detected,virlist def scanfile(self, files, dirname='', args={}): # open logfile if self.logfile: log = open(self.logfile, 'r') log.seek(0, 2) # end of file else: log = None for fname in files: try: ts = safe.osopen(fname, os.O_RDONLY) os.close(ts) except OSError as err: (ec, es) = err.args if ec==13: # permission denied return self.get_vir_info(log, (safe.fn(fname), fname), ec, es) else: raise return 0.0, b'', [] def shortname(self, filename): return filename def get_vir_info(self, log, filenames, ec, es): level = 0.0 virlist = [] debug.echo(7, "%s: %s [%d]" % (self.name, es, ec)) if ec==13: detected, info = b'', '' level += 1.0 if log: req_lines = self.req_lines l = True timeout = time.time()+5 # 5 seconds timeout while (req_lines>0) and l: l = log.readline() # ignore EOF before timeout if not l and time.time()