Add frontend, improve upload script
This commit is contained in:
parent
4d28f80980
commit
dee770c395
9 changed files with 167 additions and 7 deletions
6
public/bootstrap/css/bootstrap.min.css
vendored
Normal file
6
public/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/bootstrap/css/bootstrap.min.css.map
Normal file
1
public/bootstrap/css/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
7
public/bootstrap/js/bootstrap.bundle.min.js
vendored
Normal file
7
public/bootstrap/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
public/bootstrap/js/bootstrap.bundle.min.js.map
Normal file
1
public/bootstrap/js/bootstrap.bundle.min.js.map
Normal file
File diff suppressed because one or more lines are too long
46
public/index.php
Normal file
46
public/index.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$page_title = 'CZI Presence Detector';
|
||||||
|
$present_file = 'present.json';
|
||||||
|
|
||||||
|
$present = json_decode(file_get_contents($present_file), true);
|
||||||
|
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><?php echo $page_title; ?></title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
|
||||||
|
<script src="/bootstrap/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-light bg-light justify-content-between" style="padding: 0">
|
||||||
|
<span class="navbar-brand mb-0 h1" style="padding-left: 1rem"><?php echo $page_title; ?></span>
|
||||||
|
</nav>
|
||||||
|
<div id="content" style="padding: 2rem;">
|
||||||
|
<h2>Jetzt gerade im CZI <small>(letztes Update von <?php echo date('H:i:s d.m.Y', $present["timestamp"]); ?>)</small></h2><br>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>MAC</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<?php
|
||||||
|
foreach ($present["identities"] as $identity) {
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo $identity["name"]; ?></td>
|
||||||
|
<td><code><?php echo $identity["mac"]; ?></code></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
public/present.json
Normal file
1
public/present.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"timestamp":1691853251,"identities":[{"mac":"ff:ff:ff:ff:ff:ff","name":"BROADCAST"}]}
|
67
public/update.php
Normal file
67
public/update.php
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$secret_key = 'CHANGE-THIS';
|
||||||
|
$present_file = 'present.json';
|
||||||
|
|
||||||
|
// check for POST request
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||||
|
error_log('FAILED - not POST - '. $_SERVER['REQUEST_METHOD']);
|
||||||
|
http_response_code(405);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get content type
|
||||||
|
$content_type = isset($_SERVER['CONTENT_TYPE']) ? strtolower(trim($_SERVER['CONTENT_TYPE'])) : '';
|
||||||
|
|
||||||
|
if ($content_type != 'application/json') {
|
||||||
|
error_log('FAILED - not application/json - '. $content_type);
|
||||||
|
http_response_code(400);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get payload
|
||||||
|
$payload = trim(file_get_contents("php://input"));
|
||||||
|
|
||||||
|
if (empty($payload)) {
|
||||||
|
error_log('FAILED - no payload');
|
||||||
|
http_response_code(400);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get header signature
|
||||||
|
$header_signature = isset($_SERVER['HTTP_X_HMAC_HASH']) ? $_SERVER['HTTP_X_HMAC_HASH'] : '';
|
||||||
|
if (empty($header_signature)) {
|
||||||
|
error_log('FAILED - header signature missing');
|
||||||
|
http_response_code(401);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate payload signature
|
||||||
|
$payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
|
||||||
|
|
||||||
|
// check payload signature against header signature
|
||||||
|
if ($header_signature !== $payload_signature) {
|
||||||
|
error_log('FAILED - payload signature');
|
||||||
|
http_response_code(401);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert json to array
|
||||||
|
$decoded = json_decode($payload, true);
|
||||||
|
|
||||||
|
// check for json decode errors
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
error_log('FAILED - json decode - '. json_last_error());
|
||||||
|
http_response_code(400);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// success, do something
|
||||||
|
http_response_code(200);
|
||||||
|
|
||||||
|
$present = array(
|
||||||
|
"timestamp" => time(),
|
||||||
|
"identities" => $decoded
|
||||||
|
);
|
||||||
|
|
||||||
|
file_put_contents($present_file, json_encode($present));
|
2
scan.sh
2
scan.sh
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
adapter=wlo1
|
adapter=wlan0
|
||||||
adapter_mon="${wlo1}mon"
|
adapter_mon="${wlo1}mon"
|
||||||
|
|
||||||
# Check for root privileges
|
# Check for root privileges
|
||||||
|
|
43
upload.py
43
upload.py
|
@ -2,44 +2,75 @@
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import yaml
|
import yaml
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import hmac
|
||||||
|
import hashlib
|
||||||
|
|
||||||
IDENTITIES_PATH = "identities.yaml"
|
IDENTITIES_PATH = "identities.yaml"
|
||||||
|
WEBHOOK_URL = "http://localhost:8080/update.php"
|
||||||
|
WEBHOOK_SECRET = "CHANGE-THIS"
|
||||||
|
|
||||||
def parse_wifi_map(map_path):
|
def parse_wifi_map(map_path):
|
||||||
|
# read scan results
|
||||||
with open(map_path, 'r') as f:
|
with open(map_path, 'r') as f:
|
||||||
wifi_map = yaml.safe_load(f)
|
wifi_map = yaml.safe_load(f)
|
||||||
|
|
||||||
|
# read known identities
|
||||||
with open(IDENTITIES_PATH, 'r') as f:
|
with open(IDENTITIES_PATH, 'r') as f:
|
||||||
identities = yaml.safe_load(f)['identities']
|
identities = yaml.safe_load(f)['identities']
|
||||||
|
|
||||||
|
print("Known identities:")
|
||||||
for identity in identities:
|
for identity in identities:
|
||||||
print('mac = {}, name = {}'.format(identity['mac'],identity['name']))
|
print('mac = {}, name = {}'.format(identity['mac'],identity['name']))
|
||||||
|
|
||||||
devices = set()
|
devices = set()
|
||||||
|
|
||||||
filtered_devices = []
|
filtered_devices = []
|
||||||
|
|
||||||
|
# filter scan results for known identities
|
||||||
for ssid in wifi_map:
|
for ssid in wifi_map:
|
||||||
print('ssid = {}'.format(ssid))
|
#print('ssid = {}'.format(ssid))
|
||||||
ssid_node = wifi_map[ssid]
|
ssid_node = wifi_map[ssid]
|
||||||
for bssid in ssid_node:
|
for bssid in ssid_node:
|
||||||
print('\tbssid = {}'.format(bssid))
|
#print('\tbssid = {}'.format(bssid))
|
||||||
bssid_node = ssid_node[bssid]
|
bssid_node = ssid_node[bssid]
|
||||||
if 'devices' in bssid_node:
|
if 'devices' in bssid_node:
|
||||||
for device in bssid_node['devices']:
|
for device in bssid_node['devices']:
|
||||||
devices |= {device}
|
devices |= {device}
|
||||||
print('\t\tdevice = {}'.format(device))
|
#print('\t\tdevice = {}'.format(device))
|
||||||
for identity in identities:
|
for identity in identities:
|
||||||
if identity['mac'] == device:
|
if identity['mac'] == device:
|
||||||
filtered_devices.append(identity)
|
filtered_devices.append(identity)
|
||||||
|
|
||||||
print('\n\nSSID count: {}, Device count: {}'.format(len(wifi_map), len(devices)))
|
#print('\n\nSSID count: {}, Device count: {}'.format(len(wifi_map), len(devices)))
|
||||||
print('\nFiltered devices:')
|
print('\nFiltered devices:')
|
||||||
print(filtered_devices)
|
print(filtered_devices)
|
||||||
|
|
||||||
|
return filtered_devices
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
wifi_map_path = 'wifi_map.yaml'
|
wifi_map_path = 'wifi_map.yaml'
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
wifi_map_path = sys.argv[1]
|
wifi_map_path = sys.argv[1]
|
||||||
parse_wifi_map(wifi_map_path)
|
|
||||||
|
|
||||||
|
filtered_devices = parse_wifi_map(wifi_map_path)
|
||||||
|
|
||||||
|
# build request
|
||||||
|
json_payload = json.dumps(filtered_devices).encode("utf-8")
|
||||||
|
|
||||||
|
signature = hmac.new(
|
||||||
|
key=bytes(WEBHOOK_SECRET, "utf-8"),
|
||||||
|
msg=json_payload,
|
||||||
|
digestmod=hashlib.sha256
|
||||||
|
).hexdigest()
|
||||||
|
|
||||||
|
req_headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-hmac-hash': signature
|
||||||
|
}
|
||||||
|
|
||||||
|
# send request
|
||||||
|
r = requests.post(url=WEBHOOK_URL, data=json_payload, headers=req_headers)
|
||||||
|
|
||||||
|
print("Upload response:")
|
||||||
|
print(r.status_code)
|
||||||
|
|
Loading…
Reference in a new issue