ne pas melanger les sessions des differents visiteurs $id_auteur = intval($auteur['id_auteur']); if (!isset($_COOKIE['spip_session']) OR !preg_match(',^'.$id_auteur.'_,', $_COOKIE['spip_session'])) $_COOKIE['spip_session'] = $id_auteur.'_'.md5(uniqid(rand(),true)); $fichier_session = fichier_session('alea_ephemere'); // Si ce n'est pas un inscrit (les inscrits ont toujours des choses en session) // on verifie qu'il y a vraiment des choses if (!$id_auteur){ // On supprime les basiques pour voir le contenu effectif $auteur_verif = $auteur; if (isset($auteur_verif['id_auteur'])) unset($auteur_verif['id_auteur']); if (isset($auteur_verif['hash_env'])) unset($auteur_verif['hash_env']); if (isset($auteur_verif['ip_change'])) unset($auteur_verif['ip_change']); // Les variables vraiment nulle ne sont pas à prendre en compte non plus foreach($auteur_verif as $variable=>$valeur){ if ($valeur === null){ unset($auteur_verif[$variable]); } } // Si c'est vide alors on supprime et on ne fait rien if (!$auteur_verif){ if (@file_exists($fichier_session)) spip_unlink($fichier_session); return false; } } // Maintenant on sait qu'il faut memoriser. // On s'assure d'avoir au moins ces valeurs $auteur['id_auteur'] = $id_auteur; if (!isset($auteur['hash_env'])) $auteur['hash_env'] = hash_env(); if (!isset($auteur['ip_change'])) $auteur['ip_change'] = false; if (!ecrire_fichier_session($fichier_session, $auteur)) { include_spip('inc/minipres'); echo minipres(); exit; } else { include_spip('inc/cookie'); $duree = _RENOUVELLE_ALEA * (!isset($auteur['cookie']) ? 2 : (is_numeric($auteur['cookie']) ? $auteur['cookie'] : 20)); spip_setcookie( 'spip_session', $_COOKIE['spip_session'], time() + $duree ); spip_log("ajoute session $fichier_session cookie $duree"); return $_COOKIE['spip_session']; } } // Ajouter une donnee dans la session SPIP // http://doc.spip.org/@session_set function session_set($nom, $val=null) { // On ajoute la valeur dans la globale $GLOBALS['visiteur_session'][$nom] = $val; ajouter_session($GLOBALS['visiteur_session']); actualiser_sessions($GLOBALS['visiteur_session']); } // Lire une valeur dans la session SPIP // http://doc.spip.org/@session_get function session_get($nom) { return $GLOBALS['visiteur_session'][$nom]; } // 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) // http://doc.spip.org/@actualiser_sessions function actualiser_sessions($auteur) { if (!$id_auteur=intval($auteur['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 foreach(preg_files(_DIR_SESSIONS, '/'.$id_auteur.'_.*\.php') as $session) { $GLOBALS['visiteur_session'] = array(); include $session; # $GLOBALS['visiteur_session'] est alors l'auteur cible $auteur = array_merge($GLOBALS['visiteur_session'], $auteur); ecrire_fichier_session($session, $auteur); } // restaurer l'auteur courant $GLOBALS['visiteur_session'] = $sauve; // si c'est le meme, rafraichir les valeurs if ($auteur['id_auteur'] == $sauve['id_auteur']) verifier_session(); } // http://doc.spip.org/@ecrire_fichier_session function ecrire_fichier_session($fichier, $auteur) { // ne pas enregistrer ces elements de securite // dans le fichier de session unset($auteur['pass']); unset($auteur['htpass']); unset($auteur['low_sec']); unset($auteur['alea_actuel']); unset($auteur['alea_futur']); // ne pas enregistrer les valeurs vraiment nulle dans le fichier foreach($auteur as $variable=>$valeur){ if ($valeur === null){ unset($auteur[$variable]); } } // enregistrer les autres donnees du visiteur $texte = "<"."?php\n"; foreach ($auteur as $var => $val) $texte .= '$GLOBALS[\'visiteur_session\'][\''.$var.'\'] = ' . var_export($val,true).";\n"; $texte .= "?".">\n"; return ecrire_fichier($fichier, $texte); } // // Cette fonction efface toutes les sessions appartenant a un auteur. // On en profite pour effacer toutes les sessions // creees depuis plus de 4*_RENOUVELLE_ALEA. // Tenir compte de l'ancien format ou les noms commencaient par "session_" // et du meme coup des repertoires plats, et de l'ID 0 qui vaut les anonymes. // http://doc.spip.org/@supprimer_sessions function supprimer_sessions($id_auteur) { $i = 0; $t = (time() - (_RENOUVELLE_ALEA << 2)); $dir = opendir(_DIR_SESSIONS); while(($e = readdir($dir)) !== false) { if (!preg_match(",^\D*(\d+)_\w{32}\.php[3]?$,", $e, $r)) continue; $f = _DIR_SESSIONS . $e; if (($id_auteur AND ($r[1] == $id_auteur)) OR ($t > filemtime($f))) { spip_unlink($f); $i++; } } // pour un anonyme, se fonder sur le cookie pour trouver le fichier if (!$id_auteur) { verifier_session(); spip_unlink(fichier_session('alea_ephemere', true)); } spip_log("destruction des $i fichiers de session de $id_auteur et 0"); // forcer le recalcul de la session courante spip_session(true); } // // 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 // // http://doc.spip.org/@verifier_session 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; } // Code a inserer par inc/presentation pour rejouer la session // Voir action/cookie qui sera appele. // http://doc.spip.org/@rejouer_session function rejouer_session() { include_spip('inc/filtres'); return http_img_pack('rien.gif', " ", "id='img_session' width='0' height='0'") . http_script("\ndocument.img_session.src='" . generer_url_action('cookie','change_session=oui', true) . "'"); } // // Calcule le nom du fichier session // // http://doc.spip.org/@fichier_session function fichier_session($alea, $tantpis=false) { if (!isset($GLOBALS['meta'][$alea])) { include_spip('base/abstract_sql'); $GLOBALS['meta'][$alea] = sql_getfetsel('valeur', 'spip_meta', "nom=" . sql_quote($alea), '','', '', '', '', 'continue'); } if (!$GLOBALS['meta'][$alea] AND !$tantpis) { include_spip('inc/minipres'); echo minipres(); } else { $repertoire = _DIR_SESSIONS; if(!@file_exists($repertoire)) { if ($tantpis) return ''; $repertoire = preg_replace(','._DIR_TMP.',', '', $repertoire); include_spip('inc/flock'); $repertoire = sous_repertoire(_DIR_TMP, $repertoire); } $c = $_COOKIE['spip_session']; return $repertoire . intval($c) .'_' . md5($c.' '.$GLOBALS['meta'][$alea]). '.php'; } } // // On verifie l'IP et le nom du navigateur // // http://doc.spip.org/@hash_env function hash_env() { static $res =''; if ($res) return $res; return $res = md5($GLOBALS['ip'] . $_SERVER['HTTP_USER_AGENT']); } ?>