madaramaster 5.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. madaramaster-5.0.0/.gitignore +11 -0
  2. madaramaster-5.0.0/LICENSE +22 -0
  3. madaramaster-5.0.0/MANIFEST.in +8 -0
  4. madaramaster-5.0.0/MadaraMaster.spec +53 -0
  5. madaramaster-5.0.0/PKG-INFO +409 -0
  6. madaramaster-5.0.0/README.md +379 -0
  7. madaramaster-5.0.0/RELEASING.md +97 -0
  8. madaramaster-5.0.0/build.ps1 +82 -0
  9. madaramaster-5.0.0/madara.manifest +56 -0
  10. madaramaster-5.0.0/madara.py +7 -0
  11. madaramaster-5.0.0/madaramaster/__init__.py +3 -0
  12. madaramaster-5.0.0/madaramaster/__main__.py +5 -0
  13. madaramaster-5.0.0/madaramaster/audit.py +154 -0
  14. madaramaster-5.0.0/madaramaster/cli.py +118 -0
  15. madaramaster-5.0.0/madaramaster/commands.py +458 -0
  16. madaramaster-5.0.0/madaramaster/engine.py +957 -0
  17. madaramaster-5.0.0/madaramaster/free_space.py +114 -0
  18. madaramaster-5.0.0/madaramaster/i18n.py +323 -0
  19. madaramaster-5.0.0/madaramaster/interactive.py +208 -0
  20. madaramaster-5.0.0/madaramaster/models.py +58 -0
  21. madaramaster-5.0.0/madaramaster/residue.py +242 -0
  22. madaramaster-5.0.0/madaramaster/runner.py +206 -0
  23. madaramaster-5.0.0/madaramaster/safety.py +188 -0
  24. madaramaster-5.0.0/madaramaster/storage.py +503 -0
  25. madaramaster-5.0.0/madaramaster/trim.py +140 -0
  26. madaramaster-5.0.0/madaramaster/ui.py +330 -0
  27. madaramaster-5.0.0/madaramaster/utils.py +30 -0
  28. madaramaster-5.0.0/madaramaster.egg-info/PKG-INFO +409 -0
  29. madaramaster-5.0.0/madaramaster.egg-info/SOURCES.txt +50 -0
  30. madaramaster-5.0.0/madaramaster.egg-info/dependency_links.txt +1 -0
  31. madaramaster-5.0.0/madaramaster.egg-info/entry_points.txt +2 -0
  32. madaramaster-5.0.0/madaramaster.egg-info/requires.txt +11 -0
  33. madaramaster-5.0.0/madaramaster.egg-info/top_level.txt +1 -0
  34. madaramaster-5.0.0/pyproject.toml +64 -0
  35. madaramaster-5.0.0/scripts/release_notes.py +101 -0
  36. madaramaster-5.0.0/setup.cfg +4 -0
  37. madaramaster-5.0.0/tests/conftest.py +282 -0
  38. madaramaster-5.0.0/tests/test_audit.py +111 -0
  39. madaramaster-5.0.0/tests/test_batch_trim_writes_names.py +128 -0
  40. madaramaster-5.0.0/tests/test_dangerous_targets.py +138 -0
  41. madaramaster-5.0.0/tests/test_direct_io.py +144 -0
  42. madaramaster-5.0.0/tests/test_interactive.py +175 -0
  43. madaramaster-5.0.0/tests/test_links.py +147 -0
  44. madaramaster-5.0.0/tests/test_messages_and_standards.py +160 -0
  45. madaramaster-5.0.0/tests/test_packaging_and_cli.py +230 -0
  46. madaramaster-5.0.0/tests/test_release_notes.py +90 -0
  47. madaramaster-5.0.0/tests/test_residue.py +195 -0
  48. madaramaster-5.0.0/tests/test_safety_net.py +87 -0
  49. madaramaster-5.0.0/tests/test_trim.py +48 -0
  50. madaramaster-5.0.0/tests/test_unlink_and_verify.py +92 -0
  51. madaramaster-5.0.0/tests/test_windows_ads.py +43 -0
  52. madaramaster-5.0.0/tests/test_wipe_free_space.py +119 -0
@@ -0,0 +1,11 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .env
4
+ venv/
5
+ .vscode/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ *.egg-info/
10
+ .pytest_cache/
11
+ .ruff_cache/
@@ -0,0 +1,22 @@
1
+ Licencia MIT
2
+
3
+ Copyright (c) 2026 jaimefg1888
4
+
5
+ Por la presente se concede permiso, de forma gratuita, a cualquier persona que obtenga una copia de este software y de los archivos de documentación asociados (el "Software"), para utilizar el Software sin restricción, incluyendo sin limitación los derechos de uso, copia, modificación, fusión, publicación, distribución, sublicencia y/o venta de copias del Software, y para permitir a las personas a quienes se les proporcione el Software hacer lo mismo, sujeto a las siguientes condiciones:
6
+
7
+ El aviso de copyright anterior y este aviso de permiso se incluirán en todas las copias o partes sustanciales del Software.
8
+
9
+ EL SOFTWARE SE PROPORCIONA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITA, INCLUYENDO PERO SIN LIMITARSE A LAS GARANTÍAS DE COMERCIABILIDAD, IDONEIDAD PARA UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. EN NINGÚN CASO LOS AUTORES O TITULARES DEL COPYRIGHT SERÁN RESPONSABLES DE NINGUNA RECLAMACIÓN, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, EXTRACONTRACTUAL O DE OTRO TIPO, QUE SURJA DE O EN CONEXIÓN CON EL SOFTWARE O EL USO U OTRO TIPO DE ACCIONES EN EL SOFTWARE.
10
+
11
+ ---
12
+
13
+ ⚠️ AVISO ADICIONAL — USO AUTORIZADO ÚNICAMENTE
14
+
15
+ Esta herramienta está diseñada para la sanitización legítima de datos. Al usar este software, el usuario confirma que:
16
+
17
+ 1. Está autorizado a eliminar los datos en cuestión.
18
+ 2. Comprende que las operaciones de borrado son permanentes e irrecuperables.
19
+ 3. Ha realizado las copias de seguridad necesarias antes de ejecutar cualquier operación.
20
+ 4. Cumple con todas las leyes y regulaciones aplicables en su jurisdicción.
21
+
22
+ El autor (jaimefg1888) no acepta ninguna responsabilidad por pérdida de datos, daños o consecuencias legales derivadas del uso indebido de este software.
@@ -0,0 +1,8 @@
1
+ # Files the sdist needs beyond what setuptools picks up automatically.
2
+ # tests/conftest.py holds the safety net (mocked TRIM and storage detection,
3
+ # no device access, no writes outside tmp): the tests must never run without it.
4
+ graft tests
5
+ graft scripts
6
+ include RELEASING.md
7
+ include madara.py MadaraMaster.spec madara.manifest build.ps1 .gitignore
8
+ global-exclude __pycache__ *.py[cod]
@@ -0,0 +1,53 @@
1
+ # -*- mode: python ; coding: utf-8 -*-
2
+ # PyInstaller build definition for the Windows executable.
3
+ #
4
+ # pip install ".[build]"
5
+ # pyinstaller MadaraMaster.spec --clean --noconfirm
6
+ #
7
+ # Output: dist/MadaraMaster.exe (single-file console application).
8
+ # The embedded manifest (madara.manifest) requests "asInvoker": the program
9
+ # runs with the user's own rights and never asks for elevation by itself.
10
+
11
+ import re
12
+ from pathlib import Path
13
+
14
+ ROOT = Path(SPECPATH) # noqa: F821 — provided by PyInstaller
15
+
16
+
17
+ def manifest_xml() -> str:
18
+ """madara.manifest with {version} set from madaramaster.__version__."""
19
+ init = (ROOT / "madaramaster" / "__init__.py").read_text(encoding="utf-8")
20
+ version = re.search(r'__version__ = "([^"]+)"', init).group(1)
21
+ parts = [p for p in re.split(r"[.\-+]", version) if p.isdigit()][:4]
22
+ numeric = ".".join(parts + ["0"] * (4 - len(parts)))
23
+ template = (ROOT / "madara.manifest").read_text(encoding="utf-8")
24
+ return template.replace("{version}", numeric)
25
+
26
+
27
+ a = Analysis(
28
+ [str(ROOT / "madara.py")],
29
+ pathex=[],
30
+ binaries=[],
31
+ datas=[],
32
+ hiddenimports=[],
33
+ hookspath=[],
34
+ runtime_hooks=[],
35
+ excludes=[],
36
+ noarchive=False,
37
+ )
38
+ pyz = PYZ(a.pure)
39
+
40
+ exe = EXE(
41
+ pyz,
42
+ a.scripts,
43
+ a.binaries,
44
+ a.datas,
45
+ [],
46
+ name="MadaraMaster",
47
+ debug=False,
48
+ strip=False,
49
+ upx=False,
50
+ console=True,
51
+ manifest=manifest_xml(),
52
+ uac_admin=False,
53
+ )
@@ -0,0 +1,409 @@
1
+ Metadata-Version: 2.4
2
+ Name: madaramaster
3
+ Version: 5.0.0
4
+ Summary: Secure file sanitization: multi-pass overwrite, metadata scrubbing and deletion (NIST SP 800-88 / DoD 5220.22-M patterns).
5
+ Author: jaimefg1888
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/jaimefgdev/MadaraMaster
8
+ Project-URL: Issues, https://github.com/jaimefgdev/MadaraMaster/issues
9
+ Keywords: secure-delete,wipe,shred,sanitization,nist-800-88
10
+ Classifier: Environment :: Console
11
+ Classifier: Operating System :: Microsoft :: Windows
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: POSIX :: Linux
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: System :: Filesystems
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: aiofiles<26,>=23.2.1
21
+ Requires-Dist: rich<16,>=13.7
22
+ Requires-Dist: typer<1,>=0.9
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest<10,>=8; extra == "dev"
25
+ Requires-Dist: pytest-asyncio<2,>=0.23; extra == "dev"
26
+ Requires-Dist: ruff>=0.6; extra == "dev"
27
+ Provides-Extra: build
28
+ Requires-Dist: pyinstaller<7,>=6; extra == "build"
29
+ Dynamic: license-file
30
+
31
+ [English](#-english) · [Español](#-español)
32
+
33
+ ## 🇬🇧 English
34
+
35
+ # 🧹 MadaraMaster
36
+
37
+ Secure file deletion for Linux, Windows and macOS. MadaraMaster overwrites files with the pass patterns of NIST SP 800-88 *Clear* and DoD 5220.22-M, scrubs their metadata and then deletes them, so that ordinary undelete and file-carving tools cannot bring them back.
38
+
39
+ > ⚠️ **Read [Limitations](#limitations) before relying on it.** Overwriting a file only destroys the copy the filesystem currently points to. SSDs, copy-on-write filesystems, snapshots, backups and cloud sync can keep other copies that no file-level tool can reach.
40
+
41
+ ### Features
42
+
43
+ - **Storage detection** — tells HDD, SSD and NVMe apart on Linux (sysfs), Windows (`IOCTL_STORAGE_QUERY_PROPERTY`) and macOS (`diskutil`) and picks the number of passes accordingly.
44
+ - **Direct I/O** — `O_DIRECT | O_SYNC` on Linux and `FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH` on Windows, with page-aligned buffers; falls back to buffered I/O plus `fsync` when the filesystem does not support it.
45
+ - **Slack space** — every pass covers the file rounded up to a whole cluster, so the tail of the last cluster is overwritten too.
46
+ - **Alternate Data Streams** (Windows) — every NTFS stream of the file is overwritten and removed.
47
+ - **Metadata scrubbing** — timestamps set to epoch 0 and 3–5 renames to random names of the same length before deletion.
48
+ - **Verification** — `--verify` re-reads the file and compares it with what the last pass wrote; on mismatch the file is **not** deleted. `purge` always verifies.
49
+ - **Safety checks** — symlinks and junctions are never followed, non-regular files are skipped, files with several hard links are refused, and protected targets (filesystem roots, your home directory and its parents, system directories, mount points) are refused unless explicitly allowed. Wiping a directory asks you to type its name.
50
+ - **Audit log** — one JSON line per file in a private per-user file.
51
+ - **Free-space wipe** — `wipe-free-space` fills the free space of a filesystem with zeros and removes the fill file, even if interrupted.
52
+ - **Interactive session** — run `madara` without arguments, drag files into the terminal, review the queue and confirm.
53
+ - **Bilingual** — English and Spanish (`--lang es` or `MADARA_LANG=es`).
54
+
55
+ ### Requirements
56
+
57
+ - Python 3.10 or newer
58
+ - Runtime dependencies (installed automatically): `typer`, `rich`, `aiofiles`
59
+
60
+ ### Installation
61
+
62
+ From PyPI (published releases):
63
+
64
+ ```bash
65
+ pip install madaramaster
66
+ ```
67
+
68
+ Latest development version:
69
+
70
+ ```bash
71
+ pip install git+https://github.com/jaimefgdev/MadaraMaster
72
+ ```
73
+
74
+ or from a clone:
75
+
76
+ ```bash
77
+ git clone https://github.com/jaimefgdev/MadaraMaster
78
+ cd MadaraMaster
79
+ pip install .
80
+ ```
81
+
82
+ This installs the `madara` command. `python -m madaramaster` and `python madara.py` (from a clone) are equivalent.
83
+
84
+ **Windows executable:** download `MadaraMaster-<version>-windows-x64.exe` from the [Releases](https://github.com/jaimefgdev/MadaraMaster/releases) page (each release lists the SHA-256 of its files), or build it yourself with `.\build.ps1` (see [Development](#development)). The executable runs with your own rights and never asks for elevation by itself.
85
+
86
+ ### Usage
87
+
88
+ ```bash
89
+ madara # interactive session
90
+ madara wipe secret.pdf # wipe one file (asks for confirmation)
91
+ madara wipe ./old-project # wipe a directory tree (type its name to confirm)
92
+ madara wipe secret.pdf --dry-run # list what would be wiped, touch nothing
93
+ madara wipe data.pdf -s purge # 3 passes on HDD + verification
94
+ madara wipe data.pdf --no-log # do not write an audit log
95
+ madara wipe-free-space /mnt/data # overwrite the free space of a filesystem
96
+ madara --lang es wipe secret.pdf # Spanish interface
97
+ madara version
98
+ madara install-right-click # Windows: add "Wipe with MadaraMaster" to Explorer
99
+ ```
100
+
101
+ #### `madara wipe TARGET`
102
+
103
+ | Option | Alias | Description |
104
+ |--------|-------|-------------|
105
+ | `--confirm` | `-y` | Skip the confirmation prompt |
106
+ | `--dry-run` | `-n` | List the targets and exit |
107
+ | `--standard` | `-s` | `clear` (default), `purge` or `dod` |
108
+ | `--verify` | | Re-read and compare after wiping; keep the file on mismatch |
109
+ | `--log-path` | `-l` | Custom audit-log path |
110
+ | `--no-log` | | Do not write an audit log |
111
+ | `--hash` | | Record each file's pre-wipe SHA-256 in the audit log |
112
+ | `--trim` | | After the batch, send one TRIM per filesystem (SSD/NVMe, Linux only) |
113
+ | `--allow-hardlinks` | | Also wipe files with several hard links (destroys the data of every name) |
114
+ | `--allow-dangerous-target` | | Allow protected targets (roots, home, system directories, mount points) |
115
+
116
+ The exit code is `0` when every file was wiped and `1` otherwise.
117
+
118
+ #### `madara wipe-free-space [DIR]`
119
+
120
+ | Option | Alias | Description |
121
+ |--------|-------|-------------|
122
+ | `--confirm` | `-y` | Skip the confirmation prompt |
123
+ | `--dry-run` | `-n` | Show what would be done and exit |
124
+ | `--no-trim` | | Do not send TRIM afterwards |
125
+
126
+ The filesystem is full for a moment while this runs; existing files are not modified.
127
+
128
+ #### Global options
129
+
130
+ | Option | Description |
131
+ |--------|-------------|
132
+ | `--lang en\|es` | Interface language (also the `MADARA_LANG` environment variable) |
133
+
134
+ ### Standards
135
+
136
+ | Standard | HDD passes | SSD/NVMe passes | Verification |
137
+ |----------|-----------|-----------------|--------------|
138
+ | `clear` | 1 (zeros) | 1 (random) | only with `--verify` |
139
+ | `purge` | 3 (zeros, ones, random) | 1 (random) | always |
140
+ | `dod` | 3 (zeros, ones, random) | 1 (random) | only with `--verify` |
141
+
142
+ On flash storage one random pass is used whatever the standard: wear-leveling means extra passes do not reach more cells. Using `purge` or `dod` on SSD/NVMe prints a warning, because overwriting files on flash does **not** meet NIST SP 800-88 *Purge*.
143
+
144
+ ### Audit log
145
+
146
+ Each wiped file adds one JSON line with the UTC timestamp, path, size, standard, passes, verification result, user, hostname and outcome. By default the log lives in a private per-user location:
147
+
148
+ | OS | Default path |
149
+ |----|--------------|
150
+ | Linux | `$XDG_STATE_HOME/madaramaster/audit.jsonl` (default `~/.local/state/…`) |
151
+ | macOS | `~/Library/Logs/MadaraMaster/audit.jsonl` |
152
+ | Windows | `%LOCALAPPDATA%\MadaraMaster\audit.jsonl` |
153
+
154
+ The pre-wipe SHA-256 is only recorded with `--hash`, because it lets anyone holding the log confirm what a file contained. `--no-log` disables the log.
155
+
156
+ ### Limitations
157
+
158
+ Before wiping, MadaraMaster warns you when it detects one of these cases: SSD/NVMe drives, copy-on-write filesystems, network locations, cloud-synced folders and ext3/ext4 mounted with `data=journal`. The absence of a warning is not a guarantee.
159
+
160
+ MadaraMaster works at file level. It cannot guarantee that no copy of the data survives when:
161
+
162
+ - **The file is on an SSD, NVMe drive, USB stick or SD card.** The controller remaps writes (wear-leveling, over-provisioning), so the old blocks can stay on the chips. Use full-disk encryption from day one, or the drive's own sanitize command (ATA Secure Erase, NVMe Format / Sanitize), to purge flash.
163
+ - **The filesystem is copy-on-write or log-structured** — btrfs, ZFS, APFS, ReFS, F2FS: new data goes to new blocks and the old ones are left behind.
164
+ - **Snapshots or backups exist** — Volume Shadow Copies, Time Machine, btrfs/ZFS snapshots, backup software.
165
+ - **The file is synced or cached elsewhere** — OneDrive, Dropbox, iCloud, Google Drive, network shares.
166
+ - **The filesystem journals data** — e.g. ext4 with `data=journal`; NTFS and ext4 journal metadata such as names.
167
+ - **Other copies exist** — editor backups and autosaves, temporary files, the swap file or hibernation file, thumbnails, recently-used lists.
168
+
169
+ For strong guarantees, combine full-disk encryption with destroying the key, or sanitize the whole device.
170
+
171
+ ### Development
172
+
173
+ ```bash
174
+ pip install -e ".[dev]"
175
+ python -m pytest # test suite
176
+ ruff check . # lint
177
+ ```
178
+
179
+ The tests never wipe anything real: an autouse fixture mocks TRIM and storage detection, blocks every device path and `ioctl`, and refuses any write, rename or delete outside pytest's temporary directory. CI runs on Linux, Windows and macOS and also builds the Windows executable.
180
+
181
+ To build `MadaraMaster.exe` on Windows: `.\build.ps1`, or `pip install ".[build]"` and `pyinstaller MadaraMaster.spec --clean --noconfirm`.
182
+
183
+ Releases are automated: pushing a tag `vX.Y.Z` that matches `__version__` builds the `.exe`, the wheel and the sdist, creates a GitHub Release and publishes to PyPI. See [RELEASING.md](RELEASING.md).
184
+
185
+ ### Project structure
186
+
187
+ ```
188
+ MadaraMaster/
189
+ ├── madaramaster/
190
+ │ ├── cli.py # entry point (madara) and stable import surface
191
+ │ ├── commands.py # Typer app: wipe, wipe-free-space, version, install-right-click
192
+ │ ├── interactive.py # interactive drag-and-drop session
193
+ │ ├── runner.py # shared wipe flow: target expansion, batch with dashboard, cleanup
194
+ │ ├── ui.py # console output: banner, prompts, summary, dashboard, warnings
195
+ │ ├── i18n.py # EN/ES strings and the active language
196
+ │ ├── free_space.py # free-space fill engine
197
+ │ ├── engine.py # async wipe engine (Direct I/O, ADS, slack space, verification)
198
+ │ ├── residue.py # detection of setups where copies may survive
199
+ │ ├── safety.py # link-safe target collection and protected-target checks
200
+ │ ├── storage.py # storage-type detection (sysfs / IOCTL / diskutil)
201
+ │ ├── trim.py # TRIM on Linux (FITRIM)
202
+ │ ├── audit.py # JSON Lines audit log
203
+ │ ├── models.py # result and telemetry data classes
204
+ │ └── utils.py # formatting helpers
205
+ ├── tests/ # pytest suite with the safety net (tests/conftest.py)
206
+ ├── madara.py # compatibility entry point
207
+ ├── MadaraMaster.spec # PyInstaller build
208
+ ├── madara.manifest # Windows manifest (asInvoker)
209
+ ├── build.ps1 # Windows release script
210
+ ├── scripts/ # release-notes generator used by the release workflow
211
+ ├── RELEASING.md # release process and PyPI Trusted Publishing setup
212
+ └── pyproject.toml
213
+ ```
214
+
215
+ ### License
216
+
217
+ MIT. See the LICENSE file.
218
+
219
+ This software is provided for authorized data sanitization only. The author takes no responsibility for misuse or for data lost through incorrect use.
220
+
221
+ ---
222
+
223
+ ## 🇪🇸 Español
224
+
225
+ # 🧹 MadaraMaster
226
+
227
+ Borrado seguro de archivos para Linux, Windows y macOS. MadaraMaster sobrescribe los archivos con los patrones de pases de NIST SP 800-88 *Clear* y DoD 5220.22-M, limpia sus metadatos y después los elimina, de modo que las herramientas habituales de recuperación y *carving* no puedan devolverlos.
228
+
229
+ > ⚠️ **Lee las [Limitaciones](#limitaciones) antes de confiar en ella.** Sobrescribir un archivo solo destruye la copia a la que apunta ahora el sistema de archivos. Los SSD, los sistemas de archivos copy-on-write, las instantáneas, las copias de seguridad y la sincronización en la nube pueden conservar otras copias que ninguna herramienta a nivel de archivo alcanza.
230
+
231
+ ### Características
232
+
233
+ - **Detección de almacenamiento** — distingue HDD, SSD y NVMe en Linux (sysfs), Windows (`IOCTL_STORAGE_QUERY_PROPERTY`) y macOS (`diskutil`) y elige el número de pases en consecuencia.
234
+ - **Direct I/O** — `O_DIRECT | O_SYNC` en Linux y `FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH` en Windows, con buffers alineados a página; si el sistema de archivos no lo admite, usa I/O con buffer más `fsync`.
235
+ - **Slack space** — cada pase cubre el archivo redondeado a un clúster completo, así que también se sobrescribe la cola del último clúster.
236
+ - **Alternate Data Streams** (Windows) — se sobrescriben y eliminan todos los flujos NTFS del archivo.
237
+ - **Limpieza de metadatos** — timestamps a epoch 0 y de 3 a 5 renombrados con nombres aleatorios de la misma longitud antes de borrar.
238
+ - **Verificación** — `--verify` relee el archivo y lo compara con lo escrito en el último pase; si no coincide, el archivo **no** se elimina. `purge` siempre verifica.
239
+ - **Salvaguardas** — los enlaces simbólicos y junctions nunca se siguen, los archivos no regulares se omiten, los archivos con varios enlaces duros se rechazan y los objetivos protegidos (raíces de sistemas de archivos, tu HOME y sus directorios padre, directorios del sistema, puntos de montaje) se rechazan salvo que se permita explícitamente. Para borrar un directorio hay que escribir su nombre.
240
+ - **Log de auditoría** — una línea JSON por archivo en un fichero privado del usuario.
241
+ - **Borrado del espacio libre** — `wipe-free-space` llena de ceros el espacio libre de un sistema de archivos y elimina el archivo de relleno, incluso si se interrumpe.
242
+ - **Sesión interactiva** — ejecuta `madara` sin argumentos, arrastra archivos a la terminal, revisa la cola y confirma.
243
+ - **Bilingüe** — inglés y español (`--lang es` o `MADARA_LANG=es`).
244
+
245
+ ### Requisitos
246
+
247
+ - Python 3.10 o superior
248
+ - Dependencias (se instalan automáticamente): `typer`, `rich`, `aiofiles`
249
+
250
+ ### Instalación
251
+
252
+ Desde PyPI (versiones publicadas):
253
+
254
+ ```bash
255
+ pip install madaramaster
256
+ ```
257
+
258
+ Última versión de desarrollo:
259
+
260
+ ```bash
261
+ pip install git+https://github.com/jaimefgdev/MadaraMaster
262
+ ```
263
+
264
+ o desde un clon:
265
+
266
+ ```bash
267
+ git clone https://github.com/jaimefgdev/MadaraMaster
268
+ cd MadaraMaster
269
+ pip install .
270
+ ```
271
+
272
+ Esto instala el comando `madara`. `python -m madaramaster` y `python madara.py` (desde un clon) son equivalentes.
273
+
274
+ **Ejecutable para Windows:** descarga `MadaraMaster-<versión>-windows-x64.exe` desde la página de [Releases](https://github.com/jaimefgdev/MadaraMaster/releases) (cada versión lista el SHA-256 de sus ficheros), o genéralo tú con `.\build.ps1` (ver [Desarrollo](#desarrollo)). El ejecutable funciona con tus propios permisos y nunca pide elevación por su cuenta.
275
+
276
+ ### Uso
277
+
278
+ ```bash
279
+ madara # sesión interactiva
280
+ madara wipe secreto.pdf # borrar un archivo (pide confirmación)
281
+ madara wipe ./proyecto-viejo # borrar un árbol de directorios (escribe su nombre para confirmar)
282
+ madara wipe secreto.pdf --dry-run # listar lo que se borraría sin tocar nada
283
+ madara wipe datos.pdf -s purge # 3 pases en HDD + verificación
284
+ madara wipe datos.pdf --no-log # sin log de auditoría
285
+ madara wipe-free-space /mnt/datos # sobrescribir el espacio libre de un sistema de archivos
286
+ madara --lang es wipe secreto.pdf # interfaz en español
287
+ madara version
288
+ madara install-right-click # Windows: añade "Wipe with MadaraMaster" al Explorador
289
+ ```
290
+
291
+ #### `madara wipe OBJETIVO`
292
+
293
+ | Opción | Alias | Descripción |
294
+ |--------|-------|-------------|
295
+ | `--confirm` | `-y` | Saltar la confirmación |
296
+ | `--dry-run` | `-n` | Listar los objetivos y salir |
297
+ | `--standard` | `-s` | `clear` (por defecto), `purge` o `dod` |
298
+ | `--verify` | | Releer y comparar tras el borrado; conserva el archivo si no coincide |
299
+ | `--log-path` | `-l` | Ruta del log de auditoría |
300
+ | `--no-log` | | No escribir log de auditoría |
301
+ | `--hash` | | Guardar en el log el SHA-256 previo de cada archivo |
302
+ | `--trim` | | Al terminar, enviar un TRIM por sistema de archivos (SSD/NVMe, solo Linux) |
303
+ | `--allow-hardlinks` | | Borrar también archivos con varios enlaces duros (destruye los datos de todos sus nombres) |
304
+ | `--allow-dangerous-target` | | Permitir objetivos protegidos (raíces, HOME, directorios del sistema, puntos de montaje) |
305
+
306
+ El código de salida es `0` si se borraron todos los archivos y `1` en caso contrario.
307
+
308
+ #### `madara wipe-free-space [DIR]`
309
+
310
+ | Opción | Alias | Descripción |
311
+ |--------|-------|-------------|
312
+ | `--confirm` | `-y` | Saltar la confirmación |
313
+ | `--dry-run` | `-n` | Mostrar lo que se haría y salir |
314
+ | `--no-trim` | | No enviar TRIM al terminar |
315
+
316
+ Mientras se ejecuta, el sistema de archivos queda lleno durante un momento; los archivos existentes no se modifican.
317
+
318
+ #### Opciones globales
319
+
320
+ | Opción | Descripción |
321
+ |--------|-------------|
322
+ | `--lang en\|es` | Idioma de la interfaz (también la variable de entorno `MADARA_LANG`) |
323
+
324
+ ### Estándares
325
+
326
+ | Estándar | Pases en HDD | Pases en SSD/NVMe | Verificación |
327
+ |----------|-------------|-------------------|--------------|
328
+ | `clear` | 1 (ceros) | 1 (aleatorio) | solo con `--verify` |
329
+ | `purge` | 3 (ceros, unos, aleatorio) | 1 (aleatorio) | siempre |
330
+ | `dod` | 3 (ceros, unos, aleatorio) | 1 (aleatorio) | solo con `--verify` |
331
+
332
+ En almacenamiento flash se usa un pase aleatorio sea cual sea el estándar: por el wear-leveling, más pases no alcanzan más celdas. Al usar `purge` o `dod` en SSD/NVMe se muestra un aviso, porque sobrescribir archivos en flash **no** cumple *Purge* de NIST SP 800-88.
333
+
334
+ ### Log de auditoría
335
+
336
+ Cada archivo borrado añade una línea JSON con el timestamp UTC, la ruta, el tamaño, el estándar, los pases, el resultado de la verificación, el usuario, el hostname y el resultado. Por defecto el log está en una ubicación privada del usuario:
337
+
338
+ | SO | Ruta por defecto |
339
+ |----|------------------|
340
+ | Linux | `$XDG_STATE_HOME/madaramaster/audit.jsonl` (por defecto `~/.local/state/…`) |
341
+ | macOS | `~/Library/Logs/MadaraMaster/audit.jsonl` |
342
+ | Windows | `%LOCALAPPDATA%\MadaraMaster\audit.jsonl` |
343
+
344
+ El SHA-256 previo solo se guarda con `--hash`, porque permite a quien tenga el log confirmar qué contenía un archivo. `--no-log` desactiva el log.
345
+
346
+ ### Limitaciones
347
+
348
+ Antes de borrar, MadaraMaster avisa cuando detecta alguno de estos casos: SSD/NVMe, sistemas de archivos copy-on-write, ubicaciones de red, carpetas sincronizadas con la nube y ext3/ext4 montado con `data=journal`. Que no aparezca un aviso no es una garantía.
349
+
350
+ MadaraMaster trabaja a nivel de archivo. No puede garantizar que no sobreviva ninguna copia de los datos cuando:
351
+
352
+ - **El archivo está en un SSD, NVMe, pendrive o tarjeta SD.** El controlador reubica las escrituras (wear-leveling, sobreaprovisionamiento), así que los bloques antiguos pueden seguir en los chips. Para purgar flash, usa cifrado de disco completo desde el principio o el comando de borrado de la propia unidad (ATA Secure Erase, NVMe Format / Sanitize).
353
+ - **El sistema de archivos es copy-on-write o log-structured** — btrfs, ZFS, APFS, ReFS, F2FS: los datos nuevos van a bloques nuevos y los antiguos se quedan atrás.
354
+ - **Hay instantáneas o copias de seguridad** — Volume Shadow Copies, Time Machine, instantáneas de btrfs/ZFS, software de backup.
355
+ - **El archivo está sincronizado o en caché en otro sitio** — OneDrive, Dropbox, iCloud, Google Drive, carpetas de red.
356
+ - **El sistema de archivos registra datos en el journal** — p. ej. ext4 con `data=journal`; NTFS y ext4 registran metadatos como los nombres.
357
+ - **Existen otras copias** — copias de seguridad y autoguardados de editores, archivos temporales, el archivo de intercambio o de hibernación, miniaturas, listas de recientes.
358
+
359
+ Para garantías fuertes, combina cifrado de disco completo con la destrucción de la clave, o borra el dispositivo entero.
360
+
361
+ ### Desarrollo
362
+
363
+ ```bash
364
+ pip install -e ".[dev]"
365
+ python -m pytest # tests
366
+ ruff check . # lint
367
+ ```
368
+
369
+ Los tests nunca borran nada real: un fixture autouse sustituye TRIM y la detección de almacenamiento por mocks, bloquea toda ruta de dispositivo y todo `ioctl`, y rechaza cualquier escritura, renombrado o borrado fuera del directorio temporal de pytest. El CI se ejecuta en Linux, Windows y macOS y además construye el ejecutable de Windows.
370
+
371
+ Para construir `MadaraMaster.exe` en Windows: `.\build.ps1`, o `pip install ".[build]"` y `pyinstaller MadaraMaster.spec --clean --noconfirm`.
372
+
373
+ Las versiones se publican automáticamente: al subir un tag `vX.Y.Z` que coincida con `__version__` se construyen el `.exe`, el wheel y el sdist, se crea una GitHub Release y se publica en PyPI. Consulta [RELEASING.md](RELEASING.md).
374
+
375
+ ### Estructura del proyecto
376
+
377
+ ```
378
+ MadaraMaster/
379
+ ├── madaramaster/
380
+ │ ├── cli.py # punto de entrada (madara) e interfaz de importación estable
381
+ │ ├── commands.py # app Typer: wipe, wipe-free-space, version, install-right-click
382
+ │ ├── interactive.py # sesión interactiva de arrastrar y soltar
383
+ │ ├── runner.py # flujo común: expansión de objetivos, lote con dashboard, limpieza
384
+ │ ├── ui.py # salida por consola: banner, preguntas, resumen, dashboard, avisos
385
+ │ ├── i18n.py # textos EN/ES e idioma activo
386
+ │ ├── free_space.py # motor de relleno del espacio libre
387
+ │ ├── engine.py # motor asíncrono (Direct I/O, ADS, slack space, verificación)
388
+ │ ├── residue.py # detección de configuraciones donde pueden quedar copias
389
+ │ ├── safety.py # recogida de objetivos sin seguir enlaces y objetivos protegidos
390
+ │ ├── storage.py # detección del tipo de almacenamiento (sysfs / IOCTL / diskutil)
391
+ │ ├── trim.py # TRIM en Linux (FITRIM)
392
+ │ ├── audit.py # log de auditoría JSON Lines
393
+ │ ├── models.py # clases de datos de resultados y telemetría
394
+ │ └── utils.py # utilidades de formato
395
+ ├── tests/ # tests con la red de seguridad (tests/conftest.py)
396
+ ├── madara.py # punto de entrada de compatibilidad
397
+ ├── MadaraMaster.spec # build de PyInstaller
398
+ ├── madara.manifest # manifiesto de Windows (asInvoker)
399
+ ├── build.ps1 # script de release para Windows
400
+ ├── scripts/ # generador de notas usado por el workflow de release
401
+ ├── RELEASING.md # proceso de release y configuración de Trusted Publishing
402
+ └── pyproject.toml
403
+ ```
404
+
405
+ ### Licencia
406
+
407
+ MIT. Consulta el archivo LICENSE.
408
+
409
+ El software se proporciona solo para uso autorizado de borrado seguro de datos. El autor no se hace responsable del mal uso ni de la pérdida de datos por uso incorrecto.