diff --git a/ecrire/action/cookie.php b/ecrire/action/cookie.php index a3b9b4b26bbbb2a7e7667dc2ffec490591e24796..0722c50ae2bce2bdd7760fb3c3abd3eb99aebde7 100644 --- a/ecrire/action/cookie.php +++ b/ecrire/action/cookie.php @@ -67,24 +67,12 @@ function action_spip_cookie_dist() $var_lang_ecrire; // rejoue le cookie pour renouveler spip_session -if ($change_session == 'oui') { - if (verifier_session($spip_session)) { - // Attention : seul celui qui a le bon IP a le droit de rejouer, - // ainsi un eventuel voleur de cookie ne pourrait pas deconnecter - // sa victime, mais se ferait deconnecter par elle. - if ($auteur_session['hash_env'] == hash_env()) { - spip_log("rejoue session"); - $auteur_session['ip_change'] = false; - $cookie = creer_cookie_session($auteur_session); - supprimer_session($spip_session); - spip_setcookie('spip_session', $cookie); - } - else - spip_log("session non rejouee, changement d'IP ?"); - } + if ($change_session == 'oui') { + $var_f = charger_fonction('session', 'inc'); + $var_f(true); envoie_image_vide(); exit; -} + } // tentative de connexion en auth_http if ($essai_auth_http AND !$ignore_auth_http) { @@ -102,7 +90,8 @@ if ($logout) { if ($auteur_session['login'] == $logout) { spip_query("UPDATE spip_auteurs SET en_ligne = DATE_SUB(NOW(),INTERVAL 6 MINUTE) WHERE id_auteur = ".$auteur_session['id_auteur']); if ($spip_session) { - zap_sessions($auteur_session['id_auteur'], true); + $var_f = charger_fonction('session', 'inc'); + $var_f($auteur_session['id_auteur']); spip_setcookie('spip_session', $spip_session, time() - 3600 * 24); } @@ -160,14 +149,16 @@ if ($essai_login == "oui") { } else { spip_log("login de $session_login vers $redirect"); // Si on se connecte dans l'espace prive, - // ajouter "bonjour" (inutilise) + // ajouter "bonjour" (repere a peu pres les cookies desactives) if (ereg(_DIR_RESTREINT_ABS, $redirect)) { $redirect .= ((false !== strpos($redirect, "?")) ? "&" : "?") . 'bonjour=oui'; } if ($row_auteur['statut'] == '0minirezo') $cookie_admin = "@".$session_login; - $cookie_session = creer_cookie_session($row_auteur); + + $var_f = charger_fonction('session', 'inc'); + $cookie_session = $var_f($row_auteur); } } @@ -196,7 +187,8 @@ if ($cookie_session) { $prefs = ($row_auteur['prefs']) ? unserialize($row_auteur['prefs']) : array(); $prefs['cnx'] = ($session_remember == 'oui') ? 'perma' : ''; - update_prefs_session($prefs, $row_auteur['id_auteur']); + + spip_query("UPDATE spip_auteurs SET prefs = " . spip_abstract_quote(serialize($prefs)) . " WHERE id_auteur = " . $row_auteur['id_auteur']); } // changement de langue espace public @@ -217,11 +209,12 @@ if ($var_lang_ecrire) { spip_setcookie('spip_lang_ecrire', $var_lang_ecrire, time() + 365 * 24 * 3600); spip_setcookie('spip_lang', $var_lang_ecrire, time() + 365 * 24 * 3600); - // ce ajouter_session me semble deja fait si on arrive jusqu'ici - // avec id_auteur defini if (_FILE_CONNECT AND $id_auteur) { if (verifier_action_auteur("cookie-var_lang_ecrire", $hash, $id_auteur)) { - ajouter_session($auteur_session, $spip_session, $var_lang_ecrire); + spip_query("UPDATE spip_auteurs SET lang = " . spip_abstract_quote($var_lang_ecrire) . " WHERE id_auteur = " . intval($id_auteur)); + $auteur_session['lang'] = $var_lang_ecrire; + $var_f = charger_fonction('session', 'inc'); + $var_f($auteur_session); } } diff --git a/ecrire/exec/auteur_infos.php b/ecrire/exec/auteur_infos.php index 6dae335591a891e0ae0b535f051d300d72a54bb9..333f5769967e71b1b9c61dbdedb74963dba4b878 100644 --- a/ecrire/exec/auteur_infos.php +++ b/ecrire/exec/auteur_infos.php @@ -105,10 +105,8 @@ if (strval($nom)!='') { } if ($modif_login) { - include_spip('inc/session'); - zap_sessions ($auteur['id_auteur'], true); - if ($connect_id_auteur == $auteur['id_auteur']) - supprimer_session($GLOBALS['spip_session']); + $var_f = charger_fonction('session', 'inc'); + $var_f($auteur['id_auteur']); } // email diff --git a/ecrire/inc/auth.php b/ecrire/inc/auth.php index 44fe114ac9560e4e92de7ecffbab893c1d5dd72b..c08ce135bb0b805f6018ccde9453da512e86096a 100644 --- a/ecrire/inc/auth.php +++ b/ecrire/inc/auth.php @@ -91,7 +91,8 @@ function inc_auth_dist() { // Authentification session if ($cookie_session = $_COOKIE['spip_session']) { - if (verifier_session($cookie_session)) { + $var_f = charger_fonction('session', 'inc'); + if ($var_f()) { if ($auteur_session['statut'] == '0minirezo' OR $auteur_session['statut'] == '1comite') { $connect_login = $auteur_session['login']; diff --git a/ecrire/inc/presentation.php b/ecrire/inc/presentation.php index 207207103cecd8c3b6a346c8c0dc630ded92cdad..3b592fdc43fec516c1923e667ee8164c4da656ff 100644 --- a/ecrire/inc/presentation.php +++ b/ecrire/inc/presentation.php @@ -2857,17 +2857,7 @@ function debut_droite($rubrique="") { function fin_html() { - echo "</font>"; - - // rejouer le cookie de session si l'IP a change - if ($GLOBALS['spip_session'] && $GLOBALS['auteur_session']['ip_change']) { - echo - http_img_pack('rien.gif', " ", "name='img_session' width='0' height='0'"), - http_script("\ndocument.img_session.src='" . generer_url_public('spip_cookie','change_session=oui') . "'"); - } - - echo "</body></html>\n"; - + echo "</font>", $GLOBALS['rejoue_session'], "</body></html>\n"; } diff --git a/ecrire/inc/session.php b/ecrire/inc/session.php index ac3b59488ad3aac9cf345f2c5525e0bd58b9a8e5..cf53288bf199ebd5b625291d36ac404a5a1e194a 100644 --- a/ecrire/inc/session.php +++ b/ecrire/inc/session.php @@ -22,38 +22,38 @@ include_spip('inc/meta'); */ $GLOBALS['auteur_session'] = ''; +$GLOBALS['rejoue_session'] = ''; // -// On verifie l'IP et le nom du navigateur +// 3 actions sur les sessions, selon le type de l'argument: // -function hash_env() { - return md5($GLOBALS['ip'] . $_SERVER['HTTP_USER_AGENT']); -} - - -// -// Calcule le nom du fichier session -// -function fichier_session($id_session, $alea) { - if (ereg("^([0-9]+_)", $id_session, $regs)) - $id_auteur = $regs[1]; - return _DIR_SESSIONS . 'session_'.$id_auteur.md5($id_session.' '.$alea). '.php'; +// - numérique: efface toutes les sessions de l'id_auteur (retour quelconque) +// - tableau: cree une session pour l'auteur decrit et retourne l'identifiant +// - autre: predicat de validite de la session indiquee par le cookie +function inc_session_dist($auteur=false) +{ + if (is_numeric($auteur)) + return supprimer_sessions($auteur); + else if (is_array($auteur)) + return ajouter_session($auteur); + else return verifier_session($auteur); } // -// Ajouter une session pour l'auteur specifie +// Ajoute une session pour l'auteur decrit par un tableau issu d'un SELECT-SQL // -function ajouter_session($auteur, $id_session, $lang='') { - global $auteur_session; - if ($lang) { - spip_query("UPDATE spip_auteurs SET lang = " . spip_abstract_quote($lang) . " WHERE id_auteur = " . intval($auteur['id_auteur'])); - $auteur_session['lang'] = $lang; - } +function ajouter_session($auteur) { + global $spip_session; renouvelle_alea(); - $fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere']); + if (!$spip_session) + $spip_session = $auteur['id_auteur'].'_'.md5(creer_uniqid()); + + $fichier_session = fichier_session($spip_session, $GLOBALS['meta']['alea_ephemere']); + + if (!isset($auteur['hash_env'])) $auteur['hash_env'] = hash_env(); $texte = "<"."?php\n"; foreach (array('id_auteur', 'nom', 'login', 'email', 'statut', 'lang', 'ip_change', 'hash_env') AS $var) { @@ -64,73 +64,106 @@ function ajouter_session($auteur, $id_session, $lang='') { if (!ecrire_fichier($fichier_session, $texte)) redirige_par_entete(generer_url_action('test_dirs','',true)); + else return $spip_session; } -function update_prefs_session($prefs, $id_auteur) -{ - $prefs = serialize($prefs); - spip_query("UPDATE spip_auteurs SET prefs = " . spip_abstract_quote($prefs) . " WHERE id_auteur = $id_auteur"); +// +// Cette fonction efface toutes les sessions appartenant a l'auteur +// On en profite pour effacer toutes les sessions creees il y a plus de 48 h +// + +function supprimer_sessions($id_auteur) { + + $dir = opendir(_DIR_SESSIONS); + $t = time() - (48 * 3600); + while(($f = readdir($dir)) !== false) { + + if (ereg("^session_([0-9]+)_[a-z0-9]+\.php[3]?$", $f, $regs)){ + $f = _DIR_SESSIONS . $f; + if (($regs[1] == $id_auteur) OR ($t > filemtime($f))) + @unlink($f); + } + } } // -// Verifier et inclure une session +// Verifie et inclut une session. +// La rejoue si IP change puis accepte le changement si $change=true // -function verifier_session($id_session) { + +function verifier_session($change=false) { + + global $spip_session; // issu du cookie // Tester avec alea courant - $ok = false; - if ($id_session) { - $fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere']); - if (@file_exists($fichier_session)) { - include($fichier_session); - $ok = true; - } - else { - // Sinon, tester avec alea precedent - $fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere_ancien']); - if (@file_exists($fichier_session)) { - // Renouveler la session (avec l'alea courant) - include($fichier_session); - supprimer_session($id_session); - ajouter_session($GLOBALS['auteur_session'], $id_session); - $ok = true; - } - } + if (!$spip_session) return false; + + $fichier_session = fichier_session($spip_session, $GLOBALS['meta']['alea_ephemere']); + if (@file_exists($fichier_session)) { + include($fichier_session); + } else { + // Sinon, tester avec alea precedent + $fichier_session = fichier_session($spip_session, $GLOBALS['meta']['alea_ephemere_ancien']); + if (!@file_exists($fichier_session)) return false; + + // Renouveler la session avec l'alea courant + include($fichier_session); + @unlink($fichier_session); + ajouter_session($GLOBALS['auteur_session']); } - // marquer la session comme "ip-change" si le cas se presente - if ($ok AND (hash_env() != $GLOBALS['auteur_session']['hash_env']) AND !$GLOBALS['auteur_session']['ip_change']) { + // 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['auteur_session']['hash_env']) { + if (!$GLOBALS['auteur_session']['ip_change']) { + $GLOBALS['rejoue_session'] = rejouer_session(); $GLOBALS['auteur_session']['ip_change'] = true; - ajouter_session($GLOBALS['auteur_session'], $id_session); + ajouter_session($GLOBALS['auteur_session']); + } else if ($change) + spip_log("session non rejouee, vol de cookie ?"); + } else { if ($change) { + spip_log("rejoue session $fichier_session $spip_session"); + @unlink($fichier_session); + $auteur_session['ip_change'] = false; + unset($spip_session); + $cookie= ajouter_session($auteur_session); + spip_setcookie('spip_session', $cookie); + } } + return true; +} + +// Code a inserer par inc/presentation pour rejouer la session +// Voir action/cookie qui sera appele. - return $ok; +function rejouer_session() +{ + include_spip('inc/minipres'); + 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) . "'"); } // -// Supprimer une session +// Calcule le nom du fichier session // -function supprimer_session($id_session) { - $fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere']); - if (@file_exists($fichier_session)) { - @unlink($fichier_session); - } - $fichier_session = fichier_session($id_session, $GLOBALS['meta']['alea_ephemere_ancien']); - if (@file_exists($fichier_session)) { - @unlink($fichier_session); - } +function fichier_session($id_session, $alea) { + if (ereg("^([0-9]+_)", $id_session, $regs)) + $id_auteur = $regs[1]; + return _DIR_SESSIONS . 'session_'.$id_auteur.md5($id_session.' '.$alea). '.php'; } // -// Creer une session et retourne le cookie correspondant (a poser) +// On verifie l'IP et le nom du navigateur // -function creer_cookie_session($auteur) { - if ($id_auteur = $auteur['id_auteur']) { - $id_session = $id_auteur.'_'.md5(creer_uniqid()); - $auteur['hash_env'] = hash_env(); - ajouter_session($auteur, $id_session); - return $id_session; - } + +function hash_env() { + static $res =''; + if ($res) return $res; + return $res = md5($GLOBALS['ip'] . $_SERVER['HTTP_USER_AGENT']); } // @@ -152,38 +185,6 @@ function creer_uniqid() { } -// -// Cette fonction efface toutes les sessions appartenant a l'auteur -// On en profite pour effacer toutes les sessions creees il y a plus de 48 h -// -function zap_sessions ($id_auteur, $zap) { - - // ne pas se zapper soi-meme - if ($s = $GLOBALS['spip_session']) - $fichier_session = fichier_session($s, $GLOBALS['meta']['alea_ephemere']); - - $dir = opendir(_DIR_SESSIONS); - $t = time(); - while(($item = readdir($dir)) !== false) { - $chemin = _DIR_SESSIONS . $item; - if (ereg("^session_([0-9]+_)?([a-z0-9]+)\.php[3]?$", $item, $regs)) { - - // Si c'est une vieille session, on jette - if (($t - filemtime($chemin)) > 48 * 3600) - @unlink($chemin); - - // sinon voir si c'est une session du meme auteur - else if ($regs[1] == $id_auteur.'_') { - $zap_num ++; - if ($zap) - @unlink($chemin); - } - - } - } - - return $zap_num; -} // // reconnaitre un utilisateur authentifie en php_auth @@ -222,14 +223,6 @@ function ask_php_auth($pb, $raison, $retour, $url='', $re='', $lien='') { exit; } -// -// verifie si on a un cookie de session ou un auth_php correct -// et charge ses valeurs dans $GLOBALS['auteur_session'] -// -function verifier_session_visiteur() { - return verifier_session($_COOKIE['spip_session']) ? true : verifier_php_auth(); -} - // // Renouvellement de l'alea utilise pour valider certaines operations // (session, ajouter une image, etc.) diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php index d18c223aee840f2fc4a98b7759971ef9797c1754..017b052c1f2592fd15a8a4d35478efd196d7799f 100644 --- a/ecrire/inc/utils.php +++ b/ecrire/inc/utils.php @@ -1040,8 +1040,8 @@ function verifier_visiteur() { if (isset($_COOKIE['spip_session']) OR (isset($_SERVER['PHP_AUTH_USER']) AND !$GLOBALS['ignore_auth_http'])) { - include_spip('inc/session'); - verifier_session_visiteur(); + $var_f = charger_fonction('session', 'inc'); + if (!$var_f()) verifier_php_auth(); } } diff --git a/ecrire/index.php b/ecrire/index.php index f8ef2c80e69605ed94186517c2972d59eb683402..cf618cc6b424a09dbc52e8d53f469a817b21badc 100644 --- a/ecrire/index.php +++ b/ecrire/index.php @@ -106,7 +106,7 @@ if (isset($set_options) AND ($set_options == 'avancees' OR $set_options == 'basi $prefs_mod = true; } if ($prefs_mod AND !$var_auth) - update_prefs_session($prefs, $connect_id_auteur); + spip_query("UPDATE spip_auteurs SET prefs = " . spip_abstract_quote(serialize($prefs)) . " WHERE id_auteur = $connect_id_auteur"); if (isset($set_ecran)) { // Poser un cookie, car ce reglage depend plus du navigateur que de l'utilisateur @@ -149,7 +149,10 @@ if (isset($GLOBALS['_COOKIE']['spip_lang_ecrire'])) { // si authentifie, changer definitivement si ce n'est fait else { if (($spip_lang_ecrire <> $auteur_session['lang']) AND changer_langue($spip_lang_ecrire)) { - ajouter_session($auteur_session, $spip_session, $spip_lang_ecrire); + spip_query("UPDATE spip_auteurs SET lang = " . spip_abstract_quote($spip_lang_ecrire) . " WHERE id_auteur = " . intval($auteur_session['id_auteur'])); + $auteur_session['lang'] = $var_lang_ecrire; + $var_f = charger_fonction('session', 'inc'); + $var_f($auteur_session); } } }