Du bist nicht angemeldet. Der Zugriff auf einige Boards wurde daher deaktiviert.

#1 17. Juni 2011 06:38

nockenfell
Moderator
Ort: Gontenschwil, Schweiz
Registriert: 09. November 2010
Beiträge: 2.934
Webseite

Sichere Downloads mit FrontEndUsers und einem Mod von securefile

Vor kurzem habe ich auf meinem Blog einen Artikel zum Thema sicheren Download mit FrontEndUsers geschrieben. Diesen möchte ich euch natürlich nicht vorenthalten:

Um sichere Downloads (nur für authentifizierte Benutzer) zu ermöglichen gibt es verschiedene Wege. Ein Download-Manager-Modul wäre die eine Möglichkeit. Seit längerem gibt es für CMS Made Simple das Plugin securefile. Ich habe das Plugin nun ein wenig weiterentwickelt und den Einsatz vereinfacht.

Voraussetzung ist das FrontEndUser Modul welches den Zugriff auf die Dateien steuert.

Als erstes muss der Ordner der geschützt werden soll mit folgendem .htaccess ausgeschattet werden:

Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule ^(.+)$ download.php?fgroup=3&url=uploads/secfolder/$1 [L]

Dabei müssen folgende Parameter indivduell angepasst werden:

  • fgroup (zwingend): ID der FEU-Gruppe. Mehrere Gruppen können mit Komma getrennt werden
    Beispiel: fgroup=2 oder fgroup=2,3,8

  • url (zwingend): Pfad zum Ordner. Der Ordner muss in /uploads liegen.
    Beispiel: url=uploads/secfolder

  • pageid (optional): ID der Seite auf welche bei einem Fehler weitergeleitet werden soll
    Beispiel: page_id=95

  • pagealias (optional): Alias der Seite auf welche bei einem Fehler weitergeleitet werden soll.
    Beispiel: pagealias=fehlerseite

Zuletzt muss die download.php im CMSms Root (z.B. www.deineseite.com/download.php) abgelegt werden.
Hier die download.php

<?php
# #####################################################################
#    coded for #CMS - CMS Made Simple
#    by (c)2007 by Tina Keil (blackyfreud(at)gmail.com)
#    modified (c)2011 by BlatterTech Informatik (www.blattertech.ch)
#    Version 1.0 - 26.06.2007 inital release
#    Version 1.1 - 13.06.2011 modified by BlatterTech Informatik
#    
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#    
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
# #####################################################################    
    
require_once(dirname(__FILE__)."/include.php");

function redirect403 ($code = 403) {
    $gCms = cmsms();  
    if (isset($_GET['pagealias']) and $_GET['pagealias'] != "" and $code != 404)  {
        $manager = $gCms->GetHierarchyManager();
        $node = $manager->sureGetNodeByAlias($_GET['pagealias']);
        if (isset($node)) {
            $content =& $node->GetContent();
            if ($content !== FALSE && is_object($content) && $content->Active() && $content->HasUsableLink()) {
                $url = $content->GetUrl();
                @session_start();
                $_SESSION['securedl'] = $_GET['url'];
                $_SESSION['securegid'] = $_GET['fgroup'];
                header("Location: ".$url);
                exit;
            }
        }
    }
    if (isset($_GET['pageid']) and $_GET['pageid'] != "" and $code != 404) {
        $manager = $gCms->GetHierarchyManager();
        $node = $manager->getNodeById($_GET['pageid']);
        if (isset($node)) {
            $content =& $node->GetContent();
            if ($content !== FALSE && is_object($content) && $content->Active() && $content->HasUsableLink()) {
                $url = $content->GetUrl();
                @session_start();
                $_SESSION['securedl'] = $_GET['url'];
                $_SESSION['securegid'] = $_GET['fgroup'];
                header("Location: ".$url);
                exit;
            }
        }
    }    
    if ($code == 404) {
        header("HTTP/1.0 404 Not Found");
        echo "
            <html>
                <head>
                    <title>404 Not Found</title>
                </head>
                <body>
                    <p>File not found</p>
                </body>
            </html>
        ";
    }
    else {
        header("HTTP/1.0 403 Forbidden");
        echo "
            <html>
                <head>
                    <title>403 Forbidden</title>
                </head>
                <body>
                    <p>You have no access. Please login.</p>
                </body>
            </html>
        ";
    }
    exit;
}

// Control if all params are available
if (!isset($_GET['url']) or !isset($_GET['fgroup'])) {
    redirect403();
}

$pathinfo = pathinfo($_GET['url']);
$filename = $pathinfo['basename'];

//security check (folder must be in /uploads)
if (strpos($pathinfo['dirname'],"uploads/") === FALSE) {
    redirect403();
}

define("SECURE_FOLDER", dirname(__FILE__).DIRECTORY_SEPARATOR.$pathinfo['dirname']);     
define("LOG_DOWNLOADS", true); //creates a log file in secure folder
define("DELIVER_CHUNKED", true); //enable if you have trouble with large files

############ do not edit below unless you know what you're doing ###########
@ini_set('zlib.output_compression', 'Off');

function readfile_chunked($filename,$retbytes=true) { 
    $chunksize = 1*(1024*1024); //how many bytes per chunk
    $buffer = '';
    $cnt =0;
    $handle = fopen($filename, 'rb');
    if ($handle === false) {
        return false;
    }
    while (!feof($handle)) {
        $buffer = fread($handle, $chunksize);
        echo $buffer;
        ob_flush();
        flush();
        if ($retbytes) {
            $cnt += strlen($buffer);
        }
    }
    $status = fclose($handle);
    if ($retbytes && $status) {
           return $cnt; // return num. bytes delivered like readfile() does.
    }
    return $status;
}

function btHasAccess($feugroups) {
  if (!$feugroups) return false;
  $feusers = cms_utils::get_module('FrontEndUsers');
  $user_id = $feusers->LoggedInId();
  $groups = $feusers->GetMemberGroupsArray($user_id);
  
  $gns = array();
  if($groups !== false ) {
      foreach( $groups as $gid ) {
          $gns[] = $gid['groupid'];
      }
  }
  
  $feuArray= explode(',',$feugroups);
  $retval = false;
  foreach ($feuArray as $feu) {
      if (in_array($feu,$gns)) return true;
  }
  return false;
}

function btGetUsername() {
    $feusers = cms_utils::get_module('FrontEndUsers');
    return $feusers->LoggedInName();
}

// check FEU access
if (btHasAccess($_GET['fgroup'])) {
    $username = btGetUserName();
}
else {
    redirect403();
}

// check file_exists
if (!file_exists(SECURE_FOLDER.DIRECTORY_SEPARATOR.$filename)){
    redirect403(404);
}


if (ereg("Mac", $browser) and ereg("MSIE", $browser)) {
    $typ = "application/octet-stream";
} 
else {
    $typ = "application/x-download";
}
  
//headers
header('Pragma: public');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate'); // HTTP/1.1 
header('Cache-Control: pre-check=0, post-check=0, max-age=0'); // HTTP/1.1 
header('Content-Transfer-Encoding: none');
header("Accept-Ranges: bytes");
header("Content-Type: $typ");
header("Content-Disposition: attachment; filename=\"{$filename}\";");

//deliver file
@set_time_limit(0); //make sure large files dont get timed out.
if (DELIVER_CHUNKED == true) {
    echo @readfile_chunked(SECURE_FOLDER.DIRECTORY_SEPARATOR.$filename);
} 
else {
    echo @readfile(SECURE_FOLDER.DIRECTORY_SEPARATOR.$filename);
}
//log the download
if (LOG_DOWNLOAD == true) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $host = gethostbyaddr($ip);
    if (empty($host)) { $host = "UNRESOLVED"; }
    $datenow = date("Y.m.d");
    $timenow = date("H:i:s");
    $browser = $_SERVER['HTTP_USER_AGENT'];
    
    $logfile = SECURE_FOLDER.DIRECTORY_SEPARATOR."download_log.csv";
    $logdata = "";
    if (!is_file($logfile)) // add title at first line
        $logdata .="Date;Time;Filename;Username;IP-Adress;Host;Browser\n";
    $logdata .= $datenow.";".$timenow.";".$filename.";".$username.";".$ip.";".$host.";".$browser."\n";
    @file_put_contents($logfile, $logdata, FILE_APPEND | LOCK_EX);
}
exit;

Securefile1.1 herunterladen


[dieser Beitrag wurde mit 100% recycled bits geschrieben]
Mein Blog  /   Diverse Links rund um CMS Made Simple
Module: btAdminer, ToolBox

Offline