diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..69c1c71
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,10 @@
+IndexIgnore *
+Order Deny,Allow
+Deny from all
+
+
+ Allow from all
+
+
+ Allow from all
+
diff --git a/README.md b/README.md
index e77d265..c64b067 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,9 @@ You have to upload index.php into your server.
If you open index.php you can edit several settings.
You should make sure the edited file will be saved in UTF-8!
+An example of how to protect direct Access through .htaccess (apache)
+is available and must be adjusted to the webserver.
+
License
----------------------------------
diff --git a/index.php b/index.php
index a2ffe79..6f28446 100644
--- a/index.php
+++ b/index.php
@@ -145,6 +145,10 @@
// If set to true, you should specify some users as well (see below).
// Important: This only prevents people from seeing the list.
// They will still be able to access the files with a direct link.
+// Addition: Combine htaccess and require_login to disallow
+// direct access to file. File access gets logged more precisely.
+// Attention: Be advised, the file is processed by PHP,
+// large/slow downloads might break due to php_script_timeout
// Default: $_CONFIG['require_login'] = false;
//
$_CONFIG['require_login'] = false;
@@ -787,7 +791,7 @@
//Polish
$_TRANSLATIONS["pl"] = array(
"file_name" => "Nazwa pliku",
- "size" => "Rozmiar",
+ "size" => "Rozmiar",
"last_changed" => "Data zmiany",
"total_used_space" => "Cała przestrzeń",
"free_space" => "Wolna przestrzeń",
@@ -796,17 +800,17 @@
"failed_upload" => "Przesłanie pliku nie powiodło się",
"failed_move" => "Przenoszenie pliku nie powiodło się!",
"wrong_password" => "Niepoprawne hasło",
- "make_directory" => "Nowy folder",
+ "make_directory" => "Nowy folder",
"new_dir_failed" => "Błąd podczas tworzenia nowego folderu",
"chmod_dir_failed" => "Błąd podczas zmiany uprawnień folderu",
"unable_to_read_dir" => "Odczytanie folderu nie powiodło się",
- "location" => "Miejsce",
+ "location" => "Miejsce",
"root" => "Start",
"log_file_permission_error" => "Brak uprawnień aby utworzyć dziennik działań.",
"upload_not_allowed" => "Konfiguracja zabrania przesłania pliku do tego folderu.",
"upload_dir_not_writable" => "Nie można zapisać pliku do tego folderu.",
"mobile_version" => "Wersja mobilna",
- "standard_version" => "Widok standardowy",
+ "standard_version" => "Widok standardowy",
"page_load_time" => "Załadowano w %.2f ms",
"wrong_pass" => "Niepoprawna nazwa użytkownika lub złe hasło",
"username" => "Użytkownik",
@@ -1728,6 +1732,10 @@ function css()
$_IMAGES["xlsx"] = $_IMAGES["spreadsheet"];
$_IMAGES["xml"] = $_IMAGES["code"];
$_IMAGES["zip"] = $_IMAGES["archive"];
+$_IMAGES["download"] = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAA
+CxMAAAsTAQCanBgAAAAHdElNRQfhAxUJJiDGyieZAAAAeklEQVQoz62QsQqAMAxEn7Wbn9NZP0Dw
+/0e/Qu0QGhcrTakI4mVIAncXLvCCzmz+6tImeyKCEG9ioclbX6tcMStquiEMuMLN4xis00hC0KuE
+xFgfC0QSipKIhFaKiQNFOZievhLY2dvqjIWFb1jvBLlW+8m5zs3GTzgBdP0qMaa27WIAAAAASUVO";
/***************************************************************************/
/* HERE COMES THE CODE. */
@@ -1926,8 +1934,12 @@ public static function log($message)
public static function logAccess($path, $isDir)
{
$message = $_SERVER['REMOTE_ADDR']." ".GateKeeper::getUserName()." accessed ";
- $message .= $isDir?"dir":"file";
+ $message .= $isDir && !(isset($_GET['file']) || isset($_GET['dl'])) ? "dir" : "file";
$message .= " ".$path;
+ if (isset($_GET['file']))
+ $message.= $_GET['file'];
+ if (isset($_GET['dl']))
+ $message.= $_GET['dl'];
Logger::log($message);
}
@@ -1950,6 +1962,14 @@ public static function logCreation($path, $isDir)
Logger::log($message);
}
+ public static function logDeletion($path, $isDir)
+ {
+ $message = $_SERVER['REMOTE_ADDR']." ".GateKeeper::getUserName()." deleted ";
+ $message .= $isDir?"dir":"file";
+ $message .= " ".$path;
+ Logger::log($message);
+ }
+
public static function emailNotification($path, $isFile)
{
if(strlen(EncodeExplorer::getConfig('upload_email')) > 0)
@@ -1961,6 +1981,18 @@ public static function emailNotification($path, $isFile)
mail(EncodeExplorer::getConfig('upload_email'), "Upload notification", $message);
}
}
+
+ public static function emailNotificationDeletion($path, $isFile)
+ {
+ if(strlen(EncodeExplorer::getConfig('upload_email')) > 0)
+ {
+ $message = "This is a message to let you know that ".GateKeeper::getUserName()." ";
+ $message .= ($isFile?"deleted a file":"deleted a directory")." in Encode Explorer.\n\n";
+ $message .= "Path : ".$path."\n";
+ $message .= "IP : ".$_SERVER['REMOTE_ADDR']."\n";
+ mail(EncodeExplorer::getConfig('delete_email'), "Deletion notification", $message);
+ }
+ }
}
//
@@ -2097,6 +2129,18 @@ public static function showLoginBox(){
return true;
return false;
}
+
+
+ public static function isAccessAllowedOnFile($filepath) {
+ $path = str_replace(basename($filepath), "", $filepath);
+
+ foreach(explode("/", $path) as $dir) {
+ if (in_array($dir, EncodeExplorer::getConfig('hidden_dirs')))
+ return false;
+ }
+
+ return !in_array(basename($filepath), EncodeExplorer::getConfig('hidden_files'));
+ }
}
//
@@ -2208,6 +2252,56 @@ function uploadFile($location, $userfile)
}
}
+ function downloadFile($filepath)
+ {
+ $filepath = EncodeExplorer::getConfig('basedir').$filepath;
+ if (strpos($filepath, '../') !== false)
+ return; // Not allowed
+ if( file_exists( $filepath ) )
+ {
+ header( 'Cache-Control: public' );
+ header( 'Content-Description: File Transfer' );
+ header( 'Content-Disposition: attachment; filename='.basename($filepath) );
+ header( 'Content-Type: '.File::getFileMime($filepath) ); // application/octet-stream
+ header( 'Content-Length: '.filesize($filepath));
+ header( 'Content-Transfer-Encoding: binary' );
+ readfile( $filepath );
+ exit;
+ }
+ }
+
+ function provideFile($filepath)
+ {
+ $filepath = EncodeExplorer::getConfig('basedir').$filepath;
+ if (strpos($filepath, '../') !== false)
+ return; // Not allowed
+ if( file_exists( $filepath ) )
+ {
+ $mtime = gmdate('r', filemtime($_SERVER['SCRIPT_FILENAME']));
+ $etag = md5($mtime.$_SERVER['SCRIPT_FILENAME']);
+
+ if ((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $mtime)
+ || (isset($_SERVER['HTTP_IF_NONE_MATCH']) && str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == $etag))
+ {
+ header('HTTP/1.1 304 Not Modified');
+ return true;
+ }
+ else {
+ header( 'ETag: "'.$etag.'"' );
+ header( 'Last-Modified: '.$mtime );
+ header( 'Cache-Control: public' );
+ //header( 'Content-Description: File Transfer' );
+ header( 'Content-Disposition: filename='.basename($filepath) );
+ header( 'Content-type: '.File::getFileMime($filepath) );
+ header( 'Content-Length: '.filesize($filepath));
+ header( 'Content-Transfer-Encoding: binary' );
+ readfile( $filepath );
+ exit;
+ }
+ return true;
+ }
+ }
+
public static function delete_dir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
@@ -2221,12 +2315,16 @@ public static function delete_dir($dir) {
}
reset($objects);
rmdir($dir);
+ Logger::logDeletion("./".$dir, true);
+ Logger::emailNotificationDeletion("./".$dir, false);
}
}
public static function delete_file($file){
if(is_file($file)){
unlink($file);
+ Logger::logDeletion("./".$file, false);
+ Logger::emailNotificationDeletion("./".$file, true);
}
}
@@ -2265,6 +2363,11 @@ function run($location)
FileManager::delete_file($path);
}
}
+
+ if (isset($_GET['dl']) && !empty($_GET['dl']) && GateKeeper::isAccessAllowed() && GateKeeper::isAccessAllowedOnFile($_GET['dl']))
+ $this->downloadFile($_GET['dl']);
+ if (isset($_GET['file']) && !empty($_GET['file']) && GateKeeper::isAccessAllowed() && GateKeeper::isAccessAllowedOnFile($_GET['file']))
+ $this->provideFile($_GET['file']);
}
}
@@ -2626,7 +2729,7 @@ function init()
if(function_exists('date_default_timezone_get') && function_exists('date_default_timezone_set'))
{
@date_default_timezone_set(date_default_timezone_get());
- }
+ }
if(isset($_GET['lang']) && is_scalar($_GET['lang']) && isset($_TRANSLATIONS[$_GET['lang']]))
$this->lang = $_GET['lang'];
@@ -2726,8 +2829,8 @@ function sort()
usort($this->dirs, array('EncodeExplorer', 'cmp_'.$sort_by));
if($this->sort_as == "desc") {
$this->dirs = array_reverse($this->dirs);
- }
}
+ }
// Here we filter the comparison functions supported by our file object
$sort_by = in_array($this->sort_by, array('name', 'size', 'mod')) ? $this->sort_by : 'name';
@@ -2736,7 +2839,7 @@ function sort()
usort($this->files, array('EncodeExplorer', 'cmp_'.$sort_by));
if($this->sort_as == "desc") {
$this->files = array_reverse($this->files);
- }
+ }
}
}
@@ -2979,7 +3082,7 @@ function outputHtml()
});
logging == true)
+ if($this->logging == true && !GateKeeper::isLoginRequired())
{
?>
function logFileClick(path)
@@ -2994,7 +3097,7 @@ function logFileClick(path)
}
$("a.file").click(function(){
- logFileClick("location->getDir(true, true, false, 0);?>" + $(this).html());
+ logFileClick("./" + $(this).attr('href').replace("?dl=","").replace("?file=",""));
return true;
});
<\/div>");
+ $("body").append("
<\/div>");
positionThumbnail(e);
$("#thumb").fadeIn("medium");
},
@@ -3107,13 +3210,14 @@ function(){
mobile == false && GateKeeper::isDeleteAllowed()){?>
|
+
DL |
|
-
+ |
..
|
@@ -3146,6 +3250,7 @@ function(){
{
print "
getName())."\" href=\"".$this->makeLink(false, false, null, null, $this->location->getDir(false, true, false, 0).$dir->getNameEncoded(), $this->location->getDir(false, true, false, 0))."\"> | ";
}
+ print "
| ";
print "\n";
$row =! $row;
}
@@ -3162,8 +3267,10 @@ function(){
$row_style = ($row ? "one" : "two");
print "
files)?" last":"")."\">\n";
print "getType()."\" src=\"".$this->makeIcon($file->getType())."\" /> | \n";
- print "\n";
- print "\t\tlocation->getDir(false, true, false, 0).$file->getNameEncoded()."\"";
+ print " | \n";
+ print GateKeeper::isLoginRequired()
+ ? "\t\tlocation->getDir(false, true, false, 0).$file->getNameEncoded()."\""
+ : "\t\tlocation->getDir(false, true, false, 0).$file->getNameEncoded()."\"";
if(EncodeExplorer::getConfig('open_in_new_window') == true)
print "target=\"_blank\"";
print " class=\"item file";
@@ -3190,6 +3297,14 @@ function(){
| ";
}
+
+ print "";
+ print GateKeeper::isLoginRequired()
+ ? "location->getDir(false, true, false, 0).$file->getNameEncoded()."\" class=\"item file\" download>"
+ : "location->getDir(false, true, false, 0).$file->getNameEncoded()."\" class=\"item file\" download>";
+ print "";
+ print " | \n";
+
print "
\n";
$row =! $row;
}
@@ -3230,7 +3345,7 @@ function(){
{
?>
-