add config page and terminal page

This commit is contained in:
Your Name
2025-03-08 14:43:22 +01:00
parent 5d121761e7
commit 1e656d76a1
5 changed files with 973 additions and 1 deletions

View File

@@ -4,7 +4,8 @@ header("Content-Type: application/json");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
$type=$_GET['type'];
// Get request type from GET or POST parameters
$type = isset($_GET['type']) ? $_GET['type'] : (isset($_POST['type']) ? $_POST['type'] : '');
if ($type == "get_npm_sqlite_data") {
$database_path = "/var/www/nebuleair_pro_4g/sqlite/sensors.db";
@@ -484,3 +485,193 @@ if ($type == "wifi_scan_old") {
echo $json_data;
}
// Save config.json with password protection
if ($type == "save_config") {
// Verify that the request is using POST method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'message' => 'Invalid request method']);
exit;
}
// Get the config content from POST data
$config = isset($_POST['config']) ? $_POST['config'] : '';
if (empty($config)) {
echo json_encode(['success' => false, 'message' => 'No configuration data provided']);
exit;
}
// Validate that the content is valid JSON
$decodedConfig = json_decode($config);
if (json_last_error() !== JSON_ERROR_NONE) {
echo json_encode([
'success' => false,
'message' => 'Invalid JSON format: ' . json_last_error_msg()
]);
exit;
}
// Path to the configuration file
$configFile = '/var/www/nebuleair_pro_4g/config.json';
// Create a backup of the current config
$backupFile = '/var/www/nebuleair_pro_4g/config.json.backup-' . date('Y-m-d-H-i-s');
if (file_exists($configFile)) {
copy($configFile, $backupFile);
}
// Write the updated configuration to the file
$result = file_put_contents($configFile, $config);
if ($result === false) {
echo json_encode([
'success' => false,
'message' => 'Failed to write configuration file. Check permissions.'
]);
} else {
echo json_encode([
'success' => true,
'message' => 'Configuration saved successfully',
'bytes_written' => $result
]);
}
}
// Execute shell command with security restrictions
if ($type == "execute_command") {
// Verify that the request is using POST method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'message' => 'Invalid request method']);
exit;
}
// Get the command from POST data
$command = isset($_POST['command']) ? $_POST['command'] : '';
if (empty($command)) {
echo json_encode(['success' => false, 'message' => 'No command provided']);
exit;
}
// List of allowed commands (prefixes)
$allowedCommands = [
'ls', 'cat', 'cd', 'pwd', 'df', 'free', 'ifconfig', 'ip', 'ps', 'date', 'uptime',
'systemctl status', 'whoami', 'hostname', 'uname', 'grep', 'tail', 'head', 'find',
'less', 'more', 'du', 'echo'
];
// Check if command is allowed
$allowed = false;
foreach ($allowedCommands as $allowedCmd) {
if (strpos($command, $allowedCmd) === 0) {
$allowed = true;
break;
}
}
// Special case for systemctl restart and reboot
if (strpos($command, 'systemctl restart') === 0 || $command === 'reboot') {
// These commands don't return output through shell_exec since they change process state
// We'll just acknowledge them
if ($command === 'reboot') {
// Execute the command with exec to avoid waiting for output
exec('sudo reboot > /dev/null 2>&1 &');
echo json_encode([
'success' => true,
'output' => 'System is rebooting...'
]);
} else {
// For systemctl restart, execute it and acknowledge
$serviceName = str_replace('systemctl restart ', '', $command);
exec('sudo systemctl restart ' . escapeshellarg($serviceName) . ' > /dev/null 2>&1 &');
echo json_encode([
'success' => true,
'output' => 'Service ' . $serviceName . ' is restarting...'
]);
}
exit;
}
// Check for prohibited patterns
$prohibitedPatterns = [
'sudo rm', ';', '&&', '||', '|', '>', '>>', '&',
'wget', 'curl', 'nc', 'ssh', 'scp', 'ftp', 'telnet',
'iptables', 'passwd', 'chown', 'chmod', 'mkfs', 'dd',
'mount', 'umount', 'kill', 'killall'
];
foreach ($prohibitedPatterns as $pattern) {
if (strpos($command, $pattern) !== false) {
echo json_encode([
'success' => false,
'message' => 'Command contains prohibited operation: ' . $pattern
]);
exit;
}
}
if (!$allowed) {
echo json_encode([
'success' => false,
'message' => 'Command not allowed for security reasons'
]);
exit;
}
// Execute the command with timeout protection
$descriptorspec = [
0 => ["pipe", "r"], // stdin
1 => ["pipe", "w"], // stdout
2 => ["pipe", "w"] // stderr
];
// Escape the command to prevent shell injection
$escapedCommand = escapeshellcmd($command);
// Add timeout of 5 seconds to prevent long-running commands
$process = proc_open("timeout 5 $escapedCommand", $descriptorspec, $pipes);
if (is_resource($process)) {
// Close stdin pipe
fclose($pipes[0]);
// Get output from stdout
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
// Get any errors
$errors = stream_get_contents($pipes[2]);
fclose($pipes[2]);
// Close the process
$returnValue = proc_close($process);
// Check for errors
if ($returnValue !== 0) {
// If there was an error, but we have output, consider it a partial success
if (!empty($output)) {
echo json_encode([
'success' => true,
'output' => $output . "\n" . $errors . "\nCommand exited with code $returnValue"
]);
} else {
echo json_encode([
'success' => false,
'message' => empty($errors) ? "Command failed with exit code $returnValue" : $errors
]);
}
} else {
// Success
echo json_encode([
'success' => true,
'output' => $output
]);
}
} else {
echo json_encode([
'success' => false,
'message' => 'Failed to execute command'
]);
}
}