# Services

### chroot_execvp()
    Execute an external command (or start an daemon).

    This service can be used to start external daemons used by sagator.

    Usage: chroot_execvp('daemon_name',args=[],pid_file='')

    Where: daemon_name is a string, which defines command name
           args are strings, which defines command line arguments
           pid_file is an string to filename with PID of started daemon
           pgrp_file is an string to a process group filename

    Example: chroot_execvp('/usr/sbin/clamd','-c','/etc/clamav.conf')

    New in version 0.7.0.

### chroot_execvpe()
    Execute an external command (or start an daemon) and update variables.

    This service can be used to start external daemons used by sagator.
    You also can set environment varibles.

    Usage: chroot_execvpe('daemon_name',args=[],env={})

    Where: daemon_name is a string, which defines command name
           args are strings, which defines command line arguments
           env is an dictionary of environment variables
           pid_file is an string to filename with PID of started daemon
           pgrp_file is an string to a process group filename

    Example: chroot_execvpe('/usr/sbin/clamd',['-c','/etc/clamav.conf'],
                            {'LANG': 'C'})

    New in version 0.7.0.

### collector()
    Statistics collector service.

    This service can be used to collect some data for statistics.

    Usage: collector(ip_or_hostname='', port=-1,
                     statfile='/var/lib/sagator/status')

    Where: ip_or_hostname is an string, which defines IP to bind to
           port is an integer, which defines port number to bind to.
             If port<0 (default), no tcp socket will listen and only
             statistics from file will be processed. It is effective
             for large servers.
           statfile is an string, which defines where to store status

    Examples: collector()
          or: collector('0.0.0.0',28)

### fusefs()
    Fuse filesystem with antivirus checking.

    This service can be used to check filesystem access for viruses.

    Usage: fusefs(SCANNERS, mountpoint, root_path='/')

    Where: mountpoint is a string, which defines an directory, where files
             will be accessed.
           root_path is a path, which files will real files.

    Example: fusefs(SCANNERS, '/home', '/realhome')

    New in version 0.8.0.

### http_proxy()
    HTTP proxy service (experimental).

    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    !!!  WARNING! This service is experimental! Use at your risk!  !!!
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    This service can be used as filtering HTTP proxy.

    Usage: http_proxy(scanners, host, port, prefork=2)

    Where: scanners is an array of scanners (see README.scanners for more info)
           host is a an ip address to bind
           port is a port to bind
           prefork is a number, which defines preforked process count

    Example: http_proxy(SCANNERS, '127.0.0.1', 3128)

    Warning! Do not forget to block access to this port for non-local users.

### lmtpd()
    LMTP daemon service.

    This service can be used to start sagator as separate filtering LMTP
    daemon. Is is useful for postfix and any other LMTP client, which
    can use these filters.
    LMTP protocol is useful, if you want to set different filters for
    different users.

    Usage: lmtpd(scanners, host, port, prefork=2)

    Where: scanners is an array of scanners (see README.scanners for more info)
           host is a an ip address to bind
           port is a port to bind
           prefork is a number, which defines preforked process count.
             Set this parameter to actual processor count + 1
             or leave it's default (2).

    Example: lmtpd(SCANNERS, '127.0.0.1', 27)

    New in version 0.7.0.

### milter()
    Milter support service.

    This service can be used to start sagator as milter filter.

    Usage: milter(scanners, name, connection, umask)

    Where: scanners is an array of scanners (see README.scanners for more info)
           name is an string, milter service name
           connection in an string, which defines, where should milter service
             listen
           umask is an integer, which defines which umask should be set before
             creating local socket

    Example: milter(SCANNERS, "sagator", "inet:3333@127.0.0.1")

    For more information about milter's parameters see milter documentation.

    You need python's milter module to run this service:
      http://www.bmsi.com/python/milter.html

### recipient_policy()
    Virtual recipient policy.

    This policy check is invoked after an "RCPT TO:" smtp command is received.
    You can use an policy scanner combination as scanner. It is useable for
    postfix's before-queue policy filter or an policy filter for milter.
    This service must be defined before service, which want to use it.

    Usage: recipient_policy(scanners, dbc)

    Where: scanners is an array of policy scanners
             (see README.scanners for more info)
           dbc is an database connection

    Example: recipient_policy(POLICY_SCANNERS, db.sqlite())

    New in version 0.8.0.

### reporter()
    Reporter virtual service.

    This service is only a virtual service to configure parameters for
    reporter script.

    Usage: reporter(...parameters...)

    There you can define some parameters:
    "begin", "body", "end", "include", "exclude", "include_fx", "exclude_fx"
    and "groups".

    First three parameters are email templates. "begin" is report header.
    It must contain RFC2822 headers. "body" is message part displayed for each
    rejected/dropped message. "end" is report's tailer, added to message
    after all "body"s. See srv/reporter.py file for example.

    "webq" parameter must define base URL to webq() service. This parameter
    is autodetected as your server hostname + standard webq() root directory.
    A row with this URL is added to your standard body, if no user body
    defined.

    "groups" parameter can be used to define email groups, for example you
    can define to send reports only to admin for each domain on you server:
      reporter(groups=[
                       ['@mydomain1.com$', 'admin@mydomain1.com'],
                       ['@domain2.sk$', 'admin@domain2.sk'],
                       ['.', 'root@localhost'] # send other to root
                      ])
    It is possible to define empty string as target to ignore some records.

    Example: reporter(include='@mydomain.sk$')

    Groups are new in version 0.9.0.

### rlimit()
    Resource limit virtual service.

    This service can be used to set resource limits for sagator.

    Usage: rlimit(PARAM1=value1, PARAM2=value1, ...)

    Where: PARAM1,... are resource parameter names
           value1,... are resource values

    For example you can use there resource parameter names:
      AS for the maximum area (in bytes) of address space which may be
          taken by the process.
      NOFILE for the maximum number of open file descriptors for the
          current process.
      VMEM for the largest area of mapped memory which the process may occupy.
      DATA for the maximum size (in bytes) of the process's heap.
      RSS for the maximum resident set size that should be made available
          to the process.
      STACK for the maximum size (in bytes) of the call stack for the current
          process.
      FSIZE for the maximum size of a file which the process may create.
          This only affects the stack of the main thread in a multi-threaded
          process.
      CPU for the maximum amount of processor time (in seconds) that a process
          can use

    Aprox. 100 MB address space is required only for libclamav database.

    Example: rlimit(AS=30000000)

### scand()
    Scanner daemon with a preload library ability.

    This service can be used to scan for viruses with an library, which
    can be "preloaded" as LD_PRELOAD library.

    Usage: scand(scanner,ld_preload='',
                 sock='/tmp/scand.sock',
                 pid_file='/var/run/scand.pid',
                 as_root=False)

    Where: scanner is a scand scanner
           ld_preload is an library name, which can be preloaded with
             LD_PRELOAD parameter. By default by library will be preloaded.
           sock is path to communicate with scanner
           pid_file is a path to store daemon's pid file. This will be loaded
             at exit and this process will be killed.
           as_root is an boolean. Set it to True if you want to run scanners
             in scand as root.

    Example: scand(nod2pac(),ld_preload='/usr/lib/libnod32pac.so')
         or: scand(usrquota('mydomain.sk'),as_root=True)

    New in version 0.8.0.

### sgfilterd()
    A service to filter data sent by sgfilter command.

    This service can be used to filter an email through sagator.
    Some headers should be added to filtered email. A client for this
    service is the sgfilter script. See man sgfilter for more information.

    Usage: sgfilterd(scanners,host='127.0.0.1',port=27,prefork=2)

    Where: scanners is an array of scanners (see README.scanners for more info)
           host is a hostname to bind
           port is a tcp port to bind
           prefork is a number, which defines preforked process count.
             Set this parameter to actual processor count + 1
             or leave it's default (2).

    Example: sgfilterd(SCANNERS)

    Input protocol description:
      MAIL FROM: sender_email
      RCPT TO: recipient_email
      DATA length
      ...

    Where: sender_email is sender's email address
           recipient_email is recipient's email address. You can send more
             RCPT TO: lines.
           length is whole data length in bytes (including control characters,
             as newlines, ...)

    Output protocol description:
      XXX L.LL VIRNAME
      ...
      ^D

    Where: XXX is three digit status, one from these:
               250 - clean
               251 - not clean, but sending forced
               451 - an internal error occured during scanning
               550 - reject
               551 - drop
           L.LL is an floating number of virus/spam level status
           VIRNAME is an short description (like virus name, 'SPAM' string
               or other one line short description
           ... is modified email message (if some scanners are defined
               to modify scanned message)
           ^D is an EOF character, after message the communication is closed

    New in version 0.7.0.

### smtpd()
    SMTP daemon service.

    This service can be used to start sagator as separate filtering SMTP
    daemon. Is is useful for postfix and any other SMTP daemon, which
    can use these filters.

    Usage: smtpd(scanners, host, port, prefork=2)

    Where: scanners is an array of scanners (see README.scanners for more info)
           host is a an ip address to bind
           port is a port to bind
           prefork is a number, which defines preforked process count.
             Set this parameter to actual processor count + 1
             or leave it's default (2). For multicore servers you can use
             core_count() function to use autodetection.

    Example: smtpd(SCANNERS, '127.0.0.1', 27)

### smtpd_policy()
    SMTP policy service.

    This service can be used as smtpd policy service for postfix.

    Usage: smtpd_polixy(scanners, dbc, host, port, max_children=200)

    Where: scanners is an array of policy scanners
             (see README.scanners for more info)
           dbc is an database connection
           host is a an ip address to bind
           port is a port to bind
           max_children is a number defining maximal number of childrens
             for this service

    Example: smtpd_policy(SCANNERS, db.sqlite(), '127.0.0.1', 29)

    Postfix configuration example:
      /etc/postfix/main.cf:
        smtpd_recipient_restrictions=
                ...
                check_policy_service inet:127.0.0.1:29
                ...

    New in version 0.8.0.

### webq_jinja()
    Web service for sagator's quaratine access.

    This service can be used to access email collected by sagator via
    web interface.

    Requirements: python-jinja2 or python-jinja

    Usage: webq_jinja(host='0.0.0.0', port=8008, db,
                      log='/var/log/sagator/webq.log',
                      scanner, userconv)

    Where: host is an string, which defines IP address to bind,
             default: 0.0.0.0
           port is an integer, which defines tcp port to listen, default: 8008
           db is a database connection. For description see Databases.txt.
           log is defining a log file name, by default /var/log/sagator/webq.log
           scanner is a scanner to use for checking (only one scanner
             can be used here and it must be a buffer scanner!)
           userconv is an array, which defines regular expression
             and substitution strings. Usernames from login prompt
             are matched against this regular expression and substitued
             by substitution string.
           request_handler is an SimpleHTTPRequestHandler class.
             By default webq_jinja_request_handler is used.
             Use this class as parent if you need to override some functions.
             This parameter was introduced in sagator 1.3.

    It is recommended to use apache mod_proxy module to redirect standard
    web traffic from port 80 to webq()'s 8008. For example:
        ProxyPass /webq http://localhost:8008
        ProxyPassReverse /webq http://localhost:8008

    Example: See default config file for example.

    New in version 1.3.0.