''' libclamav - clamav pytohn module (c) 2003-2007 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. ''' cdef extern from "const_types.h": ctypedef char constchar cdef extern from "clamav.h": enum: CL_CLEAN CL_VIRUS CL_SUCCESS CL_BREAK CL_EMAXREC CL_EMAXSIZE CL_EMAXFILES #CL_ERAR CL_EZIP CL_EGZIP CL_EBZIP CL_EOLE2 CL_EMSCOMP CL_EMSCAB CL_EACCES CL_ENULLARG CL_ETMPFILE CL_EFSYNC CL_EMEM CL_EOPEN CL_EMALFDB CL_EPATSHORT CL_ETMPDIR CL_ECVD CL_ECVDEXTR CL_EMD5 CL_EDSIG CL_EIO CL_EFORMAT CL_ESUPPORT CL_ELOCKDB # db options CL_DB_PHISHING CL_DB_ACONLY CL_DB_PHISHING_URLS CL_DB_STDOPT # scan options CL_SCAN_RAW CL_SCAN_ARCHIVE CL_SCAN_MAIL CL_SCAN_OLE2 CL_SCAN_BLOCKENCRYPTED CL_SCAN_HTML CL_SCAN_PE CL_SCAN_BLOCKBROKEN CL_SCAN_MAILURL CL_SCAN_BLOCKMAX CL_SCAN_ALGORITHMIC CL_SCAN_PHISHING_DOMAINLIST CL_SCAN_PHISHING_BLOCKSSL CL_SCAN_PHISHING_BLOCKCLOAK CL_SCAN_ELF CL_SCAN_PDF CL_SCAN_STDOPT struct cl_limits: int maxreclevel int maxfiles int maxmailrec int maxratio short archivememlim long int maxfilesize struct cl_stat: char *dir int no char *stattab struct cl_engine int cl_load(char *path, cl_engine **engine, unsigned int *signo, unsigned int options) char *cl_retdbdir() int cl_build(cl_engine *engine) cl_engine *cl_dup(cl_engine *engine) void cl_free(cl_engine *engine) int cl_statinidir(char *dirname, cl_stat *dbstat) int cl_statchkdir(cl_stat *dbstat) int cl_statfree(cl_stat *dbstat) int cl_scandesc(int desc, constchar **virname, unsigned long int *scanned, cl_engine *engine, cl_limits *limits, int options) int cl_scanfile(char *filename, constchar **virname, unsigned long int *scanned, cl_engine *engine, cl_limits *limits, int options) int cl_retflevel() char *cl_retver() cl_settempdir(constchar *dir, short leavetemps) char *cl_strerror(int clerror) cdef extern from "string.h": cdef void *memset(void *s, int c, int n) class ClamAVError(Exception): '''ClamAVError''' pass CLEAN = CL_CLEAN VIRUS = CL_VIRUS SUCCESS = CL_SUCCESS BREAK = CL_BREAK EMAXREC = CL_EMAXREC EMAXSIZE = CL_EMAXSIZE EMAXFILES = CL_EMAXFILES #ERAR = CL_ERAR EZIP = CL_EZIP EGZIP = CL_EGZIP EBZIP = CL_EBZIP EOLE2 = CL_EOLE2 EMSCOMP = CL_EMSCOMP EMSCAB = CL_EMSCAB EACCES = CL_EACCES ENULLARG = CL_ENULLARG ETMPFILE = CL_ETMPFILE EFSYNC = CL_EFSYNC EMEM = CL_EMEM EOPEN = CL_EOPEN EMALFDB = CL_EMALFDB EPATSHORT = CL_EPATSHORT ETMPDIR = CL_ETMPDIR ECVD = CL_ECVD ECVDEXTR = CL_ECVDEXTR EMD5 = CL_EMD5 EDSIG = CL_EDSIG EIO = CL_EIO EFORMAT = CL_EFORMAT ESUPPORT = CL_ESUPPORT ELOCKDB = CL_ELOCKDB DB_PHISHING = CL_DB_PHISHING DB_PHISHING_URLS = CL_DB_PHISHING_URLS DB_ACONLY = CL_DB_ACONLY DB_STDOPT = CL_DB_STDOPT SCAN_RAW = CL_SCAN_RAW SCAN_ARCHIVE = CL_SCAN_ARCHIVE SCAN_MAIL = CL_SCAN_MAIL SCAN_OLE2 = CL_SCAN_OLE2 SCAN_BLOCKENCRYPTED = CL_SCAN_BLOCKENCRYPTED SCAN_HTML = CL_SCAN_HTML SCAN_PE = CL_SCAN_PE SCAN_BLOCKBROKEN = CL_SCAN_BLOCKBROKEN SCAN_MAILURL = CL_SCAN_MAILURL SCAN_BLOCKMAX = CL_SCAN_BLOCKMAX SCAN_ALGORITHMIC = CL_SCAN_ALGORITHMIC SCAN_PHISHING_DOMAINLIST = CL_SCAN_PHISHING_DOMAINLIST SCAN_PHISHING_BLOCKSSL = CL_SCAN_PHISHING_BLOCKSSL SCAN_PHISHING_BLOCKCLOAK = CL_SCAN_PHISHING_BLOCKCLOAK SCAN_ELF = CL_SCAN_ELF SCAN_PDF = CL_SCAN_PDF SCAN_STDOPT = CL_SCAN_STDOPT SCAN_DEFAULT = CL_SCAN_STDOPT # compatibility aliases CL_RAW = CL_SCAN_RAW CL_ARCHIVE = CL_SCAN_ARCHIVE CL_MAIL = CL_SCAN_MAIL CL_OLE2 = CL_SCAN_OLE2 CL_ENCRYPTED = 0 CL_DEFAULT = CL_SCAN_STDOPT cdef class clamav: cdef cl_engine *engine cdef readonly unsigned int virnum cdef char *virname cdef readonly status cdef unsigned long int size cdef cl_limits limits cdef cl_stat dbstat cdef unsigned int db_options cdef object dirname def __init__(self, db_options=CL_DB_STDOPT, dirname=None): self.virnum = 0 self.engine = NULL self.statinidir(dirname) self.load(db_options, dirname) memset(&self.limits, 0, sizeof(self.limits)) # zero limits self.limits.maxreclevel = 8 self.limits.maxmailrec = 64 self.limits.maxfilesize = 10485760 # 10 MB self.limits.maxfiles = 1024 self.limits.maxratio = 250 self.limits.archivememlim = 1 def __del__(self): self.statfree() self.free() def retver(self): return cl_retver() def free(self): cl_free(self.engine) self.engine = NULL self.virnum = 0 def load(self, db_options=CL_DB_STDOPT, dirname=None): self.db_options = db_options if dirname: self.status = cl_load(dirname, &self.engine, &self.virnum, db_options) else: self.status = cl_load(cl_retdbdir(), &self.engine, &self.virnum, db_options) self.checkstatus() if self.virnum==0: raise ClamAVError,'No signatures loaded!' self.status = cl_build(self.engine) self.checkstatus() def checkstatus(self,ret=None): if self.status in [CL_CLEAN,CL_VIRUS]: return ret else: raise ClamAVError,self.strerror() def scandesc(self,desc,options=SCAN_DEFAULT): self.size = 0 self.virname = '' self.status = cl_scandesc(desc,&self.virname,&self.size, self.engine,&self.limits,options) if self.virname==NULL: self.virname = "" return self.checkstatus(self.virname) def scanfile(self,filename,options=SCAN_DEFAULT): self.size = 0 self.virname = '' self.status = cl_scanfile(filename,&self.virname,&self.size, self.engine,&self.limits,options) if self.virname==NULL: self.virname = "" return self.checkstatus(self.virname) def statinidir(self,dirname=None): self.dirname = dirname memset(&self.dbstat, 0, sizeof(self.dbstat)) if dirname: self.status = cl_statinidir(dirname, &self.dbstat) else: self.status = cl_statinidir(cl_retdbdir(), &self.dbstat) self.checkstatus() def statchkdir(self): self.status = cl_statchkdir(&self.dbstat) return self.checkstatus(self.status) def statfree(self): self.status = cl_statfree(&self.dbstat) self.checkstatus() def strerror(self,clerror=None): if clerror==None: return cl_strerror(self.status) else: return cl_strerror(clerror) def reload(self,dirname=None): if dirname: self.dirname=dirname if self.statchkdir(): self.statfree() self.free() self.statinidir(self.dirname) self.load(self.db_options, self.dirname) return 1 else: return 0 def setlimits(self,args={}): for key,value in args.items(): if key=='maxreclevel': self.limits.maxreclevel = value elif key=='maxmailrec': self.limits.maxmailrec = value elif key=='maxfiles': self.limits.maxfiles = value elif key=='maxratio': self.limits.maxratio = value elif key=='archivememlim': self.limits.archivememlim = value elif key=='maxfilesize': self.limits.maxfilesize = value