From 5818a75d01d19a961af2ee8092f74777cdf5ce44 Mon Sep 17 00:00:00 2001
From: Fil <fil@rezo.net>
Date: Sun, 23 Dec 2007 23:22:32 +0000
Subject: [PATCH] Pour securiser l'acces aux documents, on passe desormais une
 cle dans l'URL; soit on a obtenu cette cle, et on peut voir le doc, soit non
 et on ne peut pas le voir : on ne regarde donc plus le statut du document a
 chaque hit, ca devrait alleger le serveur (sich)

---
 ecrire/action/acceder_document.php |  8 +++++---
 ecrire/inc/acces.php               |  3 +--
 ecrire/inc/documents.php           | 11 +++++++++--
 ecrire/inc/securiser_action.php    | 27 +++++++++++++++++++++++++++
 4 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/ecrire/action/acceder_document.php b/ecrire/action/acceder_document.php
index 04490c30fd..6350f5208d 100644
--- a/ecrire/action/acceder_document.php
+++ b/ecrire/action/acceder_document.php
@@ -25,8 +25,8 @@ function action_acceder_document_dist() {
 	include_spip('inc/documents');
 
 	// $file exige pour eviter le scan id_document par id_document
-	$file = rawurldecode(_request('file'));
-	$file = get_spip_doc($file);
+	$f = rawurldecode(_request('file'));
+	$file = get_spip_doc($f);
 	$arg = rawurldecode(_request('arg'));
 
 	$status = $dcc = false;
@@ -57,8 +57,10 @@ function action_acceder_document_dist() {
 
 			//
 			// Verifier les droits de lecture du document
+			// en controlant la cle passee en argument
 			//
-			if (!autoriser('voir', 'document', $doc['id_document']))
+			include_spip('inc/securiser_action');
+			if (_request('cle') != calculer_cle_action($doc['id_document'].','.$f))
 				$status = 403;
 		}
 	}
diff --git a/ecrire/inc/acces.php b/ecrire/inc/acces.php
index 54f3d348f6..1b93b1db67 100644
--- a/ecrire/inc/acces.php
+++ b/ecrire/inc/acces.php
@@ -42,7 +42,7 @@ function creer_pass_aleatoire($longueur = 8, $sel = "") {
 }
 
 //
-// Creer un identifiant aleatoire (a fusionnner avec le precedent ?)
+// Creer un identifiant aleatoire
 //
 
 // http://doc.spip.org/@creer_uniqid
@@ -123,7 +123,6 @@ function initialiser_sel() {
 	else return "";
 }
 
-
 // Cette fonction ne sert qu'a la connexion en mode http_auth.non LDAP
 // Son role est de creer le fichier htpasswd
 // Voir le plugin "acces restreint"
diff --git a/ecrire/inc/documents.php b/ecrire/inc/documents.php
index e91131e006..50e0d21964 100644
--- a/ecrire/inc/documents.php
+++ b/ecrire/inc/documents.php
@@ -63,9 +63,16 @@ function generer_url_document_dist($id_document, $args='', $ancre='') {
 	// par exemple acces_restreint
 	if ($GLOBALS['meta']["creer_htaccess"] == 'oui'
 	AND $row['distant'] != 'oui') {
-	  $args .= ($args ? "&" : '') . "arg=$id_document&file=" . rawurlencode($row['fichier']) . ($ancre ? "&ancre=$ancre" : '');
+		include_spip('inc/securiser_action');
+		$args .= ($args ? "&" : '')
+			. 'arg='.$id_document
+			. ($ancre ? "&ancre=$ancre" : '')
+			. '&cle=' . calculer_cle_action($id_document.','.$row['fichier'])
+			. '&file=' . rawurlencode($row['fichier'])
+			;
 		return generer_url_action('acceder_document', $args);
-	} else	return get_spip_doc($row['fichier']);
+	} else
+		return get_spip_doc($row['fichier']);
 }
 
 //
diff --git a/ecrire/inc/securiser_action.php b/ecrire/inc/securiser_action.php
index 50d42d4895..37e449b44e 100644
--- a/ecrire/inc/securiser_action.php
+++ b/ecrire/inc/securiser_action.php
@@ -110,5 +110,32 @@ function verifier_action_auteur($action, $valeur) {
 	return false;
 }
 
+//
+// Des fonctions independantes du visiteur, qui permettent de controler
+// par exemple que l'URL d'un document a la bonne cle de lecture
+//
+
+// Le secret du site doit rester aussi secret que possible, et est eternel
+// On ne doit pas l'exporter
+function secret_du_site() {
+	if (!isset($GLOBALS['meta']['secret_du_site'])
+	OR !strlen($GLOBALS['meta']['secret_du_site'])
+	) {
+		include_spip('inc/acces');
+		ecrire_meta('secret_du_site', creer_uniqid(), 'non');
+	}
+	return $GLOBALS['meta']['secret_du_site'];
+}
+
+// http://doc.spip.org/@calculer_cle_action
+function calculer_cle_action($action) {
+	return md5($action . secret_du_site());
+}
+
+// http://doc.spip.org/@verifier_cle_action
+function verifier_cle_action($action, $cle) {
+	return ($cle == calculer_cle_action($action));
+}
+
 
 ?>
-- 
GitLab