#!/usr/bin/env python
# vim: tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80 smarttab expandtab
"""
* Copyright (C) 2014  Sangoma Technologies Corp.
* All Rights Reserved.
*
* Author(s):
* Leonardo Lang <lang@sangoma.com>
*
* This code is Sangoma Technologies Confidential Property.
* Use of and access to this code is covered by a previously executed
* non-disclosure agreement between Sangoma Technologies and the Recipient.
* This code is being supplied for evaluation purposes only and is not to be
* used for any other purpose.
"""

import os
import re
import sys
import glob
import logging
import logging.handlers
import syslog
import subprocess
from optparse import OptionParser

parser = OptionParser()
parser.add_option("", "--debug", dest="debugging", action='store_true', help="enable debug messages")

(options, args) = parser.parse_args()

class DirectSyslogHandler(logging.Handler):
    def __init__(self):
        self.levelmap = { 'DEBUG': syslog.LOG_DEBUG, 'INFO': syslog.LOG_INFO, 'NOTICE': syslog.LOG_NOTICE,
                          'WARNING': syslog.LOG_WARNING, 'ERROR': syslog.LOG_ERR, 'CRITICAL': syslog.LOG_CRIT }
        logging.Handler.__init__(self)

    def emit(self, record):
        try:            
            msg = self.format(record)
            level = self.levelmap.get(record.levelname, syslog.LOG_INFO)
            syslog.syslog(level, msg)
        except Exception, e:
            pass

progname = os.path.basename(os.path.abspath(sys.argv[0]))

logger = logging.getLogger(progname)
logger.setLevel(logging.INFO)

handler = DirectSyslogHandler()
handler.setFormatter(logging.Formatter(progname + '[%(process)d]: %(levelname)s: ' + '%(message)s'))
logger.addHandler(handler)

if options.debugging:
    handler2 = logging.StreamHandler(sys.stderr)
    handler2.setFormatter(logging.Formatter(progname + '[%(process)d]: %(levelname)s: ' + '%(message)s'))
    logger.addHandler(handler2)
    logger.setLevel(logging.DEBUG)

reinclude = re.compile('^Include (.+)')
reportnum = re.compile('^Listen ([^:]+:)?([0-9]+)')

webbase = '/usr/webconfig'

sslports = set()
webports = set()
cfgfiles = set()

cfgfiles.add(webbase + '/conf/httpd.conf')

while True:
    try:
        fname = cfgfiles.pop()
        logger.debug('scanning "' + fname + '"...')

        try:
            fh = open(fname)

            for fullline in fh.readlines():
                line = fullline.rstrip('\n')

                mportnum = reportnum.match(line)

                if mportnum is not None:
                    pnumb = mportnum.group(2)
                    if fname.find('https') <> -1:
                        logger.debug('adding port number "' + pnumb + '" to HTTPS ports..')
                        sslports.add(pnumb)
                    else:
                        logger.debug('adding port number "' + pnumb + '" to HTTP ports..')
                        webports.add(pnumb)
                    continue

                minclude = reinclude.match(line)

                if minclude is not None:
                    pname = minclude.group(1)
                    logger.debug('adding include "' + pname + '"..')
                    if pname.startswith('\\'):
                        cfgfiles.update(set(glob.glob(pname)))
                    else:
                        cfgfiles.update(set(glob.glob(os.path.join(webbase, pname))))

        except IOError, e:
            logger.warning('unable to open "' + fname + '", skipping...')

    except KeyError, e:
        break

if len(webports) == 0:
    strwebports = '80,81'
else:
    strwebports = ','.join(reversed(list(webports)))

if len(sslports) == 0:
    strsslports = '443'

else:
    strsslports = ','.join(reversed(list(sslports)))

args = ['/usr/local/nsc/bin/snort-update-config','--http-ports',strwebports,'--ssl-ports',strsslports]

logger.debug('calling ' + str(args) + '...')
retcode = subprocess.call(args)

if retcode <> 0:
    logger.warning('calling snort-update-config returned ' + str(retcode))

sys.exit(0)
