Промежуточный коммит
This commit is contained in:
parent
3c41ed288f
commit
3a3f6edaa0
|
|
@ -0,0 +1 @@
|
||||||
|
/config.json
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
# protected-resources-list
|
# Protected Resources
|
||||||
|
Список ресурсов для настройки родительского контроля чтобы заблокировать доступ детям до запрещённых в РФ вражеских сервисов.
|
||||||
|
|
||||||
Список ресурсов для настройки родительского контроля чтобы заблокировать доступ детям до вражеских сервисов.
|
## networks
|
||||||
|
Каталог с файлами сервисов и их подсетей
|
||||||
|
|
||||||
|
## utils
|
||||||
|
Различные скрипты и утилиты
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"password": {
|
||||||
|
"type": "plaintext",
|
||||||
|
"data": "admin"
|
||||||
|
},
|
||||||
|
"networks": [
|
||||||
|
"google"
|
||||||
|
],
|
||||||
|
"zebra_restart_cmd": "/etc/init.d/zebra restart"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"102.132.96.0/20",
|
||||||
|
"129.134.0.0/19",
|
||||||
|
"103.4.96.0/22",
|
||||||
|
"157.240.0.0/16",
|
||||||
|
"163.70.128.0/19",
|
||||||
|
"173.252.64.0/18",
|
||||||
|
"179.60.192.0/21",
|
||||||
|
"185.60.216.0/21",
|
||||||
|
"204.15.20.0/22",
|
||||||
|
"31.13.24.0/17",
|
||||||
|
"45.64.40.0/22",
|
||||||
|
"57.141.0.0/16",
|
||||||
|
"66.220.144.0/20",
|
||||||
|
"69.171.224.0/19",
|
||||||
|
"69.63.176.0/19",
|
||||||
|
"74.119.76.0/22"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"188.114.98.0/23"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"179.43.150.83/32"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"104.237.160.0/19",
|
||||||
|
"108.177.14.0/24",
|
||||||
|
"136.22.132.0/23",
|
||||||
|
"142.250.0.0/15",
|
||||||
|
"172.110.32.0/21",
|
||||||
|
"172.217.0.0/16",
|
||||||
|
"208.117.224.0/19",
|
||||||
|
"208.65.152.0/22",
|
||||||
|
"209.85.0.0/16",
|
||||||
|
"216.73.80.0/20",
|
||||||
|
"35.186.232.0/24",
|
||||||
|
"64.15.112.0/20",
|
||||||
|
"64.233.0.0/16",
|
||||||
|
"74.125.0.0/16",
|
||||||
|
"178.66.83.0/24",
|
||||||
|
"173.194.0.0/16",
|
||||||
|
"173.194.221.198/32",
|
||||||
|
"216.58.206.0/24",
|
||||||
|
"8.8.8.8/32"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"18.245.46.0/24",
|
||||||
|
"52.85.49.0/24"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"104.18.39.102/32",
|
||||||
|
"172.64.148.154/32"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"domains": [],
|
||||||
|
"networks": [
|
||||||
|
"104.21.32.39/32",
|
||||||
|
"172.67.182.196/32",
|
||||||
|
"188.114.97.0/24",
|
||||||
|
"188.114.96.0/24",
|
||||||
|
"104.21.50.150/32",
|
||||||
|
"172.67.163.237/32"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Routing config</title>
|
||||||
|
<script src="jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span id="loading">Loading...</span>
|
||||||
|
<div style="display: none" id="panel">
|
||||||
|
|
||||||
|
<div id="update-panel">Checking for updates...</div>
|
||||||
|
|
||||||
|
Selected networks:
|
||||||
|
<table id="net-table">
|
||||||
|
<tr>
|
||||||
|
<td><input type="checkbox"></td>
|
||||||
|
<td><span>Network name</span></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button id="save">Save</button>
|
||||||
|
<button id="restart-quagga">Restart quagga</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import {JSONRPC} from "./jrpc.js";
|
||||||
|
|
||||||
|
let config = {};
|
||||||
|
let networks = {};
|
||||||
|
|
||||||
|
async function auth() {
|
||||||
|
let authorized = await JSONRPC.__invoke("auth");
|
||||||
|
if (!authorized) {
|
||||||
|
do {
|
||||||
|
let pass = prompt("Password");
|
||||||
|
authorized = await JSONRPC.__invoke("auth", {
|
||||||
|
"password": pass
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!authorized) {
|
||||||
|
alert("Wrong password");
|
||||||
|
}
|
||||||
|
} while (!authorized);
|
||||||
|
}
|
||||||
|
|
||||||
|
config = await JSONRPC.__invoke("getConfig");
|
||||||
|
networks = await JSONRPC.__invoke("getNetworks");
|
||||||
|
|
||||||
|
$("#loading").hide();
|
||||||
|
|
||||||
|
fillNetworks();
|
||||||
|
|
||||||
|
$("#panel").show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fillNetworks() {
|
||||||
|
let proto = $("#net-table tr");
|
||||||
|
proto.detach();
|
||||||
|
|
||||||
|
for (const net in networks) {
|
||||||
|
let item = proto.clone();
|
||||||
|
item.find("input").prop('checked', config.networks.indexOf(net) !== -1).change(function () {
|
||||||
|
if ($(this).prop('checked')) {
|
||||||
|
config.networks.push(net);
|
||||||
|
} else {
|
||||||
|
config.networks = config.networks.filter(e => e !== net);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item.find("span").text(net);
|
||||||
|
$("#net-table").append(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
auth();
|
||||||
|
$("#save").click(function () {
|
||||||
|
const self = $(this);
|
||||||
|
self.prop("disabled", true);
|
||||||
|
(async function () {
|
||||||
|
await JSONRPC.__invoke("setConfig", config);
|
||||||
|
alert("Config saved!");
|
||||||
|
self.prop("disabled", false);
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
$("#restart-quagga").click(function () {
|
||||||
|
if (confirm("Are you sure?")) {
|
||||||
|
const self = $(this);
|
||||||
|
self.prop("disabled", true);
|
||||||
|
(async function () {
|
||||||
|
try {
|
||||||
|
alert( await JSONRPC.__invoke("restart_quagga"));
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
self.prop("disabled", false);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
(async function(){
|
||||||
|
alert(await JSONRPC.__invoke("checkUpdates"));
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,59 @@
|
||||||
|
export const JSONRPC = {
|
||||||
|
url: "/rpc",
|
||||||
|
__id: 1,
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param method
|
||||||
|
* @param params
|
||||||
|
* @returns Object
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
__invoke: async function (method, params) {
|
||||||
|
if(params === undefined){
|
||||||
|
params = {};
|
||||||
|
}
|
||||||
|
const request = await JSONRPC.__performRequest(method, params);
|
||||||
|
|
||||||
|
if (!request.success) {
|
||||||
|
console.error(request.result);
|
||||||
|
throw new Error("Failed to invoke method " + method + " with params " + JSON.stringify(params));
|
||||||
|
}
|
||||||
|
|
||||||
|
return request.result;
|
||||||
|
},
|
||||||
|
__performRequest: async function (method, params) {
|
||||||
|
const __this = this;
|
||||||
|
const resp = await fetch(
|
||||||
|
__this.url,
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
mode: "cors",
|
||||||
|
cache: "no-cache",
|
||||||
|
credentials: "include",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
redirect: "follow",
|
||||||
|
referrerPolicy: "no-referrer",
|
||||||
|
body: JSON.stringify({
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: method,
|
||||||
|
params: params,
|
||||||
|
id: __this.__id++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const success = resp.status === 200;
|
||||||
|
const result = (success ? (await resp.json()).result : {
|
||||||
|
"error": true,
|
||||||
|
"code": resp.status,
|
||||||
|
"status": resp.statusText,
|
||||||
|
"body": await resp.text()
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
"result": result,
|
||||||
|
"success": success
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Config implements ArrayAccess
|
||||||
|
{
|
||||||
|
private string $path;
|
||||||
|
|
||||||
|
public function asArray(): array
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fromArray($a)
|
||||||
|
{
|
||||||
|
$this->data = $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->path = dirname(__DIR__, 2) . "/config.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function read(): void
|
||||||
|
{
|
||||||
|
$this->data = @json_decode(@file_get_contents($this->path), true);
|
||||||
|
if ($this->data == null) {
|
||||||
|
throw new RuntimeException("Failed to read or parse config file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(): void
|
||||||
|
{
|
||||||
|
file_put_contents($this->path, json_encode($this->data));
|
||||||
|
}
|
||||||
|
|
||||||
|
private mixed $data = [];
|
||||||
|
|
||||||
|
|
||||||
|
public function offsetExists(mixed $offset): bool
|
||||||
|
{
|
||||||
|
return isset($this->data[$offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetGet(mixed $offset): mixed
|
||||||
|
{
|
||||||
|
return $this->data[$offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetSet(mixed $offset, mixed $value): void
|
||||||
|
{
|
||||||
|
$this->data[$offset] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset(mixed $offset): void
|
||||||
|
{
|
||||||
|
unset($this->data[$offset]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class NetworkConfigReader
|
||||||
|
{
|
||||||
|
private array $configs = [];
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$path = dirname(__DIR__, 2) . "/networks";
|
||||||
|
foreach (new IteratorIterator(new DirectoryIterator($path)) as $file) {
|
||||||
|
/**
|
||||||
|
* @var SplFileInfo $file
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($file->getExtension() === "json") {
|
||||||
|
$key = $file->getBasename(".json");
|
||||||
|
$value = @json_decode(@file_get_contents($file->getPathname()), true);
|
||||||
|
|
||||||
|
if ($value === null) {
|
||||||
|
throw new RuntimeException("Network file " . $file->getBasename() . " is invalid or cannot be read");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->configs[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfigs(): array
|
||||||
|
{
|
||||||
|
return $this->configs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class RoutingTableReader
|
||||||
|
{
|
||||||
|
private $routes = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRoutes(): array
|
||||||
|
{
|
||||||
|
return $this->routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$result = @shell_exec("ip --json route show");
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
throw new RuntimeException("Failed to read routing table");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$this->routes = @json_decode($result, true);
|
||||||
|
|
||||||
|
if ($this->routes === null) {
|
||||||
|
throw new RuntimeException("Failed to parse json output");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->routes as $key => &$route) {
|
||||||
|
if ($route["dst"] === "default") {
|
||||||
|
$route["dst"] = "0.0.0.0/0";
|
||||||
|
} elseif (!str_contains($route["dst"], "/")) {
|
||||||
|
$route["dst"] .= "/32";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
if (!function_exists('mime_content_type')) {
|
||||||
|
|
||||||
|
function mime_content_type($filename): bool|string
|
||||||
|
{
|
||||||
|
$mime_types = array(
|
||||||
|
'txt' => 'text/plain',
|
||||||
|
'htm' => 'text/html',
|
||||||
|
'html' => 'text/html',
|
||||||
|
'php' => 'text/html',
|
||||||
|
'css' => 'text/css',
|
||||||
|
'js' => 'application/javascript',
|
||||||
|
'json' => 'application/json',
|
||||||
|
'xml' => 'application/xml',
|
||||||
|
'swf' => 'application/x-shockwave-flash',
|
||||||
|
'flv' => 'video/x-flv',
|
||||||
|
|
||||||
|
// images
|
||||||
|
'png' => 'image/png',
|
||||||
|
'jpe' => 'image/jpeg',
|
||||||
|
'jpeg' => 'image/jpeg',
|
||||||
|
'jpg' => 'image/jpeg',
|
||||||
|
'gif' => 'image/gif',
|
||||||
|
'bmp' => 'image/bmp',
|
||||||
|
'ico' => 'image/vnd.microsoft.icon',
|
||||||
|
'tiff' => 'image/tiff',
|
||||||
|
'tif' => 'image/tiff',
|
||||||
|
'svg' => 'image/svg+xml',
|
||||||
|
'svgz' => 'image/svg+xml',
|
||||||
|
|
||||||
|
// archives
|
||||||
|
'zip' => 'application/zip',
|
||||||
|
'rar' => 'application/x-rar-compressed',
|
||||||
|
'exe' => 'application/x-msdownload',
|
||||||
|
'msi' => 'application/x-msdownload',
|
||||||
|
'cab' => 'application/vnd.ms-cab-compressed',
|
||||||
|
|
||||||
|
// audio/video
|
||||||
|
'mp3' => 'audio/mpeg',
|
||||||
|
'qt' => 'video/quicktime',
|
||||||
|
'mov' => 'video/quicktime',
|
||||||
|
|
||||||
|
// adobe
|
||||||
|
'pdf' => 'application/pdf',
|
||||||
|
'psd' => 'image/vnd.adobe.photoshop',
|
||||||
|
'ai' => 'application/postscript',
|
||||||
|
'eps' => 'application/postscript',
|
||||||
|
'ps' => 'application/postscript',
|
||||||
|
|
||||||
|
// ms office
|
||||||
|
'doc' => 'application/msword',
|
||||||
|
'rtf' => 'application/rtf',
|
||||||
|
'xls' => 'application/vnd.ms-excel',
|
||||||
|
'ppt' => 'application/vnd.ms-powerpoint',
|
||||||
|
|
||||||
|
// open office
|
||||||
|
'odt' => 'application/vnd.oasis.opendocument.text',
|
||||||
|
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
|
||||||
|
);
|
||||||
|
|
||||||
|
$parts = explode('.', $filename);
|
||||||
|
$ext = strtolower(array_pop($parts));
|
||||||
|
if (array_key_exists($ext, $mime_types)) {
|
||||||
|
return $mime_types[$ext];
|
||||||
|
} elseif (function_exists('finfo_open')) {
|
||||||
|
$finfo = finfo_open(FILEINFO_MIME);
|
||||||
|
$mimetype = finfo_file($finfo, $filename);
|
||||||
|
finfo_close($finfo);
|
||||||
|
return $mimetype;
|
||||||
|
} else {
|
||||||
|
return 'application/octet-stream';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/php
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/common.inc.php";
|
||||||
|
spl_autoload_register(function ($classname) {
|
||||||
|
require_once __DIR__ . "/classes/" . $classname . ".php";
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/loader.php";
|
||||||
|
|
||||||
|
if (str_starts_with($_SERVER["REQUEST_URI"], "/assets")) {
|
||||||
|
$file = __DIR__ . $_SERVER["REQUEST_URI"];
|
||||||
|
if (!file_exists($file)) {
|
||||||
|
http_response_code(404);
|
||||||
|
echo "File not found: " . $_SERVER["REQUEST_URI"];
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
header("content-type: " . mime_content_type($file));
|
||||||
|
echo file_get_contents($file);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str_starts_with($_SERVER["REQUEST_URI"], "/rpc")) {
|
||||||
|
http_response_code(302);
|
||||||
|
header("location: /assets/index.html");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = json_decode(@file_get_contents('php://input'), true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($request === null) {
|
||||||
|
throw new RuntimeException("Failed to parse JRPC");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (["id", "jsonrpc", "method", "params"] as $param) {
|
||||||
|
if (!isset($request[$param])) {
|
||||||
|
throw new RuntimeException("Bad JRPC structure");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* {"jsonrpc":"2.0","method":"auth","params":{},"id":1}
|
||||||
|
*/
|
||||||
|
|
||||||
|
@session_start();
|
||||||
|
|
||||||
|
class RPC
|
||||||
|
{
|
||||||
|
private Config $config;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->config = new Config();
|
||||||
|
$this->config->read();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function hash($what): string
|
||||||
|
{
|
||||||
|
return md5(sha1($what) . md5($what));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getConfig(): array
|
||||||
|
{
|
||||||
|
$this->checkAuth();
|
||||||
|
return $this->config->asArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function restart_quagga()
|
||||||
|
{
|
||||||
|
return shell_exec("./zebracfg.php");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkUpdates()
|
||||||
|
{
|
||||||
|
$this->checkAuth();
|
||||||
|
$data = shell_exec("git --no-pager fetch --dry-run --porcelain --verbose 2>&1");
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function getNetworks(): array
|
||||||
|
{
|
||||||
|
$this->checkAuth();
|
||||||
|
return (new NetworkConfigReader())->getConfigs();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function setConfig($config): bool
|
||||||
|
{
|
||||||
|
$this->config->fromArray($config);
|
||||||
|
$this->config->save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkAuth(): void
|
||||||
|
{
|
||||||
|
$auth = $_SESSION["auth"] ?? false;
|
||||||
|
if (!$auth) {
|
||||||
|
throw new RuntimeException("Unauthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function comparePassword($passwd): bool
|
||||||
|
{
|
||||||
|
$pass = $this->config["password"];
|
||||||
|
if ($pass["type"] == "plaintext") {
|
||||||
|
return $pass["data"] == $passwd;
|
||||||
|
} else if ($pass["type"] == "hash") {
|
||||||
|
return $this->hash($passwd) == $pass["data"];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function logout(): void
|
||||||
|
{
|
||||||
|
$_SESSION["auth"] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function auth($params): bool
|
||||||
|
{
|
||||||
|
if (isset($params["password"])) {
|
||||||
|
if ($this->comparePassword($params["password"])) {
|
||||||
|
return $_SESSION["auth"] = true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_SESSION["auth"] ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke($method, $args)
|
||||||
|
{
|
||||||
|
$cls = new ReflectionClass(__CLASS__);
|
||||||
|
$method = $cls->getMethod($method);
|
||||||
|
if (!$method or !$method->isPublic()) {
|
||||||
|
throw new RuntimeException("Unable to find method");
|
||||||
|
}
|
||||||
|
return $method->invoke($this, $args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rpc = new RPC();
|
||||||
|
$response = $rpc($request["method"], $request["params"]);
|
||||||
|
|
||||||
|
header("content-type: application/json");
|
||||||
|
@session_write_close();
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
"jsonrpc" => "2.0",
|
||||||
|
"id" => $request["id"],
|
||||||
|
"result" => $response
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo $e->getMessage();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
#!/bin/sh
|
||||||
|
php -S 0.0.0.0:8000 server.php
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/php
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . "/loader.php";
|
||||||
|
const CFGFILE = "/etc/quagga/zebra.conf";
|
||||||
|
const REM_PREFIX = "! routes from file ";
|
||||||
|
try {
|
||||||
|
$networks = (new NetworkConfigReader())->getConfigs();
|
||||||
|
$config = new Config();
|
||||||
|
$config->read();
|
||||||
|
|
||||||
|
$routeParser = new RoutingTableReader();
|
||||||
|
$routes = $routeParser->getRoutes();
|
||||||
|
$defGatewayInterface = "";
|
||||||
|
$defGateway = "";
|
||||||
|
|
||||||
|
foreach ($routes as $route) {
|
||||||
|
if ($route["dst"] === "0.0.0.0/0") {
|
||||||
|
$defGatewayInterface = $route["dev"];
|
||||||
|
$defGateway = $route["gateway"];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$defGatewayInterface) {
|
||||||
|
throw new RuntimeException("Failed to detect default gateway interface");
|
||||||
|
}
|
||||||
|
|
||||||
|
$contents = file_get_contents(CFGFILE);
|
||||||
|
$lines = explode("\n", $contents);
|
||||||
|
|
||||||
|
//remove existing routes
|
||||||
|
foreach ($lines as $key => $line) {
|
||||||
|
if (str_starts_with($line, REM_PREFIX) or str_starts_with($line, "ip route ") and str_contains($line . " ", $defGateway . " ")) {
|
||||||
|
unset($lines[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//add new routes
|
||||||
|
foreach ($config["networks"] as $key) {
|
||||||
|
$lines[] = REM_PREFIX . $key;
|
||||||
|
if (isset($networks[$key])) {
|
||||||
|
foreach ($networks[$key]["networks"] as $route) {
|
||||||
|
$lines[] = "ip route " . $route . " " . $defGateway;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($lines as $key => $line) {
|
||||||
|
if (trim($line) === "") {
|
||||||
|
unset($lines[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$backupFile = CFGFILE . ".sav";
|
||||||
|
|
||||||
|
unlink($backupFile);
|
||||||
|
rename(CFGFILE, $backupFile);
|
||||||
|
file_put_contents(CFGFILE, implode("\n", $lines));
|
||||||
|
|
||||||
|
//restart zebra
|
||||||
|
echo shell_exec($config["zebra_restart_cmd"]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
echo "\nError:" . $e->getMessage() . "\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0);
|
||||||
Loading…
Reference in New Issue