[SPIP] ~2.1.12 -->2.1.25
[velocampus/web/www.git] / www / ecrire / inc / securiser_action.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 // interface d'appel:
16 // - au moins un argument: retourne une URL ou un formulaire securises
17 // - sans argument: verifie la securite et retourne _request('arg'), ou exit.
18
19 // http://doc.spip.org/@inc_securiser_action_dist
20 function inc_securiser_action_dist($action='', $arg='', $redirect="", $mode=false, $att='', $public=false)
21 {
22 if ($action)
23 return securiser_action_auteur($action, $arg, $redirect, $mode, $att, $public);
24 else {
25 $arg = _request('arg');
26 $hash = _request('hash');
27 $action = _request('action')?_request('action'):_request('formulaire_action');
28 if ($a = verifier_action_auteur("$action-$arg", $hash))
29 return $arg;
30 include_spip('inc/minipres');
31 echo minipres();
32 exit;
33 }
34 }
35
36 // Attention: PHP applique urldecode sur $_GET mais pas sur $_POST
37 // cf http://fr.php.net/urldecode#48481
38 // http://doc.spip.org/@securiser_action_auteur
39 function securiser_action_auteur($action, $arg, $redirect="", $mode=false, $att='', $public=false)
40 {
41 static $id_auteur=0, $pass;
42 if (!$id_auteur) {
43 list($id_auteur, $pass) = caracteriser_auteur();
44 }
45 $hash = _action_auteur("$action-$arg", $id_auteur, $pass, 'alea_ephemere');
46 if (!is_string($mode)){
47 $r = rawurlencode($redirect);
48 if ($mode===-1)
49 return array('action'=>$action,'arg'=>$arg,'hash'=>$hash);
50 else
51 return generer_url_action($action, "arg=$arg&hash=$hash" . (!$r ? '' : "&redirect=$r"), $mode, $public);
52 }
53
54 $att .= " style='margin: 0px; border: 0px'";
55 if ($redirect)
56 $redirect = "\n\t\t<input name='redirect' type='hidden' value='". str_replace("'", '&#39;', $redirect) ."' />";
57 $mode .= $redirect . "
58 <input name='hash' type='hidden' value='$hash' />
59 <input name='arg' type='hidden' value='$arg' />";
60
61 return generer_form_action($action, $mode, $att, $public);
62 }
63
64 // http://doc.spip.org/@caracteriser_auteur
65 function caracteriser_auteur() {
66 global $visiteur_session;
67 static $caracterisation = array();
68
69 if ($caracterisation) return $caracterisation;
70
71 if (!isset($visiteur_session['id_auteur'])) {
72 // si l'auteur courant n'est pas connu alors qu'il peut demander une action
73 // c'est une connexion par php_auth ou 1 instal, on se rabat sur le cookie.
74 // S'il n'avait pas le droit de realiser cette action, le hash sera faux.
75 if (isset($_COOKIE['spip_session'])
76 AND (preg_match('/^(\d+)/',$_COOKIE['spip_session'],$r))) {
77 return array($r[1], '');
78 // Necessaire aux forums anonymes.
79 // Pour le reste, ca echouera.
80 } else return array('0','');
81 }
82 // Eviter l'acces SQL si le pass est connu de PHP
83 $id_auteur = $visiteur_session['id_auteur'];
84 if (isset($visiteur_session['pass']) AND $visiteur_session['pass'])
85 return $caracterisation = array($id_auteur, $visiteur_session['pass']);
86 else if ($id_auteur>0) {
87 include_spip('base/abstract_sql');
88 $t = sql_fetsel("id_auteur, pass", "spip_auteurs", "id_auteur=$id_auteur");
89 if ($t)
90 return $caracterisation = array($t['id_auteur'], $t['pass']);
91 include_spip('inc/minipres');
92 echo minipres();
93 exit;
94 }
95 // Visiteur anonyme, pour ls forums par exemple
96 else {
97 return array('0','');
98 }
99 }
100
101 // http://doc.spip.org/@_action_auteur
102 function _action_auteur($action, $id_auteur, $pass, $alea) {
103 static $sha = array();
104 if (!isset($sha[$id_auteur.$pass.$alea])){
105 if (!isset($GLOBALS['meta'][$alea]) AND _request('exec')!=='install') {
106 include_spip('base/abstract_sql');
107 $GLOBALS['meta'][$alea] = sql_getfetsel('valeur', 'spip_meta', "nom=" . sql_quote($alea));
108 if (!($GLOBALS['meta'][$alea])) {
109 include_spip('inc/minipres');
110 echo minipres();
111 spip_log("$alea indisponible");
112 exit;
113 }
114 }
115 include_spip('auth/sha256.inc');
116 $sha[$id_auteur.$pass.$alea] = _nano_sha256($id_auteur.$pass.@$GLOBALS['meta'][$alea]);
117 }
118 if (function_exists('sha1'))
119 return sha1($action.$sha[$id_auteur.$pass.$alea]);
120 else
121 return md5($action.$sha[$id_auteur.$pass.$alea]);
122 }
123
124 // http://doc.spip.org/@calculer_action_auteur
125 function calculer_action_auteur($action) {
126 list($id_auteur, $pass) = caracteriser_auteur();
127 return _action_auteur($action, $id_auteur, $pass, 'alea_ephemere');
128 }
129
130 // http://doc.spip.org/@verifier_action_auteur
131 function verifier_action_auteur($action, $valeur) {
132 list($id_auteur, $pass) = caracteriser_auteur();
133 if ($valeur == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere'))
134 return true;
135 if ($valeur == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere_ancien'))
136 return true;
137 return false;
138 }
139
140 //
141 // Des fonctions independantes du visiteur, qui permettent de controler
142 // par exemple que l'URL d'un document a la bonne cle de lecture
143 //
144
145 // Le secret du site doit rester aussi secret que possible, et est eternel
146 // On ne doit pas l'exporter
147 // http://doc.spip.org/@secret_du_site
148 function secret_du_site() {
149 if (!isset($GLOBALS['meta']['secret_du_site'])){
150 include_spip('base/abstract_sql');
151 $GLOBALS['meta']['secret_du_site'] = sql_getfetsel('valeur', 'spip_meta', "nom='secret_du_site'");
152 }
153 if (!isset($GLOBALS['meta']['secret_du_site'])
154 OR (strlen($GLOBALS['meta']['secret_du_site'])<64)) {
155 include_spip('inc/acces');
156 include_spip('auth/sha256.inc');
157 ecrire_meta('secret_du_site', _nano_sha256($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SERVER_SIGNATURE"] . creer_uniqid()), 'non');
158 lire_metas(); // au cas ou ecrire_meta() ne fonctionne pas
159 }
160 return $GLOBALS['meta']['secret_du_site'];
161 }
162
163 // http://doc.spip.org/@calculer_cle_action
164 function calculer_cle_action($action) {
165 if (function_exists('sha1'))
166 return sha1($action . secret_du_site());
167 else
168 return md5($action . secret_du_site());
169 }
170
171 // http://doc.spip.org/@verifier_cle_action
172 function verifier_cle_action($action, $cle) {
173 return ($cle == calculer_cle_action($action));
174 }
175
176 ?>