X-Git-Url: http://git.cyclocoop.org/?p=ptitvelo%2Fweb%2Fwww.git;a=blobdiff_plain;f=www%2Fecrire%2Faction%2Flogout.php;h=a76d287a772267a9fd0d401b1d41a66c56d41dc1;hp=6a9e9685f92abec2b3e0b9dfb59c42610f0ff086;hb=f489d45ae677afde12ba9c9f70f463ea34787b45;hpb=0dda6af18a04031b1ca8e217187966077e752fe3 diff --git a/www/ecrire/action/logout.php b/www/ecrire/action/logout.php index 6a9e968..a76d287 100644 --- a/www/ecrire/action/logout.php +++ b/www/ecrire/action/logout.php @@ -14,10 +14,17 @@ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('inc/cookie'); -// http://doc.spip.org/@action_logout_dist + +/** + * Se deloger + * Pour eviter les CSRF on passe par une etape de confirmation si pas de jeton fourni + * avec un autosubmit js pour ne pas compliquer l'experience utilisateur + * + * http://doc.spip.org/@action_logout_dist + * + */ function action_logout_dist() { - global $visiteur_session, $ignore_auth_http; $logout =_request('logout'); $url = securiser_redirect_action(_request('url')); // cas particulier, logout dans l'espace public @@ -25,18 +32,41 @@ function action_logout_dist() $url = url_de_base(); // seul le loge peut se deloger (mais id_auteur peut valoir 0 apres une restauration avortee) - if (is_numeric($visiteur_session['id_auteur'])) { + if (isset($GLOBALS['visiteur_session']['id_auteur']) + AND is_numeric($GLOBALS['visiteur_session']['id_auteur']) + // des sessions anonymes avec id_auteur=0 existent, mais elle n'ont pas de statut : double check + AND isset($GLOBALS['visiteur_session']['statut'])) { + + // il faut un jeton pour fermer la session (eviter les CSRF) + if (!$jeton = _request('jeton') + OR !verifier_jeton_logout($jeton,$GLOBALS['visiteur_session'])){ + $jeton = generer_jeton_logout($GLOBALS['visiteur_session']); + $action = generer_url_action("logout","jeton=$jeton"); + $action = parametre_url($action,'logout',_request('logout')); + $action = parametre_url($action,'url',_request('url')); + include_spip("inc/minipres"); + include_spip("inc/filtres"); + $texte = bouton_action(_T('spip:icone_deconnecter'),$action); + $texte = "
$texte
"; + $texte .= ''; + $res = minipres(_T('spip:icone_deconnecter'),$texte,'',true); + echo $res; + return; + } + include_spip('inc/auth'); - auth_trace($visiteur_session, '0000-00-00 00:00:00'); + auth_trace($GLOBALS['visiteur_session'], '0000-00-00 00:00:00'); // le logout explicite vaut destruction de toutes les sessions if (isset($_COOKIE['spip_session'])) { $session = charger_fonction('session', 'inc'); - $session($visiteur_session['id_auteur']); + $session($GLOBALS['visiteur_session']['id_auteur']); spip_setcookie('spip_session', $_COOKIE['spip_session'], time()-3600); } // si authentification http, et que la personne est loge, // pour se deconnecter, il faut proposer un nouveau formulaire de connexion http - if (isset($_SERVER['PHP_AUTH_USER']) AND !$ignore_auth_http AND $GLOBALS['auth_can_disconnect']) { + if (isset($_SERVER['PHP_AUTH_USER']) + AND !$GLOBALS['ignore_auth_http'] + AND $GLOBALS['auth_can_disconnect']) { ask_php_auth(_T('login_deconnexion_ok'), _T('login_verifiez_navigateur'), _T('login_retour_public'), @@ -54,4 +84,47 @@ function action_logout_dist() : generer_url_public('login')); } -?> +/** + * Generer un jeton de logout personnel et ephemere + * @param array $session + * @param null|string $alea + * @return string + */ +function generer_jeton_logout($session,$alea=null){ + if (is_null($alea)){ + if (!isset($GLOBALS['meta']['alea_ephemere'])){ + include_spip('base/abstract_sql'); + $GLOBALS['meta']['alea_ephemere'] = sql_getfetsel('valeur', 'spip_meta', "nom='alea_ephemere'"); + } + $alea = $GLOBALS['meta']['alea_ephemere']; + } + + $jeton = md5($session['date_session'] + .$session['id_auteur'] + .$session['statut'] + .$alea + ); + return $jeton; +} + +/** + * Verifier que le jeton de logout est bon + * il faut verifier avec alea_ephemere_ancien si pas bon avec alea_ephemere + * pour gerer le cas de la rotation d'alea + * @param string $jeton + * @param array $session + * @return bool + */ +function verifier_jeton_logout($jeton,$session){ + if (generer_jeton_logout($session)===$jeton) + return true; + if (!isset($GLOBALS['meta']['alea_ephemere_ancien'])){ + include_spip('base/abstract_sql'); + $GLOBALS['meta']['alea_ephemere_ancien'] = sql_getfetsel('valeur', 'spip_meta', "nom='alea_ephemere_ancien'"); + } + if (generer_jeton_logout($session,$GLOBALS['meta']['alea_ephemere_ancien'])===$jeton) + return true; + return false; +} + +?> \ No newline at end of file