mirror of
https://github.com/jokob-sk/NetAlertX.git
synced 2025-12-07 09:36:05 -08:00
convert pholus to plugin v0.2
This commit is contained in:
@@ -579,25 +579,7 @@
|
|||||||
"DDNS_PASSWORD_name" : "DynDNS password",
|
"DDNS_PASSWORD_name" : "DynDNS password",
|
||||||
"DDNS_PASSWORD_description" : "",
|
"DDNS_PASSWORD_description" : "",
|
||||||
"DDNS_UPDATE_URL_name" : "DynDNS update URL",
|
"DDNS_UPDATE_URL_name" : "DynDNS update URL",
|
||||||
"DDNS_UPDATE_URL_description" : "Update URL starting with <code>http://</code> or <code>https://</code>.",
|
"DDNS_UPDATE_URL_description" : "Update URL starting with <code>http://</code> or <code>https://</code>.",
|
||||||
"PiHole_display_name" : "PiHole",
|
|
||||||
"PiHole_icon" : "<i class=\"fa fa-seedling\"></i>",
|
|
||||||
"Pholus_display_name" : "Pholus",
|
|
||||||
"Pholus_icon" : "<i class=\"fa fa-search\"></i>",
|
|
||||||
"PHOLUS_ACTIVE_name" : "Cycle run",
|
|
||||||
"PHOLUS_ACTIVE_description" : "<a href=\"https://github.com/jokob-sk/Pi.Alert/tree/main/pholus\" target=\"_blank\" >Pholus</a> is a sniffing tool to discover additional information about the devices on the network, including the device name. If enabled this will execute the scan before every network scan cycle until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Please be aware it can spam the network with unnecessary traffic. Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>. For a scheduled or one-off scan, check the <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code> setting</a>.",
|
|
||||||
"PHOLUS_TIMEOUT_name" : "Cycle run timeout",
|
|
||||||
"PHOLUS_TIMEOUT_description" : "How long in seconds should Pholus be sniffing on each interface if above condition is fulfilled. The longer you leave it on, the more likely devices would broadcast more info. This timeout adds to the time it takes to perform an arp-scan on your network.",
|
|
||||||
"PHOLUS_FORCE_name" : "Cycle force scan",
|
|
||||||
"PHOLUS_FORCE_description" : "Force scan every network scan, even if there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Be careful enabling this as the sniffing can easily flood your network.",
|
|
||||||
"PHOLUS_RUN_name" : "Scheduled run",
|
|
||||||
"PHOLUS_RUN_description" : "Enable a regular Pholus scan / sniff on your network. The scheduling settings can be found below. If you select <code>once</code> Pholus is run only once on start for the time specified in <a href=\"#PHOLUS_RUN_TIMEOUT\"><code>PHOLUS_RUN_TIMEOUT</code> setting</a>.",
|
|
||||||
"PHOLUS_RUN_TIMEOUT_name" : "Scheduled run timeout",
|
|
||||||
"PHOLUS_RUN_TIMEOUT_description" : "The timeout in seconds for the scheduled Pholus scan. Same notes regarding the duration apply as on the <a href=\"#PHOLUS_TIMEOUT\"><code>PHOLUS_TIMEOUT</code> setting</a>. A scheduled scan doesn not check if there are <code>(unknown)</code> or <code>(name not found)</code> devices, the scan is executed either way.",
|
|
||||||
"PHOLUS_RUN_SCHD_name" : "Schedule",
|
|
||||||
"PHOLUS_RUN_SCHD_description" : "Only enabled if you select <code>schedule</code> in the <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>0 4 * * *</code> will run the scan after 4 am in the <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> you set above</a>. Will be run NEXT time the time passes.",
|
|
||||||
"PHOLUS_DAYS_DATA_name" : "Data retention",
|
|
||||||
"PHOLUS_DAYS_DATA_description" : "How many days of Pholus scan entries should be kept (globally, not device specific!) Enter <code>0</code> to disable.",
|
|
||||||
"Nmap_display_name" : "Nmap",
|
"Nmap_display_name" : "Nmap",
|
||||||
"Nmap_icon" : "<i class=\"fa fa-ethernet\"></i>",
|
"Nmap_icon" : "<i class=\"fa fa-ethernet\"></i>",
|
||||||
"NMAP_ACTIVE_name" : "Cycle run",
|
"NMAP_ACTIVE_name" : "Cycle run",
|
||||||
|
|||||||
@@ -573,24 +573,6 @@
|
|||||||
"DDNS_PASSWORD_description" : "",
|
"DDNS_PASSWORD_description" : "",
|
||||||
"DDNS_UPDATE_URL_name" : "URL de actualización de DynDNS",
|
"DDNS_UPDATE_URL_name" : "URL de actualización de DynDNS",
|
||||||
"DDNS_UPDATE_URL_description" : "Actualice la URL que comienza con <code>http://</code> o <code>https://</code>.",
|
"DDNS_UPDATE_URL_description" : "Actualice la URL que comienza con <code>http://</code> o <code>https://</code>.",
|
||||||
"PiHole_display_name" : "PiHole",
|
|
||||||
"PiHole_icon" : "<i class=\"fa fa-seedling\"></i>",
|
|
||||||
"Pholus_display_name" : "Pholus",
|
|
||||||
"Pholus_icon" : "<i class=\"fa fa-search\"></i>",
|
|
||||||
"PHOLUS_ACTIVE_name" : "Ejecución del ciclo",
|
|
||||||
"PHOLUS_ACTIVE_description" : "<a href=\"https://github.com/jokob-sk/Pi.Alert/tree/main/pholus\" target=\"_blank\" >Pholus</a> es una herramienta de rastreo para descubrir información adicional sobre los dispositivos en la red, incluido el nombre del dispositivo. Si está habilitado, ejecutará el escaneo antes de cada ciclo de escaneo de red hasta que no haya dispositivos <code>(unknown)</code> o <code>(name not found)</code>. Tenga en cuenta que puede enviar spam a la red con tráfico innecesario. Depende de la configuración de <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code></a>. Para un análisis programado o único, verifique la configuración de <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code></a>.",
|
|
||||||
"PHOLUS_TIMEOUT_name" : "Tiempo de espera de ciclo",
|
|
||||||
"PHOLUS_TIMEOUT_description" : "¿Cuánto tiempo en segundos debe rastrear Pholus en cada interfaz si se cumple la condición anterior? Cuanto más tiempo lo deje encendido, es más probable que los dispositivos transmitan más información. Este tiempo de espera se suma al tiempo que lleva realizar un escaneo arp en su red.",
|
|
||||||
"PHOLUS_FORCE_name" : "Escaneo de fuerza de ciclo",
|
|
||||||
"PHOLUS_FORCE_description" : "Fuerce el escaneo de cada escaneo de red, incluso si no hay dispositivos <code>(unknown)</code> o <code>(name not found)</code>. Tenga cuidado al habilitar esto, ya que la detección puede inundar fácilmente su red.",
|
|
||||||
"PHOLUS_RUN_name" : "Ejecución programada",
|
|
||||||
"PHOLUS_RUN_description" : "Habilite un escaneo regular de Pholus en su red. Los ajustes de programación se pueden encontrar a continuación. Si selecciona <code>una vez</code>, Pholus se ejecuta solo una vez al inicio durante el tiempo especificado en la configuración de <a href=\"#PHOLUS_RUN_TIMEOUT\"><code>PHOLUS_RUN_TIMEOUT</code></a>.",
|
|
||||||
"PHOLUS_RUN_TIMEOUT_name" : "Tiempo de espera de ejecución programado",
|
|
||||||
"PHOLUS_RUN_TIMEOUT_description" : "El tiempo de espera en segundos para el escaneo Pholus programado. Se aplican las mismas notas con respecto a la duración que en la configuración de <a href=\"#PHOLUS_TIMEOUT\"><code>PHOLUS_TIMEOUT</code></a>. Un escaneo programado no verifica si hay dispositivos <code>(unknown)</code> o <code>(name not found)</code>, el escaneo se ejecuta de cualquier manera.",
|
|
||||||
"PHOLUS_RUN_SCHD_name" : "Programar",
|
|
||||||
"PHOLUS_RUN_SCHD_description" : "Solo está habilitado si selecciona <code>programar</code> en la configuración de <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code></a>. Asegúrese de ingresar el horario en el formato similar a cron correcto(por ejemplo, validar en <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). Por ejemplo, ingresar <code>0 4 * * *</code> ejecutará el escaneo después de las 4 am en el <a onclick=\"toggleAllSettings()\" href=\"#TIMEZONE\"><code>TIMEZONE</code> que configuró arriba</a>. Se ejecutará la PRÓXIMA vez que pase el tiempo.",
|
|
||||||
"PHOLUS_DAYS_DATA_name" : "Retención de datos",
|
|
||||||
"PHOLUS_DAYS_DATA_description" : "Cuántos días de entradas de escaneo de Pholus deben conservarse (globalmente, ¡no específico del dispositivo!). El archivo <a href=\"/maintenance.php#tab_Logging\">pialert_pholus.log</a> no se modifica. Introduzca <code>0</code> para desactivar.",
|
|
||||||
"Nmap_display_name" : "Nmap",
|
"Nmap_display_name" : "Nmap",
|
||||||
"Nmap_icon" : "<i class=\"fa fa-ethernet\"></i>",
|
"Nmap_icon" : "<i class=\"fa fa-ethernet\"></i>",
|
||||||
"NMAP_ACTIVE_name" : "Ejecución del ciclo",
|
"NMAP_ACTIVE_name" : "Ejecución del ciclo",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
{
|
{
|
||||||
"name" : "timeout",
|
"name" : "timeout",
|
||||||
"type" : "setting",
|
"type" : "setting",
|
||||||
"value" : "RUN_TIMEOUT"
|
"value" : "PHOLUS_RUN_TIMEOUT"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -68,10 +68,16 @@
|
|||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Cuando ejecutar"
|
"string" : "Cuando ejecutar"
|
||||||
}],
|
}],
|
||||||
"description": [{
|
"description": [
|
||||||
|
{
|
||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Specify when your Name-discovery scan will run. Typical setting would be <code>on_new_device</code> or <code>schedule</code> and then you specify a cron-like schedule in the <a href=\"#PHOLUS_RUN_SCHD\"><code>PHOLUS_RUN_SCHD</code>setting</a>."
|
"string" : "<a href=\"https://github.com/jokob-sk/Pi.Alert/tree/main/pholus\" target=\"_blank\" >Pholus</a> is a sniffing tool to discover additional information about the devices on the network, including the device name. If enabled this will execute the scan before every network scan cycle until there are no <code>(unknown)</code> or <code>(name not found)</code> devices. Please be aware it can spam the network with unnecessary traffic. Depends on the <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code> setting</a>. For a scheduled or one-off scan, check the <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code> setting</a>.Specify when your Name-discovery scan will run. Typical setting would be <code>on_new_device</code> or <code>schedule</code> and then you specify a cron-like schedule in the <a href=\"#PHOLUS_RUN_SCHD\"><code>PHOLUS_RUN_SCHD</code>setting</a>."
|
||||||
}]
|
},
|
||||||
|
{
|
||||||
|
"language_code":"es_es",
|
||||||
|
"string" : "<a href=\"https://github.com/jokob-sk/Pi.Alert/tree/main/pholus\" target=\"_blank\" >Pholus</a> es una herramienta de rastreo para descubrir información adicional sobre los dispositivos en la red, incluido el nombre del dispositivo. Si está habilitado, ejecutará el escaneo antes de cada ciclo de escaneo de red hasta que no haya dispositivos <code>(unknown)</code> o <code>(name not found)</code>. Tenga en cuenta que puede enviar spam a la red con tráfico innecesario. Depende de la configuración de <a onclick=\"toggleAllSettings()\" href=\"#SCAN_SUBNETS\"><code>SCAN_SUBNETS</code></a>. Para un análisis programado o único, verifique la configuración de <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code></a>."
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"function": "CMD",
|
"function": "CMD",
|
||||||
@@ -134,7 +140,7 @@
|
|||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Schedule"
|
"string" : "Schedule"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Schedule"
|
"string" : "Schedule"
|
||||||
}],
|
}],
|
||||||
@@ -143,6 +149,31 @@
|
|||||||
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>30 3 * * *</code> will run the scan at 3:30 am. Will be run NEXT time the time passes. <br/>"
|
"string" : "Only enabled if you select <code>schedule</code> in the <a href=\"#PHOLUS_RUN\"><code>PHOLUS_RUN</code> setting</a>. Make sure you enter the schedule in the correct cron-like format (e.g. validate at <a href=\"https://crontab.guru/\" target=\"_blank\">crontab.guru</a>). For example entering <code>30 3 * * *</code> will run the scan at 3:30 am. Will be run NEXT time the time passes. <br/>"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"function": "DAYS_DATA",
|
||||||
|
"type": "integer",
|
||||||
|
"default_value":30,
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name", "description"],
|
||||||
|
"name" : [{
|
||||||
|
"language_code":"en_us",
|
||||||
|
"string" : "Schedule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code":"es_es",
|
||||||
|
"string" : "Retención de datos"
|
||||||
|
}],
|
||||||
|
"description": [
|
||||||
|
{
|
||||||
|
"language_code":"en_us",
|
||||||
|
"string" : "How many days of Pholus scan entries should be kept (globally, not device specific!) Enter <code>0</code> to disable."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"language_code":"es_es",
|
||||||
|
"string" : "Cuántos días de entradas de escaneo de Pholus deben conservarse (globalmente, ¡no específico del dispositivo!). El archivo <a href=\"/maintenance.php#tab_Logging\">pialert_pholus.log</a> no se modifica. Introduzca <code>0</code> para desactivar."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"function": "WATCH",
|
"function": "WATCH",
|
||||||
"type": "text.multiselect",
|
"type": "text.multiselect",
|
||||||
@@ -153,13 +184,13 @@
|
|||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Watched"
|
"string" : "Watched"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Watched"
|
"string" : "Watched"
|
||||||
}] ,
|
}] ,
|
||||||
"description":[{
|
"description":[{
|
||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is TBC</li><li><code>Watched_Value2</code> is TBC</li><li><code>Watched_Value3</code> is TBC </li><li><code>Watched_Value4</code> is TBC </li></ul>"
|
"string" : "Send a notification if selected values change. Use <code>CTRL + Click</code> to select/deselect. <ul> <li><code>Watched_Value1</code> is Info</li><li><code>Watched_Value2</code> is Record type</li><li><code>Watched_Value3</code> is Info </li><li><code>Watched_Value4</code> is N/A </li></ul>"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -195,7 +226,7 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"column": "Object_PrimaryID",
|
"column": "Object_PrimaryID",
|
||||||
"mapped_to_column": "cur_MAC",
|
"mapped_to_column": "MAC",
|
||||||
"css_classes": "col-sm-2",
|
"css_classes": "col-sm-2",
|
||||||
"show": true,
|
"show": true,
|
||||||
"type": "device_name_mac",
|
"type": "device_name_mac",
|
||||||
@@ -212,11 +243,11 @@
|
|||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"column": "Watched_Value1",
|
"column": "Object_SecondaryID",
|
||||||
"mapped_to_column": "cur_IP",
|
"mapped_to_column": "IP_v4_or_v6",
|
||||||
"css_classes": "col-sm-2",
|
"css_classes": "col-sm-2",
|
||||||
"show": true,
|
"show": true,
|
||||||
"type": "device_ip",
|
"type": "label",
|
||||||
"default_value":"",
|
"default_value":"",
|
||||||
"options": [],
|
"options": [],
|
||||||
"localized": ["name"],
|
"localized": ["name"],
|
||||||
@@ -224,14 +255,14 @@
|
|||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "IP"
|
"string" : "IP"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "IP"
|
"string" : "IP"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"column": "Watched_Value2",
|
"column": "Watched_Value1",
|
||||||
"mapped_to_column": "cur_Vendor",
|
"mapped_to_column": "Info",
|
||||||
"css_classes": "col-sm-2",
|
"css_classes": "col-sm-2",
|
||||||
"show": true,
|
"show": true,
|
||||||
"type": "label",
|
"type": "label",
|
||||||
@@ -240,16 +271,30 @@
|
|||||||
"localized": ["name"],
|
"localized": ["name"],
|
||||||
"name":[{
|
"name":[{
|
||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Vendor"
|
"string" : "Info"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Proveedor"
|
"string" : "Info"
|
||||||
|
}]
|
||||||
|
} ,
|
||||||
|
{
|
||||||
|
"column": "Watched_Value2",
|
||||||
|
"mapped_to_column": "Record_Type",
|
||||||
|
"css_classes": "col-sm-2",
|
||||||
|
"show": true,
|
||||||
|
"type": "label",
|
||||||
|
"default_value":"",
|
||||||
|
"options": [],
|
||||||
|
"localized": ["name"],
|
||||||
|
"name":[{
|
||||||
|
"language_code":"en_us",
|
||||||
|
"string" : "Type"
|
||||||
}]
|
}]
|
||||||
} ,
|
} ,
|
||||||
{
|
{
|
||||||
"column": "Extra",
|
"column": "Watched_Value3",
|
||||||
"mapped_to_column": "cur_ScanMethod",
|
"mapped_to_column": "Value",
|
||||||
"css_classes": "col-sm-2",
|
"css_classes": "col-sm-2",
|
||||||
"show": true,
|
"show": true,
|
||||||
"type": "label",
|
"type": "label",
|
||||||
@@ -258,15 +303,16 @@
|
|||||||
"localized": ["name"],
|
"localized": ["name"],
|
||||||
"name":[{
|
"name":[{
|
||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Scan method"
|
"string" : "Info"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Método de escaneado"
|
"string" : "Info"
|
||||||
}]
|
}]
|
||||||
} ,
|
},
|
||||||
{
|
{
|
||||||
"column": "DateTimeCreated",
|
"column": "DateTimeCreated",
|
||||||
|
"mapped_to_column": "Time",
|
||||||
"css_classes": "col-sm-2",
|
"css_classes": "col-sm-2",
|
||||||
"show": true,
|
"show": true,
|
||||||
"type": "label",
|
"type": "label",
|
||||||
@@ -330,7 +376,7 @@
|
|||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Status"
|
"string" : "Status"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
"string" : "Estado"
|
"string" : "Estado"
|
||||||
}]
|
}]
|
||||||
@@ -15,6 +15,7 @@ sys.path.append('/home/pi/pialert/pialert')
|
|||||||
|
|
||||||
from logger import mylog
|
from logger import mylog
|
||||||
from plugin_helper import Plugin_Object, Plugin_Objects
|
from plugin_helper import Plugin_Object, Plugin_Objects
|
||||||
|
from helper import timeNowTZ
|
||||||
from const import fullPholusPath, logPath
|
from const import fullPholusPath, logPath
|
||||||
|
|
||||||
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
CUR_PATH = str(pathlib.Path(__file__).parent.resolve())
|
||||||
@@ -159,7 +160,7 @@ def execute_pholus_on_interface(interface, timeoutSec, mask):
|
|||||||
mylog('verbose', ['[PholusScan] Scan: Pholus SUCCESS'])
|
mylog('verbose', ['[PholusScan] Scan: Pholus SUCCESS'])
|
||||||
|
|
||||||
# check the last run output
|
# check the last run output
|
||||||
f = open(CUR_PATH + '/pialert_pholus_lastrun.log', 'r+')
|
f = open(logPath + '/pialert_pholus_lastrun.log', 'r+')
|
||||||
newLines = f.read().split('\n')
|
newLines = f.read().split('\n')
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
@@ -173,102 +174,13 @@ def execute_pholus_on_interface(interface, timeoutSec, mask):
|
|||||||
columns = line.split("|")
|
columns = line.split("|")
|
||||||
if len(columns) == 4:
|
if len(columns) == 4:
|
||||||
# "Info", "Time", "MAC", "IP_v4_or_v6", "Record_Type", "Value"
|
# "Info", "Time", "MAC", "IP_v4_or_v6", "Record_Type", "Value"
|
||||||
params.append( interface + " " + mask, timeNowTZ() , columns[0].replace(" ", ""), columns[1].replace(" ", ""), columns[2].replace(" ", ""), columns[3])
|
params.append( [interface + " " + mask, timeNowTZ() , columns[0].replace(" ", ""), columns[1].replace(" ", ""), columns[2].replace(" ", ""), columns[3]])
|
||||||
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def cleanResult(str):
|
|
||||||
# alternative str.split('.')[0]
|
|
||||||
str = str.replace("._airplay", "")
|
|
||||||
str = str.replace("._tcp", "")
|
|
||||||
str = str.replace(".local", "")
|
|
||||||
str = str.replace("._esphomelib", "")
|
|
||||||
str = str.replace("._googlecast", "")
|
|
||||||
str = str.replace(".lan", "")
|
|
||||||
str = str.replace(".home", "")
|
|
||||||
str = re.sub(r'-[a-fA-F0-9]{32}', '', str) # removing last part of e.g. Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77
|
|
||||||
str = re.sub(r'#.*', '', str) # Remove everything after '#' including the '#'
|
|
||||||
# remove trailing dots
|
|
||||||
if str.endswith('.'):
|
|
||||||
str = str[:-1]
|
|
||||||
|
|
||||||
return str
|
|
||||||
|
|
||||||
|
|
||||||
# Disclaimer - I'm interfacing with a script I didn't write (pholus3.py) so it's possible I'm missing types of answers
|
|
||||||
# it's also possible the pholus3.py script can be adjusted to provide a better output to interface with it
|
|
||||||
# Hit me with a PR if you know how! :)
|
|
||||||
def resolve_device_name_pholus (pMAC, pIP, allRes):
|
|
||||||
|
|
||||||
pholusMatchesIndexes = []
|
|
||||||
|
|
||||||
index = 0
|
|
||||||
for result in allRes:
|
|
||||||
# limiting entries used for name resolution to the ones containing the current IP (v4 only)
|
|
||||||
if result["MAC"] == pMAC and result["Record_Type"] == "Answer" and result["IP_v4_or_v6"] == pIP and '._googlezone' not in result["Value"]:
|
|
||||||
# found entries with a matching MAC address, let's collect indexes
|
|
||||||
pholusMatchesIndexes.append(index)
|
|
||||||
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
# return if nothing found
|
|
||||||
if len(pholusMatchesIndexes) == 0:
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# we have some entries let's try to select the most useful one
|
|
||||||
|
|
||||||
# airplay matches contain a lot of information
|
|
||||||
# Matches for example:
|
|
||||||
# Brand Tv (50)._airplay._tcp.local. TXT Class:32769 "acl=0 deviceid=66:66:66:66:66:66 features=0x77777,0x38BCB46 rsf=0x3 fv=p20.T-FFFFFF-03.1 flags=0x204 model=XXXX manufacturer=Brand serialNumber=XXXXXXXXXXX protovers=1.1 srcvers=777.77.77 pi=FF:FF:FF:FF:FF:FF psi=00000000-0000-0000-0000-FFFFFFFFFF gid=00000000-0000-0000-0000-FFFFFFFFFF gcgl=0 pk=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '._airplay._tcp.local. TXT Class:32769' in str(allRes[i]["Value"]) :
|
|
||||||
return allRes[i]["Value"].split('._airplay._tcp.local. TXT Class:32769')[0]
|
|
||||||
|
|
||||||
# second best - contains airplay
|
|
||||||
# Matches for example:
|
|
||||||
# _airplay._tcp.local. PTR Class:IN "Brand Tv (50)._airplay._tcp.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '_airplay._tcp.local. PTR Class:IN' in allRes[i]["Value"] and ('._googlecast') not in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
# Contains PTR Class:32769
|
|
||||||
# Matches for example:
|
|
||||||
# 3.1.168.192.in-addr.arpa. PTR Class:32769 "MyPc.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'PTR Class:32769' in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
# Contains AAAA Class:IN
|
|
||||||
# Matches for example:
|
|
||||||
# DESKTOP-SOMEID.local. AAAA Class:IN "fe80::fe80:fe80:fe80:fe80"
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'AAAA Class:IN' in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('.local.')[0])
|
|
||||||
|
|
||||||
# Contains _googlecast._tcp.local. PTR Class:IN
|
|
||||||
# Matches for example:
|
|
||||||
# _googlecast._tcp.local. PTR Class:IN "Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77._googlecast._tcp.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '_googlecast._tcp.local. PTR Class:IN' in allRes[i]["Value"] and ('Google-Cast-Group') not in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
# Contains A Class:32769
|
|
||||||
# Matches for example:
|
|
||||||
# Android.local. A Class:32769 "192.168.1.6"
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and ' A Class:32769' in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split(' A Class:32769')[0])
|
|
||||||
|
|
||||||
# # Contains PTR Class:IN
|
|
||||||
# Matches for example:
|
|
||||||
# _esphomelib._tcp.local. PTR Class:IN "ceiling-light-1._esphomelib._tcp.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'PTR Class:IN' in allRes[i]["Value"]:
|
|
||||||
if allRes[i]["Value"] and len(allRes[i]["Value"].split('"')) > 1:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
return -1
|
|
||||||
|
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
}],
|
}],
|
||||||
"description": [{
|
"description": [{
|
||||||
"language_code":"en_us",
|
"language_code":"en_us",
|
||||||
"string" : "Este complemento se utiliza para descubrir dispositivos a través de las tablas arp de un enrutador o conmutador compatible con RFC1213.."
|
"string" : "This plugin is used to discover devices via the arp table(s) of a RFC1213 compliant router or switch."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"language_code":"es_es",
|
"language_code":"es_es",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ $result = $db->query("SELECT * FROM Settings");
|
|||||||
|
|
||||||
// array
|
// array
|
||||||
$settingKeyOfLists = array();
|
$settingKeyOfLists = array();
|
||||||
$settingCoreGroups = array('General', 'NewDeviceDefaults', 'Email', 'Webhooks', 'Apprise', 'NTFY', 'PUSHSAFER', 'MQTT', 'DynDNS', 'PiHole', 'Pholus', 'Nmap', 'API');
|
$settingCoreGroups = array('General', 'NewDeviceDefaults', 'Email', 'Webhooks', 'Apprise', 'NTFY', 'PUSHSAFER', 'MQTT', 'DynDNS', 'PiHole', 'Nmap', 'API');
|
||||||
$settings = array();
|
$settings = array();
|
||||||
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
while ($row = $result -> fetchArray (SQLITE3_ASSOC)) {
|
||||||
// Push row data
|
// Push row data
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import multiprocessing
|
|||||||
import conf
|
import conf
|
||||||
from const import *
|
from const import *
|
||||||
from logger import mylog
|
from logger import mylog
|
||||||
from helper import filePermissions, isNewVersion, timeNowTZ, updateState
|
from helper import filePermissions, isNewVersion, timeNowTZ, updateState, get_setting_value
|
||||||
from api import update_api
|
from api import update_api
|
||||||
from networkscan import process_scan
|
from networkscan import process_scan
|
||||||
from initialise import importConfigs
|
from initialise import importConfigs
|
||||||
@@ -34,7 +34,6 @@ from reporting import check_and_run_event, send_notifications
|
|||||||
from plugin import run_plugin_scripts
|
from plugin import run_plugin_scripts
|
||||||
|
|
||||||
# different scanners
|
# different scanners
|
||||||
from scanners.pholusscan import performPholusScan
|
|
||||||
from scanners.nmapscan import performNmapScan
|
from scanners.nmapscan import performNmapScan
|
||||||
from scanners.internet import check_internet_IP
|
from scanners.internet import check_internet_IP
|
||||||
|
|
||||||
@@ -60,7 +59,6 @@ main structure of Pi Alert
|
|||||||
run plugins (scheduled)
|
run plugins (scheduled)
|
||||||
check internet IP
|
check internet IP
|
||||||
check vendor
|
check vendor
|
||||||
run PHOLUS
|
|
||||||
run NMAP
|
run NMAP
|
||||||
run "scan_network()"
|
run "scan_network()"
|
||||||
processing scan results
|
processing scan results
|
||||||
@@ -161,25 +159,7 @@ def main ():
|
|||||||
conf.last_update_vendors = loop_start_time
|
conf.last_update_vendors = loop_start_time
|
||||||
conf.cycle = 'update_vendors'
|
conf.cycle = 'update_vendors'
|
||||||
mylog('verbose', ['[MAIN] cycle:',conf.cycle])
|
mylog('verbose', ['[MAIN] cycle:',conf.cycle])
|
||||||
update_devices_MAC_vendors(db)
|
update_devices_MAC_vendors(db)
|
||||||
|
|
||||||
# Execute scheduled or one-off Pholus scan if enabled and run conditions fulfilled
|
|
||||||
if conf.PHOLUS_RUN == "schedule" or conf.PHOLUS_RUN == "once":
|
|
||||||
|
|
||||||
pholusSchedule = [sch for sch in conf.mySchedules if sch.service == "pholus"][0]
|
|
||||||
run = False
|
|
||||||
|
|
||||||
# run once after application starts
|
|
||||||
if conf.PHOLUS_RUN == "once" and pholusSchedule.last_run == 0:
|
|
||||||
run = True
|
|
||||||
|
|
||||||
# run if overdue scheduled time
|
|
||||||
if conf.PHOLUS_RUN == "schedule":
|
|
||||||
run = pholusSchedule.runScheduleCheck()
|
|
||||||
|
|
||||||
if run:
|
|
||||||
pholusSchedule.last_run = datetime.datetime.now(conf.tz).replace(microsecond=0)
|
|
||||||
performPholusScan(db, conf.PHOLUS_RUN_TIMEOUT, conf.userSubnets)
|
|
||||||
|
|
||||||
# Execute scheduled or one-off Nmap scan if enabled and run conditions fulfilled
|
# Execute scheduled or one-off Nmap scan if enabled and run conditions fulfilled
|
||||||
if conf.NMAP_RUN == "schedule" or conf.NMAP_RUN == "once":
|
if conf.NMAP_RUN == "schedule" or conf.NMAP_RUN == "once":
|
||||||
@@ -236,7 +216,7 @@ def main ():
|
|||||||
conf.last_cleanup = loop_start_time
|
conf.last_cleanup = loop_start_time
|
||||||
conf.cycle = 'cleanup'
|
conf.cycle = 'cleanup'
|
||||||
mylog('verbose', ['[MAIN] cycle:',conf.cycle])
|
mylog('verbose', ['[MAIN] cycle:',conf.cycle])
|
||||||
db.cleanup_database(startTime, conf.DAYS_TO_KEEP_EVENTS, conf.PHOLUS_DAYS_DATA, conf.HRS_TO_KEEP_NEWDEV, conf.PLUGINS_KEEP_HIST)
|
db.cleanup_database(startTime, conf.DAYS_TO_KEEP_EVENTS, get_setting_value('PHOLUS_DAYS_DATA'), conf.HRS_TO_KEEP_NEWDEV, conf.PLUGINS_KEEP_HIST)
|
||||||
|
|
||||||
# Commit SQL
|
# Commit SQL
|
||||||
db.commitDB()
|
db.commitDB()
|
||||||
|
|||||||
@@ -103,15 +103,6 @@ DDNS_USER = 'dynu_user'
|
|||||||
DDNS_PASSWORD = 'A0000000B0000000C0000000D0000000'
|
DDNS_PASSWORD = 'A0000000B0000000C0000000D0000000'
|
||||||
DDNS_UPDATE_URL = 'https://api.dynu.com/nic/update?'
|
DDNS_UPDATE_URL = 'https://api.dynu.com/nic/update?'
|
||||||
|
|
||||||
# PHOLUS
|
|
||||||
PHOLUS_ACTIVE = False
|
|
||||||
PHOLUS_TIMEOUT = 20
|
|
||||||
PHOLUS_FORCE = False
|
|
||||||
PHOLUS_RUN = 'once'
|
|
||||||
PHOLUS_RUN_TIMEOUT = 600
|
|
||||||
PHOLUS_RUN_SCHD = '0 4 * * *'
|
|
||||||
PHOLUS_DAYS_DATA = 0
|
|
||||||
|
|
||||||
# Nmap
|
# Nmap
|
||||||
NMAP_ACTIVE = True
|
NMAP_ACTIVE = True
|
||||||
NMAP_TIMEOUT = 150
|
NMAP_TIMEOUT = 150
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import subprocess
|
|||||||
|
|
||||||
import conf
|
import conf
|
||||||
import re
|
import re
|
||||||
from helper import timeNowTZ, get_setting, get_setting_value
|
from helper import timeNowTZ, get_setting, get_setting_value,resolve_device_name_dig, resolve_device_name_pholus
|
||||||
from scanners.internet import check_IP_format, get_internet_IP
|
from scanners.internet import check_IP_format, get_internet_IP
|
||||||
from logger import mylog, print_log
|
from logger import mylog, print_log
|
||||||
from mac_vendor import query_MAC_vendor
|
from mac_vendor import query_MAC_vendor
|
||||||
from scanners.pholusscan import performPholusScan, resolve_device_name_dig, resolve_device_name_pholus
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
@@ -363,10 +363,6 @@ def update_devices_names (db):
|
|||||||
unknownDevices = sql.fetchall()
|
unknownDevices = sql.fetchall()
|
||||||
db.commitDB()
|
db.commitDB()
|
||||||
|
|
||||||
# perform Pholus scan if (unknown) devices found
|
|
||||||
if conf.PHOLUS_ACTIVE and (len(unknownDevices) > 0 or conf.PHOLUS_FORCE):
|
|
||||||
performPholusScan(db, conf.PHOLUS_TIMEOUT, conf.userSubnets)
|
|
||||||
|
|
||||||
# skip checks if no unknown devices
|
# skip checks if no unknown devices
|
||||||
if len(unknownDevices) == 0 and conf.PHOLUS_FORCE == False:
|
if len(unknownDevices) == 0 and conf.PHOLUS_FORCE == False:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import datetime
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import pytz
|
||||||
from pytz import timezone
|
from pytz import timezone
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import json
|
import json
|
||||||
@@ -20,7 +21,12 @@ from logger import mylog, logResult
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def timeNowTZ():
|
def timeNowTZ():
|
||||||
return datetime.datetime.now(conf.tz).replace(microsecond=0)
|
if isinstance(conf.TIMEZONE, str):
|
||||||
|
tz = pytz.timezone(conf.TIMEZONE)
|
||||||
|
else:
|
||||||
|
tz = conf.TIMEZONE
|
||||||
|
|
||||||
|
return datetime.datetime.now(tz).replace(microsecond=0)
|
||||||
|
|
||||||
def timeNow():
|
def timeNow():
|
||||||
return datetime.datetime.now().replace(microsecond=0)
|
return datetime.datetime.now().replace(microsecond=0)
|
||||||
@@ -370,4 +376,135 @@ def get_setting_value(key):
|
|||||||
|
|
||||||
return setVal
|
return setVal
|
||||||
|
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
# Disclaimer - I'm interfacing with a script I didn't write (pholus3.py) so it's possible I'm missing types of answers
|
||||||
|
# it's also possible the pholus3.py script can be adjusted to provide a better output to interface with it
|
||||||
|
# Hit me with a PR if you know how! :)
|
||||||
|
def resolve_device_name_pholus (pMAC, pIP, allRes):
|
||||||
|
|
||||||
|
pholusMatchesIndexes = []
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
for result in allRes:
|
||||||
|
# limiting entries used for name resolution to the ones containing the current IP (v4 only)
|
||||||
|
if result["MAC"] == pMAC and result["Record_Type"] == "Answer" and result["IP_v4_or_v6"] == pIP and '._googlezone' not in result["Value"]:
|
||||||
|
# found entries with a matching MAC address, let's collect indexes
|
||||||
|
pholusMatchesIndexes.append(index)
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
# return if nothing found
|
||||||
|
if len(pholusMatchesIndexes) == 0:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# we have some entries let's try to select the most useful one
|
||||||
|
|
||||||
|
# airplay matches contain a lot of information
|
||||||
|
# Matches for example:
|
||||||
|
# Brand Tv (50)._airplay._tcp.local. TXT Class:32769 "acl=0 deviceid=66:66:66:66:66:66 features=0x77777,0x38BCB46 rsf=0x3 fv=p20.T-FFFFFF-03.1 flags=0x204 model=XXXX manufacturer=Brand serialNumber=XXXXXXXXXXX protovers=1.1 srcvers=777.77.77 pi=FF:FF:FF:FF:FF:FF psi=00000000-0000-0000-0000-FFFFFFFFFF gid=00000000-0000-0000-0000-FFFFFFFFFF gcgl=0 pk=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '._airplay._tcp.local. TXT Class:32769' in str(allRes[i]["Value"]) :
|
||||||
|
return allRes[i]["Value"].split('._airplay._tcp.local. TXT Class:32769')[0]
|
||||||
|
|
||||||
|
# second best - contains airplay
|
||||||
|
# Matches for example:
|
||||||
|
# _airplay._tcp.local. PTR Class:IN "Brand Tv (50)._airplay._tcp.local."
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '_airplay._tcp.local. PTR Class:IN' in allRes[i]["Value"] and ('._googlecast') not in allRes[i]["Value"]:
|
||||||
|
return cleanResult(allRes[i]["Value"].split('"')[1])
|
||||||
|
|
||||||
|
# Contains PTR Class:32769
|
||||||
|
# Matches for example:
|
||||||
|
# 3.1.168.192.in-addr.arpa. PTR Class:32769 "MyPc.local."
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'PTR Class:32769' in allRes[i]["Value"]:
|
||||||
|
return cleanResult(allRes[i]["Value"].split('"')[1])
|
||||||
|
|
||||||
|
# Contains AAAA Class:IN
|
||||||
|
# Matches for example:
|
||||||
|
# DESKTOP-SOMEID.local. AAAA Class:IN "fe80::fe80:fe80:fe80:fe80"
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'AAAA Class:IN' in allRes[i]["Value"]:
|
||||||
|
return cleanResult(allRes[i]["Value"].split('.local.')[0])
|
||||||
|
|
||||||
|
# Contains _googlecast._tcp.local. PTR Class:IN
|
||||||
|
# Matches for example:
|
||||||
|
# _googlecast._tcp.local. PTR Class:IN "Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77._googlecast._tcp.local."
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '_googlecast._tcp.local. PTR Class:IN' in allRes[i]["Value"] and ('Google-Cast-Group') not in allRes[i]["Value"]:
|
||||||
|
return cleanResult(allRes[i]["Value"].split('"')[1])
|
||||||
|
|
||||||
|
# Contains A Class:32769
|
||||||
|
# Matches for example:
|
||||||
|
# Android.local. A Class:32769 "192.168.1.6"
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and ' A Class:32769' in allRes[i]["Value"]:
|
||||||
|
return cleanResult(allRes[i]["Value"].split(' A Class:32769')[0])
|
||||||
|
|
||||||
|
# # Contains PTR Class:IN
|
||||||
|
# Matches for example:
|
||||||
|
# _esphomelib._tcp.local. PTR Class:IN "ceiling-light-1._esphomelib._tcp.local."
|
||||||
|
for i in pholusMatchesIndexes:
|
||||||
|
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'PTR Class:IN' in allRes[i]["Value"]:
|
||||||
|
if allRes[i]["Value"] and len(allRes[i]["Value"].split('"')) > 1:
|
||||||
|
return cleanResult(allRes[i]["Value"].split('"')[1])
|
||||||
|
|
||||||
|
return -1
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def resolve_device_name_dig (pMAC, pIP):
|
||||||
|
|
||||||
|
newName = ""
|
||||||
|
|
||||||
|
try :
|
||||||
|
dig_args = ['dig', '+short', '-x', pIP]
|
||||||
|
|
||||||
|
# Execute command
|
||||||
|
try:
|
||||||
|
# try runnning a subprocess
|
||||||
|
newName = subprocess.check_output (dig_args, universal_newlines=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
# An error occured, handle it
|
||||||
|
mylog('none', ['[device_name_dig] ', e.output])
|
||||||
|
# newName = "Error - check logs"
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Check returns
|
||||||
|
newName = newName.strip()
|
||||||
|
|
||||||
|
if len(newName) == 0 :
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
newName = cleanResult(newName)
|
||||||
|
|
||||||
|
if newName == "" or len(newName) == 0:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
# Return newName
|
||||||
|
return newName
|
||||||
|
|
||||||
|
# not Found
|
||||||
|
except subprocess.CalledProcessError :
|
||||||
|
return -1
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
def cleanResult(str):
|
||||||
|
# alternative str.split('.')[0]
|
||||||
|
str = str.replace("._airplay", "")
|
||||||
|
str = str.replace("._tcp", "")
|
||||||
|
str = str.replace(".local", "")
|
||||||
|
str = str.replace("._esphomelib", "")
|
||||||
|
str = str.replace("._googlecast", "")
|
||||||
|
str = str.replace(".lan", "")
|
||||||
|
str = str.replace(".home", "")
|
||||||
|
str = re.sub(r'-[a-fA-F0-9]{32}', '', str) # removing last part of e.g. Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77
|
||||||
|
str = re.sub(r'#.*', '', str) # Remove everything after '#' including the '#'
|
||||||
|
# remove trailing dots
|
||||||
|
if str.endswith('.'):
|
||||||
|
str = str[:-1]
|
||||||
|
|
||||||
|
return str
|
||||||
@@ -154,15 +154,6 @@ def importConfigs (db):
|
|||||||
conf.DDNS_PASSWORD = ccd('DDNS_PASSWORD', 'A0000000B0000000C0000000D0000000' , c_d, 'DynDNS password', 'password', '', 'DynDNS')
|
conf.DDNS_PASSWORD = ccd('DDNS_PASSWORD', 'A0000000B0000000C0000000D0000000' , c_d, 'DynDNS password', 'password', '', 'DynDNS')
|
||||||
conf.DDNS_UPDATE_URL = ccd('DDNS_UPDATE_URL', 'https://api.dynu.com/nic/update?' , c_d, 'DynDNS update URL', 'text', '', 'DynDNS')
|
conf.DDNS_UPDATE_URL = ccd('DDNS_UPDATE_URL', 'https://api.dynu.com/nic/update?' , c_d, 'DynDNS update URL', 'text', '', 'DynDNS')
|
||||||
|
|
||||||
# PHOLUS
|
|
||||||
conf.PHOLUS_ACTIVE = ccd('PHOLUS_ACTIVE', False , c_d, 'Enable Pholus scans', 'boolean', '', 'Pholus')
|
|
||||||
conf.PHOLUS_TIMEOUT = ccd('PHOLUS_TIMEOUT', 20 , c_d, 'Pholus timeout', 'integer', '', 'Pholus')
|
|
||||||
conf.PHOLUS_FORCE = ccd('PHOLUS_FORCE', False , c_d, 'Pholus force check', 'boolean', '', 'Pholus')
|
|
||||||
conf.PHOLUS_RUN = ccd('PHOLUS_RUN', 'once' , c_d, 'Pholus enable schedule', 'text.select', "['disabled', 'once', 'schedule']", 'Pholus')
|
|
||||||
conf.PHOLUS_RUN_TIMEOUT = ccd('PHOLUS_RUN_TIMEOUT', 600 , c_d, 'Pholus timeout schedule', 'integer', '', 'Pholus')
|
|
||||||
conf.PHOLUS_RUN_SCHD = ccd('PHOLUS_RUN_SCHD', '0 4 * * *' , c_d, 'Pholus schedule', 'text', '', 'Pholus')
|
|
||||||
conf.PHOLUS_DAYS_DATA = ccd('PHOLUS_DAYS_DATA', 0 , c_d, 'Pholus keep days', 'integer', '', 'Pholus')
|
|
||||||
|
|
||||||
# Nmap
|
# Nmap
|
||||||
conf.NMAP_ACTIVE = ccd('NMAP_ACTIVE', True , c_d, 'Enable Nmap scans', 'boolean', '', 'Nmap')
|
conf.NMAP_ACTIVE = ccd('NMAP_ACTIVE', True , c_d, 'Enable Nmap scans', 'boolean', '', 'Nmap')
|
||||||
conf.NMAP_TIMEOUT = ccd('NMAP_TIMEOUT', 150 , c_d, 'Nmap timeout', 'integer', '', 'Nmap')
|
conf.NMAP_TIMEOUT = ccd('NMAP_TIMEOUT', 150 , c_d, 'Nmap timeout', 'integer', '', 'Nmap')
|
||||||
@@ -197,11 +188,6 @@ def importConfigs (db):
|
|||||||
# reset schedules
|
# reset schedules
|
||||||
conf.mySchedules = []
|
conf.mySchedules = []
|
||||||
|
|
||||||
# init pholus schedule
|
|
||||||
pholusSchedule = Cron(conf.PHOLUS_RUN_SCHD).schedule(start_date=datetime.datetime.now(conf.tz))
|
|
||||||
|
|
||||||
conf.mySchedules.append(schedule_class("pholus", pholusSchedule, pholusSchedule.next(), False))
|
|
||||||
|
|
||||||
# init nmap schedule
|
# init nmap schedule
|
||||||
nmapSchedule = Cron(conf.NMAP_RUN_SCHD).schedule(start_date=datetime.datetime.now(conf.tz))
|
nmapSchedule = Cron(conf.NMAP_RUN_SCHD).schedule(start_date=datetime.datetime.now(conf.tz))
|
||||||
conf.mySchedules.append(schedule_class("nmap", nmapSchedule, nmapSchedule.next(), False))
|
conf.mySchedules.append(schedule_class("nmap", nmapSchedule, nmapSchedule.next(), False))
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ def resolve_wildcards_arr(commandArr, params):
|
|||||||
|
|
||||||
for comPart in commandArr:
|
for comPart in commandArr:
|
||||||
|
|
||||||
commandArr[i] = comPart.replace('{' + param[0] + '}', param[1]).replace('{s-quote}',"'")
|
commandArr[i] = comPart.replace('{' + str(param[0]) + '}', str(param[1])).replace('{s-quote}',"'")
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|||||||
@@ -7,196 +7,3 @@ from logger import mylog
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
def performPholusScan (db, timeoutSec, userSubnets):
|
|
||||||
sql = db.sql # TO-DO
|
|
||||||
# scan every interface
|
|
||||||
for subnet in userSubnets:
|
|
||||||
|
|
||||||
temp = subnet.split("--interface=")
|
|
||||||
|
|
||||||
if len(temp) != 2:
|
|
||||||
mylog('none', ["[PholusScan] Skip scan (need subnet in format '192.168.1.0/24 --inteface=eth0'), got: ", subnet])
|
|
||||||
return
|
|
||||||
|
|
||||||
mask = temp[0].strip()
|
|
||||||
interface = temp[1].strip()
|
|
||||||
|
|
||||||
# logging & updating app state
|
|
||||||
updateState(db,"Scan: Pholus")
|
|
||||||
mylog('none', ['[PholusScan] Scan: Pholus for ', str(timeoutSec), 's ('+ str(round(int(timeoutSec) / 60, 1)) +'min)'])
|
|
||||||
mylog('verbose', ["[PholusScan] Pholus scan on [interface] ", interface, " [mask] " , mask])
|
|
||||||
|
|
||||||
# the scan always lasts 2x as long, so the desired user time from settings needs to be halved
|
|
||||||
adjustedTimeout = str(round(int(timeoutSec) / 2, 0))
|
|
||||||
|
|
||||||
# python3 -m trace --trace /home/pi/pialert/pholus/pholus3.py eth1 -rdns_scanning 192.168.1.0/24 -stimeout 600
|
|
||||||
pholus_args = ['python3', fullPholusPath, interface, "-rdns_scanning", mask, "-stimeout", adjustedTimeout]
|
|
||||||
|
|
||||||
# Execute command
|
|
||||||
output = ""
|
|
||||||
|
|
||||||
try:
|
|
||||||
# try runnning a subprocess with a forced (timeout + 30 seconds) in case the subprocess hangs
|
|
||||||
output = subprocess.check_output (pholus_args, universal_newlines=True, stderr=subprocess.STDOUT, timeout=(timeoutSec + 30))
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
# An error occured, handle it
|
|
||||||
mylog('none', ['[PholusScan]', e.output])
|
|
||||||
mylog('none', ["[PholusScan] Error - Pholus Scan - check logs"])
|
|
||||||
except subprocess.TimeoutExpired as timeErr:
|
|
||||||
mylog('none', ['[PholusScan] Pholus TIMEOUT - the process forcefully terminated as timeout reached'])
|
|
||||||
|
|
||||||
if output == "": # check if the subprocess failed
|
|
||||||
mylog('none', ['[PholusScan] Scan: Pholus FAIL - check logs'])
|
|
||||||
else:
|
|
||||||
mylog('verbose', ['[PholusScan] Scan: Pholus SUCCESS'])
|
|
||||||
|
|
||||||
# check the last run output
|
|
||||||
f = open(logPath + '/pialert_pholus_lastrun.log', 'r+')
|
|
||||||
newLines = f.read().split('\n')
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# cleanup - select only lines containing a separator to filter out unnecessary data
|
|
||||||
newLines = list(filter(lambda x: '|' in x, newLines))
|
|
||||||
|
|
||||||
# build SQL query parameters to insert into the DB
|
|
||||||
params = []
|
|
||||||
|
|
||||||
for line in newLines:
|
|
||||||
columns = line.split("|")
|
|
||||||
if len(columns) == 4:
|
|
||||||
params.append(( interface + " " + mask, timeNowTZ() , columns[0].replace(" ", ""), columns[1].replace(" ", ""), columns[2].replace(" ", ""), columns[3], ''))
|
|
||||||
|
|
||||||
if len(params) > 0:
|
|
||||||
sql.executemany ("""INSERT INTO Pholus_Scan ("Info", "Time", "MAC", "IP_v4_or_v6", "Record_Type", "Value", "Extra") VALUES (?, ?, ?, ?, ?, ?, ?)""", params)
|
|
||||||
db.commitDB()
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
def cleanResult(str):
|
|
||||||
# alternative str.split('.')[0]
|
|
||||||
str = str.replace("._airplay", "")
|
|
||||||
str = str.replace("._tcp", "")
|
|
||||||
str = str.replace(".local", "")
|
|
||||||
str = str.replace("._esphomelib", "")
|
|
||||||
str = str.replace("._googlecast", "")
|
|
||||||
str = str.replace(".lan", "")
|
|
||||||
str = str.replace(".home", "")
|
|
||||||
str = re.sub(r'-[a-fA-F0-9]{32}', '', str) # removing last part of e.g. Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77
|
|
||||||
str = re.sub(r'#.*', '', str) # Remove everything after '#' including the '#'
|
|
||||||
# remove trailing dots
|
|
||||||
if str.endswith('.'):
|
|
||||||
str = str[:-1]
|
|
||||||
|
|
||||||
return str
|
|
||||||
|
|
||||||
|
|
||||||
# Disclaimer - I'm interfacing with a script I didn't write (pholus3.py) so it's possible I'm missing types of answers
|
|
||||||
# it's also possible the pholus3.py script can be adjusted to provide a better output to interface with it
|
|
||||||
# Hit me with a PR if you know how! :)
|
|
||||||
def resolve_device_name_pholus (pMAC, pIP, allRes):
|
|
||||||
|
|
||||||
pholusMatchesIndexes = []
|
|
||||||
|
|
||||||
index = 0
|
|
||||||
for result in allRes:
|
|
||||||
# limiting entries used for name resolution to the ones containing the current IP (v4 only)
|
|
||||||
if result["MAC"] == pMAC and result["Record_Type"] == "Answer" and result["IP_v4_or_v6"] == pIP and '._googlezone' not in result["Value"]:
|
|
||||||
# found entries with a matching MAC address, let's collect indexes
|
|
||||||
pholusMatchesIndexes.append(index)
|
|
||||||
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
# return if nothing found
|
|
||||||
if len(pholusMatchesIndexes) == 0:
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# we have some entries let's try to select the most useful one
|
|
||||||
|
|
||||||
# airplay matches contain a lot of information
|
|
||||||
# Matches for example:
|
|
||||||
# Brand Tv (50)._airplay._tcp.local. TXT Class:32769 "acl=0 deviceid=66:66:66:66:66:66 features=0x77777,0x38BCB46 rsf=0x3 fv=p20.T-FFFFFF-03.1 flags=0x204 model=XXXX manufacturer=Brand serialNumber=XXXXXXXXXXX protovers=1.1 srcvers=777.77.77 pi=FF:FF:FF:FF:FF:FF psi=00000000-0000-0000-0000-FFFFFFFFFF gid=00000000-0000-0000-0000-FFFFFFFFFF gcgl=0 pk=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '._airplay._tcp.local. TXT Class:32769' in str(allRes[i]["Value"]) :
|
|
||||||
return allRes[i]["Value"].split('._airplay._tcp.local. TXT Class:32769')[0]
|
|
||||||
|
|
||||||
# second best - contains airplay
|
|
||||||
# Matches for example:
|
|
||||||
# _airplay._tcp.local. PTR Class:IN "Brand Tv (50)._airplay._tcp.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '_airplay._tcp.local. PTR Class:IN' in allRes[i]["Value"] and ('._googlecast') not in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
# Contains PTR Class:32769
|
|
||||||
# Matches for example:
|
|
||||||
# 3.1.168.192.in-addr.arpa. PTR Class:32769 "MyPc.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'PTR Class:32769' in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
# Contains AAAA Class:IN
|
|
||||||
# Matches for example:
|
|
||||||
# DESKTOP-SOMEID.local. AAAA Class:IN "fe80::fe80:fe80:fe80:fe80"
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'AAAA Class:IN' in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('.local.')[0])
|
|
||||||
|
|
||||||
# Contains _googlecast._tcp.local. PTR Class:IN
|
|
||||||
# Matches for example:
|
|
||||||
# _googlecast._tcp.local. PTR Class:IN "Nest-Audio-ff77ff77ff77ff77ff77ff77ff77ff77._googlecast._tcp.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and '_googlecast._tcp.local. PTR Class:IN' in allRes[i]["Value"] and ('Google-Cast-Group') not in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
# Contains A Class:32769
|
|
||||||
# Matches for example:
|
|
||||||
# Android.local. A Class:32769 "192.168.1.6"
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and ' A Class:32769' in allRes[i]["Value"]:
|
|
||||||
return cleanResult(allRes[i]["Value"].split(' A Class:32769')[0])
|
|
||||||
|
|
||||||
# # Contains PTR Class:IN
|
|
||||||
# Matches for example:
|
|
||||||
# _esphomelib._tcp.local. PTR Class:IN "ceiling-light-1._esphomelib._tcp.local."
|
|
||||||
for i in pholusMatchesIndexes:
|
|
||||||
if checkIPV4(allRes[i]['IP_v4_or_v6']) and 'PTR Class:IN' in allRes[i]["Value"]:
|
|
||||||
if allRes[i]["Value"] and len(allRes[i]["Value"].split('"')) > 1:
|
|
||||||
return cleanResult(allRes[i]["Value"].split('"')[1])
|
|
||||||
|
|
||||||
return -1
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def resolve_device_name_dig (pMAC, pIP):
|
|
||||||
|
|
||||||
newName = ""
|
|
||||||
|
|
||||||
try :
|
|
||||||
dig_args = ['dig', '+short', '-x', pIP]
|
|
||||||
|
|
||||||
# Execute command
|
|
||||||
try:
|
|
||||||
# try runnning a subprocess
|
|
||||||
newName = subprocess.check_output (dig_args, universal_newlines=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
# An error occured, handle it
|
|
||||||
mylog('none', ['[device_name_dig] ', e.output])
|
|
||||||
# newName = "Error - check logs"
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# Check returns
|
|
||||||
newName = newName.strip()
|
|
||||||
|
|
||||||
if len(newName) == 0 :
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# Cleanup
|
|
||||||
newName = cleanResult(newName)
|
|
||||||
|
|
||||||
if newName == "" or len(newName) == 0:
|
|
||||||
return -1
|
|
||||||
|
|
||||||
# Return newName
|
|
||||||
return newName
|
|
||||||
|
|
||||||
# not Found
|
|
||||||
except subprocess.CalledProcessError :
|
|
||||||
return -1
|
|
||||||
|
|||||||
Reference in New Issue
Block a user