''' Header interscanners for sagator, version 0.6.2 (c) 2003-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 __future__ import absolute_import from avlib import * import re from .match import match_any __all__ = ['add_header', 'modify_header', 'modify_subject', 'remove_headers'] class add_header(match_any): ''' Add email headers. This scanner can be used to add an header line to email. Usage: add_header('Header_name','header_data',scanners) or: add_header(...).onlyif('virname') Where: 'Header_name' is a string, which defines name of the header 'header_data' is a string, which defines header's content 'virname' is a string, which defines any virus name. By default all virus names at least 1 character long: '.' There are some special pattern, which are replaced: %V ... virus name %S ... scanner name %L ... detected level ''' name = 'add_header()' def __init__(self, hdr, data, *scanners): self.ONLY_IF = b'.' self.HDR = hdr self.DATA = data match_any.__init__(self, scanners) def onlyif(self, pattern=b'.'): self.ONLY_IF = pattern return self def hdr_replace(self, to, level, detected): return re.sub("%V", tostr(detected), re.sub("%S", globals.found_by.name, re.sub("%L", str(level), to))) def scanbuffer(self, buffer, args={}): level, detected, virlist = match_any.scanbuffer(self, buffer, args) if re.search(self.ONLY_IF, detected, re.IGNORECASE): mail.addheader(self.HDR, self.hdr_replace(self.DATA, level, detected)) return level, detected, virlist class modify_header(add_header): ''' Modify email headers. This scanner can be used to modify email headers. Usage: modify_header('^Header_regexp:','Header_regexp: prefix',scanners) or: modify_header(...).onlyif('virname') Where: '^Header_regexp:' is a string, which defines regular expression to find for this header 'Header_regexp: prefix' is a string, which defines new header data 'virname' is a string, which defines any virus name. By default all virus names at least 1 character long: '.' There are some special pattern, which are replaced: %V ... virus name %S ... scanner name %L ... detected level ''' name = 'modify_header()' def __init__(self, frm, to, *scanners): self.ONLY_IF = b'.' self.MOD_FRM = tobytes(frm) self.MOD_TO = tobytes(to) match_any.__init__(self,scanners) def hdr_replace(self, to, level, detected): return re.sub(b"%V", detected, re.sub(b"%S", tobytes(globals.found_by.name), re.sub(b"%L", tobytes(str(level)), to))) def scanbuffer(self, buffer, args={}): level, detected, virlist = match_any.scanbuffer(self, buffer, args) if re.search(self.ONLY_IF, detected, re.IGNORECASE): change_to = self.hdr_replace(self.MOD_TO, level, detected) changes = mail.modheader(self.MOD_FRM, change_to) if changes==0: mail.addheader(change_to) return level, detected, virlist class modify_subject(modify_header): ''' Modify email Subject. This scanner can be used to modify email Subject. Usage: modify_subject('prefix',scanners) or: modify_subject(...).onlyif('virname') Where: 'prefix' is an prefix added into Subject. 'virname' is a string, which defines any virus name. By default all virus names at least 1 character long: '.' For more information see modify_header() interscanner. For example original Subject line is: Subject: Testing mail and i use: modify_subject('[SPAM]', spamassassind(['localhost',783])) When spam will be found, header will be modifyed to: Subject: [SPAM] Testing mail ''' name = 'modify_subject()' def __init__(self, prefix, *scanners): modify_header.__init__(self, "^Subject:", "Subject: "+prefix, scanners) class remove_headers(ascanner): ''' Remove email headers. This scanner can be used to remove email headers. Usage: remove_headers('header name' [,'next header name' [, ...] ]) Where: 'header name' is a string, which defines header key to delete ''' name = 'remove_headers()' def __init__(self, *hdrs): self.DEL_HDRS = hdrs def scanbuffer(self, buffer, args={}): for hdr in self.DEL_HDRS: mail.delheader(tobytes(hdr)) return 0.0, b'', []