Medium .htaccess protection

From D3xt3r01.tk
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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');
}