''' ICAP module, version 0.2 (c) 2003-2018 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 * import socket, re __all__ = ['savse'] class icap: def __init__(self, host, port, path='AVSCAN?action=SCAN'): self.s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) socket_settimeout(self.s, 120) self.s.connect((host, port)) self.f = self.s.makefile('rw',0) self.server = host+":"+str(port) self.path = path def check(self, buffer, filename): level, virname, response = 0.0, b'', [] # send ICAP request self.s.sendall("RESPMOD icap://"+self.server+"/"+self.path+" ICAP/1.0\r\n") self.s.sendall("Host: "+self.server+"\r\n") self.s.sendall("Allow: 204\r\n") req = "GET http://sagator.salstar.sk/"+filename+" HTTP/1.1\r\n\r\n" hdr = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n" self.s.sendall("Encapsulated: req-hdr=0, res-hdr=%d, res-body=%d\r\n\r\n" % (len(req),len(req+hdr))) debug.echo(7, 'icap(): ', req, hdr) self.s.sendall(req) self.s.sendall(hdr) # send data buffer #i,l,s=0,len(buffer),0xFF #while True: # if (i+s)>=l: # self.s.sendall("%X\r\n" % (len(buffer[i:]))) # self.s.sendall(buffer[i:]) # self.s.sendall("\r\n\r\n0\r\n\r\n") # break # else: # self.s.sendall("%X\r\n" % s) # self.s.sendall(buffer[i:i+s]) # self.s.sendall("\r\n\r\n") # i+=s self.s.sendall("%X\r\n" % (len(buffer))) self.s.sendall(buffer) self.s.sendall("\r\n\r\n0\r\n\r\n") # read protocol status ics = self.f.readline() debug.echo(7, "savse():", ics) try: icc = re.search("^ICAP/[0-9.]* ([0-9]{3}) ", ics).group(1) except: icc = '000' if icc=='204': pass # it's clean elif (icc[:2]=='20'): # returned OK while 1: line=self.f.readline() if not line: break debug.echo(7, "savse():", line) reg = re.search("^X-Infection-Found: Type=([0-9]*); Resolution=([0-9]*); Threat=([^;]*);",line) if reg: if (reg.group(1)=='0'): virname += reg.group(3) level += 1.0 debug.echo(5, "savse(): found:", virname) else: reg1 = re.search("^X-Violations-Found:", line) if reg1: while 1: line=self.f.readline() if not line: break if (line[0]==' ') or (line[0]=='\t'): response.append(line) else: break else: raise Exception(ics) return level, virname, response def close(self): self.s.shutdown(socket.SHUT_RDWR) class savse(ascanner): ''' Symantec antivirus scan engine scanner. Usage: savse('host',port) Example: parsemail(savse('localhost',1344)) Comments: You need to configure ICAP protocol on port 1344 (or another) to use this scanner properly. These options are suggested in symcscan.cfg: BindAddress=127.0.0.1 Port=1344 Protocol=ICAP ExtensionPolicy=0 ICAPActionPolicy=SCAN ICAPResponse=1 ''' name='savse()' def __init__(self, host, port=1344): self.host = host self.port = port def scanbuffer(self, buffer, args={}): c=icap(self.host,self.port) level, r, response = c.check(buffer,self.filename) c.close() return level, r, response