== Interscanners ============================== add_header() | 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 add_listed() | Add one record into SQL list for a policy. | | Usage: add_listed(dbc, flags, expire, table, scanners) | | Where: dbc is an database connection | flags is an string, which defines what and where to add. It can be: | BA - to blacklist sender's IP address | BS - to blacklist sender's email address | BR - to blacklist recipients | WA - to whitelist sender's IP address | WS - to whitelist sender's email address | WR - to whitelist recipients | expire is an integer, which defines validity of a new record | in seconds. Set it to -1 for infinite time. | table can define table alternative | | Example: add_listed(db.sqlite(), 'BA', -1, 'greylist', b2f(libclam())) | | New in version 0.8.0. alternatives() | Alternative scanners. | | Returns a virus, if one scanner returns a virus. | Scannig is ended if one scanner returns virus or clean. | Next scanner from the list is used, if previous scannes fails | (raises an error). Raises an ScannerError, if all scanners failed. | | Usage: alternatives(scanner1(),scanner2(),...) | | Where: scanner1(),... are scanners, which may find a virus b2f() | An alias for buffer2file() interscanner. buffer2file() | Buffer to file converter. | | You can use it to save buffers into files. | | Usage: buffer2file(scanner1()) | | Where: scanner1() is a interscanner or realscanner. | It must be a filescanner. buffer2mbox() | An alias for buffer2file(...,1) interscanner. cache() | Cache return value of a scanner. | | First call of this scanner caches return value for a scanner included into | and return it's value. Next calls returns stored values. | | Usage: cache('VAR',scanners...) | | Where: 'VAR' is a string, which defines variable name to cache return value | | Example: cache('var1', scanner1()) # to store and return scanner1()'s value | cache('var1') # to only return previously stored value | | New in version 0.7.0. check_level() | Select scanner based on tested scanner return status. | | Usage: check_level(tested_scanner, { | (min,max): scanner, | (min,max): scanner, ... | }) | or: check_level() | | Where: tested_scanner is a scanner, which return level will be tested | min is an integer, minimal level for this scanner | max is an integer, maximal level for this scanner | | This scanner with no arguments will return previously saved status. | Evaluation function is: min <= LEVEL < max . | When no range is found, cached reply will be returned without changes. | | Example: check_level(spamassassind(), { | (1.0, 5.0): deliver( | modify_subject('[SPAM:%L]', | check_level() | ) | ), | (5.0, 99999.0): drop('.', check_level()) | }) | | New in version 0.9.0. custom_action() | Interscanner to set custom action. | | This scanner can be used to set custom action (reject, drop, deliver) | by manually specifing this as parameters. | You can use these variables in format string: | %(VIRNAME)s name of detected virus, empty if CLEAN | %(QNAME)s quarantine file name (quarantine must be inside | custom_action scanner to use this) | %(SCANNER_NAME)s scanner which reported this virus | %(VERSION)s sagator's version | | Usage: custom_action(pattern, reply_code, reply_message, scanners) | | Where: pattern is an regular expression, which defines virus/spam to | set this action. It is checked over virus name. | reply_code is an integer or string, which defines message reply | code (250 for success, 451 for temporary failure, 550 for | reject). | reply_message is an string, which defines reply message string. | You can use variables defined above here. | | Bugs: Does not working with milter() service. | | Example: custom_action(".", 550, "Content rejected - %(VIRNAME)s", | scanners... | ) | | New in version 0.9.0. decompress() | Scanner used to decompress archives (zip,rar,arj,zoo,tar,...). | | It is a scanner, which can decompress some of files. | You can define your own decompressors and assing it to any extensions. | This scanner is a filescanner only, because external decompressors | can unpack only files. A used scanner must be also a filescanner. | If not, use file2buffer() interscanner. | | Filetype is determined on file content (not on file extension). | It can detect some exe SFX archives too. | | Usage: decompress(filescanner1(),[a,b,c,d]=[3,500,50MB,20MB]) | | Where: filescanner1() is an filescanner, which can scan all files | [a,b,c,d] is an array of 4 numbers: | a = max number of recursions | b = max number of decompressed files | c = max disk usage with all of decompressed files | d = max address space usage deliver() | A scanner to force sending some viruses/spams to original recipients. | | This scanner can be used to send some viruses/spams. | You can define by regular expression, what virus name or spam | can be sent. By default all non empty virus names will be matched. | | Usage: deliver(deliver_pattern, scanners) | | Where: deliver_pattern is an regular expression, which defines | virus name to really deliver, other emails will not be delivered. | | For compatibility issues deliver_pattern is used as fist scanner, | if it's type is not string. Also suboption .onlyif(pattern) can | be used to define deliver_pattern. deliver_to() | Interscanner to send emails to admins. | | This scanner can be used to send viruses/spams to an administrator. | | Usage: deliver_to(recipients,scanners) | or: deliver_to(...).onlyif('string') | | Where: recipients is an array of recipients | 'string' is an string, which defines regular expression. | If this expression is found in virus name, mail is | delivered, otherwise don't. drop() | Interscanner to drop viruses/spams. By default they are rejected. | | This scanner can be used to drop some viruses, like Klez. | Klez sends fake sender address and this virus can't be sent | back to sender, because sender is faked. | | Usage: drop(drop_pattern, scanners) | | This scanner does nothing else, like sets the DROP flag. | Email is passed to parent scanners and is dropped in sagator. | | Two constants drop.DEFAULT and drop.DEFAULT_EXT (extensible version) | can be used to drop most of worms, trojans and phishings, which fakes | sender email addresses. | | Examples: drop(drop.DEFAULT, scanners) | drop(drop.DEFAULT_EXT % 'SPAM|OtherVirus', scanners) | drop('.', scanners) # drop every virus/spam f2b() | An alias for file2buffer() interscanner. file2buffer() | File to buffer converter. | | This scanner converts a filescanner input into bufferscanner. | | Usage: file2buffer(scanner1()) | | Where: scanner1() is an interscanner or realscanner. | It must be a bufferscanner. interscanner() | Default scanner used for building all other interscanners. log() | Advanced logger interscanner. | | This scanner can be used to log some special data. | You can use these variables in format string: | %(LEVEL)s - detected virus level | %(VIRNAME)s - name of detected virus, empty if CLEAN | %(STATUS)s - if mail is dropped, rejected, ... | %(QNAME)s - quarantine file name | %(SCANNER_NAME)s - scanner which reported this virus | %(SENDER)s - scanned message sender | %(RECIPIENTS)s - scanned message recipients | %(RECIPIENT)s - scanned message recipients one by one (only for SQL) | %(SUBJECT)s - message's header Subject | %(SIZE)s - email size | %(VERSION)s - sagator's version | %(SENTBY_IP)s - sender's IP | %(SENTBY_NAME)s - sender's hostname | %(SENTBY_HELO)s - sender's HELO/EHLO string | %(DATETIME)s - date and time in standard format ("%c") | %(SYSLOG_DATE)s - date and time in syslog format ("%a %e %H:%M:%S") | %(PID)s - current process ID | | You also can use log.FORMAT for default format or log.SUMMARY_REPORT | for summary reporter script. | | Usage: log(logto,format,scanners...) | | Where: logto is a string, which defines filename to store these data | If logto is an integer, it defines log level in standard | log file. | format is a string, which defines data format | | New format style is introduced in version 0.9.0, for older versions please | use old format (for example "$STATUS" instead of "%(STATUS)s"). log_cleanup() | Clean old records from SQL log database table. | | Usage: log_cleanup(older_than=768) | | Where: older_than is an integer, which defines number of hours for | up-to-date records. All older records will be deleted. | By default aprox. one month (768h) of records are kept. | | New in version 1.1.0. log_sql() | SQL interscanner for python DB-API 2.0 compatible DB modules. | | Usage: log_sql(db_connection,format,scanners...) | log_sql(...).also_clean() | | Where: db_connection is a database connection. For these connections | see doc/Databases.txt file. | format is a string, which defines an SQL INSERT command with | optional variables described in log() scanner. | .also_clean() can be used to log also "CLEAN" emails | | Examples: log_sql(DB_ENGINE, log_sql.FORMAT) | log_sql(DB_ENGINE, | log_sql.FORMAT.extend('subject', '%(SUBJECT)s')) | | New in version 0.7.0. log_syslog() | Syslog logger interscanner to log via syslog. | | For detailed description see log() scanner. | | Usage: log_syslog(format,scanners...) match_all() | Returns a virus only if all scanners returns a virus. | | Usage: match_all(scanner1(),scanner2(),...) | | Where: scanner1(),... are scanners, which must find a virus match_any() | Match for any sub-scanner is required. | | Returns a virus, if one scanner returns a virus. | Next scanner from list is used, if previous scanner returns | no virus, or failed (raised an error). | | Usage: match_any(scanner1(),scanner2(),...) | | Where: scanner1(),... are scanners, which may find a virus modify_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 modify_subject() | 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 nothing() | This scanner does nothing. :-) | | Usage: nothing(some parameters...) | | Where: some parameters... are ignored :) parsemail() | Email parser interscanner. | | This scanner parses emails and send multiple of buffers into | scanner1(). If an multiscanner is used as another_scanner, | optimal method is used (scans all files at once). | | Usage: parsemail(scanner1(...) [, scanner2(...)] ) | | Example: parsemail(libclam()) quarantine() | Quarantine into a directory. | | This scanner can be used to quarantine an virus/spam. | qdir is a directory, in which viruses are stored. | Following regular expression can be used to disable quarantining | of some viruses or spams. | | Usage: quarantine('qdir', 'dont quarantine regular expression', scanners) | | Where: 'qdir' is a string, which defines a qatantine directory, | directory, in which viruses/spams are stored. | This string can contain %X substrings. These strings | are represented as defined in strftime. For more information | see "man strftime". If this directory not exitst, | it's created. | 'dont quarantine regular expression' is a regular expression, | which defines virus names, which can't be quarantined | | Example: quarantine('/var/spool/sagator/quarantine/%Y%m', '', a_scanner()) | - every month will be stored in separate directory recover() | Recover from an error. | | This scanner can be used to recover from scanner fail. If an scanner | fails (raises an error), this scanner return no virus. | | Usage: recover(scanner1(),scanner2(),...) | | Where: scanner1... are scanners regexp_find() | Recipient email address to index scanner, operating with regexp. | | It is useful only as lmtpd() scanner, because it operates on email | recipients. | | Usage: regexp_find(key, scanners) | | Where: key is an string, which defines which variable to compare. | Currently only "recipient" can be used here. | scanners is an dictionary of scanners, each returned key from | database must have coresponding key in this dictionary | | Example: regexp_find( | 'recipient', | { | '@somedomain.com$': b2f(libclam()), | '@anotherdomain.sk$': spamassassind(), | '': s2f(libclam())+spamassassind() | } | ) | | Limitations: It is not possible to include one regexp_find() into another. | | New in version 0.9.0. rename() | Interscanner to rewrite virus name returned by an scanner. | | Usage: rename(newname, scanners) | or: rename(newname, scanners).multiplier(MP) | | Where: newname is a string, which defines new virus name. | These string will be replaced: | %(VIRNAME)s old name | %(LEVEL)s detected level as float | %(STARS)s detected level as stars | MP is an multiplier for LEVEL and STARS. Returned level | is multiplied by this constant. | | Renaming is skipped, if level<1.0. report() | Report any message to admin, user or anybody. | | This module can be used to report an message to administrator | or to any user. You can use following variables in report messages: | %(FROM)s report sender | %(VIRNAME)s detected virus name | %(SMTP_COMM)s SMTP communication | %(STATUS)s status of this message (REJECTED, DROPPED, ...) | %(QNAME)s filename in quarantine | %(QQNAME)s quoted (urlencoded) filename in quarantine | %(SCANNER_OUTPUT)s returned scanner output | %(SCANNER_NAME)s name of the scanner | %(MSG_HEADER)s virus/spam header | %(MSG_BODY)s virus/spam body (without header) | %(SUBJECT)s message's header Subject | %(RANDOM)s 10 random characters (useable to generate a boundary) | %(SENDER)s virus/spam sender | %(RECIPIENTS)s virus/spam recipients joined by comma (',') | %(TO)s report recipeints | %(VERSION)s sagator's version | %(SENTBY_IP)s sender's IP | %(SENTBY_NAME)s sender's hostname | %(SENTBY_HELO)s sender's HELO/EHLO string | | Usage: report(recipients, msg, scanners) | or: report(...).sender('') | or: report(...).ifscan(cond_scanner) | | Where: recipients is an array of recipients, | like: ['', '', ...] | You can use variables mentioned above in this array, but only | %(SENDER)s can be used logically. | msg is an message template, you can use report.MSG_TMPL | cond_scanner is a scanner, which defines, when report may be sent | | Examples: | - send report to admin@localhost: | report([''], report.MSG_TMPL, ... ) | - send report to email sender: | report(['%(SENDER)s'], report.MSG_TMPL, ... ) report_recipients() | Report any message to email recipients. | | This module can be used to report an message to mail recipients. | For message description see report() scanner. | | Usage: report_recipients(msg, scanners) | or: report_recipients(...).sender('') | or: report(...).ifscan(cond_scanner) | | Where: msg is an message template, you can use report.MSG_TMPL | scanners are scanners which are used | cond_scanner is a scanner, which defines, when report may be sent retry() | Retry scanner more times. | | This scanner try to run defined scanner more than once, while if fails. | After an successful pass latest return value is returned. | | Usage: retry(count,scanner()) | | Where: count is an integer, which defines retry count | scanner(),... is a scanner, which may find a virus | | Example: retry(5, | alternatives( | spamassassind(...), | spamassassind(...) | ) | ) sql_find() | Recipient email address to index scanner, operating on SQL database. | | This scanner is an reimplementation of e2i_sql lmtpd() service from | older sagator 0.7.2. It is useful only as lmtpd() scanner, because | it operates on email recipients. | | Usage: sql_find(key, dbc, query, scanners) | | Where: key is an string, which defines which variable to compare. | Currently only "recipient" or "sender" can be used here. | dbc is an database connection | query is an SQL condition to use | scanners is an dictionary of scanners, each returned key from | database must have coresponding key in this dictionary | | Example: sql_find( | 'recipient', | db.sqlite(), | "SELECT key FROM userpref WHERE email=%s", | { | 'AV': b2f(libclam()), | 'AS': spamassassind(), | '': s2f(libclam())+spamassassind() # default | } | ) | | Limitations: It is not possible to include one sql_find() into another. | | New in version 0.9.0. status() | This interscanner can be used to collect some other statistics. | | Usage: status("String", scanner1(), scanner2(), ...) | | Where: "String" is a string, which defines a prefix for status update | This scring can't contain spaces. | These string will be replaced: | %(VIRNAME)s virus name | %(LEVEL)s detected level as float | %(STARS)s detected level as stars | scanner1(), ... are sagator's scanners | | Preffered usage: | SCANNERS = [ | status("Virus", virus_scanner1(), ...), | status("Spam", spam_scanner1(), ...) | ] | This collects Virus-count, Virus-bytes, Spam-count, Spam-bytes in collector. time_limit() | Interscanner to limit scanner execution time. | | Usage: time_limit(seconds, scanners) | | Where: seconds is an float, which defines maximum number of seconds. | After this limit scanner returns a virus and will be | dropped or rejected (maybe also quarantined) according | to configuration. | | Example: time_limit(300, parsemail(b2f(libclam())) ) | | New in version 0.7.0. == Virus scanners ============================== ascanner() | Default scanner user for building all other realscanners. attach_name() | Attachment name scanner. | | This scanner checks defined name of file in mime attachments. | By default known executable extensions will be blocked. | This scanner can be used only if it's parent is parsemail(). | | Usage: attach_name({b'VirName': b'regexp_pattern', ..}, flags=re.I) | | Where: 'VirName' is a string, which defines virus name | 'regexp_pattern' is an regular expression. If this expression | is found in attachment's name, VirName is returned | as virus name. | flags is a number, which defines regular expression flags. | By default IGNORECASE is used. | | Example: attach_name({ | 'Executable': '\.(exe|com|vxd|dll|cpl|scr|pif|lnk|bat|vbs|js)$' | }) avgd() | AVG daemon realscanner. | | This scanners is a realscanner, which can be used to scan | for viruses. It uses AVGd (a deamonized linux version of AVG7). | | Usage: avgd(params='', connto=('localhost', 54322), chroot='') | | Where: params is a string which defines command line parameters, | like -arc, -heur, -rt, ... see man page for avgscan | This option is not accepted by AVG8+, so it defaults to "". | connto is a tuple of host,port of avgd, | by default ('localhost', 54322) | chroot is an string in which sagator is running, if avgd | is not running in this chroot. By default chroot='', so your | avgscand should run inside sagator's chroot. | | To start AVGd in chroot, move all neccessary files into your chroot, | and change following line in init.d/avgd from: | daemon $AVG_HOME/avgscan -d | to: | daemon chroot /var/spool/vscan $AVG_HOME/avgscan -d | or similiar. bdc() | Bitdefender realscanner. | | This scanners is a realscanner, which can be used to scan | for viruses. It parses Bitdefender output. | | Warning: If you are using bdc in chroot, don't forget to mount | /proc directory under chroot. | | Usage: bdc(command=['/opt/bdc/bdc','--mail','--arc','--all']) | | Where: command is a array which defines command with parameters. | By default: ['/opt/bdc/bdc','--mail','--arc','--all'] clamd() | ClamAV daemon realscanner for clamav-1.0 or higher. | | This scanners is a realscanner, which can be used to scan | for viruses. ClamAV is a free program under GPL and may be freely | used. Its database is very well. | | If you need a chrooted clamd, copy it into chroot and start it | from here. If you are not familiar with it, use clamscan scanner | from this module. It easily does chroot support, but it | is not powerfull. | | Requires: clamd-1.0+ (clamav daemon) | | Usage: clamd(['localhost', 3310]) | or: clamd('/var/spool/vscan/clamd') | | Where: 1st definition defines a clam daemon on host localhost, | port 3310 (it is the default) | 2nd definition defines access to clamd via UNIX socket clamd0() | ClamAV daemon realscanner for clamav-0.103 or older. | | This scanners is a realscanner, which can be used to scan | for viruses. ClamAV is a free program under GPL and may be freely | used. Its database is very well. | | If you need a chrooted clamd, copy it into chroot and start it | from here. If you are not familiar with it, use clamscan scanner | from this module. It easily does chroot support, but it | is not powerfull. | | Requires: clamd<1.0 (clamav daemon) | | Usage: clamd0(['localhost', 3310]) | or: clamd0('/var/spool/vscan/clamd') | | Where: 1st definition defines a clam daemon on host localhost, | port 3310 (it is the default) | 2nd definition defines access to clamd via UNIX socket clamscan() | ClamAV command line realscanner. | | This scanner is a realscanner, which can be used to scan | for viruses. ClamAV is a free program under GPL and may be freely | used. Its database is very well. | | It can be easily used in chroot. mkchroot.sh from sagator package | automatically integrates it into chroot environment. | | Requires: clamscan binary from clamav | | Usage: clamscan(['/usr/bin/clamscan','--stdout','--infected', | '--no-summary','-r']) | | Where: in [] are command line parameters for clamscan binary cmd() | A realscanner used to scan over command line programs. | | Usage: cmd(['command','arg1',...],StatusCLEAN,StatusINFECTED,RE) | | Where: 'command' is a string, which command to run | 'argX' are command line arguments, as last argument the | filename is added | StatusCLEAN may be: | an array of integers, which defines "clean" exit codes | an regexp, indication no virus found | StatusINFECTED may be: | an array of integers, which defines "virus found" exit codes | RE is an regular expression string, which can extract virus | names from scanner output. cmd_bdc() | This scanner uses bdc command from BitDefender antivirus. | | See http://www.bitdefender.com/ for more info. | | Usage: cmd_bdc(command='/opt/bdc/bdc') | | Example: s2f(cmd_bdc('/opt/bdc/bdc')) cmd_clamav() | This scanner uses clamscan command from clamav project. | | See http://www.clamav.net/ for more info. | | Usage: cmd_clamav(command='clamscan') | | Example: s2f(cmd_clamav('clamscan')) cmd_drweb() | This scanner uses drweb command from DRWEB antivirus. | | See http://www.sald.com/, http://drweb.imshop.de/ for more info. | | Usage: cmd_drweb(command='/usr/local/drweb/drweb') | | Example: s2f(cmd_drweb('/usr/local/drweb/drweb')) cmd_fprot() | This scanner uses f-prot command from FRISK F-Prot antivirus. | | See http://www.f-prot.com/ for more info. | | Usage: cmd_fprot(command='f-prot', params=[]) | | Example: s2f(cmd_fprot('f-prot')) cmd_kavscanner() | This scanner uses kavscanner command from KasperskyLab kavscanner. | | See http://www.kaspersky.com/ for more info. | | Usage: cmd_kavscanner(command='/opt/kav/bin/kavscanner') | | Example: s2f(cmd_kavscanner('/opt/kav/bin/kavscanner') cmd_mks() | This scanner uses mks antivirus. | | See http://linux.mks.com.pl/ for more info. | | Usage: cmd_mks(command='mks32',extra_params_array=[]) | | Example: s2f(cmd_mks('mks32')) cmd_trendmicro() | This scanner uses trendmicro command from Trend Micro FileScanner. | | See http://www.trendmicro.com/ for more info. | | Usage: cmd_trendmicro(command='/etc/iscan/vscan') | | Example: s2f(cmd_trendmicro('/etc/iscan/vscan')) cmd_uvscan() | This scanner uses uvscan command from McAfee AntiVirus. | | See http://www.mcafee.com/ for more info. | | Usage: cmd_uvscan(command='uvscan') | | Example: s2f(cmd_uvscan('uvscan')) cmd_vbuster() | This scanner uses vbuster command from VirusBuster. | | See http://www.virusbuster.hu/en/ for more info. | | Usage: cmd_vbuster(command='vbscan') | | Example: s2f(cmd_vbuster('vbscan')) const() | Realscanner to return a constant value (virus or clean). | | This scanner has no special functionality. It returns always | a defined virus, or clean (if virus is not defined). | This scanner has no error codes. | | Usage: const(level, VirName, return_string=[]) | or const() | | Where: level is an float which defines returned infection level | If level is not defined, after scanning an error is raised. | VirName is a returned virus. | return_string is a array of strings returned | | Examples: const(0.0) # Return clean | const(1.0, 'Virus') # Return virus name "Virus" | const() # Raise an error dspam() | This realscanner uses dspam library. | | For detailed description see DSPAM documentation. | | Usage: dspam(home='/var/dspam', user=None, group=None, | classify=None, source=None, | train=None, flags=pydspam.DSF_SIGNATURE) | | Where: home is dspam home dir ('/var/dspam') | user is dspam user (user running sagator's process) | group is dspam group (group running sagator's process) | classify is how to classify this message | Available options: DSR_ISSPAM, DSR_ISINNOCENT | Default: Don't classify. | source is message source: | Available options: DSS_ERROR, DSS_CORPUS, DSS_INOCULATION | Default: No source defined. | train is training mode | Available options: DST_TEFT, DST_TOE, DST_TUM, DST_NOTRAIN | Default: DST_TEFT | flags are dspam flags | Available options: DSF_SIGNATURE, DSF_BIAS, DSF_NOISE, | DSF_WHITELIST, DSF_MERGED | Default: DSF_SIGNATURE | | Examples: | basic usage: | dspam() | training emails badly assigned as spams: | drop('',dspam(classify=DSR_ISSPAM,source=DSS_ERROR,train=DST_TOE)) | training emails badly assinged as inoocent: | drop('',dspam(classify=DSR_ISINNOCENT,source=DSS_ERROR,train=DST_TOE)) dspam_classify() | Realscanner to classify emails for DSPAM. | | This scanner can be used to classify messages as spams/hams. | For parameters see dspam() scanner documentation. | | Example: | configure SCANNERS=[ dspam_classify(source=DSS_CORPUS,flags=0) ] | and you can run sgscan to learn messages from a box: | Training ham (clean messages): | sgscan --dspam-classify=innocent MAILBOX | Training spam: | sgscan --dspam-classify=spam MAILBOX esetspac() | ESETs scanner over it's preload library module. | | You need to set LD_PRELOAD to ESETs preload library (libesets_pac.so). | You can do this by adding this line into /etc/sysconfig/sagator: | LD_PRELOAD=/usr/lib/libesets_pac.so | | Usage: esets(prefix='/tmp/scand', logfile='/var/log/messages', reg=None) | | Where: prefix is a string, which defines directory and a part of filename | to store scanned files, by default '/tmp/scand'. | logfile is a string, which defines path to logfile. This parameter | is used only when called from scanner daemon. | reg is a regular expression, which defines log format. Default | option is good for most of people. See source code for an example. | | Recommended settings for ESETS: | # use /var/log/messages as logfile for scanner | /etc/esets/esets.cfg | [global] | av_clean_mode = "none" | action_av_infected = "reject" | action_av_deleted = "reject" | [pac] | event_mask = "open:close" | ctl_incl = "/tmp/scand:/var/spool/vscan/tmp/scand" | action_av_deleted = "accept" | | New in version 1.1.1. file_magic() | File magic test (like "file -i command"). | | This scanner can be used to test file content for a special type. | You need a python module "magic", which is by default in file's | source, but in most distributions it is not compiled in package. | | Usage: file_magic({'VirName': 'regexp_pattern', ..}, flags=0, raw=True) | | Where: 'VirName' is a string, which identifies defined virus | 'regexp_pattern' is a regular expression pattern | flags is an int, which defines regular expression flags, | like re.I to ignore it's case. | raw is a boolean, when True, use MAGIC_RAW instead of MAGIC_MIME file_type() | Realscanner, which scans type of a file. | | A scanner to chcek content of a file for a special type (like zip, ...). | | Usage: file_type({'type': 'vir', ...}) | | Where 'type' is a name of type returned by filetype.* function | 'vir' is a vir name returned, if file type is matched | | Example: # scan for executables (COM, EXE, PIF and similiar types) | parsemail(file_type({'exe': 'MS Executable', | 'elf': 'Linux Executable'})) | | Obsolete since 1.1.1, use file_magic() instead. filesys() | 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. kav() | Kaspersky Antivirus realscanner. | | This scanners is a realscanner, which can be used to scan | for viruses. It parses Kaspersky antivirus output. | | Usage: kav(command=['/opt/kav/5.5/kav4unix/bin/kavscanner','-j3']) | | Where: command is a array which defines command with parameters. kavclient() | Kaspersky antivirus client realscanner. | | This scanners is a realscanner, which can be used to scan | for viruses. It parses Kaspersky antivirus client output. | | Usage: kavclient(socket_path='/var/run/aveserver', | command='/opt/kav/5.5/kav4mailservers/bin/aveclient', | chroot=True) | | Where: socket_path is a string, which defines path co aveserver socket | inside chroot. (default: /var/run/aveserver) | command is a string, which defines command to run. | (default: /opt/kav/bin/aveclient) | chroot is an string, which defines a prefix added to each filename. | If you are not running aveserver in chroot path, set it | to your CHROOT. libclam() | ClamAV realscanner - uses libclamavmodule python library. | | This scanners is a realscanner, which can be used to scan | for viruses. ClamAV is a free program under GPL and may be freely | used. Its database is very well. | | Requires: libclamav module for python (sagator-libclamav package) | | Usage: libclam(options=libclam.CL_SCAN_STDOPT, limits={}, | db_options=None, solib=None) | | Where: options is an number or structure, which defines libclam options. | See clamav documentation for more info. | limits is an tuple, which defines limits for clamav | decompressor, see clamav doc. for more info. | db_options is an number, which defines libclam loaddb options. | See clamav documentation for more info. This option is available | only with sagator-libclamav-1.2.2 or higher. | datadir is an string, defining path to clamav virus database | files. By default value compiled into libclamav. | This parameter is new in 1.2.0. | solib is a string, defining clamav shared library path and filename. | For example for clamav-0.94.2 it's "/usr/lib/libclamav.so.5". | By default it's autodetected. This parameter is new in 1.2.0. max_file_size() | Realscanner to test email's size. | | Usage: max_file_size(size, name='FileSizeOverrun') | | Where: size is a number of bytes, which if exceeded, virus is returned | name is a string, which identifies the virus name. | If this parameter is not present, 'FileSizeOverrun' is returned. | | Example: max_file_size(1024*1024*10) | # all files at least 10MB will be reported as virus nod2() | NOD2 scanner. Works with nod32lfs. | | This scanners is a realscanner, which can be used to scan | for viruses. You can use nod32 from nod32lfs package. | | Usage: nod2(['command','params...']) | | Where: in [] are command line parameters for nod32 nod2pac() | NOD32lfs scanner over it's preload library module. | | You need to set LD_PRELOAD to NOD32's preload library (libnod32pac.so). | You can do this by adding this line into /etc/sysconfig/sagator: | LD_PRELOAD=/usr/lib/libnod32pac.so | | Usage: nod2pac(prefix='/tmp/scand', logfile='/var/log/nod32d.log') | | Where: prefix is a string, which defines directory and a part of filename | to store scanned files, by default '/tmp/scand'. | logfile is a string, which defines path to logfile. This parameter | is used only when called from scanner daemon. | | Recommended settings for NOD32LFS: | /etc/nod32/nod32.cfg: | [global] | log_enabled = yes | [pac] | ctl_incl = "/var/spool/vscan/tmp/scand" | | New in version 0.8.0. regexp_scan() | Primitive regexp pattern scanner. | | There can be more patterns for one virus. All patterns in [] | must match to assign an buffer as virus (AND opeator). | There can also be more virnames in one dictionary. | | Usage: regexp_scan([['VirName', 'RegExp_Pattern...'], ...], size=0, flags=0) | | Where: 'VirName' is a string, which identifies defined virus | 'RegExp_Pattern...' is a regexp pattern | size is a number, which defines, how many bytes may be checked. | If it is 0 or not defined, whole buffer is scanned. | If it is -1, email header is scanned. | flags is an integer, which defines regular expression flags. | By default no flags are used. | | Example: regexp_scan([ | # Scan for a part of EICAR virus test file pattern | ['EICAR', '^X5O!P%@AP[4.*EICAR-STANDARD-ANTIVIRUS-TEST-FILE'], | # Scan for a an EXE file pattern endoded as base64. | ['UnknownEXE', '^TVqQ'] | ]) remove_headers() | 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 sanitize() | Sanitize (rename attachment filenames) an email. | | This scanners is a realscanner, which can be used to sanitize | email. It means all attachments are renamed to safe names. | For example "filename.exe" will be renamed to "filename-exe". | | WARNING! This scanner is in BETA stage! Id don't conform to RFC 2183! | | Usage: sanitize(insert='-',extensions='[a-z0-9]{3}') | | Where: insert is a string, which can be inserted for sanitized attachments | extensions is an regular expressios to find savse() | 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 scanc() | Scanner daemon client. | | This scanner can be used to communicate with sagator's scanner daemon | (scand() service). It is useful to run some scanners outside of chroot. | | Usage: scanc(scanner=None, addr='/tmp/scand.sock', prefix='/tmp/scand', | timeout=60) | | Where: scanner is an scanner to use for recipient signature generator. | You can leave it empty for many of scanners, but it is required | for example for usrquota() scanner. It is good to define | same scanners here as in scand() service. | add is a string, which defines path to socket for communication | with scanner daemon. | prefix is a string, which defines directory and a part of | filename to store scanned files, by default '/tmp/scand' | timeout is an integer for socket timeout setting. | Added in sagator-1.3. | | Example: scanc() | or: scanc(usrquota('mydomain.sk')) | | New in version 0.8.0. sender_regexp() | Sender IP address regexp scanner. | | This scanner can be used to scan for sender's IP address. You can use | it to perform some actions (for example send report to admin) if | a virus is comming from your local addresses. | | Usage: sender_regexp([['VirName', 'RegExp_Pattern...'], ...]) | | Where: 'VirName' is a string, which identifies defined virus | 'RegExp_Pattern...' is a regexp pattern | | Example: sender_regexp([ | ['LOCAL_IP', '(192\.168|172\.(1[6789]|2[0-9]|3[01])|10)\.'] | ]) smtp_comm() | Primitive regexp pattern scanner for SMTP communication. | | For more information about this scanner see documentation for | regexp_scan realscanner. | | This scanner also can be used to apply some scnanner to defined | email adresses. For example: | smtp_comm([['D', '^RCPT TO:.*anydomain.dom']]]) | & buffer2mbox(libclam()) | In this example, libclam() scanner is used only if mail is | adressed to an user on anydomain.dom. | | Usage: smtp_comm([['VirName', 'RegExp_Pattern...', ...], ...], flags=0) | | Where: 'VirName' is a string, which identifies defined virus | 'RegExp_Pattern...' is a regexp pattern | flags is an integer, which defines regular expression flags. | By default re.IGNORECASE|re.MULTILINE is used. sophie() | Sophie realscanner. | | This scanners is a realscanner, which can be used to scan | for viruses. Sophie uses sophos libsavi. It can also be used | for Trophie with TrendMicro antivirus scanner. | | If you need a chrooted sophie, copy it into chroot and start it | from here. Do not forget to update it's chrooted database. | | Usage: sophie(sophie_socket,chroot_path='') | | Where: sophie_socket is a filename to sophie via UNIX socket | chroot_path is a path, which you need to add | (may be the same as your CHROOT, if you are using | sagator in chroot and sophie not) string_scan() | Primitive string pattern scanner. | | There can be more patterns for one virus. All patterns | must match to assign an buffer as virus. | There can also be more virnames in one dictionary. | | Usage: string_scan([['VirName', 'Pattern1...', ...], ...], size=0) | | Where: 'VirName' is a string, which identifies defined virus | 'Pattern...' is a string pattern | size is a number, which defines, how many bytes may be checked. | If it is 0 or not defined, whole buffer is scanned. | If it is -1, email header is scanned. | | Example: string_scan([ | # Scan for a part of EICAR virus test file pattern | ['EICAR', 'X5O!P%@AP[4', 'EICAR-STANDARD-ANTIVIRUS-TEST-FILE'], | # Scan for a an EXE file pattern endoded as base64. | ['UnknownEXE', 'TVqQ'] | ]) trophie() | Trophie realscanner. | | It is an alias for sophie. See sophie documentation. usrquota() | Check user quota for an recipient. | | This scanner can be used to check user quota for an recipient. | It only can raise an error, if quota is exceeded, or it can return | clean. This scanner is only valid in combination with lmtpd() service. | | Usage: usrquota(mydestination) | | Where: mydestination is an regular expression, which defines local domains. | If it is set and only one recipient is specified | and recipients domain matches against this regular expression, | then username part will be sent into spamd. | | Example: usrquota('mydomain.sk') == Antispam scanners ============================== bogofilter() | BogoFilter scanner. | | This scanner scans for spams. If a spam is returned, a string | SPAM is returned as virus name. | | Usage: bogofilter(['/usr/bin/bogofilter','-v'], | SPAMSTRING='', | MAX_FILE_SIZE=500000) | | Where: in [] is a path and argumets of bogofilter binary | SPAMSTRING is a string, which define a report string, | which is checked. If it is found, mail is assigned as 'SPAM' | MAX_FILE_SIZE is a number, which defines maximum file size, | which can be tested. If a mail (with header) is larger, | it is not checked (by default 500000). filter() | Filter a message through a command. | | This scanner can be used to filter email through an external program. | It's return status is always clean. | | Usage: filter(['/path/command_name','-options',...]) | | Where: in [] is a path and argumets of filter binary qsf() | Quick Spam Filter scanner. | | This scanner scans for spams. If a spam is returned, a string | SPAM is returned as virus name. It uses Quick Spam Filter. | | Usage: qsf(['/usr/bin/qsf','-r'],SPAMSTRING='',MAX_FILE_SIZE=500000) | | Where: in [] is a path and argumets of qsf binary | SPAMSTRING is a string, which define a report string, | which is checked. If it is found, mail is assigned as 'SPAM' | MAX_FILE_SIZE is a number, which defines maximum file size, | which can be tested. If a mail (with header) is larger, | it is not checked (by default 500000). spamassassind() | SpamAssassin daemon scanner. | | This scanner scans for spams. If a spam is returned, a string | SPAM is returned as virus name. Sagator's level is counted as: | spamassassin_score / spamassassin_required_hits, for example for | header "X-Spam-Status: Yes, score=12.3 required=5.0": | 12.3 / 5.0 = 2.46 | | This scanner uses a spamassassind daemon. If you are not familiar with it, | you also can use spamassassin binary. Look at spamassassin scanner. | | Usage: spamassassind(['localhost',783], reqspamlevel=-1, | sa_max_file=500000, filter=False, | mydestination=None, virtual_users=None, | sa_user='vscan') | | Where: ['localhost',783] are the host and port of spamd. | if reqspamlevel is less than spam hits, spam status is returned, | if it is -1 (default), spam level from spamassassin config is used | sa_max_file is a number, which defines maximum file size in bytes, | which can be tested. If a mail (with header) is larger, | it is not checked (by default 500000). | filter is an boolean which can be used to process whole message | by spamassassin. New message (generated by spamassassin) will | be stored instead of original. It's default is False. | mydestination is an regular expression, which defines local domains. | If it is set and only one recipient is specified | and recipients domain matches against this regular expression, | then username part will be sent into spamd. | This parameter is new in 0.7.0. | virtual_users is an regular expression, which defines virtual users. | These users can be used to configure virtual user settings | for spamassassin. Only for emails with one recipient will be | applied. | sa_user is an string, which defines username sent to spamd. | By default it's vscan user. | This parameter is new in sagator-1.2.0. == Policy scanners ============================== auto_whitelist() | Whitelist IP addresses after sending some emails properly. | This whitelisting is done not more than every 10 minutes to avoid server | overload. This function is slow for large number of records, use it | carefully. | | Usage: auto_whitelist(match_count=10, table='greylist') | | Where: match_count is number of record which will must match | table can define table alternative | | Example: auto_whitelist(10) | | New in version 0.8.0. dns_check() | IP to domain (and back) resolving checker. | | This scanner can be used to check senders IP address to resolve via | DNS service. It can be uses asn real scanner or policy scanner. | | Usage: dns_check(reverse=False) | | Where: reverse can fe used to check also reverse records | | Example: dns_check() | | New in version 0.8.0. elisted() | SQL blacklist for a policy. Enhanced version. | | You can use this scanner to chcek, if an record is present in SQL table. | | Usage: elisted(flags='B', table='greylist') | | Where: flags is an character, which defines which flag will be searched | in SQL table. By default 'B' for this scanner. | table can define table alternative | | Returns: level=1.0, when client is in blacklist | level=0.0, when client is not in blacklist | | This is experimental and may change in future releases. | | Example: elisted() | | New in version 1.1.1. geoip2_country() | GeoIP2 country match (using mmdb files). | | Usage: geoip2_country(country_codes, allow=True, | db="/usr/share/GeoIP/GeoLite2-Country.mmdb") | | Where: country_codes is a list of allowed/denied countries. | Use upper case country codes only! | allow is an boolean, which defines if countries should | be allowed or denied | db is a full pathname to an GeoIP.mmdb file | | Example: geoip2_country(["SK"]) | | New in version 2.0.0. geoip_country() | GeoIP country match. | | Usage: geoip_country(country_codes, allow=True, | db="/usr/share/GeoIP/GeoIP.dat") | | Where: country_codes is a list of allowed/denied countries. | Use upper case country names only! | allow is an boolean, which defines if countries should | be allowed or denied | db is a full pathname to GeoIP.dat file | | Example: geoip_country(["SK"]) | | New in version 1.3.1. greylist() | A greylist policy scanner. | | This is an greylist implementation for sagator. | You can learn more about greylisting at: | http://www.salstar.sk/sagator/greylisting/ | | Usage: greylist(min=300, expire=48*3600, | info_url="http://www.salstar.sk/sagator/greylisting/") | | Where: min is minimum required seconds after an email is cleanly sent | (default: 5 minutes) | expire is record expiration time in seconds (default 48 hours). | If this record will be passed after min time, expiration | time will be disabled. | info_url is an string, which is displayed to greylisted clients | | Example: greylist() | | New in version 0.8.0. list_cleanup() | Cleanup obsolete records from an SQL list. | This cleanup is done not more than every 10 minutes to avoid server | overload. | | Usage: list_cleanup(lifetime=36*24*3600, table='greylist') | | Where: lifetime is number of seconds after which records are removed (36 days) | table can define table alternative | | Example: list_cleanup() | | New in version 0.8.0. listed() | SQL blacklist for a policy. | | You can use this scanner to chcek, if an record is present in SQL table. | | Usage: listed(flags='B', table='greylist') | | Where: flags is an character, which defines which flag will be searched | in SQL table. By default 'B' for this scanner. | table can define table alternative | | Returns: level=1.0, when client is in blacklist | level=0.0, when client is not in blacklist | | Example: listed() | | New in version 0.8.0. not_listed() | SQL whitelist for a policy. | | Usage: not_listed(flags='W', table='greylist') | | Where: flags is an character, which defines which flag will be searched | in SQL table. By default 'B' for this scanner. | table can define table alternative | | Returns: level=1.0, when client is not in whitelist | level=0.0, when client is in whitelist | | Example: not_listed() | | New in version 0.8.0. policy_quota_auth_limit() | A policy quota for authorized users. | | Limit number of emails from an authorized user. | Do not use multiple of policy_quota_auth_limit tests in one policy service, | use arrays for interval, max_conn, max_rcpt instead. | | Usage: policy_quota_auth_limit(interval, max_conn, max_rcpt) | | Where: interval - counting interval in seconds | max_conn - maximum number of connections to server | max_rcpt - maximum number of recipients | | Example: policy_quota_auth_limit(300, 10, 150) | | Postfix configuration example: | smtpd_data_restrictions = check_policy_service inet:127.0.0.1:30 | | SQL command, which can help you to set proper parameters. | Change 3600 with your current interval settings. | SELECT username, sum(1) AS count, sum(recipient_count) AS rcpt, | from_unixtime(timestamp/1000) AS time, group_concat(DISTINCT ip) | FROM policy_quota | GROUP BY username, floor(timestamp/1000/3600) | ORDER BY count DESC, rcpt DESC; | | New in version 1.3.0. policy_quota_cleanup() | Clean old records from SQL policy database table. | | Usage: policy_quota_cleanup(age=7*24, table="policy_quota") | | Where: age - record age in hours (by default 7 days) | table - name of policy quota SQL table | | New in version 1.3.0. rbl_check() | RBL (Real-time Blackhole list) checker. | | This scanner can be used to scan for sender's IP address contained | in a blacklist. | | Usage: rbl_check(domains) | | Where: domains are blacklist domain names (multiple parameters allowed). | | Example: rbl_check('zen.spamhaus.org') | | New in version 1.1.0. set_action() | An interscanner to return a status to set an action to return. | | You can user this scanner to set default policy returned by policy scanner, | or you can set policy according to scanner reply. | | Usage: set_action(action, *scanners) | | Where: action can be an action defined in postfix's SMTPD_POLICY_README, | for example: dunno, defer_if_permit, ok, reject, ... | | New in version 0.8.0. spf_check() | SPF (Sender Permitted From) checker. | | This scanner can be used to scan for sender's SPF records in content | scanner or policy scanner. | | Usage: spf_check(hard_error=False) | | Where: hard_error can be set to True, if you want errors raise as exceptions, | by default it is turned off. | | Example: spf_check() | | New in version 0.8.0.