[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / ecrire / action / logout.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2017 *
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 /**
14 * Action pour déconnecter une personne authentifiée
15 *
16 * @package SPIP\Core\Authentification
17 */
18
19 if (!defined('_ECRIRE_INC_VERSION')) {
20 return;
21 }
22
23 include_spip('inc/cookie');
24
25 /**
26 * Se déloger
27 *
28 * Pour éviter les CSRF on passe par une étape de confirmation si pas de jeton fourni
29 * avec un autosubmit js pour ne pas compliquer l'expérience utilisateur
30 *
31 * Déconnecte l'utilisateur en cours et le redirige sur l'URL indiquée par
32 * l'argument de l'action sécurisée, et sinon sur la page d'accueil
33 * de l'espace public.
34 *
35 */
36 function action_logout_dist() {
37 $logout = _request('logout');
38 $url = securiser_redirect_action(_request('url'));
39 // cas particulier, logout dans l'espace public
40 if ($logout == 'public' and !$url) {
41 $url = url_de_base();
42 }
43
44 // seul le loge peut se deloger (mais id_auteur peut valoir 0 apres une restauration avortee)
45 if (isset($GLOBALS['visiteur_session']['id_auteur'])
46 and is_numeric($GLOBALS['visiteur_session']['id_auteur'])
47 // des sessions anonymes avec id_auteur=0 existent, mais elle n'ont pas de statut : double check
48 and isset($GLOBALS['visiteur_session']['statut'])
49 ) {
50
51 // il faut un jeton pour fermer la session (eviter les CSRF)
52 if (!$jeton = _request('jeton')
53 or !verifier_jeton_logout($jeton, $GLOBALS['visiteur_session'])
54 ) {
55 $jeton = generer_jeton_logout($GLOBALS['visiteur_session']);
56 $action = generer_url_action("logout", "jeton=$jeton");
57 $action = parametre_url($action, 'logout', _request('logout'));
58 $action = parametre_url($action, 'url', _request('url'));
59 include_spip("inc/minipres");
60 include_spip("inc/filtres");
61 $texte = bouton_action(_T('spip:icone_deconnecter'), $action);
62 $texte = "<div class='boutons'>$texte</div>";
63 $texte .= '<script type="text/javascript">document.write("<style>body{visibility:hidden;}</style>");window.document.forms[0].submit();</script>';
64 $res = minipres(_T('spip:icone_deconnecter'), $texte, '', true);
65 echo $res;
66
67 return;
68 }
69
70 include_spip('inc/auth');
71 auth_trace($GLOBALS['visiteur_session'], '0000-00-00 00:00:00');
72 // le logout explicite vaut destruction de toutes les sessions
73 if (isset($_COOKIE['spip_session'])) {
74 $session = charger_fonction('session', 'inc');
75 $session($GLOBALS['visiteur_session']['id_auteur']);
76 spip_setcookie('spip_session', $_COOKIE['spip_session'], time() - 3600);
77 }
78 // si authentification http, et que la personne est loge,
79 // pour se deconnecter, il faut proposer un nouveau formulaire de connexion http
80 if (isset($_SERVER['PHP_AUTH_USER'])
81 and !$GLOBALS['ignore_auth_http']
82 and $GLOBALS['auth_can_disconnect']
83 ) {
84 ask_php_auth(_T('login_deconnexion_ok'),
85 _T('login_verifiez_navigateur'),
86 _T('login_retour_public'),
87 "redirect=" . _DIR_RESTREINT_ABS,
88 _T('login_test_navigateur'),
89 true);
90
91 }
92 }
93
94 // Rediriger en contrant le cache navigateur (Safari3)
95 include_spip('inc/headers');
96 redirige_par_entete($url
97 ? parametre_url($url, 'var_hasard', uniqid(rand()), '&')
98 : generer_url_public('login'));
99 }
100
101 /**
102 * Generer un jeton de logout personnel et ephemere
103 *
104 * @param array $session
105 * @param null|string $alea
106 * @return string
107 */
108 function generer_jeton_logout($session, $alea = null) {
109 if (is_null($alea)) {
110 include_spip('inc/acces');
111 $alea = charger_aleas();
112 }
113
114 $jeton = md5($session['date_session']
115 . $session['id_auteur']
116 . $session['statut']
117 . $alea
118 );
119
120 return $jeton;
121 }
122
123 /**
124 * Verifier que le jeton de logout est bon
125 *
126 * Il faut verifier avec alea_ephemere_ancien si pas bon avec alea_ephemere
127 * pour gerer le cas de la rotation d'alea
128 *
129 * @param string $jeton
130 * @param array $session
131 * @return bool
132 */
133 function verifier_jeton_logout($jeton, $session) {
134 if (generer_jeton_logout($session) === $jeton) {
135 return true;
136 }
137
138 if (generer_jeton_logout($session, $GLOBALS['meta']['alea_ephemere_ancien']) === $jeton) {
139 return true;
140 }
141
142 return false;
143 }