HOME LINKS SAL PUBLIC SOFTWARE SEARCH MADE UP

SAGATOR


== 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/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('<email@of.sender.dom>')
|     or: report(...).ifscan(cond_scanner)
|  
|  Where: recipients is an array of recipients,
|           like: ['<r1@dom>', '<r2@dom>', ...]
|           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(['<admin@localhost>'], 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('<email@of.sender.dom>')
|     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.
|  
|  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 (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

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',
|                   '--disable-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)
|  
|  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.

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: 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
|  
|  This is experimental and may change in future releases.
|  
|  Example: listed()
|  
|  New in version 1.1.1.

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.