diff --git a/back/pialert.py b/back/pialert.py index 2bbf4696..b8e6cb4e 100755 --- a/back/pialert.py +++ b/back/pialert.py @@ -3656,7 +3656,7 @@ def isNewVersion(): data = "" # make sure we received a valid response and not an API rate limit exceeded message - if len(data) > 0 and "published_at" in data[0]: + if data != "" and len(data) > 0 and isinstance(data, list) and "published_at" in data[0]: dateTimeStr = data[0]["published_at"] @@ -3850,7 +3850,7 @@ def execute_plugin(plugin): for row in arr: # There has to be always 9 columns - if len(row) == 9: + if len(row) == 9 and (row[0] in ['','null']) == False : sqlParams.append((plugin["unique_prefix"], row[0], row[1], 'null', row[2], row[3], row[4], row[5], row[6], 0, row[7], 'null', row[8])) else: mylog('none', [' [Plugins]: Skipped invalid sql result']) @@ -3896,7 +3896,7 @@ def process_plugin_events(plugin): existingPluginObjectsCount = len(pluginObjects) mylog('debug', [' [Plugins] Existing objects: ', existingPluginObjectsCount]) - mylog('debug', [' [Plugins] Events objects: ', len(plugEventsArr)]) + mylog('debug', [' [Plugins] Objects events : ', len(plugEventsArr)]) # set status as new - will be changed later if conditions are fulfilled, e.g. entry found for eve in plugEventsArr: @@ -4035,13 +4035,14 @@ def combine_plugin_objects(old, new): def resolve_wildcards(command, params): mylog('debug', [' [Plugins]: Pre-Resolved CMD: ', command]) + for param in params: mylog('debug', [' [Plugins]: key : {', param[0], '}']) mylog('debug', [' [Plugins]: resolved: ', param[1]]) command = command.replace('{' + param[0] + '}', param[1]) - mylog('debug', [' [Plugins]: Resolved CMD: ', command]) + mylog('debug', [' [Plugins]: Resolved CMD: ', command]) return command diff --git a/front/css/pialert.css b/front/css/pialert.css index 7484621d..26ba3796 100755 --- a/front/css/pialert.css +++ b/front/css/pialert.css @@ -827,5 +827,10 @@ height: 50px; padding-bottom: 8px; } +.plugins-description +{ + padding-top: 20px; +} + diff --git a/front/js/pialert_common.js b/front/js/pialert_common.js index d0318169..d78b6330 100755 --- a/front/js/pialert_common.js +++ b/front/js/pialert_common.js @@ -345,5 +345,30 @@ function openInNewTab (url) { } +// ----------------------------------------------------------------------------- +function navigateToDeviceWithIp (ip) { + + $.get('api/table_devices.json', function(res) { + + devices = res["data"]; + + mac = "" + + $.each(devices, function(index, obj) { + + if(obj.dev_LastIP.trim() == ip.trim()) + { + mac = obj.dev_MAC; + + window.open(window.location.origin +'/deviceDetails.php?mac=' + mac , "_blank"); + } + }); + + + + }); +} + + diff --git a/front/plugins.php b/front/plugins.php index 16b82b6a..55f71447 100755 --- a/front/plugins.php +++ b/front/plugins.php @@ -30,9 +30,7 @@ - + - + diff --git a/front/plugins/README.md b/front/plugins/README.md index 160e7e93..4dcccb57 100755 --- a/front/plugins/README.md +++ b/front/plugins/README.md @@ -313,8 +313,8 @@ The UI will adjust how columns are displayed in the UI based on the definition o ## Full Examples -- Script based plugin: Check the [website_monitor WEBMON) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/website_monitor/config.json) file for details. -- SQL query nased plugin: Check the [nmap_services NMAPSERV) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/nmap_services/config.json) file for details. +- Script based plugin: Check the [website_monitor (WEBMON) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/website_monitor/config.json) file for details. +- SQL query nased plugin: Check the [nmap_services (NMAPSERV) config.json](https://github.com/jokob-sk/Pi.Alert/blob/main/front/plugins/nmap_services/config.json) file for details. ### Screenshots diff --git a/front/plugins/dhcp_servers/README.md b/front/plugins/dhcp_servers/README.md new file mode 100755 index 00000000..c5474ad1 --- /dev/null +++ b/front/plugins/dhcp_servers/README.md @@ -0,0 +1,12 @@ +## Overview + +A simple sample plugin allowing for monitoring web services or urls. The status code corresponds to the commonly used [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status). + +### Usage + +- The user can specify which services (websites) to monitor via the `WEBMON_urls_to_check` setting. + +### Notes + +- Setting `(WEBMON_)SQL_internet_ip` is not used and specified for demonstration purposes only. +- Parameters `macs` and `internet_ip` in the `config.json` file are not used and specified for demonstration purposes only. \ No newline at end of file diff --git a/front/plugins/dhcp_servers/config.json b/front/plugins/dhcp_servers/config.json new file mode 100755 index 00000000..0d51badd --- /dev/null +++ b/front/plugins/dhcp_servers/config.json @@ -0,0 +1,302 @@ +{ + "code_name": "dhcp_servers", + "unique_prefix": "DHCPSRVS", + "enabled": true, + "data_source": "python-script", + "localized": ["display_name", "description", "icon"], + "display_name" : [{ + "language_code":"en_us", + "string" : "Rogue DHCP" + }], + "icon":[{ + "language_code":"en_us", + "string" : "" + }], + "description": [{ + "language_code":"en_us", + "string" : "This plugin is to use NMAP to monitor for rogue DHCP servers." + }], + "params" : [], + "database_column_definitions": + [ + { + "column": "Index", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + } , + { + "column": "Plugin", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "N/A" + }] + }, + { + "column": "Object_PrimaryID", + "css_classes": "col-sm-2", + "show": true, + "type": "deviceip", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Server Identifier" + }] + }, + { + "column": "Object_SecondaryID", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Domain Name" + }] + } , + { + "column": "DateTimeCreated", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Created" + }] + }, + { + "column": "DateTimeChanged", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Changed" + }] + }, + { + "column": "Watched_Value1", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Domain Name Server" + }] + }, + { + "column": "Watched_Value2", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "IP Offered" + }] + }, + { + "column": "Watched_Value3", + "css_classes": "col-sm-2", + "show": false, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Interface" + }] + } , + { + "column": "Watched_Value4", + "css_classes": "col-sm-2", + "show": true, + "type": "label", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Router" + }] + } , + { + "column": "UserData", + "css_classes": "col-sm-2", + "show": true, + "type": "textboxsave", + "default_value":"", + "options": [], + "localized": ["name"], + "name":[{ + "language_code":"en_us", + "string" : "Comments" + }] + }, + { + "column": "Status", + "css_classes": "col-sm-1", + "show": true, + "type": "replace", + "default_value":"", + "options": [ + { + "equals": "watched-not-changed", + "replacement": "
schedule the scheduling settings from below are applied. If you select once the scan is run only once on start of the application (container) or after you update your settings."
+ }]
+ },
+ {
+ "function": "CMD",
+ "type": "text",
+ "default_value":"python3 /home/pi/pialert/front/plugins/dhcp_servers/script.py",
+ "options": [],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code":"en_us",
+ "string" : "Command"
+ }],
+ "description": [{
+ "language_code":"en_us",
+ "string" : "Command to run"
+ }]
+ },
+ {
+ "function": "RUN_SCHD",
+ "type": "text",
+ "default_value":"0 2 * * *",
+ "options": [],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code":"en_us",
+ "string" : "Schedule"
+ }],
+ "description": [{
+ "language_code":"en_us",
+ "string" : "Only enabled if you select schedule in the DHCPSRVS_RUN setting. Make sure you enter the schedule in the correct cron-like format (e.g. validate at crontab.guru). For example entering 0 4 * * * will run the scan after 4 am in the TIMEZONE you set above. Will be run NEXT time the time passes."
+ }]
+ },
+ {
+ "function": "RUN_TIMEOUT",
+ "type": "integer",
+ "default_value":5,
+ "options": [],
+ "localized": ["name", "description"],
+ "name" : [{
+ "language_code":"en_us",
+ "string" : "Run timeout"
+ },
+ {
+ "language_code":"de_de",
+ "string" : "Wartezeit"
+ }],
+ "description": [{
+ "language_code":"en_us",
+ "string" : "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
+ }]
+ },
+ {
+ "function": "WATCH",
+ "type": "multiselect",
+ "default_value":["Watched_Value1"],
+ "options": ["Watched_Value1","Watched_Value2","Watched_Value3","Watched_Value4"],
+ "localized": ["name", "description"],
+ "name" :[{
+ "language_code":"en_us",
+ "string" : "Watched"
+ }] ,
+ "description":[{
+ "language_code":"en_us",
+ "string" : "Send a notification if selected values change. Use CTRL + Click to select/deselect. Watched_Value1 is Domain Name ServerWatched_Value2 is IP OfferedWatched_Value3 is Interface Watched_Value4 is Router new means a new unique (unique combination of PrimaryId and SecondaryId) object was discovered. watched-changed means that selected Watched_ValueN columns changed."
+ }]
+ }
+ ]
+}
+
diff --git a/front/plugins/dhcp_servers/script.py b/front/plugins/dhcp_servers/script.py
new file mode 100755
index 00000000..947fd1b5
--- /dev/null
+++ b/front/plugins/dhcp_servers/script.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# Based on the work of https://github.com/leiweibau/Pi.Alert
+
+# /home/pi/pialert/front/plugins/website_monitor/script.py urls=http://google.com,http://bing.com
+from __future__ import unicode_literals
+from time import sleep, time, strftime
+import requests
+import pathlib
+import threading
+import subprocess
+import socket
+
+import argparse
+import io
+#import smtplib
+import sys
+#from smtp_config import sender, password, receivers, host, port
+from requests.packages.urllib3.exceptions import InsecureRequestWarning
+
+import pwd
+import os
+
+curPath = str(pathlib.Path(__file__).parent.resolve())
+log_file = curPath + '/script.log'
+last_run = curPath + '/last_result.log'
+
+print(last_run)
+
+# Workflow
+
+def main():
+
+ last_run_logfile = open(last_run, 'a')
+
+ timeoutSec = 10
+
+ nmapArgs = ['sudo', 'nmap', '--script', 'broadcast-dhcp-discover']
+
+ # Execute N probes and insert in list
+ dhcp_probes = 1 # N probes
+ newLines = []
+ newLines.append(strftime("%Y-%m-%d %H:%M:%S"))
+ #dhcp_server_list_time = []
+ for _ in range(dhcp_probes):
+ output = subprocess.check_output (nmapArgs, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeoutSec ))
+ # stream = os.popen('sudo nmap --script broadcast-dhcp-discover 2>/dev/null')
+ # output = stream.read()
+ # last_run_logfile.write(output)
+
+ newLines = newLines + output.split("\n")
+
+ # parse output
+ newEntries = []
+
+ duration = ""
+ for line in newLines:
+
+ if newEntries is None:
+ index = 0
+ else:
+ index = len(newEntries) - 1
+
+ if 'Response ' in line and ' of ' in line:
+
+ newEntries.append(plugin_object_class())
+
+ elif 'Server Identifier' in line :
+ newEntries[index].primaryId = line.split(':')[1].strip()
+
+
+ elif 'Domain Name' in line :
+ newEntries[index].secondaryId = line.split(':')[1].strip()
+ elif 'Domain Name Server' in line :
+ newEntries[index].watched1 = line.split(':')[1].strip()
+ elif 'IP Offered' in line :
+ newEntries[index].watched2 = line.split(':')[1].strip()
+ elif 'Interface' in line :
+ newEntries[index].watched3 = line.split(':')[1].strip()
+ elif 'Router' in line :
+ newEntries[index].watched4 = line.split(':')[1].strip()
+ newEntries[index].foreignKey = line.split(':')[1].strip()
+ elif ('IP Address Lease Time' in line or 'Subnet Mask' in line or 'Broadcast Address' in line) :
+ newEntries[index].extra = newEntries[index].extra + ',' + line.split(':')[1].strip()
+
+
+ for e in newEntries:
+ # Insert list into the log
+
+ service_monitoring_log(e.primaryId, e.secondaryId, e.created, e.watched1, e.watched2, e.watched3, e.watched4, e.extra, e.foreignKey )
+
+# -----------------------------------------------------------------------------
+def service_monitoring_log(primaryId, secondaryId, created, watched1, watched2 = '', watched3 = '', watched4 = '', extra ='', foreignKey ='' ):
+
+ if watched1 == '':
+ watched1 = 'null'
+ if watched2 == '':
+ watched2 = 'null'
+ if watched3 == '':
+ watched3 = 'null'
+ if watched4 == '':
+ watched4 = 'null'
+
+ with open(last_run, 'a') as last_run_logfile:
+ # https://www.duckduckgo.com|192.168.0.1|2023-01-02 15:56:30|200|0.9898|null|null|Best search engine|null
+ last_run_logfile.write("{}|{}|{}|{}|{}|{}|{}|{}|{}\n".format(
+ primaryId,
+ secondaryId,
+ created,
+ watched1,
+ watched2,
+ watched3,
+ watched4,
+ extra,
+ foreignKey
+ )
+ )
+
+# -------------------------------------------------------------------
+class plugin_object_class:
+ def __init__(self, primaryId = '',secondaryId = '', watched1 = '',watched2 = '',watched3 = '',watched4 = '',extra = '',foreignKey = ''):
+ self.pluginPref = ''
+ self.primaryId = primaryId
+ self.secondaryId = secondaryId
+ self.created = strftime("%Y-%m-%d %H:%M:%S")
+ self.changed = ''
+ self.watched1 = watched1
+ self.watched2 = watched2
+ self.watched3 = watched3
+ self.watched4 = watched4
+ self.status = ''
+ self.extra = extra
+ self.userData = ''
+ self.foreignKey = foreignKey
+
+#===============================================================================
+# BEGIN
+#===============================================================================
+if __name__ == '__main__':
+ sys.exit(main())
+
diff --git a/front/plugins/website_monitor/config.json b/front/plugins/website_monitor/config.json
index 52889a17..8e5ef3e2 100755
--- a/front/plugins/website_monitor/config.json
+++ b/front/plugins/website_monitor/config.json
@@ -73,7 +73,7 @@
}]
},
{
- "column": "Object_SecondaryD",
+ "column": "Object_SecondaryID",
"css_classes": "col-sm-2",
"show": false,
"type": "label",