Add frontend, improve upload script

This commit is contained in:
JonOfUs 2023-08-12 17:23:33 +02:00
parent 4d28f80980
commit dee770c395
9 changed files with 167 additions and 7 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

46
public/index.php Normal file
View 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
View file

@ -0,0 +1 @@
{"timestamp":1691853251,"identities":[{"mac":"ff:ff:ff:ff:ff:ff","name":"BROADCAST"}]}

67
public/update.php Normal file
View 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));

View file

@ -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

View file

@ -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)