'''
NOD32/ESETs module

(c) 2003-2019 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk>
                                                                                
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

'''

from avlib import *
from .filesys import *

__all__ = ['nod2', 'nod2pac', 'esetspac']

class nod2(ascanner):
  '''
  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
  '''
  name='nod2()'
  reg_nod2_02 = re.compile(r'^object="[^"]*", name="([^"]*)", virus="([^"]*)", ',
        re.IGNORECASE)
  reg_nod2_01 = re.compile(r" - (([^ ][^-][^ ]|[a-z/-])*)$",re.IGNORECASE)
  def __init__(self, arg=['/usr/sbin/nod32', '--log-brief', '--all', '--mail',
                          '--arch', '--adv-heur', '--adware', '--unsafe']):
      self.arg = arg
  def scanfile(self, files, dirname='', args={}):
      level = 0.0
      detected = b''
      virlist = []
      if dirname:
        pf = popen(self.arg+[safe.fn(dirname)])
        pf.tocmd.close()
        for line in pf.readlines():
          virlist.append(line)
        rc = pf.wait()
        pf.fromcmd.close()
        debug.echo(4, "NOD2: ", rc, virlist)
        if rc in [1, 10]:
          reg1 = self.reg_nod2_02.search(virlist[0])
          if reg1:
            detected = reg1.group(2)
            level += 1.0
          else:
            reg1 = self.reg_nod2_01.search(virlist[0])
            level += 1.0
            if reg1:
              detected = reg1.group(1)
              level += 1.0
            else:
              debug.echo(1, "NOD2: Can't decode reply! ", virlist)
              detected = b"CANT_DECOCE_VIRNAME"
              level += 1.0
        elif rc==101: # Error occurred during archives unpacking
          return 0.5, b'ArchiveUnpackingError', virlist
        elif rc>100:
          debug.echo(1, "ERROR: NOD2: ", rc, virlist)
          raise ScannerError('Error running NOD32: [%d] %s' % (rc, virlist[0]))
      if is_infected(level, detected):
        mail.addheader('X-Sagator-NOD2', detected)
      return level, detected, virlist

class esetspac(filesys):
  '''
  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.
  '''
  name='esetspac()'
  def __init__(self, prefix='/tmp/scand', logfile='/var/log/messages',
               reg=None):
      self.prefix = prefix
      self.logfile = logfile
      if reg:
        self.reg = reg
      else:
        self.reg = re.compile(
          r'[0-9: +-]* summ(ary)?\[[0-9a-f]+\]: '
          r'+vdb=(?P<vdb>[0-9]+), '
          r'agent=pac, '
          r'(msgid=none, )?'
          r'(object="(?P<object>[^"]*)", )?'
          r'name="(?P<filename>[^"]*)", '
          r'virus="(?P<virus>[^"]*)", '
          r'action="[^"]*", '
          r'info="(?P<info>[^"]*)", ',
          re.IGNORECASE
        )
      self.ignored_virnames = ['is OK']
      self.hdr = '' #fromhdr()
  def shortname(self, filename):
      return filename.split(' -> ')[0]
  def scanfile(self, files, dirname='', args={}):
      return filesys.scanfile(self,files, dirname, args)

class nod2pac(esetspac):
  '''
  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.
  '''
  name='nod2pac()'
