X-Git-Url: http://git.cyclocoop.org/?p=velocampus%2Fweb%2Fwww.git;a=blobdiff_plain;f=www%2Fecrire%2Finc%2Fsession.php;fp=www%2Fecrire%2Finc%2Fsession.php;h=568cce9c1882362f58bfdf991976156240dcc9a3;hp=0000000000000000000000000000000000000000;hb=80b4d3e85f78d402ed2e73f8f5d1bf4c19962eed;hpb=aaf970bf4cdaf76689ecc10609048e18d073820c diff --git a/www/ecrire/inc/session.php b/www/ecrire/inc/session.php new file mode 100644 index 0000000..568cce9 --- /dev/null +++ b/www/ecrire/inc/session.php @@ -0,0 +1,325 @@ + 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']); +} + +?>