This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository mum. See http://git.chorem.org/mum.git commit c030c62fadc0a780fe48114fad9b05207b9ef13c Author: Alexis Guilbaud <guilbaud@codelutin.com> Date: Fri Jun 26 17:26:09 2015 +0200 test_conn corrected + added scan command on conf + started migration func --- app/module_loader.py | 40 +++++++++++++++++++++++++++++--- app/modules/nmap_detection.py | 11 ++++++--- app/modules/storage_modules/shelve_db.py | 28 ++++++++++++++++++++++ app/mum.py | 5 +++- migration_rules.json | 8 +++++++ mum.conf | 1 + mum.sh | 4 ++-- views/hostpage.html | 7 +++--- 8 files changed, 91 insertions(+), 13 deletions(-) diff --git a/app/module_loader.py b/app/module_loader.py index e1d5118..4f4b2cb 100644 --- a/app/module_loader.py +++ b/app/module_loader.py @@ -26,11 +26,14 @@ class ModuleLoader: Loads dynamically modules from packages connection_modules, detection_modules, monitoring_modules, storage_modules and contains several methods in order to call the methods once these modules loaded. """ - def __init__(self, conf): + def __init__(self, conf, mum_vesion): + self.logger = logging.getLogger("mum_log") self.conf = conf self.db = self.load_db() + db_version = self.db.get_db_version() + if float(db_version) < mum_vesion: + self.migrate_db(db_version) self.db.reset_tasks() - self.logger = logging.getLogger("mum_log") self.loaded_mod_moni = {} # See load_all_monitoring_modules self.loaded_mod_detect = {} # See load_all_detection_modules self.loaded_mod_conn = {} # See load_all_connection_modules @@ -51,6 +54,31 @@ class ModuleLoader: def get_db(self): return self.db + def migrate_db(self, current_db_version): + """ + Migrates the database through the rules defined on migration_rules.json + A backup of the previous database is also done. + """ + # backup creation + """ + db_loc_tree = self.conf['db_location'].split('/') + old_db_name = db_loc_tree[len(db_loc_tree) -1] + db_loc_tree.pop(len(db_loc_tree) -1) + backup_location = self.conf['db_location'] + '_v_' + str(current_db_version) + '.back' + pexpect.run("cp " + self.conf['db_location'] + " " + backup_location) + + migration_rules_file = open("migration_rules.json") + migration_rules = json.loads(migration_rules_file.read()) + for version in migration_rules: + if float(version) > current_db_version: + for add_instr in migration_rules[version]["add_field"]: + self.db.add_field(add_instr, migration_rules[version]["add_field"][add_instr]) + for rem_instr in migration_rules[version]["rem_field"]: + self.db.rem_field(rem_instr, migration_rules[version]["rem_field"][rem_instr]) + self.db.set_db_version(version) + """ + return None + def get_public_keys_loc(self): return self.conf['keys_location'] @@ -102,6 +130,7 @@ class ModuleLoader: ws, self.get_conection_modules_list(), self.get_monitoring_modules_list(), + self.conf['scan_command'], modules.HostNotFoundException) try: if re.search('^\d{1,3}(-\d{1,3})?[.]\d{1,3}(-\d{1,3})?[.]\d{1,3}(-\d{1,3})?[.]\d{1,3}(-\d{1,3})?$', param): @@ -164,9 +193,14 @@ class ModuleLoader: """ avaliable_conn = self.db.get_conf_conn(addr_host) conn = None - for i in range(len(avaliable_conn)): + self.logger.debug(str(avaliable_conn)) + i = 0 + conn_found = False + while not conn_found and i < range(len(avaliable_conn)): if avaliable_conn[i]['conn_mod_name'] == conn_mod_name: + conn_found = True conn = avaliable_conn.pop(i) + i += 1 getattr(self.loaded_mod_conn[conn['conn_mod_name']]['imported'], self.loaded_mod_conn[conn['conn_mod_name']]['class_name'])(addr_host, conn['args'], diff --git a/app/modules/nmap_detection.py b/app/modules/nmap_detection.py index 6b9d036..edcb5d5 100644 --- a/app/modules/nmap_detection.py +++ b/app/modules/nmap_detection.py @@ -9,7 +9,7 @@ from string import letters class nmap_detection: - def __init__(self, opt, db, ws, list_mod_conn, dict_mod_monitoring, hnfe): + def __init__(self, opt, db, ws, list_mod_conn, dict_mod_monitoring, command, hnfe): self.opt = opt self.db = db self.ws = ws @@ -18,6 +18,7 @@ class nmap_detection: self.list_mod_conn = list_mod_conn self.dict_mod_monitoring = dict_mod_monitoring self.HostNotFoundException = hnfe + self.command = command self.logger = logging.getLogger("mum_log") # function for splitting the different ranges of the IP adress @@ -94,28 +95,32 @@ class nmap_detection: ip = str(byte_1) + '.' + str(byte_2) + '.' + str(byte_3) + '.' + str(byte_4) self.ws.send(json.dumps({"CURRENT_STATE_INFO": "Scanning ip : " + ip})) try: - child = pexpect.spawn('nmap ' + self.opt + ' ' + ip + ' -oX ' + self.filename) + child = pexpect.spawn(self.command + ' ' + self.opt + ' ' + ip + ' -oX ' + self.filename) while child.isalive(): child.expect('Completed', timeout=None) except pexpect.EOF: self.parse_res(ip) except pexpect.TIMEOUT: + self.logger.error("Timeout on nmap execution") self.ws.send(json.dumps({"ERROR": "Timeout on nmap execution"})) except pexpect.ExceptionPexpect: + self.logger.error("nmap command not avaliable on server") self.ws.send(json.dumps({"ERROR": "nmap command not avaliable on server"})) def launch_detection_with_hostname(self, hostname): self.ws.send(json.dumps({"CURRENT_STATE_INFO": "Scanning host : " + hostname})) try: - child = pexpect.spawn('nmap ' + self.opt + ' ' + hostname + ' -oX ' + self.filename) + child = pexpect.spawn(self.command + ' ' + self.opt + ' ' + hostname + ' -oX ' + self.filename) while child.isalive(): child.expect('Completed', timeout=None) except pexpect.EOF: self.parse_res(hostname) return json.dumps(self.scanned_ip) except pexpect.TIMEOUT: + self.logger.error("Timeout on nmap execution") self.ws.send(json.dumps({"ERROR": "Timeout on nmap execution"})) except pexpect.ExceptionPexpect: + self.logger.error("nmap command not avaliable on server") self.ws.send(json.dumps({"ERROR": "nmap command not avaliable on server"})) # parse the xml result to keep only interesting values diff --git a/app/modules/storage_modules/shelve_db.py b/app/modules/storage_modules/shelve_db.py index 3836e45..ea72a11 100644 --- a/app/modules/storage_modules/shelve_db.py +++ b/app/modules/storage_modules/shelve_db.py @@ -56,6 +56,34 @@ class shelve_db: self.db = None self.lock.release() + def get_db_version(self): + self.open_db() + res = None + try: + res = self.db['version'] + except Exception: + self.logger.error(traceback.format_exc()) + finally: + self.close_db() + return res + + def set_db_version(self, new_version): + self.open_db() + try: + self.db['version'] = new_version + except Exception: + self.logger.error(traceback.format_exc()) + finally: + self.close_db() + + """ + def add_field(self, field, tab_loc): + self.open_db() + try: + for key in tab_loc: + if key == "*": + """ + def reset_tasks(self): self.open_db() try: diff --git a/app/mum.py b/app/mum.py index a44a48c..c6b4eb8 100755 --- a/app/mum.py +++ b/app/mum.py @@ -14,6 +14,8 @@ import os import logging from logging.handlers import RotatingFileHandler +VERSION = 0.2 + @route('/') def index(section='home'): return template('index') @@ -132,6 +134,7 @@ if __name__ == '__main__': parser.add_argument("--smtp_port", help="port number of the SMTP server") parser.add_argument("--smtp_address", help="e-mail address of the sender for e-mail notifications") parser.add_argument("--log_level", help="set the log level : DEBUG, INFO, WARNING, ERROR") + parser.add_argument("--scan_command", help="scan command to use (default is sudo nmap)") args = parser.parse_args() # creating the default conf structure from the configuration file @@ -181,7 +184,7 @@ if __name__ == '__main__': logger = create_logger(conf) - ml = ModuleLoader(conf) + ml = ModuleLoader(conf, VERSION) ml.load_all_monitoring_modules() ml.load_all_connection_modules() ml.load_all_detection_modules() diff --git a/migration_rules.json b/migration_rules.json new file mode 100644 index 0000000..faac1bd --- /dev/null +++ b/migration_rules.json @@ -0,0 +1,8 @@ +{ + "0.2": + { + "add_field":{ + "test": ["hosts", "*"] + } + } +} \ No newline at end of file diff --git a/mum.conf b/mum.conf index 6e7bf07..0c5bb85 100644 --- a/mum.conf +++ b/mum.conf @@ -8,6 +8,7 @@ smtp_server=localhost smtp_port= smtp_address= log_level=WARNING +scan_command=sudo nmap #scan=Scan name|Scan description|Priority|Nmap parameter options scan=Complete scan and detection|This scan is the most complete but the longest one. Recommended for commom server monitoring. Time necessary: from a minute to several hours depending of the host.|1|-sU -sS -p U:161,T:1-65535 -A -Pn diff --git a/mum.sh b/mum.sh index 39d4ef3..0eb6148 100755 --- a/mum.sh +++ b/mum.sh @@ -1,7 +1,7 @@ #!/bin/sh -DIR=$(basename /usr/lib/mum) -cd $DIR +#DIR=$(basename /usr/lib/mum) +#cd $DIR if [ ! -d "venv" ]; then echo "Preparing the virtual environment for the first launch (this may take several minutes)" diff --git a/views/hostpage.html b/views/hostpage.html index 8a34387..63b3143 100644 --- a/views/hostpage.html +++ b/views/hostpage.html @@ -1,11 +1,10 @@ <div class="col-md-offset-2 main"> <h1 class="page-header">Current state of - <span ng-click="show_display_name_input = true" - ng-show="show_display_name_input == false" - style="text-decoration:underline"> + <a ng-click="show_display_name_input = true" + ng-show="show_display_name_input == false"> {{items.display_name}} - </span> + </a> <div class="row" ng-show="show_display_name_input == true"> <div class="col-lg-6"> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.