X-Git-Url: http://git.cyclocoop.org/?p=velocampus%2Fweb%2Fwww.git;a=blobdiff_plain;f=www%2Fecrire%2Faction%2Flogout.php;h=8f68c870d4aec0eec424a6d661106ee951dd5f67;hp=0c5ae3606ded6b9974e61373d2db365055746885;hb=e99f0878011913365e49b30d90e496c24c301393;hpb=80b4d3e85f78d402ed2e73f8f5d1bf4c19962eed diff --git a/www/ecrire/action/logout.php b/www/ecrire/action/logout.php index 0c5ae36..8f68c87 100644 --- a/www/ecrire/action/logout.php +++ b/www/ecrire/action/logout.php @@ -3,7 +3,7 @@ /***************************************************************************\ * SPIP, Systeme de publication pour l'internet * * * - * Copyright (c) 2001-2011 * + * Copyright (c) 2001-2014 * * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribue sous licence GNU/GPL. * @@ -13,45 +13,118 @@ if (!defined('_ECRIRE_INC_VERSION')) return; include_spip('inc/cookie'); +include_spip('public/aiguiller'); -// http://doc.spip.org/@action_logout_dist +/** + * Se deloger + * Pour eviter les CSRF on passe par une etape de confirmation si pas de jeton, + * 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 = _request('url'); - // cas particulier, logout dans l'espace public - if ($logout == 'public' AND !$url) - $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'])) { - include_spip('inc/auth'); - auth_trace($visiteur_session, '0000-00-00 00:00:00'); - // le logout explicite vaut destruction de toutes les sessions - if (isset($_COOKIE['spip_session'])) { + // seul le loge peut se deloger + // (mais id_auteur peut valoir 0 apres une restauration avortee) + if (isset($GLOBALS['visiteur_session']['id_auteur']) + AND is_numeric($GLOBALS['visiteur_session']['id_auteur']) + // des sessions anonymes avec id_auteur=0 existent, + // mais elles n'ont pas de statut : verifier ca aussi + AND isset($GLOBALS['visiteur_session']['statut'])) { + // relancer si pas de jeton + if (!action_logout_secu($logout, $url, _request('jeton'))) { + return; // page submit retournee + } elseif (isset($_COOKIE['spip_session'])) { + // le logout explicite vaut destruction de toutes les sessions + $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']) { - ask_php_auth(_T('login_deconnexion_ok'), - _T('login_verifiez_navigateur'), - _T('login_retour_public'), - "redirect=". _DIR_RESTREINT_ABS, - _T('login_test_navigateur'), - true); - - } + include_spip('inc/auth'); + auth_trace($GLOBALS['visiteur_session'],'0000-00-00 00:00:00'); } - - // Rediriger en contrant le cache navigateur (Safari3) + // Action terminee (ou non faite si pas les droits) on redirige. + // Cas particulier, logout dans l'espace public + $url = securiser_redirect_action($url); + if ($logout == 'public' AND !$url) + $url = url_de_base(); include_spip('inc/headers'); redirige_par_entete($url + // contrer le cache navigateur (Safari3) ? parametre_url($url, 'var_hasard', uniqid(rand()), '&') : generer_url_public('login')); } +/** + * Verifier un jeton si present, ou envoyer une page le produisant + * @param string $logout + * @param string $url + * @param string $jeton + * @return boolean + */ + +function action_logout_secu($logout, $url, $jeton) +{ + if ($jeton AND verifier_jeton_logout($jeton,$GLOBALS['visiteur_session'])) + return true; + $jeton = generer_jeton_logout($GLOBALS['visiteur_session']); + $action = generer_url_action("logout","jeton=$jeton"); + $action = parametre_url($action,'logout',$logout); + $action = parametre_url($action,'url',$url); + include_spip("inc/minipres"); + include_spip("inc/filtres"); + $texte = bouton_action(_T('spip:icone_deconnecter'),$action); + $texte = "
$texte
"; + $texte .= ''; + echo minipres(_T('spip:icone_deconnecter'),$texte,'',true); + return false; +} + +/** + * 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; +} + ?>