Medium .htaccess protection: Difference between revisions
Created page with "==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 "Bro..." |
|||
(8 intermediate revisions by the same user not shown) | |||
Line 24: | Line 24: | ||
</RequireAll> | </RequireAll> | ||
</RequireAny | </RequireAny | ||
</source> | |||
==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 .. | |||
<source lang="php"> | |||
<?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: ."); | |||
</source> | |||
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... | |||
<source lang="bash"> | |||
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> | |||
</source> | |||
Here's the play.php file | |||
<source lang="php"> | |||
<?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'); | |||
} | |||
</source> | </source> |
Latest revision as of 19:55, 4 August 2013
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');
}