From b469db956989d76cdb82d021a942d4a90129a03f Mon Sep 17 00:00:00 2001
From: Cerdic <cedric@yterium.com>
Date: Mon, 28 Feb 2022 15:20:18 +0100
Subject: [PATCH] Robustesse des migrations : on ne genere pas le
 secret_des_auth tant qu'on n'est pas en mesure de faire un backup des cles
 dans la foulee : - il faut avoir le champ backup_cles en base (donc avoir
 fait la migration de base) - il faut etre sur le login d'un webmestre (donc
 sur son login *apres* migration de la base) => faut il invalider la session
 du webmestre qui upgrade pour le forcer a se reconnecter ? Le but est
 d'eviter de generer une cle et de commencer a chiffrer les password des
 utilisateurs alors qu'aucun webmestre n'a encore de backup, ce qui
 reviendrait a perdre les pass de tous ces utilisateurs si on perd le fichier
 cles.php

---
 ecrire/auth/spip.php | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/ecrire/auth/spip.php b/ecrire/auth/spip.php
index fde4f565af..5705a146c0 100644
--- a/ecrire/auth/spip.php
+++ b/ecrire/auth/spip.php
@@ -43,6 +43,7 @@ function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
 
 	$md5pass = '';
 	$shapass = $shanext = '';
+	$auteur_peut_sauver_cles = false;
 
 	if ($pass) {
 		$row = sql_fetsel(
@@ -55,6 +56,11 @@ function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
 			'',
 			$serveur
 		);
+
+		// lever un flag si cet auteur peut sauver les cles
+		if ($row['statut'] === '0minirezo' and $row['webmestre'] === 'oui' and isset($row['backup_cles'])) {
+			$auteur_peut_sauver_cles = true;
+		}
 	}
 
 	// login inexistant ou mot de passe vide
@@ -66,13 +72,6 @@ function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
 	$cles = SpipCles::instance();
 	$secret = $cles->getSecretAuth();
 
-	// Créer la clé si besoin (en verifiant la presence ou non d'un backup chez un webmestre)
-	if (!$secret) {
-		if (auth_spip_initialiser_secret()) {
-			$secret = $cles->getSecretAuth();
-		}
-	}
-
 	switch (strlen($row['pass'])) {
 		case 32:
 			// tres anciens mots de passe encodes en md5(alea.pass)
@@ -96,7 +95,7 @@ function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
 			// doit-on restaurer un backup des cles ?
 			if (
 				!$secret
-				and $row['webmestre'] === 'oui'
+				and $auteur_peut_sauver_cles
 				and !empty($row['backup_cles'])
 			) {
 				if ($cles->restore($row['backup_cles'], $pass, $row['pass'], $row['id_auteur'])) {
@@ -108,12 +107,23 @@ function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
 					sql_updateq('spip_auteurs', ['backup_cles' => ''], 'id_auteur=' . intval($row['id_auteur']));
 				}
 			}
-			if (!Password::verifier($pass, $row['pass'], $secret)) {
+
+			if (!$secret or !Password::verifier($pass, $row['pass'], $secret)) {
 				unset($row);
 			}
 			break;
 	}
 
+	// Migration depuis ancienne version : si on a pas encore de cle
+	// ET si c'est le login d'un auteur qui peut sauver la cle
+	// créer la clé (en s'assurant bien que personne n'a de backup d'un precedent fichier cle.php)
+	// si c'est un auteur normal, on ne fait rien, il garde son ancien pass hashé en sha256 en attendant le login d'un webmestre
+	if (!$secret and $auteur_peut_sauver_cles) {
+		if (auth_spip_initialiser_secret()) {
+			$secret = $cles->getSecretAuth();
+		}
+	}
+
 	// login/mot de passe incorrect
 	if (empty($row)) {
 		return [];
@@ -130,8 +140,8 @@ function auth_spip_dist($login, $pass, $serveur = '', $phpauth = false) {
 				'alea_futur' => sql_quote(creer_uniqid(), $serveur, 'text'), // @deprecated 4.1
 				'pass' => sql_quote($pass_hash_next, $serveur, 'text'),
 			];
-			// a chaque login de webmestre : sauvegarde chiffree des clé du site (avec les pass du webmestre)
-			if ($row['statut'] === '0minirezo' and $row['webmestre'] === 'oui' and isset($row['backup_cles'])) {
+			// a chaque login de webmestre : sauvegarde chiffree des clés du site (avec les pass du webmestre)
+			if ($auteur_peut_sauver_cles) {
 				$set['backup_cles'] = sql_quote($cles->backup($pass), $serveur, 'text');
 			}
 
-- 
GitLab