Files
hosting/var/www/html/files.php
Daniel Winzen fa24bb61ec Added PHP 7.2 support + minor bugfixes and performance tweaks
Note when applying this update you will have to update existing nginx vhosts to match new listening addresses (IPv6). Preferably you should update them to unix socket though and apply the changes to the tor hidden service config as well
2018-02-10 22:10:07 +01:00

438 lines
15 KiB
PHP

<?php
include('../common.php');
try{
$db=new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>PERSISTENT]);
}catch(PDOException $e){
die('No Connection to MySQL database!');
}
session_start();
$user=check_login();
if(!empty($_POST['ftp_pass'])){
$_SESSION['ftp_pass']=$_POST['ftp_pass'];
}
if(empty($_SESSION['ftp_pass'])){
send_login();
exit;
}
$ftp=ftp_connect('127.0.0.1') or die ('No Connection to FTP server!');
if(@!ftp_login($ftp, "$user[onion].onion", $_SESSION['ftp_pass'])){
send_login();
exit;
}
//prepare reusable data
const SUFFIX=['B', 'KiB', 'MiB', 'GiB'];
const TYPES=[
'jpg'=>'img',
'psd'=>'img',
'jpeg'=>'img',
'png'=>'img',
'svg'=>'img',
'gif'=>'img',
'bmp'=>'img',
'ico'=>'img',
'm4v'=>'vid',
'webm'=>'vid',
'avi'=>'vid',
'flv'=>'vid',
'mpg'=>'vid',
'mpeg'=>'vid',
'wmv'=>'vid',
'ogm'=>'vid',
'ogv'=>'vid',
'mp4'=>'vid',
'mov'=>'vid',
'3gp'=>'vid',
'm4a'=>'snd',
'mp3'=>'snd',
'flac'=>'snd',
'ogg'=>'snd',
'oga'=>'snd',
'wav'=>'snd',
'wma'=>'snd',
'bin'=>'bin',
'exe'=>'bin',
'tgz'=>'zip',
'gz'=>'zip',
'zip'=>'zip',
'bz'=>'zip',
'bz2'=>'zip',
'xz'=>'zip',
'rar'=>'zip',
'tar'=>'zip',
'7z'=>'zip',
'xlsx'=>'doc',
'xsl'=>'doc',
'xml'=>'doc',
'doc'=>'doc',
'docx'=>'doc',
'css'=>'doc',
'html'=>'doc',
'htm'=>'doc',
'shtml'=>'doc',
'pdf'=>'doc',
'mobi'=>'doc',
'epub'=>'doc',
'odt'=>'doc',
'ods'=>'doc',
'odp'=>'doc',
'txt'=>'txt',
'csv'=>'txt',
'md'=>'txt',
'sh'=>'sh',
'js'=>'sh',
'pl'=>'sh',
'py'=>'sh',
'php'=>'sh',
'phtml'=>'sh',
'asp'=>'sh',
];
if(!isset($_REQUEST['C']) || !in_array($_REQUEST['C'], array('M', 'N', 'S'))){
$sort='N';
}else{
$sort=$_REQUEST['C'];
}
if(!isset($_REQUEST['O']) || !in_array($_REQUEST['O'], array('A', 'D'))){
$order='A';
}else{
$order=$_REQUEST['O'];
}
if(!empty($_REQUEST['path'])){
$dir='/'.trim(rawurldecode($_REQUEST['path']),'/').'/';
$dir=str_replace('..', '\.\.', $dir);
$dir=preg_replace('~//+~', '/', $dir);
}else{
$dir='/';
}
if(@!ftp_chdir($ftp, $dir)){
$dir=rtrim($dir, '/');
if(@ftp_fget($ftp, $tmpfile=tmpfile(), $dir, FTP_BINARY)){
//output file
header('Content-Type: ' . mime_content_type($tmpfile));
header('Content-Disposition: filename="'.basename($dir).'"');
header('Content-Length: ' . fstat($tmpfile)['size']);
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0, private');
header('Expires: 0');
header('Pragma: no-cache');
rewind($tmpfile);
while (($buffer = fgets($tmpfile, 4096)) !== false) {
echo $buffer;
}
}else{
send_not_found();
}
fclose($tmpfile);
exit;
}
if(!empty($_POST['mkdir']) && !empty($_POST['name'])){
ftp_mkdir($ftp, $_POST['name']);
}
if(!empty($_POST['mkfile']) && !empty($_POST['name'])){
$tmpfile='/tmp/'.uniqid();
touch($tmpfile);
ftp_put($ftp, $_POST['name'], $tmpfile, FTP_BINARY);
unlink($tmpfile);
}
if(!empty($_POST['delete']) && !empty($_POST['files'])){
foreach($_POST['files'] as $file){
ftp_recursive_delete($ftp, $file);
}
}
if(!empty($_POST['rename_2']) && !empty($_POST['files'])){
foreach($_POST['files'] as $old=>$new){
ftp_rename($ftp, $old, $new);
}
}
if(!empty($_POST['rename']) && !empty($_POST['files'])){
send_rename($dir);
exit;
}
if(!empty($_POST['edit_2']) && !empty($_POST['files'])){
$tmpfile='/tmp/'.uniqid();
foreach($_POST['files'] as $name=>$content){
file_put_contents($tmpfile, $content);
ftp_put($ftp, $name, $tmpfile, FTP_BINARY);
}
unlink($tmpfile);
}
if(!empty($_POST['edit']) && !empty($_POST['files'])){
send_edit($ftp, $dir);
exit;
}
if(!empty($_POST['unzip']) && !empty($_POST['files'])){
$zip = new ZipArchive();
foreach($_POST['files'] as $file){
if(!preg_match('/\.zip$/', $file)){
continue;
}
$tmpfile='/tmp/'.uniqid().'.zip';
ftp_get($ftp, $tmpfile, $file, FTP_BINARY);
//prevent zip-bombs
$size=0;
$resource=zip_open($tmpfile);
while($dir_resource=zip_read($resource)) {
$size+=zip_entry_filesize($dir_resource);
}
zip_close($resource);
if($size<=1073741824){ //1GB limit
$zip->open($tmpfile);
$tmpdir='/tmp/'.uniqid().'/';
mkdir($tmpdir);
$zip->extractTo($tmpdir);
ftp_recursive_upload($ftp, $tmpdir);
rmdir($tmpdir);
$zip->close();
}
unlink($tmpfile);
}
}
if(!empty($_FILES['files'])){
$c=count($_FILES['files']['name']);
for($i=0; $i<$c; ++$i){
ftp_put($ftp, $dir.$_FILES['files']['name'][$i], $_FILES['files']['tmp_name'][$i], FTP_BINARY);
unlink($_FILES['files']['tmp_name'][$i]);
}
}
$files=$dirs=[];
$list=ftp_rawlist($ftp, '.');
foreach($list as $file){
preg_match('/^([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+(.*)$/', $file, $match);
if($match[0][0]==='d'){
$dirs[$match[9]]=['name'=>"$match[9]/", 'mtime'=>strtotime("$match[6] $match[7] $match[8]"), 'size'=>'-'];
}else{
$files[$match[9]]=['name'=>$match[9], 'mtime'=>ftp_mdtm($ftp, $match[9]), 'size'=>$match[5]];
}
}
//sort our files
if($sort==='M'){
$list=array_merge($dirs, $files);
usort($list, function($a, $b) {
if ($a['mtime'] === $b['mtime']) {
return 0;
}
return ($a['mtime'] < $b['mtime']) ? -1 : 1;
});
}elseif($sort==='S'){
ksort($dirs, SORT_STRING | SORT_FLAG_CASE);
usort($files, function($a, $b) {
if ($a['size'] === $b['size']) {
return 0;
}
return ($a['size'] < $b['size']) ? -1 : 1;
});
$list=array_merge($dirs, $files);
}else{
$list=array_merge($dirs, $files);
ksort($list, SORT_STRING | SORT_FLAG_CASE);
}
//order correctly
if($order==='D'){
$list=array_reverse($list);
}
$dir=htmlspecialchars($dir);
?>
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="author" content="Daniel Winzen">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Daniel's Hosting - FileManager - Index of <?php echo $dir; ?></title>
<style type="text/css">.list td:nth-child(3){word-break:break-all;} .list td:nth-child(5){text-align:right;} .list tr{height:28px;}
.back{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM2ZmZpmZmSH5BAUAAAQALAAAAAAUABYAAANLSLrc/oKE8CoZM1O7os7c9WmcN04WdoKQdBIANypAHG5YbS/7kus1RlDxA+p4xqSRpmwCKE7nINqMwKi6wEAY1VaS3tBV/OiRz4sEADs=);}
.dir{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5lmM//MmSH5BAUAAAQALAAAAAAUABYAAANUSLrc/jDKSRm4+E4wuu9AxH1kpimAQHpqiQ5CLMcrHI71GgdXngs8nI8F7A1JReFxZzyygk4iNNpJUmFWmFbF3cJ4hNRsPA6Aw+a0es0LLEzwjDsBADs=);}
.img{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPMLAAAAADMzM2YAAAAzZmZmZv8zMwCZMwCZzJmZmczMzP///wAAAAAAAAAAAAAAAAAAACH5BAUAAAsALAAAAAAUABYAAASQMMhJ57p4BcW730F2bV5JhhlZdio6KkUsF4mi2tg2y4ICBL/gaxfrAY5IwJDY4yCeCKUGNjNYDTUFVKqTGTgJa1bLVSRi3/CVlIi+EgIB9mrdJAbuaYe+ThzwZSx8BAEHf3k3CQFXhIaHgR2KE46PLytmlJV6JX6ZgJYedwOjpJ+blyWIAVCsrU9AGUmys1IRADs=);}
.snd{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPIGAAAAADMzM2ZmZpmZmczMzP///wAAAAAAACH5BAUAAAYALAAAAAAUABYAAANQaLrc/g5I+KQNdFkgJKabIHpQKBJXyZ0b8EUcepFVG9w07N1K3uwvg48xFLpULxuyBygMisxP8zlUGjdBiTOHzW59Nx7RmmHuyoxwEM1eJAAAOw==);}
.zip{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPIGAAAAADMzM2YAAP8zM5mZmf///wAAAAAAACH5BAUAAAYALAAAAAAUABYAAANuaGrRvTCuUAoNMrNKrY5d531KWHHkVgAB65IdIM8AfBZETtSRMJQ3XI43ECh8P9FtZxgUj86B8rSLGg1IZ7BCiD6x3sE2fM0Wt+aydYvLqotTLgCpNsZxNV/5emdirxB9PBqCMAE6Oi0pBjQ0EgkAOw==);}
.ukwn{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANoGLq89JCEQaudIb5pO88RNwgCYJoiuFHleYqDyrUuCgQ3sA6uMNannavSI+kknQoNQCrtLEsT6wj71Xy/JwWIzSItvY7zSzwlx9UklNoZitlg81vLk6/paiU8P5cEmoCBJDgRQIZBBAkAOw==);}
.vid{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPIGAAAAADMzM2ZmZpmZmczMzP///wAAAAAAACH5BAUAAAYALAAAAAAUABYAAANmCLrcahAQ4toEIV7BOy8SlRmMMJzoAC5jCJjpCV7tFstuu8DxqtQUXmom0gRvqlxkUWg6nQxghUEzvjwdImapEKJ8W5LtppV6cVXSDgk2s5XiIxnOeNqj1qki7dLDDQGBgoOEgRAJADs=);}
.bin{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPIFAAAAADMzM5mZmczMzP///wAAAAAAAAAAACH5BAUAAAUALAAAAAAUABYAAANpGLq89bAEQqudIb4JABkdMBATqXFeR6ilCaFr6rWuFN8qEOj8doOdUWjosxgpgqQA4AOKbhUl05aTHZe+KtSCpVpVxu7EKfSEp7TjOeshX9E469obf7Prc5g7r+6LA0qBgkk7EUOHiFMJADs=);}
.doc{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPL/AAAAADMzM/8zM5lmM//MM2bM/5mZmf///yH5BAUAAAgALAAAAAAUABYAAARvMMhJJ7oYhcO730F2bV5JhtlZceSBjixBFDT7YedMFxwQ+ECYa1c7AI5IgDAwaDY9hqhBqWE5n9AotVXqHqZCbxdcNSbPHTJXnN72zsl2mC0vcwTmOEdNL/E7eHB1a3R/fXtbAVKLjFE/GXCRSBcRADs=);}
.txt{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANYGLq89JCEQaudIb5pO88R11UiuI3XBXFA61JAEM8nCrtujbeW4AuAmq3yC0puuxcFKBwSjaykcsA8OntQpPTZvFZF2un3iu1ul1kyuuv8Bn7wuE8WkdqNCQA7);}
.sh{min-width:22px; background:no-repeat url(data:img/gif;base64,R0lGODlhFAAWAPH/AAAAADMzM5mZmf///yH5BAUAAAQALAAAAAAUABYAAANgGLq89JCEQaudIb5pO88R11UiuFXAkJIXxAEwjAYATZ9UuuZxjPc7imAoAOBUyBHRKBk5hUzR01L8AXuVanPa0b6usWyU2x2rwDLokTzw8tDiNdnNVksCxLx+eIOg0Q8JADs=);}
</style>
</head><body>
<h1>Index of <?php echo $dir; ?></h1>
<?php if($dir!=='/'){ ?>
<p>Upload up to 1GB and up to 100 files at once <form action="files.php" enctype="multipart/form-data" method="post"><input name="files[]" type="file" multiple><input type="hidden" name="path" value="<?php echo $dir; ?>"><input type="submit" value="Upload"></form></p><br>
<?php
}
$fileurl='A';
$sizeurl='A';
$dateurl='A';
if($order==='A'){
if($sort==='N'){
$fileurl='D';
}elseif($sort==='S'){
$sizeurl='D';
}else{
$dateurl='D';
}
}
?>
<form action="files.php" method="post">
<input type="submit" name="mkdir" value="Create directory">
<input type="submit" name="mkfile" value="Create file">
<input type="text" name="name"><br><br>
<input type="hidden" name="path" value="<?php echo $dir; ?>">
<input type="submit" name="delete" value="Delete">
<input type="submit" name="rename" value="Rename">
<input type="submit" name="edit" value="Edit">
<input type="submit" name="unzip" value="Unzip"><br>
<table class="list"><tr>
<th></th><th></th>
<th><a href="files.php?path=<?php echo $dir; ?>&amp;C=N&amp;O=<?php echo $fileurl; ?>">File</a></th>
<th><a href="files.php?path=<?php echo $dir; ?>&amp;C=M&amp;O=<?php echo $dateurl; ?>">Last Modified</a></th>
<th><a href="files.php?path=<?php echo $dir; ?>&amp;C=S&amp;O=<?php echo $sizeurl; ?>">Size</a></th>
</tr>
<tr><td colspan="4"><hr></td></tr>
<tr><td></td><td class="back"></td><td colspan="3"><a href="files.php?path=<?php echo substr($dir, 0, strrpos(rtrim($dir, '/'), '/'))."/&amp;C=$sort&amp;O=$order"?>">Parent Directory</a></td></tr>
<?php
foreach($list as $element){
get_properties($element['name'], $icon, $element['size']);
echo '<tr><td><input type="checkbox" name="files[]" value="'.htmlspecialchars($element['name'])."\"></td><td class=\"$icon\"></td><td><a href=\"files.php?path=$dir".str_replace('%2F', '/', rawurlencode($element['name'])).'">'.htmlspecialchars($element['name']).'</a></td><td>'.date("Y-m-d H:i", $element['mtime'])."</td><td>$element[size]</td></tr>";
}
?>
<tr><td colspan="4"><hr></td></tr>
</table>
<input type="submit" name="delete" value="Delete">
<input type="submit" name="rename" value="Rename">
<input type="submit" name="edit" value="Edit">
<input type="submit" name="unzip" value="Unzip"><br><br>
</form>
</body></html>
<?php
function get_properties($name, &$icon, &$size){
if(substr($name, -1, 1)==='/'){
$icon='dir';
}else{
$extension=strtolower(substr($name, strrpos($name, '.')+1));
if(isset(TYPES[$extension])){
$icon=TYPES[$extension];
}else{
$icon='ukwn';
}
$class=(int) log($size, 1024);
if($class!==0){
$size=sprintf('%1.1f', $size / pow(1024, $class)) . SUFFIX[$class];
}else{
$size.=SUFFIX[0];
}
}
}
function send_not_found(){
header("HTTP/1.1 404 Not Found");
echo '<!DOCTYPE html><html><head>';
echo '<title>404 Not Found</title>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
echo '</head><body>';
echo '<p>The requested file '.htmlspecialchars($_REQUEST['path']).' was not found on your account.</p>';
echo '<p><a href="files.php">Go back to home directory</a>.</p>';
echo '</body></html>';
}
function send_login(){
echo '<!DOCTYPE html><html><head>';
echo '<title>Daniel\'s Hosting - FileManager - Login</title>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
echo '</head><body>';
echo '<p>Please type in your system account password: <form action="files.php" method="post"><input name="ftp_pass" type="password" autofocus><input type="submit" value="Login"></form></p>';
echo '<p><a href="home.php">Go back to dashboard</a>.</p>';
echo '</body></html>';
}
function ftp_recursive_upload($ftp, $path){
$dir = dir($path);
while(($file = $dir->read()) !== false) {
if(is_dir($dir->path.$file)) {
if($file === '.' || $file === '..'){
continue;
}
if(@!ftp_chdir($ftp, $file)){
ftp_mkdir($ftp, $file);
ftp_chdir($ftp, $file);
}
ftp_recursive_upload($ftp, $dir->path.$file.'/');
ftp_chdir($ftp, '..');
rmdir($dir->path.$file);
}else{
ftp_put($ftp, $file, $dir->path.$file, FTP_BINARY);
unlink($dir->path.$file);
}
}
$dir->close();
}
function ftp_recursive_delete($ftp, $file){
if(@ftp_chdir($ftp, $file)){
$list = ftp_nlist($ftp, '.');
foreach($list as $tmp){
ftp_recursive_delete($ftp, $tmp);
}
ftp_chdir($ftp, '..');
ftp_rmdir($ftp, $file);
}else{
ftp_delete($ftp, $file);
}
}
function send_rename($dir){
echo '<!DOCTYPE html><html><head>';
echo '<title>Daniel\'s Hosting - FileManager - Rename file</title>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
echo '</head><body>';
echo '<form action="files.php" method="post">';
echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">';
echo '<table>';
foreach($_POST['files'] as $file){
echo '<tr><td>'.htmlspecialchars($file).'</td><td><input type="text" name="files['.htmlspecialchars($file).']" value='.htmlspecialchars($file).'></td></tr>';
}
echo '</table>';
echo '<input type="submit" name="rename_2" value="rename"></form>';
echo '<p><a href="files.php?path='.htmlspecialchars($dir).'">Go back</a>.</p>';
echo '</body></html>';
}
function send_edit($ftp, $dir){
echo '<!DOCTYPE html><html><head>';
echo '<title>Daniel\'s Hosting - FileManager - Edit file</title>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
echo '<meta name=viewport content="width=device-width, initial-scale=1">';
echo '</head><body>';
echo '<form action="files.php" method="post">';
echo '<input type="hidden" name="path" value="'.htmlspecialchars($dir).'">';
echo '<table>';
$tmpfile='/tmp/'.uniqid();
foreach($_POST['files'] as $file){
echo '<tr><td>'.htmlspecialchars($file).'</td><td><textarea name="files['.htmlspecialchars($file).']" rows="10" cols="30">';
ftp_get($ftp, $tmpfile, $file, FTP_BINARY);
echo htmlspecialchars(file_get_contents($tmpfile));
echo '</textarea></td></tr>';
}
unlink($tmpfile);
echo '</table>';
echo '<input type="submit" name="edit_2" value="Save"></form>';
echo '<p><a href="files.php?path='.htmlspecialchars($dir).'">Go back</a>.</p>';
echo '</body></html>';
}