@@ -132,6 +132,11 @@ def set_db_file_permissions():
132
132
# Set permissions
133
133
os .system ("sudo /usr/bin/chown " + get_username () + ":www-data " + PIALERT_DB_FILE )
134
134
os .system ("sudo /usr/bin/chmod 775 " + PIALERT_DB_FILE )
135
+
136
+ # Set permissions Experimental
137
+ # os.system("sudo /usr/bin/chown " + get_username() + ":www-data " + PIALERT_DB_FILE + "*")
138
+ # os.system("sudo /usr/bin/chmod 775 " + PIALERT_DB_FILE + "*")
139
+
135
140
# Get permissions
136
141
fileinfo = Path (PIALERT_DB_FILE )
137
142
file_stat = fileinfo .stat ()
@@ -376,7 +381,7 @@ def NewVersion_FrontendNotification(newVersion,update_notes):
376
381
if not os .path .exists (file_path ):
377
382
print (" Create Frontend Notification." )
378
383
else :
379
- print (" Update Frontend Notification." )
384
+ print (" Update Frontend Notification." )
380
385
with open (file_path , 'w' ) as file :
381
386
file .write (update_notes )
382
387
else :
@@ -694,7 +699,7 @@ def query_MAC_vendor(pMAC):
694
699
# not Found
695
700
except subprocess .CalledProcessError :
696
701
return - 1
697
-
702
+
698
703
#===============================================================================
699
704
# SCAN NETWORK
700
705
#===============================================================================
@@ -719,7 +724,7 @@ def scan_network():
719
724
print (' Exiting...\n ' )
720
725
return 1
721
726
722
- # ScanCycle data
727
+ # ScanCycle data
723
728
cycle_interval = scanCycle_data ['cic_EveryXmin' ]
724
729
#arpscan_retries = scanCycle_data['cic_arpscanCycles']
725
730
# arp-scan command
@@ -860,8 +865,8 @@ def execute_arpscan():
860
865
861
866
# multiple interfaces
862
867
if type (SCAN_SUBNETS ) is list :
863
- print (" arp-scan: Multiple interfaces" )
864
- for interface in SCAN_SUBNETS :
868
+ print (" arp-scan: Multiple interfaces" )
869
+ for interface in SCAN_SUBNETS :
865
870
arpscan_output += execute_arpscan_on_interface (interface )
866
871
# one interface only
867
872
else :
@@ -879,11 +884,11 @@ def execute_arpscan():
879
884
for device in re .finditer (re_pattern , arpscan_output )]
880
885
881
886
# Delete duplicate MAC
882
- unique_mac = []
883
- unique_devices = []
887
+ unique_mac = []
888
+ unique_devices = []
884
889
885
890
for device in devices_list :
886
- if device ['mac' ] not in unique_mac :
891
+ if device ['mac' ] not in unique_mac :
887
892
unique_mac .append (device ['mac' ])
888
893
unique_devices .append (device )
889
894
@@ -939,27 +944,36 @@ def copy_pihole_network():
939
944
sql .execute ("DETACH PH" )
940
945
941
946
elif PIHOLE_VERSION == 6 :
942
- #Debug
943
- #PIHOLE6_URL = 'https://localhost:443'
944
- #PIHOLE6_PASSWORD = '######'
947
+ global PIHOLE6_URL
948
+ global PIHOLE6_PASSWORD
945
949
946
- if not PIHOLE6_PASSWORD or not PIHOLE6_URL :
950
+ if not PIHOLE6_PASSWORD or not PIHOLE6_URL :
947
951
print (' ...Skipped (Config Error)' )
948
952
return
949
953
950
954
if not PIHOLE6_URL .endswith ('/' ):
951
955
PIHOLE6_URL += '/'
952
956
957
+ requests .packages .urllib3 .disable_warnings (InsecureRequestWarning )
953
958
headers = {
954
959
"accept" : "application/json" ,
955
960
"content-type" : "application/json"
956
961
}
957
962
data = {
958
963
"password" : PIHOLE6_PASSWORD
959
964
}
960
- requests .packages .urllib3 .disable_warnings (InsecureRequestWarning )
961
- response = requests .post (PIHOLE6_URL + 'api/auth' , headers = headers , json = data , verify = False )
962
- # print(response.json())
965
+ try :
966
+ response = requests .post (PIHOLE6_URL + 'api/auth' , headers = headers , json = data , verify = False , timeout = 15 )
967
+ except requests .exceptions .Timeout :
968
+ print (f" Request timed out after 15 seconds" )
969
+ return
970
+ except requests .exceptions .ConnectionError as e :
971
+ print (f" Connection error occurred" )
972
+ return
973
+ except Exception as e :
974
+ print (f" An unexpected error occurred" )
975
+ return
976
+
963
977
response_json = response .json ()
964
978
965
979
if response .status_code == 200 and response_json ['session' ]['valid' ] == True :
@@ -972,20 +986,28 @@ def copy_pihole_network():
972
986
result = {}
973
987
deviceslist = raw_deviceslist .json ()
974
988
989
+ # If pi-hole is outside the local Pi.Alert network and cannot be found with arp.
990
+ pihole_host_ip = get_ip_from_hostname (PIHOLE6_URL )
991
+
975
992
for device in deviceslist ['devices' ]:
976
993
hwaddr = device ['hwaddr' ]
977
994
lastQuery = device ['lastQuery' ]
978
995
macVendor = device ['macVendor' ]
979
996
997
+ # skip lo interface
980
998
if hwaddr == "00:00:00:00:00:00" :
981
999
continue
982
1000
983
1001
for ip_info in device ['ips' ]:
984
1002
ip = ip_info ['ip' ]
985
1003
name = ip_info ['name' ] if ip_info ['name' ] not in [None , "" ] else "(unknown)"
986
-
1004
+
987
1005
# Check whether the IP could be a IPv4 address
988
1006
if '.' in ip :
1007
+ # Change the “lastQuery” variable to mark the Pi-hole host as “active”
1008
+ if pihole_host_ip == ip :
1009
+ lastQuery = str (int (datetime .datetime .now ().timestamp ()))
1010
+
989
1011
result [hwaddr ] = {
990
1012
"ip" : ip ,
991
1013
"name" : name ,
@@ -995,18 +1017,32 @@ def copy_pihole_network():
995
1017
996
1018
# print(result)
997
1019
for hwaddr , details in result .items ():
998
- cursor .execute ("""
1020
+ sql .execute ("""
999
1021
INSERT INTO PiHole_Network (PH_MAC, PH_Vendor, PH_LastQuery, PH_Name, PH_IP)
1000
1022
VALUES (?, ?, ?, ?, ?)
1001
1023
""" , (hwaddr , details ['macVendor' ], details ['lastQuery' ], details ['name' ], details ['ip' ]))
1002
1024
1025
+ result = {}
1026
+ deviceslist = raw_deviceslist .json ()
1027
+
1003
1028
else :
1004
1029
print ("Auth required" )
1005
1030
return
1006
1031
1007
1032
else :
1008
1033
print (' ...Unsupported Version' )
1009
1034
1035
+ #-------------------------------------------------------------------------------
1036
+ def get_ip_from_hostname (url ):
1037
+ try :
1038
+ hostname_port = url .replace ("http://" , "" ).replace ("https://" , "" ).split ('/' )[0 ]
1039
+ hostname = hostname_port .split (':' )[0 ]
1040
+ ip_address = socket .gethostbyname (hostname )
1041
+ return ip_address
1042
+ except socket .gaierror as e :
1043
+ ip_address = ""
1044
+ return ip_address
1045
+
1010
1046
#-------------------------------------------------------------------------------
1011
1047
def read_fritzbox_active_hosts ():
1012
1048
# create table if not exists
0 commit comments