File download nur nach Lizenzzustimmung

R

rikola

Foren Gott
Hallo,
ich moechte ueber meine Homepage einen Quellcode zur Verfuegung stellen, es allerdings so einrichten, dass
1) google et al. den Code nicht einfach automatisch runterladen koennen
2) jemand, der auf den link zum quellarchiv klickt, vorher eine Seite oder ein pop-up Fenster sieht, auf dem er bestaetigt, dass er der Lizenz zustimmt, wenn er das Archiv runterlaedt.
Wie erreiche ich das? Bei 1) koennte eine 'robots.txt' weiterhelfen, doch habe ich noch keine hilfreiche Formatbeschreibung davon gefunden. Bei 2) dachte ich z.B. an eine .htaccess-Datei bei der dann ein dummy-Passwort eingegeben wird, solange im Fenster eben der Hinweis auf die Lizenz steht.
Fuer Tips und Links bin ich dankbar.
 
Das einfachste wäre wohl ein PHP-Skript, dass dann über einen Request-Parameter (accepted) oder ein Cookie (nicht so schön) prüft, ob auf Zustimmen geklickt wurde. Dann gibt's zwei Möglichkeiten, entweder du lieferst die Datei per PHP-Skript aus oder du generierst einen Link, der nur eine bestimmte Zeit gültig ist und lässt den Webservder die Datei ausliefern. Beispiel hier: http://redmine.lighttpd.net/wiki/1/Docs:ModSecDownload
 
Die 2. Lösung finde ich persönlich übrigens sehr elegant.
 
Mach kein Popup sondern eine extra-Seite, die in einem neuen Fenster aufgerufen wird. Sprich du hast einen Link "Download" -> per JS wird ein neues Fenster aufgemacht, in dem dann eine Seite mit deiner Lizenz angezeigt wird und unten ist dann ein submit-Button, der ein PHP-Skript aufruft, dass dich entweder auf den Link umleitet oder direkt die Datei ausliefert.
 
Klingt nach einer guten Loesung. Nach welchem Stichwort sollte ich schauen, um zu lernen, wie man mit php "eine Datei ausliefert"?
 
Mal eben gebastelt, ohne es probiert zu haben:

Aufruf wäre dann skript.php?file=filename

Code:
<?php
$dir="/home/alin/docs/trc/";
if (isset($_REQUEST["file"]  && isset($_REQUEST["accepted"])) {
    $file=$dir.basename($_REQUEST["file"]);
    header("Content-type: application/force-download");
    header("Content-Transfer-Encoding: Binary");
    header("Content-length: ".filesize($file));
    header("Content-disposition: attachment; filename=\"".basename($file)."\"");
    readfile("$file");
} else { ?>


Hier kommt dann deine Lizenz hin

<form action="/pfad/zu/dieser/php/datei" method="POST">
<input type="submit" name="accepted" value="Akzeptieren" />
<input type="hidden" name="file" value="<? echo $_REQUEST["file"]; ?>" />
</form>
<?
    }

?>


EDIT: 1 Bug korrigiert

EDIT2: Fiese Sicherheitslücke entfernt, peinlich..
 
Zuletzt bearbeitet:
das Script aber bitte nicht 1:1 übernehmen sondern als Arbeitsgrundlage sehen...
 
marce: Warum nicht? Ich hab zugegebenermaßen nicht lange drüber nachgedacht, aber was für ein Problem siehst du?
 
bin kein php-Experte, aber ein http://$URL/script.php?file=../../../../../etc/passwd&accepted=yes z.B. sieht durchaus vielversprechend aus...
 
bin kein php-Experte, aber ein http://$URL/script.php?file=../../../../../etc/passwd&accepted=yes z.B. sieht durchaus vielversprechend aus...
Kann apache denn ueber so ein Argument aus seiner chroot-Umgebung ausbrechen, in der es normalerweise laeuft? Oder laeuft apache nicht unter chroot?
 
Zuletzt bearbeitet:
ein Apache läuft per default nicht in einer chroot-Umgebung. Er läuft (default) mit einem anderen User - und darf alles, was der User darf. z.B. div. Dateien lesen. Es muss ja auch nicht mal die /etc/passwd sein - aber z.B. einer /var/www/phpMyAdmin/config.inc.php oder eine andere Configdatei mit "interessanten Infos" für CMS oder anderes darf er ja lesen (muss er ja auch).

Alles weitere (irgednweoche mod_fcg, suhosin, ... können das zwar einschränken aber per sich nicht 100% verhindern - und daher gilt: externe Daten (und da gehören Get- und Post-Parameter dazu) sind per se nicht vertrauenswürdig und müssen daher entsprechend bearbeitet werden.
 
Gut zu wissen. In meinem Fall kenne ich den Dateinamen ja auch, und das sollte es mir doch ermoeglichen, ihn fest anzugeben, so dass das Skript dann keine Uebergabeparameter bearbeitet ausser der Abfrage, ob der "accept"-Knopf gedrueckt wurde.
 
Marce, das ist ein guter Einwand, aber deshalb wird in dem Skript mit einem festen Pfad ($dir) gearbeitet und mit basename sollten alle Verzeichnisangaben entfernt werden. Aber natürlich sollte man das testen.
 
Ach ja, wenn es nur ein Dateiname ist sollte man den natürlich fest eintragen. Alternativ wäre auch denkbar, gültige Dateien in einer DB zu hinterlegen und dann mit einem Schlüssel auszuliefern. Eingaben vom Nutzer direkt zu übernehmen ist generell keine gute Idee, das stimmt schon.
 
Code:
<?php
$dir="/home/alin/docs/trc/";
if (isset($_REQUEST["file"]  && isset($_REQUEST["accepted"])) {
    [COLOR="red"][B]$file=$dir.$_REQUEST["file"];[/B][/COLOR]
    header("Content-type: application/force-download");
    header("Content-Transfer-Encoding: Binary");
    header("Content-length: ".filesize($file));
    header("Content-disposition: attachment; filename=\"".basename($file)."\"");
    [COLOR="red"][B]readfile("$file");[/B][/COLOR]
} else { ?>
?>
Du verwendest zwar Basename - aber leider an der "falschen" Stelle... Readfile geht auf den originalen Wert... - und damit kommt man auch an alles im FS, wo der Apache zugreifen kann...
 
Wow, was für ein Scheiß.. Ich hab das Skript nur geklaut und überflogen... Ich geh mal meinen Post weiter oben editieren.. Danke fürs drüberschauen..
 

Ähnliche Themen

[HowTo] TeamSpeak 2 - RC2 - Server (Deutsch/Englisch)

Zurück
Oben