Medium .htaccess protection
WHY
Because I wanted to give some access to sime files based on some stuff ..
HOW
This will allow users with the user-agents starting with "Thing", "Some" and "Browser" to directly access files with extensions ".ex3", ".ex2" and ".ex1" without needing a password... it's useful for example on tablets where the players don't/can't auth...
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /path/to/.passwords
AuthGroupFile /path/to/.groups
SetEnvIf User-Agent ^Thing isplayer=1
SetEnvIf User-Agent ^Some isplayer=1
SetEnvIf User-Agent ^Browser isplayer=1
SetEnvIf Request_URI "\.ex3$" isfile=1
SetEnvIf Request_URI "\.ex2$" isfile=1
SetEnvIf Request_URI "\.ex1$" isfile=1
<RequireAny>
Require group onegroup anothergroup
<RequireAll>
Require env isfile
Require env isplayer
</RequireAll>
</RequireAny
MEDIUM2 WAY
You can do it somehow in another way .. you can make a page "auth.php" that would use sqlite to have a database user/ip/date ..
<?php
if(!isset($_SERVER['REMOTE_ADDR'])){
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
}
if(!isset($_SERVER['REMOTE_USER'])){
$_SERVER['REMOTE_USER'] = 'cli';
}
$db = new PDO('sqlite:/tmp/sqlite.db');
$query = 'CREATE TABLE IF NOT EXISTS auth (id int, user varchar(32), ip varchar(15), data int, PRIMARY KEY (id))';
if(!$create = $db->prepare($query)){
print_r($db->errorInfo()); die();
}
$query = 'DELETE FROM auth WHERE data < "'.(time()-60*60*5).'"';
if(!$delete = $db->prepare($query)){
print_r($db->errorInfo()); die();
}
$query = 'SELECT COUNT(*) FROM auth WHERE user = "'.$_SERVER['REMOTE_USER'].'" AND ip = "'.$_SERVER['REMOTE_ADDR'].'"';
if(!$count = $db->query($query)){
print_r($db->errorInfo()); die();
}
if($count->fetchColumn() < 1){
if(!$insert = $db->query('INSERT INTO auth (user, ip, data) values ("'.$_SERVER['REMOTE_USER'].'", "'.$_SERVER['REMOTE_ADDR'].'", "'.time().'")')){
print_r($db->errorInfo()); die();
}
}else{
if(!$update = $db->query('UPDATE auth SET data = "'.time().'" WHERE user = "'.$_SERVER['REMOTE_USER'].'" AND ip = "'.$_SERVER['REMOTE_ADDR'].'"')){
print_r($db->errorInfo()); die();
}
}
header("Location: .");
Now you have a database and can auto limit so only a specified ip can access those files without a password for a specified time :)
This .htaccess will redirect all requests for those .ex1, .ex2 and .ex3 extensions that also come with a specified browser to play.php which will check the sqlite db and passthrough the requested file .. also, we will be replying a 403 for any dir index from those browsers...
Options +Indexes
SetEnvIf Request_URI "\.ex1$" DEXISFILE=yes
SetEnvIf Request_URI "\.ex2$" DEXISFILE=yes
SetEnvIf Request_URI "\.ex3$" DEXISFILE=yes
SetEnvIf User-Agent "^some" DEXISPLAYER=yes
SetEnvIf User-Agent "^browser" DEXISPLAYER=yes
SetEnvIf User-Agent "^thing" DEXISPLAYER=yes
RewriteEngine On
RewriteBase /path/to/play/
RewriteCond %{ENV:DEXISPLAYER} ^yes$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [F,L]
RewriteCond %{ENV:DEXISFILE} ^yes$
RewriteCond %{ENV:DEXISPLAYER} ^yes$
RewriteRule ^ play.php?file=%{REQUEST_FILENAME} [L]
AuthType Basic
AuthName "Restricted Files"
AuthUserFile /path/to/.passwords
AuthGroupFile /path/to/.groups
<RequireAny>
Require group somegroup anothergroup
<RequireAll>
Require env DEXISFILE
Require env DEXISPLAYER
</RequireAll>
</RequireAny>
Here's the play.php file
<?php
function ftype($file){
$fi = new finfo(FILEINFO_MIME);
$mime_type = $fi->file($file);
return $mime_type;
}
if(!isset($_SERVER['REMOTE_ADDR'])){
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
}
if(!isset($_SERVER['REMOTE_USER'])){
$_SERVER['REMOTE_USER'] = 'cli';
}
$db = new PDO('sqlite:/tmp/sqlite.db');
$query = 'CREATE TABLE IF NOT EXISTS auth (id int, user varchar(32), ip varchar(15), data int, PRIMARY KEY (id))';
if(!$create = $db->prepare($query)){
print_r($db->errorInfo()); die();
}
$query = 'SELECT COUNT(*) FROM auth WHERE ip = "'.$_SERVER['REMOTE_ADDR'].'" AND data > '.(time()-5*60*60);
if(!$count = $db->query($query)){
print_r($db->errorInfo()); die();
}
if($count->fetchColumn() > 0){
$file = $_GET['file'];
$fh = fopen($file, 'rb');
header("Content-Type: ".ftype($file));
header("Content-Length: " . filesize($file));
fpassthru($fh);
}else{
header('HTTP/1.0 403 Forbidden');
}