restauration : lire aussi l archive en clair, pas seulement la chiffree
`--support-chiffre` ecrit un tar clair quand le support est deja chiffre au repos.
Ajoute cote EXPORT le 12 septembre, et pas cote RESTAURATION : `restaurer_cles.py`,
qui est ce qui rend la cle USB autonome, ne savait lire que du GPG.
Constate en EPROUVANT l export, pas en le supposant reussi. Et le message etait le
pire possible :
gpg: aucune donnee OpenPGP valable n a ete trouvee.
ECHEC du dechiffrement. Phrase de passe erronee, ou archive abimee.
Il accusait une phrase de passe qu on n avait jamais posee, sur une archive saine. Il
envoyait chercher la faute la ou elle n est pas — au moment ou l on restaure, c est-a
-dire au moment ou l on sait le moins.
`tarfile.is_tarfile` reconnait la forme. Pas de drapeau a passer : ce serait une chose
de plus a savoir le jour ou tout a brule.
Verifie sur la cle reelle : l archive du 13 se liste, dix fichiers, chacun avec sa
destination. Le garde-fou a par ailleurs refuse d ecraser celle du 12 — « on n ecrase
pas une sauvegarde de cles : elle est peut-etre la seule » — donc la nouvelle est
datee et l ancienne reste.
make prouver : 72 OK, 0 echec, 1 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
parent
025776064a
commit
a154893fc1
2 changed files with 60 additions and 10 deletions
31
CHANGELOG.md
31
CHANGELOG.md
|
|
@ -1,5 +1,36 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-09-13 (4) — La cle USB ne savait pas relire ce qu'on venait d'y ecrire
|
||||
|
||||
`exporter_cles --support-chiffre` ecrit un TAR CLAIR quand le support est deja chiffre au
|
||||
repos : empiler GPG par-dessus ajouterait une phrase de passe a perdre sans rien proteger
|
||||
de plus. Cette capacite a ete ajoutee cote EXPORT le 2026-09-12, et **pas cote
|
||||
RESTAURATION**.
|
||||
|
||||
`restaurer_cles.py` — le script qui rend la cle autonome — ne savait lire que du GPG.
|
||||
Constate en eprouvant l'export, pas en le supposant reussi :
|
||||
|
||||
```
|
||||
gpg: aucune donnée OpenPGP valable n'a été trouvée.
|
||||
ECHEC du dechiffrement.
|
||||
Phrase de passe erronee, ou archive abimee.
|
||||
```
|
||||
|
||||
**Le message accusait une phrase de passe qu'on n'avait jamais posee**, sur une archive
|
||||
parfaitement saine. C'est le pire genre de diagnostic : il envoie chercher la faute la ou
|
||||
elle n'est pas, au moment ou l'on restaure — c'est-a-dire au moment ou l'on sait le moins.
|
||||
|
||||
`tarfile.is_tarfile` reconnait la forme ; les deux sont desormais lues. On ne demande pas
|
||||
un drapeau : ce serait une chose de plus a savoir le jour ou tout a brule.
|
||||
|
||||
### Ce que l'export a aussi montre de bon
|
||||
|
||||
Le garde-fou a REFUSE d'ecraser l'archive du 12 — « on n'ecrase pas une sauvegarde de
|
||||
cles : elle est peut-etre la seule ». La nouvelle est datee, l'ancienne reste.
|
||||
|
||||
Dix cles sortent desormais, dont `setops-vault-site-technolibre`, creee le jour meme.
|
||||
|
||||
|
||||
## 2026-09-13 (3) — Un site expose ce dont ses locataires ont besoin pour l'habiter
|
||||
|
||||
### Le constat
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ def _destination(nom: str) -> Path:
|
|||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("archive", help="Chemin de l'archive .tar.gpg")
|
||||
ap.add_argument("archive", help="Chemin de l'archive (.tar ou .tar.gpg)")
|
||||
ap.add_argument("--lister", action="store_true",
|
||||
help="Montrer ce que l'archive contient, sans rien ecrire")
|
||||
ap.add_argument("--forcer", action="store_true",
|
||||
|
|
@ -61,16 +61,35 @@ def main() -> int:
|
|||
if not arch.is_file():
|
||||
raise SystemExit(f"REFUS : {arch} introuvable.")
|
||||
|
||||
# DEUX FORMES D'ARCHIVE, ET IL FAUT LES DEUX (mesure du 2026-09-13).
|
||||
#
|
||||
# `exporter_cles --support-chiffre` ecrit un TAR CLAIR quand le support est deja
|
||||
# chiffre au repos (LUKS) : empiler GPG par-dessus ajouterait une phrase de passe a
|
||||
# perdre sans rien proteger de plus. Cette capacite a ete ajoutee cote EXPORT sans
|
||||
# l'etre cote RESTAURATION — et ce script, qui est ce qui rend la cle autonome, ne
|
||||
# savait lire que du GPG.
|
||||
#
|
||||
# L'echec etait particulierement mauvais : gpg disait « aucune donnee OpenPGP valable »
|
||||
# puis le script concluait « phrase de passe erronee, ou archive abimee ». Il accusait
|
||||
# une phrase de passe qu'on n'avait jamais posee, sur une archive parfaitement saine.
|
||||
#
|
||||
# ON RECONNAIT LA FORME, on ne la demande pas : `tarfile.is_tarfile` lit l'en-tete.
|
||||
# Un drapeau a passer serait une chose de plus a savoir le jour ou l'on restaure —
|
||||
# c'est-a-dire le jour ou l'on sait le moins.
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
clair = Path(tmp) / "cles.tar"
|
||||
print(" La phrase de passe de l'archive va etre demandee.\n")
|
||||
r = subprocess.run(["gpg", "--quiet", "--output", str(clair),
|
||||
"--decrypt", str(arch)])
|
||||
if r.returncode != 0:
|
||||
raise SystemExit(
|
||||
"\nECHEC du dechiffrement.\n"
|
||||
" Phrase de passe erronee, ou archive abimee. gpg verifie l'integrite\n"
|
||||
" (AES256 + MDC) : s'il refuse, le contenu n'est pas fiable.")
|
||||
if tarfile.is_tarfile(arch):
|
||||
print(" Archive EN CLAIR — la protection etait celle du support (LUKS).\n")
|
||||
clair = arch
|
||||
else:
|
||||
clair = Path(tmp) / "cles.tar"
|
||||
print(" Archive chiffree. La phrase de passe va etre demandee.\n")
|
||||
r = subprocess.run(["gpg", "--quiet", "--output", str(clair),
|
||||
"--decrypt", str(arch)])
|
||||
if r.returncode != 0:
|
||||
raise SystemExit(
|
||||
"\nECHEC du dechiffrement.\n"
|
||||
" Phrase de passe erronee, ou archive abimee. gpg verifie l'integrite\n"
|
||||
" (AES256 + MDC) : s'il refuse, le contenu n'est pas fiable.")
|
||||
|
||||
with tarfile.open(clair) as tar:
|
||||
noms = [n for n in tar.getnames() if "/" not in n and not n.startswith("..")]
|
||||
|
|
|
|||
Loading…
Reference in a new issue