Skip to content
Snippets Groups Projects
Config.py 13.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/env python3.3
    # -*- coding: utf-8 -*-
    #
    # Config reader to read the configuration file
    #
    # Software is free software released under the "Modified BSD license"
    #
    # Copyright (c) 2013-2014 	Alexandre Dulaunoy - a@foo.be
    
    PidgeyL's avatar
    PidgeyL committed
    # Copyright (c) 2014-2016 	Pieter-Jan Moreels - pieterjan.moreels@gmail.com
    
    PidgeyL's avatar
    PidgeyL committed
    import sys
    
    import os
    runPath = os.path.dirname(os.path.realpath(__file__))
    
    import pymongo
    import redis
    
    
    import re
    
    import datetime
    
    import configparser
    
    import urllib.parse
    
    import urllib.request as req
    
    from io import BytesIO
    import gzip
    
    
    class Configuration():
        ConfigParser = configparser.ConfigParser()
    
    PidgeyL's avatar
    PidgeyL committed
        ConfigParser.read(os.path.join(runPath, "../etc/configuration.ini"))
    
        default = {'redisHost': 'localhost', 'redisPort': 6379,
                   'redisVendorDB': 10,      'redisNotificationsDB': 11,
    
                   'mongoHost': 'localhost', 'mongoPort': 27017,
    
    TimeEmit's avatar
    TimeEmit committed
                   'mongoUsername': '', 'mongoPassword': '',
    
                   'flaskHost': "127.0.0.1", 'flaskPort': 5000,
                   'flaskDebug': True,       'pageLength': 50,
    
                   'loginRequired': False,
    
    Pieter-Jan Moreels's avatar
    Pieter-Jan Moreels committed
                   'ssl': False,             'sslCertificate': "./ssl/cve-search.crt",
                                             'sslKey': "./ssl/cve-search.crt",
    
    PidgeyL's avatar
    PidgeyL committed
                   'CVEStartYear': 2002,
    
                   'vFeedurl': "http://www.toolswatch.org/vfeed/vfeed.db.tgz",
    
                   'vFeedstatus': "http://www.toolswatch.org/update.dat",
    
                   'cvedict': "https://static.nvd.nist.gov/feeds/xml/cve/",
                   'cpedict': "https://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml",
    
                   'cwedict': "http://cwe.mitre.org/data/xml/cwec_v2.8.xml.zip",
                   'd2sec': "http://www.d2sec.com/exploits/elliot.xml",
    
                   'vendor': "https://nvd.nist.gov/download/vendorstatements.xml",
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
                   'capec': "http://capec.mitre.org/data/xml/capec_v2.6.xml",
    
                   'msbulletin': "http://download.microsoft.com/download/6/7/3/673E4349-1CA5-40B9-8879-095C72D5B49D/BulletinSearch.xlsx",
    
                   'ref': "https://cve.mitre.org/data/refs/refmap/allrefmaps.zip",
    
                   'exploitdb': "https://github.com/offensive-security/exploit-database/raw/master/files.csv",
    
    Pieter-Jan Moreels's avatar
    Pieter-Jan Moreels committed
                   'logging': True,           'logfile': "./log/cve-search.log",
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
                   'maxLogSize': '100MB',     'backlog': 5,
    
    Pieter-Jan Moreels's avatar
    Pieter-Jan Moreels committed
                   'Indexdir': './indexdir',  'updatelogfile': './log/update.log',
    
                   'includeCapec': True,      'includeD2Sec': True,
                   'includeVFeed': True,      'includeVendor': True,
    
                   'includeCWE': True,
    
    PidgeyL's avatar
    PidgeyL committed
                   'http_proxy': '',
                   'plugin_load': './etc/plugins.txt',
                   'plugin_config': './etc/plugins.ini'
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
                   }
    
    
        @classmethod
        def readSetting(cls, section, item, default):
            result = default
            try:
    
                if type(default) == bool:
                    result = cls.ConfigParser.getboolean(section, item)
                elif type(default) == int:
                    result = cls.ConfigParser.getint(section, item)
                else:
                    result = cls.ConfigParser.get(section, item)
    
            except:
                pass
            return result
    
        # Mongo
        @classmethod
        def getMongoDB(cls):
            return cls.readSetting("Mongo", "DB", cls.default['mongoDB'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getMongoConnection(cls):
            mongoHost = cls.readSetting("Mongo", "Host", cls.default['mongoHost'])
            mongoPort = cls.readSetting("Mongo", "Port", cls.default['mongoPort'])
            mongoDB = cls.getMongoDB()
    
    TimeEmit's avatar
    TimeEmit committed
            mongoUsername = cls.readSetting("Mongo", "Username", cls.default['mongoUsername'])
            mongoPassword = cls.readSetting("Mongo", "Password", cls.default['mongoPassword'])
    
    
            mongoUsername = urllib.parse.quote( mongoUsername )
            mongoPassword = urllib.parse.quote( mongoPassword )
    
    PidgeyL's avatar
    PidgeyL committed
            try:
    
                if mongoUsername and mongoPassword:
                    mongoURI = "mongodb://{username}:{password}@{host}:{port}/{db}".format(
                        username = mongoUsername, password = mongoPassword,
                        host = mongoHost, port = mongoPort,
                        db = mongoDB
                    )
                    connect = pymongo.MongoClient(mongoURI)
                else:
                    connect = pymongo.MongoClient(mongoHost, mongoPort)
    
    PidgeyL's avatar
    PidgeyL committed
            except:
                sys.exit("Unable to connect to Mongo. Is it running on %s:%s?"%(mongoHost,mongoPort))
    
            return connect[mongoDB]
    
    
        @classmethod
        def toPath(cls, path):
            return path if os.path.isabs(path) else os.path.join(runPath, "..", path)
    
    
        # Redis
        @classmethod
        def getRedisHost(cls):
            return cls.readSetting("Redis", "Host", cls.default['redisHost'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getRedisPort(cls):
            return cls.readSetting("Redis", "Port", cls.default['redisPort'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getRedisVendorConnection(cls):
            redisHost = cls.getRedisHost()
            redisPort = cls.getRedisPort()
            redisDB = cls.readSetting("Redis", "VendorsDB", cls.default['redisVendorDB'])
    
            return redis.StrictRedis(host=redisHost, port=redisPort, db=redisDB, charset='utf-8', decode_responses=True)
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        def getRedisNotificationsConnection(cls):
    
            redisHost = cls.getRedisHost()
            redisPort = cls.getRedisPort()
            redisDB = cls.readSetting("Redis", "NotificationsDB", cls.default['redisNotificationsDB'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
            return redis.StrictRedis(host=redisHost, port=redisPort, db=redisDB, charset="utf-8", decode_responses=True)
    
        @classmethod
        def getRedisRefConnection(cls):
            redisHost = cls.getRedisHost()
            redisPort = cls.getRedisPort()
            redisDB = cls.readSetting("Redis", "RefDB", cls.default['redisRefDB'])
            return redis.StrictRedis(host=redisHost, port=redisPort, db=redisDB, charset="utf-8", decode_responses=True)
    
    
        # Flask
        @classmethod
        def getFlaskHost(cls):
            return cls.readSetting("Webserver", "Host", cls.default['flaskHost'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getFlaskPort(cls):
            return cls.readSetting("Webserver", "Port", cls.default['flaskPort'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getFlaskDebug(cls):
            return cls.readSetting("Webserver", "Debug", cls.default['flaskDebug'])
    
        # Webserver
        @classmethod
        def getPageLength(cls):
            return cls.readSetting("Webserver", "PageLength", cls.default['pageLength'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def loginRequired(cls):
            return cls.readSetting("Webserver", "LoginRequired", cls.default['loginRequired'])
    
        # SSL
        @classmethod
        def useSSL(cls):
            return cls.readSetting("Webserver", "SSL", cls.default['ssl'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getSSLCert(cls):
    
            return cls.toPath(cls.readSetting("Webserver", "Certificate", cls.default['sslCertificate']))
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getSSLKey(cls):
    
            return cls.toPath(cls.readSetting("Webserver", "Key", cls.default['sslKey']))
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
    Pieter-Jan Moreels's avatar
    Pieter-Jan Moreels committed
        # CVE
    
        @classmethod
        def getCVEStartYear(cls):
            date = datetime.datetime.now()
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
            year = date.year + 1
    
            score = cls.readSetting("CVE", "StartYear", cls.default['CVEStartYear'])
            if score < 2002 or score > year:
                print('The year %i is not a valid year.\ndefault year %i will be used.' % (score, cls.default['CVEStartYear']))
                score = cls.default['CVEStartYear']
            return cls.readSetting("CVE", "StartYear", cls.default['CVEStartYear'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        # Sources
        @classmethod
        def getvFeedURL(cls):
            return cls.readSetting("Sources", "vFeed", cls.default['vFeedurl'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getvFeedStatus(cls):
            return cls.readSetting("Sources", "vFeedStatus", cls.default['vFeedstatus'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getRefURL(cls):
            return cls.readSetting("Sources", "Ref", cls.default['ref'])
    
    
    PidgeyL's avatar
    PidgeyL committed
        def getCVEDict(cls):
            return cls.readSetting("Sources", "CVE", cls.default['cvedict'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
    PidgeyL's avatar
    PidgeyL committed
        @classmethod
    
        def getCPEDict(cls):
            return cls.readSetting("Sources", "CPE", cls.default['cpedict'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getCWEDict(cls):
            return cls.readSetting("Sources", "CWE", cls.default['cwedict'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getd2secDict(cls):
            return cls.readSetting("Sources", "d2sec", cls.default['d2sec'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getVendorDict(cls):
            return cls.readSetting("Sources", "Vendor", cls.default['vendor'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
    Yoann Chevalier's avatar
    Yoann Chevalier committed
        @classmethod
        def getCAPECDict(cls):
            return cls.readSetting("Sources", "CAPEC", cls.default['capec'])
    
    Yoann Chevalier's avatar
    Yoann Chevalier committed
    
        @classmethod
        def getMSBULLETINDict(cls):
            return cls.readSetting("Sources", "MSBULLETIN", cls.default['msbulletin'])
    
    
        @classmethod
        def getexploitdbDict(cls):
            return cls.readSetting("Sources", "exploitdb", cls.default['exploitdb'])
    
        # Logging
        @classmethod
        def getLogfile(cls):
    
            return cls.toPath(cls.readSetting("Logging", "Logfile", cls.default['logfile']))
    
    Pieter-Jan Moreels's avatar
    Pieter-Jan Moreels committed
    
        @classmethod
        def getUpdateLogFile(cls):
    
            return cls.toPath(cls.readSetting("Logging", "Updatelogfile", cls.default['updatelogfile']))
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getLogging(cls):
            return cls.readSetting("Logging", "Logging", cls.default['logging'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getMaxLogSize(cls):
            size = cls.readSetting("Logging", "MaxSize", cls.default['maxLogSize'])
            split = re.findall('\d+|\D+', size)
            try:
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
                if len(split) > 2 or len(split) == 0:
    
                    raise Exception
                base = int(split[0])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
                if len(split) == 1:
    
                    multiplier = 1
                else:
                    multiplier = (split[1]).strip().lower()
                    if multiplier == "b":
                        multiplier = 1
                    elif multiplier == "mb":
                        multiplier = 1024
                    elif multiplier == "gb":
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
                        multiplier = 1024 * 1024
    
            except Exception as e:
                print(e)
                return 100 * 1024
            return base * multiplier
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def getBacklog(cls):
            return cls.readSetting("Logging", "Backlog", cls.default['backlog'])
    
        # Indexing
        @classmethod
        def getTmpdir(cls):
    
            return cls.toPath(cls.readSetting("dbmgt", "Tmpdir", cls.default['Tmpdir']))
    
        # Indexing
    
        @classmethod
        def getIndexdir(cls):
    
            return cls.toPath(cls.readSetting("FulltextIndex", "Indexdir", cls.default['Indexdir']))
    
    
        # Enabled Feeds
        @classmethod
        def includesCapec(cls):
            return cls.readSetting("EnabledFeeds", "capec", cls.default['includeCapec'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def includesVFeed(cls):
            return cls.readSetting("EnabledFeeds", "vFeed", cls.default['includeVFeed'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def includesD2Sec(cls):
            return cls.readSetting("EnabledFeeds", "d2sec", cls.default['includeD2Sec'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def includesVendor(cls):
            return cls.readSetting("EnabledFeeds", "vendor", cls.default['includeVendor'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def includesCWE(cls):
            return cls.readSetting("EnabledFeeds", "CWE", cls.default['includeCWE'])
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
    
    
        @classmethod
        def includesFeed(cls, feed):
    
    Raphaël Vinot's avatar
    Raphaël Vinot committed
            if feed == 'capec' and not cls.includesCapec():
                return False
            elif feed == 'vfeed' and not cls.includesVFeed():
                return False
            elif feed == 'd2sec' and not cls.includesD2Sec():
                return False
            elif feed == 'vendor' and not cls.includesVendor():
                return False
            elif feed == 'cwe' and not cls.includesCWE():
                return False
            else:
                return True
    
    
        # Http Proxy
        @classmethod
        def getProxy(cls):
            return cls.readSetting("Proxy", "http", cls.default['http_proxy'])
    
        @classmethod
    
        def getFile(cls, getfile, compressed=False):
    
                proxy = req.ProxyHandler({'http': cls.getProxy(), 'https': cls.getProxy()})
    
                auth = req.HTTPBasicAuthHandler()
    
                opener = req.build_opener(proxy, auth, req.HTTPHandler)
                req.install_opener(opener)
    
            if not compressed:
                return req.urlopen(getfile)
            else:
                response = req.urlopen(getfile + '.gz')
    
                if 'gzip' in response.info().get('Content-Type'):
                    buf = BytesIO(response.read())
                    data = gzip.GzipFile(fileobj=buf)
                return (data, response)
    
    PidgeyL's avatar
    PidgeyL committed
    
        # Plugins
        @classmethod
        def getPluginLoadSettings(cls):
            return cls.toPath(cls.readSetting("Plugins", "loadSettings", cls.default['plugin_load']))
    
        @classmethod
        def getPluginsettings(cls):
            return cls.toPath(cls.readSetting("Plugins", "pluginSettings", cls.default['plugin_config']))
    
    class ConfigReader():
        def __init__(self, file):
            self.ConfigParser = configparser.ConfigParser()
            self.ConfigParser.read(file)
    
        def read(self, section, item, default):
            result = default
            try:
    
                if type(default) == bool:
    
    PidgeyL's avatar
    PidgeyL committed
                    result = self.ConfigParser.getboolean(section, item)
                elif type(default) == int:
                    result = self.ConfigParser.getint(section, item)
                else:
                    result = self.ConfigParser.get(section, item)
            except:
                pass
            return result