mirror of
https://github.com/trustedsec/hate_crack.git
synced 2026-06-12 19:11:46 -07:00
3aa7138c9c
- Add transmission-cli package (provides transmission-remote binary) - Fix SETUPTOOLS_SCM_PRETEND_VERSION placement before RUN make install - Fix PATH to use /root/.local/bin and include venv bin - Switch TransmissionSession.add() from watch-dir polling to transmission-remote -a - Remove --no-auth flag (unrecognized in transmission-remote 4.1.0) - Add test_docker_torrent_downloads_wordlists E2E test Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
142 lines
4.6 KiB
Python
142 lines
4.6 KiB
Python
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
|
|
def _require_docker():
|
|
if os.environ.get("HATE_CRACK_RUN_DOCKER_TESTS") != "1":
|
|
pytest.skip("Set HATE_CRACK_RUN_DOCKER_TESTS=1 to run Docker-based tests.")
|
|
if shutil.which("docker") is None:
|
|
pytest.skip("docker not available")
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def docker_image():
|
|
_require_docker()
|
|
repo_root = Path(__file__).resolve().parents[1]
|
|
# Use a unique tag per test run to avoid conflicts
|
|
image_tag = f"hate-crack-e2e-{uuid.uuid4().hex[:8]}"
|
|
|
|
dockerfile_path = str(repo_root / "Dockerfile.test")
|
|
try:
|
|
build = subprocess.run(
|
|
["docker", "build", "-f", dockerfile_path, "-t", image_tag, str(repo_root)],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=600,
|
|
)
|
|
except subprocess.TimeoutExpired as exc:
|
|
pytest.fail(f"Docker build timed out after {exc.timeout}s")
|
|
|
|
assert build.returncode == 0, (
|
|
f"Docker build failed. stdout={build.stdout} stderr={build.stderr}"
|
|
)
|
|
|
|
yield image_tag
|
|
|
|
# Cleanup: remove the Docker image after tests complete
|
|
try:
|
|
result = subprocess.run(
|
|
["docker", "image", "rm", image_tag],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=60,
|
|
)
|
|
if result.returncode != 0:
|
|
print(
|
|
f"Warning: Failed to remove Docker image {image_tag}. "
|
|
f"stderr={result.stderr}",
|
|
file=sys.stderr,
|
|
)
|
|
except Exception as e:
|
|
# Don't fail the test if cleanup fails, but log the issue
|
|
print(
|
|
f"Warning: Exception while removing Docker image {image_tag}: {e}",
|
|
file=sys.stderr,
|
|
)
|
|
|
|
|
|
def _run_container(image_tag, command, timeout=180):
|
|
try:
|
|
run = subprocess.run(
|
|
["docker", "run", "--rm", image_tag, "bash", "-lc", command],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=timeout,
|
|
)
|
|
except subprocess.TimeoutExpired as exc:
|
|
pytest.fail(f"Docker run timed out after {exc.timeout}s")
|
|
return run
|
|
|
|
|
|
def test_docker_script_install_and_run(docker_image):
|
|
run = _run_container(
|
|
docker_image,
|
|
"$HOME/.local/bin/hate_crack --help >/tmp/hc_help.txt && ./hate_crack.py --help >/tmp/hc_script_help.txt",
|
|
timeout=120,
|
|
)
|
|
assert run.returncode == 0, (
|
|
f"Docker script install/run failed. stdout={run.stdout} stderr={run.stderr}"
|
|
)
|
|
|
|
|
|
def test_docker_hashcat_cracks_simple_password(docker_image):
|
|
command = (
|
|
"set -euo pipefail; "
|
|
"printf 'password\\nletmein\\n123456\\n' > /tmp/wordlist.txt; "
|
|
"echo 5f4dcc3b5aa765d61d8327deb882cf99 > /tmp/hash.txt; "
|
|
"hashcat -m 0 -a 0 --potfile-disable -o /tmp/out.txt /tmp/hash.txt /tmp/wordlist.txt --quiet; "
|
|
"grep -q ':password' /tmp/out.txt"
|
|
)
|
|
run = _run_container(docker_image, command, timeout=180)
|
|
assert run.returncode == 0, (
|
|
f"Docker hashcat crack failed. stdout={run.stdout} stderr={run.stderr}"
|
|
)
|
|
|
|
|
|
@pytest.mark.timeout(300)
|
|
def test_docker_torrent_downloads_wordlists(docker_image, tmp_path):
|
|
downloads_dir = tmp_path / "downloads"
|
|
downloads_dir.mkdir()
|
|
|
|
py_cmd = (
|
|
"from hate_crack.api import fetch_torrent_metadata, run_torrent_session; "
|
|
"t1 = fetch_torrent_metadata('ignis-10K.txt'); "
|
|
"t2 = fetch_torrent_metadata('hashmob.net_2025.micro.found'); "
|
|
"files = [f for f in (t1, t2) if f]; "
|
|
"run_torrent_session(files, '/downloads')"
|
|
)
|
|
|
|
try:
|
|
run = subprocess.run(
|
|
[
|
|
"docker", "run", "--rm",
|
|
"-v", f"{downloads_dir}:/downloads",
|
|
docker_image,
|
|
"bash", "-lc", f"/workspace/.venv/bin/python -c \"{py_cmd}\"",
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=300,
|
|
)
|
|
except subprocess.TimeoutExpired as exc:
|
|
pytest.fail(f"Docker torrent test timed out after {exc.timeout}s")
|
|
|
|
assert run.returncode == 0, (
|
|
f"Torrent session failed. stdout={run.stdout} stderr={run.stderr}"
|
|
)
|
|
|
|
ignis10k = downloads_dir / "ignis-10K.txt"
|
|
micro = downloads_dir / "hashmob.net_2025.micro.found"
|
|
assert ignis10k.exists() and ignis10k.stat().st_size > 0, (
|
|
f"ignis-10K.txt missing/empty. stdout={run.stdout} stderr={run.stderr}"
|
|
)
|
|
assert micro.exists() and micro.stat().st_size > 0, (
|
|
f"hashmob.net_2025.micro.found missing/empty. stdout={run.stdout} stderr={run.stderr}"
|
|
)
|