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.
- madaramaster-5.0.0/.gitignore +11 -0
- madaramaster-5.0.0/LICENSE +22 -0
- madaramaster-5.0.0/MANIFEST.in +8 -0
- madaramaster-5.0.0/MadaraMaster.spec +53 -0
- madaramaster-5.0.0/PKG-INFO +409 -0
- madaramaster-5.0.0/README.md +379 -0
- madaramaster-5.0.0/RELEASING.md +97 -0
- madaramaster-5.0.0/build.ps1 +82 -0
- madaramaster-5.0.0/madara.manifest +56 -0
- madaramaster-5.0.0/madara.py +7 -0
- madaramaster-5.0.0/madaramaster/__init__.py +3 -0
- madaramaster-5.0.0/madaramaster/__main__.py +5 -0
- madaramaster-5.0.0/madaramaster/audit.py +154 -0
- madaramaster-5.0.0/madaramaster/cli.py +118 -0
- madaramaster-5.0.0/madaramaster/commands.py +458 -0
- madaramaster-5.0.0/madaramaster/engine.py +957 -0
- madaramaster-5.0.0/madaramaster/free_space.py +114 -0
- madaramaster-5.0.0/madaramaster/i18n.py +323 -0
- madaramaster-5.0.0/madaramaster/interactive.py +208 -0
- madaramaster-5.0.0/madaramaster/models.py +58 -0
- madaramaster-5.0.0/madaramaster/residue.py +242 -0
- madaramaster-5.0.0/madaramaster/runner.py +206 -0
- madaramaster-5.0.0/madaramaster/safety.py +188 -0
- madaramaster-5.0.0/madaramaster/storage.py +503 -0
- madaramaster-5.0.0/madaramaster/trim.py +140 -0
- madaramaster-5.0.0/madaramaster/ui.py +330 -0
- madaramaster-5.0.0/madaramaster/utils.py +30 -0
- madaramaster-5.0.0/madaramaster.egg-info/PKG-INFO +409 -0
- madaramaster-5.0.0/madaramaster.egg-info/SOURCES.txt +50 -0
- madaramaster-5.0.0/madaramaster.egg-info/dependency_links.txt +1 -0
- madaramaster-5.0.0/madaramaster.egg-info/entry_points.txt +2 -0
- madaramaster-5.0.0/madaramaster.egg-info/requires.txt +11 -0
- madaramaster-5.0.0/madaramaster.egg-info/top_level.txt +1 -0
- madaramaster-5.0.0/pyproject.toml +64 -0
- madaramaster-5.0.0/scripts/release_notes.py +101 -0
- madaramaster-5.0.0/setup.cfg +4 -0
- madaramaster-5.0.0/tests/conftest.py +282 -0
- madaramaster-5.0.0/tests/test_audit.py +111 -0
- madaramaster-5.0.0/tests/test_batch_trim_writes_names.py +128 -0
- madaramaster-5.0.0/tests/test_dangerous_targets.py +138 -0
- madaramaster-5.0.0/tests/test_direct_io.py +144 -0
- madaramaster-5.0.0/tests/test_interactive.py +175 -0
- madaramaster-5.0.0/tests/test_links.py +147 -0
- madaramaster-5.0.0/tests/test_messages_and_standards.py +160 -0
- madaramaster-5.0.0/tests/test_packaging_and_cli.py +230 -0
- madaramaster-5.0.0/tests/test_release_notes.py +90 -0
- madaramaster-5.0.0/tests/test_residue.py +195 -0
- madaramaster-5.0.0/tests/test_safety_net.py +87 -0
- madaramaster-5.0.0/tests/test_trim.py +48 -0
- madaramaster-5.0.0/tests/test_unlink_and_verify.py +92 -0
- madaramaster-5.0.0/tests/test_windows_ads.py +43 -0
- madaramaster-5.0.0/tests/test_wipe_free_space.py +119 -0
|
@@ -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.
|