function verifier_session($change=false) { // si pas de cookie, c'est fichu if (!isset($_COOKIE['spip_session'])) return false; // Tester avec alea courant $fichier_session = fichier_session('alea_ephemere', true); if ($fichier_session AND @file_exists($fichier_session)) { include($fichier_session); } else { // Sinon, tester avec alea precedent $fichier_session = fichier_session('alea_ephemere_ancien', true); if (!$fichier_session OR !@file_exists($fichier_session)) return false; // Renouveler la session avec l'alea courant include($fichier_session); spip_unlink($fichier_session); ajouter_session($GLOBALS['visiteur_session']); } // Compatibilite ascendante : auteur_session est visiteur_session si // c'est un auteur SPIP authentifie (tandis qu'un visiteur_session peut // n'etre qu'identifie, sans aucune authentification). if ($GLOBALS['visiteur_session']['id_auteur']) $GLOBALS['auteur_session'] = &$GLOBALS['visiteur_session']; // Si l'adresse IP change, inc/presentation mettra une balise image // avec un URL de rappel demandant a changer le nom de la session. // Seul celui qui a l'IP d'origine est rejoue // ainsi un eventuel voleur de cookie ne pourrait pas deconnecter // sa victime, mais se ferait deconnecter par elle. if (hash_env() != $GLOBALS['visiteur_session']['hash_env']) { if (!$GLOBALS['visiteur_session']['ip_change']) { $GLOBALS['rejoue_session'] = rejouer_session(); $GLOBALS['visiteur_session']['ip_change'] = true; ajouter_session($GLOBALS['visiteur_session']); } else if ($change) { spip_log("session non rejouee, vol de cookie ?"); } } else if ($change) { spip_log("rejoue session $fichier_session ".$_COOKIE['spip_session']); spip_unlink($fichier_session); $GLOBALS['visiteur_session']['ip_change'] = false; unset($_COOKIE['spip_session']); ajouter_session($GLOBALS['visiteur_session']); } return is_numeric($GLOBALS['visiteur_session']['id_auteur'])?$GLOBALS['visiteur_session']['id_auteur']:null; }
/** * Mettre a jour les sessions existantes pour un auteur * Quand on modifie une fiche auteur on appelle cette fonction qui va * mettre a jour les fichiers de session de l'auteur en question. * (auteurs identifies seulement) * * Ne concerne que les sessions des auteurs loges (id_auteur connu) * * @param array $auteur * @param array $supprimer_cles * Liste des clés à supprimer des tableaux de sessions */ function actualiser_sessions($auteur, $supprimer_cles = array()) { $id_auteur = isset($auteur['id_auteur']) ? intval($auteur['id_auteur']) : 0; $id_auteur_courant = isset($GLOBALS['visiteur_session']['id_auteur']) ? intval($GLOBALS['visiteur_session']['id_auteur']) : 0; // si l'auteur est celui de la session courante, verifier/creer la session si besoin $fichier_session_courante = ""; if ($id_auteur == $id_auteur_courant) { ajouter_session($auteur); if ($id_auteur) { $fichier_session_courante = fichier_session('alea_ephemere'); } } // si session anonyme on ne fait rien d'autre ici : les sessions anonymes sont non partagees if (!$id_auteur) { return; } // memoriser l'auteur courant (celui qui modifie la fiche) $sauve = $GLOBALS['visiteur_session']; // .. mettre a jour les sessions de l'auteur cible // attention au $ final pour ne pas risquer d'embarquer un .php.jeton temporaire // cree par une ecriture concurente d'une session (fichier atomique temporaire) $sessions = preg_files(_DIR_SESSIONS, '/' . $id_auteur . '_.*\\.php$'); // 1ere passe : lire et fusionner les sessions foreach ($sessions as $session) { $GLOBALS['visiteur_session'] = array(); // a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence) if ($session !== $fichier_session_courante and @file_exists($session)) { include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible $auteur = array_merge($GLOBALS['visiteur_session'], $auteur); } } // supprimer les eventuelles cles dont on ne veut plus foreach ($supprimer_cles as $cle) { unset($auteur[$cle]); } $auteur_session = preparer_ecriture_session($auteur); // seconde passe : ecrire les sessions qui ne sont pas a jour foreach ($sessions as $session) { $GLOBALS['visiteur_session'] = array(); // a pu etre supprime entre le preg initial et le moment ou l'on arrive la (concurrence) if (@file_exists($session)) { include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible // est-ce que cette session est a mettre a jour ? if ($auteur_session != $GLOBALS['visiteur_session']) { ecrire_fichier_session($session, $auteur); } } } if ($id_auteur == $id_auteur_courant) { $GLOBALS['visiteur_session'] = $auteur; $GLOBALS['auteur_session'] =& $GLOBALS['visiteur_session']; } else { // restaurer l'auteur courant $GLOBALS['visiteur_session'] = $sauve; } }
/** * Verifie si le cookie spip_session indique une session valide. * Si oui, la decrit dans le tableau $visiteur_session et retourne id_auteur * La rejoue si IP change puis accepte le changement si $change=true * * Retourne false en cas d'echec, l'id_auteur de la session si defini, null sinon * * http://doc.spip.org/@verifier_session * * @param bool $change * @return bool|int|null */ function verifier_session($change = false) { // si pas de cookie, c'est fichu if (!isset($_COOKIE['spip_session'])) { return false; } // Tester avec alea courant $fichier_session = fichier_session('alea_ephemere', true); if ($fichier_session and @file_exists($fichier_session)) { include $fichier_session; } else { // Sinon, tester avec alea precedent $fichier_session = fichier_session('alea_ephemere_ancien', true); if (!$fichier_session or !@file_exists($fichier_session)) { return false; } // Renouveler la session avec l'alea courant include $fichier_session; spip_log('renouvelle session ' . $GLOBALS['visiteur_session']['id_auteur']); spip_unlink($fichier_session); ajouter_session($GLOBALS['visiteur_session']); } // Compatibilite ascendante : auteur_session est visiteur_session si // c'est un auteur SPIP authentifie (tandis qu'un visiteur_session peut // n'etre qu'identifie, sans aucune authentification). if ($GLOBALS['visiteur_session']['id_auteur']) { $GLOBALS['auteur_session'] =& $GLOBALS['visiteur_session']; } // Si l'adresse IP change, inc/presentation mettra une balise image // avec un URL de rappel demandant a changer le nom de la session. // Seul celui qui a l'IP d'origine est rejoue // ainsi un eventuel voleur de cookie ne pourrait pas deconnecter // sa victime, mais se ferait deconnecter par elle. if (hash_env() != $GLOBALS['visiteur_session']['hash_env']) { if (!$GLOBALS['visiteur_session']['ip_change']) { define('_SESSION_REJOUER', rejouer_session()); $GLOBALS['visiteur_session']['ip_change'] = true; ajouter_session($GLOBALS['visiteur_session']); } else { if ($change) { spip_log("session non rejouee, vol de cookie ?"); } } } else { if ($change) { spip_log("rejoue session {$fichier_session} " . $_COOKIE['spip_session']); spip_unlink($fichier_session); $GLOBALS['visiteur_session']['ip_change'] = false; unset($_COOKIE['spip_session']); ajouter_session($GLOBALS['visiteur_session']); } } // Si la session a ete initiee il y a trop longtemps, elle est annulee if (isset($GLOBALS['visiteur_session']) and defined('_AGE_SESSION_MAX') and _AGE_SESSION_MAX > 0 and time() - @$GLOBALS['visiteur_session']['date_session'] > _AGE_SESSION_MAX) { unset($GLOBALS['visiteur_session']); return false; } return is_numeric($GLOBALS['visiteur_session']['id_auteur']) ? $GLOBALS['visiteur_session']['id_auteur'] : null; }