Multiples erreurs de cles sur un spip4 upgradé depuis spip1 #5262

Open
opened 2 months ago by gagz · 10 comments
gagz commented 2 months ago

Hello,

Sur un site existant sous spip depuis 2002, mis à jour en spip3 en mai 2022 (oui oui), puis en spip4 dans la foulée, on ne peut plus se logger avec un compte webmestre ni créer d'users ni changer de mot de passe.

Depuis la mise à jour à spip4.1.5, un message d'erreur plus clair arrive, avec d'autres messages dans les logs:

Le web lors de la tentative de connexion (qui échoue bien sûr):

vérifier les droits d’écriture
Le système a rencontré une erreur lors de l’écriture du fichier config/cles.php.
Veuillez, en tant qu’administrateur du site, vérifier les droits d’écriture sur le répertoire config.

php_errorlog:

PHP Warning: A non-numeric value encountered in www/ecrire/src/Chiffrer/SpipCles.php on line 58

J'ai alors ajouté un spip_log juste avant cette fameuse ligne:

Spip.log (j'ai changé les valeurs mais gardé la tronche. Le saut de ligne dans 'meta=' est dans les logs aussi) :

:Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;��
�GT��j4j��5���91�'
:Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;��
�GT��j4j��5���91�'
:Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;��
�GT��j4j��5���91�'
:Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;��
�GT��j4j��5���91�'
:Pub:!INFO: Restauration de la cle secret_des_auth par id_auteur 575
:Pub:!INFO: Les cles secretes ont ete restaurées avec le backup du webmestre #575
:Pub:!INFO: Ecriture fichier config/cles.php impossible
:Pub:ERREUR: Echec restauration des cles : verifier les droits d'ecriture ?

J'ai aussi vérifié les droits d'écriture, mais je ne peux de toutes manière pas y toucher car chez l'hébergeur les droits sont fixés et tous les fichiers appartiennent au même user.
(en l'occurence, le fichier cles.php est à 660)

Sur conseil de jluc, j'ai remplacé la ligne return $key ^ $meta; par return bin2hex(pack('H*',$key) ^ pack('H*',$meta));, mais j'obtiens la même erreur dans le web, et php_errorlog contient de nombreuses lignes de ce type:

PHP Warning:  pack(): Type H: illegal hex digit � in www/ecrire/src/Chiffrer/SpipCles.php on line 61

Je l'ai donc transformée en :

return pack('H*',bin2hex($key)) ^ pack('H*',bin2hex($meta));

Et alors retour à la même chose qu'avec la ligne d'origine de spip (return $key ^ $meta;)

Mon fichier cles.php contient deux lignes:

  • une en php avec un die("blabla");
  • une en json avec uniquement 'secret_du_site' ayant une valeur supposément base64.

Dans la base de données, table spip_meta, la valeur 'meta' contient aussi une valeur supposément base64.

Dernière info que je puisse donner: le collate de la table est latin1_swedish_ci, de même pour la colonne contenant la clé.

Voilà mon problème!

Avez-vous des idées?

Merci beaucoup!

Hello, Sur un site existant sous spip depuis 2002, mis à jour en spip3 en mai 2022 (oui oui), puis en spip4 dans la foulée, on ne peut plus se logger avec un compte webmestre ni créer d'users ni changer de mot de passe. Depuis la mise à jour à spip4.1.5, un message d'erreur plus clair arrive, avec d'autres messages dans les logs: Le web lors de la tentative de connexion (qui échoue bien sûr): ``` vérifier les droits d’écriture Le système a rencontré une erreur lors de l’écriture du fichier config/cles.php. Veuillez, en tant qu’administrateur du site, vérifier les droits d’écriture sur le répertoire config. ``` php_errorlog: > PHP Warning: A non-numeric value encountered in www/ecrire/src/Chiffrer/SpipCles.php on line 58 J'ai alors ajouté un spip_log juste avant cette fameuse ligne: Spip.log (j'ai changé les valeurs mais gardé la tronche. Le saut de ligne dans 'meta=' est dans les logs aussi) : ``` :Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;�� �GT��j4j��5���91�' :Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;�� �GT��j4j��5���91�' :Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;�� �GT��j4j��5���91�' :Pub:ERREUR: key='���;���Uic�_:��!?�G�' meta='^iAS�i�;�� �GT��j4j��5���91�' :Pub:!INFO: Restauration de la cle secret_des_auth par id_auteur 575 :Pub:!INFO: Les cles secretes ont ete restaurées avec le backup du webmestre #575 :Pub:!INFO: Ecriture fichier config/cles.php impossible :Pub:ERREUR: Echec restauration des cles : verifier les droits d'ecriture ? ``` J'ai aussi vérifié les droits d'écriture, mais je ne peux de toutes manière pas y toucher car chez l'hébergeur les droits sont fixés et tous les fichiers appartiennent au même user. (en l'occurence, le fichier cles.php est à 660) Sur conseil de jluc, j'ai remplacé la ligne `return $key ^ $meta;` par `return bin2hex(pack('H*',$key) ^ pack('H*',$meta));`, mais j'obtiens la même erreur dans le web, et php_errorlog contient de nombreuses lignes de ce type: ``` PHP Warning: pack(): Type H: illegal hex digit � in www/ecrire/src/Chiffrer/SpipCles.php on line 61 ``` Je l'ai donc transformée en : ``` return pack('H*',bin2hex($key)) ^ pack('H*',bin2hex($meta)); ``` Et alors retour à la même chose qu'avec la ligne d'origine de spip (return $key ^ $meta;) Mon fichier cles.php contient deux lignes: - une en php avec un die("blabla"); - une en json avec uniquement 'secret_du_site' ayant une valeur supposément base64. Dans la base de données, table spip_meta, la valeur 'meta' contient aussi une valeur supposément base64. Dernière info que je puisse donner: le collate de la table est latin1_swedish_ci, de même pour la colonne contenant la clé. Voilà mon problème! Avez-vous des idées? Merci beaucoup!
Owner

Le message d'erreur dit bien ce qu'il dit. Il y a un problème d'écriture du fichier
config/cles.php du coup SPIP n'arrive pas à stocker la cle d'authentification qui sert à hasher les pass en base. Soit le dossier config/ n'est pas accessible en écriture par le user web, soit le fichier config/cles.php lui même est problématique.

Après relecture attentive du code d'ecriture du fichier avec verrou avec @marcimat on propose le patch
b9b55be291
à essayer

Le message d'erreur dit bien ce qu'il dit. Il y a un problème d'écriture du fichier `config/cles.php` du coup SPIP n'arrive pas à stocker la cle d'authentification qui sert à hasher les pass en base. Soit le dossier config/ n'est pas accessible en écriture par le user web, soit le fichier `config/cles.php` lui même est problématique. Après relecture attentive du code d'ecriture du fichier avec verrou avec @marcimat on propose le patch https://git.spip.net/spip/spip/commit/b9b55be291fe3e9ded1ab8b2435d6c88fbdc26a5 à essayer
Poster

Hey,

Ok j'ai cherry-pick le commit et l'ai passé en prod, et là, paf ça marche!!

Quelle est la meilleure chose à faire maintenant pour moi? Je laisse ce commit dans notre branche, et j'espère qu'elle sera fusionnée à la prochaine mise à jour?

Hey, Ok j'ai cherry-pick le commit et l'ai passé en prod, et là, paf ça marche!! Quelle est la meilleure chose à faire maintenant pour moi? Je laisse ce commit dans notre branche, et j'espère qu'elle sera fusionnée à la prochaine mise à jour?
Owner

Si tu peux nous aider encore un peu à faire mieux alors

  • cherry-pick 8c60adac05
  • supprime le fichier config/cles.php
  • deconnecte toi et reconnecte toi
Si tu peux nous aider encore un peu à faire mieux alors - cherry-pick 8c60adac05dfedf91b8053fe85122fe3997cdcc5 - supprime le fichier config/cles.php - deconnecte toi et reconnecte toi
b_b added the
bug
authentification
labels 2 months ago
b_b added this to the 4.1 milestone 2 months ago
Owner

Et pas merci gitea de m'avoir fait raté la notification du commentaire de @cerdic :\

Et pas merci gitea de m'avoir fait raté la notification du commentaire de @cerdic :\
Poster

Re,

Ok alors du coup depuis tout à l'heure j'ai galéré un peu, jusqu'à réaliser que notre site était passé à spip4.1.5 en partie uniquement… "en partie", car notre script de mise à jour utilisait "rsync --size-only", donc les fichiers qui ne changeaient pas en taille n'étaient pas transférés, ce qui était le cas d'environ 7 fichiers (j'ai vérifié avec git diff --names-only <commit tag v4.1.2>..<commit tag v4.2.5> puis une relecture manuelle du code)

(C'est pas évident à gérer car tout passe par Tor, donc tout est très lent, les rsync à 4000 fichiers je vous raconte pas le délire)

J'ai donc finalisé la mise à jour du site (espérons), puis retesté de me connecter et j'obtiens la même erreur.

J'ai donc de nouveau cherry-pick b9b55be291 et l'ai poussé en prod, et j'ai pu me connecter (j'avais remis le fichier cles.php foireux). Le fichier cles.php a bien gagné une clé supplémentaire.

Ensuite j'renommé cles.php, puis retenté un login: échec (l'erreur d'écriture du début).

J'ai alors cherry-pick 8c60adac05, poussé en prod, et encore échec.

Avec cles.php contenant uniquement le secret_du_site

flock.log:

:Pub:!INFO: Ecriture fichier config/cles.php impossible

spip.log:

:Pub:!INFO: Ecriture fichier config/cles.php impossible
:Pub:ERREUR: Echec restauration des cles : verifier les droits d'ecriture ?

php_errorlog:

PHP Warning: A non-numeric value encountered in www/ecrire/src/Chiffrer/SpipCles.php on line 58

Avec cles.php existant mais vide:

Échec de la connexion

flock.log et spip.log

:Pub:!INFO: ecrire_fichier: operation atomique via rename() impossible, fallback non atomique via file_put_contents

php_errorlog:

file_put_contents(config/cles.php.78799770162df01b81d9007.01196137): failed to open stream: Permission denied in www/ecrire/inc/flock.php on line 241

Avec uniquement secret_du_site dans cles.php, ça marche et il rajoute bien secret_des_auth.

Voilàààà

Tu peux encore me faire tester si tu veux, bien que ça va pas être de suite de suite je pense.

MERCII

Re, Ok alors du coup depuis tout à l'heure j'ai galéré un peu, jusqu'à réaliser que notre site était passé à spip4.1.5 en partie uniquement… "en partie", car notre script de mise à jour utilisait "rsync --size-only", donc les fichiers qui ne changeaient pas en taille n'étaient pas transférés, ce qui était le cas d'environ 7 fichiers (j'ai vérifié avec `git diff --names-only <commit tag v4.1.2>..<commit tag v4.2.5>` puis une relecture manuelle du code) (C'est pas évident à gérer car tout passe par Tor, donc tout est très lent, les rsync à 4000 fichiers je vous raconte pas le délire) J'ai donc finalisé la mise à jour du site (espérons), puis retesté de me connecter et j'obtiens la même erreur. J'ai donc de nouveau cherry-pick b9b55be291fe3e9ded1ab8b2435d6c88fbdc26a5 et l'ai poussé en prod, et j'ai pu me connecter (j'avais remis le fichier cles.php foireux). Le fichier cles.php a bien gagné une clé supplémentaire. Ensuite j'renommé cles.php, puis retenté un login: échec (l'erreur d'écriture du début). J'ai alors cherry-pick 8c60adac05dfedf91b8053fe85122fe3997cdcc5, poussé en prod, et encore échec. **Avec cles.php contenant uniquement le secret_du_site** flock.log: > :Pub:!INFO: Ecriture fichier config/cles.php impossible spip.log: > :Pub:!INFO: Ecriture fichier config/cles.php impossible > :Pub:ERREUR: Echec restauration des cles : verifier les droits d'ecriture ? php_errorlog: > PHP Warning: A non-numeric value encountered in www/ecrire/src/Chiffrer/SpipCles.php on line 58 **Avec cles.php existant mais vide:** Échec de la connexion flock.log et spip.log > :Pub:!INFO: ecrire_fichier: operation atomique via rename() impossible, fallback non atomique via file_put_contents php_errorlog: > file_put_contents(config/cles.php.78799770162df01b81d9007.01196137): failed to open stream: Permission denied in www/ecrire/inc/flock.php on line 241 **Avec uniquement secret_du_site dans cles.php**, ça marche et il rajoute bien secret_des_auth. Voilàààà Tu peux encore me faire tester si tu veux, bien que ça va pas être de suite de suite je pense. MERCII
Owner

Quelques prises de notes

Rien de spécialement atomique a priori (autre que l’usage natif de PHP)

Symfony/filesystem

League/Flysystem

Librairies spécifiques

Mais bon, semblent pas avoir de truc plus magiques

Quelques prises de notes Rien de spécialement atomique a priori (autre que l’usage natif de PHP) ### Symfony/filesystem - copy : https://github.com/symfony/filesystem/blob/6.1/Filesystem.php#L37 - rename : https://github.com/symfony/filesystem/blob/6.1/Filesystem.php#L278 ### League/Flysystem - copy : https://github.com/thephpleague/flysystem/blob/3.2.0/src/Local/LocalFilesystemAdapter.php#L271 - rename : https://github.com/thephpleague/flysystem/blob/3.2.0/src/Local/LocalFilesystemAdapter.php#L255 ### Librairies spécifiques Mais bon, semblent pas avoir de truc plus magiques - https://packagist.org/packages/nette/safe-stream (notamment while usleep pour obtenir le lock en lecture de fichier https://github.com/nette/safe-stream/blob/master/src/SafeStream/Wrapper.php#L77) - https://github.com/spiral/files/blob/master/src/Files.php#L113 (avant de write, vérifie le chmod du fichier)
Owner

Ah ben je comprends pas comment ça a pu marcher avec le patch précédent, et tu vois bien qu'il y a un soucis de droits d'écriture: quand il essaye d'écrire un nouveau fichier dans config/ il se mange l'erreur

file_put_contents(config/cles.php.78799770162df01b81d9007.01196137): failed to open stream: Permission denied in www/ecrire/inc/flock.php on line 241

je me demande si le premier lock que l'on pause ne provoquerait pas un lock temporaire au niveau du répertoire, et le patch précédent marchait parce qu'il perdait du temps à faire un truc qui marche pas avant la dernière tentative.

Du coup peux-tu essayer avec le patch supplémentaire
19864bb517
qui a un peu plus de log aussi, et si jamais ça marche essayer de réduire la valeur dans le usleep() pour voir quelle tempo minimale marcherait ?

Ah ben je comprends pas comment ça a pu marcher avec le patch précédent, et tu vois bien qu'il y a un soucis de droits d'écriture: quand il essaye d'écrire un nouveau fichier dans config/ il se mange l'erreur ``` file_put_contents(config/cles.php.78799770162df01b81d9007.01196137): failed to open stream: Permission denied in www/ecrire/inc/flock.php on line 241 ``` je me demande si le premier lock que l'on pause ne provoquerait pas un lock temporaire au niveau du répertoire, et le patch précédent marchait parce qu'il perdait du temps à faire un truc qui marche pas avant la dernière tentative. Du coup peux-tu essayer avec le patch supplémentaire https://git.spip.net/spip/spip/commit/19864bb51757a6fa2377cafdeab6c7a59c99f750 qui a un peu plus de log aussi, et si jamais ça marche essayer de réduire la valeur dans le `usleep()` pour voir quelle tempo minimale marcherait ?
Owner

@cerdic pourquoi usleep et pas sleep ?

Je lis ici https://www.php.net/manual/fr/function.usleep.php#75399 que usleep consomme du cpu alors que sleep non cf :

the idea of sleep and usleep is that by letting the cpu run a few idle cycles so the other programs can have some cycles run of their own. what results in better response times and lower overall system-load. so if you have to wait for something, go to sleep for a few seconds instead of occupying the cpu while doing absolute nothing but waitting.

@cerdic pourquoi `usleep` et pas `sleep` ? Je lis ici https://www.php.net/manual/fr/function.usleep.php#75399 que usleep consomme du cpu alors que sleep non cf : > the idea of sleep and usleep is that by letting the cpu run a few idle cycles so the other programs can have some cycles run of their own. what results in better response times and lower overall system-load. so if you have to wait for something, go to sleep for a few seconds instead of occupying the cpu while doing absolute nothing but waitting.
Owner

L’idée @b_b c’est déjà de faire un test, et accessoirement pas attendre en secondes, mais en micro secondes…

L’idée @b_b c’est déjà de faire un test, et accessoirement pas attendre en secondes, mais en micro secondes…
Owner

Ha vi, je suis passé à côté du fait que sleep n'accepte que des int en paramètre, my bad.

Ha vi, je suis passé à côté du fait que sleep n'accepte que des int en paramètre, my bad.
Sign in to join this conversation.
No Milestone
No project
No Assignees
4 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.