From 884aca149a4d959b6cd9791c5daaebc28d24793a Mon Sep 17 00:00:00 2001 From: Data-Monkey Date: Sun, 21 May 2023 17:40:05 +1000 Subject: [PATCH] more splitting done --- .gitignore | 3 +- db/pialert.db | Bin 180224 -> 245760 bytes pialert/config.py | 22 +++++ pialert/database.py | 61 +++++++++++- pialert/helper.py | 41 +++++++- pialert/logger.py | 1 + pialert/pialert.py | 225 ++++++++++++++------------------------------ 7 files changed, 194 insertions(+), 159 deletions(-) create mode 100644 pialert/config.py diff --git a/.gitignore b/.gitignore index f908738e..a785a3b4 100755 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ front/plugins/**/*.log __pycache__/ *.py[cod] -*$py.class \ No newline at end of file +*$py.class +db/pialert.db \ No newline at end of file diff --git a/db/pialert.db b/db/pialert.db index ff4e27315457b56f048e1ce792b7f6e37591bc93..4b5bd1db4b2a54485a683c8efda866c6452e39e6 100755 GIT binary patch literal 245760 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 XSGZ*CgGC&ZE#qkL+Z0uUyYK%4Bum+v delta 4393 zcmeI0Yj6|S6@d5b>amh+uP_+d7Dg)>Y|AhF#DGH+BMVStWP=5vwBRcC8Wh`-D#->H zhS#b|(p)mS4$C@~6#AAIT3grIYDkrpCt5ySqZH z@T2aJ{;RytbI-l^+`H#|=UxvEa)X1W($>9AftbK|h9W)w7++19DFEsPo~IhV?4~HH zl$<5xq{;EKk<#kAZmN94pq5C0n)n2VftD(seP=utNlQ8R#VK}WL~E4 z(`V>a@KbP6UydLzeK-q$Hp%3}TKr&=*#>KH%@pH+Ed0_GvjtY;;VGt=2!Auhxan}F z^tuNBbr{x?qM2dX39A&*XH5*pHVS=#b|IRHUl{>6-DSqYIVd6;d&fz8{pTP9Pn-kZ z#_28jIe?fzutPZEX*}2_^a*Wy8eHx^AsCCA6?N@66p{*M_}y`^6QSJR zC*$CNG@NsubdipCoQLg3)N0gQoK6_>i#fA)Fp2fErF3PT7?`bPDr=qMuV+id&u4SB zCY`0(DW00i7FW-$H>IKH48)>*7gCpynN+Si(L1+M8qS3|n8(<Lp`!_{H>4hI(e z)f8>LrfH%7^+f(eg*B+PC21w8$Qsf~tC`d#ii>A_nz1YW19qprTK7;lrv07vh}NLF zz}V~Ha^6}?4 zm^b5}J}QIl+F>f2s;4qmr~fM5mv+Z=+W3WWpW(LQ74|OM#ya)Cr_O7?tKYBtn=Yiw z)LxTEw~M0s+|jkYZobMgLr7d0AZ8CoyJQ~{f@ zmvZPW_4V-jfUF+QKG}hY@2(`t8o^ab?l&@wdjT~xt(#Wo+Clf~e0({cQwiG{) z9YGm-i`@=Lp9E#tA8GS6w)i9d9)b9Hw8*v3-QaWc9&e-jATOa*(cqiC{8KHyC?Rz< zH#JG>-ey-rtJ_(P(sh6{>upLp^*`nkAe->ORrhDeH4mmWWeu?LM7zk z-;RQhMl8+}VH2!VRQ@4?0pGsP7;%pXbu`lBUx>sLbCacB&CpS#6EDuJ14I1Q%r}7v zAPwF=2F3XH80q8G7?jY6!57ECf$isrZgbMMoo5Zz>@egk@TWC~(Ke|bhs1x70$!yC<8+8_^6{5)x*CF(^HTk14PfLRE z4%|4&RD&@NVWZieB#@d$L$MQegS~0$Aqzo?FrPtbuwJaJIlU zH63898V;~U%?3JLw*U>Wc_}i`WwjEaZ0sA^H8RhJmBIdpHAMWw>7S4#LuZwO^#T>v zD^*ypl%4XiP05kUb-abvW!$H@`$>;1m_Q!Rf_PY?PV%gQWl54>d4_i^p5cv*)sQHW zB1AUk%Am#^*MuM1h%qL6G5K!GoqCeXKj!3QOj7i>xoqTswTqa_if>5#T z79?afBBg!Vo5+HM+@%$|WS?|j?j(`@5ez6beaO0qo9zyCbO^!3w{a~3<~YBKq#oLATe#}k|%sr+G&mXV}bT(WbOW-tG~TlAc;EJVN>X+vOrJt z)G3?M&@Dt_De|XcWfB@g$5V`J?FxkV31Pt>6FO4bCq{ciu|Q{_omi9{5dOG{$#SWt z$15CH8crE;D5a8YL&D2QRipDT%2g6xaU$X6EaJHf6J8CCveks7kwuM28m(0`l15o- zNNUKQ<9$3b#jI9sK;4pblOkQX2PK8t8)E-VNq{9!Z~cEY^*>lm6&t194*3toQaisy QQuwcSe)eTqD{cM$4Hw8WVgLXD diff --git a/pialert/config.py b/pialert/config.py new file mode 100644 index 00000000..e0da2934 --- /dev/null +++ b/pialert/config.py @@ -0,0 +1,22 @@ + + +global mySettings, mySettingsSQLsafe +#------------------------------------------------------------------------------- +# Import user values +# Check config dictionary +def ccd(key, default, config, name, inputtype, options, group, events=[], desc = "", regex = ""): + result = default + + # use existing value if already supplied, otherwise default value is used + if key in config: + result = config[key] + + global mySettings + + if inputtype == 'text': + result = result.replace('\'', "{s-quote}") + + mySettingsSQLsafe.append((key, name, desc, inputtype, options, regex, str(result), group, str(events))) + mySettings.append((key, name, desc, inputtype, options, regex, result, group, str(events))) + + return result \ No newline at end of file diff --git a/pialert/database.py b/pialert/database.py index ccf3db9a..071cfbaa 100644 --- a/pialert/database.py +++ b/pialert/database.py @@ -5,6 +5,7 @@ import sqlite3 from const import fullDbPath from logger import print_log, mylog + #=============================================================================== # SQL queries #=============================================================================== @@ -34,7 +35,8 @@ class DB(): def __init__(self): self.sql = None self.sql_connection = None - + + #------------------------------------------------------------------------------- def openDB (self): # Check if DB is open if self.sql_connection != None : @@ -55,7 +57,8 @@ class DB(): if self.sql_connection == None : mylog('debug','commitDB: databse is not open') return - mylog('debug','commitDB: comiting DB changes') + + # mylog('debug','commitDB: comiting DB changes') # Commit changes to DB self.sql_connection.commit() @@ -81,6 +84,58 @@ class DB(): return arr + #=============================================================================== + # Cleanup / upkeep database + #=============================================================================== + def cleanup_database (self, startTime, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA): + # Header + updateState(self,"Upkeep: Clean DB") + mylog('verbose', ['[', startTime, '] Upkeep Database:' ]) + + # Cleanup Online History + mylog('verbose', [' Online_History: Delete all but keep latest 150 entries']) + self.sql.execute ("""DELETE from Online_History where "Index" not in ( SELECT "Index" from Online_History order by Scan_Date desc limit 150)""") + + mylog('verbose', [' Optimize Database']) + # Cleanup Events + mylog('verbose', [' Events: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days']) + self.sql.execute ("DELETE FROM Events WHERE eve_DateTime <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')") + + # Cleanup Plugin Events History + mylog('verbose', [' Plugin Events History: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days']) + self.sql.execute ("DELETE FROM Plugins_History WHERE DateTimeChanged <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')") + + # Cleanup Pholus_Scan + if PHOLUS_DAYS_DATA != 0: + mylog('verbose', [' Pholus_Scan: Delete all older than ' + str(PHOLUS_DAYS_DATA) + ' days']) + self.sql.execute ("DELETE FROM Pholus_Scan WHERE Time <= date('now', '-"+ str(PHOLUS_DAYS_DATA) +" day')") # improvement possibility: keep at least N per mac + + # De-Dupe (de-duplicate - remove duplicate entries) from the Pholus_Scan table + mylog('verbose', [' Pholus_Scan: Delete all duplicates']) + self.sql.execute ("""DELETE FROM Pholus_Scan + WHERE rowid > ( + SELECT MIN(rowid) FROM Pholus_Scan p2 + WHERE Pholus_Scan.MAC = p2.MAC + AND Pholus_Scan.Value = p2.Value + AND Pholus_Scan.Record_Type = p2.Record_Type + );""") + + # De-Dupe (de-duplicate - remove duplicate entries) from the Nmap_Scan table + mylog('verbose', [' Nmap_Scan: Delete all duplicates']) + self.sql.execute ("""DELETE FROM Nmap_Scan + WHERE rowid > ( + SELECT MIN(rowid) FROM Nmap_Scan p2 + WHERE Nmap_Scan.MAC = p2.MAC + AND Nmap_Scan.Port = p2.Port + AND Nmap_Scan.State = p2.State + AND Nmap_Scan.Service = p2.Service + );""") + + # Shrink DB + mylog('verbose', [' Shrink Database']) + self.sql.execute ("VACUUM;") + + self.commitDB() @@ -97,7 +152,9 @@ def initOrSetParam(db, parID, parValue): #------------------------------------------------------------------------------- def updateState(db, newState): + #sql = db.sql + mylog('debug', ' [updateState] changing state to: "' + newState +'"') db.sql.execute ("UPDATE Parameters SET par_Value='"+ newState +"' WHERE par_ID='Back_App_State'") db.commitDB() diff --git a/pialert/helper.py b/pialert/helper.py index b92fdc57..51eb358e 100644 --- a/pialert/helper.py +++ b/pialert/helper.py @@ -4,7 +4,7 @@ import os import subprocess from const import * -from logger import mylog +from logger import mylog, logResult #------------------------------------------------------------------------------- def timeNow(): @@ -65,3 +65,42 @@ def fixPermissions(): # An error occured, handle it mylog('none', ["[Setup] Fix Failed. Execute this command manually inside of the container: ", ' '.join(com)]) mylog('none', [e.output]) + + +#------------------------------------------------------------------------------- +def initialiseFile(pathToCheck, defaultFile): + # if file not readable (missing?) try to copy over the backed-up (default) one + if str(os.access(pathToCheck, os.R_OK)) == "False": + mylog('none', ["[Setup] ("+ pathToCheck +") file is not readable or missing. Trying to copy over the default one."]) + try: + # try runnning a subprocess + p = subprocess.Popen(["cp", defaultFile , pathToCheck], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + stdout, stderr = p.communicate() + + if str(os.access(pathToCheck, os.R_OK)) == "False": + mylog('none', ["[Setup] Error copying ("+defaultFile+") to ("+pathToCheck+"). Make sure the app has Read & Write access to the parent directory."]) + else: + mylog('none', ["[Setup] ("+defaultFile+") copied over successfully to ("+pathToCheck+")."]) + + # write stdout and stderr into .log files for debugging if needed + logResult (stdout, stderr) # TO-DO should be changed to mylog + + except subprocess.CalledProcessError as e: + # An error occured, handle it + mylog('none', ["[Setup] Error copying ("+defaultFile+"). Make sure the app has Read & Write access to " + pathToCheck]) + mylog('none', [e.output]) + + +def filePermissions(): + # check and initialize pialert.conf + (confR_access, dbR_access) = checkPermissionsOK() # Initial check + + if confR_access == False: + initialiseFile(fullConfPath, "/home/pi/pialert/back/pialert.conf_bak" ) + + # check and initialize pialert.db + if dbR_access == False: + initialiseFile(fullDbPath, "/home/pi/pialert/back/pialert.db_bak") + + # last attempt + fixPermissions() \ No newline at end of file diff --git a/pialert/logger.py b/pialert/logger.py index f0e6a450..154a1082 100644 --- a/pialert/logger.py +++ b/pialert/logger.py @@ -3,6 +3,7 @@ import datetime from const import * + #------------------------------------------------------------------------------- debugLevels = [ ('none', 0), ('minimal', 1), ('verbose', 2), ('debug', 3) diff --git a/pialert/pialert.py b/pialert/pialert.py index dc2215a2..cc0edbb8 100755 --- a/pialert/pialert.py +++ b/pialert/pialert.py @@ -45,8 +45,9 @@ import multiprocessing from const import * from logger import mylog, print_log, logResult -from helper import checkPermissionsOK, fixPermissions, timeNow, updateSubnets +from helper import filePermissions, timeNow, updateSubnets from database import * +from config import ccd # Global variables @@ -63,45 +64,8 @@ sql_connection = None -#------------------------------------------------------------------------------- -def initialiseFile(pathToCheck, defaultFile): - # if file not readable (missing?) try to copy over the backed-up (default) one - if str(os.access(pathToCheck, os.R_OK)) == "False": - mylog('none', ["[Setup] ("+ pathToCheck +") file is not readable or missing. Trying to copy over the default one."]) - try: - # try runnning a subprocess - p = subprocess.Popen(["cp", defaultFile , pathToCheck], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - stdout, stderr = p.communicate() - if str(os.access(pathToCheck, os.R_OK)) == "False": - mylog('none', ["[Setup] Error copying ("+defaultFile+") to ("+pathToCheck+"). Make sure the app has Read & Write access to the parent directory."]) - else: - mylog('none', ["[Setup] ("+defaultFile+") copied over successfully to ("+pathToCheck+")."]) - # write stdout and stderr into .log files for debugging if needed - logResult (stdout, stderr) # TO-DO should be changed to mylog - - except subprocess.CalledProcessError as e: - # An error occured, handle it - mylog('none', ["[Setup] Error copying ("+defaultFile+"). Make sure the app has Read & Write access to " + pathToCheck]) - mylog('none', [e.output]) - -#=============================================================================== -# Basic checks and Setup -#=============================================================================== - -# check and initialize pialert.conf -(confR_access, dbR_access) = checkPermissionsOK() # Initial check - -if confR_access == False: - initialiseFile(fullConfPath, "/home/pi/pialert/back/pialert.conf_bak" ) - -# check and initialize pialert.db -if dbR_access == False: - initialiseFile(fullDbPath, "/home/pi/pialert/back/pialert.db_bak") - -# last attempt -fixPermissions() #=============================================================================== # Initialise user defined values @@ -110,27 +74,6 @@ fixPermissions() #------------------------------------------------------------------------------- - -#------------------------------------------------------------------------------- -# Import user values -# Check config dictionary -def ccd(key, default, config, name, inputtype, options, group, events=[], desc = "", regex = ""): - result = default - - # use existing value if already supplied, otherwise default value is used - if key in config: - result = config[key] - - global mySettings - - if inputtype == 'text': - result = result.replace('\'', "{s-quote}") - - mySettingsSQLsafe.append((key, name, desc, inputtype, options, regex, str(result), group, str(events))) - mySettings.append((key, name, desc, inputtype, options, regex, result, group, str(events))) - - return result - #------------------------------------------------------------------------------- def importConfigs (db): @@ -170,7 +113,7 @@ def importConfigs (db): return mySettings = [] # reset settings - mySettingsSQLsafe = [] # same as aboverr but safe to be passed into a SQL query + mySettingsSQLsafe = [] # same as above but safe to be passed into a SQL query # load the variables from pialert.conf code = compile(config_file.read_text(), config_file.name, "exec") @@ -288,6 +231,8 @@ def importConfigs (db): # Format and prepare the list of subnets userSubnets = updateSubnets(SCAN_SUBNETS) + + # Plugins START # ----------------- if ENABLE_PLUGINS: @@ -341,7 +286,7 @@ def importConfigs (db): lastTimeImported = time.time() # Is used to display a message in the UI when old (outdated) settings are loaded - initOrSetParam("Back_Settings_Imported",(round(time.time() * 1000),) ) + initOrSetParam(db, "Back_Settings_Imported",(round(time.time() * 1000),) ) #commitDB(sql_connection) db.commitDB() @@ -351,8 +296,15 @@ def importConfigs (db): mylog('info', ['[', timeNow(), '] Config: Imported new config']) + + + + + +#=============================================================================== +#=============================================================================== +# MAIN #=============================================================================== -# MAIN #=============================================================================== cycle = "" check_report = [1, "internet_IP", "update_vendors_silent"] @@ -375,37 +327,47 @@ def main (): # Initialize global variables global time_started, cycle, last_network_scan, last_internet_IP_scan, last_run, last_cleanup, last_update_vendors # second set of global variables - global startTime, log_timestamp, sql_connection, sql, plugins_once_run + global startTime, log_timestamp, plugins_once_run + + # To-Do all these DB Globals need to be removed + global db, sql, sql_connection + + # check file permissions and fix if required + filePermissions() # Open DB once and keep open # Opening / closing DB frequently actually casues more issues - db = DB() - print(db, db.sql, db.sql_connection ) + db = DB() # instance of class DB db.openDB() - print(db, db.sql, db.sql_connection ) - # To-Do replace the following to lines with the db dict or class + # To-Do replace the following to lines with the db class sql_connection = db.sql_connection sql = db.sql # Upgrade DB if needed upgradeDB(db) + + #=============================================================================== + # This is the mail loop of Pi.Alert + #=============================================================================== + while True: # update time started time_started = datetime.datetime.now() + mylog('debug', ['[', timeNow(), '] [MAIN] Stating loop']) # re-load user configuration and plugins importConfigs(db) # Handle plugins executed ONCE if ENABLE_PLUGINS and plugins_once_run == False: - run_plugin_scripts('once') + run_plugin_scripts(db, 'once') plugins_once_run = True # check if there is a front end initiated event which needs to be executed - check_and_run_event() + check_and_run_event(db) # Update API endpoints update_api() @@ -417,8 +379,7 @@ def main (): last_run = time_started # Header - updateState(db,"Process: Start") - mylog('verbose', ['[', timeNow(), '] Process: Start']) + updateState(db,"Process: Start") # Timestamp startTime = time_started @@ -426,7 +387,7 @@ def main (): # Check if any plugins need to run on schedule if ENABLE_PLUGINS: - run_plugin_scripts('schedule') + run_plugin_scripts(db,'schedule') # determine run/scan type based on passed time # -------------------------------------------- @@ -441,6 +402,7 @@ def main (): if last_update_vendors + datetime.timedelta(days = 7) < time_started: last_update_vendors = time_started cycle = 'update_vendors' + mylog('verbose', ['[', timeNow(), '] cycle:',cycle]) update_devices_MAC_vendors() # Execute scheduled or one-off Pholus scan if enabled and run conditions fulfilled @@ -459,7 +421,7 @@ def main (): if run: pholusSchedule.last_run = datetime.datetime.now(tz).replace(microsecond=0) - performPholusScan(PHOLUS_RUN_TIMEOUT) + performPholusScan(db, PHOLUS_RUN_TIMEOUT) # Execute scheduled or one-off Nmap scan if enabled and run conditions fulfilled if NMAP_RUN == "schedule" or NMAP_RUN == "once": @@ -483,6 +445,8 @@ def main (): if last_network_scan + datetime.timedelta(minutes=SCAN_CYCLE_MINUTES) < time_started: last_network_scan = time_started cycle = 1 # network scan + mylog('verbose', ['[', timeNow(), '] cycle:',cycle]) + # scan_network() # DEBUG start ++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -520,20 +484,21 @@ def main (): if len(newDevices) > 0: # run all plugins registered to be run when new devices are found if ENABLE_PLUGINS: - run_plugin_scripts('on_new_device') + run_plugin_scripts(db, 'on_new_device') # Scan newly found devices with Nmap if enabled if NMAP_ACTIVE and len(newDevices) > 0: - performNmapScan(newDevices) + performNmapScan( newDevices) # send all configured notifications - send_notifications() + send_notifications(db) # clean up the DB once a day if last_cleanup + datetime.timedelta(hours = 24) < time_started: last_cleanup = time_started cycle = 'cleanup' - cleanup_database() + mylog('verbose', ['[', timeNow(), '] cycle:',cycle]) + db.cleanup_database(startTime, DAYS_TO_KEEP_EVENTS, PHOLUS_DAYS_DATA) # Commit SQL db.commitDB() @@ -545,13 +510,15 @@ def main (): action = "network_scan" mylog('verbose', ['[', timeNow(), '] Last action: ', action]) cycle = "" + mylog('verbose', ['[', timeNow(), '] cycle:',cycle]) # Footer updateState(db,"Process: Wait") mylog('verbose', ['[', timeNow(), '] Process: Wait']) else: # do something - cycle = "" + cycle = "" + mylog('verbose', ['[', timeNow(), '] [MAIN] waiting to start next loop']) #loop time.sleep(5) # wait for N seconds @@ -563,7 +530,7 @@ def main (): def check_internet_IP (): # Header - updateState(sql_connection,"Scan: Internet IP") + updateState(db,"Scan: Internet IP") mylog('verbose', ['[', startTime, '] Check Internet IP:']) # Get Internet IP @@ -581,13 +548,13 @@ def check_internet_IP (): # Get previous stored IP mylog('verbose', [' Retrieving previous IP:']) - previous_IP = get_previous_internet_IP () + previous_IP = get_previous_internet_IP (db) mylog('verbose', [' ', previous_IP]) # Check IP Change if internet_IP != previous_IP : mylog('info', [' New internet IP: ', internet_IP]) - save_new_internet_IP (internet_IP) + save_new_internet_IP (db, internet_IP) else : mylog('verbose', [' No changes to perform']) @@ -700,7 +667,7 @@ def save_new_internet_IP (db, pNewIP): append_line_to_file (logPath + '/IP_changes.log', '['+str(startTime) +']\t'+ pNewIP +'\n') - prevIp = get_previous_internet_IP() + prevIp = get_previous_internet_IP(db) # Save event sql.execute ("""INSERT INTO Events (eve_MAC, eve_IP, eve_DateTime, eve_EventType, eve_AdditionalInfo, @@ -732,65 +699,13 @@ def check_IP_format (pIP): return IP.group(0) -#=============================================================================== -# Cleanup / upkeep database -#=============================================================================== -def cleanup_database (db): - # Header - updateState(sql_connection,"Upkeep: Clean DB") - mylog('verbose', ['[', startTime, '] Upkeep Database:' ]) - - # Cleanup Online History - mylog('verbose', [' Online_History: Delete all but keep latest 150 entries']) - sql.execute ("""DELETE from Online_History where "Index" not in ( SELECT "Index" from Online_History order by Scan_Date desc limit 150)""") - - mylog('verbose', [' Optimize Database']) - # Cleanup Events - mylog('verbose', [' Events: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days']) - sql.execute ("DELETE FROM Events WHERE eve_DateTime <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')") - - # Cleanup Plugin Events History - mylog('verbose', [' Plugin Events History: Delete all older than '+str(DAYS_TO_KEEP_EVENTS)+' days']) - sql.execute ("DELETE FROM Plugins_History WHERE DateTimeChanged <= date('now', '-"+str(DAYS_TO_KEEP_EVENTS)+" day')") - - # Cleanup Pholus_Scan - if PHOLUS_DAYS_DATA != 0: - mylog('verbose', [' Pholus_Scan: Delete all older than ' + str(PHOLUS_DAYS_DATA) + ' days']) - sql.execute ("DELETE FROM Pholus_Scan WHERE Time <= date('now', '-"+ str(PHOLUS_DAYS_DATA) +" day')") # improvement possibility: keep at least N per mac - - # De-Dupe (de-duplicate - remove duplicate entries) from the Pholus_Scan table - mylog('verbose', [' Pholus_Scan: Delete all duplicates']) - sql.execute ("""DELETE FROM Pholus_Scan - WHERE rowid > ( - SELECT MIN(rowid) FROM Pholus_Scan p2 - WHERE Pholus_Scan.MAC = p2.MAC - AND Pholus_Scan.Value = p2.Value - AND Pholus_Scan.Record_Type = p2.Record_Type - );""") - - # De-Dupe (de-duplicate - remove duplicate entries) from the Nmap_Scan table - mylog('verbose', [' Nmap_Scan: Delete all duplicates']) - sql.execute ("""DELETE FROM Nmap_Scan - WHERE rowid > ( - SELECT MIN(rowid) FROM Nmap_Scan p2 - WHERE Nmap_Scan.MAC = p2.MAC - AND Nmap_Scan.Port = p2.Port - AND Nmap_Scan.State = p2.State - AND Nmap_Scan.Service = p2.Service - );""") - - # Shrink DB - mylog('verbose', [' Shrink Database']) - sql.execute ("VACUUM;") - - db.commitDB() #=============================================================================== # UPDATE DEVICE MAC VENDORS #=============================================================================== def update_devices_MAC_vendors (db, pArg = ''): # Header - updateState(sql_connection,"Upkeep: Vendors") + updateState(db,"Upkeep: Vendors") mylog('verbose', ['[', startTime, '] Upkeep - Update HW Vendors:' ]) # Update vendors DB (iab oui) @@ -878,11 +793,11 @@ def query_MAC_vendor (pMAC): #=============================================================================== # SCAN NETWORK #=============================================================================== -def scan_network (db): +def scan_network (): reporting = False # Header - updateState(sql_connection,"Scan: Network") + updateState(db,"Scan: Network") mylog('verbose', ['[', startTime, '] Scan Devices:' ]) # Query ScanCycle properties @@ -942,19 +857,19 @@ def scan_network (db): # Resolve devices names print_log (' Resolve devices names') - update_devices_names() + update_devices_names(db) # Void false connection - disconnections mylog('verbose', [' Voiding false (ghost) disconnections']) - void_ghost_disconnections () + void_ghost_disconnections (db) # Pair session events (Connection / Disconnection) mylog('verbose', [' Pairing session events (connection / disconnection) ']) - pair_sessions_events() + pair_sessions_events(db) # Sessions snapshot mylog('verbose', [' Creating sessions snapshot']) - create_sessions_snapshot () + create_sessions_snapshot (db) # Sessions snapshot mylog('verbose', [' Inserting scan results into Online_History']) @@ -962,14 +877,14 @@ def scan_network (db): # Skip repeated notifications mylog('verbose', [' Skipping repeated notifications']) - skip_repeated_notifications () + skip_repeated_notifications (db) # Commit changes db.commitDB() # Run splugin scripts which are set to run every timne after a scan finished if ENABLE_PLUGINS: - run_plugin_scripts('always_after_scan') + run_plugin_scripts(db,'always_after_scan') return reporting @@ -1565,7 +1480,7 @@ def update_devices_names (db): #------------------------------------------------------------------------------- -def performNmapScan(db, devicesToScan): +def performNmapScan( devicesToScan): global changedPorts_json_struc @@ -1577,7 +1492,7 @@ def performNmapScan(db, devicesToScan): devTotal = len(devicesToScan) - updateState(sql_connection,"Scan: Nmap") + updateState(db,"Scan: Nmap") mylog('verbose', ['[', timeNow(), '] Scan: Nmap for max ', str(timeoutSec), 's ('+ str(round(int(timeoutSec) / 60, 1)) +'min) per device']) @@ -1770,7 +1685,7 @@ def performPholusScan (db, timeoutSec): interface = temp[1].strip() # logging & updating app state - updateState(sql_connection,"Scan: Pholus") + updateState(db,"Scan: Pholus") mylog('info', ['[', timeNow(), '] Scan: Pholus for ', str(timeoutSec), 's ('+ str(round(int(timeoutSec) / 60, 1)) +'min)']) mylog('verbose', [" Pholus scan on [interface] ", interface, " [mask] " , mask]) @@ -2129,7 +2044,7 @@ def send_notifications (db): # Open html Template template_file = open(pialertPath + '/back/report_template.html', 'r') - if isNewVersion(): + if isNewVersion(db): template_file = open(pialertPath + '/back/report_template_new_version.html', 'r') mail_html = template_file.read() @@ -2261,38 +2176,38 @@ def send_notifications (db): mylog('none', [' Changes detected, sending reports']) if REPORT_MAIL and check_config('email'): - updateState(sql_connection,"Send: Email") + updateState(db,"Send: Email") mylog('info', [' Sending report by Email']) send_email (mail_text, mail_html) else : mylog('verbose', [' Skip email']) if REPORT_APPRISE and check_config('apprise'): - updateState(sql_connection,"Send: Apprise") + updateState(db,"Send: Apprise") mylog('info', [' Sending report by Apprise']) send_apprise (mail_html, mail_text) else : mylog('verbose', [' Skip Apprise']) if REPORT_WEBHOOK and check_config('webhook'): - updateState(sql_connection,"Send: Webhook") + updateState(db,"Send: Webhook") mylog('info', [' Sending report by Webhook']) send_webhook (json_final, mail_text) else : mylog('verbose', [' Skip webhook']) if REPORT_NTFY and check_config('ntfy'): - updateState(sql_connection,"Send: NTFY") + updateState(db,"Send: NTFY") mylog('info', [' Sending report by NTFY']) send_ntfy (mail_text) else : mylog('verbose', [' Skip NTFY']) if REPORT_PUSHSAFER and check_config('pushsafer'): - updateState(sql_connection,"Send: PUSHSAFER") + updateState(db,"Send: PUSHSAFER") mylog('info', [' Sending report by PUSHSAFER']) send_pushsafer (mail_text) else : mylog('verbose', [' Skip PUSHSAFER']) # Update MQTT entities if REPORT_MQTT and check_config('mqtt'): - updateState(sql_connection,"Send: MQTT") + updateState(db,"Send: MQTT") mylog('info', [' Establishing MQTT thread']) mqtt_start() else : @@ -3347,12 +3262,12 @@ def custom_plugin_decoder(pluginDict): return namedtuple('X', pluginDict.keys())(*pluginDict.values()) #------------------------------------------------------------------------------- -def run_plugin_scripts(runType): +def run_plugin_scripts(db, runType): global plugins, tz, mySchedules # Header - updateState(sql_connection,"Run: Plugins") + updateState(db,"Run: Plugins") mylog('debug', [' [Plugins] Check if any plugins need to be executed on run type: ', runType])